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 const char *byte_reg PARAMS ((rtx, int));
48 static int h8300_interrupt_function_p PARAMS ((tree));
49 static int h8300_monitor_function_p PARAMS ((tree));
50 static int h8300_os_task_function_p PARAMS ((tree));
51 static void dosize PARAMS ((FILE *, const char *, unsigned int));
52 static int round_frame_size PARAMS ((int));
53 static unsigned int compute_saved_regs PARAMS ((void));
54 static void push PARAMS ((FILE *, int));
55 static void pop PARAMS ((FILE *, int));
56 static const char *cond_string PARAMS ((enum rtx_code));
57 const struct attribute_spec h8300_attribute_table[];
58 static tree h8300_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
59 static tree h8300_handle_eightbit_data_attribute PARAMS ((tree *, tree, tree, int, bool *));
60 static tree h8300_handle_tiny_data_attribute PARAMS ((tree *, tree, tree, int, bool *));
61 static void h8300_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
62 static void h8300_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
63 #ifndef OBJECT_FORMAT_ELF
64 static void h8300_asm_named_section PARAMS ((const char *, unsigned int));
67 /* CPU_TYPE, says what cpu we're compiling for. */
70 /* True if the current function is an interrupt handler
71 (either via #pragma or an attribute specification). */
72 static int interrupt_handler;
74 /* True if the current function is an OS Task
75 (via an attribute specification). */
78 /* True if the current function is a monitor
79 (via an attribute specification). */
82 /* True if a #pragma saveall has been seen for the current function. */
83 static int pragma_saveall;
85 static const char *const names_big[] =
86 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" };
88 static const char *const names_extended[] =
89 { "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" };
91 static const char *const names_upper_extended[] =
92 { "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7" };
94 /* Points to one of the above. */
95 /* ??? The above could be put in an array indexed by CPU_TYPE. */
96 const char * const *h8_reg_names;
98 /* Various operations needed by the following, indexed by CPU_TYPE. */
100 const char *h8_push_op, *h8_pop_op, *h8_mov_op;
102 /* Initialize the GCC target structure. */
103 #undef TARGET_ATTRIBUTE_TABLE
104 #define TARGET_ATTRIBUTE_TABLE h8300_attribute_table
106 #undef TARGET_ASM_ALIGNED_HI_OP
107 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
109 #undef TARGET_ASM_FUNCTION_PROLOGUE
110 #define TARGET_ASM_FUNCTION_PROLOGUE h8300_output_function_prologue
111 #undef TARGET_ASM_FUNCTION_EPILOGUE
112 #define TARGET_ASM_FUNCTION_EPILOGUE h8300_output_function_epilogue
114 struct gcc_target targetm = TARGET_INITIALIZER;
116 /* Initialize various cpu specific globals at start up. */
121 static const char *const h8_push_ops[2] = { "push" , "push.l" };
122 static const char *const h8_pop_ops[2] = { "pop" , "pop.l" };
123 static const char *const h8_mov_ops[2] = { "mov.w", "mov.l" };
127 cpu_type = (int) CPU_H8300;
128 h8_reg_names = names_big;
132 /* For this we treat the H8/300H and H8/S the same. */
133 cpu_type = (int) CPU_H8300H;
134 h8_reg_names = names_extended;
136 h8_push_op = h8_push_ops[cpu_type];
137 h8_pop_op = h8_pop_ops[cpu_type];
138 h8_mov_op = h8_mov_ops[cpu_type];
140 if (!TARGET_H8300S && TARGET_MAC)
142 error ("-ms2600 is used without -ms");
152 static const char *const names_small[] = {
153 "r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
154 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h"
157 return names_small[REGNO (x) * 2 + b];
160 /* REGNO must be saved/restored across calls if this macro is true. */
162 #define WORD_REG_USED(regno) \
164 /* No need to save registers if this function will not return. */ \
165 && ! TREE_THIS_VOLATILE (current_function_decl) \
167 /* Save any call saved register that was used. */ \
168 || (regs_ever_live[regno] && !call_used_regs[regno]) \
169 /* Save the frame pointer if it was used. */ \
170 || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno]) \
171 /* Save any register used in an interrupt handler. */ \
172 || (interrupt_handler && regs_ever_live[regno]) \
173 /* Save call clobbered registers in non-leaf interrupt \
175 || (interrupt_handler \
176 && call_used_regs[regno] \
177 && !current_function_is_leaf)))
179 /* Output assembly language to FILE for the operation OP with operand size
180 SIZE to adjust the stack pointer. */
183 dosize (file, op, size)
188 /* On the H8/300H and H8/S, for sizes <= 8 bytes, it is as good or
189 better to use adds/subs insns rather than add.l/sub.l with an
192 Also, on the H8/300, if we don't have a temporary to hold the
193 size of the frame in the prologue, we simply emit a sequence of
194 subs since this shouldn't happen often. */
195 if ((TARGET_H8300 && size <= 4)
196 || ((TARGET_H8300H || TARGET_H8300S) && size <= 8)
197 || (TARGET_H8300 && interrupt_handler)
198 || (TARGET_H8300 && current_function_needs_context
199 && ! strcmp (op, "sub")))
201 unsigned HOST_WIDE_INT amount;
203 /* Try different amounts in descending order. */
204 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
208 for (; size >= amount; size -= amount)
209 fprintf (file, "\t%ss\t#%d,sp\n", op, amount);
215 fprintf (file, "\tmov.w\t#%d,r3\n\t%s.w\tr3,sp\n", size, op);
217 fprintf (file, "\t%s.l\t#%d,sp\n", op, size);
221 /* Round up frame size SIZE. */
224 round_frame_size (size)
227 return (size + STACK_BOUNDARY / 8 - 1) & -STACK_BOUNDARY / 8;
230 /* Compute which registers to push/pop.
231 Return a bit vector of registers. */
234 compute_saved_regs ()
236 unsigned int saved_regs = 0;
239 /* Construct a bit vector of registers to be pushed/popped. */
240 for (regno = 0; regno <= 6; regno++)
242 if (WORD_REG_USED (regno))
243 saved_regs |= 1 << regno;
246 /* Don't push/pop the frame pointer as it is treated separately. */
247 if (frame_pointer_needed)
248 saved_regs &= ~(1 << FRAME_POINTER_REGNUM);
253 /* Output assembly language code to push register RN. */
260 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[rn]);
263 /* Output assembly language code to pop register RN. */
270 fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[rn]);
273 /* This is what the stack looks like after the prolog of
274 a function with a frame has been set up:
280 <saved registers> <- sp
282 This is what the stack looks like after the prolog of
283 a function which doesn't have a frame:
288 <saved registers> <- sp
291 /* Output assembly language code for the function prologue. */
294 h8300_output_function_prologue (file, size)
298 int fsize = round_frame_size (size);
303 /* Note a function with the interrupt attribute and set interrupt_handler
305 if (h8300_interrupt_function_p (current_function_decl))
306 interrupt_handler = 1;
308 /* If the current function has the OS_Task attribute set, then
309 we have a naked prologue. */
310 if (h8300_os_task_function_p (current_function_decl))
312 fprintf (file, ";OS_Task prologue\n");
317 if (h8300_monitor_function_p (current_function_decl))
319 /* My understanding of monitor functions is they act just
320 like interrupt functions, except the prologue must
322 fprintf (file, ";monitor prologue\n");
323 interrupt_handler = 1;
327 fprintf (file, "\tsubs\t#2,sp\n");
329 fprintf (file, "\tstc\tccr,r0l\n");
330 fprintf (file, "\tmov.b\tr0l,@(2,sp)\n");
332 fprintf (file, "\torc\t#128,ccr\n");
334 else if (TARGET_H8300H)
337 fprintf (file, "\tstc\tccr,r0l\n");
338 fprintf (file, "\tmov.b\tr0l,@(4,sp)\n");
340 fprintf (file, "\torc\t#128,ccr\n");
342 else if (TARGET_H8300S)
344 fprintf (file, "\tstc\texr,@-sp\n");
346 fprintf (file, "\tstc\tccr,r0l\n");
347 fprintf (file, "\tmov.b\tr0l,@(6,sp)\n");
349 fprintf (file, "\torc\t#128,ccr\n");
355 if (frame_pointer_needed)
358 push (file, FRAME_POINTER_REGNUM);
359 fprintf (file, "\t%s\t%s,%s\n", h8_mov_op,
360 h8_reg_names[STACK_POINTER_REGNUM],
361 h8_reg_names[FRAME_POINTER_REGNUM]);
364 /* Leave room for locals. */
365 dosize (file, "sub", fsize);
367 /* Push the rest of the registers in ascending order. */
368 saved_regs = compute_saved_regs ();
369 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx += n_regs)
374 if (saved_regs & (1 << regno))
378 /* See how many registers we can push at the same time. */
379 if ((regno == 0 || regno == 4)
380 && ((saved_regs >> regno) & 0x0f) == 0x0f)
383 else if ((regno == 0 || regno == 4)
384 && ((saved_regs >> regno) & 0x07) == 0x07)
387 else if ((regno == 0 || regno == 2 || regno == 4 || regno == 6)
388 && ((saved_regs >> regno) & 0x03) == 0x03)
395 fprintf (file, "\tstm.l\t%s-%s,@-sp\n",
397 h8_reg_names[regno + (n_regs - 1)]);
402 /* Output assembly language code for the function epilogue. */
405 h8300_output_function_epilogue (file, size)
409 int fsize = round_frame_size (size);
411 rtx insn = get_last_insn ();
417 /* OS_Task epilogues are nearly naked -- they just have an
419 fprintf (file, ";OS_task epilogue\n");
420 fprintf (file, "\trts\n");
424 /* Monitor epilogues are the same as interrupt function epilogues.
425 Just make a note that we're in an monitor epilogue. */
427 fprintf (file, ";monitor epilogue\n");
429 /* If the last insn was a BARRIER, we don't have to write any code. */
430 if (GET_CODE (insn) == NOTE)
431 insn = prev_nonnote_insn (insn);
432 if (insn && GET_CODE (insn) == BARRIER)
435 /* Pop the saved registers in descending order. */
436 saved_regs = compute_saved_regs ();
437 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx += n_regs)
439 int regno = (FIRST_PSEUDO_REGISTER - 1) - idx;
442 if (saved_regs & (1 << regno))
446 /* See how many registers we can pop at the same time. */
447 if ((regno == 7 || regno == 3)
448 && ((saved_regs >> (regno - 3)) & 0x0f) == 0x0f)
451 else if ((regno == 6 || regno == 2)
452 && ((saved_regs >> (regno - 2)) & 0x07) == 0x07)
455 else if ((regno == 7 || regno == 5 || regno == 3 || regno == 1)
456 && ((saved_regs >> (regno - 1)) & 0x03) == 0x03)
463 fprintf (file, "\tldm.l\t@sp+,%s-%s\n",
464 h8_reg_names[regno - (n_regs - 1)],
465 h8_reg_names[regno]);
469 /* Deallocate locals. */
470 dosize (file, "add", fsize);
472 /* Pop frame pointer if we had one. */
473 if (frame_pointer_needed)
474 pop (file, FRAME_POINTER_REGNUM);
476 if (interrupt_handler)
477 fprintf (file, "\trte\n");
479 fprintf (file, "\trts\n");
482 interrupt_handler = 0;
488 /* Output assembly code for the start of the file. */
491 asm_file_start (file)
494 fprintf (file, ";\tGCC For the Hitachi H8/300\n");
495 fprintf (file, ";\tBy Hitachi America Ltd and Cygnus Support\n");
497 fprintf (file, "; -O%d\n", optimize);
499 fprintf (file, "\n\t.h8300h\n");
500 else if (TARGET_H8300S)
501 fprintf (file, "\n\t.h8300s\n");
503 fprintf (file, "\n\n");
504 output_file_directive (file, main_input_filename);
507 /* Output assembly language code for the end of file. */
513 fprintf (file, "\t.end\n");
516 /* Return true if VALUE is a valid constant for constraint 'P'.
517 IE: VALUE is a power of two <= 2**15. */
520 small_power_of_two (value)
523 int power = exact_log2 (value);
524 return power >= 0 && power <= 15;
527 /* Return true if VALUE is a valid constant for constraint 'O', which
528 means that the constant would be ok to use as a bit for a bclr
535 return small_power_of_two ((~value) & 0xff);
538 /* Return true if OP is a valid source operand for an integer move
542 general_operand_src (op, mode)
544 enum machine_mode mode;
546 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
548 return general_operand (op, mode);
551 /* Return true if OP is a valid destination operand for an integer move
555 general_operand_dst (op, mode)
557 enum machine_mode mode;
559 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == PRE_DEC)
561 return general_operand (op, mode);
564 /* Return true if OP is a const valid for a bit clear instruction. */
567 o_operand (operand, mode)
569 enum machine_mode mode ATTRIBUTE_UNUSED;
571 return (GET_CODE (operand) == CONST_INT
572 && CONST_OK_FOR_O (INTVAL (operand)));
575 /* Return true if OP is a const valid for a bit set or bit xor instruction. */
578 p_operand (operand, mode)
580 enum machine_mode mode ATTRIBUTE_UNUSED;
582 return (GET_CODE (operand) == CONST_INT
583 && CONST_OK_FOR_P (INTVAL (operand)));
586 /* Return true if OP is a valid call operand. */
589 call_insn_operand (op, mode)
591 enum machine_mode mode ATTRIBUTE_UNUSED;
593 if (GET_CODE (op) == MEM)
595 rtx inside = XEXP (op, 0);
596 if (register_operand (inside, Pmode))
598 if (CONSTANT_ADDRESS_P (inside))
604 /* Return 1 if an addition/subtraction of a constant integer can be
605 transformed into two consecutive adds/subs that are faster than the
606 straightforward way. Otherwise, return 0. */
609 two_insn_adds_subs_operand (op, mode)
611 enum machine_mode mode;
613 if (GET_CODE (op) == CONST_INT)
615 HOST_WIDE_INT value = INTVAL (op);
617 /* Force VALUE to be positive so that we do not have to consider
618 the negative case. */
621 if (TARGET_H8300H || TARGET_H8300S)
623 /* A constant addition/subtraction takes 2 states in QImode,
624 4 states in HImode, and 6 states in SImode. Thus, the
625 only case we can win is when SImode is used, in which
626 case, two adds/subs are used, taking 4 states. */
636 /* We do not profit directly by splitting addition or
637 subtraction of 3 and 4. However, since these are
638 implemented as a sequence of adds or subs, they do not
639 clobber (cc0) unlike a sequence of add.b and add.x. */
650 /* Split an add of a small constant into two adds/subs insns. */
653 split_adds_subs (mode, operands)
654 enum machine_mode mode;
657 HOST_WIDE_INT val = INTVAL (operands[1]);
658 rtx reg = operands[0];
659 HOST_WIDE_INT sign = 1;
660 HOST_WIDE_INT amount;
662 /* Force VAL to be positive so that we do not have to consider the
670 /* Try different amounts in descending order. */
671 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
675 for (; val >= amount; val -= amount)
677 rtx tmp = gen_rtx_PLUS (mode, reg, GEN_INT (sign * amount));
678 emit_insn (gen_rtx_SET (VOIDmode, reg, tmp));
685 /* Return true if OP is a valid call operand, and OP represents
686 an operand for a small call (4 bytes instead of 6 bytes). */
689 small_call_insn_operand (op, mode)
691 enum machine_mode mode ATTRIBUTE_UNUSED;
693 if (GET_CODE (op) == MEM)
695 rtx inside = XEXP (op, 0);
697 /* Register indirect is a small call. */
698 if (register_operand (inside, Pmode))
701 /* A call through the function vector is a small
703 if (GET_CODE (inside) == SYMBOL_REF
704 && SYMBOL_REF_FLAG (inside))
707 /* Otherwise it's a large call. */
711 /* Return true if OP is a valid jump operand. */
714 jump_address_operand (op, mode)
716 enum machine_mode mode;
718 if (GET_CODE (op) == REG)
719 return mode == Pmode;
721 if (GET_CODE (op) == MEM)
723 rtx inside = XEXP (op, 0);
724 if (register_operand (inside, Pmode))
726 if (CONSTANT_ADDRESS_P (inside))
732 /* Recognize valid operands for bitfield instructions. */
734 extern int rtx_equal_function_value_matters;
737 bit_operand (op, mode)
739 enum machine_mode mode;
741 /* We can except any general operand, expept that MEM operands must
742 be limited to those that use addresses valid for the 'U' constraint. */
743 if (!general_operand (op, mode))
746 /* Accept any mem during RTL generation. Otherwise, the code that does
747 insv and extzv will think that we can not handle memory. However,
748 to avoid reload problems, we only accept 'U' MEM operands after RTL
749 generation. This means that any named pattern which uses this predicate
750 must force its operands to match 'U' before emitting RTL. */
752 if (GET_CODE (op) == REG)
754 if (GET_CODE (op) == SUBREG)
756 if (!rtx_equal_function_value_matters)
757 /* We're building rtl. */
758 return GET_CODE (op) == MEM;
760 return (GET_CODE (op) == MEM
761 && EXTRA_CONSTRAINT (op, 'U'));
765 bit_memory_operand (op, mode)
767 enum machine_mode mode ATTRIBUTE_UNUSED;
769 return (GET_CODE (op) == MEM
770 && EXTRA_CONSTRAINT (op, 'U'));
773 /* Handle machine specific pragmas for compatibility with existing
774 compilers for the H8/300.
776 pragma saveall generates prolog/epilog code which saves and
777 restores all the registers on function entry.
779 pragma interrupt saves and restores all registers, and exits with
780 an rte instruction rather than an rts. A pointer to a function
781 with this attribute may be safely used in an interrupt vector. */
784 h8300_pr_interrupt (pfile)
785 cpp_reader *pfile ATTRIBUTE_UNUSED;
787 interrupt_handler = 1;
791 h8300_pr_saveall (pfile)
792 cpp_reader *pfile ATTRIBUTE_UNUSED;
797 /* If the next function argument with MODE and TYPE is to be passed in
798 a register, return a reg RTX for the hard register in which to pass
799 the argument. CUM represents the state after the last argument.
800 If the argument is to be pushed, NULL_RTX is returned. */
803 function_arg (cum, mode, type, named)
804 CUMULATIVE_ARGS *cum;
805 enum machine_mode mode;
809 static const char *const hand_list[] = {
828 rtx result = NULL_RTX;
832 /* Never pass unnamed arguments in registers. */
836 /* Pass 3 regs worth of data in regs when user asked on the command line. */
837 if (TARGET_QUICKCALL)
840 /* If calling hand written assembler, use 4 regs of args. */
843 const char * const *p;
845 fname = XSTR (cum->libcall, 0);
847 /* See if this libcall is one of the hand coded ones. */
848 for (p = hand_list; *p && strcmp (*p, fname) != 0; p++)
860 size = int_size_in_bytes (type);
862 size = GET_MODE_SIZE (mode);
864 if (size + cum->nbytes <= regpass * UNITS_PER_WORD
865 && cum->nbytes / UNITS_PER_WORD <= 3)
866 result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
872 /* Return the cost of the rtx R with code CODE. */
892 if (TARGET_H8300H || TARGET_H8300S)
913 /* Documentation for the machine specific operand escapes:
915 'E' like s but negative.
916 'F' like t but negative.
917 'G' constant just the negative
918 'R' print operand as a byte:8 address if appropriate, else fall back to
920 'S' print operand as a long word
921 'T' print operand as a word
922 'V' find the set bit, and print its number.
923 'W' find the clear bit, and print its number.
924 'X' print operand as a byte
925 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
926 If this operand isn't a register, fall back to 'R' handling.
928 'b' print the bit opcode
929 'e' first word of 32 bit value - if reg, then least reg. if mem
930 then least. if const then most sig word
931 'f' second word of 32 bit value - if reg, then biggest reg. if mem
932 then +2. if const then least sig word
933 'j' print operand as condition code.
934 'k' print operand as reverse condition code.
935 's' print as low byte of 16 bit value
936 't' print as high byte of 16 bit value
937 'w' print as low byte of 32 bit value
938 'x' print as 2nd byte of 32 bit value
939 'y' print as 3rd byte of 32 bit value
940 'z' print as msb of 32 bit value
943 /* Return assembly language string which identifies a comparison type. */
976 /* Print operand X using operand code CODE to assembly language output file
980 print_operand (file, x, code)
985 /* This is used for communication between codes V,W,Z and Y. */
991 switch (GET_CODE (x))
994 fprintf (file, "%sl", names_big[REGNO (x)]);
997 fprintf (file, "#%d", (-INTVAL (x)) & 0xff);
1004 switch (GET_CODE (x))
1007 fprintf (file, "%sh", names_big[REGNO (x)]);
1010 fprintf (file, "#%d", ((-INTVAL (x)) & 0xff00) >> 8);
1017 if (GET_CODE (x) != CONST_INT)
1019 fprintf (file, "#%d", 0xff & (-INTVAL (x)));
1022 if (GET_CODE (x) == REG)
1023 fprintf (file, "%s", names_extended[REGNO (x)]);
1028 if (GET_CODE (x) == REG)
1029 fprintf (file, "%s", names_big[REGNO (x)]);
1034 bitint = exact_log2 (INTVAL (x));
1037 fprintf (file, "#%d", bitint & 7);
1040 bitint = exact_log2 ((~INTVAL (x)) & 0xff);
1043 fprintf (file, "#%d", bitint & 7);
1047 if (GET_CODE (x) == REG)
1048 fprintf (file, "%s", byte_reg (x, 0));
1055 if (GET_CODE (x) == REG)
1056 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
1058 print_operand (file, x, 'R');
1062 bitint = INTVAL (x);
1063 fprintf (file, "#%d", bitint & 7);
1066 switch (GET_CODE (x))
1069 fprintf (file, "bor");
1072 fprintf (file, "bxor");
1075 fprintf (file, "band");
1082 switch (GET_CODE (x))
1086 fprintf (file, "%s", names_big[REGNO (x)]);
1088 fprintf (file, "%s", names_upper_extended[REGNO (x)]);
1091 print_operand (file, x, 0);
1094 fprintf (file, "#%d", ((INTVAL (x) >> 16) & 0xffff));
1100 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1101 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1102 fprintf (file, "#%ld", ((val >> 16) & 0xffff));
1111 switch (GET_CODE (x))
1115 fprintf (file, "%s", names_big[REGNO (x) + 1]);
1117 fprintf (file, "%s", names_big[REGNO (x)]);
1120 x = adjust_address (x, HImode, 2);
1121 print_operand (file, x, 0);
1124 fprintf (file, "#%d", INTVAL (x) & 0xffff);
1130 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1131 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1132 fprintf (file, "#%ld", (val & 0xffff));
1140 asm_fprintf (file, cond_string (GET_CODE (x)));
1143 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
1146 if (GET_CODE (x) == CONST_INT)
1147 fprintf (file, "#%d", (INTVAL (x)) & 0xff);
1149 fprintf (file, "%s", byte_reg (x, 0));
1152 if (GET_CODE (x) == CONST_INT)
1153 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1155 fprintf (file, "%s", byte_reg (x, 1));
1158 if (GET_CODE (x) != CONST_INT)
1160 fprintf (file, "%d", INTVAL (x));
1163 if (GET_CODE (x) == CONST_INT)
1164 fprintf (file, "#%d", INTVAL (x) & 0xff);
1166 fprintf (file, "%s",
1167 byte_reg (x, TARGET_H8300 ? 2 : 0));
1170 if (GET_CODE (x) == CONST_INT)
1171 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1173 fprintf (file, "%s",
1174 byte_reg (x, TARGET_H8300 ? 3 : 1));
1177 if (GET_CODE (x) == CONST_INT)
1178 fprintf (file, "#%d", (INTVAL (x) >> 16) & 0xff);
1180 fprintf (file, "%s", byte_reg (x, 0));
1183 if (GET_CODE (x) == CONST_INT)
1184 fprintf (file, "#%d", (INTVAL (x) >> 24) & 0xff);
1186 fprintf (file, "%s", byte_reg (x, 1));
1191 switch (GET_CODE (x))
1194 switch (GET_MODE (x))
1197 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */
1198 fprintf (file, "%s", byte_reg (x, 0));
1199 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1200 fprintf (file, "%s", names_big[REGNO (x)]);
1204 fprintf (file, "%s", names_big[REGNO (x)]);
1208 fprintf (file, "%s", names_extended[REGNO (x)]);
1216 fprintf (file, "@");
1217 output_address (XEXP (x, 0));
1219 /* If this is an 'R' operand (reference into the 8-bit
1220 area), then specify a symbolic address as "foo:8",
1221 otherwise if operand is still in eight bit section, use
1223 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
1224 && SYMBOL_REF_FLAG (XEXP (x, 0)))
1225 fprintf (file, (code == 'R' ? ":8" : ":16"));
1226 else if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
1227 && TINY_DATA_NAME_P (XSTR (XEXP (x, 0), 0)))
1228 fprintf (file, ":16");
1229 else if ((code == 'R')
1230 && EIGHTBIT_CONSTANT_ADDRESS_P (XEXP (x, 0)))
1231 fprintf (file, ":8");
1238 fprintf (file, "#");
1239 print_operand_address (file, x);
1245 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1246 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1247 fprintf (file, "#%ld", val);
1256 /* Output assembly language output for the address ADDR to FILE. */
1259 print_operand_address (file, addr)
1263 switch (GET_CODE (addr))
1266 fprintf (file, "%s", h8_reg_names[REGNO (addr)]);
1270 fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
1274 fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);
1278 fprintf (file, "(");
1279 if (GET_CODE (XEXP (addr, 0)) == REG)
1282 print_operand_address (file, XEXP (addr, 1));
1283 fprintf (file, ",");
1284 print_operand_address (file, XEXP (addr, 0));
1289 print_operand_address (file, XEXP (addr, 0));
1290 fprintf (file, "+");
1291 print_operand_address (file, XEXP (addr, 1));
1293 fprintf (file, ")");
1298 /* Since the H8/300 only has 16 bit pointers, negative values are also
1299 those >= 32768. This happens for example with pointer minus a
1300 constant. We don't want to turn (char *p - 2) into
1301 (char *p + 65534) because loop unrolling can build upon this
1302 (IE: char *p + 131068). */
1303 int n = INTVAL (addr);
1305 n = (int) (short) n;
1307 /* ??? Why the special case for -ve values? */
1308 fprintf (file, "-%d", -n);
1310 fprintf (file, "%d", n);
1315 output_addr_const (file, addr);
1320 /* Output all insn addresses and their sizes into the assembly language
1321 output file. This is helpful for debugging whether the length attributes
1322 in the md file are correct. This is not meant to be a user selectable
1326 final_prescan_insn (insn, operand, num_operands)
1327 rtx insn, *operand ATTRIBUTE_UNUSED;
1328 int num_operands ATTRIBUTE_UNUSED;
1330 /* This holds the last insn address. */
1331 static int last_insn_address = 0;
1333 int uid = INSN_UID (insn);
1335 if (TARGET_RTL_DUMP)
1337 fprintf (asm_out_file, "\n****************");
1338 print_rtl (asm_out_file, PATTERN (insn));
1339 fprintf (asm_out_file, "\n");
1342 if (TARGET_ADDRESSES)
1344 fprintf (asm_out_file, "; 0x%x %d\n", INSN_ADDRESSES (uid),
1345 INSN_ADDRESSES (uid) - last_insn_address);
1346 last_insn_address = INSN_ADDRESSES (uid);
1350 /* Prepare for an SI sized move. */
1356 rtx src = operands[1];
1357 rtx dst = operands[0];
1358 if (!reload_in_progress && !reload_completed)
1360 if (!register_operand (dst, GET_MODE (dst)))
1362 rtx tmp = gen_reg_rtx (GET_MODE (dst));
1363 emit_move_insn (tmp, src);
1370 /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
1371 Define the offset between two registers, one to be eliminated, and
1372 the other its replacement, at the start of a routine. */
1375 initial_offset (from, to)
1380 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1381 offset = UNITS_PER_WORD + frame_pointer_needed * UNITS_PER_WORD;
1382 else if (from == RETURN_ADDRESS_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1383 offset = frame_pointer_needed * UNITS_PER_WORD;
1388 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1389 if (WORD_REG_USED (regno))
1390 offset += UNITS_PER_WORD;
1392 /* See the comments for get_frame_size. We need to round it up to
1395 offset += ((get_frame_size () + STACK_BOUNDARY / BITS_PER_UNIT - 1)
1396 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
1398 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1399 offset += UNITS_PER_WORD; /* Skip saved PC */
1405 h8300_return_addr_rtx (count, frame)
1412 ret = gen_rtx_MEM (Pmode,
1413 gen_rtx_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM));
1414 else if (flag_omit_frame_pointer)
1417 ret = gen_rtx_MEM (Pmode,
1418 memory_address (Pmode,
1419 plus_constant (frame, UNITS_PER_WORD)));
1420 set_mem_alias_set (ret, get_frame_alias_set ());
1424 /* Update the condition code from the insn. */
1427 notice_update_cc (body, insn)
1431 switch (get_attr_cc (insn))
1434 /* Insn does not affect CC at all. */
1438 /* Insn does not change CC, but the 0'th operand has been changed. */
1439 if (cc_status.value1 != 0
1440 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
1441 cc_status.value1 = 0;
1445 /* Insn sets the Z,N flags of CC to recog_data.operand[0].
1446 The V flag is unusable. The C flag may or may not be known but
1447 that's ok because alter_cond will change tests to use EQ/NE. */
1449 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
1450 cc_status.value1 = recog_data.operand[0];
1454 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
1455 The C flag may or may not be known but that's ok because
1456 alter_cond will change tests to use EQ/NE. */
1458 cc_status.flags |= CC_NO_CARRY;
1459 cc_status.value1 = recog_data.operand[0];
1463 /* The insn is a compare instruction. */
1465 cc_status.value1 = SET_SRC (body);
1469 /* Insn doesn't leave CC in a usable state. */
1475 /* Recognize valid operators for bit instructions. */
1478 bit_operator (x, mode)
1480 enum machine_mode mode ATTRIBUTE_UNUSED;
1482 enum rtx_code code = GET_CODE (x);
1490 output_logical_op (mode, code, operands)
1491 enum machine_mode mode;
1495 /* Pretend that every byte is affected if both operands are registers. */
1496 unsigned HOST_WIDE_INT intval =
1497 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
1498 ? INTVAL (operands[2]) : 0x55555555);
1499 /* The determinant of the algorithm. If we perform an AND, 0
1500 affects a bit. Otherwise, 1 affects a bit. */
1501 unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
1502 /* The name of an insn. */
1524 /* First, see if we can finish with one insn. */
1525 if ((TARGET_H8300H || TARGET_H8300S)
1526 && ((det & 0x00ff) != 0)
1527 && ((det & 0xff00) != 0))
1529 sprintf (insn_buf, "%s.w\t%%T2,%%T0", opname);
1530 output_asm_insn (insn_buf, operands);
1534 /* Take care of the lower byte. */
1535 if ((det & 0x00ff) != 0)
1537 sprintf (insn_buf, "%s\t%%s2,%%s0", opname);
1538 output_asm_insn (insn_buf, operands);
1540 /* Take care of the upper byte. */
1541 if ((det & 0xff00) != 0)
1543 sprintf (insn_buf, "%s\t%%t2,%%t0", opname);
1544 output_asm_insn (insn_buf, operands);
1549 /* First, see if we can finish with one insn.
1551 If code is either AND or XOR, we exclude two special cases,
1552 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
1553 can do a better job. */
1554 if ((TARGET_H8300H || TARGET_H8300S)
1555 && ((det & 0x0000ffff) != 0)
1556 && ((det & 0xffff0000) != 0)
1557 && (code == IOR || det != 0xffffff00)
1558 && (code == IOR || det != 0xffff00ff))
1560 sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname);
1561 output_asm_insn (insn_buf, operands);
1565 /* Take care of the lower and upper words individually. For
1566 each word, we try different methods in the order of
1568 1) the special insn (in case of AND or XOR),
1569 2) the word-wise insn, and
1570 3) The byte-wise insn. */
1571 if ((det & 0x0000ffff) == 0x0000ffff
1572 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
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 ((det & 0xffff0000) == 0xffff0000
1598 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
1599 output_asm_insn ((code == AND)
1600 ? "sub.w\t%e0,%e0" : "not.w\t%e0",
1602 else if (TARGET_H8300H || TARGET_H8300S)
1604 if ((det & 0xffff0000) != 0)
1606 sprintf (insn_buf, "%s.w\t%%e2,%%e0", opname);
1607 output_asm_insn (insn_buf, operands);
1612 if ((det & 0x00ff0000) != 0)
1614 sprintf (insn_buf, "%s\t%%y2,%%y0", opname);
1615 output_asm_insn (insn_buf, operands);
1617 if ((det & 0xff000000) != 0)
1619 sprintf (insn_buf, "%s\t%%z2,%%z0", opname);
1620 output_asm_insn (insn_buf, operands);
1633 We devote a fair bit of code to getting efficient shifts since we
1634 can only shift one bit at a time on the H8/300 and H8/300H and only
1635 one or two bits at a time on the H8/S.
1637 All shift code falls into one of the following ways of
1640 o SHIFT_INLINE: Emit straight line code for the shift; this is used
1641 when a straight line shift is about the same size or smaller than
1644 o SHIFT_ROT_AND: Rotate the value the opposite direction, then mask
1645 off the bits we don't need. This is used when only a few of the
1646 bits in the original value will survive in the shifted value.
1648 o SHIFT_SPECIAL: Often it's possible to move a byte or a word to
1649 simulate a shift by 8, 16, or 24 bits. Once moved, a few inline
1650 shifts can be added if the shift count is slightly more than 8 or
1651 16. This case also includes other oddballs that are not worth
1654 o SHIFT_LOOP: Emit a loop using one (or two on H8/S) bit shifts.
1656 Here are some thoughts on what the absolutely positively best code
1657 is. "Best" here means some rational trade-off between code size
1658 and speed, where speed is more preferred but not at the expense of
1659 generating 20 insns.
1661 Below, a trailing '*' after the shift count indicates the "best"
1662 mode isn't implemented. We only describe SHIFT_SPECIAL cases to
1663 simplify the table. For other cases, refer to shift_alg_[qhs]i.
1665 H8/300 QImode shifts
1666 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
1668 H8/300 HImode shifts
1669 7 - shift 2nd half other way into carry.
1670 copy 1st half into 2nd half
1671 rotate 2nd half other way with carry
1672 rotate 1st half other way (no carry)
1673 mask off bits in 1st half (ASHIFT | LSHIFTRT).
1674 sign extend 1st half (ASHIFTRT)
1675 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1676 9-12 - do shift by 8, inline remaining shifts
1677 15 - ASHIFTRT: shll, subx, set other byte
1679 H8/300 SImode shifts
1680 7* - shift other way once, move bytes into place,
1681 move carry into place (possibly with sign extension)
1682 8 - move bytes into place, zero or sign extend other
1683 15* - shift other way once, move word into place, move carry into place
1684 16 - move word, zero or sign extend other
1685 24* - move bytes into place, zero or sign extend other
1686 31 - ASHIFTRT: shll top byte, subx, copy to other bytes
1688 H8/300H QImode shifts (same as H8/300 QImode shifts)
1689 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
1691 H8/300H HImode shifts
1692 7 - shift 2nd half other way into carry.
1693 copy 1st half into 2nd half
1694 rotate entire word other way using carry
1695 mask off remaining bits (ASHIFT | LSHIFTRT)
1696 sign extend remaining bits (ASHIFTRT)
1697 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1698 9-12 - do shift by 8, inline remaining shifts
1699 15 - ASHIFTRT: shll, subx, set other byte
1701 H8/300H SImode shifts
1702 (These are complicated by the fact that we don't have byte level access to
1704 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1705 15* - shift other way once, move word into place, move carry into place
1706 (with sign extension for ASHIFTRT)
1707 16 - move word into place, zero or sign extend other
1708 17-20 - do 16bit shift, then inline remaining shifts
1709 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1710 move word 0 to word 1, zero word 0
1711 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1712 zero word 1, zero byte 1
1713 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1714 sign extend byte 0, sign extend word 0
1715 25-27* - either loop, or
1716 do 24 bit shift, inline rest
1717 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1720 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
1723 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1724 9-12 - do shift by 8, inline remaining shifts
1725 15 - ASHIFTRT: shll, subx, set other byte
1728 (These are complicated by the fact that we don't have byte level access to
1730 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1731 15* - shift other way once, move word into place, move carry into place
1732 (with sign extension for ASHIFTRT)
1733 16 - move word into place, zero or sign extend other
1734 17-20 - do 16bit shift, then inline remaining shifts
1735 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1736 move word 0 to word 1, zero word 0
1737 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1738 zero word 1, zero byte 1
1739 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1740 sign extend byte 0, sign extend word 0
1741 25-27* - either loop, or
1742 do 24 bit shift, inline rest
1743 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1748 nshift_operator (x, mode)
1750 enum machine_mode mode ATTRIBUTE_UNUSED;
1752 switch (GET_CODE (x))
1764 /* Called from the .md file to emit code to do shifts.
1765 Return a boolean indicating success.
1766 (Currently this is always TRUE). */
1769 expand_a_shift (mode, code, operands)
1770 enum machine_mode mode;
1774 emit_move_insn (operands[0], operands[1]);
1776 /* Need a loop to get all the bits we want - we generate the
1777 code at emit time, but need to allocate a scratch reg now. */
1779 emit_insn (gen_rtx_PARALLEL
1782 gen_rtx_SET (VOIDmode, operands[0],
1783 gen_rtx (code, mode, operands[0],
1785 gen_rtx_CLOBBER (VOIDmode,
1786 gen_rtx_SCRATCH (QImode)))));
1791 /* See above for explanation of this enum. */
1801 /* Symbols of the various shifts which can be used as indices. */
1805 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
1808 /* Symbols of the various modes which can be used as indices. */
1812 QIshift, HIshift, SIshift
1815 /* For single bit shift insns, record assembler and what bits of the
1816 condition code are valid afterwards (represented as various CC_FOO
1817 bits, 0 means CC isn't left in a usable state). */
1821 const char *const assembler;
1825 /* Assembler instruction shift table.
1827 These tables are used to look up the basic shifts.
1828 They are indexed by cpu, shift_type, and mode. */
1830 static const struct shift_insn shift_one[2][3][3] =
1836 { "shll\t%X0", CC_NO_CARRY },
1837 { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1838 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }
1840 /* SHIFT_LSHIFTRT */
1842 { "shlr\t%X0", CC_NO_CARRY },
1843 { "shlr\t%t0\n\trotxr\t%s0", 0 },
1844 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1846 /* SHIFT_ASHIFTRT */
1848 { "shar\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1849 { "shar\t%t0\n\trotxr\t%s0", 0 },
1850 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1857 { "shll.b\t%X0", CC_NO_CARRY },
1858 { "shll.w\t%T0", CC_NO_CARRY },
1859 { "shll.l\t%S0", CC_NO_CARRY }
1861 /* SHIFT_LSHIFTRT */
1863 { "shlr.b\t%X0", CC_NO_CARRY },
1864 { "shlr.w\t%T0", CC_NO_CARRY },
1865 { "shlr.l\t%S0", CC_NO_CARRY }
1867 /* SHIFT_ASHIFTRT */
1869 { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1870 { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1871 { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
1876 static const struct shift_insn shift_two[3][3] =
1880 { "shll.b\t#2,%X0", CC_NO_CARRY },
1881 { "shll.w\t#2,%T0", CC_NO_CARRY },
1882 { "shll.l\t#2,%S0", CC_NO_CARRY }
1884 /* SHIFT_LSHIFTRT */
1886 { "shlr.b\t#2,%X0", CC_NO_CARRY },
1887 { "shlr.w\t#2,%T0", CC_NO_CARRY },
1888 { "shlr.l\t#2,%S0", CC_NO_CARRY }
1890 /* SHIFT_ASHIFTRT */
1892 { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1893 { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1894 { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
1898 /* Rotates are organized by which shift they'll be used in implementing.
1899 There's no need to record whether the cc is valid afterwards because
1900 it is the AND insn that will decide this. */
1902 static const char *const rotate_one[2][3][3] =
1909 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
1912 /* SHIFT_LSHIFTRT */
1915 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
1918 /* SHIFT_ASHIFTRT */
1921 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
1933 /* SHIFT_LSHIFTRT */
1939 /* SHIFT_ASHIFTRT */
1948 static const char *const rotate_two[3][3] =
1956 /* SHIFT_LSHIFTRT */
1962 /* SHIFT_ASHIFTRT */
1970 /* Macros to keep the shift algorithm tables small. */
1971 #define INL SHIFT_INLINE
1972 #define ROT SHIFT_ROT_AND
1973 #define LOP SHIFT_LOOP
1974 #define SPC SHIFT_SPECIAL
1976 /* The shift algorithms for each machine, mode, shift type, and shift
1977 count are defined below. The three tables below correspond to
1978 QImode, HImode, and SImode, respectively. Each table is organized
1979 by, in the order of indecies, machine, shift type, and shift count. */
1981 static const enum shift_alg shift_alg_qi[3][3][8] = {
1984 /* 0 1 2 3 4 5 6 7 */
1985 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
1986 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
1987 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
1991 /* 0 1 2 3 4 5 6 7 */
1992 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
1993 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
1994 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
1998 /* 0 1 2 3 4 5 6 7 */
1999 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_ASHIFT */
2000 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_LSHIFTRT */
2001 { INL, INL, INL, INL, INL, INL, INL, SPC } /* SHIFT_ASHIFTRT */
2005 static const enum shift_alg shift_alg_hi[3][3][16] = {
2008 /* 0 1 2 3 4 5 6 7 */
2009 /* 8 9 10 11 12 13 14 15 */
2010 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2011 SPC, SPC, SPC, SPC, SPC, LOP, LOP, ROT }, /* SHIFT_ASHIFT */
2012 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2013 SPC, SPC, SPC, SPC, SPC, LOP, LOP, ROT }, /* SHIFT_LSHIFTRT */
2014 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2015 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2019 /* 0 1 2 3 4 5 6 7 */
2020 /* 8 9 10 11 12 13 14 15 */
2021 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2022 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2023 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2024 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2025 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2026 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2030 /* 0 1 2 3 4 5 6 7 */
2031 /* 8 9 10 11 12 13 14 15 */
2032 { INL, INL, INL, INL, INL, INL, INL, INL,
2033 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2034 { INL, INL, INL, INL, INL, INL, INL, INL,
2035 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2036 { INL, INL, INL, INL, INL, INL, INL, INL,
2037 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2041 static const enum shift_alg shift_alg_si[3][3][32] = {
2044 /* 0 1 2 3 4 5 6 7 */
2045 /* 8 9 10 11 12 13 14 15 */
2046 /* 16 17 18 19 20 21 22 23 */
2047 /* 24 25 26 27 28 29 30 31 */
2048 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2049 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2050 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2051 LOP, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
2052 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2053 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2054 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2055 LOP, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
2056 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2057 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2058 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2059 LOP, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2063 /* 0 1 2 3 4 5 6 7 */
2064 /* 8 9 10 11 12 13 14 15 */
2065 /* 16 17 18 19 20 21 22 23 */
2066 /* 24 25 26 27 28 29 30 31 */
2067 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
2068 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
2069 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
2070 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
2071 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
2072 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
2073 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
2074 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
2075 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
2076 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2077 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
2078 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2082 /* 0 1 2 3 4 5 6 7 */
2083 /* 8 9 10 11 12 13 14 15 */
2084 /* 16 17 18 19 20 21 22 23 */
2085 /* 24 25 26 27 28 29 30 31 */
2086 { INL, INL, INL, INL, INL, INL, INL, INL,
2087 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
2088 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
2089 SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
2090 { INL, INL, INL, INL, INL, INL, INL, INL,
2091 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
2092 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
2093 SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
2094 { INL, INL, INL, INL, INL, INL, INL, INL,
2095 INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2096 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
2097 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2107 /* Shift algorithm. */
2110 /* The number of bits to be shifted by shift1 and shift2. Valid
2111 when ALG is SHIFT_SPECIAL. */
2112 unsigned int remainder;
2114 /* Special insn for a shift. Valid when ALG is SHIFT_SPECIAL. */
2115 const char *special;
2117 /* Insn for a one-bit shift. Valid when ALG is either SHIFT_INLINE
2118 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2121 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
2122 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2125 /* Valid CC flags. */
2129 static void get_shift_alg PARAMS ((enum shift_type,
2130 enum shift_mode, unsigned int,
2131 struct shift_info *));
2133 /* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
2134 best algorithm for doing the shift. The assembler code is stored
2135 in the pointers in INFO. We don't achieve maximum efficiency in
2136 all cases, but the hooks are here to do so.
2138 For now we just use lots of switch statements. Since we don't even come
2139 close to supporting all the cases, this is simplest. If this function ever
2140 gets too big, perhaps resort to a more table based lookup. Of course,
2141 at this point you may just wish to do it all in rtl.
2143 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
2144 1,2,3,4 will be inlined (1,2 for SI). */
2147 get_shift_alg (shift_type, shift_mode, count, info)
2148 enum shift_type shift_type;
2149 enum shift_mode shift_mode;
2151 struct shift_info *info;
2155 /* Find the target CPU. */
2158 else if (TARGET_H8300H)
2163 /* Find the shift algorithm. */
2167 if (GET_MODE_BITSIZE (QImode) <= count)
2168 info->alg = SHIFT_LOOP;
2170 info->alg = shift_alg_qi[cpu][shift_type][count];
2174 if (GET_MODE_BITSIZE (HImode) <= count)
2175 info->alg = SHIFT_LOOP;
2177 info->alg = shift_alg_hi[cpu][shift_type][count];
2181 if (GET_MODE_BITSIZE (SImode) <= count)
2182 info->alg = SHIFT_LOOP;
2184 info->alg = shift_alg_si[cpu][shift_type][count];
2191 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
2195 info->remainder = count;
2199 /* It is up to the caller to know that looping clobbers cc. */
2200 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2201 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2202 info->cc_valid_p = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
2206 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
2207 info->shift2 = rotate_two[shift_type][shift_mode];
2208 info->cc_valid_p = 0;
2212 /* REMAINDER is 0 for most cases, so initialize it to 0. */
2213 info->remainder = 0;
2214 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2215 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2216 info->cc_valid_p = 0;
2220 /* Here we only deal with SHIFT_SPECIAL. */
2224 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2225 through the entire value. */
2226 if (shift_type == SHIFT_ASHIFTRT && count == 7)
2228 info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
2240 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";
2242 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
2244 case SHIFT_LSHIFTRT:
2246 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";
2248 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
2250 case SHIFT_ASHIFTRT:
2251 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
2255 else if (8 <= count && count <= 12)
2257 info->remainder = count - 8;
2262 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
2263 info->shift1 = "shal.b\t%t0";
2264 info->shift2 = "shal.b\t#2,%t0";
2266 case SHIFT_LSHIFTRT:
2267 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
2268 info->shift1 = "shlr.b\t%s0";
2269 info->shift2 = "shlr.b\t#2,%s0";
2271 case SHIFT_ASHIFTRT:
2273 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
2275 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
2276 info->shift1 = "shar.b\t%s0";
2277 info->shift2 = "shar.b\t#2,%s0";
2281 else if (count == 15 && shift_type == SHIFT_ASHIFTRT)
2283 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
2289 if (count == 8 && TARGET_H8300)
2294 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";
2296 case SHIFT_LSHIFTRT:
2297 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";
2299 case SHIFT_ASHIFTRT:
2300 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";
2304 else if (count == 8 && !TARGET_H8300)
2309 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";
2311 case SHIFT_LSHIFTRT:
2312 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";
2314 case SHIFT_ASHIFTRT:
2315 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";
2319 else if (count == 15 && !TARGET_H8300)
2324 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
2326 case SHIFT_LSHIFTRT:
2327 info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
2329 case SHIFT_ASHIFTRT:
2333 else if ((TARGET_H8300 && count == 16)
2334 || (TARGET_H8300H && 16 <= count && count <= 19)
2335 || (TARGET_H8300S && 16 <= count && count <= 21))
2337 info->remainder = count - 16;
2342 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2343 info->shift1 = "shll.l\t%S0";
2344 info->shift2 = "shll.l\t#2,%S0";
2346 case SHIFT_LSHIFTRT:
2347 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
2348 info->shift1 = "shlr.l\t%S0";
2349 info->shift2 = "shlr.l\t#2,%S0";
2351 case SHIFT_ASHIFTRT:
2353 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2355 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
2356 info->shift1 = "shar.l\t%S0";
2357 info->shift2 = "shar.l\t#2,%S0";
2361 else if ((TARGET_H8300H && count == 24)
2362 || (TARGET_H8300S && 24 <= count && count <= 25))
2364 info->remainder = count - 24;
2369 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";
2370 info->shift1 = "shll.l\t%S0";
2371 info->shift2 = "shll.l\t#2,%S0";
2373 case SHIFT_LSHIFTRT:
2374 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
2375 info->shift1 = "shlr.l\t%S0";
2376 info->shift2 = "shlr.l\t#2,%S0";
2378 case SHIFT_ASHIFTRT:
2379 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
2380 info->shift1 = "shar.l\t%S0";
2381 info->shift2 = "shar.l\t#2,%S0";
2385 else if (count == 31)
2392 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2394 case SHIFT_LSHIFTRT:
2395 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2397 case SHIFT_ASHIFTRT:
2398 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2407 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
2409 case SHIFT_LSHIFTRT:
2410 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
2412 case SHIFT_ASHIFTRT:
2413 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2426 info->shift2 = NULL;
2429 /* Emit the assembler code for doing shifts. */
2432 output_a_shift (operands)
2435 static int loopend_lab;
2436 rtx shift = operands[3];
2437 enum machine_mode mode = GET_MODE (shift);
2438 enum rtx_code code = GET_CODE (shift);
2439 enum shift_type shift_type;
2440 enum shift_mode shift_mode;
2441 struct shift_info info;
2448 shift_mode = QIshift;
2451 shift_mode = HIshift;
2454 shift_mode = SIshift;
2463 shift_type = SHIFT_ASHIFTRT;
2466 shift_type = SHIFT_LSHIFTRT;
2469 shift_type = SHIFT_ASHIFT;
2475 if (GET_CODE (operands[2]) != CONST_INT)
2477 /* Indexing by reg, so have to loop and test at top. */
2478 output_asm_insn ("mov.b %X2,%X4", operands);
2479 fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab);
2481 /* Get the assembler code to do one shift. */
2482 get_shift_alg (shift_type, shift_mode, 1, &info);
2484 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2485 output_asm_insn (info.shift1, operands);
2486 output_asm_insn ("add #0xff,%X4", operands);
2487 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2488 fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
2494 int n = INTVAL (operands[2]);
2496 /* If the count is negative, make it 0. */
2499 /* If the count is too big, truncate it.
2500 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2501 do the intuitive thing. */
2502 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
2503 n = GET_MODE_BITSIZE (mode);
2505 get_shift_alg (shift_type, shift_mode, n, &info);
2510 output_asm_insn (info.special, operands);
2516 /* Emit two bit shifts first. */
2517 if (info.shift2 != NULL)
2519 for (; n > 1; n -= 2)
2520 output_asm_insn (info.shift2, operands);
2523 /* Now emit one bit shifts for any residual. */
2525 output_asm_insn (info.shift1, operands);
2527 /* Keep track of CC. */
2528 if (info.cc_valid_p)
2530 cc_status.value1 = operands[0];
2531 cc_status.flags |= info.cc_valid_p;
2537 int m = GET_MODE_BITSIZE (mode) - n;
2538 int mask = (shift_type == SHIFT_ASHIFT
2539 ? ((1 << m) - 1) << n
2543 /* Not all possibilities of rotate are supported. They shouldn't
2544 be generated, but let's watch for 'em. */
2545 if (info.shift1 == 0)
2548 /* Emit two bit rotates first. */
2549 if (info.shift2 != NULL)
2551 for (; m > 1; m -= 2)
2552 output_asm_insn (info.shift2, operands);
2555 /* Now single bit rotates for any residual. */
2557 output_asm_insn (info.shift1, operands);
2559 /* Now mask off the high bits. */
2565 sprintf (insn_buf, "and\t#%d,%%X0", mask);
2566 cc_status.value1 = operands[0];
2567 cc_status.flags |= CC_NO_CARRY;
2570 sprintf (insn_buf, "and\t#%d,%%s0\n\tand\t#%d,%%t0",
2571 mask & 255, mask >> 8);
2579 sprintf (insn_buf, "and.%c\t#%d,%%%c0",
2580 "bwl"[shift_mode], mask,
2581 mode == QImode ? 'X' : mode == HImode ? 'T' : 'S');
2582 cc_status.value1 = operands[0];
2583 cc_status.flags |= CC_NO_CARRY;
2585 output_asm_insn (insn_buf, operands);
2590 /* A loop to shift by a "large" constant value.
2591 If we have shift-by-2 insns, use them. */
2592 if (info.shift2 != NULL)
2594 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
2595 names_big[REGNO (operands[4])]);
2596 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2597 output_asm_insn (info.shift2, operands);
2598 output_asm_insn ("add #0xff,%X4", operands);
2599 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2601 output_asm_insn (info.shift1, operands);
2605 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
2606 names_big[REGNO (operands[4])]);
2607 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2608 output_asm_insn (info.shift1, operands);
2609 output_asm_insn ("add #0xff,%X4", operands);
2610 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2620 /* A rotation by a non-constant will cause a loop to be generated, in
2621 which a rotation by one bit is used. A rotation by a constant,
2622 including the one in the loop, will be taken care of by
2623 emit_a_rotate () at the insn emit time. */
2626 expand_a_rotate (code, operands)
2630 rtx dst = operands[0];
2631 rtx src = operands[1];
2632 rtx rotate_amount = operands[2];
2633 enum machine_mode mode = GET_MODE (dst);
2636 /* We rotate in place. */
2637 emit_move_insn (dst, src);
2639 if (GET_CODE (rotate_amount) != CONST_INT)
2641 rtx counter = gen_reg_rtx (QImode);
2642 rtx start_label = gen_label_rtx ();
2643 rtx end_label = gen_label_rtx ();
2645 /* If the rotate amount is less than or equal to 0,
2646 we go out of the loop. */
2647 emit_cmp_and_jump_insns (rotate_amount, GEN_INT (0), LE, NULL_RTX,
2648 QImode, 0, end_label);
2650 /* Initialize the loop counter. */
2651 emit_move_insn (counter, rotate_amount);
2653 emit_label (start_label);
2655 /* Rotate by one bit. */
2656 tmp = gen_rtx (code, mode, dst, GEN_INT (1));
2657 emit_insn (gen_rtx_SET (mode, dst, tmp));
2659 /* Decrement the counter by 1. */
2660 tmp = gen_rtx_PLUS (QImode, counter, GEN_INT (-1));
2661 emit_insn (gen_rtx_SET (VOIDmode, counter, tmp));
2663 /* If the loop counter is non-zero, we go back to the beginning
2665 emit_cmp_and_jump_insns (counter, GEN_INT (0), NE, NULL_RTX, QImode, 1,
2668 emit_label (end_label);
2672 /* Rotate by AMOUNT bits. */
2673 tmp = gen_rtx (code, mode, dst, rotate_amount);
2674 emit_insn (gen_rtx_SET (mode, dst, tmp));
2680 /* Emit rotate insns. */
2683 emit_a_rotate (code, operands)
2687 rtx dst = operands[0];
2688 rtx rotate_amount = operands[2];
2689 enum shift_mode rotate_mode;
2690 enum shift_type rotate_type;
2691 const char *insn_buf;
2694 enum machine_mode mode = GET_MODE (dst);
2696 if (GET_CODE (rotate_amount) != CONST_INT)
2702 rotate_mode = QIshift;
2705 rotate_mode = HIshift;
2708 rotate_mode = SIshift;
2717 rotate_type = SHIFT_ASHIFT;
2720 rotate_type = SHIFT_LSHIFTRT;
2726 amount = INTVAL (rotate_amount);
2728 /* Clean up AMOUNT. */
2731 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
2732 amount = GET_MODE_BITSIZE (mode);
2734 /* Determine the faster direction. After this phase, amount will be
2735 at most a half of GET_MODE_BITSIZE (mode). */
2736 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / 2U)
2738 /* Flip the direction. */
2739 amount = GET_MODE_BITSIZE (mode) - amount;
2741 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
2744 /* See if a byte swap (in HImode) or a word swap (in SImode) can
2745 boost up the rotation. */
2746 if ((mode == HImode && TARGET_H8300 && amount >= 5)
2747 || (mode == HImode && TARGET_H8300H && amount >= 6)
2748 || (mode == HImode && TARGET_H8300S && amount == 8)
2749 || (mode == SImode && TARGET_H8300H && amount >= 10)
2750 || (mode == SImode && TARGET_H8300S && amount >= 13))
2755 /* This code works on any family. */
2756 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
2757 output_asm_insn (insn_buf, operands);
2761 /* This code works on the H8/300H and H8/S. */
2762 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
2763 output_asm_insn (insn_buf, operands);
2770 /* Adjust AMOUNT and flip the direction. */
2771 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
2773 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
2776 /* Emit rotate insns. */
2777 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2)
2780 insn_buf = rotate_two[rotate_type][rotate_mode];
2782 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode];
2784 for (; amount >= bits; amount -= bits)
2785 output_asm_insn (insn_buf, operands);
2791 /* Fix the operands of a gen_xxx so that it could become a bit
2795 fix_bit_operand (operands, what, type)
2800 /* The bit_operand predicate accepts any memory during RTL generation, but
2801 only 'U' memory afterwards, so if this is a MEM operand, we must force
2802 it to be valid for 'U' by reloading the address. */
2804 if (GET_CODE (operands[2]) == CONST_INT)
2806 if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), what))
2808 /* Ok to have a memory dest. */
2809 if (GET_CODE (operands[0]) == MEM
2810 && !EXTRA_CONSTRAINT (operands[0], 'U'))
2812 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
2813 copy_to_mode_reg (Pmode,
2814 XEXP (operands[0], 0)));
2815 MEM_COPY_ATTRIBUTES (mem, operands[0]);
2819 if (GET_CODE (operands[1]) == MEM
2820 && !EXTRA_CONSTRAINT (operands[1], 'U'))
2822 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
2823 copy_to_mode_reg (Pmode,
2824 XEXP (operands[1], 0)));
2825 MEM_COPY_ATTRIBUTES (mem, operands[0]);
2832 /* Dest and src op must be register. */
2834 operands[1] = force_reg (QImode, operands[1]);
2836 rtx res = gen_reg_rtx (QImode);
2837 emit_insn (gen_rtx_SET (VOIDmode, res,
2838 gen_rtx (type, QImode, operands[1], operands[2])));
2839 emit_insn (gen_rtx_SET (VOIDmode, operands[0], res));
2844 /* Return nonzero if FUNC is an interrupt function as specified
2845 by the "interrupt" attribute. */
2848 h8300_interrupt_function_p (func)
2853 if (TREE_CODE (func) != FUNCTION_DECL)
2856 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
2857 return a != NULL_TREE;
2860 /* Return nonzero if FUNC is an OS_Task function as specified
2861 by the "OS_Task" attribute. */
2864 h8300_os_task_function_p (func)
2869 if (TREE_CODE (func) != FUNCTION_DECL)
2872 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func));
2873 return a != NULL_TREE;
2876 /* Return nonzero if FUNC is a monitor function as specified
2877 by the "monitor" attribute. */
2880 h8300_monitor_function_p (func)
2885 if (TREE_CODE (func) != FUNCTION_DECL)
2888 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func));
2889 return a != NULL_TREE;
2892 /* Return nonzero if FUNC is a function that should be called
2893 through the function vector. */
2896 h8300_funcvec_function_p (func)
2901 if (TREE_CODE (func) != FUNCTION_DECL)
2904 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func));
2905 return a != NULL_TREE;
2908 /* Return nonzero if DECL is a variable that's in the eight bit
2912 h8300_eightbit_data_p (decl)
2917 if (TREE_CODE (decl) != VAR_DECL)
2920 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl));
2921 return a != NULL_TREE;
2924 /* Return nonzero if DECL is a variable that's in the tiny
2928 h8300_tiny_data_p (decl)
2933 if (TREE_CODE (decl) != VAR_DECL)
2936 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl));
2937 return a != NULL_TREE;
2940 /* Supported attributes:
2942 interrupt_handler: output a prologue and epilogue suitable for an
2945 function_vector: This function should be called through the
2948 eightbit_data: This variable lives in the 8-bit data area and can
2949 be referenced with 8-bit absolute memory addresses.
2951 tiny_data: This variable lives in the tiny data area and can be
2952 referenced with 16-bit absolute memory references. */
2954 const struct attribute_spec h8300_attribute_table[] =
2956 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
2957 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
2958 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
2959 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
2960 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
2961 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute },
2962 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute },
2963 { NULL, 0, 0, false, false, false, NULL }
2967 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
2968 struct attribute_spec.handler. */
2970 h8300_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
2973 tree args ATTRIBUTE_UNUSED;
2974 int flags ATTRIBUTE_UNUSED;
2977 if (TREE_CODE (*node) != FUNCTION_DECL)
2979 warning ("`%s' attribute only applies to functions",
2980 IDENTIFIER_POINTER (name));
2981 *no_add_attrs = true;
2987 /* Handle an "eightbit_data" attribute; arguments as in
2988 struct attribute_spec.handler. */
2990 h8300_handle_eightbit_data_attribute (node, name, args, flags, no_add_attrs)
2993 tree args ATTRIBUTE_UNUSED;
2994 int flags ATTRIBUTE_UNUSED;
2999 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
3001 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
3005 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3006 *no_add_attrs = true;
3012 /* Handle an "tiny_data" attribute; arguments as in
3013 struct attribute_spec.handler. */
3015 h8300_handle_tiny_data_attribute (node, name, args, flags, no_add_attrs)
3018 tree args ATTRIBUTE_UNUSED;
3019 int flags ATTRIBUTE_UNUSED;
3024 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
3026 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
3030 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3031 *no_add_attrs = true;
3038 h8300_encode_label (decl)
3041 const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
3042 int len = strlen (str);
3043 char *newstr = alloca (len + 2);
3046 strcpy (&newstr[1], str);
3048 XSTR (XEXP (DECL_RTL (decl), 0), 0) =
3049 ggc_alloc_string (newstr, len + 1);
3053 output_simode_bld (bild, operands)
3057 /* Clear the destination register. */
3058 if (TARGET_H8300H || TARGET_H8300S)
3059 output_asm_insn ("sub.l\t%S0,%S0", operands);
3061 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
3063 /* Now output the bit load or bit inverse load, and store it in
3066 output_asm_insn ("bild\t%Z2,%Y1\n\tbst\t#0,%w0", operands);
3068 output_asm_insn ("bld\t%Z2,%Y1\n\tbst\t#0,%w0", operands);
3074 /* Given INSN and its current length LENGTH, return the adjustment
3075 (in bytes) to correctly compute INSN's length.
3077 We use this to get the lengths of various memory references correct. */
3080 h8300_adjust_insn_length (insn, length)
3082 int length ATTRIBUTE_UNUSED;
3084 rtx pat = PATTERN (insn);
3086 /* We must filter these out before calling get_attr_adjust_length. */
3087 if (GET_CODE (pat) == USE
3088 || GET_CODE (pat) == CLOBBER
3089 || GET_CODE (pat) == SEQUENCE
3090 || GET_CODE (pat) == ADDR_VEC
3091 || GET_CODE (pat) == ADDR_DIFF_VEC)
3094 if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO)
3097 /* Adjust length for reg->mem and mem->reg copies. */
3098 if (GET_CODE (pat) == SET
3099 && (GET_CODE (SET_SRC (pat)) == MEM
3100 || GET_CODE (SET_DEST (pat)) == MEM))
3102 /* This insn might need a length adjustment. */
3105 if (GET_CODE (SET_SRC (pat)) == MEM)
3106 addr = XEXP (SET_SRC (pat), 0);
3108 addr = XEXP (SET_DEST (pat), 0);
3110 /* On the H8/300, only one adjustment is necessary; if the
3111 address mode is register indirect, then this insn is two
3112 bytes shorter than indicated in the machine description. */
3113 if (TARGET_H8300 && GET_CODE (addr) == REG)
3116 /* On the H8/300H and H8/S, register indirect is 6 bytes shorter than
3117 indicated in the machine description. */
3118 if ((TARGET_H8300H || TARGET_H8300S)
3119 && GET_CODE (addr) == REG)
3122 /* On the H8/300H and H8/S, reg + d, for small displacements is
3123 4 bytes shorter than indicated in the machine description. */
3124 if ((TARGET_H8300H || TARGET_H8300S)
3125 && GET_CODE (addr) == PLUS
3126 && GET_CODE (XEXP (addr, 0)) == REG
3127 && GET_CODE (XEXP (addr, 1)) == CONST_INT
3128 && INTVAL (XEXP (addr, 1)) > -32768
3129 && INTVAL (XEXP (addr, 1)) < 32767)
3132 /* On the H8/300H and H8/S, abs:16 is two bytes shorter than the
3133 more general abs:24. */
3134 if ((TARGET_H8300H || TARGET_H8300S)
3135 && GET_CODE (addr) == SYMBOL_REF
3136 && TINY_DATA_NAME_P (XSTR (addr, 0)))
3140 /* Loading some constants needs adjustment. */
3141 if (GET_CODE (pat) == SET
3142 && GET_CODE (SET_SRC (pat)) == CONST_INT
3143 && GET_MODE (SET_DEST (pat)) == SImode
3144 && INTVAL (SET_SRC (pat)) != 0)
3146 int val = INTVAL (SET_SRC (pat));
3149 && ((val & 0xffff) == 0
3150 || ((val >> 16) & 0xffff) == 0))
3153 if (TARGET_H8300H || TARGET_H8300S)
3155 if (val == (val & 0xff)
3156 || val == (val & 0xff00))
3159 if (val == -4 || val == -2 || val == -1)
3164 /* Shifts need various adjustments. */
3165 if (GET_CODE (pat) == PARALLEL
3166 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
3167 && (GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFTRT
3168 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == LSHIFTRT
3169 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFT))
3171 rtx src = SET_SRC (XVECEXP (pat, 0, 0));
3172 enum machine_mode mode = GET_MODE (src);
3175 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3178 shift = INTVAL (XEXP (src, 1));
3179 /* According to ANSI, negative shift is undefined. It is
3180 considered to be zero in this case (see function
3181 output_a_shift above). */
3185 /* QImode shifts by small constants take one insn
3186 per shift. So the adjustment is 20 (md length) -
3188 if (mode == QImode && shift <= 4)
3189 return -(20 - shift * 2);
3191 /* Similarly for HImode and SImode shifts by small constants on
3192 the H8/300H and H8/S. */
3193 if ((TARGET_H8300H || TARGET_H8300S)
3194 && (mode == HImode || mode == SImode) && shift <= 4)
3195 return -(20 - shift * 2);
3197 /* HImode shifts by small constants for the H8/300. */
3198 if (mode == HImode && shift <= 4)
3199 return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 2 : 4)));
3201 /* SImode shifts by small constants for the H8/300. */
3202 if (mode == SImode && shift <= 2)
3203 return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 6 : 8)));
3205 /* XXX ??? Could check for more shift/rotate cases here. */
3208 /* Rotations need various adjustments. */
3209 if (GET_CODE (pat) == SET
3210 && (GET_CODE (SET_SRC (pat)) == ROTATE
3211 || GET_CODE (SET_SRC (pat)) == ROTATERT))
3213 rtx src = SET_SRC (pat);
3214 enum machine_mode mode = GET_MODE (src);
3218 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3221 amount = INTVAL (XEXP (src, 1));
3223 /* Clean up AMOUNT. */
3226 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3227 amount = GET_MODE_BITSIZE (mode);
3229 /* Determine the faster direction. After this phase, amount
3230 will be at most a half of GET_MODE_BITSIZE (mode). */
3231 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / 2U)
3232 /* Flip the direction. */
3233 amount = GET_MODE_BITSIZE (mode) - amount;
3235 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3236 boost up the rotation. */
3237 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3238 || (mode == HImode && TARGET_H8300H && amount >= 6)
3239 || (mode == HImode && TARGET_H8300S && amount == 8)
3240 || (mode == SImode && TARGET_H8300H && amount >= 10)
3241 || (mode == SImode && TARGET_H8300S && amount >= 13))
3243 /* Adjust AMOUNT and flip the direction. */
3244 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3248 /* We use 2-bit rotatations on the H8/S. */
3250 amount = amount / 2 + amount % 2;
3252 /* The H8/300 uses three insns to rotate one bit, taking 6
3254 states += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2);
3256 return -(20 - states);
3262 #ifndef OBJECT_FORMAT_ELF
3264 h8300_asm_named_section (name, flags)
3266 unsigned int flags ATTRIBUTE_UNUSED;
3268 /* ??? Perhaps we should be using default_coff_asm_named_section. */
3269 fprintf (asm_out_file, "\t.section %s\n", name);
3271 #endif /* ! OBJECT_FORMAT_ELF */