1 /* Subroutines for insn-output.c for Hitachi H8/300.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002 Free Software Foundation, Inc.
4 Contributed by Steve Chamberlain (sac@cygnus.com),
5 Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
7 This file is part of GNU CC.
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING. If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
34 #include "insn-attr.h"
44 #include "target-def.h"
46 /* Forward declarations. */
47 static int h8300_interrupt_function_p PARAMS ((tree));
48 static int h8300_monitor_function_p PARAMS ((tree));
49 static int h8300_os_task_function_p PARAMS ((tree));
50 static void dosize PARAMS ((FILE *, const char *, unsigned int));
51 static int round_frame_size PARAMS ((int));
52 static unsigned int compute_saved_regs PARAMS ((void));
53 static void push PARAMS ((FILE *, int));
54 static void pop PARAMS ((FILE *, int));
55 static const char *cond_string PARAMS ((enum rtx_code));
56 const struct attribute_spec h8300_attribute_table[];
57 static tree h8300_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
58 static tree h8300_handle_eightbit_data_attribute PARAMS ((tree *, tree, tree, int, bool *));
59 static tree h8300_handle_tiny_data_attribute PARAMS ((tree *, tree, tree, int, bool *));
60 static void h8300_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
61 static void h8300_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
62 #ifndef OBJECT_FORMAT_ELF
63 static void h8300_asm_named_section PARAMS ((const char *, unsigned int));
66 /* CPU_TYPE, says what cpu we're compiling for. */
69 /* True if the current function is an interrupt handler
70 (either via #pragma or an attribute specification). */
71 static int interrupt_handler;
73 /* True if the current function is an OS Task
74 (via an attribute specification). */
77 /* True if the current function is a monitor
78 (via an attribute specification). */
81 /* True if a #pragma saveall has been seen for the current function. */
82 static int pragma_saveall;
84 static const char *const names_big[] =
85 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" };
87 static const char *const names_extended[] =
88 { "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" };
90 static const char *const names_upper_extended[] =
91 { "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7" };
93 /* Points to one of the above. */
94 /* ??? The above could be put in an array indexed by CPU_TYPE. */
95 const char * const *h8_reg_names;
97 /* Various operations needed by the following, indexed by CPU_TYPE. */
99 const char *h8_push_op, *h8_pop_op, *h8_mov_op;
101 /* Initialize the GCC target structure. */
102 #undef TARGET_ATTRIBUTE_TABLE
103 #define TARGET_ATTRIBUTE_TABLE h8300_attribute_table
105 #undef TARGET_ASM_ALIGNED_HI_OP
106 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
108 #undef TARGET_ASM_FUNCTION_PROLOGUE
109 #define TARGET_ASM_FUNCTION_PROLOGUE h8300_output_function_prologue
110 #undef TARGET_ASM_FUNCTION_EPILOGUE
111 #define TARGET_ASM_FUNCTION_EPILOGUE h8300_output_function_epilogue
113 struct gcc_target targetm = TARGET_INITIALIZER;
115 /* Initialize various cpu specific globals at start up. */
120 static const char *const h8_push_ops[2] = { "push" , "push.l" };
121 static const char *const h8_pop_ops[2] = { "pop" , "pop.l" };
122 static const char *const h8_mov_ops[2] = { "mov.w", "mov.l" };
126 cpu_type = (int) CPU_H8300;
127 h8_reg_names = names_big;
131 /* For this we treat the H8/300H and H8/S the same. */
132 cpu_type = (int) CPU_H8300H;
133 h8_reg_names = names_extended;
135 h8_push_op = h8_push_ops[cpu_type];
136 h8_pop_op = h8_pop_ops[cpu_type];
137 h8_mov_op = h8_mov_ops[cpu_type];
139 if (!TARGET_H8300S && TARGET_MAC)
141 error ("-ms2600 is used without -ms");
151 static const char *const names_small[] = {
152 "r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
153 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h"
156 return names_small[REGNO (x) * 2 + b];
159 /* REGNO must be saved/restored across calls if this macro is true. */
161 #define WORD_REG_USED(regno) \
163 /* No need to save registers if this function will not return. */ \
164 && ! TREE_THIS_VOLATILE (current_function_decl) \
166 /* Save any call saved register that was used. */ \
167 || (regs_ever_live[regno] && !call_used_regs[regno]) \
168 /* Save the frame pointer if it was used. */ \
169 || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno]) \
170 /* Save any register used in an interrupt handler. */ \
171 || (interrupt_handler && regs_ever_live[regno]) \
172 /* Save call clobbered registers in non-leaf interrupt \
174 || (interrupt_handler \
175 && call_used_regs[regno] \
176 && !current_function_is_leaf)))
178 /* Output assembly language to FILE for the operation OP with operand size
179 SIZE to adjust the stack pointer. */
182 dosize (file, op, size)
187 /* On the H8/300H and H8/S, for sizes <= 8 bytes, it is as good or
188 better to use adds/subs insns rather than add.l/sub.l with an
191 Also, on the H8/300, if we don't have a temporary to hold the
192 size of the frame in the prologue, we simply emit a sequence of
193 subs since this shouldn't happen often. */
194 if ((TARGET_H8300 && size <= 4)
195 || ((TARGET_H8300H || TARGET_H8300S) && size <= 8)
196 || (TARGET_H8300 && interrupt_handler)
197 || (TARGET_H8300 && current_function_needs_context
198 && ! strcmp (op, "sub")))
200 unsigned HOST_WIDE_INT amount;
202 /* Try different amounts in descending order. */
203 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
207 for (; size >= amount; size -= amount)
208 fprintf (file, "\t%ss\t#%d,sp\n", op, amount);
214 fprintf (file, "\tmov.w\t#%d,r3\n\t%s.w\tr3,sp\n", size, op);
216 fprintf (file, "\t%s.l\t#%d,sp\n", op, size);
220 /* Round up frame size SIZE. */
223 round_frame_size (size)
226 return (size + STACK_BOUNDARY / 8 - 1) & -STACK_BOUNDARY / 8;
229 /* Compute which registers to push/pop.
230 Return a bit vector of registers. */
233 compute_saved_regs ()
235 unsigned int saved_regs = 0;
238 /* Construct a bit vector of registers to be pushed/popped. */
239 for (regno = 0; regno <= 6; regno++)
241 if (WORD_REG_USED (regno))
242 saved_regs |= 1 << regno;
245 /* Don't push/pop the frame pointer as it is treated separately. */
246 if (frame_pointer_needed)
247 saved_regs &= ~(1 << FRAME_POINTER_REGNUM);
252 /* Output assembly language code to push register RN. */
259 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[rn]);
262 /* Output assembly language code to pop register RN. */
269 fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[rn]);
272 /* This is what the stack looks like after the prolog of
273 a function with a frame has been set up:
279 <saved registers> <- sp
281 This is what the stack looks like after the prolog of
282 a function which doesn't have a frame:
287 <saved registers> <- sp
290 /* Output assembly language code for the function prologue. */
293 h8300_output_function_prologue (file, size)
297 int fsize = round_frame_size (size);
302 /* Note a function with the interrupt attribute and set interrupt_handler
304 if (h8300_interrupt_function_p (current_function_decl))
305 interrupt_handler = 1;
307 /* If the current function has the OS_Task attribute set, then
308 we have a naked prologue. */
309 if (h8300_os_task_function_p (current_function_decl))
311 fprintf (file, ";OS_Task prologue\n");
316 if (h8300_monitor_function_p (current_function_decl))
318 /* My understanding of monitor functions is they act just
319 like interrupt functions, except the prologue must
321 fprintf (file, ";monitor prologue\n");
322 interrupt_handler = 1;
326 fprintf (file, "\tsubs\t#2,sp\n");
328 fprintf (file, "\tstc\tccr,r0l\n");
329 fprintf (file, "\tmov.b\tr0l,@(2,sp)\n");
331 fprintf (file, "\torc\t#128,ccr\n");
333 else if (TARGET_H8300H)
336 fprintf (file, "\tstc\tccr,r0l\n");
337 fprintf (file, "\tmov.b\tr0l,@(4,sp)\n");
339 fprintf (file, "\torc\t#128,ccr\n");
341 else if (TARGET_H8300S)
343 fprintf (file, "\tstc\texr,@-sp\n");
345 fprintf (file, "\tstc\tccr,r0l\n");
346 fprintf (file, "\tmov.b\tr0l,@(6,sp)\n");
348 fprintf (file, "\torc\t#128,ccr\n");
354 if (frame_pointer_needed)
357 push (file, FRAME_POINTER_REGNUM);
358 fprintf (file, "\t%s\t%s,%s\n", h8_mov_op,
359 h8_reg_names[STACK_POINTER_REGNUM],
360 h8_reg_names[FRAME_POINTER_REGNUM]);
363 /* Leave room for locals. */
364 dosize (file, "sub", fsize);
366 /* Push the rest of the registers in ascending order. */
367 saved_regs = compute_saved_regs ();
368 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx += n_regs)
373 if (saved_regs & (1 << regno))
377 /* See how many registers we can push at the same time. */
378 if ((regno == 0 || regno == 4)
379 && ((saved_regs >> regno) & 0x0f) == 0x0f)
382 else if ((regno == 0 || regno == 4)
383 && ((saved_regs >> regno) & 0x07) == 0x07)
386 else if ((regno == 0 || regno == 2 || regno == 4 || regno == 6)
387 && ((saved_regs >> regno) & 0x03) == 0x03)
394 fprintf (file, "\tstm.l\t%s-%s,@-sp\n",
396 h8_reg_names[regno + (n_regs - 1)]);
401 /* Output assembly language code for the function epilogue. */
404 h8300_output_function_epilogue (file, size)
408 int fsize = round_frame_size (size);
410 rtx insn = get_last_insn ();
416 /* OS_Task epilogues are nearly naked -- they just have an
418 fprintf (file, ";OS_task epilogue\n");
419 fprintf (file, "\trts\n");
423 /* Monitor epilogues are the same as interrupt function epilogues.
424 Just make a note that we're in an monitor epilogue. */
426 fprintf (file, ";monitor epilogue\n");
428 /* If the last insn was a BARRIER, we don't have to write any code. */
429 if (GET_CODE (insn) == NOTE)
430 insn = prev_nonnote_insn (insn);
431 if (insn && GET_CODE (insn) == BARRIER)
434 /* Pop the saved registers in descending order. */
435 saved_regs = compute_saved_regs ();
436 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx += n_regs)
438 int regno = (FIRST_PSEUDO_REGISTER - 1) - idx;
441 if (saved_regs & (1 << regno))
445 /* See how many registers we can pop at the same time. */
446 if ((regno == 7 || regno == 3)
447 && ((saved_regs >> (regno - 3)) & 0x0f) == 0x0f)
450 else if ((regno == 6 || regno == 2)
451 && ((saved_regs >> (regno - 2)) & 0x07) == 0x07)
454 else if ((regno == 7 || regno == 5 || regno == 3 || regno == 1)
455 && ((saved_regs >> (regno - 1)) & 0x03) == 0x03)
462 fprintf (file, "\tldm.l\t@sp+,%s-%s\n",
463 h8_reg_names[regno - (n_regs - 1)],
464 h8_reg_names[regno]);
468 /* Deallocate locals. */
469 dosize (file, "add", fsize);
471 /* Pop frame pointer if we had one. */
472 if (frame_pointer_needed)
473 pop (file, FRAME_POINTER_REGNUM);
475 if (interrupt_handler)
476 fprintf (file, "\trte\n");
478 fprintf (file, "\trts\n");
481 interrupt_handler = 0;
487 /* Output assembly code for the start of the file. */
490 asm_file_start (file)
493 fprintf (file, ";\tGCC For the Hitachi H8/300\n");
494 fprintf (file, ";\tBy Hitachi America Ltd and Cygnus Support\n");
496 fprintf (file, "; -O%d\n", optimize);
498 fprintf (file, "\n\t.h8300h\n");
499 else if (TARGET_H8300S)
500 fprintf (file, "\n\t.h8300s\n");
502 fprintf (file, "\n\n");
503 output_file_directive (file, main_input_filename);
506 /* Output assembly language code for the end of file. */
512 fprintf (file, "\t.end\n");
515 /* Return true if VALUE is a valid constant for constraint 'P'.
516 IE: VALUE is a power of two <= 2**15. */
519 small_power_of_two (value)
522 int power = exact_log2 (value);
523 return power >= 0 && power <= 15;
526 /* Return true if VALUE is a valid constant for constraint 'O', which
527 means that the constant would be ok to use as a bit for a bclr
534 return small_power_of_two ((~value) & 0xff);
537 /* Return true if OP is a valid source operand for an integer move
541 general_operand_src (op, mode)
543 enum machine_mode mode;
545 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
547 return general_operand (op, mode);
550 /* Return true if OP is a valid destination operand for an integer move
554 general_operand_dst (op, mode)
556 enum machine_mode mode;
558 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == PRE_DEC)
560 return general_operand (op, mode);
563 /* Return true if OP is a const valid for a bit clear instruction. */
566 o_operand (operand, mode)
568 enum machine_mode mode ATTRIBUTE_UNUSED;
570 return (GET_CODE (operand) == CONST_INT
571 && CONST_OK_FOR_O (INTVAL (operand)));
574 /* Return true if OP is a const valid for a bit set or bit xor instruction. */
577 p_operand (operand, mode)
579 enum machine_mode mode ATTRIBUTE_UNUSED;
581 return (GET_CODE (operand) == CONST_INT
582 && CONST_OK_FOR_P (INTVAL (operand)));
585 /* Return true if OP is a valid call operand. */
588 call_insn_operand (op, mode)
590 enum machine_mode mode ATTRIBUTE_UNUSED;
592 if (GET_CODE (op) == MEM)
594 rtx inside = XEXP (op, 0);
595 if (register_operand (inside, Pmode))
597 if (CONSTANT_ADDRESS_P (inside))
603 /* Return 1 if an addition/subtraction of a constant integer can be
604 transformed into two consecutive adds/subs that are faster than the
605 straightforward way. Otherwise, return 0. */
608 two_insn_adds_subs_operand (op, mode)
610 enum machine_mode mode;
612 if (GET_CODE (op) == CONST_INT)
614 HOST_WIDE_INT value = INTVAL (op);
616 /* Force VALUE to be positive so that we do not have to consider
617 the negative case. */
620 if (TARGET_H8300H || TARGET_H8300S)
622 /* A constant addition/subtraction takes 2 states in QImode,
623 4 states in HImode, and 6 states in SImode. Thus, the
624 only case we can win is when SImode is used, in which
625 case, two adds/subs are used, taking 4 states. */
635 /* We do not profit directly by splitting addition or
636 subtraction of 3 and 4. However, since these are
637 implemented as a sequence of adds or subs, they do not
638 clobber (cc0) unlike a sequence of add.b and add.x. */
649 /* Split an add of a small constant into two adds/subs insns. */
652 split_adds_subs (mode, operands)
653 enum machine_mode mode;
656 HOST_WIDE_INT val = INTVAL (operands[1]);
657 rtx reg = operands[0];
658 HOST_WIDE_INT sign = 1;
659 HOST_WIDE_INT amount;
661 /* Force VAL to be positive so that we do not have to consider the
669 /* Try different amounts in descending order. */
670 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
674 for (; val >= amount; val -= amount)
676 rtx tmp = gen_rtx_PLUS (mode, reg, GEN_INT (sign * amount));
677 emit_insn (gen_rtx_SET (VOIDmode, reg, tmp));
684 /* Return true if OP is a valid call operand, and OP represents
685 an operand for a small call (4 bytes instead of 6 bytes). */
688 small_call_insn_operand (op, mode)
690 enum machine_mode mode ATTRIBUTE_UNUSED;
692 if (GET_CODE (op) == MEM)
694 rtx inside = XEXP (op, 0);
696 /* Register indirect is a small call. */
697 if (register_operand (inside, Pmode))
700 /* A call through the function vector is a small
702 if (GET_CODE (inside) == SYMBOL_REF
703 && SYMBOL_REF_FLAG (inside))
706 /* Otherwise it's a large call. */
710 /* Return true if OP is a valid jump operand. */
713 jump_address_operand (op, mode)
715 enum machine_mode mode;
717 if (GET_CODE (op) == REG)
718 return mode == Pmode;
720 if (GET_CODE (op) == MEM)
722 rtx inside = XEXP (op, 0);
723 if (register_operand (inside, Pmode))
725 if (CONSTANT_ADDRESS_P (inside))
731 /* Recognize valid operands for bitfield instructions. */
733 extern int rtx_equal_function_value_matters;
736 bit_operand (op, mode)
738 enum machine_mode mode;
740 /* We can except any general operand, expept that MEM operands must
741 be limited to those that use addresses valid for the 'U' constraint. */
742 if (!general_operand (op, mode))
745 /* Accept any mem during RTL generation. Otherwise, the code that does
746 insv and extzv will think that we can not handle memory. However,
747 to avoid reload problems, we only accept 'U' MEM operands after RTL
748 generation. This means that any named pattern which uses this predicate
749 must force its operands to match 'U' before emitting RTL. */
751 if (GET_CODE (op) == REG)
753 if (GET_CODE (op) == SUBREG)
755 if (!rtx_equal_function_value_matters)
756 /* We're building rtl. */
757 return GET_CODE (op) == MEM;
759 return (GET_CODE (op) == MEM
760 && EXTRA_CONSTRAINT (op, 'U'));
764 bit_memory_operand (op, mode)
766 enum machine_mode mode ATTRIBUTE_UNUSED;
768 return (GET_CODE (op) == MEM
769 && EXTRA_CONSTRAINT (op, 'U'));
772 /* Handle machine specific pragmas for compatibility with existing
773 compilers for the H8/300.
775 pragma saveall generates prolog/epilog code which saves and
776 restores all the registers on function entry.
778 pragma interrupt saves and restores all registers, and exits with
779 an rte instruction rather than an rts. A pointer to a function
780 with this attribute may be safely used in an interrupt vector. */
783 h8300_pr_interrupt (pfile)
784 cpp_reader *pfile ATTRIBUTE_UNUSED;
786 interrupt_handler = 1;
790 h8300_pr_saveall (pfile)
791 cpp_reader *pfile ATTRIBUTE_UNUSED;
796 /* If the next function argument with MODE and TYPE is to be passed in
797 a register, return a reg RTX for the hard register in which to pass
798 the argument. CUM represents the state after the last argument.
799 If the argument is to be pushed, NULL_RTX is returned. */
802 function_arg (cum, mode, type, named)
803 CUMULATIVE_ARGS *cum;
804 enum machine_mode mode;
808 static const char *const hand_list[] = {
827 rtx result = NULL_RTX;
831 /* Never pass unnamed arguments in registers. */
835 /* Pass 3 regs worth of data in regs when user asked on the command line. */
836 if (TARGET_QUICKCALL)
839 /* If calling hand written assembler, use 4 regs of args. */
842 const char * const *p;
844 fname = XSTR (cum->libcall, 0);
846 /* See if this libcall is one of the hand coded ones. */
847 for (p = hand_list; *p && strcmp (*p, fname) != 0; p++)
859 size = int_size_in_bytes (type);
861 size = GET_MODE_SIZE (mode);
863 if (size + cum->nbytes <= regpass * UNITS_PER_WORD
864 && cum->nbytes / UNITS_PER_WORD <= 3)
865 result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
871 /* Return the cost of the rtx R with code CODE. */
891 if (TARGET_H8300H || TARGET_H8300S)
912 /* Documentation for the machine specific operand escapes:
914 'E' like s but negative.
915 'F' like t but negative.
916 'G' constant just the negative
917 'R' print operand as a byte:8 address if appropriate, else fall back to
919 'S' print operand as a long word
920 'T' print operand as a word
921 'V' find the set bit, and print its number.
922 'W' find the clear bit, and print its number.
923 'X' print operand as a byte
924 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
925 If this operand isn't a register, fall back to 'R' handling.
927 'b' print the bit opcode
928 'e' first word of 32 bit value - if reg, then least reg. if mem
929 then least. if const then most sig word
930 'f' second word of 32 bit value - if reg, then biggest reg. if mem
931 then +2. if const then least sig word
932 'j' print operand as condition code.
933 'k' print operand as reverse condition code.
934 's' print as low byte of 16 bit value
935 't' print as high byte of 16 bit value
936 'w' print as low byte of 32 bit value
937 'x' print as 2nd byte of 32 bit value
938 'y' print as 3rd byte of 32 bit value
939 'z' print as msb of 32 bit value
942 /* Return assembly language string which identifies a comparison type. */
975 /* Print operand X using operand code CODE to assembly language output file
979 print_operand (file, x, code)
984 /* This is used for communication between codes V,W,Z and Y. */
990 switch (GET_CODE (x))
993 fprintf (file, "%sl", names_big[REGNO (x)]);
996 fprintf (file, "#%d", (-INTVAL (x)) & 0xff);
1003 switch (GET_CODE (x))
1006 fprintf (file, "%sh", names_big[REGNO (x)]);
1009 fprintf (file, "#%d", ((-INTVAL (x)) & 0xff00) >> 8);
1016 if (GET_CODE (x) != CONST_INT)
1018 fprintf (file, "#%d", 0xff & (-INTVAL (x)));
1021 if (GET_CODE (x) == REG)
1022 fprintf (file, "%s", names_extended[REGNO (x)]);
1027 if (GET_CODE (x) == REG)
1028 fprintf (file, "%s", names_big[REGNO (x)]);
1033 bitint = exact_log2 (INTVAL (x));
1036 fprintf (file, "#%d", bitint & 7);
1039 bitint = exact_log2 ((~INTVAL (x)) & 0xff);
1042 fprintf (file, "#%d", bitint & 7);
1046 if (GET_CODE (x) == REG)
1047 fprintf (file, "%s", byte_reg (x, 0));
1054 if (GET_CODE (x) == REG)
1055 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
1057 print_operand (file, x, 'R');
1061 bitint = INTVAL (x);
1062 fprintf (file, "#%d", bitint & 7);
1065 switch (GET_CODE (x))
1068 fprintf (file, "bor");
1071 fprintf (file, "bxor");
1074 fprintf (file, "band");
1081 switch (GET_CODE (x))
1085 fprintf (file, "%s", names_big[REGNO (x)]);
1087 fprintf (file, "%s", names_upper_extended[REGNO (x)]);
1090 print_operand (file, x, 0);
1093 fprintf (file, "#%d", ((INTVAL (x) >> 16) & 0xffff));
1099 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1100 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1101 fprintf (file, "#%ld", ((val >> 16) & 0xffff));
1110 switch (GET_CODE (x))
1114 fprintf (file, "%s", names_big[REGNO (x) + 1]);
1116 fprintf (file, "%s", names_big[REGNO (x)]);
1119 x = adjust_address (x, HImode, 2);
1120 print_operand (file, x, 0);
1123 fprintf (file, "#%d", INTVAL (x) & 0xffff);
1129 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1130 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1131 fprintf (file, "#%ld", (val & 0xffff));
1139 asm_fprintf (file, cond_string (GET_CODE (x)));
1142 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
1145 if (GET_CODE (x) == CONST_INT)
1146 fprintf (file, "#%d", (INTVAL (x)) & 0xff);
1148 fprintf (file, "%s", byte_reg (x, 0));
1151 if (GET_CODE (x) == CONST_INT)
1152 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1154 fprintf (file, "%s", byte_reg (x, 1));
1157 if (GET_CODE (x) != CONST_INT)
1159 fprintf (file, "%d", INTVAL (x));
1162 if (GET_CODE (x) == CONST_INT)
1163 fprintf (file, "#%d", INTVAL (x) & 0xff);
1165 fprintf (file, "%s",
1166 byte_reg (x, TARGET_H8300 ? 2 : 0));
1169 if (GET_CODE (x) == CONST_INT)
1170 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1172 fprintf (file, "%s",
1173 byte_reg (x, TARGET_H8300 ? 3 : 1));
1176 if (GET_CODE (x) == CONST_INT)
1177 fprintf (file, "#%d", (INTVAL (x) >> 16) & 0xff);
1179 fprintf (file, "%s", byte_reg (x, 0));
1182 if (GET_CODE (x) == CONST_INT)
1183 fprintf (file, "#%d", (INTVAL (x) >> 24) & 0xff);
1185 fprintf (file, "%s", byte_reg (x, 1));
1190 switch (GET_CODE (x))
1193 switch (GET_MODE (x))
1196 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */
1197 fprintf (file, "%s", byte_reg (x, 0));
1198 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1199 fprintf (file, "%s", names_big[REGNO (x)]);
1203 fprintf (file, "%s", names_big[REGNO (x)]);
1207 fprintf (file, "%s", names_extended[REGNO (x)]);
1215 fprintf (file, "@");
1216 output_address (XEXP (x, 0));
1218 /* If this is an 'R' operand (reference into the 8-bit
1219 area), then specify a symbolic address as "foo:8",
1220 otherwise if operand is still in eight bit section, use
1222 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
1223 && SYMBOL_REF_FLAG (XEXP (x, 0)))
1224 fprintf (file, (code == 'R' ? ":8" : ":16"));
1225 else if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
1226 && TINY_DATA_NAME_P (XSTR (XEXP (x, 0), 0)))
1227 fprintf (file, ":16");
1228 else if ((code == 'R')
1229 && EIGHTBIT_CONSTANT_ADDRESS_P (XEXP (x, 0)))
1230 fprintf (file, ":8");
1237 fprintf (file, "#");
1238 print_operand_address (file, x);
1244 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1245 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1246 fprintf (file, "#%ld", val);
1255 /* Output assembly language output for the address ADDR to FILE. */
1258 print_operand_address (file, addr)
1262 switch (GET_CODE (addr))
1265 fprintf (file, "%s", h8_reg_names[REGNO (addr)]);
1269 fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
1273 fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);
1277 fprintf (file, "(");
1278 if (GET_CODE (XEXP (addr, 0)) == REG)
1281 print_operand_address (file, XEXP (addr, 1));
1282 fprintf (file, ",");
1283 print_operand_address (file, XEXP (addr, 0));
1288 print_operand_address (file, XEXP (addr, 0));
1289 fprintf (file, "+");
1290 print_operand_address (file, XEXP (addr, 1));
1292 fprintf (file, ")");
1297 /* Since the H8/300 only has 16 bit pointers, negative values are also
1298 those >= 32768. This happens for example with pointer minus a
1299 constant. We don't want to turn (char *p - 2) into
1300 (char *p + 65534) because loop unrolling can build upon this
1301 (IE: char *p + 131068). */
1302 int n = INTVAL (addr);
1304 n = (int) (short) n;
1306 /* ??? Why the special case for -ve values? */
1307 fprintf (file, "-%d", -n);
1309 fprintf (file, "%d", n);
1314 output_addr_const (file, addr);
1319 /* Output all insn addresses and their sizes into the assembly language
1320 output file. This is helpful for debugging whether the length attributes
1321 in the md file are correct. This is not meant to be a user selectable
1325 final_prescan_insn (insn, operand, num_operands)
1326 rtx insn, *operand ATTRIBUTE_UNUSED;
1327 int num_operands ATTRIBUTE_UNUSED;
1329 /* This holds the last insn address. */
1330 static int last_insn_address = 0;
1332 int uid = INSN_UID (insn);
1334 if (TARGET_RTL_DUMP)
1336 fprintf (asm_out_file, "\n****************");
1337 print_rtl (asm_out_file, PATTERN (insn));
1338 fprintf (asm_out_file, "\n");
1341 if (TARGET_ADDRESSES)
1343 fprintf (asm_out_file, "; 0x%x %d\n", INSN_ADDRESSES (uid),
1344 INSN_ADDRESSES (uid) - last_insn_address);
1345 last_insn_address = INSN_ADDRESSES (uid);
1349 /* Prepare for an SI sized move. */
1355 rtx src = operands[1];
1356 rtx dst = operands[0];
1357 if (!reload_in_progress && !reload_completed)
1359 if (!register_operand (dst, GET_MODE (dst)))
1361 rtx tmp = gen_reg_rtx (GET_MODE (dst));
1362 emit_move_insn (tmp, src);
1369 /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
1370 Define the offset between two registers, one to be eliminated, and
1371 the other its replacement, at the start of a routine. */
1374 initial_offset (from, to)
1379 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1380 offset = UNITS_PER_WORD + frame_pointer_needed * UNITS_PER_WORD;
1381 else if (from == RETURN_ADDRESS_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1382 offset = frame_pointer_needed * UNITS_PER_WORD;
1387 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1388 if (WORD_REG_USED (regno))
1389 offset += UNITS_PER_WORD;
1391 /* See the comments for get_frame_size. We need to round it up to
1394 offset += ((get_frame_size () + STACK_BOUNDARY / BITS_PER_UNIT - 1)
1395 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
1397 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1398 offset += UNITS_PER_WORD; /* Skip saved PC */
1404 h8300_return_addr_rtx (count, frame)
1411 ret = gen_rtx_MEM (Pmode,
1412 gen_rtx_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM));
1413 else if (flag_omit_frame_pointer)
1416 ret = gen_rtx_MEM (Pmode,
1417 memory_address (Pmode,
1418 plus_constant (frame, UNITS_PER_WORD)));
1419 set_mem_alias_set (ret, get_frame_alias_set ());
1423 /* Update the condition code from the insn. */
1426 notice_update_cc (body, insn)
1430 switch (get_attr_cc (insn))
1433 /* Insn does not affect CC at all. */
1437 /* Insn does not change CC, but the 0'th operand has been changed. */
1438 if (cc_status.value1 != 0
1439 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
1440 cc_status.value1 = 0;
1444 /* Insn sets the Z,N flags of CC to recog_data.operand[0].
1445 The V flag is unusable. The C flag may or may not be known but
1446 that's ok because alter_cond will change tests to use EQ/NE. */
1448 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
1449 cc_status.value1 = recog_data.operand[0];
1453 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
1454 The C flag may or may not be known but that's ok because
1455 alter_cond will change tests to use EQ/NE. */
1457 cc_status.flags |= CC_NO_CARRY;
1458 cc_status.value1 = recog_data.operand[0];
1462 /* The insn is a compare instruction. */
1464 cc_status.value1 = SET_SRC (body);
1468 /* Insn doesn't leave CC in a usable state. */
1474 /* Recognize valid operators for bit instructions. */
1477 bit_operator (x, mode)
1479 enum machine_mode mode ATTRIBUTE_UNUSED;
1481 enum rtx_code code = GET_CODE (x);
1489 output_logical_op (mode, code, operands)
1490 enum machine_mode mode;
1494 /* Pretend that every byte is affected if both operands are registers. */
1495 unsigned HOST_WIDE_INT intval =
1496 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
1497 ? INTVAL (operands[2]) : 0x55555555);
1498 /* The determinant of the algorithm. If we perform an AND, 0
1499 affects a bit. Otherwise, 1 affects a bit. */
1500 unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
1501 /* The name of an insn. */
1523 /* First, see if we can finish with one insn. */
1524 if ((TARGET_H8300H || TARGET_H8300S)
1525 && ((det & 0x00ff) != 0)
1526 && ((det & 0xff00) != 0))
1528 sprintf (insn_buf, "%s.w\t%%T2,%%T0", opname);
1529 output_asm_insn (insn_buf, operands);
1533 /* Take care of the lower byte. */
1534 if ((det & 0x00ff) != 0)
1536 sprintf (insn_buf, "%s\t%%s2,%%s0", opname);
1537 output_asm_insn (insn_buf, operands);
1539 /* Take care of the upper byte. */
1540 if ((det & 0xff00) != 0)
1542 sprintf (insn_buf, "%s\t%%t2,%%t0", opname);
1543 output_asm_insn (insn_buf, operands);
1548 /* First, see if we can finish with one insn.
1550 If code is either AND or XOR, we exclude two special cases,
1551 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
1552 can do a better job. */
1553 if ((TARGET_H8300H || TARGET_H8300S)
1554 && ((det & 0x0000ffff) != 0)
1555 && ((det & 0xffff0000) != 0)
1556 && (code == IOR || det != 0xffffff00)
1557 && (code == IOR || det != 0xffff00ff))
1559 sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname);
1560 output_asm_insn (insn_buf, operands);
1564 /* Take care of the lower and upper words individually. For
1565 each word, we try different methods in the order of
1567 1) the special insn (in case of AND or XOR),
1568 2) the word-wise insn, and
1569 3) The byte-wise insn. */
1570 if ((TARGET_H8300H || TARGET_H8300S)
1571 && ((det & 0x0000ffff) == 0x0000ffff)
1573 output_asm_insn ((code == AND)
1574 ? "sub.w\t%f0,%f0" : "not.w\t%f0",
1576 else if ((TARGET_H8300H || TARGET_H8300S)
1577 && ((det & 0x000000ff) != 0)
1578 && ((det & 0x0000ff00) != 0))
1580 sprintf (insn_buf, "%s.w\t%%f2,%%f0", opname);
1581 output_asm_insn (insn_buf, operands);
1585 if ((det & 0x000000ff) != 0)
1587 sprintf (insn_buf, "%s\t%%w2,%%w0", opname);
1588 output_asm_insn (insn_buf, operands);
1590 if ((det & 0x0000ff00) != 0)
1592 sprintf (insn_buf, "%s\t%%x2,%%x0", opname);
1593 output_asm_insn (insn_buf, operands);
1597 if ((TARGET_H8300H || TARGET_H8300S)
1598 && ((det & 0xffff0000) == 0xffff0000)
1600 output_asm_insn ((code == AND)
1601 ? "sub.w\t%e0,%e0" : "not.w\t%e0",
1603 else if (TARGET_H8300H || TARGET_H8300S)
1605 if ((det & 0xffff0000) != 0)
1607 sprintf (insn_buf, "%s.w\t%%e2,%%e0", opname);
1608 output_asm_insn (insn_buf, operands);
1613 if ((det & 0x00ff0000) != 0)
1615 sprintf (insn_buf, "%s\t%%y2,%%y0", opname);
1616 output_asm_insn (insn_buf, operands);
1618 if ((det & 0xff000000) != 0)
1620 sprintf (insn_buf, "%s\t%%z2,%%z0", opname);
1621 output_asm_insn (insn_buf, operands);
1634 We devote a fair bit of code to getting efficient shifts since we
1635 can only shift one bit at a time on the H8/300 and H8/300H and only
1636 one or two bits at a time on the H8/S.
1638 All shift code falls into one of the following ways of
1641 o SHIFT_INLINE: Emit straight line code for the shift; this is used
1642 when a straight line shift is about the same size or smaller than
1645 o SHIFT_ROT_AND: Rotate the value the opposite direction, then mask
1646 off the bits we don't need. This is used when only a few of the
1647 bits in the original value will survive in the shifted value.
1649 o SHIFT_SPECIAL: Often it's possible to move a byte or a word to
1650 simulate a shift by 8, 16, or 24 bits. Once moved, a few inline
1651 shifts can be added if the shift count is slightly more than 8 or
1652 16. This case also includes other oddballs that are not worth
1655 o SHIFT_LOOP: Emit a loop using one (or two on H8/S) bit shifts.
1657 Here are some thoughts on what the absolutely positively best code
1658 is. "Best" here means some rational trade-off between code size
1659 and speed, where speed is more preferred but not at the expense of
1660 generating 20 insns.
1662 Below, a trailing '*' after the shift count indicates the "best"
1663 mode isn't implemented. We only describe SHIFT_SPECIAL cases to
1664 simplify the table. For other cases, refer to shift_alg_[qhs]i.
1666 H8/300 QImode shifts
1667 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
1669 H8/300 HImode shifts
1670 7 - shift 2nd half other way into carry.
1671 copy 1st half into 2nd half
1672 rotate 2nd half other way with carry
1673 rotate 1st half other way (no carry)
1674 mask off bits in 1st half (ASHIFT | LSHIFTRT).
1675 sign extend 1st half (ASHIFTRT)
1676 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1677 9-12 - do shift by 8, inline remaining shifts
1678 15 - ASHIFTRT: shll, subx, set other byte
1680 H8/300 SImode shifts
1681 7* - shift other way once, move bytes into place,
1682 move carry into place (possibly with sign extension)
1683 8 - move bytes into place, zero or sign extend other
1684 15* - shift other way once, move word into place, move carry into place
1685 16 - move word, zero or sign extend other
1686 24* - move bytes into place, zero or sign extend other
1687 31 - ASHIFTRT: shll top byte, subx, copy to other bytes
1689 H8/300H QImode shifts (same as H8/300 QImode shifts)
1690 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
1692 H8/300H HImode shifts
1693 7 - shift 2nd half other way into carry.
1694 copy 1st half into 2nd half
1695 rotate entire word other way using carry
1696 mask off remaining bits (ASHIFT | LSHIFTRT)
1697 sign extend remaining bits (ASHIFTRT)
1698 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1699 9-12 - do shift by 8, inline remaining shifts
1700 15 - ASHIFTRT: shll, subx, set other byte
1702 H8/300H SImode shifts
1703 (These are complicated by the fact that we don't have byte level access to
1705 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1706 15* - shift other way once, move word into place, move carry into place
1707 (with sign extension for ASHIFTRT)
1708 16 - move word into place, zero or sign extend other
1709 17-20 - do 16bit shift, then inline remaining shifts
1710 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1711 move word 0 to word 1, zero word 0
1712 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1713 zero word 1, zero byte 1
1714 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1715 sign extend byte 0, sign extend word 0
1716 25-27* - either loop, or
1717 do 24 bit shift, inline rest
1718 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1721 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
1724 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1725 9-12 - do shift by 8, inline remaining shifts
1726 15 - ASHIFTRT: shll, subx, set other byte
1729 (These are complicated by the fact that we don't have byte level access to
1731 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1732 15* - shift other way once, move word into place, move carry into place
1733 (with sign extension for ASHIFTRT)
1734 16 - move word into place, zero or sign extend other
1735 17-20 - do 16bit shift, then inline remaining shifts
1736 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1737 move word 0 to word 1, zero word 0
1738 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1739 zero word 1, zero byte 1
1740 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1741 sign extend byte 0, sign extend word 0
1742 25-27* - either loop, or
1743 do 24 bit shift, inline rest
1744 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1749 nshift_operator (x, mode)
1751 enum machine_mode mode ATTRIBUTE_UNUSED;
1753 switch (GET_CODE (x))
1765 /* Called from the .md file to emit code to do shifts.
1766 Return a boolean indicating success.
1767 (Currently this is always TRUE). */
1770 expand_a_shift (mode, code, operands)
1771 enum machine_mode mode;
1775 emit_move_insn (operands[0], operands[1]);
1777 /* Need a loop to get all the bits we want - we generate the
1778 code at emit time, but need to allocate a scratch reg now. */
1780 emit_insn (gen_rtx_PARALLEL
1783 gen_rtx_SET (VOIDmode, operands[0],
1784 gen_rtx (code, mode, operands[0],
1786 gen_rtx_CLOBBER (VOIDmode,
1787 gen_rtx_SCRATCH (QImode)))));
1792 /* See above for explanation of this enum. */
1802 /* Symbols of the various shifts which can be used as indices. */
1806 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
1809 /* Symbols of the various modes which can be used as indices. */
1813 QIshift, HIshift, SIshift
1816 /* For single bit shift insns, record assembler and what bits of the
1817 condition code are valid afterwards (represented as various CC_FOO
1818 bits, 0 means CC isn't left in a usable state). */
1822 const char *const assembler;
1826 /* Assembler instruction shift table.
1828 These tables are used to look up the basic shifts.
1829 They are indexed by cpu, shift_type, and mode. */
1831 static const struct shift_insn shift_one[2][3][3] =
1837 { "shll\t%X0", CC_NO_CARRY },
1838 { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1839 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }
1841 /* SHIFT_LSHIFTRT */
1843 { "shlr\t%X0", CC_NO_CARRY },
1844 { "shlr\t%t0\n\trotxr\t%s0", 0 },
1845 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1847 /* SHIFT_ASHIFTRT */
1849 { "shar\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1850 { "shar\t%t0\n\trotxr\t%s0", 0 },
1851 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1858 { "shll.b\t%X0", CC_NO_CARRY },
1859 { "shll.w\t%T0", CC_NO_CARRY },
1860 { "shll.l\t%S0", CC_NO_CARRY }
1862 /* SHIFT_LSHIFTRT */
1864 { "shlr.b\t%X0", CC_NO_CARRY },
1865 { "shlr.w\t%T0", CC_NO_CARRY },
1866 { "shlr.l\t%S0", CC_NO_CARRY }
1868 /* SHIFT_ASHIFTRT */
1870 { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1871 { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1872 { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
1877 static const struct shift_insn shift_two[3][3] =
1881 { "shll.b\t#2,%X0", CC_NO_CARRY },
1882 { "shll.w\t#2,%T0", CC_NO_CARRY },
1883 { "shll.l\t#2,%S0", CC_NO_CARRY }
1885 /* SHIFT_LSHIFTRT */
1887 { "shlr.b\t#2,%X0", CC_NO_CARRY },
1888 { "shlr.w\t#2,%T0", CC_NO_CARRY },
1889 { "shlr.l\t#2,%S0", CC_NO_CARRY }
1891 /* SHIFT_ASHIFTRT */
1893 { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1894 { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1895 { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
1899 /* Rotates are organized by which shift they'll be used in implementing.
1900 There's no need to record whether the cc is valid afterwards because
1901 it is the AND insn that will decide this. */
1903 static const char *const rotate_one[2][3][3] =
1910 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
1913 /* SHIFT_LSHIFTRT */
1916 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
1919 /* SHIFT_ASHIFTRT */
1922 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
1934 /* SHIFT_LSHIFTRT */
1940 /* SHIFT_ASHIFTRT */
1949 static const char *const rotate_two[3][3] =
1957 /* SHIFT_LSHIFTRT */
1963 /* SHIFT_ASHIFTRT */
1971 /* Macros to keep the shift algorithm tables small. */
1972 #define INL SHIFT_INLINE
1973 #define ROT SHIFT_ROT_AND
1974 #define LOP SHIFT_LOOP
1975 #define SPC SHIFT_SPECIAL
1977 /* The shift algorithms for each machine, mode, shift type, and shift
1978 count are defined below. The three tables below correspond to
1979 QImode, HImode, and SImode, respectively. Each table is organized
1980 by, in the order of indecies, machine, shift type, and shift count. */
1982 static const enum shift_alg shift_alg_qi[3][3][8] = {
1985 /* 0 1 2 3 4 5 6 7 */
1986 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
1987 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
1988 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
1992 /* 0 1 2 3 4 5 6 7 */
1993 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
1994 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
1995 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
1999 /* 0 1 2 3 4 5 6 7 */
2000 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_ASHIFT */
2001 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_LSHIFTRT */
2002 { INL, INL, INL, INL, INL, INL, INL, SPC } /* SHIFT_ASHIFTRT */
2006 static const enum shift_alg shift_alg_hi[3][3][16] = {
2009 /* 0 1 2 3 4 5 6 7 */
2010 /* 8 9 10 11 12 13 14 15 */
2011 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2012 SPC, SPC, SPC, SPC, SPC, LOP, LOP, ROT }, /* SHIFT_ASHIFT */
2013 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2014 SPC, SPC, SPC, SPC, SPC, LOP, LOP, ROT }, /* SHIFT_LSHIFTRT */
2015 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2016 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2020 /* 0 1 2 3 4 5 6 7 */
2021 /* 8 9 10 11 12 13 14 15 */
2022 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2023 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2024 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2025 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2026 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2027 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2031 /* 0 1 2 3 4 5 6 7 */
2032 /* 8 9 10 11 12 13 14 15 */
2033 { INL, INL, INL, INL, INL, INL, INL, INL,
2034 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2035 { INL, INL, INL, INL, INL, INL, INL, INL,
2036 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2037 { INL, INL, INL, INL, INL, INL, INL, INL,
2038 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2042 static const enum shift_alg shift_alg_si[3][3][32] = {
2045 /* 0 1 2 3 4 5 6 7 */
2046 /* 8 9 10 11 12 13 14 15 */
2047 /* 16 17 18 19 20 21 22 23 */
2048 /* 24 25 26 27 28 29 30 31 */
2049 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2050 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2051 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2052 LOP, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
2053 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2054 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2055 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2056 LOP, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
2057 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2058 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2059 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2060 LOP, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2064 /* 0 1 2 3 4 5 6 7 */
2065 /* 8 9 10 11 12 13 14 15 */
2066 /* 16 17 18 19 20 21 22 23 */
2067 /* 24 25 26 27 28 29 30 31 */
2068 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
2069 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
2070 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
2071 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
2072 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
2073 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
2074 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
2075 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
2076 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
2077 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2078 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
2079 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2083 /* 0 1 2 3 4 5 6 7 */
2084 /* 8 9 10 11 12 13 14 15 */
2085 /* 16 17 18 19 20 21 22 23 */
2086 /* 24 25 26 27 28 29 30 31 */
2087 { INL, INL, INL, INL, INL, INL, INL, INL,
2088 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
2089 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
2090 SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
2091 { INL, INL, INL, INL, INL, INL, INL, INL,
2092 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
2093 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
2094 SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
2095 { INL, INL, INL, INL, INL, INL, INL, INL,
2096 INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2097 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
2098 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2108 /* Shift algorithm. */
2111 /* The number of bits to be shifted by shift1 and shift2. Valid
2112 when ALG is SHIFT_SPECIAL. */
2113 unsigned int remainder;
2115 /* Special insn for a shift. Valid when ALG is SHIFT_SPECIAL. */
2116 const char *special;
2118 /* Insn for a one-bit shift. Valid when ALG is either SHIFT_INLINE
2119 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2122 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
2123 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2126 /* Valid CC flags. */
2130 static void get_shift_alg PARAMS ((enum shift_type,
2131 enum shift_mode, unsigned int,
2132 struct shift_info *));
2134 /* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
2135 best algorithm for doing the shift. The assembler code is stored
2136 in the pointers in INFO. We don't achieve maximum efficiency in
2137 all cases, but the hooks are here to do so.
2139 For now we just use lots of switch statements. Since we don't even come
2140 close to supporting all the cases, this is simplest. If this function ever
2141 gets too big, perhaps resort to a more table based lookup. Of course,
2142 at this point you may just wish to do it all in rtl.
2144 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
2145 1,2,3,4 will be inlined (1,2 for SI). */
2148 get_shift_alg (shift_type, shift_mode, count, info)
2149 enum shift_type shift_type;
2150 enum shift_mode shift_mode;
2152 struct shift_info *info;
2156 /* Find the target CPU. */
2159 else if (TARGET_H8300H)
2164 /* Find the shift algorithm. */
2168 if (GET_MODE_BITSIZE (QImode) <= count)
2169 info->alg = SHIFT_LOOP;
2171 info->alg = shift_alg_qi[cpu][shift_type][count];
2175 if (GET_MODE_BITSIZE (HImode) <= count)
2176 info->alg = SHIFT_LOOP;
2178 info->alg = shift_alg_hi[cpu][shift_type][count];
2182 if (GET_MODE_BITSIZE (SImode) <= count)
2183 info->alg = SHIFT_LOOP;
2185 info->alg = shift_alg_si[cpu][shift_type][count];
2192 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
2196 info->remainder = count;
2200 /* It is up to the caller to know that looping clobbers cc. */
2201 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2202 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2203 info->cc_valid_p = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
2207 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
2208 info->shift2 = rotate_two[shift_type][shift_mode];
2209 info->cc_valid_p = 0;
2213 /* REMAINDER is 0 for most cases, so initialize it to 0. */
2214 info->remainder = 0;
2215 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2216 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2217 info->cc_valid_p = 0;
2221 /* Here we only deal with SHIFT_SPECIAL. */
2225 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2226 through the entire value. */
2227 if (shift_type == SHIFT_ASHIFTRT && count == 7)
2229 info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
2241 info->special = "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";
2243 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
2245 case SHIFT_LSHIFTRT:
2247 info->special = "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";
2249 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
2251 case SHIFT_ASHIFTRT:
2252 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
2256 else if (8 <= count && count <= 12)
2258 info->remainder = count - 8;
2263 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
2264 info->shift1 = "shal.b\t%t0";
2265 info->shift2 = "shal.b\t#2,%t0";
2267 case SHIFT_LSHIFTRT:
2268 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
2269 info->shift1 = "shlr.b\t%s0";
2270 info->shift2 = "shlr.b\t#2,%s0";
2272 case SHIFT_ASHIFTRT:
2274 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
2276 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
2277 info->shift1 = "shar.b\t%s0";
2278 info->shift2 = "shar.b\t#2,%s0";
2282 else if (count == 15 && shift_type == SHIFT_ASHIFTRT)
2284 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
2290 if (count == 8 && TARGET_H8300)
2295 info->special = "mov.b\t%y0,%z0\n\tmov.b\t%x0,%y0\n\tmov.b\t%w0,%x0\n\tsub.b\t%w0,%w0";
2297 case SHIFT_LSHIFTRT:
2298 info->special = "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tsub.b\t%z0,%z0";
2300 case SHIFT_ASHIFTRT:
2301 info->special = "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";
2305 else if (count == 8 && !TARGET_H8300)
2310 info->special = "mov.w\t%e0,%f4\n\tmov.b\t%s4,%t4\n\tmov.b\t%t0,%s4\n\tmov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f4,%e0";
2312 case SHIFT_LSHIFTRT:
2313 info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\textu.w\t%f4\n\tmov.w\t%f4,%e0";
2315 case SHIFT_ASHIFTRT:
2316 info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\texts.w\t%f4\n\tmov.w\t%f4,%e0";
2320 else if (count == 15 && !TARGET_H8300)
2325 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
2327 case SHIFT_LSHIFTRT:
2328 info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
2330 case SHIFT_ASHIFTRT:
2334 else if ((TARGET_H8300 && count == 16)
2335 || (TARGET_H8300H && 16 <= count && count <= 19)
2336 || (TARGET_H8300S && 16 <= count && count <= 21))
2338 info->remainder = count - 16;
2343 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2344 info->shift1 = "shll.l\t%S0";
2345 info->shift2 = "shll.l\t#2,%S0";
2347 case SHIFT_LSHIFTRT:
2348 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
2349 info->shift1 = "shlr.l\t%S0";
2350 info->shift2 = "shlr.l\t#2,%S0";
2352 case SHIFT_ASHIFTRT:
2354 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2356 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
2357 info->shift1 = "shar.l\t%S0";
2358 info->shift2 = "shar.l\t#2,%S0";
2362 else if ((TARGET_H8300H && count == 24)
2363 || (TARGET_H8300S && 24 <= count && count <= 25))
2365 info->remainder = count - 24;
2370 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2371 info->shift1 = "shll.l\t%S0";
2372 info->shift2 = "shll.l\t#2,%S0";
2374 case SHIFT_LSHIFTRT:
2375 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
2376 info->shift1 = "shlr.l\t%S0";
2377 info->shift2 = "shlr.l\t#2,%S0";
2379 case SHIFT_ASHIFTRT:
2380 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
2381 info->shift1 = "shar.l\t%S0";
2382 info->shift2 = "shar.l\t#2,%S0";
2386 else if (count == 31)
2393 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2395 case SHIFT_LSHIFTRT:
2396 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2398 case SHIFT_ASHIFTRT:
2399 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2408 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
2410 case SHIFT_LSHIFTRT:
2411 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
2413 case SHIFT_ASHIFTRT:
2414 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2427 info->shift2 = NULL;
2430 /* Emit the assembler code for doing shifts. */
2433 output_a_shift (operands)
2436 static int loopend_lab;
2437 rtx shift = operands[3];
2438 enum machine_mode mode = GET_MODE (shift);
2439 enum rtx_code code = GET_CODE (shift);
2440 enum shift_type shift_type;
2441 enum shift_mode shift_mode;
2442 struct shift_info info;
2449 shift_mode = QIshift;
2452 shift_mode = HIshift;
2455 shift_mode = SIshift;
2464 shift_type = SHIFT_ASHIFTRT;
2467 shift_type = SHIFT_LSHIFTRT;
2470 shift_type = SHIFT_ASHIFT;
2476 if (GET_CODE (operands[2]) != CONST_INT)
2478 /* Indexing by reg, so have to loop and test at top. */
2479 output_asm_insn ("mov.b %X2,%X4", operands);
2480 fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab);
2482 /* Get the assembler code to do one shift. */
2483 get_shift_alg (shift_type, shift_mode, 1, &info);
2485 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2486 output_asm_insn (info.shift1, operands);
2487 output_asm_insn ("add #0xff,%X4", operands);
2488 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2489 fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
2495 int n = INTVAL (operands[2]);
2497 /* If the count is negative, make it 0. */
2500 /* If the count is too big, truncate it.
2501 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2502 do the intuitive thing. */
2503 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
2504 n = GET_MODE_BITSIZE (mode);
2506 get_shift_alg (shift_type, shift_mode, n, &info);
2511 output_asm_insn (info.special, operands);
2517 /* Emit two bit shifts first. */
2518 if (info.shift2 != NULL)
2520 for (; n > 1; n -= 2)
2521 output_asm_insn (info.shift2, operands);
2524 /* Now emit one bit shifts for any residual. */
2526 output_asm_insn (info.shift1, operands);
2528 /* Keep track of CC. */
2529 if (info.cc_valid_p)
2531 cc_status.value1 = operands[0];
2532 cc_status.flags |= info.cc_valid_p;
2538 int m = GET_MODE_BITSIZE (mode) - n;
2539 int mask = (shift_type == SHIFT_ASHIFT
2540 ? ((1 << m) - 1) << n
2544 /* Not all possibilities of rotate are supported. They shouldn't
2545 be generated, but let's watch for 'em. */
2546 if (info.shift1 == 0)
2549 /* Emit two bit rotates first. */
2550 if (info.shift2 != NULL)
2552 for (; m > 1; m -= 2)
2553 output_asm_insn (info.shift2, operands);
2556 /* Now single bit rotates for any residual. */
2558 output_asm_insn (info.shift1, operands);
2560 /* Now mask off the high bits. */
2566 sprintf (insn_buf, "and\t#%d,%%X0", mask);
2567 cc_status.value1 = operands[0];
2568 cc_status.flags |= CC_NO_CARRY;
2571 sprintf (insn_buf, "and\t#%d,%%s0\n\tand\t#%d,%%t0",
2572 mask & 255, mask >> 8);
2580 sprintf (insn_buf, "and.%c\t#%d,%%%c0",
2581 "bwl"[shift_mode], mask,
2582 mode == QImode ? 'X' : mode == HImode ? 'T' : 'S');
2583 cc_status.value1 = operands[0];
2584 cc_status.flags |= CC_NO_CARRY;
2586 output_asm_insn (insn_buf, operands);
2591 /* A loop to shift by a "large" constant value.
2592 If we have shift-by-2 insns, use them. */
2593 if (info.shift2 != NULL)
2595 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
2596 names_big[REGNO (operands[4])]);
2597 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2598 output_asm_insn (info.shift2, operands);
2599 output_asm_insn ("add #0xff,%X4", operands);
2600 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2602 output_asm_insn (info.shift1, operands);
2606 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
2607 names_big[REGNO (operands[4])]);
2608 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2609 output_asm_insn (info.shift1, operands);
2610 output_asm_insn ("add #0xff,%X4", operands);
2611 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2621 /* A rotation by a non-constant will cause a loop to be generated, in
2622 which a rotation by one bit is used. A rotation by a constant,
2623 including the one in the loop, will be taken care of by
2624 emit_a_rotate () at the insn emit time. */
2627 expand_a_rotate (code, operands)
2631 rtx dst = operands[0];
2632 rtx src = operands[1];
2633 rtx rotate_amount = operands[2];
2634 enum machine_mode mode = GET_MODE (dst);
2637 /* We rotate in place. */
2638 emit_move_insn (dst, src);
2640 if (GET_CODE (rotate_amount) != CONST_INT)
2642 rtx counter = gen_reg_rtx (QImode);
2643 rtx start_label = gen_label_rtx ();
2644 rtx end_label = gen_label_rtx ();
2646 /* If the rotate amount is less than or equal to 0,
2647 we go out of the loop. */
2648 emit_cmp_and_jump_insns (rotate_amount, GEN_INT (0), LE, NULL_RTX,
2649 QImode, 0, end_label);
2651 /* Initialize the loop counter. */
2652 emit_move_insn (counter, rotate_amount);
2654 emit_label (start_label);
2656 /* Rotate by one bit. */
2657 tmp = gen_rtx (code, mode, dst, GEN_INT (1));
2658 emit_insn (gen_rtx_SET (mode, dst, tmp));
2660 /* Decrement the counter by 1. */
2661 tmp = gen_rtx_PLUS (QImode, counter, GEN_INT (-1));
2662 emit_insn (gen_rtx_SET (VOIDmode, counter, tmp));
2664 /* If the loop counter is non-zero, we go back to the beginning
2666 emit_cmp_and_jump_insns (counter, GEN_INT (0), NE, NULL_RTX, QImode, 1,
2669 emit_label (end_label);
2673 /* Rotate by AMOUNT bits. */
2674 tmp = gen_rtx (code, mode, dst, rotate_amount);
2675 emit_insn (gen_rtx_SET (mode, dst, tmp));
2681 /* Emit rotate insns. */
2684 emit_a_rotate (code, operands)
2688 rtx dst = operands[0];
2689 rtx rotate_amount = operands[2];
2690 enum shift_mode rotate_mode;
2691 enum shift_type rotate_type;
2692 const char *insn_buf;
2695 enum machine_mode mode = GET_MODE (dst);
2697 if (GET_CODE (rotate_amount) != CONST_INT)
2703 rotate_mode = QIshift;
2706 rotate_mode = HIshift;
2709 rotate_mode = SIshift;
2718 rotate_type = SHIFT_ASHIFT;
2721 rotate_type = SHIFT_LSHIFTRT;
2727 amount = INTVAL (rotate_amount);
2729 /* Clean up AMOUNT. */
2732 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
2733 amount = GET_MODE_BITSIZE (mode);
2735 /* Determine the faster direction. After this phase, amount will be
2736 at most a half of GET_MODE_BITSIZE (mode). */
2737 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / 2U)
2739 /* Flip the direction. */
2740 amount = GET_MODE_BITSIZE (mode) - amount;
2742 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
2745 /* See if a byte swap (in HImode) or a word swap (in SImode) can
2746 boost up the rotation. */
2747 if ((mode == HImode && TARGET_H8300 && amount >= 5)
2748 || (mode == HImode && TARGET_H8300H && amount >= 6)
2749 || (mode == HImode && TARGET_H8300S && amount == 8)
2750 || (mode == SImode && TARGET_H8300H && amount >= 10)
2751 || (mode == SImode && TARGET_H8300S && amount >= 13))
2756 /* This code works on any family. */
2757 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
2758 output_asm_insn (insn_buf, operands);
2762 /* This code works on the H8/300H and H8/S. */
2763 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
2764 output_asm_insn (insn_buf, operands);
2771 /* Adjust AMOUNT and flip the direction. */
2772 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
2774 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
2777 /* Emit rotate insns. */
2778 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2)
2781 insn_buf = rotate_two[rotate_type][rotate_mode];
2783 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode];
2785 for (; amount >= bits; amount -= bits)
2786 output_asm_insn (insn_buf, operands);
2792 /* Fix the operands of a gen_xxx so that it could become a bit
2796 fix_bit_operand (operands, what, type)
2801 /* The bit_operand predicate accepts any memory during RTL generation, but
2802 only 'U' memory afterwards, so if this is a MEM operand, we must force
2803 it to be valid for 'U' by reloading the address. */
2805 if (GET_CODE (operands[2]) == CONST_INT)
2807 if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), what))
2809 /* Ok to have a memory dest. */
2810 if (GET_CODE (operands[0]) == MEM
2811 && !EXTRA_CONSTRAINT (operands[0], 'U'))
2813 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
2814 copy_to_mode_reg (Pmode,
2815 XEXP (operands[0], 0)));
2816 MEM_COPY_ATTRIBUTES (mem, operands[0]);
2820 if (GET_CODE (operands[1]) == MEM
2821 && !EXTRA_CONSTRAINT (operands[1], 'U'))
2823 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
2824 copy_to_mode_reg (Pmode,
2825 XEXP (operands[1], 0)));
2826 MEM_COPY_ATTRIBUTES (mem, operands[0]);
2833 /* Dest and src op must be register. */
2835 operands[1] = force_reg (QImode, operands[1]);
2837 rtx res = gen_reg_rtx (QImode);
2838 emit_insn (gen_rtx_SET (VOIDmode, res,
2839 gen_rtx (type, QImode, operands[1], operands[2])));
2840 emit_insn (gen_rtx_SET (VOIDmode, operands[0], res));
2845 /* Return nonzero if FUNC is an interrupt function as specified
2846 by the "interrupt" attribute. */
2849 h8300_interrupt_function_p (func)
2854 if (TREE_CODE (func) != FUNCTION_DECL)
2857 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
2858 return a != NULL_TREE;
2861 /* Return nonzero if FUNC is an OS_Task function as specified
2862 by the "OS_Task" attribute. */
2865 h8300_os_task_function_p (func)
2870 if (TREE_CODE (func) != FUNCTION_DECL)
2873 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func));
2874 return a != NULL_TREE;
2877 /* Return nonzero if FUNC is a monitor function as specified
2878 by the "monitor" attribute. */
2881 h8300_monitor_function_p (func)
2886 if (TREE_CODE (func) != FUNCTION_DECL)
2889 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func));
2890 return a != NULL_TREE;
2893 /* Return nonzero if FUNC is a function that should be called
2894 through the function vector. */
2897 h8300_funcvec_function_p (func)
2902 if (TREE_CODE (func) != FUNCTION_DECL)
2905 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func));
2906 return a != NULL_TREE;
2909 /* Return nonzero if DECL is a variable that's in the eight bit
2913 h8300_eightbit_data_p (decl)
2918 if (TREE_CODE (decl) != VAR_DECL)
2921 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl));
2922 return a != NULL_TREE;
2925 /* Return nonzero if DECL is a variable that's in the tiny
2929 h8300_tiny_data_p (decl)
2934 if (TREE_CODE (decl) != VAR_DECL)
2937 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl));
2938 return a != NULL_TREE;
2941 /* Supported attributes:
2943 interrupt_handler: output a prologue and epilogue suitable for an
2946 function_vector: This function should be called through the
2949 eightbit_data: This variable lives in the 8-bit data area and can
2950 be referenced with 8-bit absolute memory addresses.
2952 tiny_data: This variable lives in the tiny data area and can be
2953 referenced with 16-bit absolute memory references. */
2955 const struct attribute_spec h8300_attribute_table[] =
2957 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
2958 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
2959 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
2960 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
2961 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
2962 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute },
2963 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute },
2964 { NULL, 0, 0, false, false, false, NULL }
2968 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
2969 struct attribute_spec.handler. */
2971 h8300_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
2974 tree args ATTRIBUTE_UNUSED;
2975 int flags ATTRIBUTE_UNUSED;
2978 if (TREE_CODE (*node) != FUNCTION_DECL)
2980 warning ("`%s' attribute only applies to functions",
2981 IDENTIFIER_POINTER (name));
2982 *no_add_attrs = true;
2988 /* Handle an "eightbit_data" attribute; arguments as in
2989 struct attribute_spec.handler. */
2991 h8300_handle_eightbit_data_attribute (node, name, args, flags, no_add_attrs)
2994 tree args ATTRIBUTE_UNUSED;
2995 int flags ATTRIBUTE_UNUSED;
3000 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
3002 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
3006 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3007 *no_add_attrs = true;
3013 /* Handle an "tiny_data" attribute; arguments as in
3014 struct attribute_spec.handler. */
3016 h8300_handle_tiny_data_attribute (node, name, args, flags, no_add_attrs)
3019 tree args ATTRIBUTE_UNUSED;
3020 int flags ATTRIBUTE_UNUSED;
3025 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
3027 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
3031 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3032 *no_add_attrs = true;
3039 h8300_encode_label (decl)
3042 const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
3043 int len = strlen (str);
3044 char *newstr = alloca (len + 2);
3047 strcpy (&newstr[1], str);
3049 XSTR (XEXP (DECL_RTL (decl), 0), 0) =
3050 ggc_alloc_string (newstr, len + 1);
3054 output_simode_bld (bild, operands)
3058 /* Clear the destination register. */
3059 if (TARGET_H8300H || TARGET_H8300S)
3060 output_asm_insn ("sub.l\t%S0,%S0", operands);
3062 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
3064 /* Now output the bit load or bit inverse load, and store it in
3067 output_asm_insn ("bild\t%Z2,%Y1\n\tbst\t#0,%w0", operands);
3069 output_asm_insn ("bld\t%Z2,%Y1\n\tbst\t#0,%w0", operands);
3075 /* Given INSN and its current length LENGTH, return the adjustment
3076 (in bytes) to correctly compute INSN's length.
3078 We use this to get the lengths of various memory references correct. */
3081 h8300_adjust_insn_length (insn, length)
3083 int length ATTRIBUTE_UNUSED;
3085 rtx pat = PATTERN (insn);
3087 /* We must filter these out before calling get_attr_adjust_length. */
3088 if (GET_CODE (pat) == USE
3089 || GET_CODE (pat) == CLOBBER
3090 || GET_CODE (pat) == SEQUENCE
3091 || GET_CODE (pat) == ADDR_VEC
3092 || GET_CODE (pat) == ADDR_DIFF_VEC)
3095 if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO)
3098 /* Adjust length for reg->mem and mem->reg copies. */
3099 if (GET_CODE (pat) == SET
3100 && (GET_CODE (SET_SRC (pat)) == MEM
3101 || GET_CODE (SET_DEST (pat)) == MEM))
3103 /* This insn might need a length adjustment. */
3106 if (GET_CODE (SET_SRC (pat)) == MEM)
3107 addr = XEXP (SET_SRC (pat), 0);
3109 addr = XEXP (SET_DEST (pat), 0);
3111 /* On the H8/300, only one adjustment is necessary; if the
3112 address mode is register indirect, then this insn is two
3113 bytes shorter than indicated in the machine description. */
3114 if (TARGET_H8300 && GET_CODE (addr) == REG)
3117 /* On the H8/300H and H8/S, register indirect is 6 bytes shorter than
3118 indicated in the machine description. */
3119 if ((TARGET_H8300H || TARGET_H8300S)
3120 && GET_CODE (addr) == REG)
3123 /* On the H8/300H and H8/S, reg + d, for small displacements is
3124 4 bytes shorter than indicated in the machine description. */
3125 if ((TARGET_H8300H || TARGET_H8300S)
3126 && GET_CODE (addr) == PLUS
3127 && GET_CODE (XEXP (addr, 0)) == REG
3128 && GET_CODE (XEXP (addr, 1)) == CONST_INT
3129 && INTVAL (XEXP (addr, 1)) > -32768
3130 && INTVAL (XEXP (addr, 1)) < 32767)
3133 /* On the H8/300H and H8/S, abs:16 is two bytes shorter than the
3134 more general abs:24. */
3135 if ((TARGET_H8300H || TARGET_H8300S)
3136 && GET_CODE (addr) == SYMBOL_REF
3137 && TINY_DATA_NAME_P (XSTR (addr, 0)))
3141 /* Loading some constants needs adjustment. */
3142 if (GET_CODE (pat) == SET
3143 && GET_CODE (SET_SRC (pat)) == CONST_INT
3144 && GET_MODE (SET_DEST (pat)) == SImode
3145 && INTVAL (SET_SRC (pat)) != 0)
3147 int val = INTVAL (SET_SRC (pat));
3150 && ((val & 0xffff) == 0
3151 || ((val >> 16) & 0xffff) == 0))
3154 if (TARGET_H8300H || TARGET_H8300S)
3156 if (val == (val & 0xff)
3157 || val == (val & 0xff00))
3160 if (val == -4 || val == -2 || val == -1)
3165 /* Shifts need various adjustments. */
3166 if (GET_CODE (pat) == PARALLEL
3167 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
3168 && (GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFTRT
3169 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == LSHIFTRT
3170 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFT))
3172 rtx src = SET_SRC (XVECEXP (pat, 0, 0));
3173 enum machine_mode mode = GET_MODE (src);
3176 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3179 shift = INTVAL (XEXP (src, 1));
3180 /* According to ANSI, negative shift is undefined. It is
3181 considered to be zero in this case (see function
3182 output_a_shift above). */
3186 /* QImode shifts by small constants take one insn
3187 per shift. So the adjustment is 20 (md length) -
3189 if (mode == QImode && shift <= 4)
3190 return -(20 - shift * 2);
3192 /* Similarly for HImode and SImode shifts by small constants on
3193 the H8/300H and H8/S. */
3194 if ((TARGET_H8300H || TARGET_H8300S)
3195 && (mode == HImode || mode == SImode) && shift <= 4)
3196 return -(20 - shift * 2);
3198 /* HImode shifts by small constants for the H8/300. */
3199 if (mode == HImode && shift <= 4)
3200 return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 2 : 4)));
3202 /* SImode shifts by small constants for the H8/300. */
3203 if (mode == SImode && shift <= 2)
3204 return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 6 : 8)));
3206 /* XXX ??? Could check for more shift/rotate cases here. */
3209 /* Rotations need various adjustments. */
3210 if (GET_CODE (pat) == SET
3211 && (GET_CODE (SET_SRC (pat)) == ROTATE
3212 || GET_CODE (SET_SRC (pat)) == ROTATERT))
3214 rtx src = SET_SRC (pat);
3215 enum machine_mode mode = GET_MODE (src);
3219 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3222 amount = INTVAL (XEXP (src, 1));
3224 /* Clean up AMOUNT. */
3227 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3228 amount = GET_MODE_BITSIZE (mode);
3230 /* Determine the faster direction. After this phase, amount
3231 will be at most a half of GET_MODE_BITSIZE (mode). */
3232 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / 2U)
3233 /* Flip the direction. */
3234 amount = GET_MODE_BITSIZE (mode) - amount;
3236 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3237 boost up the rotation. */
3238 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3239 || (mode == HImode && TARGET_H8300H && amount >= 6)
3240 || (mode == HImode && TARGET_H8300S && amount == 8)
3241 || (mode == SImode && TARGET_H8300H && amount >= 10)
3242 || (mode == SImode && TARGET_H8300S && amount >= 13))
3244 /* Adjust AMOUNT and flip the direction. */
3245 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3249 /* We use 2-bit rotatations on the H8/S. */
3251 amount = amount / 2 + amount % 2;
3253 /* The H8/300 uses three insns to rotate one bit, taking 6
3255 states += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2);
3257 return -(20 - states);
3263 #ifndef OBJECT_FORMAT_ELF
3265 h8300_asm_named_section (name, flags)
3267 unsigned int flags ATTRIBUTE_UNUSED;
3269 /* ??? Perhaps we should be using default_coff_asm_named_section. */
3270 fprintf (asm_out_file, "\t.section %s\n", name);
3272 #endif /* ! OBJECT_FORMAT_ELF */