1 /* Subroutines for insn-output.c for Hitachi H8/300.
2 Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
3 Contributed by Steve Chamberlain (sac@cygnus.com),
4 Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
27 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
33 #include "insn-attr.h"
40 /* Forward declarations. */
41 void print_operand_address ();
44 static int h8300_interrupt_function_p
PROTO ((tree
));
45 static int h8300_monitor_function_p
PROTO ((tree
));
46 static int h8300_os_task_function_p
PROTO ((tree
));
48 /* CPU_TYPE, says what cpu we're compiling for. */
51 /* True if the current function is an interrupt handler
52 (either via #pragma or an attribute specification). */
53 int interrupt_handler
;
55 /* True if the current function is an OS Task
56 (via an attribute specification). */
59 /* True if the current function is a monitor
60 (via an attribute specification). */
63 /* True if a #pragma saveall has been seen for the current function. */
66 static char *names_big
[] =
67 {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7"};
69 static char *names_extended
[] =
70 {"er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"};
72 static char *names_upper_extended
[] =
73 {"e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"};
75 /* Points to one of the above. */
76 /* ??? The above could be put in an array indexed by CPU_TYPE. */
79 /* Various operations needed by the following, indexed by CPU_TYPE. */
81 static char *h8_push_ops
[2] =
83 static char *h8_pop_ops
[2] =
85 static char *h8_mov_ops
[2] =
88 char *h8_push_op
, *h8_pop_op
, *h8_mov_op
;
90 /* Initialize various cpu specific globals at start up. */
97 cpu_type
= (int) CPU_H8300
;
98 h8_reg_names
= names_big
;
102 /* For this we treat the H8/300 and H8/S the same. */
103 cpu_type
= (int) CPU_H8300H
;
104 h8_reg_names
= names_extended
;
106 h8_push_op
= h8_push_ops
[cpu_type
];
107 h8_pop_op
= h8_pop_ops
[cpu_type
];
108 h8_mov_op
= h8_mov_ops
[cpu_type
];
116 static char *names_small
[] =
117 {"r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
118 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h"};
120 return names_small
[REGNO (x
) * 2 + b
];
123 /* REGNO must be saved/restored across calls if this macro is true. */
125 #define WORD_REG_USED(regno) \
129 || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno]) \
130 || (regs_ever_live[regno] & !call_used_regs[regno])))
132 /* Output assembly language to FILE for the operation OP with operand size
133 SIZE to adjust the stack pointer. */
136 dosize (file
, op
, size
)
141 /* On the h8300h and h8300s, for sizes <= 8 bytes it is as good or
142 better to use adds/subs insns rather than add.l/sub.l
143 with an immediate value. */
144 if (size
> 4 && size
<= 8 && (TARGET_H8300H
|| TARGET_H8300S
))
146 /* Crank the size down to <= 4 */
147 fprintf (file
, "\t%ss\t#%d,sp\n", op
, 4);
154 if (TARGET_H8300H
|| TARGET_H8300S
)
156 fprintf (file
, "\t%ss\t#%d,sp\n", op
, 4);
161 fprintf (file
, "\t%ss\t#%d,sp\n", op
, 2);
163 /* Fall through... */
166 fprintf (file
, "\t%ss\t#%d,sp\n", op
, size
);
174 if (current_function_needs_context
175 && strcmp (op
, "sub") == 0)
177 /* Egad. We don't have a temporary to hold the
178 size of the frame in the prologue! Just inline
179 the bastard since this shouldn't happen often. */
182 fprintf (file
, "\tsubs\t#2,sp\n");
187 fprintf (file
, "\tsubs\t#1,sp\n");
192 fprintf (file
, "\tmov.w\t#%d,r3\n\t%s.w\tr3,sp\n", size
, op
);
195 fprintf (file
, "\t%s\t#%d,sp\n", op
, size
);
201 /* Output assembly language code for the function prologue. */
202 static int push_order
[FIRST_PSEUDO_REGISTER
] =
203 {0, 1, 2, 3, 4, 5, 6, -1, -1, -1};
204 static int pop_order
[FIRST_PSEUDO_REGISTER
] =
205 {6, 5, 4, 3, 2, 1, 0, -1, -1, -1};
207 /* This is what the stack looks like after the prolog of
208 a function with a frame has been set up:
214 <saved registers> <- sp
216 This is what the stack looks like after the prolog of
217 a function which doesn't have a frame:
222 <saved registers> <- sp
226 function_prologue (file
, size
)
230 register int mask
= 0;
231 int fsize
= (size
+ STACK_BOUNDARY
/ 8 - 1) & -STACK_BOUNDARY
/ 8;
234 /* Note a function with the interrupt attribute and set interrupt_handler
236 if (h8300_interrupt_function_p (current_function_decl
))
237 interrupt_handler
= 1;
239 /* If the current function has the OS_Task attribute set, then
240 we have a naked prologue. */
241 if (h8300_os_task_function_p (current_function_decl
))
243 fprintf (file
, ";OS_Task prologue\n");
248 if (h8300_monitor_function_p (current_function_decl
))
250 /* My understanding of monitor functions is they act just
251 like interrupt functions, except the prologue must
253 fprintf (file
, ";monitor prologue\n");
254 interrupt_handler
= 1;
258 fprintf (file
, "\tsubs\t#2,sp\n");
259 fprintf (file
, "\tpush\tr0\n");
260 fprintf (file
, "\tstc\tccr,r0l\n");
261 fprintf (file
, "\torc\t#128,ccr\n");
262 fprintf (file
, "\tmov.b\tr0l,@(4,sp)\n");
266 fprintf (file
, "\tpush\ter0\n");
267 fprintf (file
, "\tstc\tccr,r0l\n");
268 fprintf (file
, "\torc\t#128,ccr\n");
269 fprintf (file
, "\tmov.b\tr0l,@(4,sp)\n");
273 if (frame_pointer_needed
)
276 fprintf (file
, "\t%s\t%s\n", h8_push_op
,
277 h8_reg_names
[FRAME_POINTER_REGNUM
]);
278 fprintf (file
, "\t%s\t%s,%s\n", h8_mov_op
,
279 h8_reg_names
[STACK_POINTER_REGNUM
],
280 h8_reg_names
[FRAME_POINTER_REGNUM
]);
283 /* leave room for locals */
284 dosize (file
, "sub", fsize
);
286 /* Push the rest of the registers */
287 for (idx
= 0; idx
< FIRST_PSEUDO_REGISTER
; idx
++)
289 int regno
= push_order
[idx
];
292 && WORD_REG_USED (regno
)
293 && (!frame_pointer_needed
|| regno
!= FRAME_POINTER_REGNUM
))
297 /* Try to push multiple registers. */
298 if (regno
== 0 || regno
== 4)
300 int second_regno
= push_order
[idx
+ 1];
301 int third_regno
= push_order
[idx
+ 2];
302 int fourth_regno
= push_order
[idx
+ 3];
304 if (fourth_regno
>= 0
305 && WORD_REG_USED (fourth_regno
)
306 && (!frame_pointer_needed
307 || fourth_regno
!= FRAME_POINTER_REGNUM
)
309 && WORD_REG_USED (third_regno
)
310 && (!frame_pointer_needed
311 || third_regno
!= FRAME_POINTER_REGNUM
)
313 && WORD_REG_USED (second_regno
)
314 && (!frame_pointer_needed
315 || second_regno
!= FRAME_POINTER_REGNUM
))
317 fprintf (file
, "\tstm.l %s-%s,@-sp\n",
319 h8_reg_names
[fourth_regno
]);
324 if (regno
== 0 || regno
== 4)
326 int second_regno
= push_order
[idx
+ 1];
327 int third_regno
= push_order
[idx
+ 2];
330 && WORD_REG_USED (third_regno
)
331 && (!frame_pointer_needed
332 || third_regno
!= FRAME_POINTER_REGNUM
)
334 && WORD_REG_USED (second_regno
)
335 && (!frame_pointer_needed
336 || second_regno
!= FRAME_POINTER_REGNUM
))
338 fprintf (file
, "\tstm.l %s-%s,@-sp\n",
340 h8_reg_names
[third_regno
]);
345 if (regno
== 0 || regno
== 2 || regno
== 4 || regno
== 6)
347 int second_regno
= push_order
[idx
+ 1];
349 if (second_regno
>= 0
350 && WORD_REG_USED (second_regno
)
351 && (!frame_pointer_needed
352 || second_regno
!= FRAME_POINTER_REGNUM
))
354 fprintf (file
, "\tstm.l %s-%s,@-sp\n",
356 h8_reg_names
[second_regno
]);
362 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[regno
]);
367 /* Output assembly language code for the function epilogue. */
370 function_epilogue (file
, size
)
375 register int mask
= 0;
376 int fsize
= (size
+ STACK_BOUNDARY
/ 8 - 1) & -STACK_BOUNDARY
/ 8;
378 rtx insn
= get_last_insn ();
382 /* OS_Task epilogues are nearly naked -- they just have an
384 fprintf (file
, ";OS_task epilogue\n");
385 fprintf (file
, "\trts\n");
389 /* monitor epilogues are the same as interrupt function epilogues.
390 Just make a note that we're in an monitor epilogue. */
392 fprintf(file
, ";monitor epilogue\n");
394 /* If the last insn was a BARRIER, we don't have to write any code. */
395 if (GET_CODE (insn
) == NOTE
)
396 insn
= prev_nonnote_insn (insn
);
397 if (insn
&& GET_CODE (insn
) == BARRIER
)
400 /* Pop the saved registers. */
401 for (idx
= 0; idx
< FIRST_PSEUDO_REGISTER
; idx
++)
403 int regno
= pop_order
[idx
];
406 && WORD_REG_USED (regno
)
407 && (!frame_pointer_needed
|| regno
!= FRAME_POINTER_REGNUM
))
411 /* Try to pop multiple registers. */
412 if (regno
== 7 || regno
== 3)
414 int second_regno
= pop_order
[idx
+ 1];
415 int third_regno
= pop_order
[idx
+ 2];
416 int fourth_regno
= pop_order
[idx
+ 3];
418 if (fourth_regno
>= 0
419 && WORD_REG_USED (fourth_regno
)
420 && (!frame_pointer_needed
421 || fourth_regno
!= FRAME_POINTER_REGNUM
)
423 && WORD_REG_USED (third_regno
)
424 && (!frame_pointer_needed
425 || third_regno
!= FRAME_POINTER_REGNUM
)
427 && WORD_REG_USED (second_regno
)
428 && (!frame_pointer_needed
429 || second_regno
!= FRAME_POINTER_REGNUM
))
431 fprintf (file
, "\tldm.l @sp+,%s-%s\n",
432 h8_reg_names
[fourth_regno
],
433 h8_reg_names
[regno
]);
438 if (regno
== 6 || regno
== 2)
440 int second_regno
= pop_order
[idx
+ 1];
441 int third_regno
= pop_order
[idx
+ 2];
444 && WORD_REG_USED (third_regno
)
445 && (!frame_pointer_needed
446 || third_regno
!= FRAME_POINTER_REGNUM
)
448 && WORD_REG_USED (second_regno
)
449 && (!frame_pointer_needed
450 || second_regno
!= FRAME_POINTER_REGNUM
))
452 fprintf (file
, "\tldm.l @sp+,%s-%s\n",
453 h8_reg_names
[third_regno
],
454 h8_reg_names
[regno
]);
459 if (regno
== 7 || regno
== 5 || regno
== 3 || regno
== 1)
461 int second_regno
= pop_order
[idx
+ 1];
463 if (second_regno
>= 0
464 && WORD_REG_USED (second_regno
)
465 && (!frame_pointer_needed
466 || second_regno
!= FRAME_POINTER_REGNUM
))
468 fprintf (file
, "\tldm.l @sp+,%s-%s\n",
469 h8_reg_names
[second_regno
],
470 h8_reg_names
[regno
]);
476 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[regno
]);
480 /* deallocate locals */
481 dosize (file
, "add", fsize
);
483 /* pop frame pointer if we had one. */
484 if (frame_pointer_needed
)
485 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[FRAME_POINTER_REGNUM
]);
487 /* If this is a monitor function, there is one register still left on
490 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[0]);
492 if (interrupt_handler
)
493 fprintf (file
, "\trte\n");
495 fprintf (file
, "\trts\n");
498 interrupt_handler
= 0;
504 /* Output assembly code for the start of the file. */
506 asm_file_start (file
)
509 fprintf (file
, ";\tGCC For the Hitachi H8/300\n");
510 fprintf (file
, ";\tBy Hitachi America Ltd and Cygnus Support\n");
511 fprintf (file
, ";\trelease F-1\n");
513 fprintf (file
, "; -O%d\n", optimize
);
515 fprintf (file
, "\n\t.h8300h\n");
516 else if (TARGET_H8300S
)
517 fprintf (file
, "\n\t.h8300s\n");
519 fprintf (file
, "\n\n");
520 output_file_directive (file
, main_input_filename
);
523 /* Output assembly language code for the end of file. */
529 fprintf (file
, "\t.end\n");
532 /* Return true if VALUE is a valid constant for constraint 'P'.
533 IE: VALUE is a power of two <= 2**15. */
536 small_power_of_two (value
)
562 /* Return true if VALUE is a valid constant for constraint 'O', which
563 means that the constant would be ok to use as a bit for a bclr
570 return small_power_of_two ((~value
) & 0xff);
573 /* Return true is OP is a valid source operand for an integer move
577 general_operand_src (op
, mode
)
579 enum machine_mode mode
;
581 if (GET_CODE (op
) == MEM
&& GET_CODE (XEXP (op
, 0)) == POST_INC
)
583 return general_operand (op
, mode
);
586 /* Return true if OP is a valid destination operand for an integer move
590 general_operand_dst (op
, mode
)
592 enum machine_mode mode
;
594 if (GET_CODE (op
) == MEM
&& GET_CODE (XEXP (op
, 0)) == PRE_DEC
)
596 return general_operand (op
, mode
);
599 /* Return true if OP is a const valid for a bit clear instruction. */
602 o_operand (operand
, mode
)
604 enum machine_mode mode
;
606 return (GET_CODE (operand
) == CONST_INT
607 && CONST_OK_FOR_O (INTVAL (operand
)));
610 /* Return true if OP is a const valid for a bit set or bit xor instruction. */
613 p_operand (operand
, mode
)
615 enum machine_mode mode
;
617 return (GET_CODE (operand
) == CONST_INT
618 && CONST_OK_FOR_P (INTVAL (operand
)));
621 /* Return true if OP is a valid call operand. */
624 call_insn_operand (op
, mode
)
626 enum machine_mode mode
;
628 if (GET_CODE (op
) == MEM
)
630 rtx inside
= XEXP (op
, 0);
631 if (register_operand (inside
, Pmode
))
633 if (CONSTANT_ADDRESS_P (inside
))
640 adds_subs_operand (op
, mode
)
642 enum machine_mode mode
;
644 if (GET_CODE (op
) == CONST_INT
)
646 if (INTVAL (op
) <= 4 && INTVAL (op
) >= 0)
648 if (INTVAL (op
) >= -4 && INTVAL (op
) <= 0)
650 if ((TARGET_H8300H
|| TARGET_H8300S
)
652 && (INTVAL (op
) <= 8 && INTVAL (op
) >= 0))
654 if ((TARGET_H8300H
|| TARGET_H8300S
)
656 && (INTVAL (op
) >= -8 && INTVAL (op
) <= 0))
662 /* Return nonzero if op is an adds/subs operand which only requires
663 one insn to implement. It is assumed that OP is already an adds/subs
666 one_insn_adds_subs_operand (op
, mode
)
668 enum machine_mode mode
;
670 int val
= INTVAL (op
);
672 if (val
== 1 || val
== -1
673 || val
== 2 || val
== -2
674 || ((TARGET_H8300H
|| TARGET_H8300S
)
675 && (val
== 4 || val
== -4)))
681 output_adds_subs (operands
)
684 int val
= INTVAL (operands
[2]);
686 /* First get the value into the range -4..4 inclusive.
688 The only way it can be out of this range is when TARGET_H8300H
689 or TARGET_H8300S is true, thus it is safe to use adds #4 and subs #4. */
692 output_asm_insn ("adds #4,%A0", operands
);
698 output_asm_insn ("subs #4,%A0", operands
);
702 /* Handle case were val == 4 or val == -4 and we're compiling
703 for TARGET_H8300H or TARGET_H8300S. */
704 if ((TARGET_H8300H
|| TARGET_H8300S
)
706 return "adds #4,%A0";
708 if ((TARGET_H8300H
|| TARGET_H8300S
)
710 return "subs #4,%A0";
714 output_asm_insn ("adds #2,%A0", operands
);
720 output_asm_insn ("subs #2,%A0", operands
);
724 /* val should be one or two now. */
726 return "adds #2,%A0";
729 return "subs #2,%A0";
731 /* val should be one now. */
733 return "adds #1,%A0";
736 return "subs #1,%A0";
738 /* If not optimizing, we might be asked to add 0. */
742 /* In theory, this can't happen. */
746 /* Return true if OP is a valid call operand, and OP represents
747 an operand for a small call (4 bytes instead of 6 bytes). */
750 small_call_insn_operand (op
, mode
)
752 enum machine_mode mode
;
754 if (GET_CODE (op
) == MEM
)
756 rtx inside
= XEXP (op
, 0);
758 /* Register indirect is a small call. */
759 if (register_operand (inside
, Pmode
))
762 /* A call through the function vector is a small
764 if (GET_CODE (inside
) == SYMBOL_REF
765 && SYMBOL_REF_FLAG (inside
))
768 /* Otherwise it's a large call. */
772 /* Return true if OP is a valid jump operand. */
775 jump_address_operand (op
, mode
)
777 enum machine_mode mode
;
779 if (GET_CODE (op
) == REG
)
780 return mode
== Pmode
;
782 if (GET_CODE (op
) == MEM
)
784 rtx inside
= XEXP (op
, 0);
785 if (register_operand (inside
, Pmode
))
787 if (CONSTANT_ADDRESS_P (inside
))
793 /* Recognize valid operands for bitfield instructions. */
795 extern int rtx_equal_function_value_matters
;
798 bit_operand (op
, mode
)
800 enum machine_mode mode
;
802 /* We can except any general operand, expept that MEM operands must
803 be limited to those that use addresses valid for the 'U' constraint. */
804 if (!general_operand (op
, mode
))
807 /* Accept any mem during RTL generation. Otherwise, the code that does
808 insv and extzv will think that we can not handle memory. However,
809 to avoid reload problems, we only accept 'U' MEM operands after RTL
810 generation. This means that any named pattern which uses this predicate
811 must force its operands to match 'U' before emitting RTL. */
813 if (GET_CODE (op
) == REG
)
815 if (GET_CODE (op
) == SUBREG
)
817 if (!rtx_equal_function_value_matters
)
819 /* We're building rtl */
820 return GET_CODE (op
) == MEM
;
824 return (GET_CODE (op
) == MEM
825 && EXTRA_CONSTRAINT (op
, 'U'));
830 bit_memory_operand (op
, mode
)
832 enum machine_mode mode
;
834 return (GET_CODE (op
) == MEM
835 && EXTRA_CONSTRAINT (op
, 'U'));
838 /* Recognize valid operators for bit test. */
841 eq_operator (x
, mode
)
843 enum machine_mode mode
;
845 return (GET_CODE (x
) == EQ
|| GET_CODE (x
) == NE
);
848 /* Handle machine specific pragmas for compatibility with existing
849 compilers for the H8/300.
851 pragma saveall generates prolog/epilog code which saves and
852 restores all the registers on function entry.
854 pragma interrupt saves and restores all registers, and exits with
855 an rte instruction rather than an rts. A pointer to a function
856 with this attribute may be safely used in an interrupt vector. */
859 handle_pragma (file
, t
)
864 register char *pname
;
866 if (TREE_CODE (t
) != IDENTIFIER_NODE
)
869 pname
= IDENTIFIER_POINTER (t
);
870 if (strcmp (pname
, "interrupt") == 0)
871 interrupt_handler
= retval
= 1;
872 else if (strcmp (pname
, "saveall") == 0)
873 pragma_saveall
= retval
= 1;
878 /* If the next arg with MODE and TYPE is to be passed in a register, return
879 the rtx to represent where it is passed. CUM represents the state after
880 the last argument. NAMED is not used. */
882 static char *hand_list
[] =
902 /* Return an RTX to represent where a value with mode MODE will be returned
903 from a function. If the result is 0, the argument is pushed. */
906 function_arg (cum
, mode
, type
, named
)
907 CUMULATIVE_ARGS
*cum
;
908 enum machine_mode mode
;
916 /* Never pass unnamed arguments in registers. */
920 /* Pass 3 regs worth of data in regs when user asked on the command line. */
921 if (TARGET_QUICKCALL
)
924 /* If calling hand written assembler, use 4 regs of args. */
930 fname
= XSTR (cum
->libcall
, 0);
932 /* See if this libcall is one of the hand coded ones. */
934 for (p
= hand_list
; *p
&& strcmp (*p
, fname
) != 0; p
++)
946 size
= int_size_in_bytes (type
);
948 size
= GET_MODE_SIZE (mode
);
950 if (size
+ cum
->nbytes
> regpass
* UNITS_PER_WORD
)
956 switch (cum
->nbytes
/ UNITS_PER_WORD
)
959 result
= gen_rtx (REG
, mode
, 0);
962 result
= gen_rtx (REG
, mode
, 1);
965 result
= gen_rtx (REG
, mode
, 2);
968 result
= gen_rtx (REG
, mode
, 3);
979 /* Return the cost of the rtx R with code CODE. */
999 if (TARGET_H8300H
|| TARGET_H8300S
)
1020 /* Documentation for the machine specific operand escapes:
1022 'A' print rn in h8/300 mode, erN in H8/300H mode
1023 'C' print (operand - 2).
1024 'E' like s but negative.
1025 'F' like t but negative.
1026 'G' constant just the negative
1027 'L' fake label, changed after used twice.
1028 'M' turn a 'M' constant into its negative mod 2.
1029 'P' if operand is incing/decing sp, print .w, otherwise .b.
1030 'R' print operand as a byte:8 address if appropriate, else fall back to
1032 'S' print operand as a long word
1033 'T' print operand as a word
1034 'U' if operand is incing/decing sp, print l, otherwise nothing.
1035 'V' find the set bit, and print its number.
1036 'W' find the clear bit, and print its number.
1037 'X' print operand as a byte
1038 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
1039 If this operand isn't a register, fall back to 'R' handling.
1041 'b' print the bit opcode
1042 'c' print the ibit opcode
1043 'd' bcc if EQ, bcs if NE
1044 'e' first word of 32 bit value - if reg, then least reg. if mem
1045 then least. if const then most sig word
1046 'f' second word of 32 bit value - if reg, then biggest reg. if mem
1047 then +2. if const then least sig word
1048 'g' bcs if EQ, bcc if NE
1049 'j' print operand as condition code.
1050 'k' print operand as reverse condition code.
1051 's' print as low byte of 16 bit value
1052 't' print as high byte of 16 bit value
1053 'w' print as low byte of 32 bit value
1054 'x' print as 2nd byte of 32 bit value
1055 'y' print as 3rd byte of 32 bit value
1056 'z' print as msb of 32 bit value
1059 /* Return assembly language string which identifies a comparison type. */
1092 /* Print operand X using operand code CODE to assembly language output file
1096 print_operand (file
, x
, code
)
1101 /* This is used to general unique labels for the 'L' code. */
1102 static int lab
= 1000;
1104 /* This is used for communication between the 'P' and 'U' codes. */
1105 static char *last_p
;
1107 /* This is used for communication between codes V,W,Z and Y. */
1113 if (GET_CODE (x
) == REG
)
1114 fprintf (file
, "%s", h8_reg_names
[REGNO (x
)]);
1119 fprintf (file
, "#%d", INTVAL (x
) - 2);
1122 switch (GET_CODE (x
))
1125 fprintf (file
, "%sl", names_big
[REGNO (x
)]);
1128 fprintf (file
, "#%d", (-INTVAL (x
)) & 0xff);
1135 switch (GET_CODE (x
))
1138 fprintf (file
, "%sh", names_big
[REGNO (x
)]);
1141 fprintf (file
, "#%d", ((-INTVAL (x
)) & 0xff00) >> 8);
1148 if (GET_CODE (x
) != CONST_INT
)
1150 fprintf (file
, "#%d", 0xff & (-INTVAL (x
)));
1153 /* 'L' must always be used twice in a single pattern. It generates
1154 the same label twice, and then will generate a unique label the
1155 next time it is used. */
1156 asm_fprintf (file
, "tl%d", (lab
++) / 2);
1159 /* For 3/-3 and 4/-4, the other 2 is handled separately. */
1166 fprintf (file
, "#2");
1172 fprintf (file
, "#1");
1179 if (REGNO (XEXP (XEXP (x
, 0), 0)) == STACK_POINTER_REGNUM
)
1182 fprintf (file
, ".w");
1187 fprintf (file
, ".b");
1191 if (GET_CODE (x
) == REG
)
1192 fprintf (file
, "%s", names_extended
[REGNO (x
)]);
1197 if (GET_CODE (x
) == REG
)
1198 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1203 fprintf (file
, "%s%s", names_big
[REGNO (x
)], last_p
);
1206 bitint
= exact_log2 (INTVAL (x
));
1209 fprintf (file
, "#%d", bitint
& 7);
1212 bitint
= exact_log2 ((~INTVAL (x
)) & 0xff);
1215 fprintf (file
, "#%d", bitint
& 7);
1219 if (GET_CODE (x
) == REG
)
1220 fprintf (file
, "%s", byte_reg (x
, 0));
1227 if (GET_CODE (x
) == REG
)
1228 fprintf (file
, "%s%c", names_big
[REGNO (x
)], bitint
> 7 ? 'h' : 'l');
1230 print_operand (file
, x
, 'R');
1234 bitint
= INTVAL (x
);
1235 fprintf (file
, "#%d", bitint
& 7);
1238 switch (GET_CODE (x
))
1241 fprintf (file
, "bor");
1244 fprintf (file
, "bxor");
1247 fprintf (file
, "band");
1252 switch (GET_CODE (x
))
1255 fprintf (file
, "bior");
1258 fprintf (file
, "bixor");
1261 fprintf (file
, "biand");
1266 switch (GET_CODE (x
))
1269 fprintf (file
, "bcc");
1272 fprintf (file
, "bcs");
1279 switch (GET_CODE (x
))
1283 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1285 fprintf (file
, "%s", names_upper_extended
[REGNO (x
)]);
1288 x
= adj_offsettable_operand (x
, 0);
1289 print_operand (file
, x
, 0);
1292 fprintf (file
, "#%d", ((INTVAL (x
) >> 16) & 0xffff));
1300 switch (GET_CODE (x
))
1304 fprintf (file
, "%s", names_big
[REGNO (x
) + 1]);
1306 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1309 x
= adj_offsettable_operand (x
, 2);
1310 print_operand (file
, x
, 0);
1313 fprintf (file
, "#%d", INTVAL (x
) & 0xffff);
1320 switch (GET_CODE (x
))
1323 fprintf (file
, "bcc");
1326 fprintf (file
, "bcs");
1333 asm_fprintf (file
, cond_string (GET_CODE (x
)));
1336 asm_fprintf (file
, cond_string (reverse_condition (GET_CODE (x
))));
1339 if (GET_CODE (x
) == CONST_INT
)
1340 fprintf (file
, "#%d", (INTVAL (x
)) & 0xff);
1342 fprintf (file
, "%s", byte_reg (x
, 0));
1345 if (GET_CODE (x
) == CONST_INT
)
1346 fprintf (file
, "#%d", (INTVAL (x
) >> 8) & 0xff);
1348 fprintf (file
, "%s", byte_reg (x
, 1));
1351 if (GET_CODE (x
) != CONST_INT
)
1353 fprintf (file
, "%d", INTVAL (x
));
1356 if (GET_CODE (x
) == CONST_INT
)
1357 fprintf (file
, "#%d", INTVAL (x
) & 0xff);
1359 fprintf (file
, "%s",
1360 byte_reg (x
, TARGET_H8300
? 2 : 0));
1363 if (GET_CODE (x
) == CONST_INT
)
1364 fprintf (file
, "#%d", (INTVAL (x
) >> 8) & 0xff);
1366 fprintf (file
, "%s",
1367 byte_reg (x
, TARGET_H8300
? 3 : 1));
1370 if (GET_CODE (x
) == CONST_INT
)
1371 fprintf (file
, "#%d", (INTVAL (x
) >> 16) & 0xff);
1373 fprintf (file
, "%s", byte_reg (x
, 0));
1376 if (GET_CODE (x
) == CONST_INT
)
1377 fprintf (file
, "#%d", (INTVAL (x
) >> 24) & 0xff);
1379 fprintf (file
, "%s", byte_reg (x
, 1));
1384 switch (GET_CODE (x
))
1387 switch (GET_MODE (x
))
1390 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */
1391 fprintf (file
, "%s", byte_reg (x
, 0));
1392 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1393 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1397 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1401 fprintf (file
, "%s", names_extended
[REGNO (x
)]);
1409 fprintf (file
, "@");
1410 output_address (XEXP (x
, 0));
1412 /* If this is an 'R' operand (reference into the 8-bit area),
1413 then specify a symbolic address as "foo:8". */
1415 && GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
1416 && SYMBOL_REF_FLAG (XEXP (x
, 0)))
1417 fprintf (file
, ":8");
1418 if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
1419 && TINY_DATA_NAME_P (XSTR (XEXP (x
, 0), 0)))
1420 fprintf (file
, ":16");
1427 fprintf (file
, "#");
1428 print_operand_address (file
, x
);
1434 /* Output assembly language output for the address ADDR to FILE. */
1437 print_operand_address (file
, addr
)
1441 switch (GET_CODE (addr
))
1444 fprintf (file
, "%s", h8_reg_names
[REGNO (addr
)]);
1448 fprintf (file
, "-%s", h8_reg_names
[REGNO (XEXP (addr
, 0))]);
1452 fprintf (file
, "%s+", h8_reg_names
[REGNO (XEXP (addr
, 0))]);
1456 fprintf (file
, "(");
1457 if (GET_CODE (XEXP (addr
, 0)) == REG
)
1460 print_operand_address (file
, XEXP (addr
, 1));
1461 fprintf (file
, ",");
1462 print_operand_address (file
, XEXP (addr
, 0));
1467 print_operand_address (file
, XEXP (addr
, 0));
1468 fprintf (file
, "+");
1469 print_operand_address (file
, XEXP (addr
, 1));
1471 fprintf (file
, ")");
1476 /* Since the h8/300 only has 16 bit pointers, negative values are also
1477 those >= 32768. This happens for example with pointer minus a
1478 constant. We don't want to turn (char *p - 2) into
1479 (char *p + 65534) because loop unrolling can build upon this
1480 (IE: char *p + 131068). */
1481 int n
= INTVAL (addr
);
1483 n
= (int) (short) n
;
1485 /* ??? Why the special case for -ve values? */
1486 fprintf (file
, "-%d", -n
);
1488 fprintf (file
, "%d", n
);
1493 output_addr_const (file
, addr
);
1498 /* Output all insn addresses and their sizes into the assembly language
1499 output file. This is helpful for debugging whether the length attributes
1500 in the md file are correct. This is not meant to be a user selectable
1504 final_prescan_insn (insn
, operand
, num_operands
)
1508 /* This holds the last insn address. */
1509 static int last_insn_address
= 0;
1511 int uid
= INSN_UID (insn
);
1513 if (TARGET_RTL_DUMP
)
1515 fprintf (asm_out_file
, "\n****************");
1516 print_rtl (asm_out_file
, PATTERN (insn
));
1517 fprintf (asm_out_file
, "\n");
1520 if (TARGET_ADDRESSES
)
1522 fprintf (asm_out_file
, "; 0x%x %d\n", insn_addresses
[uid
],
1523 insn_addresses
[uid
] - last_insn_address
);
1524 last_insn_address
= insn_addresses
[uid
];
1528 /* Prepare for an SI sized move. */
1534 rtx src
= operands
[1];
1535 rtx dst
= operands
[0];
1536 if (!reload_in_progress
&& !reload_completed
)
1538 if (!register_operand (dst
, GET_MODE (dst
)))
1540 rtx tmp
= gen_reg_rtx (GET_MODE (dst
));
1541 emit_move_insn (tmp
, src
);
1548 /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
1549 Define the offset between two registers, one to be eliminated, and the other
1550 its replacement, at the start of a routine. */
1553 initial_offset (from
, to
)
1557 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
1558 offset
= UNITS_PER_WORD
+ frame_pointer_needed
* UNITS_PER_WORD
;
1563 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1564 if ((regs_ever_live
[regno
]
1565 && (!call_used_regs
[regno
] || regno
== FRAME_POINTER_REGNUM
)))
1566 offset
+= UNITS_PER_WORD
;
1568 /* See the comments for get_frame_size. We need to round it up to
1571 offset
+= ((get_frame_size () + STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
1572 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
1574 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
1575 offset
+= UNITS_PER_WORD
; /* Skip saved PC */
1580 /* Update the condition code from the insn. */
1583 notice_update_cc (body
, insn
)
1587 switch (get_attr_cc (insn
))
1590 /* Insn does not affect CC at all. */
1594 /* Insn does not change CC, but the 0'th operand has been changed. */
1595 if (cc_status
.value1
!= 0
1596 && reg_overlap_mentioned_p (recog_operand
[0], cc_status
.value1
))
1597 cc_status
.value1
= 0;
1601 /* Insn sets the Z,N flags of CC to recog_operand[0].
1602 The V flag is unusable. The C flag may or may not be known but
1603 that's ok because alter_cond will change tests to use EQ/NE. */
1605 cc_status
.flags
|= CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
;
1606 cc_status
.value1
= recog_operand
[0];
1610 /* Insn sets the Z,N,V flags of CC to recog_operand[0].
1611 The C flag may or may not be known but that's ok because
1612 alter_cond will change tests to use EQ/NE. */
1614 cc_status
.flags
|= CC_NO_CARRY
;
1615 cc_status
.value1
= recog_operand
[0];
1619 /* The insn is a compare instruction. */
1621 cc_status
.value1
= SET_SRC (body
);
1625 /* Insn doesn't leave CC in a usable state. */
1631 /* Recognize valid operators for bit instructions */
1634 bit_operator (x
, mode
)
1636 enum machine_mode mode
;
1638 enum rtx_code code
= GET_CODE (x
);
1647 We devote a fair bit of code to getting efficient shifts since we can only
1648 shift one bit at a time on the H8/300 and H8/300H and only one or two
1649 bits at a time on the H8/S.
1651 The basic shift methods:
1653 * loop shifts -- emit a loop using one (or two on H8/S) bit shifts;
1654 this is the default. SHIFT_LOOP
1656 * inlined shifts -- emit straight line code for the shift; this is
1657 used when a straight line shift is about the same size or smaller
1658 than a loop. We allow the inline version to be slightly longer in
1659 some cases as it saves a register. SHIFT_INLINE
1661 * rotate + and -- rotate the value the opposite direction, then
1662 mask off the values we don't need. This is used when only a few
1663 of the bits in the original value will survive in the shifted value.
1664 Again, this is used when it's about the same size or smaller than
1665 a loop. We allow this version to be slightly longer as it is usually
1666 much faster than a loop. SHIFT_ROT_AND
1668 * swap (+ shifts) -- often it's possible to swap bytes/words to
1669 simulate a shift by 8/16. Once swapped a few inline shifts can be
1670 added if the shift count is slightly more than 8 or 16. This is used
1671 when it's about the same size or smaller than a loop. We allow this
1672 version to be slightly longer as it is usually much faster than a loop.
1675 * There other oddballs. Not worth explaining. SHIFT_SPECIAL
1678 Here are some thoughts on what the absolutely positively best code is.
1679 "Best" here means some rational trade-off between code size and speed,
1680 where speed is more preferred but not at the expense of generating 20 insns.
1682 A trailing '*' after the shift count indicates the "best" mode isn't
1685 H8/300 QImode shifts
1686 1-4 - do them inline
1687 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1689 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1690 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1692 H8/300 HImode shifts
1693 1-4 - do them inline
1695 7 - shift 2nd half other way into carry.
1696 copy 1st half into 2nd half
1697 rotate 2nd half other way with carry
1698 rotate 1st half other way (no carry)
1699 mask off bits in 1st half (ASHIFT | LSHIFTRT).
1700 sign extend 1st half (ASHIFTRT)
1701 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1702 9-12 - do shift by 8, inline remaining shifts
1703 13-14* - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1705 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1706 - ASHIFTRT: shll, subx, set other byte
1708 H8/300 SImode shifts
1709 1-2 - do them inline
1711 7* - shift other way once, move bytes into place,
1712 move carry into place (possibly with sign extension)
1713 8 - move bytes into place, zero or sign extend other
1715 15* - shift other way once, move word into place, move carry into place
1716 16 - move word, zero or sign extend other
1718 24* - move bytes into place, zero or sign extend other
1720 28-30* - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,
1723 31 - ASHIFT | LSHIFTRT: rotate top byte, mask, byte byte into place,
1725 ASHIFTRT: shll top byte, subx, copy to other bytes
1727 H8/300H QImode shifts (same as H8/300 QImode shifts)
1728 1-4 - do them inline
1729 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1731 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1732 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1735 H8/300H HImode shifts
1736 1-4 - do them inline
1738 7 - shift 2nd half other way into carry.
1739 copy 1st half into 2nd half
1740 rotate entire word other way using carry
1741 mask off remaining bits (ASHIFT | LSHIFTRT)
1742 sign extend remaining bits (ASHIFTRT)
1743 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1744 9-12 - do shift by 8, inline remaining shifts
1745 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1747 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1748 - ASHIFTRT: shll, subx, set other byte
1750 H8/300H SImode shifts
1751 (These are complicated by the fact that we don't have byte level access to
1753 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1754 1-4 - do them inline
1756 15* - shift other way once, move word into place, move carry into place
1757 (with sign extension for ASHIFTRT)
1758 16 - move word into place, zero or sign extend other
1759 17-20 - do 16bit shift, then inline remaining shifts
1761 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1762 move word 0 to word 1, zero word 0
1763 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1764 zero word 1, zero byte 1
1765 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1766 sign extend byte 0, sign extend word 0
1767 25-27* - either loop, or
1768 do 24 bit shift, inline rest
1769 28-30 - ASHIFT: rotate 4/3/2, mask
1770 LSHIFTRT: rotate 4/3/2, mask
1772 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1775 1-6 - do them inline
1776 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1777 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1780 1-7 - do them inline
1781 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1782 9-12 - do shift by 8, inline remaining shifts
1783 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1785 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1786 - ASHIFTRT: shll, subx, set other byte
1789 (These are complicated by the fact that we don't have byte level access to
1791 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1792 1-10 - do them inline
1794 15* - shift other way once, move word into place, move carry into place
1795 (with sign extension for ASHIFTRT)
1796 16 - move word into place, zero or sign extend other
1797 17-20 - do 16bit shift, then inline remaining shifts
1799 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1800 move word 0 to word 1, zero word 0
1801 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1802 zero word 1, zero byte 1
1803 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1804 sign extend byte 0, sign extend word 0
1805 25-27* - either loop, or
1806 do 24 bit shift, inline rest
1807 28-30 - ASHIFT: rotate 4/3/2, mask
1808 LSHIFTRT: rotate 4/3/2, mask
1810 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1815 nshift_operator (x
, mode
)
1817 enum machine_mode mode
;
1819 switch (GET_CODE (x
))
1831 /* Called from the .md file to emit code to do shifts.
1832 Returns a boolean indicating success
1833 (currently this is always TRUE). */
1836 expand_a_shift (mode
, code
, operands
)
1837 enum machine_mode mode
;
1841 emit_move_insn (operands
[0], operands
[1]);
1843 /* need a loop to get all the bits we want - we generate the
1844 code at emit time, but need to allocate a scratch reg now */
1847 (PARALLEL
, VOIDmode
,
1849 gen_rtx (SET
, VOIDmode
, operands
[0],
1850 gen_rtx (code
, mode
, operands
[0], operands
[2])),
1851 gen_rtx (CLOBBER
, VOIDmode
, gen_rtx (SCRATCH
, QImode
, 0)))));
1856 /* Shift algorithm determination.
1858 There are various ways of doing a shift:
1859 SHIFT_INLINE: If the amount is small enough, just generate as many one-bit
1861 SHIFT_ROT_AND: If the amount is large but close to either end, rotate the
1862 necessary bits into position and then set the rest to zero.
1863 SHIFT_SPECIAL: Hand crafted assembler.
1864 SHIFT_LOOP: If the above methods fail, just loop. */
1875 /* Symbols of the various shifts which can be used as indices. */
1879 SHIFT_ASHIFT
, SHIFT_LSHIFTRT
, SHIFT_ASHIFTRT
1882 /* Symbols of the various modes which can be used as indices. */
1886 QIshift
, HIshift
, SIshift
1889 /* For single bit shift insns, record assembler and what bits of the
1890 condition code are valid afterwards (represented as various CC_FOO
1891 bits, 0 means CC isn't left in a usable state). */
1899 /* Assembler instruction shift table.
1901 These tables are used to look up the basic shifts.
1902 They are indexed by cpu, shift_type, and mode.
1905 static const struct shift_insn shift_one
[2][3][3] =
1911 { "shll\t%X0", CC_NO_CARRY
},
1912 { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1913 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }
1915 /* SHIFT_LSHIFTRT */
1917 { "shlr\t%X0", CC_NO_CARRY
},
1918 { "shlr\t%t0\n\trotxr\t%s0", 0 },
1919 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1921 /* SHIFT_ASHIFTRT */
1923 { "shar\t%X0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1924 { "shar\t%t0\n\trotxr\t%s0", 0 },
1925 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1932 { "shll.b\t%X0", CC_NO_CARRY
},
1933 { "shll.w\t%T0", CC_NO_CARRY
},
1934 { "shll.l\t%S0", CC_NO_CARRY
}
1936 /* SHIFT_LSHIFTRT */
1938 { "shlr.b\t%X0", CC_NO_CARRY
},
1939 { "shlr.w\t%T0", CC_NO_CARRY
},
1940 { "shlr.l\t%S0", CC_NO_CARRY
}
1942 /* SHIFT_ASHIFTRT */
1944 { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1945 { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1946 { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
}
1951 static const struct shift_insn shift_two
[3][3] =
1955 { "shll.b\t#2,%X0", CC_NO_CARRY
},
1956 { "shll.w\t#2,%T0", CC_NO_CARRY
},
1957 { "shll.l\t#2,%S0", CC_NO_CARRY
}
1959 /* SHIFT_LSHIFTRT */
1961 { "shlr.b\t#2,%X0", CC_NO_CARRY
},
1962 { "shlr.w\t#2,%T0", CC_NO_CARRY
},
1963 { "shlr.l\t#2,%S0", CC_NO_CARRY
}
1965 /* SHIFT_ASHIFTRT */
1967 { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1968 { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1969 { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
}
1973 /* Rotates are organized by which shift they'll be used in implementing.
1974 There's no need to record whether the cc is valid afterwards because
1975 it is the AND insn that will decide this. */
1977 static const char *const rotate_one
[2][3][3] =
1984 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
1987 /* SHIFT_LSHIFTRT */
1990 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
1993 /* SHIFT_ASHIFTRT */
1996 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
2008 /* SHIFT_LSHIFTRT */
2014 /* SHIFT_ASHIFTRT */
2023 static const char *const rotate_two
[3][3] =
2031 /* SHIFT_LSHIFTRT */
2037 /* SHIFT_ASHIFTRT */
2045 /* Given CPU, MODE, SHIFT_TYPE, and shift count COUNT, determine the best
2046 algorithm for doing the shift. The assembler code is stored in ASSEMBLER.
2047 We don't achieve maximum efficiency in all cases, but the hooks are here
2050 For now we just use lots of switch statements. Since we don't even come
2051 close to supporting all the cases, this is simplest. If this function ever
2052 gets too big, perhaps resort to a more table based lookup. Of course,
2053 at this point you may just wish to do it all in rtl.
2055 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
2056 1,2,3,4 will be inlined (1,2 for SI). */
2058 static enum shift_alg
2059 get_shift_alg (cpu
, shift_type
, mode
, count
, assembler_p
,
2060 assembler2_p
, cc_valid_p
)
2062 enum shift_type shift_type
;
2063 enum machine_mode mode
;
2065 const char **assembler_p
;
2066 const char **assembler2_p
;
2069 /* The default is to loop. */
2070 enum shift_alg alg
= SHIFT_LOOP
;
2071 enum shift_mode shift_mode
;
2073 /* We don't handle negative shifts or shifts greater than the word size,
2074 they should have been handled already. */
2076 if (count
< 0 || count
> GET_MODE_BITSIZE (mode
))
2082 shift_mode
= QIshift
;
2085 shift_mode
= HIshift
;
2088 shift_mode
= SIshift
;
2094 /* Assume either SHIFT_LOOP or SHIFT_INLINE.
2095 It is up to the caller to know that looping clobbers cc. */
2096 *assembler_p
= shift_one
[cpu
][shift_type
][shift_mode
].assembler
;
2098 *assembler2_p
= shift_two
[shift_type
][shift_mode
].assembler
;
2100 *assembler2_p
= NULL
;
2101 *cc_valid_p
= shift_one
[cpu
][shift_type
][shift_mode
].cc_valid
;
2103 /* Now look for cases we want to optimize. */
2109 return SHIFT_INLINE
;
2112 /* Shift by 5/6 are only 3 insns on the H8/S, so it's just as
2113 fast as SHIFT_ROT_AND, plus CC is valid. */
2114 if (TARGET_H8300S
&& count
<= 6)
2115 return SHIFT_INLINE
;
2117 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2118 through the entire value. */
2119 if (shift_type
== SHIFT_ASHIFTRT
&& count
== 7)
2121 *assembler_p
= "shll\t%X0\n\tsubx\t%X0,%X0";
2123 return SHIFT_SPECIAL
;
2126 /* Other ASHIFTRTs are too much of a pain. */
2127 if (shift_type
== SHIFT_ASHIFTRT
)
2130 /* Other shifts by 5, 6, or 7 bits use SHIFT_ROT_AND. */
2131 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2133 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2135 return SHIFT_ROT_AND
;
2140 return SHIFT_INLINE
;
2141 else if (TARGET_H8300S
&& count
<= 7)
2142 return SHIFT_INLINE
;
2143 else if (count
== 7)
2145 if (shift_type
== SHIFT_ASHIFT
&& TARGET_H8300
)
2147 *assembler_p
= "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.b\t%t0\n\trotr.b\t%s0\n\tand.b\t#0x80,%s0";
2149 return SHIFT_SPECIAL
;
2152 if (shift_type
== SHIFT_ASHIFT
&& TARGET_H8300H
)
2154 *assembler_p
= "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
2156 return SHIFT_SPECIAL
;
2159 if (shift_type
== SHIFT_LSHIFTRT
&& TARGET_H8300
)
2161 *assembler_p
= "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\trotl.b\t%t0\n\tand.b\t#0x01,%t0";
2163 return SHIFT_SPECIAL
;
2166 if (shift_type
== SHIFT_LSHIFTRT
&& TARGET_H8300H
)
2168 *assembler_p
= "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
2170 return SHIFT_SPECIAL
;
2173 if (shift_type
== SHIFT_ASHIFTRT
)
2175 *assembler_p
= "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
2177 return SHIFT_SPECIAL
;
2180 else if (count
== 8)
2185 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
2187 return SHIFT_SPECIAL
;
2188 case SHIFT_LSHIFTRT
:
2189 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
2191 return SHIFT_SPECIAL
;
2192 case SHIFT_ASHIFTRT
:
2194 *assembler_p
= "mov.b\t%t0,%s0\n\tshll\t%t0\n\tsubx\t%t0,%t0\t";
2196 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0";
2198 return SHIFT_SPECIAL
;
2201 else if (count
== 9)
2206 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0";
2208 return SHIFT_SPECIAL
;
2209 case SHIFT_LSHIFTRT
:
2210 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0";
2212 return SHIFT_SPECIAL
;
2213 case SHIFT_ASHIFTRT
:
2215 *assembler_p
= "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0";
2217 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0";
2219 return SHIFT_SPECIAL
;
2222 else if (count
== 10)
2228 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\t";
2230 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0\n\tshal.b\t%t0";
2232 return SHIFT_SPECIAL
;
2233 case SHIFT_LSHIFTRT
:
2235 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0";
2237 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0\n\tshlr.b\t%s0";
2239 return SHIFT_SPECIAL
;
2240 case SHIFT_ASHIFTRT
:
2242 *assembler_p
= "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0\n\tshar.b\t%s0";
2243 else if (TARGET_H8300H
)
2244 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0\n\tshar.b\t%s0";
2245 else if (TARGET_H8300S
)
2246 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t#2,%s0";
2248 return SHIFT_SPECIAL
;
2251 else if (count
== 11)
2257 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\tshal.b\t%t0";
2259 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0\n\tshal.b\t%t0\n\tshal.b\t%t0";
2261 return SHIFT_SPECIAL
;
2262 case SHIFT_LSHIFTRT
:
2264 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0\n\tshlr.b\t%s0";
2266 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0\n\tshlr.b\t%s0\n\tshlr.b\t%s0";
2268 return SHIFT_SPECIAL
;
2269 case SHIFT_ASHIFTRT
:
2271 *assembler_p
= "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0";
2272 else if (TARGET_H8300H
)
2273 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0";
2274 else if (TARGET_H8300S
)
2275 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t#2,%s0\n\tshar.b\t%s0";
2277 return SHIFT_SPECIAL
;
2280 else if (count
== 12)
2286 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\tshal.b\t#2,%t0";
2288 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0\n\tshal.b\t%t0\n\tshal.b\t%t0\n\tshal.b\t%t0";
2290 return SHIFT_SPECIAL
;
2291 case SHIFT_LSHIFTRT
:
2293 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0\n\tshlr.b\t#2,%s0";
2295 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0\n\tshlr.b\t%s0\n\tshlr.b\t%s0\n\tshlr.b\t%s0";
2297 return SHIFT_SPECIAL
;
2298 case SHIFT_ASHIFTRT
:
2300 *assembler_p
= "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0";
2301 else if (TARGET_H8300H
)
2302 *assembler_p
= "mov.b\t%t0,%s0\n\textw.w\t%T0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0";
2303 else if (TARGET_H8300S
)
2304 *assembler_p
= "mov.b\t%t0,%s0\n\textw.w\t%T0\n\tshar.b\t#2,%s0\n\tshar.b\t#2,%s0";
2306 return SHIFT_SPECIAL
;
2309 else if (!TARGET_H8300
&& (count
== 13 || count
== 14)
2312 if (count
== 15 && shift_type
== SHIFT_ASHIFTRT
)
2314 *assembler_p
= "shll\t%t0,%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
2316 return SHIFT_SPECIAL
;
2318 else if (shift_type
!= SHIFT_ASHIFTRT
)
2320 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2322 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2324 *assembler2_p
= NULL
;
2326 return SHIFT_ROT_AND
;
2332 if (count
<= (TARGET_H8300
? 2 : 4))
2333 return SHIFT_INLINE
;
2334 else if (TARGET_H8300S
&& count
<= 10)
2335 return SHIFT_INLINE
;
2336 else if (count
== 8 && TARGET_H8300
)
2341 *assembler_p
= "mov.b\t%y0,%z0n\tmov.b\t%x0,%y0\n\tmov.b\t%w0,%x0\n\tsub.b\t%w0,%w0";
2343 return SHIFT_SPECIAL
;
2344 case SHIFT_LSHIFTRT
:
2345 *assembler_p
= "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tsub.b\t%z0,%z0";
2347 return SHIFT_SPECIAL
;
2348 case SHIFT_ASHIFTRT
:
2349 *assembler_p
= "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tshll\t%z0\n\tsubx\t%z0,%z0";
2351 return SHIFT_SPECIAL
;
2354 else if (count
== 16)
2359 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2361 return SHIFT_SPECIAL
;
2362 case SHIFT_LSHIFTRT
:
2363 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
2365 return SHIFT_SPECIAL
;
2366 case SHIFT_ASHIFTRT
:
2368 *assembler_p
= "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2370 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0";
2372 return SHIFT_SPECIAL
;
2375 else if (count
== 17 && !TARGET_H8300
)
2380 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0";
2382 return SHIFT_SPECIAL
;
2383 case SHIFT_LSHIFTRT
:
2384 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0";
2386 return SHIFT_SPECIAL
;
2387 case SHIFT_ASHIFTRT
:
2388 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0";
2390 return SHIFT_SPECIAL
;
2393 else if (count
== 18 && !TARGET_H8300
)
2399 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0";
2401 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0\n\tshll.l\t%S0";
2403 return SHIFT_SPECIAL
;
2404 case SHIFT_LSHIFTRT
:
2406 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0";
2408 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0\n\tshlr.l\t%S0";
2410 return SHIFT_SPECIAL
;
2411 case SHIFT_ASHIFTRT
:
2413 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0";
2415 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0\n\tshar.l\t%S0";
2417 return SHIFT_SPECIAL
;
2420 else if (count
== 19 && !TARGET_H8300
)
2426 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0\n\tshll.l\t%S0";
2428 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0\n\tshll.l\t%S0\n\tshll.l\t%S0";
2430 return SHIFT_SPECIAL
;
2431 case SHIFT_LSHIFTRT
:
2433 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0\n\tshlr.l\t%S0";
2435 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0\n\tshlr.l\t%S0\n\tshlr.l\t%S0";
2437 return SHIFT_SPECIAL
;
2438 case SHIFT_ASHIFTRT
:
2440 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0\n\tshar.l\t%S0";
2442 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0\n\tshar.l\t%S0\n\tshar.l\t%S0";
2444 return SHIFT_SPECIAL
;
2447 else if (count
== 20 && TARGET_H8300S
)
2452 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0\n\tshll.l\t#2,%S0";
2454 return SHIFT_SPECIAL
;
2455 case SHIFT_LSHIFTRT
:
2456 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0\n\tshlr.l\t#2,%S0";
2458 return SHIFT_SPECIAL
;
2459 case SHIFT_ASHIFTRT
:
2460 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0\n\tshar.l\t#2,%S0";
2462 return SHIFT_SPECIAL
;
2465 else if (count
>= 28 && count
<= 30 && !TARGET_H8300
)
2467 if (shift_type
== SHIFT_ASHIFTRT
)
2473 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2475 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2477 *assembler2_p
= NULL
;
2479 return SHIFT_ROT_AND
;
2482 else if (count
== 31)
2484 if (shift_type
== SHIFT_ASHIFTRT
)
2487 *assembler_p
= "shll\t%z0\n\tsubx %w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2489 *assembler_p
= "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2491 return SHIFT_SPECIAL
;
2497 if (shift_type
== SHIFT_ASHIFT
)
2498 *assembler_p
= "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2500 *assembler_p
= "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2502 return SHIFT_SPECIAL
;
2506 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2508 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2510 *assembler2_p
= NULL
;
2512 return SHIFT_ROT_AND
;
2525 /* Emit the assembler code for doing shifts. */
2528 emit_a_shift (insn
, operands
)
2532 static int loopend_lab
;
2536 rtx inside
= PATTERN (insn
);
2537 rtx shift
= operands
[3];
2538 enum machine_mode mode
= GET_MODE (shift
);
2539 enum rtx_code code
= GET_CODE (shift
);
2540 enum shift_type shift_type
;
2541 enum shift_mode shift_mode
;
2548 shift_mode
= QIshift
;
2551 shift_mode
= HIshift
;
2554 shift_mode
= SIshift
;
2563 shift_type
= SHIFT_ASHIFTRT
;
2566 shift_type
= SHIFT_LSHIFTRT
;
2569 shift_type
= SHIFT_ASHIFT
;
2575 if (GET_CODE (operands
[2]) != CONST_INT
)
2577 /* Indexing by reg, so have to loop and test at top */
2578 output_asm_insn ("mov.b %X2,%X4", operands
);
2579 fprintf (asm_out_file
, "\tble .Lle%d\n", loopend_lab
);
2581 /* Get the assembler code to do one shift. */
2582 get_shift_alg (cpu_type
, shift_type
, mode
, 1, &assembler
,
2583 &assembler2
, &cc_valid
);
2587 int n
= INTVAL (operands
[2]);
2590 /* If the count is negative, make it 0. */
2593 /* If the count is too big, truncate it.
2594 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2595 do the intuitive thing. */
2596 else if (n
> GET_MODE_BITSIZE (mode
))
2597 n
= GET_MODE_BITSIZE (mode
);
2599 alg
= get_shift_alg (cpu_type
, shift_type
, mode
, n
, &assembler
,
2600 &assembler2
, &cc_valid
);
2605 /* Emit two bit shifts first. */
2606 while (n
> 1 && assembler2
!= NULL
)
2608 output_asm_insn (assembler2
, operands
);
2612 /* Now emit one bit shifts for any residual. */
2615 output_asm_insn (assembler
, operands
);
2619 /* Keep track of CC. */
2622 cc_status
.value1
= operands
[0];
2623 cc_status
.flags
|= cc_valid
;
2629 int m
= GET_MODE_BITSIZE (mode
) - n
;
2630 int mask
= (shift_type
== SHIFT_ASHIFT
2631 ? ((1 << GET_MODE_BITSIZE (mode
) - n
) - 1) << n
2632 : (1 << GET_MODE_BITSIZE (mode
) - n
) - 1);
2634 /* Not all possibilities of rotate are supported. They shouldn't
2635 be generated, but let's watch for 'em. */
2639 /* Emit two bit rotates first. */
2640 while (m
> 1 && assembler2
!= NULL
)
2642 output_asm_insn (assembler2
, operands
);
2646 /* Now single bit rotates for any residual. */
2649 output_asm_insn (assembler
, operands
);
2653 /* Now mask off the high bits. */
2659 sprintf (insn_buf
, "and #%d,%%X0",
2661 cc_status
.value1
= operands
[0];
2662 cc_status
.flags
|= CC_NO_CARRY
;
2665 sprintf (insn_buf
, "and #%d,%%s0\n\tand #%d,%%t0",
2666 mask
& 255, mask
>> 8, n
);
2674 sprintf (insn_buf
, "and.%c #%d,%%%c0",
2675 "bwl"[shift_mode
], mask
,
2676 mode
== QImode
? 'X' : mode
== HImode
? 'T' : 'S');
2677 cc_status
.value1
= operands
[0];
2678 cc_status
.flags
|= CC_NO_CARRY
;
2680 output_asm_insn (insn_buf
, operands
);
2684 output_asm_insn (assembler
, operands
);
2688 /* A loop to shift by a "large" constant value.
2689 If we have shift-by-2 insns, use them. */
2690 if (assembler2
!= NULL
)
2692 fprintf (asm_out_file
, "\tmov.b #%d,%sl\n", n
/ 2,
2693 names_big
[REGNO (operands
[4])]);
2694 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
2695 output_asm_insn (assembler2
, operands
);
2696 output_asm_insn ("add #0xff,%X4", operands
);
2697 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
2699 output_asm_insn (assembler
, operands
);
2704 fprintf (asm_out_file
, "\tmov.b #%d,%sl\n", n
,
2705 names_big
[REGNO (operands
[4])]);
2706 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
2707 output_asm_insn (assembler
, operands
);
2708 output_asm_insn ("add #0xff,%X4", operands
);
2709 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
2714 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
2715 output_asm_insn (assembler
, operands
);
2716 output_asm_insn ("add #0xff,%X4", operands
);
2717 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
2718 fprintf (asm_out_file
, ".Lle%d:\n", loopend_lab
);
2723 /* Fix the operands of a gen_xxx so that it could become a bit
2727 fix_bit_operand (operands
, what
, type
)
2732 /* The bit_operand predicate accepts any memory during RTL generation, but
2733 only 'U' memory afterwards, so if this is a MEM operand, we must force
2734 it to be valid for 'U' by reloading the address. */
2736 if (GET_CODE (operands
[2]) == CONST_INT
)
2738 if (CONST_OK_FOR_LETTER_P (INTVAL (operands
[2]), what
))
2740 /* Ok to have a memory dest. */
2741 if (GET_CODE (operands
[0]) == MEM
&& !EXTRA_CONSTRAINT (operands
[0], 'U'))
2744 mem
= gen_rtx (MEM
, GET_MODE (operands
[0]),
2745 copy_to_mode_reg (Pmode
, XEXP (operands
[0], 0)));
2746 RTX_UNCHANGING_P (mem
) = RTX_UNCHANGING_P (operands
[0]);
2747 MEM_IN_STRUCT_P (mem
) = MEM_IN_STRUCT_P (operands
[0]);
2748 MEM_VOLATILE_P (mem
) = MEM_VOLATILE_P (operands
[0]);
2752 if (GET_CODE (operands
[1]) == MEM
&& !EXTRA_CONSTRAINT (operands
[1], 'U'))
2755 mem
= gen_rtx (MEM
, GET_MODE (operands
[1]),
2756 copy_to_mode_reg (Pmode
, XEXP (operands
[1], 0)));
2757 RTX_UNCHANGING_P (mem
) = RTX_UNCHANGING_P (operands
[1]);
2758 MEM_IN_STRUCT_P (mem
) = MEM_IN_STRUCT_P (operands
[1]);
2759 MEM_VOLATILE_P (mem
) = MEM_VOLATILE_P (operands
[1]);
2766 /* Dest and src op must be register. */
2768 operands
[1] = force_reg (QImode
, operands
[1]);
2770 rtx res
= gen_reg_rtx (QImode
);
2771 emit_insn (gen_rtx (SET
, VOIDmode
, res
, gen_rtx (type
, QImode
, operands
[1], operands
[2])));
2772 emit_insn (gen_rtx (SET
, VOIDmode
, operands
[0], res
));
2777 /* Return nonzero if FUNC is an interrupt function as specified
2778 by the "interrupt" attribute. */
2781 h8300_interrupt_function_p (func
)
2786 if (TREE_CODE (func
) != FUNCTION_DECL
)
2789 a
= lookup_attribute ("interrupt_handler", DECL_MACHINE_ATTRIBUTES (func
));
2790 return a
!= NULL_TREE
;
2793 /* Return nonzero if FUNC is an OS_Task function as specified
2794 by the "OS_Task" attribute. */
2797 h8300_os_task_function_p (func
)
2802 if (TREE_CODE (func
) != FUNCTION_DECL
)
2805 a
= lookup_attribute ("OS_Task", DECL_MACHINE_ATTRIBUTES (func
));
2806 return a
!= NULL_TREE
;
2809 /* Return nonzero if FUNC is a monitor function as specified
2810 by the "monitor" attribute. */
2813 h8300_monitor_function_p (func
)
2818 if (TREE_CODE (func
) != FUNCTION_DECL
)
2821 a
= lookup_attribute ("monitor", DECL_MACHINE_ATTRIBUTES (func
));
2822 return a
!= NULL_TREE
;
2825 /* Return nonzero if FUNC is a function that should be called
2826 through the function vector. */
2829 h8300_funcvec_function_p (func
)
2834 if (TREE_CODE (func
) != FUNCTION_DECL
)
2837 a
= lookup_attribute ("function_vector", DECL_MACHINE_ATTRIBUTES (func
));
2838 return a
!= NULL_TREE
;
2841 /* Return nonzero if DECL is a variable that's in the eight bit
2845 h8300_eightbit_data_p (decl
)
2850 if (TREE_CODE (decl
) != VAR_DECL
)
2853 a
= lookup_attribute ("eightbit_data", DECL_MACHINE_ATTRIBUTES (decl
));
2854 return a
!= NULL_TREE
;
2857 /* Return nonzero if DECL is a variable that's in the tiny
2861 h8300_tiny_data_p (decl
)
2866 if (TREE_CODE (decl
) != VAR_DECL
)
2869 a
= lookup_attribute ("tiny_data", DECL_MACHINE_ATTRIBUTES (decl
));
2870 return a
!= NULL_TREE
;
2873 /* Return nonzero if ATTR is a valid attribute for DECL.
2874 ATTRIBUTES are any existing attributes and ARGS are the arguments
2877 Supported attributes:
2879 interrupt_handler: output a prologue and epilogue suitable for an
2882 function_vector: This function should be called through the
2885 eightbit_data: This variable lives in the 8-bit data area and can
2886 be referenced with 8-bit absolute memory addresses.
2888 tiny_data: This variable lives in the tiny data area and can be
2889 referenced with 16-bit absolute memory references. */
2892 h8300_valid_machine_decl_attribute (decl
, attributes
, attr
, args
)
2898 if (args
!= NULL_TREE
)
2901 if (is_attribute_p ("interrupt_handler", attr
)
2902 || is_attribute_p ("OS_Task", attr
)
2903 || is_attribute_p ("monitor", attr
)
2904 || is_attribute_p ("function_vector", attr
))
2905 return TREE_CODE (decl
) == FUNCTION_DECL
;
2907 if (is_attribute_p ("eightbit_data", attr
)
2908 && (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
)))
2910 if (DECL_INITIAL (decl
) == NULL_TREE
)
2912 warning ("Only initialized variables can be placed into the 8-bit area.");
2915 DECL_SECTION_NAME (decl
) = build_string (7, ".eight");
2919 if (is_attribute_p ("tiny_data", attr
)
2920 && (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
)))
2922 if (DECL_INITIAL (decl
) == NULL_TREE
)
2924 warning ("Only initialized variables can be placed into the 8-bit area.");
2927 DECL_SECTION_NAME (decl
) = build_string (6, ".tiny");
2934 extern struct obstack
*saveable_obstack
;
2936 h8300_encode_label (decl
)
2939 char *str
= XSTR (XEXP (DECL_RTL (decl
), 0), 0);
2940 int len
= strlen (str
);
2943 newstr
= obstack_alloc (saveable_obstack
, len
+ 2);
2945 strcpy (newstr
+ 1, str
);
2947 XSTR (XEXP (DECL_RTL (decl
), 0), 0) = newstr
;
2951 output_simode_bld (bild
, log2
, operands
)
2956 /* Clear the destination register. */
2957 if (TARGET_H8300H
|| TARGET_H8300S
)
2958 output_asm_insn ("sub.l\t%S0,%S0", operands
);
2960 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands
);
2962 /* Get the bit number we want to load. */
2964 operands
[2] = GEN_INT (exact_log2 (INTVAL (operands
[2])));
2966 /* Now output the bit load or bit inverse load, and store it in
2969 output_asm_insn ("bild\t%Z2,%Y1\n\tbst\t#0,%w0", operands
);
2971 output_asm_insn ("bld\t%Z2,%Y1\n\tbst\t#0,%w0", operands
);
2977 /* Given INSN and it's current length LENGTH, return the adjustment
2978 (in bytes) to correctly compute INSN's length.
2980 We use this to get the lengths of various memory references correct. */
2982 h8300_adjust_insn_length (insn
, length
)
2986 rtx pat
= PATTERN (insn
);
2988 /* Adjust length for reg->mem and mem->reg copies. */
2989 if (GET_CODE (pat
) == SET
2990 && (GET_CODE (SET_SRC (pat
)) == MEM
2991 || GET_CODE (SET_DEST (pat
)) == MEM
))
2993 /* This insn might need a length adjustment. */
2996 if (GET_CODE (SET_SRC (pat
)) == MEM
)
2997 addr
= XEXP (SET_SRC (pat
), 0);
2999 addr
= XEXP (SET_DEST (pat
), 0);
3001 /* On the H8/300, only one adjustment is necessary; if the
3002 address mode is register indirect, then this insn is two
3003 bytes shorter than indicated in the machine description. */
3004 if (TARGET_H8300
&& GET_CODE (addr
) == REG
)
3007 /* On the H8/300H and H8/S, register indirect is 6 bytes shorter than
3008 indicated in the machine description. */
3009 if ((TARGET_H8300H
|| TARGET_H8300S
)
3010 && GET_CODE (addr
) == REG
)
3013 /* On the H8/300H and H8/300S, reg + d, for small displacements is 4
3014 bytes shorter than indicated in the machine description. */
3015 if ((TARGET_H8300H
|| TARGET_H8300S
)
3016 && GET_CODE (addr
) == PLUS
3017 && GET_CODE (XEXP (addr
, 0)) == REG
3018 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
3019 && INTVAL (XEXP (addr
, 1)) > -32768
3020 && INTVAL (XEXP (addr
, 1)) < 32767)
3023 /* On the H8/300H and H8/300S, abs:16 is two bytes shorter than the
3024 more general abs:24. */
3025 if ((TARGET_H8300H
|| TARGET_H8300S
)
3026 && GET_CODE (addr
) == SYMBOL_REF
3027 && TINY_DATA_NAME_P (XSTR (addr
, 0)))
3031 /* Loading some constants needs adjustment. */
3032 if (GET_CODE (pat
) == SET
3033 && GET_CODE (SET_SRC (pat
)) == CONST_INT
3034 && GET_MODE (SET_DEST (pat
)) == SImode
3035 && INTVAL (SET_SRC (pat
)) != 0)
3038 && ((INTVAL (SET_SRC (pat
)) & 0xffff) == 0
3039 || ((INTVAL (SET_SRC (pat
)) >> 16) & 0xffff) == 0))
3042 if (TARGET_H8300H
|| TARGET_H8300S
)
3044 int val
= INTVAL (SET_SRC (pat
));
3046 if (val
== (val
& 0xff)
3047 || val
== (val
& 0xff00))
3050 if (val
== -4 || val
== -2 || val
== -1)
3055 /* Shifts need various adjustments. */
3056 if (GET_CODE (pat
) == PARALLEL
3057 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
3058 && (GET_CODE (SET_SRC (XVECEXP (pat
, 0, 0))) == ASHIFTRT
3059 || GET_CODE (SET_SRC (XVECEXP (pat
, 0, 0))) == LSHIFTRT
3060 || GET_CODE (SET_SRC (XVECEXP (pat
, 0, 0))) == ASHIFT
))
3062 rtx src
= SET_SRC (XVECEXP (pat
, 0, 0));
3063 enum machine_mode mode
= GET_MODE (src
);
3065 if (GET_CODE (XEXP (src
, 1)) != CONST_INT
)
3068 /* QImode shifts by small constants take one insn
3069 per shift. So the adjustment is 20 (md length) -
3071 if (mode
== QImode
&& INTVAL (XEXP (src
, 1)) <= 4)
3072 return -(20 - INTVAL (XEXP (src
, 1)) * 2);
3074 /* Similarly for HImode and SImode shifts by
3075 small constants on the H8/300H and H8/300S. */
3076 if ((TARGET_H8300H
|| TARGET_H8300S
)
3077 && (mode
== HImode
|| mode
== SImode
)
3078 && INTVAL (XEXP (src
, 1)) <= 4)
3079 return -(20 - INTVAL (XEXP (src
, 1)) * 2);
3081 /* HImode shifts by small constants for the H8/300. */
3083 && INTVAL (XEXP (src
, 1)) <= 4)
3084 return -(20 - (INTVAL (XEXP (src
, 1))
3085 * (GET_CODE (src
) == ASHIFT
? 2 : 4)));
3087 /* SImode shifts by small constants for the H8/300. */
3089 && INTVAL (XEXP (src
, 1)) <= 2)
3090 return -(20 - (INTVAL (XEXP (src
, 1))
3091 * (GET_CODE (src
) == ASHIFT
? 6 : 8)));
3093 /* XXX ??? Could check for more shift/rotate cases here. */