* config/h8300/h8300.c: Fix formatting.
[official-gcc.git] / gcc / config / h8300 / h8300.c
blob7d984544efbdb7c081909d1a7256780b5af4aab7
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)
12 any later version.
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. */
24 #include "config.h"
25 #include "system.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "output.h"
34 #include "insn-attr.h"
35 #include "flags.h"
36 #include "recog.h"
37 #include "expr.h"
38 #include "function.h"
39 #include "toplev.h"
40 #include "c-pragma.h"
41 #include "tm_p.h"
42 #include "ggc.h"
43 #include "target.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));
65 #endif
67 /* CPU_TYPE, says what cpu we're compiling for. */
68 int cpu_type;
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). */
76 static int os_task;
78 /* True if the current function is a monitor
79 (via an attribute specification). */
80 static int monitor;
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. */
118 void
119 h8300_init_once ()
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" };
125 if (TARGET_H8300)
127 cpu_type = (int) CPU_H8300;
128 h8_reg_names = names_big;
130 else
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");
143 target_flags |= 1;
147 static const char *
148 byte_reg (x, b)
149 rtx x;
150 int b;
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) \
163 (regno < 7 \
164 /* No need to save registers if this function will not return. */ \
165 && ! TREE_THIS_VOLATILE (current_function_decl) \
166 && (pragma_saveall \
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 \
174 handlers. */ \
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. */
182 static void
183 dosize (file, op, size)
184 FILE *file;
185 const char *op;
186 unsigned int 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
190 immediate value.
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;
205 amount > 0;
206 amount /= 2)
208 for (; size >= amount; size -= amount)
209 fprintf (file, "\t%ss\t#%d,sp\n", op, amount);
212 else
214 if (TARGET_H8300)
215 fprintf (file, "\tmov.w\t#%d,r3\n\t%s.w\tr3,sp\n", size, op);
216 else
217 fprintf (file, "\t%s.l\t#%d,sp\n", op, size);
221 /* Round up frame size SIZE. */
223 static int
224 round_frame_size (size)
225 int 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. */
233 static unsigned int
234 compute_saved_regs ()
236 unsigned int saved_regs = 0;
237 int regno;
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);
250 return saved_regs;
253 /* Output assembly language code to push register RN. */
255 static void
256 push (file, rn)
257 FILE *file;
258 int 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. */
265 static void
266 pop (file, rn)
267 FILE *file;
268 int 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:
276 <args>
278 FP <- fp
279 <locals>
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:
285 <args>
287 <locals>
288 <saved registers> <- sp
291 /* Output assembly language code for the function prologue. */
293 static void
294 h8300_output_function_prologue (file, size)
295 FILE *file;
296 HOST_WIDE_INT size;
298 int fsize = round_frame_size (size);
299 int idx;
300 int saved_regs;
301 int n_regs;
303 /* Note a function with the interrupt attribute and set interrupt_handler
304 accordingly. */
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");
313 os_task = 1;
314 return;
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
321 mask interrupts. */
322 fprintf (file, ";monitor prologue\n");
323 interrupt_handler = 1;
324 monitor = 1;
325 if (TARGET_H8300)
327 fprintf (file, "\tsubs\t#2,sp\n");
328 push (file, 0);
329 fprintf (file, "\tstc\tccr,r0l\n");
330 fprintf (file, "\tmov.b\tr0l,@(2,sp)\n");
331 pop (file, 0);
332 fprintf (file, "\torc\t#128,ccr\n");
334 else if (TARGET_H8300H)
336 push (file, 0);
337 fprintf (file, "\tstc\tccr,r0l\n");
338 fprintf (file, "\tmov.b\tr0l,@(4,sp)\n");
339 pop (file, 0);
340 fprintf (file, "\torc\t#128,ccr\n");
342 else if (TARGET_H8300S)
344 fprintf (file, "\tstc\texr,@-sp\n");
345 push (file, 0);
346 fprintf (file, "\tstc\tccr,r0l\n");
347 fprintf (file, "\tmov.b\tr0l,@(6,sp)\n");
348 pop (file, 0);
349 fprintf (file, "\torc\t#128,ccr\n");
351 else
352 abort ();
355 if (frame_pointer_needed)
357 /* Push fp. */
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)
371 int regno = idx;
373 n_regs = 1;
374 if (saved_regs & (1 << regno))
376 if (TARGET_H8300S)
378 /* See how many registers we can push at the same time. */
379 if ((regno == 0 || regno == 4)
380 && ((saved_regs >> regno) & 0x0f) == 0x0f)
381 n_regs = 4;
383 else if ((regno == 0 || regno == 4)
384 && ((saved_regs >> regno) & 0x07) == 0x07)
385 n_regs = 3;
387 else if ((regno == 0 || regno == 2 || regno == 4 || regno == 6)
388 && ((saved_regs >> regno) & 0x03) == 0x03)
389 n_regs = 2;
392 if (n_regs == 1)
393 push (file, regno);
394 else
395 fprintf (file, "\tstm.l\t%s-%s,@-sp\n",
396 h8_reg_names[regno],
397 h8_reg_names[regno + (n_regs - 1)]);
402 /* Output assembly language code for the function epilogue. */
404 static void
405 h8300_output_function_epilogue (file, size)
406 FILE *file;
407 HOST_WIDE_INT size;
409 int fsize = round_frame_size (size);
410 int idx;
411 rtx insn = get_last_insn ();
412 int saved_regs;
413 int n_regs;
415 if (os_task)
417 /* OS_Task epilogues are nearly naked -- they just have an
418 rts instruction. */
419 fprintf (file, ";OS_task epilogue\n");
420 fprintf (file, "\trts\n");
421 goto out;
424 /* Monitor epilogues are the same as interrupt function epilogues.
425 Just make a note that we're in an monitor epilogue. */
426 if (monitor)
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)
433 goto out;
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;
441 n_regs = 1;
442 if (saved_regs & (1 << regno))
444 if (TARGET_H8300S)
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)
449 n_regs = 4;
451 else if ((regno == 6 || regno == 2)
452 && ((saved_regs >> (regno - 2)) & 0x07) == 0x07)
453 n_regs = 3;
455 else if ((regno == 7 || regno == 5 || regno == 3 || regno == 1)
456 && ((saved_regs >> (regno - 1)) & 0x03) == 0x03)
457 n_regs = 2;
460 if (n_regs == 1)
461 pop (file, regno);
462 else
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");
478 else
479 fprintf (file, "\trts\n");
481 out:
482 interrupt_handler = 0;
483 os_task = 0;
484 monitor = 0;
485 pragma_saveall = 0;
488 /* Output assembly code for the start of the file. */
490 void
491 asm_file_start (file)
492 FILE *file;
494 fprintf (file, ";\tGCC For the Hitachi H8/300\n");
495 fprintf (file, ";\tBy Hitachi America Ltd and Cygnus Support\n");
496 if (optimize)
497 fprintf (file, "; -O%d\n", optimize);
498 if (TARGET_H8300H)
499 fprintf (file, "\n\t.h8300h\n");
500 else if (TARGET_H8300S)
501 fprintf (file, "\n\t.h8300s\n");
502 else
503 fprintf (file, "\n\n");
504 output_file_directive (file, main_input_filename);
507 /* Output assembly language code for the end of file. */
509 void
510 asm_file_end (file)
511 FILE *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)
521 HOST_WIDE_INT 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
529 instruction. */
532 ok_for_bclr (value)
533 HOST_WIDE_INT value;
535 return small_power_of_two ((~value) & 0xff);
538 /* Return true if OP is a valid source operand for an integer move
539 instruction. */
542 general_operand_src (op, mode)
543 rtx op;
544 enum machine_mode mode;
546 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
547 return 1;
548 return general_operand (op, mode);
551 /* Return true if OP is a valid destination operand for an integer move
552 instruction. */
555 general_operand_dst (op, mode)
556 rtx op;
557 enum machine_mode mode;
559 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == PRE_DEC)
560 return 1;
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)
568 rtx operand;
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 valid call operand. */
578 call_insn_operand (op, mode)
579 rtx op;
580 enum machine_mode mode ATTRIBUTE_UNUSED;
582 if (GET_CODE (op) == MEM)
584 rtx inside = XEXP (op, 0);
585 if (register_operand (inside, Pmode))
586 return 1;
587 if (CONSTANT_ADDRESS_P (inside))
588 return 1;
590 return 0;
593 /* Return 1 if an addition/subtraction of a constant integer can be
594 transformed into two consecutive adds/subs that are faster than the
595 straightforward way. Otherwise, return 0. */
598 two_insn_adds_subs_operand (op, mode)
599 rtx op;
600 enum machine_mode mode;
602 if (GET_CODE (op) == CONST_INT)
604 HOST_WIDE_INT value = INTVAL (op);
606 /* Force VALUE to be positive so that we do not have to consider
607 the negative case. */
608 if (value < 0)
609 value = -value;
610 if (TARGET_H8300H || TARGET_H8300S)
612 /* A constant addition/subtraction takes 2 states in QImode,
613 4 states in HImode, and 6 states in SImode. Thus, the
614 only case we can win is when SImode is used, in which
615 case, two adds/subs are used, taking 4 states. */
616 if (mode == SImode
617 && (value == 2 + 1
618 || value == 4 + 1
619 || value == 4 + 2
620 || value == 4 + 4))
621 return 1;
623 else
625 /* We do not profit directly by splitting addition or
626 subtraction of 3 and 4. However, since these are
627 implemented as a sequence of adds or subs, they do not
628 clobber (cc0) unlike a sequence of add.b and add.x. */
629 if (mode == HImode
630 && (value == 2 + 1
631 || value == 2 + 2))
632 return 1;
636 return 0;
639 /* Split an add of a small constant into two adds/subs insns. */
641 void
642 split_adds_subs (mode, operands)
643 enum machine_mode mode;
644 rtx *operands;
646 HOST_WIDE_INT val = INTVAL (operands[1]);
647 rtx reg = operands[0];
648 HOST_WIDE_INT sign = 1;
649 HOST_WIDE_INT amount;
651 /* Force VAL to be positive so that we do not have to consider the
652 sign. */
653 if (val < 0)
655 val = -val;
656 sign = -1;
659 /* Try different amounts in descending order. */
660 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
661 amount > 0;
662 amount /= 2)
664 for (; val >= amount; val -= amount)
666 rtx tmp = gen_rtx_PLUS (mode, reg, GEN_INT (sign * amount));
667 emit_insn (gen_rtx_SET (VOIDmode, reg, tmp));
671 return;
674 /* Return true if OP is a valid call operand, and OP represents
675 an operand for a small call (4 bytes instead of 6 bytes). */
678 small_call_insn_operand (op, mode)
679 rtx op;
680 enum machine_mode mode ATTRIBUTE_UNUSED;
682 if (GET_CODE (op) == MEM)
684 rtx inside = XEXP (op, 0);
686 /* Register indirect is a small call. */
687 if (register_operand (inside, Pmode))
688 return 1;
690 /* A call through the function vector is a small
691 call too. */
692 if (GET_CODE (inside) == SYMBOL_REF
693 && SYMBOL_REF_FLAG (inside))
694 return 1;
696 /* Otherwise it's a large call. */
697 return 0;
700 /* Return true if OP is a valid jump operand. */
703 jump_address_operand (op, mode)
704 rtx op;
705 enum machine_mode mode;
707 if (GET_CODE (op) == REG)
708 return mode == Pmode;
710 if (GET_CODE (op) == MEM)
712 rtx inside = XEXP (op, 0);
713 if (register_operand (inside, Pmode))
714 return 1;
715 if (CONSTANT_ADDRESS_P (inside))
716 return 1;
718 return 0;
721 /* Recognize valid operands for bitfield instructions. */
723 extern int rtx_equal_function_value_matters;
726 bit_operand (op, mode)
727 rtx op;
728 enum machine_mode mode;
730 /* We can except any general operand, expept that MEM operands must
731 be limited to those that use addresses valid for the 'U' constraint. */
732 if (!general_operand (op, mode))
733 return 0;
735 /* Accept any mem during RTL generation. Otherwise, the code that does
736 insv and extzv will think that we can not handle memory. However,
737 to avoid reload problems, we only accept 'U' MEM operands after RTL
738 generation. This means that any named pattern which uses this predicate
739 must force its operands to match 'U' before emitting RTL. */
741 if (GET_CODE (op) == REG)
742 return 1;
743 if (GET_CODE (op) == SUBREG)
744 return 1;
745 if (!rtx_equal_function_value_matters)
746 /* We're building rtl. */
747 return GET_CODE (op) == MEM;
748 else
749 return (GET_CODE (op) == MEM
750 && EXTRA_CONSTRAINT (op, 'U'));
754 bit_memory_operand (op, mode)
755 rtx op;
756 enum machine_mode mode ATTRIBUTE_UNUSED;
758 return (GET_CODE (op) == MEM
759 && EXTRA_CONSTRAINT (op, 'U'));
762 /* Handle machine specific pragmas for compatibility with existing
763 compilers for the H8/300.
765 pragma saveall generates prolog/epilog code which saves and
766 restores all the registers on function entry.
768 pragma interrupt saves and restores all registers, and exits with
769 an rte instruction rather than an rts. A pointer to a function
770 with this attribute may be safely used in an interrupt vector. */
772 void
773 h8300_pr_interrupt (pfile)
774 cpp_reader *pfile ATTRIBUTE_UNUSED;
776 interrupt_handler = 1;
779 void
780 h8300_pr_saveall (pfile)
781 cpp_reader *pfile ATTRIBUTE_UNUSED;
783 pragma_saveall = 1;
786 /* If the next function argument with MODE and TYPE is to be passed in
787 a register, return a reg RTX for the hard register in which to pass
788 the argument. CUM represents the state after the last argument.
789 If the argument is to be pushed, NULL_RTX is returned. */
792 function_arg (cum, mode, type, named)
793 CUMULATIVE_ARGS *cum;
794 enum machine_mode mode;
795 tree type;
796 int named;
798 static const char *const hand_list[] = {
799 "__main",
800 "__cmpsi2",
801 "__divhi3",
802 "__modhi3",
803 "__udivhi3",
804 "__umodhi3",
805 "__divsi3",
806 "__modsi3",
807 "__udivsi3",
808 "__umodsi3",
809 "__mulhi3",
810 "__mulsi3",
811 "__reg_memcpy",
812 "__reg_memset",
813 "__ucmpsi2",
817 rtx result = NULL_RTX;
818 const char *fname;
819 int regpass = 0;
821 /* Never pass unnamed arguments in registers. */
822 if (!named)
823 return NULL_RTX;
825 /* Pass 3 regs worth of data in regs when user asked on the command line. */
826 if (TARGET_QUICKCALL)
827 regpass = 3;
829 /* If calling hand written assembler, use 4 regs of args. */
830 if (cum->libcall)
832 const char * const *p;
834 fname = XSTR (cum->libcall, 0);
836 /* See if this libcall is one of the hand coded ones. */
837 for (p = hand_list; *p && strcmp (*p, fname) != 0; p++)
840 if (*p)
841 regpass = 4;
844 if (regpass)
846 int size;
848 if (mode == BLKmode)
849 size = int_size_in_bytes (type);
850 else
851 size = GET_MODE_SIZE (mode);
853 if (size + cum->nbytes <= regpass * UNITS_PER_WORD
854 && cum->nbytes / UNITS_PER_WORD <= 3)
855 result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
858 return result;
861 /* Return the cost of the rtx R with code CODE. */
864 const_costs (r, c, outer_code)
865 rtx r;
866 enum rtx_code c;
867 enum rtx_code outer_code;
869 switch (c)
871 case CONST_INT:
872 switch (INTVAL (r))
874 case 0:
875 return 0;
876 case 1:
877 case 2:
878 case -1:
879 case -2:
880 return 0 + (outer_code == SET);
881 case 4:
882 case -4:
883 if (TARGET_H8300H || TARGET_H8300S)
884 return 0 + (outer_code == SET);
885 else
886 return 1;
887 default:
888 return 1;
891 case CONST:
892 case LABEL_REF:
893 case SYMBOL_REF:
894 return 3;
896 case CONST_DOUBLE:
897 return 20;
899 default:
900 return 4;
904 /* Documentation for the machine specific operand escapes:
906 'E' like s but negative.
907 'F' like t but negative.
908 'G' constant just the negative
909 'R' print operand as a byte:8 address if appropriate, else fall back to
910 'X' handling.
911 'S' print operand as a long word
912 'T' print operand as a word
913 'V' find the set bit, and print its number.
914 'W' find the clear bit, and print its number.
915 'X' print operand as a byte
916 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
917 If this operand isn't a register, fall back to 'R' handling.
918 'Z' print int & 7.
919 'b' print the bit opcode
920 'e' first word of 32 bit value - if reg, then least reg. if mem
921 then least. if const then most sig word
922 'f' second word of 32 bit value - if reg, then biggest reg. if mem
923 then +2. if const then least sig word
924 'j' print operand as condition code.
925 'k' print operand as reverse condition code.
926 's' print as low byte of 16 bit value
927 't' print as high byte of 16 bit value
928 'w' print as low byte of 32 bit value
929 'x' print as 2nd byte of 32 bit value
930 'y' print as 3rd byte of 32 bit value
931 'z' print as msb of 32 bit value
934 /* Return assembly language string which identifies a comparison type. */
936 static const char *
937 cond_string (code)
938 enum rtx_code code;
940 switch (code)
942 case NE:
943 return "ne";
944 case EQ:
945 return "eq";
946 case GE:
947 return "ge";
948 case GT:
949 return "gt";
950 case LE:
951 return "le";
952 case LT:
953 return "lt";
954 case GEU:
955 return "hs";
956 case GTU:
957 return "hi";
958 case LEU:
959 return "ls";
960 case LTU:
961 return "lo";
962 default:
963 abort ();
967 /* Print operand X using operand code CODE to assembly language output file
968 FILE. */
970 void
971 print_operand (file, x, code)
972 FILE *file;
973 rtx x;
974 int code;
976 /* This is used for communication between codes V,W,Z and Y. */
977 static int bitint;
979 switch (code)
981 case 'E':
982 switch (GET_CODE (x))
984 case REG:
985 fprintf (file, "%sl", names_big[REGNO (x)]);
986 break;
987 case CONST_INT:
988 fprintf (file, "#%d", (-INTVAL (x)) & 0xff);
989 break;
990 default:
991 abort ();
993 break;
994 case 'F':
995 switch (GET_CODE (x))
997 case REG:
998 fprintf (file, "%sh", names_big[REGNO (x)]);
999 break;
1000 case CONST_INT:
1001 fprintf (file, "#%d", ((-INTVAL (x)) & 0xff00) >> 8);
1002 break;
1003 default:
1004 abort ();
1006 break;
1007 case 'G':
1008 if (GET_CODE (x) != CONST_INT)
1009 abort ();
1010 fprintf (file, "#%d", 0xff & (-INTVAL (x)));
1011 break;
1012 case 'S':
1013 if (GET_CODE (x) == REG)
1014 fprintf (file, "%s", names_extended[REGNO (x)]);
1015 else
1016 goto def;
1017 break;
1018 case 'T':
1019 if (GET_CODE (x) == REG)
1020 fprintf (file, "%s", names_big[REGNO (x)]);
1021 else
1022 goto def;
1023 break;
1024 case 'V':
1025 bitint = exact_log2 (INTVAL (x));
1026 if (bitint == -1)
1027 abort ();
1028 fprintf (file, "#%d", bitint & 7);
1029 break;
1030 case 'W':
1031 bitint = exact_log2 ((~INTVAL (x)) & 0xff);
1032 if (bitint == -1)
1033 abort ();
1034 fprintf (file, "#%d", bitint & 7);
1035 break;
1036 case 'R':
1037 case 'X':
1038 if (GET_CODE (x) == REG)
1039 fprintf (file, "%s", byte_reg (x, 0));
1040 else
1041 goto def;
1042 break;
1043 case 'Y':
1044 if (bitint == -1)
1045 abort ();
1046 if (GET_CODE (x) == REG)
1047 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
1048 else
1049 print_operand (file, x, 'R');
1050 bitint = -1;
1051 break;
1052 case 'Z':
1053 bitint = INTVAL (x);
1054 fprintf (file, "#%d", bitint & 7);
1055 break;
1056 case 'b':
1057 switch (GET_CODE (x))
1059 case IOR:
1060 fprintf (file, "bor");
1061 break;
1062 case XOR:
1063 fprintf (file, "bxor");
1064 break;
1065 case AND:
1066 fprintf (file, "band");
1067 break;
1068 default:
1069 break;
1071 break;
1072 case 'e':
1073 switch (GET_CODE (x))
1075 case REG:
1076 if (TARGET_H8300)
1077 fprintf (file, "%s", names_big[REGNO (x)]);
1078 else
1079 fprintf (file, "%s", names_upper_extended[REGNO (x)]);
1080 break;
1081 case MEM:
1082 print_operand (file, x, 0);
1083 break;
1084 case CONST_INT:
1085 fprintf (file, "#%d", ((INTVAL (x) >> 16) & 0xffff));
1086 break;
1087 case CONST_DOUBLE:
1089 long val;
1090 REAL_VALUE_TYPE rv;
1091 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1092 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1093 fprintf (file, "#%ld", ((val >> 16) & 0xffff));
1094 break;
1096 default:
1097 abort ();
1098 break;
1100 break;
1101 case 'f':
1102 switch (GET_CODE (x))
1104 case REG:
1105 if (TARGET_H8300)
1106 fprintf (file, "%s", names_big[REGNO (x) + 1]);
1107 else
1108 fprintf (file, "%s", names_big[REGNO (x)]);
1109 break;
1110 case MEM:
1111 x = adjust_address (x, HImode, 2);
1112 print_operand (file, x, 0);
1113 break;
1114 case CONST_INT:
1115 fprintf (file, "#%d", INTVAL (x) & 0xffff);
1116 break;
1117 case CONST_DOUBLE:
1119 long val;
1120 REAL_VALUE_TYPE rv;
1121 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1122 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1123 fprintf (file, "#%ld", (val & 0xffff));
1124 break;
1126 default:
1127 abort ();
1129 break;
1130 case 'j':
1131 asm_fprintf (file, cond_string (GET_CODE (x)));
1132 break;
1133 case 'k':
1134 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
1135 break;
1136 case 's':
1137 if (GET_CODE (x) == CONST_INT)
1138 fprintf (file, "#%d", (INTVAL (x)) & 0xff);
1139 else
1140 fprintf (file, "%s", byte_reg (x, 0));
1141 break;
1142 case 't':
1143 if (GET_CODE (x) == CONST_INT)
1144 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1145 else
1146 fprintf (file, "%s", byte_reg (x, 1));
1147 break;
1148 case 'u':
1149 if (GET_CODE (x) != CONST_INT)
1150 abort ();
1151 fprintf (file, "%d", INTVAL (x));
1152 break;
1153 case 'w':
1154 if (GET_CODE (x) == CONST_INT)
1155 fprintf (file, "#%d", INTVAL (x) & 0xff);
1156 else
1157 fprintf (file, "%s",
1158 byte_reg (x, TARGET_H8300 ? 2 : 0));
1159 break;
1160 case 'x':
1161 if (GET_CODE (x) == CONST_INT)
1162 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1163 else
1164 fprintf (file, "%s",
1165 byte_reg (x, TARGET_H8300 ? 3 : 1));
1166 break;
1167 case 'y':
1168 if (GET_CODE (x) == CONST_INT)
1169 fprintf (file, "#%d", (INTVAL (x) >> 16) & 0xff);
1170 else
1171 fprintf (file, "%s", byte_reg (x, 0));
1172 break;
1173 case 'z':
1174 if (GET_CODE (x) == CONST_INT)
1175 fprintf (file, "#%d", (INTVAL (x) >> 24) & 0xff);
1176 else
1177 fprintf (file, "%s", byte_reg (x, 1));
1178 break;
1180 default:
1181 def:
1182 switch (GET_CODE (x))
1184 case REG:
1185 switch (GET_MODE (x))
1187 case QImode:
1188 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */
1189 fprintf (file, "%s", byte_reg (x, 0));
1190 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1191 fprintf (file, "%s", names_big[REGNO (x)]);
1192 #endif
1193 break;
1194 case HImode:
1195 fprintf (file, "%s", names_big[REGNO (x)]);
1196 break;
1197 case SImode:
1198 case SFmode:
1199 fprintf (file, "%s", names_extended[REGNO (x)]);
1200 break;
1201 default:
1202 abort ();
1204 break;
1206 case MEM:
1208 rtx addr = XEXP (x, 0);
1210 fprintf (file, "@");
1211 output_address (addr);
1213 /* If this is an 'R' operand (reference into the 8-bit
1214 area), then specify a symbolic address as "foo:8",
1215 otherwise if operand is still in eight bit section, use
1216 "foo:16". */
1217 if (GET_CODE (addr) == SYMBOL_REF
1218 && SYMBOL_REF_FLAG (addr))
1219 fprintf (file, (code == 'R' ? ":8" : ":16"));
1220 else if (GET_CODE (addr) == SYMBOL_REF
1221 && TINY_DATA_NAME_P (XSTR (addr, 0)))
1222 fprintf (file, ":16");
1223 else if ((code == 'R')
1224 && EIGHTBIT_CONSTANT_ADDRESS_P (addr))
1225 fprintf (file, ":8");
1227 break;
1229 case CONST_INT:
1230 case SYMBOL_REF:
1231 case CONST:
1232 case LABEL_REF:
1233 fprintf (file, "#");
1234 print_operand_address (file, x);
1235 break;
1236 case CONST_DOUBLE:
1238 long val;
1239 REAL_VALUE_TYPE rv;
1240 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1241 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1242 fprintf (file, "#%ld", val);
1243 break;
1245 default:
1246 break;
1251 /* Output assembly language output for the address ADDR to FILE. */
1253 void
1254 print_operand_address (file, addr)
1255 FILE *file;
1256 rtx addr;
1258 switch (GET_CODE (addr))
1260 case REG:
1261 fprintf (file, "%s", h8_reg_names[REGNO (addr)]);
1262 break;
1264 case PRE_DEC:
1265 fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
1266 break;
1268 case POST_INC:
1269 fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);
1270 break;
1272 case PLUS:
1273 fprintf (file, "(");
1274 if (GET_CODE (XEXP (addr, 0)) == REG)
1276 /* reg,foo */
1277 print_operand_address (file, XEXP (addr, 1));
1278 fprintf (file, ",");
1279 print_operand_address (file, XEXP (addr, 0));
1281 else
1283 /* foo+k */
1284 print_operand_address (file, XEXP (addr, 0));
1285 fprintf (file, "+");
1286 print_operand_address (file, XEXP (addr, 1));
1288 fprintf (file, ")");
1289 break;
1291 case CONST_INT:
1293 /* Since the H8/300 only has 16 bit pointers, negative values are also
1294 those >= 32768. This happens for example with pointer minus a
1295 constant. We don't want to turn (char *p - 2) into
1296 (char *p + 65534) because loop unrolling can build upon this
1297 (IE: char *p + 131068). */
1298 int n = INTVAL (addr);
1299 if (TARGET_H8300)
1300 n = (int) (short) n;
1301 if (n < 0)
1302 /* ??? Why the special case for -ve values? */
1303 fprintf (file, "-%d", -n);
1304 else
1305 fprintf (file, "%d", n);
1306 break;
1309 default:
1310 output_addr_const (file, addr);
1311 break;
1315 /* Output all insn addresses and their sizes into the assembly language
1316 output file. This is helpful for debugging whether the length attributes
1317 in the md file are correct. This is not meant to be a user selectable
1318 option. */
1320 void
1321 final_prescan_insn (insn, operand, num_operands)
1322 rtx insn, *operand ATTRIBUTE_UNUSED;
1323 int num_operands ATTRIBUTE_UNUSED;
1325 /* This holds the last insn address. */
1326 static int last_insn_address = 0;
1328 int uid = INSN_UID (insn);
1330 if (TARGET_RTL_DUMP)
1332 fprintf (asm_out_file, "\n****************");
1333 print_rtl (asm_out_file, PATTERN (insn));
1334 fprintf (asm_out_file, "\n");
1337 if (TARGET_ADDRESSES)
1339 fprintf (asm_out_file, "; 0x%x %d\n", INSN_ADDRESSES (uid),
1340 INSN_ADDRESSES (uid) - last_insn_address);
1341 last_insn_address = INSN_ADDRESSES (uid);
1345 /* Prepare for an SI sized move. */
1348 do_movsi (operands)
1349 rtx operands[];
1351 rtx src = operands[1];
1352 rtx dst = operands[0];
1353 if (!reload_in_progress && !reload_completed)
1355 if (!register_operand (dst, GET_MODE (dst)))
1357 rtx tmp = gen_reg_rtx (GET_MODE (dst));
1358 emit_move_insn (tmp, src);
1359 operands[1] = tmp;
1362 return 0;
1365 /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
1366 Define the offset between two registers, one to be eliminated, and
1367 the other its replacement, at the start of a routine. */
1370 initial_offset (from, to)
1371 int from, to;
1373 int offset = 0;
1375 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1376 offset = UNITS_PER_WORD + frame_pointer_needed * UNITS_PER_WORD;
1377 else if (from == RETURN_ADDRESS_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1378 offset = frame_pointer_needed * UNITS_PER_WORD;
1379 else
1381 int regno;
1383 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1384 if (WORD_REG_USED (regno))
1385 offset += UNITS_PER_WORD;
1387 /* See the comments for get_frame_size. We need to round it up to
1388 STACK_BOUNDARY. */
1390 offset += ((get_frame_size () + STACK_BOUNDARY / BITS_PER_UNIT - 1)
1391 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
1393 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1394 offset += UNITS_PER_WORD; /* Skip saved PC */
1396 return offset;
1400 h8300_return_addr_rtx (count, frame)
1401 int count;
1402 rtx frame;
1404 rtx ret;
1406 if (count == 0)
1407 ret = gen_rtx_MEM (Pmode,
1408 gen_rtx_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM));
1409 else if (flag_omit_frame_pointer)
1410 return (rtx) 0;
1411 else
1412 ret = gen_rtx_MEM (Pmode,
1413 memory_address (Pmode,
1414 plus_constant (frame, UNITS_PER_WORD)));
1415 set_mem_alias_set (ret, get_frame_alias_set ());
1416 return ret;
1419 /* Update the condition code from the insn. */
1421 void
1422 notice_update_cc (body, insn)
1423 rtx body;
1424 rtx insn;
1426 switch (get_attr_cc (insn))
1428 case CC_NONE:
1429 /* Insn does not affect CC at all. */
1430 break;
1432 case CC_NONE_0HIT:
1433 /* Insn does not change CC, but the 0'th operand has been changed. */
1434 if (cc_status.value1 != 0
1435 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
1436 cc_status.value1 = 0;
1437 if (cc_status.value2 != 0
1438 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value2))
1439 cc_status.value2 = 0;
1440 break;
1442 case CC_SET_ZN:
1443 /* Insn sets the Z,N flags of CC to recog_data.operand[0].
1444 The V flag is unusable. The C flag may or may not be known but
1445 that's ok because alter_cond will change tests to use EQ/NE. */
1446 CC_STATUS_INIT;
1447 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
1448 cc_status.value1 = recog_data.operand[0];
1449 break;
1451 case CC_SET_ZNV:
1452 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
1453 The C flag may or may not be known but that's ok because
1454 alter_cond will change tests to use EQ/NE. */
1455 CC_STATUS_INIT;
1456 cc_status.flags |= CC_NO_CARRY;
1457 cc_status.value1 = recog_data.operand[0];
1458 if (GET_CODE (body) == SET && REG_P (SET_SRC (body)))
1459 cc_status.value2 = SET_SRC (body);
1460 break;
1462 case CC_COMPARE:
1463 /* The insn is a compare instruction. */
1464 CC_STATUS_INIT;
1465 cc_status.value1 = SET_SRC (body);
1466 break;
1468 case CC_CLOBBER:
1469 /* Insn doesn't leave CC in a usable state. */
1470 CC_STATUS_INIT;
1471 break;
1475 /* Recognize valid operators for bit instructions. */
1478 bit_operator (x, mode)
1479 rtx x;
1480 enum machine_mode mode ATTRIBUTE_UNUSED;
1482 enum rtx_code code = GET_CODE (x);
1484 return (code == XOR
1485 || code == AND
1486 || code == IOR);
1489 const char *
1490 output_logical_op (mode, operands)
1491 enum machine_mode mode;
1492 rtx *operands;
1494 /* Figure out the logical op that we need to perform. */
1495 enum rtx_code code = GET_CODE (operands[3]);
1496 /* Pretend that every byte is affected if both operands are registers. */
1497 unsigned HOST_WIDE_INT intval =
1498 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
1499 ? INTVAL (operands[2]) : 0x55555555);
1500 /* The determinant of the algorithm. If we perform an AND, 0
1501 affects a bit. Otherwise, 1 affects a bit. */
1502 unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
1503 /* The name of an insn. */
1504 const char *opname;
1505 char insn_buf[100];
1507 switch (code)
1509 case AND:
1510 opname = "and";
1511 break;
1512 case IOR:
1513 opname = "or";
1514 break;
1515 case XOR:
1516 opname = "xor";
1517 break;
1518 default:
1519 abort ();
1522 switch (mode)
1524 case HImode:
1525 /* First, see if we can finish with one insn. */
1526 if ((TARGET_H8300H || TARGET_H8300S)
1527 && ((det & 0x00ff) != 0)
1528 && ((det & 0xff00) != 0))
1530 sprintf (insn_buf, "%s.w\t%%T2,%%T0", opname);
1531 output_asm_insn (insn_buf, operands);
1533 else
1535 /* Take care of the lower byte. */
1536 if ((det & 0x00ff) != 0)
1538 sprintf (insn_buf, "%s\t%%s2,%%s0", opname);
1539 output_asm_insn (insn_buf, operands);
1541 /* Take care of the upper byte. */
1542 if ((det & 0xff00) != 0)
1544 sprintf (insn_buf, "%s\t%%t2,%%t0", opname);
1545 output_asm_insn (insn_buf, operands);
1548 break;
1549 case SImode:
1550 /* First, see if we can finish with one insn.
1552 If code is either AND or XOR, we exclude two special cases,
1553 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
1554 can do a better job. */
1555 if ((TARGET_H8300H || TARGET_H8300S)
1556 && ((det & 0x0000ffff) != 0)
1557 && ((det & 0xffff0000) != 0)
1558 && (code == IOR || det != 0xffffff00)
1559 && (code == IOR || det != 0xffff00ff))
1561 sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname);
1562 output_asm_insn (insn_buf, operands);
1564 else
1566 /* Take care of the lower and upper words individually. For
1567 each word, we try different methods in the order of
1569 1) the special insn (in case of AND or XOR),
1570 2) the word-wise insn, and
1571 3) The byte-wise insn. */
1572 if ((det & 0x0000ffff) == 0x0000ffff
1573 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
1574 output_asm_insn ((code == AND)
1575 ? "sub.w\t%f0,%f0" : "not.w\t%f0",
1576 operands);
1577 else if ((TARGET_H8300H || TARGET_H8300S)
1578 && ((det & 0x000000ff) != 0)
1579 && ((det & 0x0000ff00) != 0))
1581 sprintf (insn_buf, "%s.w\t%%f2,%%f0", opname);
1582 output_asm_insn (insn_buf, operands);
1584 else
1586 if ((det & 0x000000ff) != 0)
1588 sprintf (insn_buf, "%s\t%%w2,%%w0", opname);
1589 output_asm_insn (insn_buf, operands);
1591 if ((det & 0x0000ff00) != 0)
1593 sprintf (insn_buf, "%s\t%%x2,%%x0", opname);
1594 output_asm_insn (insn_buf, operands);
1598 if ((det & 0xffff0000) == 0xffff0000
1599 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
1600 output_asm_insn ((code == AND)
1601 ? "sub.w\t%e0,%e0" : "not.w\t%e0",
1602 operands);
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);
1611 else
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);
1625 break;
1626 default:
1627 abort ();
1629 return "";
1632 unsigned int
1633 compute_logical_op_length (mode, operands)
1634 enum machine_mode mode;
1635 rtx *operands;
1637 /* Figure out the logical op that we need to perform. */
1638 enum rtx_code code = GET_CODE (operands[3]);
1639 /* Pretend that every byte is affected if both operands are registers. */
1640 unsigned HOST_WIDE_INT intval =
1641 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
1642 ? INTVAL (operands[2]) : 0x55555555);
1643 /* The determinant of the algorithm. If we perform an AND, 0
1644 affects a bit. Otherwise, 1 affects a bit. */
1645 unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
1646 /* Insn length. */
1647 unsigned int length = 0;
1649 switch (mode)
1651 case HImode:
1652 /* First, see if we can finish with one insn. */
1653 if ((TARGET_H8300H || TARGET_H8300S)
1654 && ((det & 0x00ff) != 0)
1655 && ((det & 0xff00) != 0))
1657 if (REG_P (operands[2]))
1658 length += 2;
1659 else
1660 length += 4;
1662 else
1664 /* Take care of the lower byte. */
1665 if ((det & 0x00ff) != 0)
1666 length += 2;
1668 /* Take care of the upper byte. */
1669 if ((det & 0xff00) != 0)
1670 length += 2;
1672 break;
1673 case SImode:
1674 /* First, see if we can finish with one insn.
1676 If code is either AND or XOR, we exclude two special cases,
1677 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
1678 can do a better job. */
1679 if ((TARGET_H8300H || TARGET_H8300S)
1680 && ((det & 0x0000ffff) != 0)
1681 && ((det & 0xffff0000) != 0)
1682 && (code == IOR || det != 0xffffff00)
1683 && (code == IOR || det != 0xffff00ff))
1685 if (REG_P (operands[2]))
1686 length += 4;
1687 else
1688 length += 6;
1690 else
1692 /* Take care of the lower and upper words individually. For
1693 each word, we try different methods in the order of
1695 1) the special insn (in case of AND or XOR),
1696 2) the word-wise insn, and
1697 3) The byte-wise insn. */
1698 if ((det & 0x0000ffff) == 0x0000ffff
1699 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
1701 length += 2;
1703 else if ((TARGET_H8300H || TARGET_H8300S)
1704 && ((det & 0x000000ff) != 0)
1705 && ((det & 0x0000ff00) != 0))
1707 length += 4;
1709 else
1711 if ((det & 0x000000ff) != 0)
1712 length += 2;
1714 if ((det & 0x0000ff00) != 0)
1715 length += 2;
1718 if ((det & 0xffff0000) == 0xffff0000
1719 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
1721 length += 2;
1723 else if (TARGET_H8300H || TARGET_H8300S)
1725 if ((det & 0xffff0000) != 0)
1726 length += 4;
1728 else
1730 if ((det & 0x00ff0000) != 0)
1731 length += 2;
1733 if ((det & 0xff000000) != 0)
1734 length += 2;
1737 break;
1738 default:
1739 abort ();
1741 return length;
1745 compute_logical_op_cc (mode, operands)
1746 enum machine_mode mode;
1747 rtx *operands;
1749 /* Figure out the logical op that we need to perform. */
1750 enum rtx_code code = GET_CODE (operands[3]);
1751 /* Pretend that every byte is affected if both operands are registers. */
1752 unsigned HOST_WIDE_INT intval =
1753 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
1754 ? INTVAL (operands[2]) : 0x55555555);
1755 /* The determinant of the algorithm. If we perform an AND, 0
1756 affects a bit. Otherwise, 1 affects a bit. */
1757 unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
1758 /* Condition code. */
1759 enum attr_cc cc = CC_CLOBBER;
1761 switch (mode)
1763 case HImode:
1764 /* First, see if we can finish with one insn. */
1765 if ((TARGET_H8300H || TARGET_H8300S)
1766 && ((det & 0x00ff) != 0)
1767 && ((det & 0xff00) != 0))
1769 cc = CC_SET_ZNV;
1771 break;
1772 case SImode:
1773 /* First, see if we can finish with one insn.
1775 If code is either AND or XOR, we exclude two special cases,
1776 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
1777 can do a better job. */
1778 if ((TARGET_H8300H || TARGET_H8300S)
1779 && ((det & 0x0000ffff) != 0)
1780 && ((det & 0xffff0000) != 0)
1781 && (code == IOR || det != 0xffffff00)
1782 && (code == IOR || det != 0xffff00ff))
1784 cc = CC_SET_ZNV;
1786 break;
1787 default:
1788 abort ();
1790 return cc;
1793 /* Shifts.
1795 We devote a fair bit of code to getting efficient shifts since we
1796 can only shift one bit at a time on the H8/300 and H8/300H and only
1797 one or two bits at a time on the H8/S.
1799 All shift code falls into one of the following ways of
1800 implementation:
1802 o SHIFT_INLINE: Emit straight line code for the shift; this is used
1803 when a straight line shift is about the same size or smaller than
1804 a loop.
1806 o SHIFT_ROT_AND: Rotate the value the opposite direction, then mask
1807 off the bits we don't need. This is used when only a few of the
1808 bits in the original value will survive in the shifted value.
1810 o SHIFT_SPECIAL: Often it's possible to move a byte or a word to
1811 simulate a shift by 8, 16, or 24 bits. Once moved, a few inline
1812 shifts can be added if the shift count is slightly more than 8 or
1813 16. This case also includes other oddballs that are not worth
1814 explaning here.
1816 o SHIFT_LOOP: Emit a loop using one (or two on H8/S) bit shifts.
1818 Here are some thoughts on what the absolutely positively best code
1819 is. "Best" here means some rational trade-off between code size
1820 and speed, where speed is more preferred but not at the expense of
1821 generating 20 insns.
1823 Below, a trailing '*' after the shift count indicates the "best"
1824 mode isn't implemented. We only describe SHIFT_SPECIAL cases to
1825 simplify the table. For other cases, refer to shift_alg_[qhs]i.
1827 H8/300 QImode shifts
1828 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
1830 H8/300 HImode shifts
1831 7 - shift 2nd half other way into carry.
1832 copy 1st half into 2nd half
1833 rotate 2nd half other way with carry
1834 rotate 1st half other way (no carry)
1835 mask off bits in 1st half (ASHIFT | LSHIFTRT).
1836 sign extend 1st half (ASHIFTRT)
1837 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1838 9-12 - do shift by 8, inline remaining shifts
1839 15 - ASHIFTRT: shll, subx, set other byte
1841 H8/300 SImode shifts
1842 7* - shift other way once, move bytes into place,
1843 move carry into place (possibly with sign extension)
1844 8 - move bytes into place, zero or sign extend other
1845 15* - shift other way once, move word into place, move carry into place
1846 16 - move word, zero or sign extend other
1847 24* - move bytes into place, zero or sign extend other
1848 31 - ASHIFTRT: shll top byte, subx, copy to other bytes
1850 H8/300H QImode shifts (same as H8/300 QImode shifts)
1851 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
1853 H8/300H HImode shifts
1854 7 - shift 2nd half other way into carry.
1855 copy 1st half into 2nd half
1856 rotate entire word other way using carry
1857 mask off remaining bits (ASHIFT | LSHIFTRT)
1858 sign extend remaining bits (ASHIFTRT)
1859 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1860 9-12 - do shift by 8, inline remaining shifts
1861 15 - ASHIFTRT: shll, subx, set other byte
1863 H8/300H SImode shifts
1864 (These are complicated by the fact that we don't have byte level access to
1865 the top word.)
1866 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1867 15* - shift other way once, move word into place, move carry into place
1868 (with sign extension for ASHIFTRT)
1869 16 - move word into place, zero or sign extend other
1870 17-20 - do 16bit shift, then inline remaining shifts
1871 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1872 move word 0 to word 1, zero word 0
1873 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1874 zero word 1, zero byte 1
1875 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1876 sign extend byte 0, sign extend word 0
1877 25-27* - either loop, or
1878 do 24 bit shift, inline rest
1879 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1881 H8/S QImode shifts
1882 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
1884 H8/S HImode shifts
1885 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1886 9-12 - do shift by 8, inline remaining shifts
1887 15 - ASHIFTRT: shll, subx, set other byte
1889 H8/S SImode shifts
1890 (These are complicated by the fact that we don't have byte level access to
1891 the top word.)
1892 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1893 15* - shift other way once, move word into place, move carry into place
1894 (with sign extension for ASHIFTRT)
1895 16 - move word into place, zero or sign extend other
1896 17-20 - do 16bit shift, then inline remaining shifts
1897 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1898 move word 0 to word 1, zero word 0
1899 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1900 zero word 1, zero byte 1
1901 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1902 sign extend byte 0, sign extend word 0
1903 25-27* - either loop, or
1904 do 24 bit shift, inline rest
1905 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1907 Panic!!! */
1910 nshift_operator (x, mode)
1911 rtx x;
1912 enum machine_mode mode ATTRIBUTE_UNUSED;
1914 switch (GET_CODE (x))
1916 case ASHIFTRT:
1917 case LSHIFTRT:
1918 case ASHIFT:
1919 return 1;
1921 default:
1922 return 0;
1926 /* Called from the .md file to emit code to do shifts.
1927 Return a boolean indicating success.
1928 (Currently this is always TRUE). */
1931 expand_a_shift (mode, code, operands)
1932 enum machine_mode mode;
1933 int code;
1934 rtx operands[];
1936 emit_move_insn (operands[0], operands[1]);
1938 /* Need a loop to get all the bits we want - we generate the
1939 code at emit time, but need to allocate a scratch reg now. */
1941 emit_insn (gen_rtx_PARALLEL
1942 (VOIDmode,
1943 gen_rtvec (2,
1944 gen_rtx_SET (VOIDmode, operands[0],
1945 gen_rtx (code, mode, operands[0],
1946 operands[2])),
1947 gen_rtx_CLOBBER (VOIDmode,
1948 gen_rtx_SCRATCH (QImode)))));
1950 return 1;
1953 /* See above for explanation of this enum. */
1955 enum shift_alg
1957 SHIFT_INLINE,
1958 SHIFT_ROT_AND,
1959 SHIFT_SPECIAL,
1960 SHIFT_LOOP
1963 /* Symbols of the various shifts which can be used as indices. */
1965 enum shift_type
1967 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
1970 /* Symbols of the various modes which can be used as indices. */
1972 enum shift_mode
1974 QIshift, HIshift, SIshift
1977 /* For single bit shift insns, record assembler and what bits of the
1978 condition code are valid afterwards (represented as various CC_FOO
1979 bits, 0 means CC isn't left in a usable state). */
1981 struct shift_insn
1983 const char *const assembler;
1984 const int cc_valid;
1987 /* Assembler instruction shift table.
1989 These tables are used to look up the basic shifts.
1990 They are indexed by cpu, shift_type, and mode. */
1992 static const struct shift_insn shift_one[2][3][3] =
1994 /* H8/300 */
1996 /* SHIFT_ASHIFT */
1998 { "shll\t%X0", CC_NO_CARRY },
1999 { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2000 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }
2002 /* SHIFT_LSHIFTRT */
2004 { "shlr\t%X0", CC_NO_CARRY },
2005 { "shlr\t%t0\n\trotxr\t%s0", 0 },
2006 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
2008 /* SHIFT_ASHIFTRT */
2010 { "shar\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2011 { "shar\t%t0\n\trotxr\t%s0", 0 },
2012 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
2015 /* H8/300H */
2017 /* SHIFT_ASHIFT */
2019 { "shll.b\t%X0", CC_NO_CARRY },
2020 { "shll.w\t%T0", CC_NO_CARRY },
2021 { "shll.l\t%S0", CC_NO_CARRY }
2023 /* SHIFT_LSHIFTRT */
2025 { "shlr.b\t%X0", CC_NO_CARRY },
2026 { "shlr.w\t%T0", CC_NO_CARRY },
2027 { "shlr.l\t%S0", CC_NO_CARRY }
2029 /* SHIFT_ASHIFTRT */
2031 { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2032 { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2033 { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
2038 static const struct shift_insn shift_two[3][3] =
2040 /* SHIFT_ASHIFT */
2042 { "shll.b\t#2,%X0", CC_NO_CARRY },
2043 { "shll.w\t#2,%T0", CC_NO_CARRY },
2044 { "shll.l\t#2,%S0", CC_NO_CARRY }
2046 /* SHIFT_LSHIFTRT */
2048 { "shlr.b\t#2,%X0", CC_NO_CARRY },
2049 { "shlr.w\t#2,%T0", CC_NO_CARRY },
2050 { "shlr.l\t#2,%S0", CC_NO_CARRY }
2052 /* SHIFT_ASHIFTRT */
2054 { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2055 { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2056 { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
2060 /* Rotates are organized by which shift they'll be used in implementing.
2061 There's no need to record whether the cc is valid afterwards because
2062 it is the AND insn that will decide this. */
2064 static const char *const rotate_one[2][3][3] =
2066 /* H8/300 */
2068 /* SHIFT_ASHIFT */
2070 "rotr\t%X0",
2071 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
2074 /* SHIFT_LSHIFTRT */
2076 "rotl\t%X0",
2077 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
2080 /* SHIFT_ASHIFTRT */
2082 "rotl\t%X0",
2083 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
2087 /* H8/300H */
2089 /* SHIFT_ASHIFT */
2091 "rotr.b\t%X0",
2092 "rotr.w\t%T0",
2093 "rotr.l\t%S0"
2095 /* SHIFT_LSHIFTRT */
2097 "rotl.b\t%X0",
2098 "rotl.w\t%T0",
2099 "rotl.l\t%S0"
2101 /* SHIFT_ASHIFTRT */
2103 "rotl.b\t%X0",
2104 "rotl.w\t%T0",
2105 "rotl.l\t%S0"
2110 static const char *const rotate_two[3][3] =
2112 /* SHIFT_ASHIFT */
2114 "rotr.b\t#2,%X0",
2115 "rotr.w\t#2,%T0",
2116 "rotr.l\t#2,%S0"
2118 /* SHIFT_LSHIFTRT */
2120 "rotl.b\t#2,%X0",
2121 "rotl.w\t#2,%T0",
2122 "rotl.l\t#2,%S0"
2124 /* SHIFT_ASHIFTRT */
2126 "rotl.b\t#2,%X0",
2127 "rotl.w\t#2,%T0",
2128 "rotl.l\t#2,%S0"
2132 /* Macros to keep the shift algorithm tables small. */
2133 #define INL SHIFT_INLINE
2134 #define ROT SHIFT_ROT_AND
2135 #define LOP SHIFT_LOOP
2136 #define SPC SHIFT_SPECIAL
2138 /* The shift algorithms for each machine, mode, shift type, and shift
2139 count are defined below. The three tables below correspond to
2140 QImode, HImode, and SImode, respectively. Each table is organized
2141 by, in the order of indecies, machine, shift type, and shift count. */
2143 static const enum shift_alg shift_alg_qi[3][3][8] = {
2145 /* TARGET_H8300 */
2146 /* 0 1 2 3 4 5 6 7 */
2147 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2148 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2149 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
2152 /* TARGET_H8300H */
2153 /* 0 1 2 3 4 5 6 7 */
2154 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2155 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2156 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
2159 /* TARGET_H8300S */
2160 /* 0 1 2 3 4 5 6 7 */
2161 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_ASHIFT */
2162 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_LSHIFTRT */
2163 { INL, INL, INL, INL, INL, INL, INL, SPC } /* SHIFT_ASHIFTRT */
2167 static const enum shift_alg shift_alg_hi[3][3][16] = {
2169 /* TARGET_H8300 */
2170 /* 0 1 2 3 4 5 6 7 */
2171 /* 8 9 10 11 12 13 14 15 */
2172 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2173 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
2174 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2175 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
2176 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2177 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2180 /* TARGET_H8300H */
2181 /* 0 1 2 3 4 5 6 7 */
2182 /* 8 9 10 11 12 13 14 15 */
2183 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2184 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2185 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2186 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2187 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2188 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2191 /* TARGET_H8300S */
2192 /* 0 1 2 3 4 5 6 7 */
2193 /* 8 9 10 11 12 13 14 15 */
2194 { INL, INL, INL, INL, INL, INL, INL, INL,
2195 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2196 { INL, INL, INL, INL, INL, INL, INL, INL,
2197 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2198 { INL, INL, INL, INL, INL, INL, INL, INL,
2199 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2203 static const enum shift_alg shift_alg_si[3][3][32] = {
2205 /* TARGET_H8300 */
2206 /* 0 1 2 3 4 5 6 7 */
2207 /* 8 9 10 11 12 13 14 15 */
2208 /* 16 17 18 19 20 21 22 23 */
2209 /* 24 25 26 27 28 29 30 31 */
2210 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2211 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2212 SPC, SPC, SPC, SPC, SPC, LOP, LOP, LOP,
2213 SPC, SPC, SPC, SPC, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
2214 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2215 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC,
2216 SPC, SPC, SPC, LOP, LOP, LOP, LOP, LOP,
2217 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
2218 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2219 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
2220 SPC, SPC, LOP, LOP, LOP, LOP, LOP, LOP,
2221 SPC, SPC, SPC, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2224 /* TARGET_H8300H */
2225 /* 0 1 2 3 4 5 6 7 */
2226 /* 8 9 10 11 12 13 14 15 */
2227 /* 16 17 18 19 20 21 22 23 */
2228 /* 24 25 26 27 28 29 30 31 */
2229 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
2230 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
2231 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
2232 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
2233 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
2234 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
2235 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
2236 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
2237 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
2238 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2239 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
2240 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2243 /* TARGET_H8300S */
2244 /* 0 1 2 3 4 5 6 7 */
2245 /* 8 9 10 11 12 13 14 15 */
2246 /* 16 17 18 19 20 21 22 23 */
2247 /* 24 25 26 27 28 29 30 31 */
2248 { INL, INL, INL, INL, INL, INL, INL, INL,
2249 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
2250 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
2251 SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
2252 { INL, INL, INL, INL, INL, INL, INL, INL,
2253 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
2254 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
2255 SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
2256 { INL, INL, INL, INL, INL, INL, INL, INL,
2257 INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2258 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
2259 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2263 #undef INL
2264 #undef ROT
2265 #undef LOP
2266 #undef SPC
2268 struct shift_info {
2269 /* Shift algorithm. */
2270 enum shift_alg alg;
2272 /* The number of bits to be shifted by shift1 and shift2. Valid
2273 when ALG is SHIFT_SPECIAL. */
2274 unsigned int remainder;
2276 /* Special insn for a shift. Valid when ALG is SHIFT_SPECIAL. */
2277 const char *special;
2279 /* Insn for a one-bit shift. Valid when ALG is either SHIFT_INLINE
2280 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2281 const char *shift1;
2283 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
2284 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2285 const char *shift2;
2287 /* Valid CC flags. */
2288 int cc_valid_p;
2291 static void get_shift_alg PARAMS ((enum shift_type,
2292 enum shift_mode, unsigned int,
2293 struct shift_info *));
2295 /* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
2296 best algorithm for doing the shift. The assembler code is stored
2297 in the pointers in INFO. We don't achieve maximum efficiency in
2298 all cases, but the hooks are here to do so.
2300 For now we just use lots of switch statements. Since we don't even come
2301 close to supporting all the cases, this is simplest. If this function ever
2302 gets too big, perhaps resort to a more table based lookup. Of course,
2303 at this point you may just wish to do it all in rtl.
2305 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
2306 1,2,3,4 will be inlined (1,2 for SI). */
2308 static void
2309 get_shift_alg (shift_type, shift_mode, count, info)
2310 enum shift_type shift_type;
2311 enum shift_mode shift_mode;
2312 unsigned int count;
2313 struct shift_info *info;
2315 int cpu;
2317 /* Find the target CPU. */
2318 if (TARGET_H8300)
2319 cpu = 0;
2320 else if (TARGET_H8300H)
2321 cpu = 1;
2322 else
2323 cpu = 2;
2325 /* Find the shift algorithm. */
2326 switch (shift_mode)
2328 case QIshift:
2329 if (GET_MODE_BITSIZE (QImode) <= count)
2330 info->alg = SHIFT_LOOP;
2331 else
2332 info->alg = shift_alg_qi[cpu][shift_type][count];
2333 break;
2335 case HIshift:
2336 if (GET_MODE_BITSIZE (HImode) <= count)
2337 info->alg = SHIFT_LOOP;
2338 else
2339 info->alg = shift_alg_hi[cpu][shift_type][count];
2340 break;
2342 case SIshift:
2343 if (GET_MODE_BITSIZE (SImode) <= count)
2344 info->alg = SHIFT_LOOP;
2345 else
2346 info->alg = shift_alg_si[cpu][shift_type][count];
2347 break;
2349 default:
2350 abort ();
2353 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
2354 switch (info->alg)
2356 case SHIFT_INLINE:
2357 info->remainder = count;
2358 /* Fall through. */
2360 case SHIFT_LOOP:
2361 /* It is up to the caller to know that looping clobbers cc. */
2362 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2363 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2364 info->cc_valid_p = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
2365 goto end;
2367 case SHIFT_ROT_AND:
2368 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
2369 info->shift2 = rotate_two[shift_type][shift_mode];
2370 info->cc_valid_p = 0;
2371 goto end;
2373 case SHIFT_SPECIAL:
2374 /* REMAINDER is 0 for most cases, so initialize it to 0. */
2375 info->remainder = 0;
2376 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2377 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2378 info->cc_valid_p = 0;
2379 break;
2382 /* Here we only deal with SHIFT_SPECIAL. */
2383 switch (shift_mode)
2385 case QIshift:
2386 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2387 through the entire value. */
2388 if (shift_type == SHIFT_ASHIFTRT && count == 7)
2390 info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
2391 goto end;
2393 abort ();
2395 case HIshift:
2396 if (count == 7)
2398 switch (shift_type)
2400 case SHIFT_ASHIFT:
2401 if (TARGET_H8300)
2402 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";
2403 else
2404 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
2405 goto end;
2406 case SHIFT_LSHIFTRT:
2407 if (TARGET_H8300)
2408 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";
2409 else
2410 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
2411 goto end;
2412 case SHIFT_ASHIFTRT:
2413 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
2414 goto end;
2417 else if (8 <= count && count <= 12)
2419 info->remainder = count - 8;
2421 switch (shift_type)
2423 case SHIFT_ASHIFT:
2424 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
2425 info->shift1 = "shal.b\t%t0";
2426 info->shift2 = "shal.b\t#2,%t0";
2427 goto end;
2428 case SHIFT_LSHIFTRT:
2429 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
2430 info->shift1 = "shlr.b\t%s0";
2431 info->shift2 = "shlr.b\t#2,%s0";
2432 goto end;
2433 case SHIFT_ASHIFTRT:
2434 if (TARGET_H8300)
2435 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
2436 else
2437 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
2438 info->shift1 = "shar.b\t%s0";
2439 info->shift2 = "shar.b\t#2,%s0";
2440 goto end;
2443 else if (count == 15)
2445 switch (shift_type)
2447 case SHIFT_ASHIFT:
2448 info->special = "bld\t#0,%s0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#7,%t0";
2449 goto end;
2450 case SHIFT_LSHIFTRT:
2451 info->special = "bld\t#7,%t0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#0,%s0";
2452 goto end;
2453 case SHIFT_ASHIFTRT:
2454 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
2455 goto end;
2458 abort ();
2460 case SIshift:
2461 if (TARGET_H8300 && 8 <= count && count <= 9)
2463 info->remainder = count - 8;
2465 switch (shift_type)
2467 case SHIFT_ASHIFT:
2468 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";
2469 goto end;
2470 case SHIFT_LSHIFTRT:
2471 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";
2472 info->shift1 = "shlr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0";
2473 goto end;
2474 case SHIFT_ASHIFTRT:
2475 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";
2476 goto end;
2479 else if (count == 8 && !TARGET_H8300)
2481 switch (shift_type)
2483 case SHIFT_ASHIFT:
2484 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";
2485 goto end;
2486 case SHIFT_LSHIFTRT:
2487 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";
2488 goto end;
2489 case SHIFT_ASHIFTRT:
2490 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";
2491 goto end;
2494 else if (count == 15 && TARGET_H8300)
2496 switch (shift_type)
2498 case SHIFT_ASHIFT:
2499 abort ();
2500 case SHIFT_LSHIFTRT:
2501 info->special = "bld\t#7,%z0\n\tmov.w\t%e0,%f0\n\txor\t%y0,%y0\n\txor\t%z0,%z0\n\trotxl\t%w0,%w0\n\trotxl\t%x0,%x0\n\trotxl\t%y0,%y0";
2502 goto end;
2503 case SHIFT_ASHIFTRT:
2504 info->special = "bld\t#7,%z0\n\tmov.w\t%e0,%f0\n\trotxl\t%w0,%w0\n\trotxl\t%x0,%x0\n\tsubx\t%y0,%y0\n\tsubx\t%z0,%z0";
2505 goto end;
2508 else if (count == 15 && !TARGET_H8300)
2510 switch (shift_type)
2512 case SHIFT_ASHIFT:
2513 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
2514 goto end;
2515 case SHIFT_LSHIFTRT:
2516 info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
2517 goto end;
2518 case SHIFT_ASHIFTRT:
2519 abort ();
2522 else if ((TARGET_H8300 && 16 <= count && count <= 20)
2523 || (TARGET_H8300H && 16 <= count && count <= 19)
2524 || (TARGET_H8300S && 16 <= count && count <= 21))
2526 info->remainder = count - 16;
2528 switch (shift_type)
2530 case SHIFT_ASHIFT:
2531 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2532 if (TARGET_H8300)
2534 info->shift1 = "add.w\t%e0,%e0";
2536 else
2538 info->shift1 = "shll.l\t%S0";
2539 info->shift2 = "shll.l\t#2,%S0";
2541 goto end;
2542 case SHIFT_LSHIFTRT:
2543 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
2544 if (TARGET_H8300)
2546 info->shift1 = "shlr\t%x0\n\trotxr\t%w0";
2548 else
2550 info->shift1 = "shlr.l\t%S0";
2551 info->shift2 = "shlr.l\t#2,%S0";
2553 goto end;
2554 case SHIFT_ASHIFTRT:
2555 if (TARGET_H8300)
2557 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2558 info->shift1 = "shar\t%x0\n\trotxr\t%w0";
2560 else
2562 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
2563 info->shift1 = "shar.l\t%S0";
2564 info->shift2 = "shar.l\t#2,%S0";
2566 goto end;
2569 else if (TARGET_H8300 && 24 <= count && count <= 28)
2571 info->remainder = count - 24;
2573 switch (shift_type)
2575 case SHIFT_ASHIFT:
2576 info->special = "mov.b\t%w0,%z0\n\tsub.b\t%y0,%y0\n\tsub.w\t%f0,%f0";
2577 info->shift1 = "shll.b\t%z0";
2578 goto end;
2579 case SHIFT_LSHIFTRT:
2580 info->special = "mov.b\t%z0,%w0\n\tsub.b\t%x0,%x0\n\tsub.w\t%e0,%e0";
2581 info->shift1 = "shlr.b\t%w0";
2582 goto end;
2583 case SHIFT_ASHIFTRT:
2584 info->special = "mov.b\t%z0,%w0\n\tbld\t#7,%w0\n\tsubx\t%x0,%x0\n\tsubx\t%x0,%x0\n\tsubx\t%x0,%x0";
2585 info->shift1 = "shar.b\t%w0";
2586 goto end;
2589 else if ((TARGET_H8300H && count == 24)
2590 || (TARGET_H8300S && 24 <= count && count <= 25))
2592 info->remainder = count - 24;
2594 switch (shift_type)
2596 case SHIFT_ASHIFT:
2597 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";
2598 info->shift1 = "shll.l\t%S0";
2599 info->shift2 = "shll.l\t#2,%S0";
2600 goto end;
2601 case SHIFT_LSHIFTRT:
2602 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
2603 info->shift1 = "shlr.l\t%S0";
2604 info->shift2 = "shlr.l\t#2,%S0";
2605 goto end;
2606 case SHIFT_ASHIFTRT:
2607 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
2608 info->shift1 = "shar.l\t%S0";
2609 info->shift2 = "shar.l\t#2,%S0";
2610 goto end;
2613 else if (count == 31)
2615 if (TARGET_H8300)
2617 switch (shift_type)
2619 case SHIFT_ASHIFT:
2620 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2621 goto end;
2622 case SHIFT_LSHIFTRT:
2623 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2624 goto end;
2625 case SHIFT_ASHIFTRT:
2626 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2627 goto end;
2630 else
2632 switch (shift_type)
2634 case SHIFT_ASHIFT:
2635 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
2636 goto end;
2637 case SHIFT_LSHIFTRT:
2638 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
2639 goto end;
2640 case SHIFT_ASHIFTRT:
2641 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2642 goto end;
2646 abort ();
2648 default:
2649 abort ();
2652 end:
2653 if (!TARGET_H8300S)
2654 info->shift2 = NULL;
2657 /* Emit the assembler code for doing shifts. */
2659 const char *
2660 output_a_shift (operands)
2661 rtx *operands;
2663 static int loopend_lab;
2664 rtx shift = operands[3];
2665 enum machine_mode mode = GET_MODE (shift);
2666 enum rtx_code code = GET_CODE (shift);
2667 enum shift_type shift_type;
2668 enum shift_mode shift_mode;
2669 struct shift_info info;
2671 loopend_lab++;
2673 switch (mode)
2675 case QImode:
2676 shift_mode = QIshift;
2677 break;
2678 case HImode:
2679 shift_mode = HIshift;
2680 break;
2681 case SImode:
2682 shift_mode = SIshift;
2683 break;
2684 default:
2685 abort ();
2688 switch (code)
2690 case ASHIFTRT:
2691 shift_type = SHIFT_ASHIFTRT;
2692 break;
2693 case LSHIFTRT:
2694 shift_type = SHIFT_LSHIFTRT;
2695 break;
2696 case ASHIFT:
2697 shift_type = SHIFT_ASHIFT;
2698 break;
2699 default:
2700 abort ();
2703 if (GET_CODE (operands[2]) != CONST_INT)
2705 /* Indexing by reg, so have to loop and test at top. */
2706 output_asm_insn ("mov.b %X2,%X4", operands);
2707 fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab);
2709 /* Get the assembler code to do one shift. */
2710 get_shift_alg (shift_type, shift_mode, 1, &info);
2712 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2713 output_asm_insn (info.shift1, operands);
2714 output_asm_insn ("add #0xff,%X4", operands);
2715 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2716 fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
2718 return "";
2720 else
2722 int n = INTVAL (operands[2]);
2724 /* If the count is negative, make it 0. */
2725 if (n < 0)
2726 n = 0;
2727 /* If the count is too big, truncate it.
2728 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2729 do the intuitive thing. */
2730 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
2731 n = GET_MODE_BITSIZE (mode);
2733 get_shift_alg (shift_type, shift_mode, n, &info);
2735 switch (info.alg)
2737 case SHIFT_SPECIAL:
2738 output_asm_insn (info.special, operands);
2739 /* Fall through. */
2741 case SHIFT_INLINE:
2742 n = info.remainder;
2744 /* Emit two bit shifts first. */
2745 if (info.shift2 != NULL)
2747 for (; n > 1; n -= 2)
2748 output_asm_insn (info.shift2, operands);
2751 /* Now emit one bit shifts for any residual. */
2752 for (; n > 0; n--)
2753 output_asm_insn (info.shift1, operands);
2755 /* Keep track of CC. */
2756 if (info.cc_valid_p)
2758 cc_status.value1 = operands[0];
2759 cc_status.flags |= info.cc_valid_p;
2761 return "";
2763 case SHIFT_ROT_AND:
2765 int m = GET_MODE_BITSIZE (mode) - n;
2766 int mask = (shift_type == SHIFT_ASHIFT
2767 ? ((1 << m) - 1) << n
2768 : (1 << m) - 1);
2769 char insn_buf[200];
2771 /* Not all possibilities of rotate are supported. They shouldn't
2772 be generated, but let's watch for 'em. */
2773 if (info.shift1 == 0)
2774 abort ();
2776 /* Emit two bit rotates first. */
2777 if (info.shift2 != NULL)
2779 for (; m > 1; m -= 2)
2780 output_asm_insn (info.shift2, operands);
2783 /* Now single bit rotates for any residual. */
2784 for (; m > 0; m--)
2785 output_asm_insn (info.shift1, operands);
2787 /* Now mask off the high bits. */
2788 if (TARGET_H8300)
2790 switch (mode)
2792 case QImode:
2793 sprintf (insn_buf, "and\t#%d,%%X0", mask);
2794 cc_status.value1 = operands[0];
2795 cc_status.flags |= CC_NO_CARRY;
2796 break;
2797 case HImode:
2798 sprintf (insn_buf, "and\t#%d,%%s0\n\tand\t#%d,%%t0",
2799 mask & 255, mask >> 8);
2800 break;
2801 default:
2802 abort ();
2805 else
2807 sprintf (insn_buf, "and.%c\t#%d,%%%c0",
2808 "bwl"[shift_mode], mask,
2809 mode == QImode ? 'X' : mode == HImode ? 'T' : 'S');
2810 cc_status.value1 = operands[0];
2811 cc_status.flags |= CC_NO_CARRY;
2813 output_asm_insn (insn_buf, operands);
2814 return "";
2817 case SHIFT_LOOP:
2818 /* A loop to shift by a "large" constant value.
2819 If we have shift-by-2 insns, use them. */
2820 if (info.shift2 != NULL)
2822 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
2823 names_big[REGNO (operands[4])]);
2824 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2825 output_asm_insn (info.shift2, operands);
2826 output_asm_insn ("add #0xff,%X4", operands);
2827 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2828 if (n % 2)
2829 output_asm_insn (info.shift1, operands);
2831 else
2833 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
2834 names_big[REGNO (operands[4])]);
2835 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2836 output_asm_insn (info.shift1, operands);
2837 output_asm_insn ("add #0xff,%X4", operands);
2838 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2840 return "";
2842 default:
2843 abort ();
2848 /* A rotation by a non-constant will cause a loop to be generated, in
2849 which a rotation by one bit is used. A rotation by a constant,
2850 including the one in the loop, will be taken care of by
2851 emit_a_rotate () at the insn emit time. */
2854 expand_a_rotate (code, operands)
2855 enum rtx_code code;
2856 rtx operands[];
2858 rtx dst = operands[0];
2859 rtx src = operands[1];
2860 rtx rotate_amount = operands[2];
2861 enum machine_mode mode = GET_MODE (dst);
2862 rtx tmp;
2864 /* We rotate in place. */
2865 emit_move_insn (dst, src);
2867 if (GET_CODE (rotate_amount) != CONST_INT)
2869 rtx counter = gen_reg_rtx (QImode);
2870 rtx start_label = gen_label_rtx ();
2871 rtx end_label = gen_label_rtx ();
2873 /* If the rotate amount is less than or equal to 0,
2874 we go out of the loop. */
2875 emit_cmp_and_jump_insns (rotate_amount, GEN_INT (0), LE, NULL_RTX,
2876 QImode, 0, end_label);
2878 /* Initialize the loop counter. */
2879 emit_move_insn (counter, rotate_amount);
2881 emit_label (start_label);
2883 /* Rotate by one bit. */
2884 tmp = gen_rtx (code, mode, dst, GEN_INT (1));
2885 emit_insn (gen_rtx_SET (mode, dst, tmp));
2887 /* Decrement the counter by 1. */
2888 tmp = gen_rtx_PLUS (QImode, counter, GEN_INT (-1));
2889 emit_insn (gen_rtx_SET (VOIDmode, counter, tmp));
2891 /* If the loop counter is non-zero, we go back to the beginning
2892 of the loop. */
2893 emit_cmp_and_jump_insns (counter, GEN_INT (0), NE, NULL_RTX, QImode, 1,
2894 start_label);
2896 emit_label (end_label);
2898 else
2900 /* Rotate by AMOUNT bits. */
2901 tmp = gen_rtx (code, mode, dst, rotate_amount);
2902 emit_insn (gen_rtx_SET (mode, dst, tmp));
2905 return 1;
2908 /* Emit rotate insns. */
2910 const char *
2911 emit_a_rotate (code, operands)
2912 enum rtx_code code;
2913 rtx *operands;
2915 rtx dst = operands[0];
2916 rtx rotate_amount = operands[2];
2917 enum shift_mode rotate_mode;
2918 enum shift_type rotate_type;
2919 const char *insn_buf;
2920 int bits;
2921 int amount;
2922 enum machine_mode mode = GET_MODE (dst);
2924 if (GET_CODE (rotate_amount) != CONST_INT)
2925 abort ();
2927 switch (mode)
2929 case QImode:
2930 rotate_mode = QIshift;
2931 break;
2932 case HImode:
2933 rotate_mode = HIshift;
2934 break;
2935 case SImode:
2936 rotate_mode = SIshift;
2937 break;
2938 default:
2939 abort ();
2942 switch (code)
2944 case ROTATERT:
2945 rotate_type = SHIFT_ASHIFT;
2946 break;
2947 case ROTATE:
2948 rotate_type = SHIFT_LSHIFTRT;
2949 break;
2950 default:
2951 abort ();
2954 amount = INTVAL (rotate_amount);
2956 /* Clean up AMOUNT. */
2957 if (amount < 0)
2958 amount = 0;
2959 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
2960 amount = GET_MODE_BITSIZE (mode);
2962 /* Determine the faster direction. After this phase, amount will be
2963 at most a half of GET_MODE_BITSIZE (mode). */
2964 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / 2U)
2966 /* Flip the direction. */
2967 amount = GET_MODE_BITSIZE (mode) - amount;
2968 rotate_type =
2969 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
2972 /* See if a byte swap (in HImode) or a word swap (in SImode) can
2973 boost up the rotation. */
2974 if ((mode == HImode && TARGET_H8300 && amount >= 5)
2975 || (mode == HImode && TARGET_H8300H && amount >= 6)
2976 || (mode == HImode && TARGET_H8300S && amount == 8)
2977 || (mode == SImode && TARGET_H8300H && amount >= 10)
2978 || (mode == SImode && TARGET_H8300S && amount >= 13))
2980 switch (mode)
2982 case HImode:
2983 /* This code works on any family. */
2984 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
2985 output_asm_insn (insn_buf, operands);
2986 break;
2988 case SImode:
2989 /* This code works on the H8/300H and H8/S. */
2990 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
2991 output_asm_insn (insn_buf, operands);
2992 break;
2994 default:
2995 abort ();
2998 /* Adjust AMOUNT and flip the direction. */
2999 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3000 rotate_type =
3001 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
3004 /* Emit rotate insns. */
3005 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2)
3007 if (bits == 2)
3008 insn_buf = rotate_two[rotate_type][rotate_mode];
3009 else
3010 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode];
3012 for (; amount >= bits; amount -= bits)
3013 output_asm_insn (insn_buf, operands);
3016 return "";
3019 /* Fix the operands of a gen_xxx so that it could become a bit
3020 operating insn. */
3023 fix_bit_operand (operands, what, type)
3024 rtx *operands;
3025 int what;
3026 enum rtx_code type;
3028 /* The bit_operand predicate accepts any memory during RTL generation, but
3029 only 'U' memory afterwards, so if this is a MEM operand, we must force
3030 it to be valid for 'U' by reloading the address. */
3032 if (GET_CODE (operands[2]) == CONST_INT)
3034 if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), what))
3036 /* Ok to have a memory dest. */
3037 if (GET_CODE (operands[0]) == MEM
3038 && !EXTRA_CONSTRAINT (operands[0], 'U'))
3040 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
3041 copy_to_mode_reg (Pmode,
3042 XEXP (operands[0], 0)));
3043 MEM_COPY_ATTRIBUTES (mem, operands[0]);
3044 operands[0] = mem;
3047 if (GET_CODE (operands[1]) == MEM
3048 && !EXTRA_CONSTRAINT (operands[1], 'U'))
3050 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
3051 copy_to_mode_reg (Pmode,
3052 XEXP (operands[1], 0)));
3053 MEM_COPY_ATTRIBUTES (mem, operands[0]);
3054 operands[1] = mem;
3056 return 0;
3060 /* Dest and src op must be register. */
3062 operands[1] = force_reg (QImode, operands[1]);
3064 rtx res = gen_reg_rtx (QImode);
3065 emit_insn (gen_rtx_SET (VOIDmode, res,
3066 gen_rtx (type, QImode, operands[1], operands[2])));
3067 emit_insn (gen_rtx_SET (VOIDmode, operands[0], res));
3069 return 1;
3072 /* Return nonzero if FUNC is an interrupt function as specified
3073 by the "interrupt" attribute. */
3075 static int
3076 h8300_interrupt_function_p (func)
3077 tree func;
3079 tree a;
3081 if (TREE_CODE (func) != FUNCTION_DECL)
3082 return 0;
3084 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
3085 return a != NULL_TREE;
3088 /* Return nonzero if FUNC is an OS_Task function as specified
3089 by the "OS_Task" attribute. */
3091 static int
3092 h8300_os_task_function_p (func)
3093 tree func;
3095 tree a;
3097 if (TREE_CODE (func) != FUNCTION_DECL)
3098 return 0;
3100 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func));
3101 return a != NULL_TREE;
3104 /* Return nonzero if FUNC is a monitor function as specified
3105 by the "monitor" attribute. */
3107 static int
3108 h8300_monitor_function_p (func)
3109 tree func;
3111 tree a;
3113 if (TREE_CODE (func) != FUNCTION_DECL)
3114 return 0;
3116 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func));
3117 return a != NULL_TREE;
3120 /* Return nonzero if FUNC is a function that should be called
3121 through the function vector. */
3124 h8300_funcvec_function_p (func)
3125 tree func;
3127 tree a;
3129 if (TREE_CODE (func) != FUNCTION_DECL)
3130 return 0;
3132 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func));
3133 return a != NULL_TREE;
3136 /* Return nonzero if DECL is a variable that's in the eight bit
3137 data area. */
3140 h8300_eightbit_data_p (decl)
3141 tree decl;
3143 tree a;
3145 if (TREE_CODE (decl) != VAR_DECL)
3146 return 0;
3148 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl));
3149 return a != NULL_TREE;
3152 /* Return nonzero if DECL is a variable that's in the tiny
3153 data area. */
3156 h8300_tiny_data_p (decl)
3157 tree decl;
3159 tree a;
3161 if (TREE_CODE (decl) != VAR_DECL)
3162 return 0;
3164 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl));
3165 return a != NULL_TREE;
3168 /* Supported attributes:
3170 interrupt_handler: output a prologue and epilogue suitable for an
3171 interrupt handler.
3173 function_vector: This function should be called through the
3174 function vector.
3176 eightbit_data: This variable lives in the 8-bit data area and can
3177 be referenced with 8-bit absolute memory addresses.
3179 tiny_data: This variable lives in the tiny data area and can be
3180 referenced with 16-bit absolute memory references. */
3182 const struct attribute_spec h8300_attribute_table[] =
3184 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
3185 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3186 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3187 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3188 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3189 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute },
3190 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute },
3191 { NULL, 0, 0, false, false, false, NULL }
3195 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
3196 struct attribute_spec.handler. */
3197 static tree
3198 h8300_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
3199 tree *node;
3200 tree name;
3201 tree args ATTRIBUTE_UNUSED;
3202 int flags ATTRIBUTE_UNUSED;
3203 bool *no_add_attrs;
3205 if (TREE_CODE (*node) != FUNCTION_DECL)
3207 warning ("`%s' attribute only applies to functions",
3208 IDENTIFIER_POINTER (name));
3209 *no_add_attrs = true;
3212 return NULL_TREE;
3215 /* Handle an "eightbit_data" attribute; arguments as in
3216 struct attribute_spec.handler. */
3217 static tree
3218 h8300_handle_eightbit_data_attribute (node, name, args, flags, no_add_attrs)
3219 tree *node;
3220 tree name;
3221 tree args ATTRIBUTE_UNUSED;
3222 int flags ATTRIBUTE_UNUSED;
3223 bool *no_add_attrs;
3225 tree decl = *node;
3227 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
3229 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
3231 else
3233 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3234 *no_add_attrs = true;
3237 return NULL_TREE;
3240 /* Handle an "tiny_data" attribute; arguments as in
3241 struct attribute_spec.handler. */
3242 static tree
3243 h8300_handle_tiny_data_attribute (node, name, args, flags, no_add_attrs)
3244 tree *node;
3245 tree name;
3246 tree args ATTRIBUTE_UNUSED;
3247 int flags ATTRIBUTE_UNUSED;
3248 bool *no_add_attrs;
3250 tree decl = *node;
3252 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
3254 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
3256 else
3258 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3259 *no_add_attrs = true;
3262 return NULL_TREE;
3265 void
3266 h8300_encode_label (decl)
3267 tree decl;
3269 const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
3270 int len = strlen (str);
3271 char *newstr = alloca (len + 2);
3273 newstr[0] = '&';
3274 strcpy (&newstr[1], str);
3276 XSTR (XEXP (DECL_RTL (decl), 0), 0) =
3277 ggc_alloc_string (newstr, len + 1);
3280 const char *
3281 output_simode_bld (bild, operands)
3282 int bild;
3283 rtx operands[];
3285 if (TARGET_H8300)
3287 /* Clear the destination register. */
3288 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
3290 /* Now output the bit load or bit inverse load, and store it in
3291 the destination. */
3292 if (bild)
3293 output_asm_insn ("bild\t%Z2,%Y1", operands);
3294 else
3295 output_asm_insn ("bld\t%Z2,%Y1", operands);
3297 output_asm_insn ("bst\t#0,%w0", operands);
3299 else
3301 /* Output the bit load or bit inverse load. */
3302 if (bild)
3303 output_asm_insn ("bild\t%Z2,%Y1", operands);
3304 else
3305 output_asm_insn ("bld\t%Z2,%Y1", operands);
3307 /* Clear the destination register and perform the bit store. */
3308 output_asm_insn ("xor.l\t%S0,%S0\n\tbst\t#0,%w0", operands);
3311 /* All done. */
3312 return "";
3315 /* Given INSN and its current length LENGTH, return the adjustment
3316 (in bytes) to correctly compute INSN's length.
3318 We use this to get the lengths of various memory references correct. */
3321 h8300_adjust_insn_length (insn, length)
3322 rtx insn;
3323 int length ATTRIBUTE_UNUSED;
3325 rtx pat = PATTERN (insn);
3327 /* We must filter these out before calling get_attr_adjust_length. */
3328 if (GET_CODE (pat) == USE
3329 || GET_CODE (pat) == CLOBBER
3330 || GET_CODE (pat) == SEQUENCE
3331 || GET_CODE (pat) == ADDR_VEC
3332 || GET_CODE (pat) == ADDR_DIFF_VEC)
3333 return 0;
3335 if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO)
3336 return 0;
3338 /* Adjust length for reg->mem and mem->reg copies. */
3339 if (GET_CODE (pat) == SET
3340 && (GET_CODE (SET_SRC (pat)) == MEM
3341 || GET_CODE (SET_DEST (pat)) == MEM))
3343 /* This insn might need a length adjustment. */
3344 rtx addr;
3346 if (GET_CODE (SET_SRC (pat)) == MEM)
3347 addr = XEXP (SET_SRC (pat), 0);
3348 else
3349 addr = XEXP (SET_DEST (pat), 0);
3351 /* On the H8/300, only one adjustment is necessary; if the
3352 address mode is register indirect, then this insn is two
3353 bytes shorter than indicated in the machine description. */
3354 if (TARGET_H8300 && GET_CODE (addr) == REG)
3355 return -2;
3357 /* On the H8/300H and H8/S, register indirect is 6 bytes shorter than
3358 indicated in the machine description. */
3359 if ((TARGET_H8300H || TARGET_H8300S)
3360 && GET_CODE (addr) == REG)
3361 return -6;
3363 /* On the H8/300H and H8/S, reg + d, for small displacements is
3364 4 bytes shorter than indicated in the machine description. */
3365 if ((TARGET_H8300H || TARGET_H8300S)
3366 && GET_CODE (addr) == PLUS
3367 && GET_CODE (XEXP (addr, 0)) == REG
3368 && GET_CODE (XEXP (addr, 1)) == CONST_INT
3369 && INTVAL (XEXP (addr, 1)) > -32768
3370 && INTVAL (XEXP (addr, 1)) < 32767)
3371 return -4;
3373 /* On the H8/300H and H8/S, abs:16 is two bytes shorter than the
3374 more general abs:24. */
3375 if ((TARGET_H8300H || TARGET_H8300S)
3376 && GET_CODE (addr) == SYMBOL_REF
3377 && TINY_DATA_NAME_P (XSTR (addr, 0)))
3378 return -2;
3381 /* Loading some constants needs adjustment. */
3382 if (GET_CODE (pat) == SET
3383 && GET_CODE (SET_SRC (pat)) == CONST_INT
3384 && GET_MODE (SET_DEST (pat)) == SImode
3385 && INTVAL (SET_SRC (pat)) != 0)
3387 int val = INTVAL (SET_SRC (pat));
3389 if (TARGET_H8300
3390 && ((val & 0xffff) == 0
3391 || ((val >> 16) & 0xffff) == 0))
3392 return -2;
3394 if (TARGET_H8300H || TARGET_H8300S)
3396 if (val == (val & 0xff)
3397 || val == (val & 0xff00))
3398 return 4 - 6;
3400 switch (val & 0xffffffff)
3402 case 0xffffffff:
3403 case 0xfffffffe:
3404 case 0xfffffffc:
3405 case 0x0000ffff:
3406 case 0x0000fffe:
3407 case 0xffff0000:
3408 case 0xfffe0000:
3409 case 0x00010000:
3410 case 0x00020000:
3411 return 4 - 6;
3416 /* Shifts need various adjustments. */
3417 if (GET_CODE (pat) == PARALLEL
3418 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
3419 && (GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFTRT
3420 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == LSHIFTRT
3421 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFT))
3423 rtx src = SET_SRC (XVECEXP (pat, 0, 0));
3424 enum machine_mode mode = GET_MODE (src);
3425 int shift;
3427 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3428 return 0;
3430 shift = INTVAL (XEXP (src, 1));
3431 /* According to ANSI, negative shift is undefined. It is
3432 considered to be zero in this case (see function
3433 output_a_shift above). */
3434 if (shift < 0)
3435 shift = 0;
3437 /* QImode shifts by small constants take one insn
3438 per shift. So the adjustment is 20 (md length) -
3439 # shifts * 2. */
3440 if (mode == QImode && shift <= 4)
3441 return -(20 - shift * 2);
3443 /* Similarly for HImode and SImode shifts by small constants on
3444 the H8/300H and H8/S. */
3445 if ((TARGET_H8300H || TARGET_H8300S)
3446 && (mode == HImode || mode == SImode) && shift <= 4)
3447 return -(20 - shift * 2);
3449 /* HImode shifts by small constants for the H8/300. */
3450 if (mode == HImode && shift <= 4)
3451 return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 2 : 4)));
3453 /* SImode shifts by small constants for the H8/300. */
3454 if (mode == SImode && shift <= 2)
3455 return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 6 : 8)));
3457 /* XXX ??? Could check for more shift/rotate cases here. */
3460 /* Rotations need various adjustments. */
3461 if (GET_CODE (pat) == SET
3462 && (GET_CODE (SET_SRC (pat)) == ROTATE
3463 || GET_CODE (SET_SRC (pat)) == ROTATERT))
3465 rtx src = SET_SRC (pat);
3466 enum machine_mode mode = GET_MODE (src);
3467 int amount;
3468 int states = 0;
3470 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3471 return 0;
3473 amount = INTVAL (XEXP (src, 1));
3475 /* Clean up AMOUNT. */
3476 if (amount < 0)
3477 amount = 0;
3478 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3479 amount = GET_MODE_BITSIZE (mode);
3481 /* Determine the faster direction. After this phase, amount
3482 will be at most a half of GET_MODE_BITSIZE (mode). */
3483 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / 2U)
3484 /* Flip the direction. */
3485 amount = GET_MODE_BITSIZE (mode) - amount;
3487 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3488 boost up the rotation. */
3489 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3490 || (mode == HImode && TARGET_H8300H && amount >= 6)
3491 || (mode == HImode && TARGET_H8300S && amount == 8)
3492 || (mode == SImode && TARGET_H8300H && amount >= 10)
3493 || (mode == SImode && TARGET_H8300S && amount >= 13))
3495 /* Adjust AMOUNT and flip the direction. */
3496 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3497 states += 6;
3500 /* We use 2-bit rotatations on the H8/S. */
3501 if (TARGET_H8300S)
3502 amount = amount / 2 + amount % 2;
3504 /* The H8/300 uses three insns to rotate one bit, taking 6
3505 states. */
3506 states += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2);
3508 return -(20 - states);
3511 return 0;
3514 #ifndef OBJECT_FORMAT_ELF
3515 static void
3516 h8300_asm_named_section (name, flags)
3517 const char *name;
3518 unsigned int flags ATTRIBUTE_UNUSED;
3520 /* ??? Perhaps we should be using default_coff_asm_named_section. */
3521 fprintf (asm_out_file, "\t.section %s\n", name);
3523 #endif /* ! OBJECT_FORMAT_ELF */