1 /* Subroutines for insn-output.c for Hitachi H8/300.
2 Copyright (C) 1992, 93-99, 2000 Free Software
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"
33 #include "insn-flags.h"
35 #include "insn-attr.h"
44 /* Forward declarations. */
45 static int h8300_interrupt_function_p
PARAMS ((tree
));
46 static int h8300_monitor_function_p
PARAMS ((tree
));
47 static int h8300_os_task_function_p
PARAMS ((tree
));
48 static void dosize
PARAMS ((FILE *, const char *, unsigned int));
49 static const char *cond_string
PARAMS ((enum rtx_code
));
51 /* CPU_TYPE, says what cpu we're compiling for. */
54 /* True if the current function is an interrupt handler
55 (either via #pragma or an attribute specification). */
56 int interrupt_handler
;
58 /* True if the current function is an OS Task
59 (via an attribute specification). */
62 /* True if the current function is a monitor
63 (via an attribute specification). */
66 /* True if a #pragma saveall has been seen for the current function. */
69 static const char *const names_big
[] =
70 {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7"};
72 static const char *const names_extended
[] =
73 {"er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"};
75 static const char *const names_upper_extended
[] =
76 {"e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"};
78 /* Points to one of the above. */
79 /* ??? The above could be put in an array indexed by CPU_TYPE. */
80 const char * const *h8_reg_names
;
82 /* Various operations needed by the following, indexed by CPU_TYPE. */
84 static const char *const h8_push_ops
[2] = {"push", "push.l"};
85 static const char *const h8_pop_ops
[2] = {"pop", "pop.l"};
86 static const char *const h8_mov_ops
[2] = {"mov.w", "mov.l"};
88 const char *h8_push_op
, *h8_pop_op
, *h8_mov_op
;
90 /* Initialize various cpu specific globals at start up. */
97 cpu_type
= (int) CPU_H8300
;
98 h8_reg_names
= names_big
;
102 /* For this we treat the H8/300 and H8/S the same. */
103 cpu_type
= (int) CPU_H8300H
;
104 h8_reg_names
= names_extended
;
106 h8_push_op
= h8_push_ops
[cpu_type
];
107 h8_pop_op
= h8_pop_ops
[cpu_type
];
108 h8_mov_op
= h8_mov_ops
[cpu_type
];
116 static const char *const names_small
[] =
117 {"r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
118 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h"};
120 return names_small
[REGNO (x
) * 2 + b
];
123 /* REGNO must be saved/restored across calls if this macro is true. */
125 #define WORD_REG_USED(regno) \
127 /* No need to save registers if this function will not return.*/\
128 && ! TREE_THIS_VOLATILE (current_function_decl) \
130 /* Save any call saved register that was used. */ \
131 || (regs_ever_live[regno] && !call_used_regs[regno]) \
132 /* Save the frame pointer if it was used. */ \
133 || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno])\
134 /* Save any register used in an interrupt handler. */ \
135 || (interrupt_handler && regs_ever_live[regno]) \
136 /* Save call clobbered registers in non-leaf interrupt \
138 || (interrupt_handler \
139 && call_used_regs[regno] \
140 && !current_function_is_leaf)))
142 /* Output assembly language to FILE for the operation OP with operand size
143 SIZE to adjust the stack pointer. */
146 dosize (file
, op
, size
)
151 /* On the h8300h and h8300s, for sizes <= 8 bytes it is as good or
152 better to use adds/subs insns rather than add.l/sub.l
153 with an immediate value. */
154 if (size
> 4 && size
<= 8 && (TARGET_H8300H
|| TARGET_H8300S
))
156 /* Crank the size down to <= 4 */
157 fprintf (file
, "\t%ss\t#%d,sp\n", op
, 4);
164 if (TARGET_H8300H
|| TARGET_H8300S
)
166 fprintf (file
, "\t%ss\t#%d,sp\n", op
, 4);
171 fprintf (file
, "\t%ss\t#%d,sp\n", op
, 2);
173 /* Fall through... */
176 fprintf (file
, "\t%ss\t#%d,sp\n", op
, size
);
184 if (current_function_needs_context
185 && strcmp (op
, "sub") == 0)
187 /* Egad. We don't have a temporary to hold the
188 size of the frame in the prologue! Just inline
189 the bastard since this shouldn't happen often. */
192 fprintf (file
, "\tsubs\t#2,sp\n");
197 fprintf (file
, "\tsubs\t#1,sp\n");
202 fprintf (file
, "\tmov.w\t#%d,r3\n\t%s.w\tr3,sp\n", size
, op
);
205 fprintf (file
, "\t%s\t#%d,sp\n", op
, size
);
211 /* Output assembly language code for the function prologue. */
212 static int push_order
[FIRST_PSEUDO_REGISTER
] =
213 {0, 1, 2, 3, 4, 5, 6, -1, -1, -1};
214 static int pop_order
[FIRST_PSEUDO_REGISTER
] =
215 {6, 5, 4, 3, 2, 1, 0, -1, -1, -1};
217 /* This is what the stack looks like after the prolog of
218 a function with a frame has been set up:
224 <saved registers> <- sp
226 This is what the stack looks like after the prolog of
227 a function which doesn't have a frame:
232 <saved registers> <- sp
236 function_prologue (file
, size
)
240 int fsize
= (size
+ STACK_BOUNDARY
/ 8 - 1) & -STACK_BOUNDARY
/ 8;
243 /* Note a function with the interrupt attribute and set interrupt_handler
245 if (h8300_interrupt_function_p (current_function_decl
))
246 interrupt_handler
= 1;
248 /* If the current function has the OS_Task attribute set, then
249 we have a naked prologue. */
250 if (h8300_os_task_function_p (current_function_decl
))
252 fprintf (file
, ";OS_Task prologue\n");
257 if (h8300_monitor_function_p (current_function_decl
))
259 /* My understanding of monitor functions is they act just
260 like interrupt functions, except the prologue must
262 fprintf (file
, ";monitor prologue\n");
263 interrupt_handler
= 1;
267 fprintf (file
, "\tsubs\t#2,sp\n");
268 fprintf (file
, "\tpush\tr0\n");
269 fprintf (file
, "\tstc\tccr,r0l\n");
270 fprintf (file
, "\torc\t#128,ccr\n");
271 fprintf (file
, "\tmov.b\tr0l,@(4,sp)\n");
275 fprintf (file
, "\tpush\ter0\n");
276 fprintf (file
, "\tstc\tccr,r0l\n");
277 fprintf (file
, "\torc\t#128,ccr\n");
278 fprintf (file
, "\tmov.b\tr0l,@(4,sp)\n");
282 if (frame_pointer_needed
)
285 fprintf (file
, "\t%s\t%s\n", h8_push_op
,
286 h8_reg_names
[FRAME_POINTER_REGNUM
]);
287 fprintf (file
, "\t%s\t%s,%s\n", h8_mov_op
,
288 h8_reg_names
[STACK_POINTER_REGNUM
],
289 h8_reg_names
[FRAME_POINTER_REGNUM
]);
292 /* leave room for locals */
293 dosize (file
, "sub", fsize
);
295 /* Push the rest of the registers */
296 for (idx
= 0; idx
< FIRST_PSEUDO_REGISTER
; idx
++)
298 int regno
= push_order
[idx
];
301 && WORD_REG_USED (regno
)
302 && (!frame_pointer_needed
|| regno
!= FRAME_POINTER_REGNUM
))
306 /* Try to push multiple registers. */
307 if (regno
== 0 || regno
== 4)
309 int second_regno
= push_order
[idx
+ 1];
310 int third_regno
= push_order
[idx
+ 2];
311 int fourth_regno
= push_order
[idx
+ 3];
313 if (fourth_regno
>= 0
314 && WORD_REG_USED (fourth_regno
)
315 && (!frame_pointer_needed
316 || fourth_regno
!= FRAME_POINTER_REGNUM
)
318 && WORD_REG_USED (third_regno
)
319 && (!frame_pointer_needed
320 || third_regno
!= FRAME_POINTER_REGNUM
)
322 && WORD_REG_USED (second_regno
)
323 && (!frame_pointer_needed
324 || second_regno
!= FRAME_POINTER_REGNUM
))
326 fprintf (file
, "\tstm.l %s-%s,@-sp\n",
328 h8_reg_names
[fourth_regno
]);
333 if (regno
== 0 || regno
== 4)
335 int second_regno
= push_order
[idx
+ 1];
336 int third_regno
= push_order
[idx
+ 2];
339 && WORD_REG_USED (third_regno
)
340 && (!frame_pointer_needed
341 || third_regno
!= FRAME_POINTER_REGNUM
)
343 && WORD_REG_USED (second_regno
)
344 && (!frame_pointer_needed
345 || second_regno
!= FRAME_POINTER_REGNUM
))
347 fprintf (file
, "\tstm.l %s-%s,@-sp\n",
349 h8_reg_names
[third_regno
]);
354 if (regno
== 0 || regno
== 2 || regno
== 4 || regno
== 6)
356 int second_regno
= push_order
[idx
+ 1];
358 if (second_regno
>= 0
359 && WORD_REG_USED (second_regno
)
360 && (!frame_pointer_needed
361 || second_regno
!= FRAME_POINTER_REGNUM
))
363 fprintf (file
, "\tstm.l %s-%s,@-sp\n",
365 h8_reg_names
[second_regno
]);
371 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[regno
]);
376 /* Output assembly language code for the function epilogue. */
379 function_epilogue (file
, size
)
383 int fsize
= (size
+ STACK_BOUNDARY
/ 8 - 1) & -STACK_BOUNDARY
/ 8;
385 rtx insn
= get_last_insn ();
389 /* OS_Task epilogues are nearly naked -- they just have an
391 fprintf (file
, ";OS_task epilogue\n");
392 fprintf (file
, "\trts\n");
396 /* monitor epilogues are the same as interrupt function epilogues.
397 Just make a note that we're in an monitor epilogue. */
399 fprintf(file
, ";monitor epilogue\n");
401 /* If the last insn was a BARRIER, we don't have to write any code. */
402 if (GET_CODE (insn
) == NOTE
)
403 insn
= prev_nonnote_insn (insn
);
404 if (insn
&& GET_CODE (insn
) == BARRIER
)
407 /* Pop the saved registers. */
408 for (idx
= 0; idx
< FIRST_PSEUDO_REGISTER
; idx
++)
410 int regno
= pop_order
[idx
];
413 && WORD_REG_USED (regno
)
414 && (!frame_pointer_needed
|| regno
!= FRAME_POINTER_REGNUM
))
418 /* Try to pop multiple registers. */
419 if (regno
== 7 || regno
== 3)
421 int second_regno
= pop_order
[idx
+ 1];
422 int third_regno
= pop_order
[idx
+ 2];
423 int fourth_regno
= pop_order
[idx
+ 3];
425 if (fourth_regno
>= 0
426 && WORD_REG_USED (fourth_regno
)
427 && (!frame_pointer_needed
428 || fourth_regno
!= FRAME_POINTER_REGNUM
)
430 && WORD_REG_USED (third_regno
)
431 && (!frame_pointer_needed
432 || third_regno
!= FRAME_POINTER_REGNUM
)
434 && WORD_REG_USED (second_regno
)
435 && (!frame_pointer_needed
436 || second_regno
!= FRAME_POINTER_REGNUM
))
438 fprintf (file
, "\tldm.l @sp+,%s-%s\n",
439 h8_reg_names
[fourth_regno
],
440 h8_reg_names
[regno
]);
445 if (regno
== 6 || regno
== 2)
447 int second_regno
= pop_order
[idx
+ 1];
448 int third_regno
= pop_order
[idx
+ 2];
451 && WORD_REG_USED (third_regno
)
452 && (!frame_pointer_needed
453 || third_regno
!= FRAME_POINTER_REGNUM
)
455 && WORD_REG_USED (second_regno
)
456 && (!frame_pointer_needed
457 || second_regno
!= FRAME_POINTER_REGNUM
))
459 fprintf (file
, "\tldm.l @sp+,%s-%s\n",
460 h8_reg_names
[third_regno
],
461 h8_reg_names
[regno
]);
466 if (regno
== 7 || regno
== 5 || regno
== 3 || regno
== 1)
468 int second_regno
= pop_order
[idx
+ 1];
470 if (second_regno
>= 0
471 && WORD_REG_USED (second_regno
)
472 && (!frame_pointer_needed
473 || second_regno
!= FRAME_POINTER_REGNUM
))
475 fprintf (file
, "\tldm.l @sp+,%s-%s\n",
476 h8_reg_names
[second_regno
],
477 h8_reg_names
[regno
]);
483 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[regno
]);
487 /* deallocate locals */
488 dosize (file
, "add", fsize
);
490 /* pop frame pointer if we had one. */
491 if (frame_pointer_needed
)
492 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[FRAME_POINTER_REGNUM
]);
494 /* If this is a monitor function, there is one register still left on
497 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[0]);
499 if (interrupt_handler
)
500 fprintf (file
, "\trte\n");
502 fprintf (file
, "\trts\n");
505 interrupt_handler
= 0;
511 /* Output assembly code for the start of the file. */
514 asm_file_start (file
)
517 fprintf (file
, ";\tGCC For the Hitachi H8/300\n");
518 fprintf (file
, ";\tBy Hitachi America Ltd and Cygnus Support\n");
519 fprintf (file
, ";\trelease F-1\n");
521 fprintf (file
, "; -O%d\n", optimize
);
523 fprintf (file
, "\n\t.h8300h\n");
524 else if (TARGET_H8300S
)
525 fprintf (file
, "\n\t.h8300s\n");
527 fprintf (file
, "\n\n");
528 output_file_directive (file
, main_input_filename
);
531 /* Output assembly language code for the end of file. */
537 fprintf (file
, "\t.end\n");
540 /* Return true if VALUE is a valid constant for constraint 'P'.
541 IE: VALUE is a power of two <= 2**15. */
544 small_power_of_two (value
)
570 /* Return true if VALUE is a valid constant for constraint 'O', which
571 means that the constant would be ok to use as a bit for a bclr
578 return small_power_of_two ((~value
) & 0xff);
581 /* Return true is OP is a valid source operand for an integer move
585 general_operand_src (op
, mode
)
587 enum machine_mode mode
;
589 if (GET_CODE (op
) == MEM
&& GET_CODE (XEXP (op
, 0)) == POST_INC
)
591 return general_operand (op
, mode
);
594 /* Return true if OP is a valid destination operand for an integer move
598 general_operand_dst (op
, mode
)
600 enum machine_mode mode
;
602 if (GET_CODE (op
) == MEM
&& GET_CODE (XEXP (op
, 0)) == PRE_DEC
)
604 return general_operand (op
, mode
);
607 /* Return true if OP is a const valid for a bit clear instruction. */
610 o_operand (operand
, mode
)
612 enum machine_mode mode ATTRIBUTE_UNUSED
;
614 return (GET_CODE (operand
) == CONST_INT
615 && CONST_OK_FOR_O (INTVAL (operand
)));
618 /* Return true if OP is a const valid for a bit set or bit xor instruction. */
621 p_operand (operand
, mode
)
623 enum machine_mode mode ATTRIBUTE_UNUSED
;
625 return (GET_CODE (operand
) == CONST_INT
626 && CONST_OK_FOR_P (INTVAL (operand
)));
629 /* Return true if OP is a valid call operand. */
632 call_insn_operand (op
, mode
)
634 enum machine_mode mode ATTRIBUTE_UNUSED
;
636 if (GET_CODE (op
) == MEM
)
638 rtx inside
= XEXP (op
, 0);
639 if (register_operand (inside
, Pmode
))
641 if (CONSTANT_ADDRESS_P (inside
))
648 adds_subs_operand (op
, mode
)
650 enum machine_mode mode ATTRIBUTE_UNUSED
;
652 if (GET_CODE (op
) == CONST_INT
)
654 if (INTVAL (op
) <= 4 && INTVAL (op
) >= 0)
656 if (INTVAL (op
) >= -4 && INTVAL (op
) <= 0)
658 if ((TARGET_H8300H
|| TARGET_H8300S
)
660 && (INTVAL (op
) <= 8 && INTVAL (op
) >= 0))
662 if ((TARGET_H8300H
|| TARGET_H8300S
)
664 && (INTVAL (op
) >= -8 && INTVAL (op
) <= 0))
670 /* Return nonzero if op is an adds/subs operand which only requires
671 one insn to implement. It is assumed that OP is already an adds/subs
674 one_insn_adds_subs_operand (op
, mode
)
676 enum machine_mode mode ATTRIBUTE_UNUSED
;
678 int val
= INTVAL (op
);
680 if (val
== 1 || val
== -1
681 || val
== 2 || val
== -2
682 || ((TARGET_H8300H
|| TARGET_H8300S
)
683 && (val
== 4 || val
== -4)))
689 output_adds_subs (operands
)
692 int val
= INTVAL (operands
[2]);
694 /* First get the value into the range -4..4 inclusive.
696 The only way it can be out of this range is when TARGET_H8300H
697 or TARGET_H8300S is true, thus it is safe to use adds #4 and subs #4. */
700 output_asm_insn ("adds #4,%A0", operands
);
706 output_asm_insn ("subs #4,%A0", operands
);
710 /* Handle case were val == 4 or val == -4 and we're compiling
711 for TARGET_H8300H or TARGET_H8300S. */
712 if ((TARGET_H8300H
|| TARGET_H8300S
)
714 return "adds #4,%A0";
716 if ((TARGET_H8300H
|| TARGET_H8300S
)
718 return "subs #4,%A0";
722 output_asm_insn ("adds #2,%A0", operands
);
728 output_asm_insn ("subs #2,%A0", operands
);
732 /* val should be one or two now. */
734 return "adds #2,%A0";
737 return "subs #2,%A0";
739 /* val should be one now. */
741 return "adds #1,%A0";
744 return "subs #1,%A0";
746 /* If not optimizing, we might be asked to add 0. */
750 /* In theory, this can't happen. */
754 /* Return true if OP is a valid call operand, and OP represents
755 an operand for a small call (4 bytes instead of 6 bytes). */
758 small_call_insn_operand (op
, mode
)
760 enum machine_mode mode ATTRIBUTE_UNUSED
;
762 if (GET_CODE (op
) == MEM
)
764 rtx inside
= XEXP (op
, 0);
766 /* Register indirect is a small call. */
767 if (register_operand (inside
, Pmode
))
770 /* A call through the function vector is a small
772 if (GET_CODE (inside
) == SYMBOL_REF
773 && SYMBOL_REF_FLAG (inside
))
776 /* Otherwise it's a large call. */
780 /* Return true if OP is a valid jump operand. */
783 jump_address_operand (op
, mode
)
785 enum machine_mode mode
;
787 if (GET_CODE (op
) == REG
)
788 return mode
== Pmode
;
790 if (GET_CODE (op
) == MEM
)
792 rtx inside
= XEXP (op
, 0);
793 if (register_operand (inside
, Pmode
))
795 if (CONSTANT_ADDRESS_P (inside
))
801 /* Recognize valid operands for bitfield instructions. */
803 extern int rtx_equal_function_value_matters
;
806 bit_operand (op
, mode
)
808 enum machine_mode mode
;
810 /* We can except any general operand, expept that MEM operands must
811 be limited to those that use addresses valid for the 'U' constraint. */
812 if (!general_operand (op
, mode
))
815 /* Accept any mem during RTL generation. Otherwise, the code that does
816 insv and extzv will think that we can not handle memory. However,
817 to avoid reload problems, we only accept 'U' MEM operands after RTL
818 generation. This means that any named pattern which uses this predicate
819 must force its operands to match 'U' before emitting RTL. */
821 if (GET_CODE (op
) == REG
)
823 if (GET_CODE (op
) == SUBREG
)
825 if (!rtx_equal_function_value_matters
)
827 /* We're building rtl */
828 return GET_CODE (op
) == MEM
;
832 return (GET_CODE (op
) == MEM
833 && EXTRA_CONSTRAINT (op
, 'U'));
838 bit_memory_operand (op
, mode
)
840 enum machine_mode mode ATTRIBUTE_UNUSED
;
842 return (GET_CODE (op
) == MEM
843 && EXTRA_CONSTRAINT (op
, 'U'));
846 /* Recognize valid operators for bit test. */
849 eq_operator (x
, mode
)
851 enum machine_mode mode ATTRIBUTE_UNUSED
;
853 return (GET_CODE (x
) == EQ
|| GET_CODE (x
) == NE
);
856 /* Handle machine specific pragmas for compatibility with existing
857 compilers for the H8/300.
859 pragma saveall generates prolog/epilog code which saves and
860 restores all the registers on function entry.
862 pragma interrupt saves and restores all registers, and exits with
863 an rte instruction rather than an rts. A pointer to a function
864 with this attribute may be safely used in an interrupt vector. */
867 handle_pragma (p_getc
, p_ungetc
, pname
)
868 int (* ATTRIBUTE_UNUSED p_getc
) PARAMS ((void));
869 void (* ATTRIBUTE_UNUSED p_ungetc
) PARAMS ((int));
874 if (strcmp (pname
, "interrupt") == 0)
875 interrupt_handler
= retval
= 1;
876 else if (strcmp (pname
, "saveall") == 0)
877 pragma_saveall
= retval
= 1;
882 /* If the next arg with MODE and TYPE is to be passed in a register, return
883 the rtx to represent where it is passed. CUM represents the state after
884 the last argument. NAMED is not used. */
886 static const char *const hand_list
[] =
906 /* Return an RTX to represent where a value with mode MODE will be returned
907 from a function. If the result is 0, the argument is pushed. */
910 function_arg (cum
, mode
, type
, named
)
911 CUMULATIVE_ARGS
*cum
;
912 enum machine_mode mode
;
920 /* Never pass unnamed arguments in registers. */
924 /* Pass 3 regs worth of data in regs when user asked on the command line. */
925 if (TARGET_QUICKCALL
)
928 /* If calling hand written assembler, use 4 regs of args. */
932 const char * const *p
;
934 fname
= XSTR (cum
->libcall
, 0);
936 /* See if this libcall is one of the hand coded ones. */
938 for (p
= hand_list
; *p
&& strcmp (*p
, fname
) != 0; p
++)
950 size
= int_size_in_bytes (type
);
952 size
= GET_MODE_SIZE (mode
);
954 if (size
+ cum
->nbytes
> regpass
* UNITS_PER_WORD
)
960 switch (cum
->nbytes
/ UNITS_PER_WORD
)
963 result
= gen_rtx_REG (mode
, 0);
966 result
= gen_rtx_REG (mode
, 1);
969 result
= gen_rtx_REG (mode
, 2);
972 result
= gen_rtx_REG (mode
, 3);
983 /* Return the cost of the rtx R with code CODE. */
1003 if (TARGET_H8300H
|| TARGET_H8300S
)
1024 /* Documentation for the machine specific operand escapes:
1026 'A' print rn in h8/300 mode, erN in H8/300H mode
1027 'C' print (operand - 2).
1028 'E' like s but negative.
1029 'F' like t but negative.
1030 'G' constant just the negative
1031 'M' turn a 'M' constant into its negative mod 2.
1032 'P' if operand is incing/decing sp, print .w, otherwise .b.
1033 'R' print operand as a byte:8 address if appropriate, else fall back to
1035 'S' print operand as a long word
1036 'T' print operand as a word
1037 'U' if operand is incing/decing sp, print l, otherwise nothing.
1038 'V' find the set bit, and print its number.
1039 'W' find the clear bit, and print its number.
1040 'X' print operand as a byte
1041 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
1042 If this operand isn't a register, fall back to 'R' handling.
1044 'b' print the bit opcode
1045 'c' print the ibit opcode
1046 'd' bcc if EQ, bcs if NE
1047 'e' first word of 32 bit value - if reg, then least reg. if mem
1048 then least. if const then most sig word
1049 'f' second word of 32 bit value - if reg, then biggest reg. if mem
1050 then +2. if const then least sig word
1051 'g' bcs if EQ, bcc if NE
1052 'j' print operand as condition code.
1053 'k' print operand as reverse condition code.
1054 's' print as low byte of 16 bit value
1055 't' print as high byte of 16 bit value
1056 'w' print as low byte of 32 bit value
1057 'x' print as 2nd byte of 32 bit value
1058 'y' print as 3rd byte of 32 bit value
1059 'z' print as msb of 32 bit value
1062 /* Return assembly language string which identifies a comparison type. */
1095 /* Print operand X using operand code CODE to assembly language output file
1099 print_operand (file
, x
, code
)
1104 /* This is used for communication between the 'P' and 'U' codes. */
1105 static const char *last_p
;
1107 /* This is used for communication between codes V,W,Z and Y. */
1113 if (GET_CODE (x
) == REG
)
1114 fprintf (file
, "%s", h8_reg_names
[REGNO (x
)]);
1119 fprintf (file
, "#%d", INTVAL (x
) - 2);
1122 switch (GET_CODE (x
))
1125 fprintf (file
, "%sl", names_big
[REGNO (x
)]);
1128 fprintf (file
, "#%d", (-INTVAL (x
)) & 0xff);
1135 switch (GET_CODE (x
))
1138 fprintf (file
, "%sh", names_big
[REGNO (x
)]);
1141 fprintf (file
, "#%d", ((-INTVAL (x
)) & 0xff00) >> 8);
1148 if (GET_CODE (x
) != CONST_INT
)
1150 fprintf (file
, "#%d", 0xff & (-INTVAL (x
)));
1153 /* For 3/-3 and 4/-4, the other 2 is handled separately. */
1160 fprintf (file
, "#2");
1166 fprintf (file
, "#1");
1173 if (REGNO (XEXP (XEXP (x
, 0), 0)) == STACK_POINTER_REGNUM
)
1176 fprintf (file
, ".w");
1181 fprintf (file
, ".b");
1185 if (GET_CODE (x
) == REG
)
1186 fprintf (file
, "%s", names_extended
[REGNO (x
)]);
1191 if (GET_CODE (x
) == REG
)
1192 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1197 fprintf (file
, "%s%s", names_big
[REGNO (x
)], last_p
);
1200 bitint
= exact_log2 (INTVAL (x
));
1203 fprintf (file
, "#%d", bitint
& 7);
1206 bitint
= exact_log2 ((~INTVAL (x
)) & 0xff);
1209 fprintf (file
, "#%d", bitint
& 7);
1213 if (GET_CODE (x
) == REG
)
1214 fprintf (file
, "%s", byte_reg (x
, 0));
1221 if (GET_CODE (x
) == REG
)
1222 fprintf (file
, "%s%c", names_big
[REGNO (x
)], bitint
> 7 ? 'h' : 'l');
1224 print_operand (file
, x
, 'R');
1228 bitint
= INTVAL (x
);
1229 fprintf (file
, "#%d", bitint
& 7);
1232 switch (GET_CODE (x
))
1235 fprintf (file
, "bor");
1238 fprintf (file
, "bxor");
1241 fprintf (file
, "band");
1248 switch (GET_CODE (x
))
1251 fprintf (file
, "bior");
1254 fprintf (file
, "bixor");
1257 fprintf (file
, "biand");
1264 switch (GET_CODE (x
))
1267 fprintf (file
, "bcc");
1270 fprintf (file
, "bcs");
1277 switch (GET_CODE (x
))
1281 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1283 fprintf (file
, "%s", names_upper_extended
[REGNO (x
)]);
1286 x
= adj_offsettable_operand (x
, 0);
1287 print_operand (file
, x
, 0);
1290 fprintf (file
, "#%d", ((INTVAL (x
) >> 16) & 0xffff));
1296 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
1297 REAL_VALUE_TO_TARGET_SINGLE (rv
, val
);
1298 fprintf (file
, "#%ld", ((val
>> 16) & 0xffff));
1307 switch (GET_CODE (x
))
1311 fprintf (file
, "%s", names_big
[REGNO (x
) + 1]);
1313 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1316 x
= adj_offsettable_operand (x
, 2);
1317 print_operand (file
, x
, 0);
1320 fprintf (file
, "#%d", INTVAL (x
) & 0xffff);
1326 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
1327 REAL_VALUE_TO_TARGET_SINGLE (rv
, val
);
1328 fprintf (file
, "#%ld", (val
& 0xffff));
1336 switch (GET_CODE (x
))
1339 fprintf (file
, "bcc");
1342 fprintf (file
, "bcs");
1349 asm_fprintf (file
, cond_string (GET_CODE (x
)));
1352 asm_fprintf (file
, cond_string (reverse_condition (GET_CODE (x
))));
1355 if (GET_CODE (x
) == CONST_INT
)
1356 fprintf (file
, "#%d", (INTVAL (x
)) & 0xff);
1358 fprintf (file
, "%s", byte_reg (x
, 0));
1361 if (GET_CODE (x
) == CONST_INT
)
1362 fprintf (file
, "#%d", (INTVAL (x
) >> 8) & 0xff);
1364 fprintf (file
, "%s", byte_reg (x
, 1));
1367 if (GET_CODE (x
) != CONST_INT
)
1369 fprintf (file
, "%d", INTVAL (x
));
1372 if (GET_CODE (x
) == CONST_INT
)
1373 fprintf (file
, "#%d", INTVAL (x
) & 0xff);
1375 fprintf (file
, "%s",
1376 byte_reg (x
, TARGET_H8300
? 2 : 0));
1379 if (GET_CODE (x
) == CONST_INT
)
1380 fprintf (file
, "#%d", (INTVAL (x
) >> 8) & 0xff);
1382 fprintf (file
, "%s",
1383 byte_reg (x
, TARGET_H8300
? 3 : 1));
1386 if (GET_CODE (x
) == CONST_INT
)
1387 fprintf (file
, "#%d", (INTVAL (x
) >> 16) & 0xff);
1389 fprintf (file
, "%s", byte_reg (x
, 0));
1392 if (GET_CODE (x
) == CONST_INT
)
1393 fprintf (file
, "#%d", (INTVAL (x
) >> 24) & 0xff);
1395 fprintf (file
, "%s", byte_reg (x
, 1));
1400 switch (GET_CODE (x
))
1403 switch (GET_MODE (x
))
1406 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */
1407 fprintf (file
, "%s", byte_reg (x
, 0));
1408 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1409 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1413 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1417 fprintf (file
, "%s", names_extended
[REGNO (x
)]);
1425 fprintf (file
, "@");
1426 output_address (XEXP (x
, 0));
1428 /* If this is an 'R' operand (reference into the 8-bit
1429 area), then specify a symbolic address as "foo:8",
1430 otherwise if operand is still in eight bit section, use
1432 if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
1433 && SYMBOL_REF_FLAG (XEXP (x
, 0)))
1434 fprintf (file
, (code
== 'R' ? ":8" : ":16"));
1435 else if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
1436 && TINY_DATA_NAME_P (XSTR (XEXP (x
, 0), 0)))
1437 fprintf (file
, ":16");
1444 fprintf (file
, "#");
1445 print_operand_address (file
, x
);
1451 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
1452 REAL_VALUE_TO_TARGET_SINGLE (rv
, val
);
1453 fprintf (file
, "#%ld", val
);
1462 /* Output assembly language output for the address ADDR to FILE. */
1465 print_operand_address (file
, addr
)
1469 switch (GET_CODE (addr
))
1472 fprintf (file
, "%s", h8_reg_names
[REGNO (addr
)]);
1476 fprintf (file
, "-%s", h8_reg_names
[REGNO (XEXP (addr
, 0))]);
1480 fprintf (file
, "%s+", h8_reg_names
[REGNO (XEXP (addr
, 0))]);
1484 fprintf (file
, "(");
1485 if (GET_CODE (XEXP (addr
, 0)) == REG
)
1488 print_operand_address (file
, XEXP (addr
, 1));
1489 fprintf (file
, ",");
1490 print_operand_address (file
, XEXP (addr
, 0));
1495 print_operand_address (file
, XEXP (addr
, 0));
1496 fprintf (file
, "+");
1497 print_operand_address (file
, XEXP (addr
, 1));
1499 fprintf (file
, ")");
1504 /* Since the h8/300 only has 16 bit pointers, negative values are also
1505 those >= 32768. This happens for example with pointer minus a
1506 constant. We don't want to turn (char *p - 2) into
1507 (char *p + 65534) because loop unrolling can build upon this
1508 (IE: char *p + 131068). */
1509 int n
= INTVAL (addr
);
1511 n
= (int) (short) n
;
1513 /* ??? Why the special case for -ve values? */
1514 fprintf (file
, "-%d", -n
);
1516 fprintf (file
, "%d", n
);
1521 output_addr_const (file
, addr
);
1526 /* Output all insn addresses and their sizes into the assembly language
1527 output file. This is helpful for debugging whether the length attributes
1528 in the md file are correct. This is not meant to be a user selectable
1532 final_prescan_insn (insn
, operand
, num_operands
)
1533 rtx insn
, *operand ATTRIBUTE_UNUSED
;
1534 int num_operands ATTRIBUTE_UNUSED
;
1536 /* This holds the last insn address. */
1537 static int last_insn_address
= 0;
1539 int uid
= INSN_UID (insn
);
1541 if (TARGET_RTL_DUMP
)
1543 fprintf (asm_out_file
, "\n****************");
1544 print_rtl (asm_out_file
, PATTERN (insn
));
1545 fprintf (asm_out_file
, "\n");
1548 if (TARGET_ADDRESSES
)
1550 fprintf (asm_out_file
, "; 0x%x %d\n", insn_addresses
[uid
],
1551 insn_addresses
[uid
] - last_insn_address
);
1552 last_insn_address
= insn_addresses
[uid
];
1556 /* Prepare for an SI sized move. */
1562 rtx src
= operands
[1];
1563 rtx dst
= operands
[0];
1564 if (!reload_in_progress
&& !reload_completed
)
1566 if (!register_operand (dst
, GET_MODE (dst
)))
1568 rtx tmp
= gen_reg_rtx (GET_MODE (dst
));
1569 emit_move_insn (tmp
, src
);
1576 /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
1577 Define the offset between two registers, one to be eliminated, and the other
1578 its replacement, at the start of a routine. */
1581 initial_offset (from
, to
)
1586 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
1587 offset
= UNITS_PER_WORD
+ frame_pointer_needed
* UNITS_PER_WORD
;
1592 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1593 if (WORD_REG_USED (regno
))
1594 offset
+= UNITS_PER_WORD
;
1596 /* See the comments for get_frame_size. We need to round it up to
1599 offset
+= ((get_frame_size () + STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
1600 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
1602 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
1603 offset
+= UNITS_PER_WORD
; /* Skip saved PC */
1608 /* Update the condition code from the insn. */
1611 notice_update_cc (body
, insn
)
1615 switch (get_attr_cc (insn
))
1618 /* Insn does not affect CC at all. */
1622 /* Insn does not change CC, but the 0'th operand has been changed. */
1623 if (cc_status
.value1
!= 0
1624 && reg_overlap_mentioned_p (recog_data
.operand
[0], cc_status
.value1
))
1625 cc_status
.value1
= 0;
1629 /* Insn sets the Z,N flags of CC to recog_data.operand[0].
1630 The V flag is unusable. The C flag may or may not be known but
1631 that's ok because alter_cond will change tests to use EQ/NE. */
1633 cc_status
.flags
|= CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
;
1634 cc_status
.value1
= recog_data
.operand
[0];
1638 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
1639 The C flag may or may not be known but that's ok because
1640 alter_cond will change tests to use EQ/NE. */
1642 cc_status
.flags
|= CC_NO_CARRY
;
1643 cc_status
.value1
= recog_data
.operand
[0];
1647 /* The insn is a compare instruction. */
1649 cc_status
.value1
= SET_SRC (body
);
1653 /* Insn doesn't leave CC in a usable state. */
1659 /* Recognize valid operators for bit instructions */
1662 bit_operator (x
, mode
)
1664 enum machine_mode mode ATTRIBUTE_UNUSED
;
1666 enum rtx_code code
= GET_CODE (x
);
1675 We devote a fair bit of code to getting efficient shifts since we can only
1676 shift one bit at a time on the H8/300 and H8/300H and only one or two
1677 bits at a time on the H8/S.
1679 The basic shift methods:
1681 * loop shifts -- emit a loop using one (or two on H8/S) bit shifts;
1682 this is the default. SHIFT_LOOP
1684 * inlined shifts -- emit straight line code for the shift; this is
1685 used when a straight line shift is about the same size or smaller
1686 than a loop. We allow the inline version to be slightly longer in
1687 some cases as it saves a register. SHIFT_INLINE
1689 * rotate + and -- rotate the value the opposite direction, then
1690 mask off the values we don't need. This is used when only a few
1691 of the bits in the original value will survive in the shifted value.
1692 Again, this is used when it's about the same size or smaller than
1693 a loop. We allow this version to be slightly longer as it is usually
1694 much faster than a loop. SHIFT_ROT_AND
1696 * swap (+ shifts) -- often it's possible to swap bytes/words to
1697 simulate a shift by 8/16. Once swapped a few inline shifts can be
1698 added if the shift count is slightly more than 8 or 16. This is used
1699 when it's about the same size or smaller than a loop. We allow this
1700 version to be slightly longer as it is usually much faster than a loop.
1703 * There other oddballs. Not worth explaining. SHIFT_SPECIAL
1706 Here are some thoughts on what the absolutely positively best code is.
1707 "Best" here means some rational trade-off between code size and speed,
1708 where speed is more preferred but not at the expense of generating 20 insns.
1710 A trailing '*' after the shift count indicates the "best" mode isn't
1713 H8/300 QImode shifts
1714 1-4 - do them inline
1715 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1717 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1718 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1720 H8/300 HImode shifts
1721 1-4 - do them inline
1723 7 - shift 2nd half other way into carry.
1724 copy 1st half into 2nd half
1725 rotate 2nd half other way with carry
1726 rotate 1st half other way (no carry)
1727 mask off bits in 1st half (ASHIFT | LSHIFTRT).
1728 sign extend 1st half (ASHIFTRT)
1729 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1730 9-12 - do shift by 8, inline remaining shifts
1731 13-14* - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1733 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1734 - ASHIFTRT: shll, subx, set other byte
1736 H8/300 SImode shifts
1737 1-2 - do them inline
1739 7* - shift other way once, move bytes into place,
1740 move carry into place (possibly with sign extension)
1741 8 - move bytes into place, zero or sign extend other
1743 15* - shift other way once, move word into place, move carry into place
1744 16 - move word, zero or sign extend other
1746 24* - move bytes into place, zero or sign extend other
1748 28-30* - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,
1751 31 - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,
1753 ASHIFTRT: shll top byte, subx, copy to other bytes
1755 H8/300H QImode shifts (same as H8/300 QImode shifts)
1756 1-4 - do them inline
1757 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1759 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1760 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1763 H8/300H HImode shifts
1764 1-4 - do them inline
1766 7 - shift 2nd half other way into carry.
1767 copy 1st half into 2nd half
1768 rotate entire word other way using carry
1769 mask off remaining bits (ASHIFT | LSHIFTRT)
1770 sign extend remaining bits (ASHIFTRT)
1771 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1772 9-12 - do shift by 8, inline remaining shifts
1773 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1775 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1776 - ASHIFTRT: shll, subx, set other byte
1778 H8/300H SImode shifts
1779 (These are complicated by the fact that we don't have byte level access to
1781 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1782 1-4 - do them inline
1784 15* - shift other way once, move word into place, move carry into place
1785 (with sign extension for ASHIFTRT)
1786 16 - move word into place, zero or sign extend other
1787 17-20 - do 16bit shift, then inline remaining shifts
1789 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1790 move word 0 to word 1, zero word 0
1791 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1792 zero word 1, zero byte 1
1793 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1794 sign extend byte 0, sign extend word 0
1795 25-27* - either loop, or
1796 do 24 bit shift, inline rest
1797 28-30 - ASHIFT: rotate 4/3/2, mask
1798 LSHIFTRT: rotate 4/3/2, mask
1800 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1803 1-6 - do them inline
1804 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1805 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1808 1-7 - do them inline
1809 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1810 9-12 - do shift by 8, inline remaining shifts
1811 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1813 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1814 - ASHIFTRT: shll, subx, set other byte
1817 (These are complicated by the fact that we don't have byte level access to
1819 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1820 1-10 - do them inline
1822 15* - shift other way once, move word into place, move carry into place
1823 (with sign extension for ASHIFTRT)
1824 16 - move word into place, zero or sign extend other
1825 17-20 - do 16bit shift, then inline remaining shifts
1827 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1828 move word 0 to word 1, zero word 0
1829 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1830 zero word 1, zero byte 1
1831 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1832 sign extend byte 0, sign extend word 0
1833 25-27* - either loop, or
1834 do 24 bit shift, inline rest
1835 28-30 - ASHIFT: rotate 4/3/2, mask
1836 LSHIFTRT: rotate 4/3/2, mask
1838 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1843 nshift_operator (x
, mode
)
1845 enum machine_mode mode ATTRIBUTE_UNUSED
;
1847 switch (GET_CODE (x
))
1859 /* Called from the .md file to emit code to do shifts.
1860 Returns a boolean indicating success
1861 (currently this is always TRUE). */
1864 expand_a_shift (mode
, code
, operands
)
1865 enum machine_mode mode
;
1869 emit_move_insn (operands
[0], operands
[1]);
1871 /* need a loop to get all the bits we want - we generate the
1872 code at emit time, but need to allocate a scratch reg now */
1874 emit_insn (gen_rtx_PARALLEL
1877 gen_rtx_SET (VOIDmode
, operands
[0],
1878 gen_rtx (code
, mode
, operands
[0],
1880 gen_rtx_CLOBBER (VOIDmode
,
1881 gen_rtx_SCRATCH (QImode
)))));
1886 /* Shift algorithm determination.
1888 There are various ways of doing a shift:
1889 SHIFT_INLINE: If the amount is small enough, just generate as many one-bit
1891 SHIFT_ROT_AND: If the amount is large but close to either end, rotate the
1892 necessary bits into position and then set the rest to zero.
1893 SHIFT_SPECIAL: Hand crafted assembler.
1894 SHIFT_LOOP: If the above methods fail, just loop. */
1905 /* Symbols of the various shifts which can be used as indices. */
1909 SHIFT_ASHIFT
, SHIFT_LSHIFTRT
, SHIFT_ASHIFTRT
1912 /* Symbols of the various modes which can be used as indices. */
1916 QIshift
, HIshift
, SIshift
1919 /* For single bit shift insns, record assembler and what bits of the
1920 condition code are valid afterwards (represented as various CC_FOO
1921 bits, 0 means CC isn't left in a usable state). */
1925 const char *assembler
;
1929 /* Assembler instruction shift table.
1931 These tables are used to look up the basic shifts.
1932 They are indexed by cpu, shift_type, and mode.
1935 static const struct shift_insn shift_one
[2][3][3] =
1941 { "shll\t%X0", CC_NO_CARRY
},
1942 { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1943 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }
1945 /* SHIFT_LSHIFTRT */
1947 { "shlr\t%X0", CC_NO_CARRY
},
1948 { "shlr\t%t0\n\trotxr\t%s0", 0 },
1949 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1951 /* SHIFT_ASHIFTRT */
1953 { "shar\t%X0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1954 { "shar\t%t0\n\trotxr\t%s0", 0 },
1955 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1962 { "shll.b\t%X0", CC_NO_CARRY
},
1963 { "shll.w\t%T0", CC_NO_CARRY
},
1964 { "shll.l\t%S0", CC_NO_CARRY
}
1966 /* SHIFT_LSHIFTRT */
1968 { "shlr.b\t%X0", CC_NO_CARRY
},
1969 { "shlr.w\t%T0", CC_NO_CARRY
},
1970 { "shlr.l\t%S0", CC_NO_CARRY
}
1972 /* SHIFT_ASHIFTRT */
1974 { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1975 { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1976 { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
}
1981 static const struct shift_insn shift_two
[3][3] =
1985 { "shll.b\t#2,%X0", CC_NO_CARRY
},
1986 { "shll.w\t#2,%T0", CC_NO_CARRY
},
1987 { "shll.l\t#2,%S0", CC_NO_CARRY
}
1989 /* SHIFT_LSHIFTRT */
1991 { "shlr.b\t#2,%X0", CC_NO_CARRY
},
1992 { "shlr.w\t#2,%T0", CC_NO_CARRY
},
1993 { "shlr.l\t#2,%S0", CC_NO_CARRY
}
1995 /* SHIFT_ASHIFTRT */
1997 { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1998 { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1999 { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
}
2003 /* Rotates are organized by which shift they'll be used in implementing.
2004 There's no need to record whether the cc is valid afterwards because
2005 it is the AND insn that will decide this. */
2007 static const char *const rotate_one
[2][3][3] =
2014 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
2017 /* SHIFT_LSHIFTRT */
2020 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
2023 /* SHIFT_ASHIFTRT */
2026 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
2038 /* SHIFT_LSHIFTRT */
2044 /* SHIFT_ASHIFTRT */
2053 static const char *const rotate_two
[3][3] =
2061 /* SHIFT_LSHIFTRT */
2067 /* SHIFT_ASHIFTRT */
2075 static enum shift_alg get_shift_alg
PARAMS ((enum attr_cpu
, enum shift_type
,
2076 enum machine_mode
, int,
2077 const char **, const char **,
2080 /* Given CPU, MODE, SHIFT_TYPE, and shift count COUNT, determine the best
2081 algorithm for doing the shift. The assembler code is stored in ASSEMBLER.
2082 We don't achieve maximum efficiency in all cases, but the hooks are here
2085 For now we just use lots of switch statements. Since we don't even come
2086 close to supporting all the cases, this is simplest. If this function ever
2087 gets too big, perhaps resort to a more table based lookup. Of course,
2088 at this point you may just wish to do it all in rtl.
2090 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
2091 1,2,3,4 will be inlined (1,2 for SI). */
2093 static enum shift_alg
2094 get_shift_alg (cpu
, shift_type
, mode
, count
, assembler_p
,
2095 assembler2_p
, cc_valid_p
)
2097 enum shift_type shift_type
;
2098 enum machine_mode mode
;
2100 const char **assembler_p
;
2101 const char **assembler2_p
;
2104 /* The default is to loop. */
2105 enum shift_alg alg
= SHIFT_LOOP
;
2106 enum shift_mode shift_mode
;
2108 /* We don't handle negative shifts or shifts greater than the word size,
2109 they should have been handled already. */
2111 if (count
< 0 || count
> GET_MODE_BITSIZE (mode
))
2117 shift_mode
= QIshift
;
2120 shift_mode
= HIshift
;
2123 shift_mode
= SIshift
;
2129 /* Assume either SHIFT_LOOP or SHIFT_INLINE.
2130 It is up to the caller to know that looping clobbers cc. */
2131 *assembler_p
= shift_one
[cpu
][shift_type
][shift_mode
].assembler
;
2133 *assembler2_p
= shift_two
[shift_type
][shift_mode
].assembler
;
2135 *assembler2_p
= NULL
;
2136 *cc_valid_p
= shift_one
[cpu
][shift_type
][shift_mode
].cc_valid
;
2138 /* Now look for cases we want to optimize. */
2144 return SHIFT_INLINE
;
2147 /* Shift by 5/6 are only 3 insns on the H8/S, so it's just as
2148 fast as SHIFT_ROT_AND, plus CC is valid. */
2149 if (TARGET_H8300S
&& count
<= 6)
2150 return SHIFT_INLINE
;
2152 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2153 through the entire value. */
2154 if (shift_type
== SHIFT_ASHIFTRT
&& count
== 7)
2156 *assembler_p
= "shll\t%X0\n\tsubx\t%X0,%X0";
2158 return SHIFT_SPECIAL
;
2161 /* Other ASHIFTRTs are too much of a pain. */
2162 if (shift_type
== SHIFT_ASHIFTRT
)
2165 /* Other shifts by 5, 6, or 7 bits use SHIFT_ROT_AND. */
2166 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2168 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2170 return SHIFT_ROT_AND
;
2175 return SHIFT_INLINE
;
2176 else if (TARGET_H8300S
&& count
<= 7)
2177 return SHIFT_INLINE
;
2178 else if (count
== 7)
2180 if (shift_type
== SHIFT_ASHIFT
&& TARGET_H8300
)
2182 *assembler_p
= "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.b\t%t0\n\trotr.b\t%s0\n\tand.b\t#0x80,%s0";
2184 return SHIFT_SPECIAL
;
2187 if (shift_type
== SHIFT_ASHIFT
&& TARGET_H8300H
)
2189 *assembler_p
= "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
2191 return SHIFT_SPECIAL
;
2194 if (shift_type
== SHIFT_LSHIFTRT
&& TARGET_H8300
)
2196 *assembler_p
= "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\trotl.b\t%t0\n\tand.b\t#0x01,%t0";
2198 return SHIFT_SPECIAL
;
2201 if (shift_type
== SHIFT_LSHIFTRT
&& TARGET_H8300H
)
2203 *assembler_p
= "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
2205 return SHIFT_SPECIAL
;
2208 if (shift_type
== SHIFT_ASHIFTRT
)
2210 *assembler_p
= "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
2212 return SHIFT_SPECIAL
;
2215 else if (count
== 8)
2220 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
2222 return SHIFT_SPECIAL
;
2223 case SHIFT_LSHIFTRT
:
2224 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
2226 return SHIFT_SPECIAL
;
2227 case SHIFT_ASHIFTRT
:
2229 *assembler_p
= "mov.b\t%t0,%s0\n\tshll\t%t0\n\tsubx\t%t0,%t0\t";
2231 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0";
2233 return SHIFT_SPECIAL
;
2236 else if (count
== 9)
2241 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0";
2243 return SHIFT_SPECIAL
;
2244 case SHIFT_LSHIFTRT
:
2245 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0";
2247 return SHIFT_SPECIAL
;
2248 case SHIFT_ASHIFTRT
:
2250 *assembler_p
= "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0";
2252 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0";
2254 return SHIFT_SPECIAL
;
2257 else if (count
== 10)
2263 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\t";
2265 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0\n\tshal.b\t%t0";
2267 return SHIFT_SPECIAL
;
2268 case SHIFT_LSHIFTRT
:
2270 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0";
2272 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0\n\tshlr.b\t%s0";
2274 return SHIFT_SPECIAL
;
2275 case SHIFT_ASHIFTRT
:
2277 *assembler_p
= "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0\n\tshar.b\t%s0";
2278 else if (TARGET_H8300H
)
2279 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0\n\tshar.b\t%s0";
2280 else if (TARGET_H8300S
)
2281 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t#2,%s0";
2283 return SHIFT_SPECIAL
;
2286 else if (count
== 11)
2292 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\tshal.b\t%t0";
2294 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0\n\tshal.b\t%t0\n\tshal.b\t%t0";
2296 return SHIFT_SPECIAL
;
2297 case SHIFT_LSHIFTRT
:
2299 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0\n\tshlr.b\t%s0";
2301 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0\n\tshlr.b\t%s0\n\tshlr.b\t%s0";
2303 return SHIFT_SPECIAL
;
2304 case SHIFT_ASHIFTRT
:
2306 *assembler_p
= "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0";
2307 else if (TARGET_H8300H
)
2308 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0";
2309 else if (TARGET_H8300S
)
2310 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t#2,%s0\n\tshar.b\t%s0";
2312 return SHIFT_SPECIAL
;
2315 else if (count
== 12)
2321 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\tshal.b\t#2,%t0";
2323 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0\n\tshal.b\t%t0\n\tshal.b\t%t0\n\tshal.b\t%t0";
2325 return SHIFT_SPECIAL
;
2326 case SHIFT_LSHIFTRT
:
2328 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0\n\tshlr.b\t#2,%s0";
2330 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0\n\tshlr.b\t%s0\n\tshlr.b\t%s0\n\tshlr.b\t%s0";
2332 return SHIFT_SPECIAL
;
2333 case SHIFT_ASHIFTRT
:
2335 *assembler_p
= "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0";
2336 else if (TARGET_H8300H
)
2337 *assembler_p
= "mov.b\t%t0,%s0\n\textw.w\t%T0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0";
2338 else if (TARGET_H8300S
)
2339 *assembler_p
= "mov.b\t%t0,%s0\n\textw.w\t%T0\n\tshar.b\t#2,%s0\n\tshar.b\t#2,%s0";
2341 return SHIFT_SPECIAL
;
2344 else if ((!TARGET_H8300
&& (count
== 13 || count
== 14))
2347 if (count
== 15 && shift_type
== SHIFT_ASHIFTRT
)
2349 *assembler_p
= "shll\t%t0,%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
2351 return SHIFT_SPECIAL
;
2353 else if (shift_type
!= SHIFT_ASHIFTRT
)
2355 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2357 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2359 *assembler2_p
= NULL
;
2361 return SHIFT_ROT_AND
;
2367 if (count
<= (TARGET_H8300
? 2 : 4))
2368 return SHIFT_INLINE
;
2369 else if (TARGET_H8300S
&& count
<= 10)
2370 return SHIFT_INLINE
;
2371 else if (count
== 8 && TARGET_H8300
)
2376 *assembler_p
= "mov.b\t%y0,%z0\n\tmov.b\t%x0,%y0\n\tmov.b\t%w0,%x0\n\tsub.b\t%w0,%w0";
2378 return SHIFT_SPECIAL
;
2379 case SHIFT_LSHIFTRT
:
2380 *assembler_p
= "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tsub.b\t%z0,%z0";
2382 return SHIFT_SPECIAL
;
2383 case SHIFT_ASHIFTRT
:
2384 *assembler_p
= "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tshll\t%z0\n\tsubx\t%z0,%z0";
2386 return SHIFT_SPECIAL
;
2389 else if (count
== 8 && !TARGET_H8300
)
2394 *assembler_p
= "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";
2396 return SHIFT_SPECIAL
;
2397 case SHIFT_LSHIFTRT
:
2398 *assembler_p
= "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";
2400 return SHIFT_SPECIAL
;
2401 case SHIFT_ASHIFTRT
:
2402 *assembler_p
= "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";
2404 return SHIFT_SPECIAL
;
2407 else if (count
== 16)
2412 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2414 return SHIFT_SPECIAL
;
2415 case SHIFT_LSHIFTRT
:
2416 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
2418 return SHIFT_SPECIAL
;
2419 case SHIFT_ASHIFTRT
:
2421 *assembler_p
= "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2423 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0";
2425 return SHIFT_SPECIAL
;
2428 else if (count
== 17 && !TARGET_H8300
)
2433 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0";
2435 return SHIFT_SPECIAL
;
2436 case SHIFT_LSHIFTRT
:
2437 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0";
2439 return SHIFT_SPECIAL
;
2440 case SHIFT_ASHIFTRT
:
2441 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0";
2443 return SHIFT_SPECIAL
;
2446 else if (count
== 18 && !TARGET_H8300
)
2452 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0";
2454 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0\n\tshll.l\t%S0";
2456 return SHIFT_SPECIAL
;
2457 case SHIFT_LSHIFTRT
:
2459 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0";
2461 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0\n\tshlr.l\t%S0";
2463 return SHIFT_SPECIAL
;
2464 case SHIFT_ASHIFTRT
:
2466 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0";
2468 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0\n\tshar.l\t%S0";
2470 return SHIFT_SPECIAL
;
2473 else if (count
== 19 && !TARGET_H8300
)
2479 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0\n\tshll.l\t%S0";
2481 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0\n\tshll.l\t%S0\n\tshll.l\t%S0";
2483 return SHIFT_SPECIAL
;
2484 case SHIFT_LSHIFTRT
:
2486 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0\n\tshlr.l\t%S0";
2488 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0\n\tshlr.l\t%S0\n\tshlr.l\t%S0";
2490 return SHIFT_SPECIAL
;
2491 case SHIFT_ASHIFTRT
:
2493 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0\n\tshar.l\t%S0";
2495 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0\n\tshar.l\t%S0\n\tshar.l\t%S0";
2497 return SHIFT_SPECIAL
;
2500 else if (count
== 20 && TARGET_H8300S
)
2505 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0\n\tshll.l\t#2,%S0";
2507 return SHIFT_SPECIAL
;
2508 case SHIFT_LSHIFTRT
:
2509 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0\n\tshlr.l\t#2,%S0";
2511 return SHIFT_SPECIAL
;
2512 case SHIFT_ASHIFTRT
:
2513 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0\n\tshar.l\t#2,%S0";
2515 return SHIFT_SPECIAL
;
2518 else if (count
== 24 && !TARGET_H8300
)
2523 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2525 return SHIFT_SPECIAL
;
2526 case SHIFT_LSHIFTRT
:
2527 *assembler_p
= "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
2529 return SHIFT_SPECIAL
;
2530 case SHIFT_ASHIFTRT
:
2531 *assembler_p
= "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
2533 return SHIFT_SPECIAL
;
2536 else if (count
>= 28 && count
<= 30 && !TARGET_H8300
)
2538 if (shift_type
== SHIFT_ASHIFTRT
)
2544 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2546 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2548 *assembler2_p
= NULL
;
2550 return SHIFT_ROT_AND
;
2553 else if (count
== 31)
2555 if (shift_type
== SHIFT_ASHIFTRT
)
2558 *assembler_p
= "shll\t%z0\n\tsubx %w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2560 *assembler_p
= "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2562 return SHIFT_SPECIAL
;
2568 if (shift_type
== SHIFT_ASHIFT
)
2569 *assembler_p
= "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2571 *assembler_p
= "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2573 return SHIFT_SPECIAL
;
2577 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2579 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2581 *assembler2_p
= NULL
;
2583 return SHIFT_ROT_AND
;
2596 /* Emit the assembler code for doing shifts. */
2599 emit_a_shift (insn
, operands
)
2600 rtx insn ATTRIBUTE_UNUSED
;
2603 static int loopend_lab
;
2604 const char *assembler
;
2605 const char *assembler2
;
2607 rtx shift
= operands
[3];
2608 enum machine_mode mode
= GET_MODE (shift
);
2609 enum rtx_code code
= GET_CODE (shift
);
2610 enum shift_type shift_type
;
2611 enum shift_mode shift_mode
;
2618 shift_mode
= QIshift
;
2621 shift_mode
= HIshift
;
2624 shift_mode
= SIshift
;
2633 shift_type
= SHIFT_ASHIFTRT
;
2636 shift_type
= SHIFT_LSHIFTRT
;
2639 shift_type
= SHIFT_ASHIFT
;
2645 if (GET_CODE (operands
[2]) != CONST_INT
)
2647 /* Indexing by reg, so have to loop and test at top */
2648 output_asm_insn ("mov.b %X2,%X4", operands
);
2649 fprintf (asm_out_file
, "\tble .Lle%d\n", loopend_lab
);
2651 /* Get the assembler code to do one shift. */
2652 get_shift_alg (cpu_type
, shift_type
, mode
, 1, &assembler
,
2653 &assembler2
, &cc_valid
);
2657 int n
= INTVAL (operands
[2]);
2660 /* If the count is negative, make it 0. */
2663 /* If the count is too big, truncate it.
2664 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2665 do the intuitive thing. */
2666 else if (n
> GET_MODE_BITSIZE (mode
))
2667 n
= GET_MODE_BITSIZE (mode
);
2669 alg
= get_shift_alg (cpu_type
, shift_type
, mode
, n
, &assembler
,
2670 &assembler2
, &cc_valid
);
2675 /* Emit two bit shifts first. */
2676 while (n
> 1 && assembler2
!= NULL
)
2678 output_asm_insn (assembler2
, operands
);
2682 /* Now emit one bit shifts for any residual. */
2685 output_asm_insn (assembler
, operands
);
2689 /* Keep track of CC. */
2692 cc_status
.value1
= operands
[0];
2693 cc_status
.flags
|= cc_valid
;
2699 int m
= GET_MODE_BITSIZE (mode
) - n
;
2700 int mask
= (shift_type
== SHIFT_ASHIFT
2701 ? ((1 << (GET_MODE_BITSIZE (mode
) - n
)) - 1) << n
2702 : (1 << (GET_MODE_BITSIZE (mode
) - n
)) - 1);
2704 /* Not all possibilities of rotate are supported. They shouldn't
2705 be generated, but let's watch for 'em. */
2709 /* Emit two bit rotates first. */
2710 while (m
> 1 && assembler2
!= NULL
)
2712 output_asm_insn (assembler2
, operands
);
2716 /* Now single bit rotates for any residual. */
2719 output_asm_insn (assembler
, operands
);
2723 /* Now mask off the high bits. */
2729 sprintf (insn_buf
, "and #%d,%%X0", mask
);
2730 cc_status
.value1
= operands
[0];
2731 cc_status
.flags
|= CC_NO_CARRY
;
2734 sprintf (insn_buf
, "and #%d,%%s0\n\tand #%d,%%t0",
2735 mask
& 255, mask
>> 8);
2745 sprintf (insn_buf
, "and.%c #%d,%%%c0",
2746 "bwl"[shift_mode
], mask
,
2747 mode
== QImode
? 'X' : mode
== HImode
? 'T' : 'S');
2748 cc_status
.value1
= operands
[0];
2749 cc_status
.flags
|= CC_NO_CARRY
;
2751 output_asm_insn (insn_buf
, operands
);
2755 output_asm_insn (assembler
, operands
);
2759 /* A loop to shift by a "large" constant value.
2760 If we have shift-by-2 insns, use them. */
2761 if (assembler2
!= NULL
)
2763 fprintf (asm_out_file
, "\tmov.b #%d,%sl\n", n
/ 2,
2764 names_big
[REGNO (operands
[4])]);
2765 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
2766 output_asm_insn (assembler2
, operands
);
2767 output_asm_insn ("add #0xff,%X4", operands
);
2768 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
2770 output_asm_insn (assembler
, operands
);
2775 fprintf (asm_out_file
, "\tmov.b #%d,%sl\n", n
,
2776 names_big
[REGNO (operands
[4])]);
2777 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
2778 output_asm_insn (assembler
, operands
);
2779 output_asm_insn ("add #0xff,%X4", operands
);
2780 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
2785 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
2786 output_asm_insn (assembler
, operands
);
2787 output_asm_insn ("add #0xff,%X4", operands
);
2788 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
2789 fprintf (asm_out_file
, ".Lle%d:\n", loopend_lab
);
2794 /* Fix the operands of a gen_xxx so that it could become a bit
2798 fix_bit_operand (operands
, what
, type
)
2803 /* The bit_operand predicate accepts any memory during RTL generation, but
2804 only 'U' memory afterwards, so if this is a MEM operand, we must force
2805 it to be valid for 'U' by reloading the address. */
2807 if (GET_CODE (operands
[2]) == CONST_INT
)
2809 if (CONST_OK_FOR_LETTER_P (INTVAL (operands
[2]), what
))
2811 /* Ok to have a memory dest. */
2812 if (GET_CODE (operands
[0]) == MEM
&& !EXTRA_CONSTRAINT (operands
[0], 'U'))
2814 rtx mem
= gen_rtx_MEM (GET_MODE (operands
[0]),
2815 copy_to_mode_reg (Pmode
,
2816 XEXP (operands
[0], 0)));
2817 RTX_UNCHANGING_P (mem
) = RTX_UNCHANGING_P (operands
[0]);
2818 MEM_COPY_ATTRIBUTES (mem
, operands
[0]);
2822 if (GET_CODE (operands
[1]) == MEM
&& !EXTRA_CONSTRAINT (operands
[1], 'U'))
2824 rtx mem
= gen_rtx_MEM (GET_MODE (operands
[1]),
2825 copy_to_mode_reg (Pmode
,
2826 XEXP (operands
[1], 0)));
2827 RTX_UNCHANGING_P (mem
) = RTX_UNCHANGING_P (operands
[1]);
2828 MEM_COPY_ATTRIBUTES (mem
, operands
[0]);
2835 /* Dest and src op must be register. */
2837 operands
[1] = force_reg (QImode
, operands
[1]);
2839 rtx res
= gen_reg_rtx (QImode
);
2840 emit_insn (gen_rtx_SET (VOIDmode
, res
,
2841 gen_rtx (type
, QImode
, operands
[1], operands
[2])));
2842 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], res
));
2847 /* Return nonzero if FUNC is an interrupt function as specified
2848 by the "interrupt" attribute. */
2851 h8300_interrupt_function_p (func
)
2856 if (TREE_CODE (func
) != FUNCTION_DECL
)
2859 a
= lookup_attribute ("interrupt_handler", DECL_MACHINE_ATTRIBUTES (func
));
2860 return a
!= NULL_TREE
;
2863 /* Return nonzero if FUNC is an OS_Task function as specified
2864 by the "OS_Task" attribute. */
2867 h8300_os_task_function_p (func
)
2872 if (TREE_CODE (func
) != FUNCTION_DECL
)
2875 a
= lookup_attribute ("OS_Task", DECL_MACHINE_ATTRIBUTES (func
));
2876 return a
!= NULL_TREE
;
2879 /* Return nonzero if FUNC is a monitor function as specified
2880 by the "monitor" attribute. */
2883 h8300_monitor_function_p (func
)
2888 if (TREE_CODE (func
) != FUNCTION_DECL
)
2891 a
= lookup_attribute ("monitor", DECL_MACHINE_ATTRIBUTES (func
));
2892 return a
!= NULL_TREE
;
2895 /* Return nonzero if FUNC is a function that should be called
2896 through the function vector. */
2899 h8300_funcvec_function_p (func
)
2904 if (TREE_CODE (func
) != FUNCTION_DECL
)
2907 a
= lookup_attribute ("function_vector", DECL_MACHINE_ATTRIBUTES (func
));
2908 return a
!= NULL_TREE
;
2911 /* Return nonzero if DECL is a variable that's in the eight bit
2915 h8300_eightbit_data_p (decl
)
2920 if (TREE_CODE (decl
) != VAR_DECL
)
2923 a
= lookup_attribute ("eightbit_data", DECL_MACHINE_ATTRIBUTES (decl
));
2924 return a
!= NULL_TREE
;
2927 /* Return nonzero if DECL is a variable that's in the tiny
2931 h8300_tiny_data_p (decl
)
2936 if (TREE_CODE (decl
) != VAR_DECL
)
2939 a
= lookup_attribute ("tiny_data", DECL_MACHINE_ATTRIBUTES (decl
));
2940 return a
!= NULL_TREE
;
2943 /* Return nonzero if ATTR is a valid attribute for DECL.
2944 ATTRIBUTES are any existing attributes and ARGS are the arguments
2947 Supported attributes:
2949 interrupt_handler: output a prologue and epilogue suitable for an
2952 function_vector: This function should be called through the
2955 eightbit_data: This variable lives in the 8-bit data area and can
2956 be referenced with 8-bit absolute memory addresses.
2958 tiny_data: This variable lives in the tiny data area and can be
2959 referenced with 16-bit absolute memory references. */
2962 h8300_valid_machine_decl_attribute (decl
, attributes
, attr
, args
)
2964 tree attributes ATTRIBUTE_UNUSED
;
2968 if (args
!= NULL_TREE
)
2971 if (is_attribute_p ("interrupt_handler", attr
)
2972 || is_attribute_p ("OS_Task", attr
)
2973 || is_attribute_p ("monitor", attr
)
2974 || is_attribute_p ("function_vector", attr
))
2975 return TREE_CODE (decl
) == FUNCTION_DECL
;
2977 if (is_attribute_p ("eightbit_data", attr
)
2978 && (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
)))
2980 if (DECL_INITIAL (decl
) == NULL_TREE
)
2982 warning ("Only initialized variables can be placed into the 8-bit area.");
2985 DECL_SECTION_NAME (decl
) = build_string (7, ".eight");
2989 if (is_attribute_p ("tiny_data", attr
)
2990 && (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
)))
2992 if (DECL_INITIAL (decl
) == NULL_TREE
)
2994 warning ("Only initialized variables can be placed into the 8-bit area.");
2997 DECL_SECTION_NAME (decl
) = build_string (6, ".tiny");
3004 extern struct obstack
*saveable_obstack
;
3007 h8300_encode_label (decl
)
3010 const char *str
= XSTR (XEXP (DECL_RTL (decl
), 0), 0);
3011 int len
= strlen (str
);
3014 newstr
= obstack_alloc (saveable_obstack
, len
+ 2);
3016 strcpy (newstr
+ 1, str
);
3018 XSTR (XEXP (DECL_RTL (decl
), 0), 0) = newstr
;
3022 output_simode_bld (bild
, log2
, operands
)
3027 /* Clear the destination register. */
3028 if (TARGET_H8300H
|| TARGET_H8300S
)
3029 output_asm_insn ("sub.l\t%S0,%S0", operands
);
3031 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands
);
3033 /* Get the bit number we want to load. */
3035 operands
[2] = GEN_INT (exact_log2 (INTVAL (operands
[2])));
3037 /* Now output the bit load or bit inverse load, and store it in
3040 output_asm_insn ("bild\t%Z2,%Y1\n\tbst\t#0,%w0", operands
);
3042 output_asm_insn ("bld\t%Z2,%Y1\n\tbst\t#0,%w0", operands
);
3048 /* Given INSN and its current length LENGTH, return the adjustment
3049 (in bytes) to correctly compute INSN's length.
3051 We use this to get the lengths of various memory references correct. */
3054 h8300_adjust_insn_length (insn
, length
)
3056 int length ATTRIBUTE_UNUSED
;
3060 /* We must filter these ou before calling get_attr_adjust_length. */
3061 if (GET_CODE (PATTERN (insn
)) == USE
3062 || GET_CODE (PATTERN (insn
)) == CLOBBER
3063 || GET_CODE (PATTERN (insn
)) == SEQUENCE
3064 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
3065 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
3068 if (get_attr_adjust_length (insn
) == ADJUST_LENGTH_NO
)
3071 pat
= PATTERN (insn
);
3073 /* Adjust length for reg->mem and mem->reg copies. */
3074 if (GET_CODE (pat
) == SET
3075 && (GET_CODE (SET_SRC (pat
)) == MEM
3076 || GET_CODE (SET_DEST (pat
)) == MEM
))
3078 /* This insn might need a length adjustment. */
3081 if (GET_CODE (SET_SRC (pat
)) == MEM
)
3082 addr
= XEXP (SET_SRC (pat
), 0);
3084 addr
= XEXP (SET_DEST (pat
), 0);
3086 /* On the H8/300, only one adjustment is necessary; if the
3087 address mode is register indirect, then this insn is two
3088 bytes shorter than indicated in the machine description. */
3089 if (TARGET_H8300
&& GET_CODE (addr
) == REG
)
3092 /* On the H8/300H and H8/S, register indirect is 6 bytes shorter than
3093 indicated in the machine description. */
3094 if ((TARGET_H8300H
|| TARGET_H8300S
)
3095 && GET_CODE (addr
) == REG
)
3098 /* On the H8/300H and H8/300S, reg + d, for small displacements is 4
3099 bytes shorter than indicated in the machine description. */
3100 if ((TARGET_H8300H
|| TARGET_H8300S
)
3101 && GET_CODE (addr
) == PLUS
3102 && GET_CODE (XEXP (addr
, 0)) == REG
3103 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
3104 && INTVAL (XEXP (addr
, 1)) > -32768
3105 && INTVAL (XEXP (addr
, 1)) < 32767)
3108 /* On the H8/300H and H8/300S, abs:16 is two bytes shorter than the
3109 more general abs:24. */
3110 if ((TARGET_H8300H
|| TARGET_H8300S
)
3111 && GET_CODE (addr
) == SYMBOL_REF
3112 && TINY_DATA_NAME_P (XSTR (addr
, 0)))
3116 /* Loading some constants needs adjustment. */
3117 if (GET_CODE (pat
) == SET
3118 && GET_CODE (SET_SRC (pat
)) == CONST_INT
3119 && GET_MODE (SET_DEST (pat
)) == SImode
3120 && INTVAL (SET_SRC (pat
)) != 0)
3123 && ((INTVAL (SET_SRC (pat
)) & 0xffff) == 0
3124 || ((INTVAL (SET_SRC (pat
)) >> 16) & 0xffff) == 0))
3127 if (TARGET_H8300H
|| TARGET_H8300S
)
3129 int val
= INTVAL (SET_SRC (pat
));
3131 if (val
== (val
& 0xff)
3132 || val
== (val
& 0xff00))
3135 if (val
== -4 || val
== -2 || val
== -1)
3140 /* Shifts need various adjustments. */
3141 if (GET_CODE (pat
) == PARALLEL
3142 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
3143 && (GET_CODE (SET_SRC (XVECEXP (pat
, 0, 0))) == ASHIFTRT
3144 || GET_CODE (SET_SRC (XVECEXP (pat
, 0, 0))) == LSHIFTRT
3145 || GET_CODE (SET_SRC (XVECEXP (pat
, 0, 0))) == ASHIFT
))
3147 rtx src
= SET_SRC (XVECEXP (pat
, 0, 0));
3148 enum machine_mode mode
= GET_MODE (src
);
3151 if (GET_CODE (XEXP (src
, 1)) != CONST_INT
)
3154 shift
= INTVAL (XEXP (src
, 1));
3155 /* According to ANSI, negative shift is undefined. It is
3156 considered to be zero in this case (see function
3157 emit_a_shift above). */
3161 /* QImode shifts by small constants take one insn
3162 per shift. So the adjustment is 20 (md length) -
3164 if (mode
== QImode
&& shift
<= 4)
3165 return -(20 - shift
* 2);
3167 /* Similarly for HImode and SImode shifts by
3168 small constants on the H8/300H and H8/300S. */
3169 if ((TARGET_H8300H
|| TARGET_H8300S
)
3170 && (mode
== HImode
|| mode
== SImode
) && shift
<= 4)
3171 return -(20 - shift
* 2);
3173 /* HImode shifts by small constants for the H8/300. */
3174 if (mode
== HImode
&& shift
<= 4)
3175 return -(20 - (shift
* (GET_CODE (src
) == ASHIFT
? 2 : 4)));
3177 /* SImode shifts by small constants for the H8/300. */
3178 if (mode
== SImode
&& shift
<= 2)
3179 return -(20 - (shift
* (GET_CODE (src
) == ASHIFT
? 6 : 8)));
3181 /* XXX ??? Could check for more shift/rotate cases here. */