1 /* Subroutines for insn-output.c for Hitachi H8/300.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002 Free Software Foundation, Inc.
4 Contributed by Steve Chamberlain (sac@cygnus.com),
5 Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
7 This file is part of GNU CC.
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING. If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
34 #include "insn-attr.h"
44 #include "target-def.h"
46 /* Forward declarations. */
47 static int h8300_interrupt_function_p
PARAMS ((tree
));
48 static int h8300_monitor_function_p
PARAMS ((tree
));
49 static int h8300_os_task_function_p
PARAMS ((tree
));
50 static void dosize
PARAMS ((FILE *, const char *, unsigned int));
51 static int round_frame_size
PARAMS ((int));
52 static unsigned int compute_saved_regs
PARAMS ((void));
53 static void push
PARAMS ((FILE *, int));
54 static void pop
PARAMS ((FILE *, int));
55 static const char *cond_string
PARAMS ((enum rtx_code
));
56 const struct attribute_spec h8300_attribute_table
[];
57 static tree h8300_handle_fndecl_attribute
PARAMS ((tree
*, tree
, tree
, int, bool *));
58 static tree h8300_handle_eightbit_data_attribute
PARAMS ((tree
*, tree
, tree
, int, bool *));
59 static tree h8300_handle_tiny_data_attribute
PARAMS ((tree
*, tree
, tree
, int, bool *));
60 static void h8300_output_function_prologue
PARAMS ((FILE *, HOST_WIDE_INT
));
61 static void h8300_output_function_epilogue
PARAMS ((FILE *, HOST_WIDE_INT
));
62 #ifndef OBJECT_FORMAT_ELF
63 static void h8300_asm_named_section
PARAMS ((const char *, unsigned int));
66 /* CPU_TYPE, says what cpu we're compiling for. */
69 /* True if the current function is an interrupt handler
70 (either via #pragma or an attribute specification). */
71 int interrupt_handler
;
73 /* True if the current function is an OS Task
74 (via an attribute specification). */
77 /* True if the current function is a monitor
78 (via an attribute specification). */
81 /* True if a #pragma saveall has been seen for the current function. */
84 static const char *const names_big
[] =
85 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" };
87 static const char *const names_extended
[] =
88 { "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" };
90 static const char *const names_upper_extended
[] =
91 { "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7" };
93 /* Points to one of the above. */
94 /* ??? The above could be put in an array indexed by CPU_TYPE. */
95 const char * const *h8_reg_names
;
97 /* Various operations needed by the following, indexed by CPU_TYPE. */
99 static const char *const h8_push_ops
[2] = { "push", "push.l" };
100 static const char *const h8_pop_ops
[2] = { "pop", "pop.l" };
101 static const char *const h8_mov_ops
[2] = { "mov.w", "mov.l" };
103 const char *h8_push_op
, *h8_pop_op
, *h8_mov_op
;
105 /* Initialize the GCC target structure. */
106 #undef TARGET_ATTRIBUTE_TABLE
107 #define TARGET_ATTRIBUTE_TABLE h8300_attribute_table
109 #undef TARGET_ASM_ALIGNED_HI_OP
110 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
112 #undef TARGET_ASM_FUNCTION_PROLOGUE
113 #define TARGET_ASM_FUNCTION_PROLOGUE h8300_output_function_prologue
114 #undef TARGET_ASM_FUNCTION_EPILOGUE
115 #define TARGET_ASM_FUNCTION_EPILOGUE h8300_output_function_epilogue
117 struct gcc_target targetm
= TARGET_INITIALIZER
;
119 /* Initialize various cpu specific globals at start up. */
126 cpu_type
= (int) CPU_H8300
;
127 h8_reg_names
= names_big
;
131 /* For this we treat the H8/300H and H8/S the same. */
132 cpu_type
= (int) CPU_H8300H
;
133 h8_reg_names
= names_extended
;
135 h8_push_op
= h8_push_ops
[cpu_type
];
136 h8_pop_op
= h8_pop_ops
[cpu_type
];
137 h8_mov_op
= h8_mov_ops
[cpu_type
];
139 if (!TARGET_H8300S
&& TARGET_MAC
)
141 error ("-ms2600 is used without -ms");
151 static const char *const names_small
[] =
152 {"r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
153 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h"};
155 return names_small
[REGNO (x
) * 2 + b
];
158 /* REGNO must be saved/restored across calls if this macro is true. */
160 #define WORD_REG_USED(regno) \
162 /* No need to save registers if this function will not return. */\
163 && ! TREE_THIS_VOLATILE (current_function_decl) \
165 /* Save any call saved register that was used. */ \
166 || (regs_ever_live[regno] && !call_used_regs[regno]) \
167 /* Save the frame pointer if it was used. */ \
168 || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno])\
169 /* Save any register used in an interrupt handler. */ \
170 || (interrupt_handler && regs_ever_live[regno]) \
171 /* Save call clobbered registers in non-leaf interrupt \
173 || (interrupt_handler \
174 && call_used_regs[regno] \
175 && !current_function_is_leaf)))
177 /* Output assembly language to FILE for the operation OP with operand size
178 SIZE to adjust the stack pointer. */
181 dosize (file
, op
, size
)
186 /* On the H8/300H and H8/S, for sizes <= 8 bytes, it is as good or
187 better to use adds/subs insns rather than add.l/sub.l with an
190 Also, on the H8/300, if we don't have a temporary to hold the
191 size of the frame in the prologue, we simply emit a sequence of
192 subs since this shouldn't happen often. */
193 if ((TARGET_H8300
&& size
<= 4)
194 || ((TARGET_H8300H
|| TARGET_H8300S
) && size
<= 8)
195 || (TARGET_H8300
&& interrupt_handler
)
196 || (TARGET_H8300
&& current_function_needs_context
197 && ! strcmp (op
, "sub")))
199 unsigned HOST_WIDE_INT amount
;
201 /* Try different amounts in descending order. */
202 for (amount
= (TARGET_H8300H
|| TARGET_H8300S
) ? 4 : 2;
206 for (; size
>= amount
; size
-= amount
)
207 fprintf (file
, "\t%ss\t#%d,sp\n", op
, amount
);
213 fprintf (file
, "\tmov.w\t#%d,r3\n\t%s.w\tr3,sp\n", size
, op
);
215 fprintf (file
, "\t%s.l\t#%d,sp\n", op
, size
);
219 /* Round up frame size SIZE. */
222 round_frame_size (size
)
225 return (size
+ STACK_BOUNDARY
/ 8 - 1) & -STACK_BOUNDARY
/ 8;
228 /* Compute which registers to push/pop.
229 Return a bit vector of registers. */
232 compute_saved_regs ()
234 unsigned int saved_regs
= 0;
237 /* Construct a bit vector of registers to be pushed/popped. */
238 for (regno
= 0; regno
<= 6; regno
++)
240 if (WORD_REG_USED (regno
))
241 saved_regs
|= 1 << regno
;
244 /* Don't push/pop the frame pointer as it is treated separately. */
245 if (frame_pointer_needed
)
246 saved_regs
&= ~(1 << FRAME_POINTER_REGNUM
);
251 /* Output assembly language code to push register RN. */
258 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[rn
]);
261 /* Output assembly language code to pop register RN. */
268 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[rn
]);
271 /* This is what the stack looks like after the prolog of
272 a function with a frame has been set up:
278 <saved registers> <- sp
280 This is what the stack looks like after the prolog of
281 a function which doesn't have a frame:
286 <saved registers> <- sp
289 /* Output assembly language code for the function prologue. */
292 h8300_output_function_prologue (file
, size
)
296 int fsize
= round_frame_size (size
);
301 /* Note a function with the interrupt attribute and set interrupt_handler
303 if (h8300_interrupt_function_p (current_function_decl
))
304 interrupt_handler
= 1;
306 /* If the current function has the OS_Task attribute set, then
307 we have a naked prologue. */
308 if (h8300_os_task_function_p (current_function_decl
))
310 fprintf (file
, ";OS_Task prologue\n");
315 if (h8300_monitor_function_p (current_function_decl
))
317 /* My understanding of monitor functions is they act just
318 like interrupt functions, except the prologue must
320 fprintf (file
, ";monitor prologue\n");
321 interrupt_handler
= 1;
325 fprintf (file
, "\tsubs\t#2,sp\n");
327 fprintf (file
, "\tstc\tccr,r0l\n");
328 fprintf (file
, "\tmov.b\tr0l,@(2,sp)\n");
330 fprintf (file
, "\torc\t#128,ccr\n");
332 else if (TARGET_H8300H
)
335 fprintf (file
, "\tstc\tccr,r0l\n");
336 fprintf (file
, "\tmov.b\tr0l,@(4,sp)\n");
338 fprintf (file
, "\torc\t#128,ccr\n");
340 else if (TARGET_H8300S
)
342 fprintf (file
, "\tstc\texr,@-sp\n");
344 fprintf (file
, "\tstc\tccr,r0l\n");
345 fprintf (file
, "\tmov.b\tr0l,@(6,sp)\n");
347 fprintf (file
, "\torc\t#128,ccr\n");
353 if (frame_pointer_needed
)
356 push (file
, FRAME_POINTER_REGNUM
);
357 fprintf (file
, "\t%s\t%s,%s\n", h8_mov_op
,
358 h8_reg_names
[STACK_POINTER_REGNUM
],
359 h8_reg_names
[FRAME_POINTER_REGNUM
]);
362 /* Leave room for locals. */
363 dosize (file
, "sub", fsize
);
365 /* Push the rest of the registers in ascending order. */
366 saved_regs
= compute_saved_regs ();
367 for (idx
= 0; idx
< FIRST_PSEUDO_REGISTER
; idx
+= n_regs
)
372 if (saved_regs
& (1 << regno
))
376 /* See how many registers we can push at the same time. */
377 if ((regno
== 0 || regno
== 4)
378 && ((saved_regs
>> regno
) & 0x0f) == 0x0f)
381 else if ((regno
== 0 || regno
== 4)
382 && ((saved_regs
>> regno
) & 0x07) == 0x07)
385 else if ((regno
== 0 || regno
== 2 || regno
== 4 || regno
== 6)
386 && ((saved_regs
>> regno
) & 0x03) == 0x03)
393 fprintf (file
, "\tstm.l\t%s-%s,@-sp\n",
395 h8_reg_names
[regno
+ (n_regs
- 1)]);
400 /* Output assembly language code for the function epilogue. */
403 h8300_output_function_epilogue (file
, size
)
407 int fsize
= round_frame_size (size
);
409 rtx insn
= get_last_insn ();
415 /* OS_Task epilogues are nearly naked -- they just have an
417 fprintf (file
, ";OS_task epilogue\n");
418 fprintf (file
, "\trts\n");
422 /* Monitor epilogues are the same as interrupt function epilogues.
423 Just make a note that we're in an monitor epilogue. */
425 fprintf (file
, ";monitor epilogue\n");
427 /* If the last insn was a BARRIER, we don't have to write any code. */
428 if (GET_CODE (insn
) == NOTE
)
429 insn
= prev_nonnote_insn (insn
);
430 if (insn
&& GET_CODE (insn
) == BARRIER
)
433 /* Pop the saved registers in descending order. */
434 saved_regs
= compute_saved_regs ();
435 for (idx
= 0; idx
< FIRST_PSEUDO_REGISTER
; idx
+= n_regs
)
437 int regno
= (FIRST_PSEUDO_REGISTER
- 1) - idx
;
440 if (saved_regs
& (1 << regno
))
444 /* See how many registers we can pop at the same time. */
445 if ((regno
== 7 || regno
== 3)
446 && ((saved_regs
>> (regno
- 3)) & 0x0f) == 0x0f)
449 else if ((regno
== 6 || regno
== 2)
450 && ((saved_regs
>> (regno
- 2)) & 0x07) == 0x07)
453 else if ((regno
== 7 || regno
== 5 || regno
== 3 || regno
== 1)
454 && ((saved_regs
>> (regno
- 1)) & 0x03) == 0x03)
461 fprintf (file
, "\tldm.l\t@sp+,%s-%s\n",
462 h8_reg_names
[regno
- (n_regs
- 1)],
463 h8_reg_names
[regno
]);
467 /* Deallocate locals. */
468 dosize (file
, "add", fsize
);
470 /* Pop frame pointer if we had one. */
471 if (frame_pointer_needed
)
472 pop (file
, FRAME_POINTER_REGNUM
);
474 if (interrupt_handler
)
475 fprintf (file
, "\trte\n");
477 fprintf (file
, "\trts\n");
480 interrupt_handler
= 0;
486 /* Output assembly code for the start of the file. */
489 asm_file_start (file
)
492 fprintf (file
, ";\tGCC For the Hitachi H8/300\n");
493 fprintf (file
, ";\tBy Hitachi America Ltd and Cygnus Support\n");
495 fprintf (file
, "; -O%d\n", optimize
);
497 fprintf (file
, "\n\t.h8300h\n");
498 else if (TARGET_H8300S
)
499 fprintf (file
, "\n\t.h8300s\n");
501 fprintf (file
, "\n\n");
502 output_file_directive (file
, main_input_filename
);
505 /* Output assembly language code for the end of file. */
511 fprintf (file
, "\t.end\n");
514 /* Return true if VALUE is a valid constant for constraint 'P'.
515 IE: VALUE is a power of two <= 2**15. */
518 small_power_of_two (value
)
521 int power
= exact_log2 (value
);
522 return power
>= 0 && power
<= 15;
525 /* Return true if VALUE is a valid constant for constraint 'O', which
526 means that the constant would be ok to use as a bit for a bclr
533 return small_power_of_two ((~value
) & 0xff);
536 /* Return true if OP is a valid source operand for an integer move
540 general_operand_src (op
, mode
)
542 enum machine_mode mode
;
544 if (GET_CODE (op
) == MEM
&& GET_CODE (XEXP (op
, 0)) == POST_INC
)
546 return general_operand (op
, mode
);
549 /* Return true if OP is a valid destination operand for an integer move
553 general_operand_dst (op
, mode
)
555 enum machine_mode mode
;
557 if (GET_CODE (op
) == MEM
&& GET_CODE (XEXP (op
, 0)) == PRE_DEC
)
559 return general_operand (op
, mode
);
562 /* Return true if OP is a const valid for a bit clear instruction. */
565 o_operand (operand
, mode
)
567 enum machine_mode mode ATTRIBUTE_UNUSED
;
569 return (GET_CODE (operand
) == CONST_INT
570 && CONST_OK_FOR_O (INTVAL (operand
)));
573 /* Return true if OP is a const valid for a bit set or bit xor instruction. */
576 p_operand (operand
, mode
)
578 enum machine_mode mode ATTRIBUTE_UNUSED
;
580 return (GET_CODE (operand
) == CONST_INT
581 && CONST_OK_FOR_P (INTVAL (operand
)));
584 /* Return true if OP is a valid call operand. */
587 call_insn_operand (op
, mode
)
589 enum machine_mode mode ATTRIBUTE_UNUSED
;
591 if (GET_CODE (op
) == MEM
)
593 rtx inside
= XEXP (op
, 0);
594 if (register_operand (inside
, Pmode
))
596 if (CONSTANT_ADDRESS_P (inside
))
602 /* Return 1 if an addition/subtraction of a constant integer can be
603 transformed into two consecutive adds/subs that are faster than the
604 straightforward way. Otherwise, return 0. */
607 two_insn_adds_subs_operand (op
, mode
)
609 enum machine_mode mode
;
611 if (GET_CODE (op
) == CONST_INT
)
613 HOST_WIDE_INT value
= INTVAL (op
);
615 /* Force VALUE to be positive so that we do not have to consider
616 the negative case. */
619 if (TARGET_H8300H
|| TARGET_H8300S
)
621 /* A constant addition/subtraction takes 2 states in QImode,
622 4 states in HImode, and 6 states in SImode. Thus, the
623 only case we can win is when SImode is used, in which
624 case, two adds/subs are used, taking 4 states. */
634 /* A constant addition/subtraction takes 2 states in
635 QImode. It takes 6 states in HImode, requiring the
636 constant to be loaded to a register first, and a lot more
637 in SImode. Thus the only case we can win is when either
638 HImode or SImode is used. */
649 /* Split an add of a small constant into two adds/subs insns. */
652 split_adds_subs (mode
, operands
)
653 enum machine_mode mode
;
656 HOST_WIDE_INT val
= INTVAL (operands
[1]);
657 rtx reg
= operands
[0];
658 HOST_WIDE_INT sign
= 1;
659 HOST_WIDE_INT amount
;
661 /* Force VAL to be positive so that we do not have to consider the
669 /* Try different amounts in descending order. */
670 for (amount
= (TARGET_H8300H
|| TARGET_H8300S
) ? 4 : 2;
674 for (; val
>= amount
; val
-= amount
)
676 rtx tmp
= gen_rtx_PLUS (mode
, reg
, GEN_INT (sign
* amount
));
677 emit_insn (gen_rtx_SET (VOIDmode
, reg
, tmp
));
684 /* Return true if OP is a valid call operand, and OP represents
685 an operand for a small call (4 bytes instead of 6 bytes). */
688 small_call_insn_operand (op
, mode
)
690 enum machine_mode mode ATTRIBUTE_UNUSED
;
692 if (GET_CODE (op
) == MEM
)
694 rtx inside
= XEXP (op
, 0);
696 /* Register indirect is a small call. */
697 if (register_operand (inside
, Pmode
))
700 /* A call through the function vector is a small
702 if (GET_CODE (inside
) == SYMBOL_REF
703 && SYMBOL_REF_FLAG (inside
))
706 /* Otherwise it's a large call. */
710 /* Return true if OP is a valid jump operand. */
713 jump_address_operand (op
, mode
)
715 enum machine_mode mode
;
717 if (GET_CODE (op
) == REG
)
718 return mode
== Pmode
;
720 if (GET_CODE (op
) == MEM
)
722 rtx inside
= XEXP (op
, 0);
723 if (register_operand (inside
, Pmode
))
725 if (CONSTANT_ADDRESS_P (inside
))
731 /* Recognize valid operands for bitfield instructions. */
733 extern int rtx_equal_function_value_matters
;
736 bit_operand (op
, mode
)
738 enum machine_mode mode
;
740 /* We can except any general operand, expept that MEM operands must
741 be limited to those that use addresses valid for the 'U' constraint. */
742 if (!general_operand (op
, mode
))
745 /* Accept any mem during RTL generation. Otherwise, the code that does
746 insv and extzv will think that we can not handle memory. However,
747 to avoid reload problems, we only accept 'U' MEM operands after RTL
748 generation. This means that any named pattern which uses this predicate
749 must force its operands to match 'U' before emitting RTL. */
751 if (GET_CODE (op
) == REG
)
753 if (GET_CODE (op
) == SUBREG
)
755 if (!rtx_equal_function_value_matters
)
756 /* We're building rtl. */
757 return GET_CODE (op
) == MEM
;
759 return (GET_CODE (op
) == MEM
760 && EXTRA_CONSTRAINT (op
, 'U'));
764 bit_memory_operand (op
, mode
)
766 enum machine_mode mode ATTRIBUTE_UNUSED
;
768 return (GET_CODE (op
) == MEM
769 && EXTRA_CONSTRAINT (op
, 'U'));
772 /* Handle machine specific pragmas for compatibility with existing
773 compilers for the H8/300.
775 pragma saveall generates prolog/epilog code which saves and
776 restores all the registers on function entry.
778 pragma interrupt saves and restores all registers, and exits with
779 an rte instruction rather than an rts. A pointer to a function
780 with this attribute may be safely used in an interrupt vector. */
783 h8300_pr_interrupt (pfile
)
784 cpp_reader
*pfile ATTRIBUTE_UNUSED
;
786 interrupt_handler
= 1;
790 h8300_pr_saveall (pfile
)
791 cpp_reader
*pfile ATTRIBUTE_UNUSED
;
796 static const char *const hand_list
[] =
816 /* If the next function argument with MODE and TYPE is to be passed in
817 a register, return a reg RTX for the hard register in which to pass
818 the argument. CUM represents the state after the last argument.
819 If the argument is to be pushed, NULL_RTX is returned. */
822 function_arg (cum
, mode
, type
, named
)
823 CUMULATIVE_ARGS
*cum
;
824 enum machine_mode mode
;
828 rtx result
= NULL_RTX
;
832 /* Never pass unnamed arguments in registers. */
836 /* Pass 3 regs worth of data in regs when user asked on the command line. */
837 if (TARGET_QUICKCALL
)
840 /* If calling hand written assembler, use 4 regs of args. */
843 const char * const *p
;
845 fname
= XSTR (cum
->libcall
, 0);
847 /* See if this libcall is one of the hand coded ones. */
848 for (p
= hand_list
; *p
&& strcmp (*p
, fname
) != 0; p
++)
860 size
= int_size_in_bytes (type
);
862 size
= GET_MODE_SIZE (mode
);
864 if (size
+ cum
->nbytes
<= regpass
* UNITS_PER_WORD
865 && cum
->nbytes
/ UNITS_PER_WORD
<= 3)
866 result
= gen_rtx_REG (mode
, cum
->nbytes
/ UNITS_PER_WORD
);
872 /* Return the cost of the rtx R with code CODE. */
892 if (TARGET_H8300H
|| TARGET_H8300S
)
913 /* Documentation for the machine specific operand escapes:
915 'E' like s but negative.
916 'F' like t but negative.
917 'G' constant just the negative
918 'R' print operand as a byte:8 address if appropriate, else fall back to
920 'S' print operand as a long word
921 'T' print operand as a word
922 'V' find the set bit, and print its number.
923 'W' find the clear bit, and print its number.
924 'X' print operand as a byte
925 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
926 If this operand isn't a register, fall back to 'R' handling.
928 'b' print the bit opcode
929 'e' first word of 32 bit value - if reg, then least reg. if mem
930 then least. if const then most sig word
931 'f' second word of 32 bit value - if reg, then biggest reg. if mem
932 then +2. if const then least sig word
933 'j' print operand as condition code.
934 'k' print operand as reverse condition code.
935 's' print as low byte of 16 bit value
936 't' print as high byte of 16 bit value
937 'w' print as low byte of 32 bit value
938 'x' print as 2nd byte of 32 bit value
939 'y' print as 3rd byte of 32 bit value
940 'z' print as msb of 32 bit value
943 /* Return assembly language string which identifies a comparison type. */
976 /* Print operand X using operand code CODE to assembly language output file
980 print_operand (file
, x
, code
)
985 /* This is used for communication between codes V,W,Z and Y. */
991 switch (GET_CODE (x
))
994 fprintf (file
, "%sl", names_big
[REGNO (x
)]);
997 fprintf (file
, "#%d", (-INTVAL (x
)) & 0xff);
1004 switch (GET_CODE (x
))
1007 fprintf (file
, "%sh", names_big
[REGNO (x
)]);
1010 fprintf (file
, "#%d", ((-INTVAL (x
)) & 0xff00) >> 8);
1017 if (GET_CODE (x
) != CONST_INT
)
1019 fprintf (file
, "#%d", 0xff & (-INTVAL (x
)));
1022 if (GET_CODE (x
) == REG
)
1023 fprintf (file
, "%s", names_extended
[REGNO (x
)]);
1028 if (GET_CODE (x
) == REG
)
1029 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1034 bitint
= exact_log2 (INTVAL (x
));
1037 fprintf (file
, "#%d", bitint
& 7);
1040 bitint
= exact_log2 ((~INTVAL (x
)) & 0xff);
1043 fprintf (file
, "#%d", bitint
& 7);
1047 if (GET_CODE (x
) == REG
)
1048 fprintf (file
, "%s", byte_reg (x
, 0));
1055 if (GET_CODE (x
) == REG
)
1056 fprintf (file
, "%s%c", names_big
[REGNO (x
)], bitint
> 7 ? 'h' : 'l');
1058 print_operand (file
, x
, 'R');
1062 bitint
= INTVAL (x
);
1063 fprintf (file
, "#%d", bitint
& 7);
1066 switch (GET_CODE (x
))
1069 fprintf (file
, "bor");
1072 fprintf (file
, "bxor");
1075 fprintf (file
, "band");
1082 switch (GET_CODE (x
))
1086 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1088 fprintf (file
, "%s", names_upper_extended
[REGNO (x
)]);
1091 print_operand (file
, x
, 0);
1094 fprintf (file
, "#%d", ((INTVAL (x
) >> 16) & 0xffff));
1100 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
1101 REAL_VALUE_TO_TARGET_SINGLE (rv
, val
);
1102 fprintf (file
, "#%ld", ((val
>> 16) & 0xffff));
1111 switch (GET_CODE (x
))
1115 fprintf (file
, "%s", names_big
[REGNO (x
) + 1]);
1117 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1120 x
= adjust_address (x
, HImode
, 2);
1121 print_operand (file
, x
, 0);
1124 fprintf (file
, "#%d", INTVAL (x
) & 0xffff);
1130 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
1131 REAL_VALUE_TO_TARGET_SINGLE (rv
, val
);
1132 fprintf (file
, "#%ld", (val
& 0xffff));
1140 asm_fprintf (file
, cond_string (GET_CODE (x
)));
1143 asm_fprintf (file
, cond_string (reverse_condition (GET_CODE (x
))));
1146 if (GET_CODE (x
) == CONST_INT
)
1147 fprintf (file
, "#%d", (INTVAL (x
)) & 0xff);
1149 fprintf (file
, "%s", byte_reg (x
, 0));
1152 if (GET_CODE (x
) == CONST_INT
)
1153 fprintf (file
, "#%d", (INTVAL (x
) >> 8) & 0xff);
1155 fprintf (file
, "%s", byte_reg (x
, 1));
1158 if (GET_CODE (x
) != CONST_INT
)
1160 fprintf (file
, "%d", INTVAL (x
));
1163 if (GET_CODE (x
) == CONST_INT
)
1164 fprintf (file
, "#%d", INTVAL (x
) & 0xff);
1166 fprintf (file
, "%s",
1167 byte_reg (x
, TARGET_H8300
? 2 : 0));
1170 if (GET_CODE (x
) == CONST_INT
)
1171 fprintf (file
, "#%d", (INTVAL (x
) >> 8) & 0xff);
1173 fprintf (file
, "%s",
1174 byte_reg (x
, TARGET_H8300
? 3 : 1));
1177 if (GET_CODE (x
) == CONST_INT
)
1178 fprintf (file
, "#%d", (INTVAL (x
) >> 16) & 0xff);
1180 fprintf (file
, "%s", byte_reg (x
, 0));
1183 if (GET_CODE (x
) == CONST_INT
)
1184 fprintf (file
, "#%d", (INTVAL (x
) >> 24) & 0xff);
1186 fprintf (file
, "%s", byte_reg (x
, 1));
1191 switch (GET_CODE (x
))
1194 switch (GET_MODE (x
))
1197 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */
1198 fprintf (file
, "%s", byte_reg (x
, 0));
1199 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1200 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1204 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1208 fprintf (file
, "%s", names_extended
[REGNO (x
)]);
1216 fprintf (file
, "@");
1217 output_address (XEXP (x
, 0));
1219 /* If this is an 'R' operand (reference into the 8-bit
1220 area), then specify a symbolic address as "foo:8",
1221 otherwise if operand is still in eight bit section, use
1223 if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
1224 && SYMBOL_REF_FLAG (XEXP (x
, 0)))
1225 fprintf (file
, (code
== 'R' ? ":8" : ":16"));
1226 else if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
1227 && TINY_DATA_NAME_P (XSTR (XEXP (x
, 0), 0)))
1228 fprintf (file
, ":16");
1229 else if ((code
== 'R')
1230 && EIGHTBIT_CONSTANT_ADDRESS_P (XEXP (x
, 0)))
1231 fprintf (file
, ":8");
1238 fprintf (file
, "#");
1239 print_operand_address (file
, x
);
1245 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
1246 REAL_VALUE_TO_TARGET_SINGLE (rv
, val
);
1247 fprintf (file
, "#%ld", val
);
1256 /* Output assembly language output for the address ADDR to FILE. */
1259 print_operand_address (file
, addr
)
1263 switch (GET_CODE (addr
))
1266 fprintf (file
, "%s", h8_reg_names
[REGNO (addr
)]);
1270 fprintf (file
, "-%s", h8_reg_names
[REGNO (XEXP (addr
, 0))]);
1274 fprintf (file
, "%s+", h8_reg_names
[REGNO (XEXP (addr
, 0))]);
1278 fprintf (file
, "(");
1279 if (GET_CODE (XEXP (addr
, 0)) == REG
)
1282 print_operand_address (file
, XEXP (addr
, 1));
1283 fprintf (file
, ",");
1284 print_operand_address (file
, XEXP (addr
, 0));
1289 print_operand_address (file
, XEXP (addr
, 0));
1290 fprintf (file
, "+");
1291 print_operand_address (file
, XEXP (addr
, 1));
1293 fprintf (file
, ")");
1298 /* Since the H8/300 only has 16 bit pointers, negative values are also
1299 those >= 32768. This happens for example with pointer minus a
1300 constant. We don't want to turn (char *p - 2) into
1301 (char *p + 65534) because loop unrolling can build upon this
1302 (IE: char *p + 131068). */
1303 int n
= INTVAL (addr
);
1305 n
= (int) (short) n
;
1307 /* ??? Why the special case for -ve values? */
1308 fprintf (file
, "-%d", -n
);
1310 fprintf (file
, "%d", n
);
1315 output_addr_const (file
, addr
);
1320 /* Output all insn addresses and their sizes into the assembly language
1321 output file. This is helpful for debugging whether the length attributes
1322 in the md file are correct. This is not meant to be a user selectable
1326 final_prescan_insn (insn
, operand
, num_operands
)
1327 rtx insn
, *operand ATTRIBUTE_UNUSED
;
1328 int num_operands ATTRIBUTE_UNUSED
;
1330 /* This holds the last insn address. */
1331 static int last_insn_address
= 0;
1333 int uid
= INSN_UID (insn
);
1335 if (TARGET_RTL_DUMP
)
1337 fprintf (asm_out_file
, "\n****************");
1338 print_rtl (asm_out_file
, PATTERN (insn
));
1339 fprintf (asm_out_file
, "\n");
1342 if (TARGET_ADDRESSES
)
1344 fprintf (asm_out_file
, "; 0x%x %d\n", INSN_ADDRESSES (uid
),
1345 INSN_ADDRESSES (uid
) - last_insn_address
);
1346 last_insn_address
= INSN_ADDRESSES (uid
);
1350 /* Prepare for an SI sized move. */
1356 rtx src
= operands
[1];
1357 rtx dst
= operands
[0];
1358 if (!reload_in_progress
&& !reload_completed
)
1360 if (!register_operand (dst
, GET_MODE (dst
)))
1362 rtx tmp
= gen_reg_rtx (GET_MODE (dst
));
1363 emit_move_insn (tmp
, src
);
1370 /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
1371 Define the offset between two registers, one to be eliminated, and
1372 the other its replacement, at the start of a routine. */
1375 initial_offset (from
, to
)
1380 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
1381 offset
= UNITS_PER_WORD
+ frame_pointer_needed
* UNITS_PER_WORD
;
1382 else if (from
== RETURN_ADDRESS_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
1383 offset
= frame_pointer_needed
* UNITS_PER_WORD
;
1388 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1389 if (WORD_REG_USED (regno
))
1390 offset
+= UNITS_PER_WORD
;
1392 /* See the comments for get_frame_size. We need to round it up to
1395 offset
+= ((get_frame_size () + STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
1396 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
1398 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
1399 offset
+= UNITS_PER_WORD
; /* Skip saved PC */
1405 h8300_return_addr_rtx (count
, frame
)
1412 ret
= gen_rtx_MEM (Pmode
,
1413 gen_rtx_REG (Pmode
, RETURN_ADDRESS_POINTER_REGNUM
));
1414 else if (flag_omit_frame_pointer
)
1417 ret
= gen_rtx_MEM (Pmode
,
1418 memory_address (Pmode
,
1419 plus_constant (frame
, UNITS_PER_WORD
)));
1420 set_mem_alias_set (ret
, get_frame_alias_set ());
1424 /* Update the condition code from the insn. */
1427 notice_update_cc (body
, insn
)
1431 switch (get_attr_cc (insn
))
1434 /* Insn does not affect CC at all. */
1438 /* Insn does not change CC, but the 0'th operand has been changed. */
1439 if (cc_status
.value1
!= 0
1440 && reg_overlap_mentioned_p (recog_data
.operand
[0], cc_status
.value1
))
1441 cc_status
.value1
= 0;
1445 /* Insn sets the Z,N flags of CC to recog_data.operand[0].
1446 The V flag is unusable. The C flag may or may not be known but
1447 that's ok because alter_cond will change tests to use EQ/NE. */
1449 cc_status
.flags
|= CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
;
1450 cc_status
.value1
= recog_data
.operand
[0];
1454 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
1455 The C flag may or may not be known but that's ok because
1456 alter_cond will change tests to use EQ/NE. */
1458 cc_status
.flags
|= CC_NO_CARRY
;
1459 cc_status
.value1
= recog_data
.operand
[0];
1463 /* The insn is a compare instruction. */
1465 cc_status
.value1
= SET_SRC (body
);
1469 /* Insn doesn't leave CC in a usable state. */
1475 /* Recognize valid operators for bit instructions. */
1478 bit_operator (x
, mode
)
1480 enum machine_mode mode ATTRIBUTE_UNUSED
;
1482 enum rtx_code code
= GET_CODE (x
);
1490 output_logical_op (mode
, code
, operands
)
1491 enum machine_mode mode
;
1495 /* Pretend that every byte is affected if both operands are registers. */
1496 unsigned HOST_WIDE_INT intval
=
1497 (unsigned HOST_WIDE_INT
) ((GET_CODE (operands
[2]) == CONST_INT
)
1498 ? INTVAL (operands
[2]) : 0x55555555);
1499 /* The determinant of the algorithm. If we perform an AND, 0
1500 affects a bit. Otherwise, 1 affects a bit. */
1501 unsigned HOST_WIDE_INT det
= (code
!= AND
) ? intval
: ~intval
;
1502 /* The name of an insn. */
1524 /* First, see if we can finish with one insn. */
1525 if ((TARGET_H8300H
|| TARGET_H8300S
)
1526 && ((det
& 0x00ff) != 0)
1527 && ((det
& 0xff00) != 0))
1529 sprintf (insn_buf
, "%s.w\t%%T2,%%T0", opname
);
1530 output_asm_insn (insn_buf
, operands
);
1534 /* Take care of the lower byte. */
1535 if ((det
& 0x00ff) != 0)
1537 sprintf (insn_buf
, "%s\t%%s2,%%s0", opname
);
1538 output_asm_insn (insn_buf
, operands
);
1540 /* Take care of the upper byte. */
1541 if ((det
& 0xff00) != 0)
1543 sprintf (insn_buf
, "%s\t%%t2,%%t0", opname
);
1544 output_asm_insn (insn_buf
, operands
);
1549 /* First, see if we can finish with one insn.
1551 If code is either AND or XOR, we exclude two special cases,
1552 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
1553 can do a better job. */
1554 if ((TARGET_H8300H
|| TARGET_H8300S
)
1555 && ((det
& 0x0000ffff) != 0)
1556 && ((det
& 0xffff0000) != 0)
1557 && (code
== IOR
|| det
!= 0xffffff00)
1558 && (code
== IOR
|| det
!= 0xffff00ff))
1560 sprintf (insn_buf
, "%s.l\t%%S2,%%S0", opname
);
1561 output_asm_insn (insn_buf
, operands
);
1565 /* Take care of the lower and upper words individually. For
1566 each word, we try different methods in the order of
1568 1) the special insn (in case of AND or XOR),
1569 2) the word-wise insn, and
1570 3) The byte-wise insn. */
1571 if ((TARGET_H8300H
|| TARGET_H8300S
)
1572 && ((det
& 0x0000ffff) == 0x0000ffff)
1574 output_asm_insn ((code
== AND
)
1575 ? "sub.w\t%f0,%f0" : "not.w\t%f0",
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
);
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 ((TARGET_H8300H
|| TARGET_H8300S
)
1599 && ((det
& 0xffff0000) == 0xffff0000)
1601 output_asm_insn ((code
== AND
)
1602 ? "sub.w\t%e0,%e0" : "not.w\t%e0",
1604 else if (TARGET_H8300H
|| TARGET_H8300S
)
1606 if ((det
& 0xffff0000) != 0)
1608 sprintf (insn_buf
, "%s.w\t%%e2,%%e0", opname
);
1609 output_asm_insn (insn_buf
, operands
);
1614 if ((det
& 0x00ff0000) != 0)
1616 sprintf (insn_buf
, "%s\t%%y2,%%y0", opname
);
1617 output_asm_insn (insn_buf
, operands
);
1619 if ((det
& 0xff000000) != 0)
1621 sprintf (insn_buf
, "%s\t%%z2,%%z0", opname
);
1622 output_asm_insn (insn_buf
, operands
);
1635 We devote a fair bit of code to getting efficient shifts since we
1636 can only shift one bit at a time on the H8/300 and H8/300H and only
1637 one or two bits at a time on the H8/S.
1639 All shift code falls into one of the following ways of
1642 o SHIFT_INLINE: Emit straight line code for the shift; this is used
1643 when a straight line shift is about the same size or smaller than
1646 o SHIFT_ROT_AND: Rotate the value the opposite direction, then mask
1647 off the bits we don't need. This is used when only a few of the
1648 bits in the original value will survive in the shifted value.
1650 o SHIFT_SPECIAL: Often it's possible to move a byte or a word to
1651 simulate a shift by 8, 16, or 24 bits. Once moved, a few inline
1652 shifts can be added if the shift count is slightly more than 8 or
1653 16. This case also includes other oddballs that are not worth
1656 o SHIFT_LOOP: Emit a loop using one (or two on H8/S) bit shifts.
1658 Here are some thoughts on what the absolutely positively best code
1659 is. "Best" here means some rational trade-off between code size
1660 and speed, where speed is more preferred but not at the expense of
1661 generating 20 insns.
1663 Below, a trailing '*' after the shift count indicates the "best"
1664 mode isn't implemented. We only describe SHIFT_SPECIAL cases to
1665 simplify the table. For other cases, refer to shift_alg_[qhs]i.
1667 H8/300 QImode shifts
1668 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
1670 H8/300 HImode shifts
1671 7 - shift 2nd half other way into carry.
1672 copy 1st half into 2nd half
1673 rotate 2nd half other way with carry
1674 rotate 1st half other way (no carry)
1675 mask off bits in 1st half (ASHIFT | LSHIFTRT).
1676 sign extend 1st half (ASHIFTRT)
1677 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1678 9-12 - do shift by 8, inline remaining shifts
1679 15 - ASHIFTRT: shll, subx, set other byte
1681 H8/300 SImode shifts
1682 7* - shift other way once, move bytes into place,
1683 move carry into place (possibly with sign extension)
1684 8 - move bytes into place, zero or sign extend other
1685 15* - shift other way once, move word into place, move carry into place
1686 16 - move word, zero or sign extend other
1687 24* - move bytes into place, zero or sign extend other
1688 31 - ASHIFTRT: shll top byte, subx, copy to other bytes
1690 H8/300H QImode shifts (same as H8/300 QImode shifts)
1691 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
1693 H8/300H HImode shifts
1694 7 - shift 2nd half other way into carry.
1695 copy 1st half into 2nd half
1696 rotate entire word other way using carry
1697 mask off remaining bits (ASHIFT | LSHIFTRT)
1698 sign extend remaining bits (ASHIFTRT)
1699 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1700 9-12 - do shift by 8, inline remaining shifts
1701 15 - ASHIFTRT: shll, subx, set other byte
1703 H8/300H SImode shifts
1704 (These are complicated by the fact that we don't have byte level access to
1706 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1707 15* - shift other way once, move word into place, move carry into place
1708 (with sign extension for ASHIFTRT)
1709 16 - move word into place, zero or sign extend other
1710 17-20 - do 16bit shift, then inline remaining shifts
1711 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1712 move word 0 to word 1, zero word 0
1713 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1714 zero word 1, zero byte 1
1715 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1716 sign extend byte 0, sign extend word 0
1717 25-27* - either loop, or
1718 do 24 bit shift, inline rest
1719 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1722 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
1725 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1726 9-12 - do shift by 8, inline remaining shifts
1727 15 - ASHIFTRT: shll, subx, set other byte
1730 (These are complicated by the fact that we don't have byte level access to
1732 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1733 15* - shift other way once, move word into place, move carry into place
1734 (with sign extension for ASHIFTRT)
1735 16 - move word into place, zero or sign extend other
1736 17-20 - do 16bit shift, then inline remaining shifts
1737 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1738 move word 0 to word 1, zero word 0
1739 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1740 zero word 1, zero byte 1
1741 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1742 sign extend byte 0, sign extend word 0
1743 25-27* - either loop, or
1744 do 24 bit shift, inline rest
1745 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1750 nshift_operator (x
, mode
)
1752 enum machine_mode mode ATTRIBUTE_UNUSED
;
1754 switch (GET_CODE (x
))
1766 /* Called from the .md file to emit code to do shifts.
1767 Return a boolean indicating success.
1768 (Currently this is always TRUE). */
1771 expand_a_shift (mode
, code
, operands
)
1772 enum machine_mode mode
;
1776 emit_move_insn (operands
[0], operands
[1]);
1778 /* Need a loop to get all the bits we want - we generate the
1779 code at emit time, but need to allocate a scratch reg now. */
1781 emit_insn (gen_rtx_PARALLEL
1784 gen_rtx_SET (VOIDmode
, operands
[0],
1785 gen_rtx (code
, mode
, operands
[0],
1787 gen_rtx_CLOBBER (VOIDmode
,
1788 gen_rtx_SCRATCH (QImode
)))));
1793 /* See above for explanation of this enum. */
1803 /* Symbols of the various shifts which can be used as indices. */
1807 SHIFT_ASHIFT
, SHIFT_LSHIFTRT
, SHIFT_ASHIFTRT
1810 /* Symbols of the various modes which can be used as indices. */
1814 QIshift
, HIshift
, SIshift
1817 /* For single bit shift insns, record assembler and what bits of the
1818 condition code are valid afterwards (represented as various CC_FOO
1819 bits, 0 means CC isn't left in a usable state). */
1823 const char *const assembler
;
1827 /* Assembler instruction shift table.
1829 These tables are used to look up the basic shifts.
1830 They are indexed by cpu, shift_type, and mode. */
1832 static const struct shift_insn shift_one
[2][3][3] =
1838 { "shll\t%X0", CC_NO_CARRY
},
1839 { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1840 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }
1842 /* SHIFT_LSHIFTRT */
1844 { "shlr\t%X0", CC_NO_CARRY
},
1845 { "shlr\t%t0\n\trotxr\t%s0", 0 },
1846 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1848 /* SHIFT_ASHIFTRT */
1850 { "shar\t%X0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1851 { "shar\t%t0\n\trotxr\t%s0", 0 },
1852 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1859 { "shll.b\t%X0", CC_NO_CARRY
},
1860 { "shll.w\t%T0", CC_NO_CARRY
},
1861 { "shll.l\t%S0", CC_NO_CARRY
}
1863 /* SHIFT_LSHIFTRT */
1865 { "shlr.b\t%X0", CC_NO_CARRY
},
1866 { "shlr.w\t%T0", CC_NO_CARRY
},
1867 { "shlr.l\t%S0", CC_NO_CARRY
}
1869 /* SHIFT_ASHIFTRT */
1871 { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1872 { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1873 { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
}
1878 static const struct shift_insn shift_two
[3][3] =
1882 { "shll.b\t#2,%X0", CC_NO_CARRY
},
1883 { "shll.w\t#2,%T0", CC_NO_CARRY
},
1884 { "shll.l\t#2,%S0", CC_NO_CARRY
}
1886 /* SHIFT_LSHIFTRT */
1888 { "shlr.b\t#2,%X0", CC_NO_CARRY
},
1889 { "shlr.w\t#2,%T0", CC_NO_CARRY
},
1890 { "shlr.l\t#2,%S0", CC_NO_CARRY
}
1892 /* SHIFT_ASHIFTRT */
1894 { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1895 { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1896 { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
}
1900 /* Rotates are organized by which shift they'll be used in implementing.
1901 There's no need to record whether the cc is valid afterwards because
1902 it is the AND insn that will decide this. */
1904 static const char *const rotate_one
[2][3][3] =
1911 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
1914 /* SHIFT_LSHIFTRT */
1917 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
1920 /* SHIFT_ASHIFTRT */
1923 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
1935 /* SHIFT_LSHIFTRT */
1941 /* SHIFT_ASHIFTRT */
1950 static const char *const rotate_two
[3][3] =
1958 /* SHIFT_LSHIFTRT */
1964 /* SHIFT_ASHIFTRT */
1972 /* Macros to keep the shift algorithm tables small. */
1973 #define INL SHIFT_INLINE
1974 #define ROT SHIFT_ROT_AND
1975 #define LOP SHIFT_LOOP
1976 #define SPC SHIFT_SPECIAL
1978 /* The shift algorithms for each machine, mode, shift type, and shift
1979 count are defined below. The three tables below correspond to
1980 QImode, HImode, and SImode, respectively. Each table is organized
1981 by, in the order of indecies, machine, shift type, and shift count. */
1983 static const enum shift_alg shift_alg_qi
[3][3][8] = {
1986 /* 0 1 2 3 4 5 6 7 */
1987 { INL
, INL
, INL
, INL
, INL
, ROT
, ROT
, ROT
}, /* SHIFT_ASHIFT */
1988 { INL
, INL
, INL
, INL
, INL
, ROT
, ROT
, ROT
}, /* SHIFT_LSHIFTRT */
1989 { INL
, INL
, INL
, INL
, INL
, LOP
, LOP
, SPC
} /* SHIFT_ASHIFTRT */
1993 /* 0 1 2 3 4 5 6 7 */
1994 { INL
, INL
, INL
, INL
, INL
, ROT
, ROT
, ROT
}, /* SHIFT_ASHIFT */
1995 { INL
, INL
, INL
, INL
, INL
, ROT
, ROT
, ROT
}, /* SHIFT_LSHIFTRT */
1996 { INL
, INL
, INL
, INL
, INL
, LOP
, LOP
, SPC
} /* SHIFT_ASHIFTRT */
2000 /* 0 1 2 3 4 5 6 7 */
2001 { INL
, INL
, INL
, INL
, INL
, INL
, ROT
, ROT
}, /* SHIFT_ASHIFT */
2002 { INL
, INL
, INL
, INL
, INL
, INL
, ROT
, ROT
}, /* SHIFT_LSHIFTRT */
2003 { INL
, INL
, INL
, INL
, INL
, INL
, INL
, SPC
} /* SHIFT_ASHIFTRT */
2007 static const enum shift_alg shift_alg_hi
[3][3][16] = {
2010 /* 0 1 2 3 4 5 6 7 */
2011 /* 8 9 10 11 12 13 14 15 */
2012 { INL
, INL
, INL
, INL
, INL
, LOP
, LOP
, SPC
,
2013 SPC
, SPC
, SPC
, SPC
, SPC
, LOP
, LOP
, ROT
}, /* SHIFT_ASHIFT */
2014 { INL
, INL
, INL
, INL
, INL
, LOP
, LOP
, SPC
,
2015 SPC
, SPC
, SPC
, SPC
, SPC
, LOP
, LOP
, ROT
}, /* SHIFT_LSHIFTRT */
2016 { INL
, INL
, INL
, INL
, INL
, LOP
, LOP
, SPC
,
2017 SPC
, SPC
, SPC
, SPC
, SPC
, LOP
, LOP
, SPC
}, /* SHIFT_ASHIFTRT */
2021 /* 0 1 2 3 4 5 6 7 */
2022 /* 8 9 10 11 12 13 14 15 */
2023 { INL
, INL
, INL
, INL
, INL
, LOP
, LOP
, SPC
,
2024 SPC
, SPC
, SPC
, SPC
, SPC
, ROT
, ROT
, ROT
}, /* SHIFT_ASHIFT */
2025 { INL
, INL
, INL
, INL
, INL
, LOP
, LOP
, SPC
,
2026 SPC
, SPC
, SPC
, SPC
, SPC
, ROT
, ROT
, ROT
}, /* SHIFT_LSHIFTRT */
2027 { INL
, INL
, INL
, INL
, INL
, LOP
, LOP
, SPC
,
2028 SPC
, SPC
, SPC
, SPC
, SPC
, LOP
, LOP
, SPC
}, /* SHIFT_ASHIFTRT */
2032 /* 0 1 2 3 4 5 6 7 */
2033 /* 8 9 10 11 12 13 14 15 */
2034 { INL
, INL
, INL
, INL
, INL
, INL
, INL
, INL
,
2035 SPC
, SPC
, SPC
, SPC
, SPC
, ROT
, ROT
, ROT
}, /* SHIFT_ASHIFT */
2036 { INL
, INL
, INL
, INL
, INL
, INL
, INL
, INL
,
2037 SPC
, SPC
, SPC
, SPC
, SPC
, ROT
, ROT
, ROT
}, /* SHIFT_LSHIFTRT */
2038 { INL
, INL
, INL
, INL
, INL
, INL
, INL
, INL
,
2039 SPC
, SPC
, SPC
, SPC
, SPC
, LOP
, LOP
, SPC
}, /* SHIFT_ASHIFTRT */
2043 static const enum shift_alg shift_alg_si
[3][3][32] = {
2046 /* 0 1 2 3 4 5 6 7 */
2047 /* 8 9 10 11 12 13 14 15 */
2048 /* 16 17 18 19 20 21 22 23 */
2049 /* 24 25 26 27 28 29 30 31 */
2050 { INL
, INL
, INL
, LOP
, LOP
, LOP
, LOP
, LOP
,
2051 SPC
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
,
2052 SPC
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
,
2053 LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, SPC
}, /* SHIFT_ASHIFT */
2054 { INL
, INL
, INL
, LOP
, LOP
, LOP
, LOP
, LOP
,
2055 SPC
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
,
2056 SPC
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
,
2057 LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, SPC
}, /* SHIFT_LSHIFTRT */
2058 { INL
, INL
, INL
, LOP
, LOP
, LOP
, LOP
, LOP
,
2059 SPC
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
,
2060 SPC
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
,
2061 LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, SPC
}, /* SHIFT_ASHIFTRT */
2065 /* 0 1 2 3 4 5 6 7 */
2066 /* 8 9 10 11 12 13 14 15 */
2067 /* 16 17 18 19 20 21 22 23 */
2068 /* 24 25 26 27 28 29 30 31 */
2069 { INL
, INL
, INL
, INL
, INL
, LOP
, LOP
, LOP
,
2070 SPC
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, SPC
,
2071 SPC
, SPC
, SPC
, SPC
, LOP
, LOP
, LOP
, LOP
,
2072 SPC
, LOP
, LOP
, LOP
, ROT
, ROT
, ROT
, SPC
}, /* SHIFT_ASHIFT */
2073 { INL
, INL
, INL
, INL
, INL
, LOP
, LOP
, LOP
,
2074 SPC
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, SPC
,
2075 SPC
, SPC
, SPC
, SPC
, LOP
, LOP
, LOP
, LOP
,
2076 SPC
, LOP
, LOP
, LOP
, ROT
, ROT
, ROT
, SPC
}, /* SHIFT_LSHIFTRT */
2077 { INL
, INL
, INL
, INL
, INL
, LOP
, LOP
, LOP
,
2078 SPC
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
,
2079 SPC
, SPC
, SPC
, SPC
, LOP
, LOP
, LOP
, LOP
,
2080 SPC
, LOP
, LOP
, LOP
, LOP
, LOP
, LOP
, SPC
}, /* SHIFT_ASHIFTRT */
2084 /* 0 1 2 3 4 5 6 7 */
2085 /* 8 9 10 11 12 13 14 15 */
2086 /* 16 17 18 19 20 21 22 23 */
2087 /* 24 25 26 27 28 29 30 31 */
2088 { INL
, INL
, INL
, INL
, INL
, INL
, INL
, INL
,
2089 INL
, INL
, INL
, LOP
, LOP
, LOP
, LOP
, SPC
,
2090 SPC
, SPC
, SPC
, SPC
, SPC
, SPC
, LOP
, LOP
,
2091 SPC
, SPC
, LOP
, LOP
, ROT
, ROT
, ROT
, SPC
}, /* SHIFT_ASHIFT */
2092 { INL
, INL
, INL
, INL
, INL
, INL
, INL
, INL
,
2093 INL
, INL
, INL
, LOP
, LOP
, LOP
, LOP
, SPC
,
2094 SPC
, SPC
, SPC
, SPC
, SPC
, SPC
, LOP
, LOP
,
2095 SPC
, SPC
, LOP
, LOP
, ROT
, ROT
, ROT
, SPC
}, /* SHIFT_LSHIFTRT */
2096 { INL
, INL
, INL
, INL
, INL
, INL
, INL
, INL
,
2097 INL
, INL
, INL
, LOP
, LOP
, LOP
, LOP
, LOP
,
2098 SPC
, SPC
, SPC
, SPC
, SPC
, SPC
, LOP
, LOP
,
2099 SPC
, SPC
, LOP
, LOP
, LOP
, LOP
, LOP
, SPC
}, /* SHIFT_ASHIFTRT */
2109 /* Shift algorithm. */
2112 /* The number of bits to be shifted by shift1 and shift2. Valid
2113 when ALG is SHIFT_SPECIAL. */
2114 unsigned int remainder
;
2116 /* Special insn for a shift. Valid when ALG is SHIFT_SPECIAL. */
2117 const char *special
;
2119 /* Insn for a one-bit shift. Valid when ALG is either SHIFT_INLINE
2120 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2123 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
2124 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2127 /* Valid CC flags. */
2131 static void get_shift_alg
PARAMS ((enum shift_type
,
2132 enum shift_mode
, unsigned int,
2133 struct shift_info
*));
2135 /* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
2136 best algorithm for doing the shift. The assembler code is stored
2137 in the pointers in INFO. We don't achieve maximum efficiency in
2138 all cases, but the hooks are here to do so.
2140 For now we just use lots of switch statements. Since we don't even come
2141 close to supporting all the cases, this is simplest. If this function ever
2142 gets too big, perhaps resort to a more table based lookup. Of course,
2143 at this point you may just wish to do it all in rtl.
2145 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
2146 1,2,3,4 will be inlined (1,2 for SI). */
2149 get_shift_alg (shift_type
, shift_mode
, count
, info
)
2150 enum shift_type shift_type
;
2151 enum shift_mode shift_mode
;
2153 struct shift_info
*info
;
2157 /* Find the target CPU. */
2160 else if (TARGET_H8300H
)
2165 /* Find the shift algorithm. */
2169 if (GET_MODE_BITSIZE (QImode
) <= count
)
2170 info
->alg
= SHIFT_LOOP
;
2172 info
->alg
= shift_alg_qi
[cpu
][shift_type
][count
];
2176 if (GET_MODE_BITSIZE (HImode
) <= count
)
2177 info
->alg
= SHIFT_LOOP
;
2179 info
->alg
= shift_alg_hi
[cpu
][shift_type
][count
];
2183 if (GET_MODE_BITSIZE (SImode
) <= count
)
2184 info
->alg
= SHIFT_LOOP
;
2186 info
->alg
= shift_alg_si
[cpu
][shift_type
][count
];
2193 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
2197 info
->remainder
= count
;
2201 /* It is up to the caller to know that looping clobbers cc. */
2202 info
->shift1
= shift_one
[cpu_type
][shift_type
][shift_mode
].assembler
;
2203 info
->shift2
= shift_two
[shift_type
][shift_mode
].assembler
;
2204 info
->cc_valid_p
= shift_one
[cpu_type
][shift_type
][shift_mode
].cc_valid
;
2208 info
->shift1
= rotate_one
[cpu_type
][shift_type
][shift_mode
];
2209 info
->shift2
= rotate_two
[shift_type
][shift_mode
];
2210 info
->cc_valid_p
= 0;
2214 /* REMAINDER is 0 for most cases, so initialize it to 0. */
2215 info
->remainder
= 0;
2216 info
->shift1
= shift_one
[cpu_type
][shift_type
][shift_mode
].assembler
;
2217 info
->shift2
= shift_two
[shift_type
][shift_mode
].assembler
;
2218 info
->cc_valid_p
= 0;
2222 /* Here we only deal with SHIFT_SPECIAL. */
2226 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2227 through the entire value. */
2228 if (shift_type
== SHIFT_ASHIFTRT
&& count
== 7)
2230 info
->special
= "shll\t%X0\n\tsubx\t%X0,%X0";
2242 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";
2244 info
->special
= "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
2246 case SHIFT_LSHIFTRT
:
2248 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";
2250 info
->special
= "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
2252 case SHIFT_ASHIFTRT
:
2253 info
->special
= "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
2257 else if (8 <= count
&& count
<= 12)
2259 info
->remainder
= count
- 8;
2264 info
->special
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
2265 info
->shift1
= "shal.b\t%t0";
2266 info
->shift2
= "shal.b\t#2,%t0";
2268 case SHIFT_LSHIFTRT
:
2269 info
->special
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
2270 info
->shift1
= "shlr.b\t%s0";
2271 info
->shift2
= "shlr.b\t#2,%s0";
2273 case SHIFT_ASHIFTRT
:
2275 info
->special
= "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
2277 info
->special
= "mov.b\t%t0,%s0\n\texts.w\t%T0";
2278 info
->shift1
= "shar.b\t%s0";
2279 info
->shift2
= "shar.b\t#2,%s0";
2283 else if (count
== 15 && shift_type
== SHIFT_ASHIFTRT
)
2285 info
->special
= "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
2291 if (count
== 8 && TARGET_H8300
)
2296 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";
2298 case SHIFT_LSHIFTRT
:
2299 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";
2301 case SHIFT_ASHIFTRT
:
2302 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";
2306 else if (count
== 8 && !TARGET_H8300
)
2311 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";
2313 case SHIFT_LSHIFTRT
:
2314 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";
2316 case SHIFT_ASHIFTRT
:
2317 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";
2321 else if (count
== 15 && !TARGET_H8300
)
2326 info
->special
= "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
2328 case SHIFT_LSHIFTRT
:
2329 info
->special
= "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
2331 case SHIFT_ASHIFTRT
:
2335 else if ((TARGET_H8300
&& count
== 16)
2336 || (TARGET_H8300H
&& 16 <= count
&& count
<= 19)
2337 || (TARGET_H8300S
&& 16 <= count
&& count
<= 21))
2339 info
->remainder
= count
- 16;
2344 info
->special
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2345 info
->shift1
= "shll.l\t%S0";
2346 info
->shift2
= "shll.l\t#2,%S0";
2348 case SHIFT_LSHIFTRT
:
2349 info
->special
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
2350 info
->shift1
= "shlr.l\t%S0";
2351 info
->shift2
= "shlr.l\t#2,%S0";
2353 case SHIFT_ASHIFTRT
:
2355 info
->special
= "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2357 info
->special
= "mov.w\t%e0,%f0\n\texts.l\t%S0";
2358 info
->shift1
= "shar.l\t%S0";
2359 info
->shift2
= "shar.l\t#2,%S0";
2363 else if ((TARGET_H8300H
&& count
== 24)
2364 || (TARGET_H8300S
&& 24 <= count
&& count
<= 25))
2366 info
->remainder
= count
- 24;
2371 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";
2372 info
->shift1
= "shll.l\t%S0";
2373 info
->shift2
= "shll.l\t#2,%S0";
2375 case SHIFT_LSHIFTRT
:
2376 info
->special
= "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
2377 info
->shift1
= "shlr.l\t%S0";
2378 info
->shift2
= "shlr.l\t#2,%S0";
2380 case SHIFT_ASHIFTRT
:
2381 info
->special
= "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
2382 info
->shift1
= "shar.l\t%S0";
2383 info
->shift2
= "shar.l\t#2,%S0";
2387 else if (count
== 31)
2394 info
->special
= "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2396 case SHIFT_LSHIFTRT
:
2397 info
->special
= "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2399 case SHIFT_ASHIFTRT
:
2400 info
->special
= "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2409 info
->special
= "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
2411 case SHIFT_LSHIFTRT
:
2412 info
->special
= "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
2414 case SHIFT_ASHIFTRT
:
2415 info
->special
= "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2428 info
->shift2
= NULL
;
2431 /* Emit the assembler code for doing shifts. */
2434 output_a_shift (insn
, operands
)
2435 rtx insn ATTRIBUTE_UNUSED
;
2438 static int loopend_lab
;
2439 rtx shift
= operands
[3];
2440 enum machine_mode mode
= GET_MODE (shift
);
2441 enum rtx_code code
= GET_CODE (shift
);
2442 enum shift_type shift_type
;
2443 enum shift_mode shift_mode
;
2444 struct shift_info info
;
2451 shift_mode
= QIshift
;
2454 shift_mode
= HIshift
;
2457 shift_mode
= SIshift
;
2466 shift_type
= SHIFT_ASHIFTRT
;
2469 shift_type
= SHIFT_LSHIFTRT
;
2472 shift_type
= SHIFT_ASHIFT
;
2478 if (GET_CODE (operands
[2]) != CONST_INT
)
2480 /* Indexing by reg, so have to loop and test at top. */
2481 output_asm_insn ("mov.b %X2,%X4", operands
);
2482 fprintf (asm_out_file
, "\tble .Lle%d\n", loopend_lab
);
2484 /* Get the assembler code to do one shift. */
2485 get_shift_alg (shift_type
, shift_mode
, 1, &info
);
2487 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
2488 output_asm_insn (info
.shift1
, operands
);
2489 output_asm_insn ("add #0xff,%X4", operands
);
2490 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
2491 fprintf (asm_out_file
, ".Lle%d:\n", loopend_lab
);
2497 int n
= INTVAL (operands
[2]);
2499 /* If the count is negative, make it 0. */
2502 /* If the count is too big, truncate it.
2503 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2504 do the intuitive thing. */
2505 else if ((unsigned int) n
> GET_MODE_BITSIZE (mode
))
2506 n
= GET_MODE_BITSIZE (mode
);
2508 get_shift_alg (shift_type
, shift_mode
, n
, &info
);
2513 output_asm_insn (info
.special
, operands
);
2519 /* Emit two bit shifts first. */
2520 while (n
> 1 && info
.shift2
!= NULL
)
2522 output_asm_insn (info
.shift2
, operands
);
2526 /* Now emit one bit shifts for any residual. */
2529 output_asm_insn (info
.shift1
, operands
);
2533 /* Keep track of CC. */
2534 if (info
.cc_valid_p
)
2536 cc_status
.value1
= operands
[0];
2537 cc_status
.flags
|= info
.cc_valid_p
;
2543 int m
= GET_MODE_BITSIZE (mode
) - n
;
2544 int mask
= (shift_type
== SHIFT_ASHIFT
2545 ? ((1 << (GET_MODE_BITSIZE (mode
) - n
)) - 1) << n
2546 : (1 << (GET_MODE_BITSIZE (mode
) - n
)) - 1);
2549 /* Not all possibilities of rotate are supported. They shouldn't
2550 be generated, but let's watch for 'em. */
2551 if (info
.shift1
== 0)
2554 /* Emit two bit rotates first. */
2555 while (m
> 1 && info
.shift2
!= NULL
)
2557 output_asm_insn (info
.shift2
, operands
);
2561 /* Now single bit rotates for any residual. */
2564 output_asm_insn (info
.shift1
, operands
);
2568 /* Now mask off the high bits. */
2574 sprintf (insn_buf
, "and\t#%d,%%X0", mask
);
2575 cc_status
.value1
= operands
[0];
2576 cc_status
.flags
|= CC_NO_CARRY
;
2579 sprintf (insn_buf
, "and\t#%d,%%s0\n\tand\t#%d,%%t0",
2580 mask
& 255, mask
>> 8);
2590 sprintf (insn_buf
, "and.%c\t#%d,%%%c0",
2591 "bwl"[shift_mode
], mask
,
2592 mode
== QImode
? 'X' : mode
== HImode
? 'T' : 'S');
2593 cc_status
.value1
= operands
[0];
2594 cc_status
.flags
|= CC_NO_CARRY
;
2596 output_asm_insn (insn_buf
, operands
);
2601 /* A loop to shift by a "large" constant value.
2602 If we have shift-by-2 insns, use them. */
2603 if (info
.shift2
!= NULL
)
2605 fprintf (asm_out_file
, "\tmov.b #%d,%sl\n", n
/ 2,
2606 names_big
[REGNO (operands
[4])]);
2607 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
2608 output_asm_insn (info
.shift2
, operands
);
2609 output_asm_insn ("add #0xff,%X4", operands
);
2610 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
2612 output_asm_insn (info
.shift1
, operands
);
2616 fprintf (asm_out_file
, "\tmov.b #%d,%sl\n", n
,
2617 names_big
[REGNO (operands
[4])]);
2618 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
2619 output_asm_insn (info
.shift1
, operands
);
2620 output_asm_insn ("add #0xff,%X4", operands
);
2621 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
2631 /* A rotation by a non-constant will cause a loop to be generated, in
2632 which a rotation by one bit is used. A rotation by a constant,
2633 including the one in the loop, will be taken care of by
2634 emit_a_rotate () at the insn emit time. */
2637 expand_a_rotate (code
, operands
)
2641 rtx dst
= operands
[0];
2642 rtx src
= operands
[1];
2643 rtx rotate_amount
= operands
[2];
2644 enum machine_mode mode
= GET_MODE (dst
);
2647 /* We rotate in place. */
2648 emit_move_insn (dst
, src
);
2650 if (GET_CODE (rotate_amount
) != CONST_INT
)
2652 rtx counter
= gen_reg_rtx (QImode
);
2653 rtx start_label
= gen_label_rtx ();
2654 rtx end_label
= gen_label_rtx ();
2656 /* If the rotate amount is less than or equal to 0,
2657 we go out of the loop. */
2658 emit_cmp_and_jump_insns (rotate_amount
, GEN_INT (0), LE
, NULL_RTX
,
2659 QImode
, 0, end_label
);
2661 /* Initialize the loop counter. */
2662 emit_move_insn (counter
, rotate_amount
);
2664 emit_label (start_label
);
2666 /* Rotate by one bit. */
2667 tmp
= gen_rtx (code
, mode
, dst
, GEN_INT (1));
2668 emit_insn (gen_rtx_SET (mode
, dst
, tmp
));
2670 /* Decrement the counter by 1. */
2671 tmp
= gen_rtx_PLUS (QImode
, counter
, GEN_INT (-1));
2672 emit_insn (gen_rtx_SET (VOIDmode
, counter
, tmp
));
2674 /* If the loop counter is non-zero, we go back to the beginning
2676 emit_cmp_and_jump_insns (counter
, GEN_INT (0), NE
, NULL_RTX
, QImode
, 1,
2679 emit_label (end_label
);
2683 /* Rotate by AMOUNT bits. */
2684 tmp
= gen_rtx (code
, mode
, dst
, rotate_amount
);
2685 emit_insn (gen_rtx_SET (mode
, dst
, tmp
));
2691 /* Emit rotate insns. */
2694 emit_a_rotate (code
, operands
)
2698 rtx dst
= operands
[0];
2699 rtx rotate_amount
= operands
[2];
2700 enum shift_mode rotate_mode
;
2701 enum shift_type rotate_type
;
2702 const char *insn_buf
;
2705 enum machine_mode mode
= GET_MODE (dst
);
2707 if (GET_CODE (rotate_amount
) != CONST_INT
)
2713 rotate_mode
= QIshift
;
2716 rotate_mode
= HIshift
;
2719 rotate_mode
= SIshift
;
2728 rotate_type
= SHIFT_ASHIFT
;
2731 rotate_type
= SHIFT_LSHIFTRT
;
2737 amount
= INTVAL (rotate_amount
);
2739 /* Clean up AMOUNT. */
2742 if ((unsigned int) amount
> GET_MODE_BITSIZE (mode
))
2743 amount
= GET_MODE_BITSIZE (mode
);
2745 /* Determine the faster direction. After this phase, amount will be
2746 at most a half of GET_MODE_BITSIZE (mode). */
2747 if ((unsigned int) amount
> GET_MODE_BITSIZE (mode
) / 2U)
2749 /* Flip the direction. */
2750 amount
= GET_MODE_BITSIZE (mode
) - amount
;
2752 (rotate_type
== SHIFT_ASHIFT
) ? SHIFT_LSHIFTRT
: SHIFT_ASHIFT
;
2755 /* See if a byte swap (in HImode) or a word swap (in SImode) can
2756 boost up the rotation. */
2757 if ((mode
== HImode
&& TARGET_H8300
&& amount
>= 5)
2758 || (mode
== HImode
&& TARGET_H8300H
&& amount
>= 6)
2759 || (mode
== HImode
&& TARGET_H8300S
&& amount
== 8)
2760 || (mode
== SImode
&& TARGET_H8300H
&& amount
>= 10)
2761 || (mode
== SImode
&& TARGET_H8300S
&& amount
>= 13))
2766 /* This code works on any family. */
2767 insn_buf
= "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
2768 output_asm_insn (insn_buf
, operands
);
2772 /* This code works on the H8/300H and H8/S. */
2773 insn_buf
= "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
2774 output_asm_insn (insn_buf
, operands
);
2781 /* Adjust AMOUNT and flip the direction. */
2782 amount
= GET_MODE_BITSIZE (mode
) / 2 - amount
;
2784 (rotate_type
== SHIFT_ASHIFT
) ? SHIFT_LSHIFTRT
: SHIFT_ASHIFT
;
2787 /* Emit rotate insns. */
2788 for (bits
= TARGET_H8300S
? 2 : 1; bits
> 0; bits
/= 2)
2791 insn_buf
= rotate_two
[rotate_type
][rotate_mode
];
2793 insn_buf
= rotate_one
[cpu_type
][rotate_type
][rotate_mode
];
2795 for (; amount
>= bits
; amount
-= bits
)
2796 output_asm_insn (insn_buf
, operands
);
2802 /* Fix the operands of a gen_xxx so that it could become a bit
2806 fix_bit_operand (operands
, what
, type
)
2811 /* The bit_operand predicate accepts any memory during RTL generation, but
2812 only 'U' memory afterwards, so if this is a MEM operand, we must force
2813 it to be valid for 'U' by reloading the address. */
2815 if (GET_CODE (operands
[2]) == CONST_INT
)
2817 if (CONST_OK_FOR_LETTER_P (INTVAL (operands
[2]), what
))
2819 /* Ok to have a memory dest. */
2820 if (GET_CODE (operands
[0]) == MEM
2821 && !EXTRA_CONSTRAINT (operands
[0], 'U'))
2823 rtx mem
= gen_rtx_MEM (GET_MODE (operands
[0]),
2824 copy_to_mode_reg (Pmode
,
2825 XEXP (operands
[0], 0)));
2826 MEM_COPY_ATTRIBUTES (mem
, operands
[0]);
2830 if (GET_CODE (operands
[1]) == MEM
2831 && !EXTRA_CONSTRAINT (operands
[1], 'U'))
2833 rtx mem
= gen_rtx_MEM (GET_MODE (operands
[1]),
2834 copy_to_mode_reg (Pmode
,
2835 XEXP (operands
[1], 0)));
2836 MEM_COPY_ATTRIBUTES (mem
, operands
[0]);
2843 /* Dest and src op must be register. */
2845 operands
[1] = force_reg (QImode
, operands
[1]);
2847 rtx res
= gen_reg_rtx (QImode
);
2848 emit_insn (gen_rtx_SET (VOIDmode
, res
,
2849 gen_rtx (type
, QImode
, operands
[1], operands
[2])));
2850 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], res
));
2855 /* Return nonzero if FUNC is an interrupt function as specified
2856 by the "interrupt" attribute. */
2859 h8300_interrupt_function_p (func
)
2864 if (TREE_CODE (func
) != FUNCTION_DECL
)
2867 a
= lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func
));
2868 return a
!= NULL_TREE
;
2871 /* Return nonzero if FUNC is an OS_Task function as specified
2872 by the "OS_Task" attribute. */
2875 h8300_os_task_function_p (func
)
2880 if (TREE_CODE (func
) != FUNCTION_DECL
)
2883 a
= lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func
));
2884 return a
!= NULL_TREE
;
2887 /* Return nonzero if FUNC is a monitor function as specified
2888 by the "monitor" attribute. */
2891 h8300_monitor_function_p (func
)
2896 if (TREE_CODE (func
) != FUNCTION_DECL
)
2899 a
= lookup_attribute ("monitor", DECL_ATTRIBUTES (func
));
2900 return a
!= NULL_TREE
;
2903 /* Return nonzero if FUNC is a function that should be called
2904 through the function vector. */
2907 h8300_funcvec_function_p (func
)
2912 if (TREE_CODE (func
) != FUNCTION_DECL
)
2915 a
= lookup_attribute ("function_vector", DECL_ATTRIBUTES (func
));
2916 return a
!= NULL_TREE
;
2919 /* Return nonzero if DECL is a variable that's in the eight bit
2923 h8300_eightbit_data_p (decl
)
2928 if (TREE_CODE (decl
) != VAR_DECL
)
2931 a
= lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl
));
2932 return a
!= NULL_TREE
;
2935 /* Return nonzero if DECL is a variable that's in the tiny
2939 h8300_tiny_data_p (decl
)
2944 if (TREE_CODE (decl
) != VAR_DECL
)
2947 a
= lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl
));
2948 return a
!= NULL_TREE
;
2951 /* Supported attributes:
2953 interrupt_handler: output a prologue and epilogue suitable for an
2956 function_vector: This function should be called through the
2959 eightbit_data: This variable lives in the 8-bit data area and can
2960 be referenced with 8-bit absolute memory addresses.
2962 tiny_data: This variable lives in the tiny data area and can be
2963 referenced with 16-bit absolute memory references. */
2965 const struct attribute_spec h8300_attribute_table
[] =
2967 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
2968 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute
},
2969 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute
},
2970 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute
},
2971 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute
},
2972 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute
},
2973 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute
},
2974 { NULL
, 0, 0, false, false, false, NULL
}
2978 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
2979 struct attribute_spec.handler. */
2981 h8300_handle_fndecl_attribute (node
, name
, args
, flags
, no_add_attrs
)
2984 tree args ATTRIBUTE_UNUSED
;
2985 int flags ATTRIBUTE_UNUSED
;
2988 if (TREE_CODE (*node
) != FUNCTION_DECL
)
2990 warning ("`%s' attribute only applies to functions",
2991 IDENTIFIER_POINTER (name
));
2992 *no_add_attrs
= true;
2998 /* Handle an "eightbit_data" attribute; arguments as in
2999 struct attribute_spec.handler. */
3001 h8300_handle_eightbit_data_attribute (node
, name
, args
, flags
, no_add_attrs
)
3004 tree args ATTRIBUTE_UNUSED
;
3005 int flags ATTRIBUTE_UNUSED
;
3010 if (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
))
3012 DECL_SECTION_NAME (decl
) = build_string (7, ".eight");
3016 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
3017 *no_add_attrs
= true;
3023 /* Handle an "tiny_data" attribute; arguments as in
3024 struct attribute_spec.handler. */
3026 h8300_handle_tiny_data_attribute (node
, name
, args
, flags
, no_add_attrs
)
3029 tree args ATTRIBUTE_UNUSED
;
3030 int flags ATTRIBUTE_UNUSED
;
3035 if (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
))
3037 DECL_SECTION_NAME (decl
) = build_string (6, ".tiny");
3041 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
3042 *no_add_attrs
= true;
3049 h8300_encode_label (decl
)
3052 const char *str
= XSTR (XEXP (DECL_RTL (decl
), 0), 0);
3053 int len
= strlen (str
);
3054 char *newstr
= alloca (len
+ 2);
3057 strcpy (&newstr
[1], str
);
3059 XSTR (XEXP (DECL_RTL (decl
), 0), 0) =
3060 ggc_alloc_string (newstr
, len
+ 1);
3064 output_simode_bld (bild
, operands
)
3068 /* Clear the destination register. */
3069 if (TARGET_H8300H
|| TARGET_H8300S
)
3070 output_asm_insn ("sub.l\t%S0,%S0", operands
);
3072 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands
);
3074 /* Now output the bit load or bit inverse load, and store it in
3077 output_asm_insn ("bild\t%Z2,%Y1\n\tbst\t#0,%w0", operands
);
3079 output_asm_insn ("bld\t%Z2,%Y1\n\tbst\t#0,%w0", operands
);
3085 /* Given INSN and its current length LENGTH, return the adjustment
3086 (in bytes) to correctly compute INSN's length.
3088 We use this to get the lengths of various memory references correct. */
3091 h8300_adjust_insn_length (insn
, length
)
3093 int length ATTRIBUTE_UNUSED
;
3095 rtx pat
= PATTERN (insn
);
3097 /* We must filter these out before calling get_attr_adjust_length. */
3098 if (GET_CODE (pat
) == USE
3099 || GET_CODE (pat
) == CLOBBER
3100 || GET_CODE (pat
) == SEQUENCE
3101 || GET_CODE (pat
) == ADDR_VEC
3102 || GET_CODE (pat
) == ADDR_DIFF_VEC
)
3105 if (get_attr_adjust_length (insn
) == ADJUST_LENGTH_NO
)
3108 /* Adjust length for reg->mem and mem->reg copies. */
3109 if (GET_CODE (pat
) == SET
3110 && (GET_CODE (SET_SRC (pat
)) == MEM
3111 || GET_CODE (SET_DEST (pat
)) == MEM
))
3113 /* This insn might need a length adjustment. */
3116 if (GET_CODE (SET_SRC (pat
)) == MEM
)
3117 addr
= XEXP (SET_SRC (pat
), 0);
3119 addr
= XEXP (SET_DEST (pat
), 0);
3121 /* On the H8/300, only one adjustment is necessary; if the
3122 address mode is register indirect, then this insn is two
3123 bytes shorter than indicated in the machine description. */
3124 if (TARGET_H8300
&& GET_CODE (addr
) == REG
)
3127 /* On the H8/300H and H8/S, register indirect is 6 bytes shorter than
3128 indicated in the machine description. */
3129 if ((TARGET_H8300H
|| TARGET_H8300S
)
3130 && GET_CODE (addr
) == REG
)
3133 /* On the H8/300H and H8/S, reg + d, for small displacements is
3134 4 bytes shorter than indicated in the machine description. */
3135 if ((TARGET_H8300H
|| TARGET_H8300S
)
3136 && GET_CODE (addr
) == PLUS
3137 && GET_CODE (XEXP (addr
, 0)) == REG
3138 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
3139 && INTVAL (XEXP (addr
, 1)) > -32768
3140 && INTVAL (XEXP (addr
, 1)) < 32767)
3143 /* On the H8/300H and H8/S, abs:16 is two bytes shorter than the
3144 more general abs:24. */
3145 if ((TARGET_H8300H
|| TARGET_H8300S
)
3146 && GET_CODE (addr
) == SYMBOL_REF
3147 && TINY_DATA_NAME_P (XSTR (addr
, 0)))
3151 /* Loading some constants needs adjustment. */
3152 if (GET_CODE (pat
) == SET
3153 && GET_CODE (SET_SRC (pat
)) == CONST_INT
3154 && GET_MODE (SET_DEST (pat
)) == SImode
3155 && INTVAL (SET_SRC (pat
)) != 0)
3157 int val
= INTVAL (SET_SRC (pat
));
3160 && ((val
& 0xffff) == 0
3161 || ((val
>> 16) & 0xffff) == 0))
3164 if (TARGET_H8300H
|| TARGET_H8300S
)
3166 if (val
== (val
& 0xff)
3167 || val
== (val
& 0xff00))
3170 if (val
== -4 || val
== -2 || val
== -1)
3175 /* Shifts need various adjustments. */
3176 if (GET_CODE (pat
) == PARALLEL
3177 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
3178 && (GET_CODE (SET_SRC (XVECEXP (pat
, 0, 0))) == ASHIFTRT
3179 || GET_CODE (SET_SRC (XVECEXP (pat
, 0, 0))) == LSHIFTRT
3180 || GET_CODE (SET_SRC (XVECEXP (pat
, 0, 0))) == ASHIFT
))
3182 rtx src
= SET_SRC (XVECEXP (pat
, 0, 0));
3183 enum machine_mode mode
= GET_MODE (src
);
3186 if (GET_CODE (XEXP (src
, 1)) != CONST_INT
)
3189 shift
= INTVAL (XEXP (src
, 1));
3190 /* According to ANSI, negative shift is undefined. It is
3191 considered to be zero in this case (see function
3192 output_a_shift above). */
3196 /* QImode shifts by small constants take one insn
3197 per shift. So the adjustment is 20 (md length) -
3199 if (mode
== QImode
&& shift
<= 4)
3200 return -(20 - shift
* 2);
3202 /* Similarly for HImode and SImode shifts by small constants on
3203 the H8/300H and H8/S. */
3204 if ((TARGET_H8300H
|| TARGET_H8300S
)
3205 && (mode
== HImode
|| mode
== SImode
) && shift
<= 4)
3206 return -(20 - shift
* 2);
3208 /* HImode shifts by small constants for the H8/300. */
3209 if (mode
== HImode
&& shift
<= 4)
3210 return -(20 - (shift
* (GET_CODE (src
) == ASHIFT
? 2 : 4)));
3212 /* SImode shifts by small constants for the H8/300. */
3213 if (mode
== SImode
&& shift
<= 2)
3214 return -(20 - (shift
* (GET_CODE (src
) == ASHIFT
? 6 : 8)));
3216 /* XXX ??? Could check for more shift/rotate cases here. */
3219 /* Rotations need various adjustments. */
3220 if (GET_CODE (pat
) == SET
3221 && (GET_CODE (SET_SRC (pat
)) == ROTATE
3222 || GET_CODE (SET_SRC (pat
)) == ROTATERT
))
3224 rtx src
= SET_SRC (pat
);
3225 enum machine_mode mode
= GET_MODE (src
);
3229 if (GET_CODE (XEXP (src
, 1)) != CONST_INT
)
3232 amount
= INTVAL (XEXP (src
, 1));
3234 /* Clean up AMOUNT. */
3237 if ((unsigned int) amount
> GET_MODE_BITSIZE (mode
))
3238 amount
= GET_MODE_BITSIZE (mode
);
3240 /* Determine the faster direction. After this phase, amount
3241 will be at most a half of GET_MODE_BITSIZE (mode). */
3242 if ((unsigned int) amount
> GET_MODE_BITSIZE (mode
) / 2U)
3243 /* Flip the direction. */
3244 amount
= GET_MODE_BITSIZE (mode
) - amount
;
3246 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3247 boost up the rotation. */
3248 if ((mode
== HImode
&& TARGET_H8300
&& amount
>= 5)
3249 || (mode
== HImode
&& TARGET_H8300H
&& amount
>= 6)
3250 || (mode
== HImode
&& TARGET_H8300S
&& amount
== 8)
3251 || (mode
== SImode
&& TARGET_H8300H
&& amount
>= 10)
3252 || (mode
== SImode
&& TARGET_H8300S
&& amount
>= 13))
3254 /* Adjust AMOUNT and flip the direction. */
3255 amount
= GET_MODE_BITSIZE (mode
) / 2 - amount
;
3259 /* We use 2-bit rotatations on the H8/S. */
3261 amount
= amount
/ 2 + amount
% 2;
3263 /* The H8/300 uses three insns to rotate one bit, taking 6
3265 states
+= amount
* ((TARGET_H8300
&& mode
== HImode
) ? 6 : 2);
3267 return -(20 - states
);
3273 #ifndef OBJECT_FORMAT_ELF
3275 h8300_asm_named_section (name
, flags
)
3277 unsigned int flags ATTRIBUTE_UNUSED
;
3279 /* ??? Perhaps we should be using default_coff_asm_named_section. */
3280 fprintf (asm_out_file
, "\t.section %s\n", name
);
3282 #endif /* ! OBJECT_FORMAT_ELF */