1 /* Subroutines for insn-output.c for Hitachi H8/300.
2 Copyright (C) 1992, 93, 94, 95, 96, 97, 1998, 1999 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"
42 /* Forward declarations. */
43 void print_operand_address ();
46 static int h8300_interrupt_function_p
PROTO ((tree
));
47 static int h8300_monitor_function_p
PROTO ((tree
));
48 static int h8300_os_task_function_p
PROTO ((tree
));
50 /* CPU_TYPE, says what cpu we're compiling for. */
53 /* True if the current function is an interrupt handler
54 (either via #pragma or an attribute specification). */
55 int interrupt_handler
;
57 /* True if the current function is an OS Task
58 (via an attribute specification). */
61 /* True if the current function is a monitor
62 (via an attribute specification). */
65 /* True if a #pragma saveall has been seen for the current function. */
68 static char *names_big
[] =
69 {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7"};
71 static char *names_extended
[] =
72 {"er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"};
74 static char *names_upper_extended
[] =
75 {"e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"};
77 /* Points to one of the above. */
78 /* ??? The above could be put in an array indexed by CPU_TYPE. */
81 /* Various operations needed by the following, indexed by CPU_TYPE. */
83 static char *h8_push_ops
[2] =
85 static char *h8_pop_ops
[2] =
87 static char *h8_mov_ops
[2] =
90 char *h8_push_op
, *h8_pop_op
, *h8_mov_op
;
92 /* Initialize various cpu specific globals at start up. */
99 cpu_type
= (int) CPU_H8300
;
100 h8_reg_names
= names_big
;
104 /* For this we treat the H8/300 and H8/S the same. */
105 cpu_type
= (int) CPU_H8300H
;
106 h8_reg_names
= names_extended
;
108 h8_push_op
= h8_push_ops
[cpu_type
];
109 h8_pop_op
= h8_pop_ops
[cpu_type
];
110 h8_mov_op
= h8_mov_ops
[cpu_type
];
118 static char *names_small
[] =
119 {"r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
120 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h"};
122 return names_small
[REGNO (x
) * 2 + b
];
125 /* REGNO must be saved/restored across calls if this macro is true. */
127 #define WORD_REG_USED(regno) \
131 || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno]) \
132 || (regs_ever_live[regno] && !call_used_regs[regno])))
134 /* Output assembly language to FILE for the operation OP with operand size
135 SIZE to adjust the stack pointer. */
138 dosize (file
, op
, size
)
143 /* On the h8300h and h8300s, for sizes <= 8 bytes it is as good or
144 better to use adds/subs insns rather than add.l/sub.l
145 with an immediate value. */
146 if (size
> 4 && size
<= 8 && (TARGET_H8300H
|| TARGET_H8300S
))
148 /* Crank the size down to <= 4 */
149 fprintf (file
, "\t%ss\t#%d,sp\n", op
, 4);
156 if (TARGET_H8300H
|| TARGET_H8300S
)
158 fprintf (file
, "\t%ss\t#%d,sp\n", op
, 4);
163 fprintf (file
, "\t%ss\t#%d,sp\n", op
, 2);
165 /* Fall through... */
168 fprintf (file
, "\t%ss\t#%d,sp\n", op
, size
);
176 if (current_function_needs_context
177 && strcmp (op
, "sub") == 0)
179 /* Egad. We don't have a temporary to hold the
180 size of the frame in the prologue! Just inline
181 the bastard since this shouldn't happen often. */
184 fprintf (file
, "\tsubs\t#2,sp\n");
189 fprintf (file
, "\tsubs\t#1,sp\n");
194 fprintf (file
, "\tmov.w\t#%d,r3\n\t%s.w\tr3,sp\n", size
, op
);
197 fprintf (file
, "\t%s\t#%d,sp\n", op
, size
);
203 /* Output assembly language code for the function prologue. */
204 static int push_order
[FIRST_PSEUDO_REGISTER
] =
205 {0, 1, 2, 3, 4, 5, 6, -1, -1, -1};
206 static int pop_order
[FIRST_PSEUDO_REGISTER
] =
207 {6, 5, 4, 3, 2, 1, 0, -1, -1, -1};
209 /* This is what the stack looks like after the prolog of
210 a function with a frame has been set up:
216 <saved registers> <- sp
218 This is what the stack looks like after the prolog of
219 a function which doesn't have a frame:
224 <saved registers> <- sp
228 function_prologue (file
, size
)
232 register int mask
= 0;
233 int fsize
= (size
+ STACK_BOUNDARY
/ 8 - 1) & -STACK_BOUNDARY
/ 8;
236 /* Note a function with the interrupt attribute and set interrupt_handler
238 if (h8300_interrupt_function_p (current_function_decl
))
239 interrupt_handler
= 1;
241 /* If the current function has the OS_Task attribute set, then
242 we have a naked prologue. */
243 if (h8300_os_task_function_p (current_function_decl
))
245 fprintf (file
, ";OS_Task prologue\n");
250 if (h8300_monitor_function_p (current_function_decl
))
252 /* My understanding of monitor functions is they act just
253 like interrupt functions, except the prologue must
255 fprintf (file
, ";monitor prologue\n");
256 interrupt_handler
= 1;
260 fprintf (file
, "\tsubs\t#2,sp\n");
261 fprintf (file
, "\tpush\tr0\n");
262 fprintf (file
, "\tstc\tccr,r0l\n");
263 fprintf (file
, "\torc\t#128,ccr\n");
264 fprintf (file
, "\tmov.b\tr0l,@(4,sp)\n");
268 fprintf (file
, "\tpush\ter0\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 if (frame_pointer_needed
)
278 fprintf (file
, "\t%s\t%s\n", h8_push_op
,
279 h8_reg_names
[FRAME_POINTER_REGNUM
]);
280 fprintf (file
, "\t%s\t%s,%s\n", h8_mov_op
,
281 h8_reg_names
[STACK_POINTER_REGNUM
],
282 h8_reg_names
[FRAME_POINTER_REGNUM
]);
285 /* leave room for locals */
286 dosize (file
, "sub", fsize
);
288 /* Push the rest of the registers */
289 for (idx
= 0; idx
< FIRST_PSEUDO_REGISTER
; idx
++)
291 int regno
= push_order
[idx
];
294 && WORD_REG_USED (regno
)
295 && (!frame_pointer_needed
|| regno
!= FRAME_POINTER_REGNUM
))
299 /* Try to push multiple registers. */
300 if (regno
== 0 || regno
== 4)
302 int second_regno
= push_order
[idx
+ 1];
303 int third_regno
= push_order
[idx
+ 2];
304 int fourth_regno
= push_order
[idx
+ 3];
306 if (fourth_regno
>= 0
307 && WORD_REG_USED (fourth_regno
)
308 && (!frame_pointer_needed
309 || fourth_regno
!= FRAME_POINTER_REGNUM
)
311 && WORD_REG_USED (third_regno
)
312 && (!frame_pointer_needed
313 || third_regno
!= FRAME_POINTER_REGNUM
)
315 && WORD_REG_USED (second_regno
)
316 && (!frame_pointer_needed
317 || second_regno
!= FRAME_POINTER_REGNUM
))
319 fprintf (file
, "\tstm.l %s-%s,@-sp\n",
321 h8_reg_names
[fourth_regno
]);
326 if (regno
== 0 || regno
== 4)
328 int second_regno
= push_order
[idx
+ 1];
329 int third_regno
= push_order
[idx
+ 2];
332 && WORD_REG_USED (third_regno
)
333 && (!frame_pointer_needed
334 || third_regno
!= FRAME_POINTER_REGNUM
)
336 && WORD_REG_USED (second_regno
)
337 && (!frame_pointer_needed
338 || second_regno
!= FRAME_POINTER_REGNUM
))
340 fprintf (file
, "\tstm.l %s-%s,@-sp\n",
342 h8_reg_names
[third_regno
]);
347 if (regno
== 0 || regno
== 2 || regno
== 4 || regno
== 6)
349 int second_regno
= push_order
[idx
+ 1];
351 if (second_regno
>= 0
352 && WORD_REG_USED (second_regno
)
353 && (!frame_pointer_needed
354 || second_regno
!= FRAME_POINTER_REGNUM
))
356 fprintf (file
, "\tstm.l %s-%s,@-sp\n",
358 h8_reg_names
[second_regno
]);
364 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[regno
]);
369 /* Output assembly language code for the function epilogue. */
372 function_epilogue (file
, size
)
377 register int mask
= 0;
378 int fsize
= (size
+ STACK_BOUNDARY
/ 8 - 1) & -STACK_BOUNDARY
/ 8;
380 rtx insn
= get_last_insn ();
384 /* OS_Task epilogues are nearly naked -- they just have an
386 fprintf (file
, ";OS_task epilogue\n");
387 fprintf (file
, "\trts\n");
391 /* monitor epilogues are the same as interrupt function epilogues.
392 Just make a note that we're in an monitor epilogue. */
394 fprintf(file
, ";monitor epilogue\n");
396 /* If the last insn was a BARRIER, we don't have to write any code. */
397 if (GET_CODE (insn
) == NOTE
)
398 insn
= prev_nonnote_insn (insn
);
399 if (insn
&& GET_CODE (insn
) == BARRIER
)
402 /* Pop the saved registers. */
403 for (idx
= 0; idx
< FIRST_PSEUDO_REGISTER
; idx
++)
405 int regno
= pop_order
[idx
];
408 && WORD_REG_USED (regno
)
409 && (!frame_pointer_needed
|| regno
!= FRAME_POINTER_REGNUM
))
413 /* Try to pop multiple registers. */
414 if (regno
== 7 || regno
== 3)
416 int second_regno
= pop_order
[idx
+ 1];
417 int third_regno
= pop_order
[idx
+ 2];
418 int fourth_regno
= pop_order
[idx
+ 3];
420 if (fourth_regno
>= 0
421 && WORD_REG_USED (fourth_regno
)
422 && (!frame_pointer_needed
423 || fourth_regno
!= FRAME_POINTER_REGNUM
)
425 && WORD_REG_USED (third_regno
)
426 && (!frame_pointer_needed
427 || third_regno
!= FRAME_POINTER_REGNUM
)
429 && WORD_REG_USED (second_regno
)
430 && (!frame_pointer_needed
431 || second_regno
!= FRAME_POINTER_REGNUM
))
433 fprintf (file
, "\tldm.l @sp+,%s-%s\n",
434 h8_reg_names
[fourth_regno
],
435 h8_reg_names
[regno
]);
440 if (regno
== 6 || regno
== 2)
442 int second_regno
= pop_order
[idx
+ 1];
443 int third_regno
= pop_order
[idx
+ 2];
446 && WORD_REG_USED (third_regno
)
447 && (!frame_pointer_needed
448 || third_regno
!= FRAME_POINTER_REGNUM
)
450 && WORD_REG_USED (second_regno
)
451 && (!frame_pointer_needed
452 || second_regno
!= FRAME_POINTER_REGNUM
))
454 fprintf (file
, "\tldm.l @sp+,%s-%s\n",
455 h8_reg_names
[third_regno
],
456 h8_reg_names
[regno
]);
461 if (regno
== 7 || regno
== 5 || regno
== 3 || regno
== 1)
463 int second_regno
= pop_order
[idx
+ 1];
465 if (second_regno
>= 0
466 && WORD_REG_USED (second_regno
)
467 && (!frame_pointer_needed
468 || second_regno
!= FRAME_POINTER_REGNUM
))
470 fprintf (file
, "\tldm.l @sp+,%s-%s\n",
471 h8_reg_names
[second_regno
],
472 h8_reg_names
[regno
]);
478 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[regno
]);
482 /* deallocate locals */
483 dosize (file
, "add", fsize
);
485 /* pop frame pointer if we had one. */
486 if (frame_pointer_needed
)
487 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[FRAME_POINTER_REGNUM
]);
489 /* If this is a monitor function, there is one register still left on
492 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[0]);
494 if (interrupt_handler
)
495 fprintf (file
, "\trte\n");
497 fprintf (file
, "\trts\n");
500 interrupt_handler
= 0;
506 /* Output assembly code for the start of the file. */
508 asm_file_start (file
)
511 fprintf (file
, ";\tGCC For the Hitachi H8/300\n");
512 fprintf (file
, ";\tBy Hitachi America Ltd and Cygnus Support\n");
513 fprintf (file
, ";\trelease F-1\n");
515 fprintf (file
, "; -O%d\n", optimize
);
517 fprintf (file
, "\n\t.h8300h\n");
518 else if (TARGET_H8300S
)
519 fprintf (file
, "\n\t.h8300s\n");
521 fprintf (file
, "\n\n");
522 output_file_directive (file
, main_input_filename
);
525 /* Output assembly language code for the end of file. */
531 fprintf (file
, "\t.end\n");
534 /* Return true if VALUE is a valid constant for constraint 'P'.
535 IE: VALUE is a power of two <= 2**15. */
538 small_power_of_two (value
)
564 /* Return true if VALUE is a valid constant for constraint 'O', which
565 means that the constant would be ok to use as a bit for a bclr
572 return small_power_of_two ((~value
) & 0xff);
575 /* Return true is OP is a valid source operand for an integer move
579 general_operand_src (op
, mode
)
581 enum machine_mode mode
;
583 if (GET_CODE (op
) == MEM
&& GET_CODE (XEXP (op
, 0)) == POST_INC
)
585 return general_operand (op
, mode
);
588 /* Return true if OP is a valid destination operand for an integer move
592 general_operand_dst (op
, mode
)
594 enum machine_mode mode
;
596 if (GET_CODE (op
) == MEM
&& GET_CODE (XEXP (op
, 0)) == PRE_DEC
)
598 return general_operand (op
, mode
);
601 /* Return true if OP is a const valid for a bit clear instruction. */
604 o_operand (operand
, mode
)
606 enum machine_mode mode
;
608 return (GET_CODE (operand
) == CONST_INT
609 && CONST_OK_FOR_O (INTVAL (operand
)));
612 /* Return true if OP is a const valid for a bit set or bit xor instruction. */
615 p_operand (operand
, mode
)
617 enum machine_mode mode
;
619 return (GET_CODE (operand
) == CONST_INT
620 && CONST_OK_FOR_P (INTVAL (operand
)));
623 /* Return true if OP is a valid call operand. */
626 call_insn_operand (op
, mode
)
628 enum machine_mode mode
;
630 if (GET_CODE (op
) == MEM
)
632 rtx inside
= XEXP (op
, 0);
633 if (register_operand (inside
, Pmode
))
635 if (CONSTANT_ADDRESS_P (inside
))
642 adds_subs_operand (op
, mode
)
644 enum machine_mode mode
;
646 if (GET_CODE (op
) == CONST_INT
)
648 if (INTVAL (op
) <= 4 && INTVAL (op
) >= 0)
650 if (INTVAL (op
) >= -4 && INTVAL (op
) <= 0)
652 if ((TARGET_H8300H
|| TARGET_H8300S
)
654 && (INTVAL (op
) <= 8 && INTVAL (op
) >= 0))
656 if ((TARGET_H8300H
|| TARGET_H8300S
)
658 && (INTVAL (op
) >= -8 && INTVAL (op
) <= 0))
664 /* Return nonzero if op is an adds/subs operand which only requires
665 one insn to implement. It is assumed that OP is already an adds/subs
668 one_insn_adds_subs_operand (op
, mode
)
670 enum machine_mode mode
;
672 int val
= INTVAL (op
);
674 if (val
== 1 || val
== -1
675 || val
== 2 || val
== -2
676 || ((TARGET_H8300H
|| TARGET_H8300S
)
677 && (val
== 4 || val
== -4)))
683 output_adds_subs (operands
)
686 int val
= INTVAL (operands
[2]);
688 /* First get the value into the range -4..4 inclusive.
690 The only way it can be out of this range is when TARGET_H8300H
691 or TARGET_H8300S is true, thus it is safe to use adds #4 and subs #4. */
694 output_asm_insn ("adds #4,%A0", operands
);
700 output_asm_insn ("subs #4,%A0", operands
);
704 /* Handle case were val == 4 or val == -4 and we're compiling
705 for TARGET_H8300H or TARGET_H8300S. */
706 if ((TARGET_H8300H
|| TARGET_H8300S
)
708 return "adds #4,%A0";
710 if ((TARGET_H8300H
|| TARGET_H8300S
)
712 return "subs #4,%A0";
716 output_asm_insn ("adds #2,%A0", operands
);
722 output_asm_insn ("subs #2,%A0", operands
);
726 /* val should be one or two now. */
728 return "adds #2,%A0";
731 return "subs #2,%A0";
733 /* val should be one now. */
735 return "adds #1,%A0";
738 return "subs #1,%A0";
740 /* If not optimizing, we might be asked to add 0. */
744 /* In theory, this can't happen. */
748 /* Return true if OP is a valid call operand, and OP represents
749 an operand for a small call (4 bytes instead of 6 bytes). */
752 small_call_insn_operand (op
, mode
)
754 enum machine_mode mode
;
756 if (GET_CODE (op
) == MEM
)
758 rtx inside
= XEXP (op
, 0);
760 /* Register indirect is a small call. */
761 if (register_operand (inside
, Pmode
))
764 /* A call through the function vector is a small
766 if (GET_CODE (inside
) == SYMBOL_REF
767 && SYMBOL_REF_FLAG (inside
))
770 /* Otherwise it's a large call. */
774 /* Return true if OP is a valid jump operand. */
777 jump_address_operand (op
, mode
)
779 enum machine_mode mode
;
781 if (GET_CODE (op
) == REG
)
782 return mode
== Pmode
;
784 if (GET_CODE (op
) == MEM
)
786 rtx inside
= XEXP (op
, 0);
787 if (register_operand (inside
, Pmode
))
789 if (CONSTANT_ADDRESS_P (inside
))
795 /* Recognize valid operands for bitfield instructions. */
797 extern int rtx_equal_function_value_matters
;
800 bit_operand (op
, mode
)
802 enum machine_mode mode
;
804 /* We can except any general operand, expept that MEM operands must
805 be limited to those that use addresses valid for the 'U' constraint. */
806 if (!general_operand (op
, mode
))
809 /* Accept any mem during RTL generation. Otherwise, the code that does
810 insv and extzv will think that we can not handle memory. However,
811 to avoid reload problems, we only accept 'U' MEM operands after RTL
812 generation. This means that any named pattern which uses this predicate
813 must force its operands to match 'U' before emitting RTL. */
815 if (GET_CODE (op
) == REG
)
817 if (GET_CODE (op
) == SUBREG
)
819 if (!rtx_equal_function_value_matters
)
821 /* We're building rtl */
822 return GET_CODE (op
) == MEM
;
826 return (GET_CODE (op
) == MEM
827 && EXTRA_CONSTRAINT (op
, 'U'));
832 bit_memory_operand (op
, mode
)
834 enum machine_mode mode
;
836 return (GET_CODE (op
) == MEM
837 && EXTRA_CONSTRAINT (op
, 'U'));
840 /* Recognize valid operators for bit test. */
843 eq_operator (x
, mode
)
845 enum machine_mode mode
;
847 return (GET_CODE (x
) == EQ
|| GET_CODE (x
) == NE
);
850 /* Handle machine specific pragmas for compatibility with existing
851 compilers for the H8/300.
853 pragma saveall generates prolog/epilog code which saves and
854 restores all the registers on function entry.
856 pragma interrupt saves and restores all registers, and exits with
857 an rte instruction rather than an rts. A pointer to a function
858 with this attribute may be safely used in an interrupt vector. */
861 handle_pragma (p_getc
, p_ungetc
, pname
)
862 int (* p_getc
) PROTO ((void));
863 void (* p_ungetc
) PROTO ((int));
868 if (strcmp (pname
, "interrupt") == 0)
869 interrupt_handler
= retval
= 1;
870 else if (strcmp (pname
, "saveall") == 0)
871 pragma_saveall
= retval
= 1;
876 /* If the next arg with MODE and TYPE is to be passed in a register, return
877 the rtx to represent where it is passed. CUM represents the state after
878 the last argument. NAMED is not used. */
880 static char *hand_list
[] =
900 /* Return an RTX to represent where a value with mode MODE will be returned
901 from a function. If the result is 0, the argument is pushed. */
904 function_arg (cum
, mode
, type
, named
)
905 CUMULATIVE_ARGS
*cum
;
906 enum machine_mode mode
;
914 /* Never pass unnamed arguments in registers. */
918 /* Pass 3 regs worth of data in regs when user asked on the command line. */
919 if (TARGET_QUICKCALL
)
922 /* If calling hand written assembler, use 4 regs of args. */
928 fname
= XSTR (cum
->libcall
, 0);
930 /* See if this libcall is one of the hand coded ones. */
932 for (p
= hand_list
; *p
&& strcmp (*p
, fname
) != 0; p
++)
944 size
= int_size_in_bytes (type
);
946 size
= GET_MODE_SIZE (mode
);
948 if (size
+ cum
->nbytes
> regpass
* UNITS_PER_WORD
)
954 switch (cum
->nbytes
/ UNITS_PER_WORD
)
957 result
= gen_rtx (REG
, mode
, 0);
960 result
= gen_rtx (REG
, mode
, 1);
963 result
= gen_rtx (REG
, mode
, 2);
966 result
= gen_rtx (REG
, mode
, 3);
977 /* Return the cost of the rtx R with code CODE. */
997 if (TARGET_H8300H
|| TARGET_H8300S
)
1018 /* Documentation for the machine specific operand escapes:
1020 'A' print rn in h8/300 mode, erN in H8/300H mode
1021 'C' print (operand - 2).
1022 'E' like s but negative.
1023 'F' like t but negative.
1024 'G' constant just the negative
1025 'M' turn a 'M' constant into its negative mod 2.
1026 'P' if operand is incing/decing sp, print .w, otherwise .b.
1027 'R' print operand as a byte:8 address if appropriate, else fall back to
1029 'S' print operand as a long word
1030 'T' print operand as a word
1031 'U' if operand is incing/decing sp, print l, otherwise nothing.
1032 'V' find the set bit, and print its number.
1033 'W' find the clear bit, and print its number.
1034 'X' print operand as a byte
1035 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
1036 If this operand isn't a register, fall back to 'R' handling.
1038 'b' print the bit opcode
1039 'c' print the ibit opcode
1040 'd' bcc if EQ, bcs if NE
1041 'e' first word of 32 bit value - if reg, then least reg. if mem
1042 then least. if const then most sig word
1043 'f' second word of 32 bit value - if reg, then biggest reg. if mem
1044 then +2. if const then least sig word
1045 'g' bcs if EQ, bcc if NE
1046 'j' print operand as condition code.
1047 'k' print operand as reverse condition code.
1048 's' print as low byte of 16 bit value
1049 't' print as high byte of 16 bit value
1050 'w' print as low byte of 32 bit value
1051 'x' print as 2nd byte of 32 bit value
1052 'y' print as 3rd byte of 32 bit value
1053 'z' print as msb of 32 bit value
1056 /* Return assembly language string which identifies a comparison type. */
1089 /* Print operand X using operand code CODE to assembly language output file
1093 print_operand (file
, x
, code
)
1098 /* This is used for communication between the 'P' and 'U' codes. */
1099 static char *last_p
;
1101 /* This is used for communication between codes V,W,Z and Y. */
1107 if (GET_CODE (x
) == REG
)
1108 fprintf (file
, "%s", h8_reg_names
[REGNO (x
)]);
1113 fprintf (file
, "#%d", INTVAL (x
) - 2);
1116 switch (GET_CODE (x
))
1119 fprintf (file
, "%sl", names_big
[REGNO (x
)]);
1122 fprintf (file
, "#%d", (-INTVAL (x
)) & 0xff);
1129 switch (GET_CODE (x
))
1132 fprintf (file
, "%sh", names_big
[REGNO (x
)]);
1135 fprintf (file
, "#%d", ((-INTVAL (x
)) & 0xff00) >> 8);
1142 if (GET_CODE (x
) != CONST_INT
)
1144 fprintf (file
, "#%d", 0xff & (-INTVAL (x
)));
1147 /* For 3/-3 and 4/-4, the other 2 is handled separately. */
1154 fprintf (file
, "#2");
1160 fprintf (file
, "#1");
1167 if (REGNO (XEXP (XEXP (x
, 0), 0)) == STACK_POINTER_REGNUM
)
1170 fprintf (file
, ".w");
1175 fprintf (file
, ".b");
1179 if (GET_CODE (x
) == REG
)
1180 fprintf (file
, "%s", names_extended
[REGNO (x
)]);
1185 if (GET_CODE (x
) == REG
)
1186 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1191 fprintf (file
, "%s%s", names_big
[REGNO (x
)], last_p
);
1194 bitint
= exact_log2 (INTVAL (x
));
1197 fprintf (file
, "#%d", bitint
& 7);
1200 bitint
= exact_log2 ((~INTVAL (x
)) & 0xff);
1203 fprintf (file
, "#%d", bitint
& 7);
1207 if (GET_CODE (x
) == REG
)
1208 fprintf (file
, "%s", byte_reg (x
, 0));
1215 if (GET_CODE (x
) == REG
)
1216 fprintf (file
, "%s%c", names_big
[REGNO (x
)], bitint
> 7 ? 'h' : 'l');
1218 print_operand (file
, x
, 'R');
1222 bitint
= INTVAL (x
);
1223 fprintf (file
, "#%d", bitint
& 7);
1226 switch (GET_CODE (x
))
1229 fprintf (file
, "bor");
1232 fprintf (file
, "bxor");
1235 fprintf (file
, "band");
1240 switch (GET_CODE (x
))
1243 fprintf (file
, "bior");
1246 fprintf (file
, "bixor");
1249 fprintf (file
, "biand");
1254 switch (GET_CODE (x
))
1257 fprintf (file
, "bcc");
1260 fprintf (file
, "bcs");
1267 switch (GET_CODE (x
))
1271 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1273 fprintf (file
, "%s", names_upper_extended
[REGNO (x
)]);
1276 x
= adj_offsettable_operand (x
, 0);
1277 print_operand (file
, x
, 0);
1280 fprintf (file
, "#%d", ((INTVAL (x
) >> 16) & 0xffff));
1286 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
1287 REAL_VALUE_TO_TARGET_SINGLE (rv
, val
);
1288 fprintf (file
, "#%d", ((val
>> 16) & 0xffff));
1297 switch (GET_CODE (x
))
1301 fprintf (file
, "%s", names_big
[REGNO (x
) + 1]);
1303 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1306 x
= adj_offsettable_operand (x
, 2);
1307 print_operand (file
, x
, 0);
1310 fprintf (file
, "#%d", INTVAL (x
) & 0xffff);
1316 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
1317 REAL_VALUE_TO_TARGET_SINGLE (rv
, val
);
1318 fprintf (file
, "#%d", (val
& 0xffff));
1326 switch (GET_CODE (x
))
1329 fprintf (file
, "bcc");
1332 fprintf (file
, "bcs");
1339 asm_fprintf (file
, cond_string (GET_CODE (x
)));
1342 asm_fprintf (file
, cond_string (reverse_condition (GET_CODE (x
))));
1345 if (GET_CODE (x
) == CONST_INT
)
1346 fprintf (file
, "#%d", (INTVAL (x
)) & 0xff);
1348 fprintf (file
, "%s", byte_reg (x
, 0));
1351 if (GET_CODE (x
) == CONST_INT
)
1352 fprintf (file
, "#%d", (INTVAL (x
) >> 8) & 0xff);
1354 fprintf (file
, "%s", byte_reg (x
, 1));
1357 if (GET_CODE (x
) != CONST_INT
)
1359 fprintf (file
, "%d", INTVAL (x
));
1362 if (GET_CODE (x
) == CONST_INT
)
1363 fprintf (file
, "#%d", INTVAL (x
) & 0xff);
1365 fprintf (file
, "%s",
1366 byte_reg (x
, TARGET_H8300
? 2 : 0));
1369 if (GET_CODE (x
) == CONST_INT
)
1370 fprintf (file
, "#%d", (INTVAL (x
) >> 8) & 0xff);
1372 fprintf (file
, "%s",
1373 byte_reg (x
, TARGET_H8300
? 3 : 1));
1376 if (GET_CODE (x
) == CONST_INT
)
1377 fprintf (file
, "#%d", (INTVAL (x
) >> 16) & 0xff);
1379 fprintf (file
, "%s", byte_reg (x
, 0));
1382 if (GET_CODE (x
) == CONST_INT
)
1383 fprintf (file
, "#%d", (INTVAL (x
) >> 24) & 0xff);
1385 fprintf (file
, "%s", byte_reg (x
, 1));
1390 switch (GET_CODE (x
))
1393 switch (GET_MODE (x
))
1396 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */
1397 fprintf (file
, "%s", byte_reg (x
, 0));
1398 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1399 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1403 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1407 fprintf (file
, "%s", names_extended
[REGNO (x
)]);
1415 fprintf (file
, "@");
1416 output_address (XEXP (x
, 0));
1418 /* If this is an 'R' operand (reference into the 8-bit
1419 area), then specify a symbolic address as "foo:8",
1420 otherwise if operand is still in eight bit section, use
1422 if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
1423 && SYMBOL_REF_FLAG (XEXP (x
, 0)))
1424 fprintf (file
, (code
== 'R' ? ":8" : ":16"));
1425 else if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
1426 && TINY_DATA_NAME_P (XSTR (XEXP (x
, 0), 0)))
1427 fprintf (file
, ":16");
1434 fprintf (file
, "#");
1435 print_operand_address (file
, x
);
1441 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
1442 REAL_VALUE_TO_TARGET_SINGLE (rv
, val
);
1443 fprintf (file
, "#%d", val
);
1450 /* Output assembly language output for the address ADDR to FILE. */
1453 print_operand_address (file
, addr
)
1457 switch (GET_CODE (addr
))
1460 fprintf (file
, "%s", h8_reg_names
[REGNO (addr
)]);
1464 fprintf (file
, "-%s", h8_reg_names
[REGNO (XEXP (addr
, 0))]);
1468 fprintf (file
, "%s+", h8_reg_names
[REGNO (XEXP (addr
, 0))]);
1472 fprintf (file
, "(");
1473 if (GET_CODE (XEXP (addr
, 0)) == REG
)
1476 print_operand_address (file
, XEXP (addr
, 1));
1477 fprintf (file
, ",");
1478 print_operand_address (file
, XEXP (addr
, 0));
1483 print_operand_address (file
, XEXP (addr
, 0));
1484 fprintf (file
, "+");
1485 print_operand_address (file
, XEXP (addr
, 1));
1487 fprintf (file
, ")");
1492 /* Since the h8/300 only has 16 bit pointers, negative values are also
1493 those >= 32768. This happens for example with pointer minus a
1494 constant. We don't want to turn (char *p - 2) into
1495 (char *p + 65534) because loop unrolling can build upon this
1496 (IE: char *p + 131068). */
1497 int n
= INTVAL (addr
);
1499 n
= (int) (short) n
;
1501 /* ??? Why the special case for -ve values? */
1502 fprintf (file
, "-%d", -n
);
1504 fprintf (file
, "%d", n
);
1509 output_addr_const (file
, addr
);
1514 /* Output all insn addresses and their sizes into the assembly language
1515 output file. This is helpful for debugging whether the length attributes
1516 in the md file are correct. This is not meant to be a user selectable
1520 final_prescan_insn (insn
, operand
, num_operands
)
1524 /* This holds the last insn address. */
1525 static int last_insn_address
= 0;
1527 int uid
= INSN_UID (insn
);
1529 if (TARGET_RTL_DUMP
)
1531 fprintf (asm_out_file
, "\n****************");
1532 print_rtl (asm_out_file
, PATTERN (insn
));
1533 fprintf (asm_out_file
, "\n");
1536 if (TARGET_ADDRESSES
)
1538 fprintf (asm_out_file
, "; 0x%x %d\n", insn_addresses
[uid
],
1539 insn_addresses
[uid
] - last_insn_address
);
1540 last_insn_address
= insn_addresses
[uid
];
1544 /* Prepare for an SI sized move. */
1550 rtx src
= operands
[1];
1551 rtx dst
= operands
[0];
1552 if (!reload_in_progress
&& !reload_completed
)
1554 if (!register_operand (dst
, GET_MODE (dst
)))
1556 rtx tmp
= gen_reg_rtx (GET_MODE (dst
));
1557 emit_move_insn (tmp
, src
);
1564 /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
1565 Define the offset between two registers, one to be eliminated, and the other
1566 its replacement, at the start of a routine. */
1569 initial_offset (from
, to
)
1573 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
1574 offset
= UNITS_PER_WORD
+ frame_pointer_needed
* UNITS_PER_WORD
;
1579 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1580 if (WORD_REG_USED (regno
))
1581 offset
+= UNITS_PER_WORD
;
1583 /* See the comments for get_frame_size. We need to round it up to
1586 offset
+= ((get_frame_size () + STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
1587 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
1589 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
1590 offset
+= UNITS_PER_WORD
; /* Skip saved PC */
1595 /* Update the condition code from the insn. */
1598 notice_update_cc (body
, insn
)
1602 switch (get_attr_cc (insn
))
1605 /* Insn does not affect CC at all. */
1609 /* Insn does not change CC, but the 0'th operand has been changed. */
1610 if (cc_status
.value1
!= 0
1611 && reg_overlap_mentioned_p (recog_operand
[0], cc_status
.value1
))
1612 cc_status
.value1
= 0;
1616 /* Insn sets the Z,N flags of CC to recog_operand[0].
1617 The V flag is unusable. The C flag may or may not be known but
1618 that's ok because alter_cond will change tests to use EQ/NE. */
1620 cc_status
.flags
|= CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
;
1621 cc_status
.value1
= recog_operand
[0];
1625 /* Insn sets the Z,N,V flags of CC to recog_operand[0].
1626 The C flag may or may not be known but that's ok because
1627 alter_cond will change tests to use EQ/NE. */
1629 cc_status
.flags
|= CC_NO_CARRY
;
1630 cc_status
.value1
= recog_operand
[0];
1634 /* The insn is a compare instruction. */
1636 cc_status
.value1
= SET_SRC (body
);
1640 /* Insn doesn't leave CC in a usable state. */
1646 /* Recognize valid operators for bit instructions */
1649 bit_operator (x
, mode
)
1651 enum machine_mode mode
;
1653 enum rtx_code code
= GET_CODE (x
);
1662 We devote a fair bit of code to getting efficient shifts since we can only
1663 shift one bit at a time on the H8/300 and H8/300H and only one or two
1664 bits at a time on the H8/S.
1666 The basic shift methods:
1668 * loop shifts -- emit a loop using one (or two on H8/S) bit shifts;
1669 this is the default. SHIFT_LOOP
1671 * inlined shifts -- emit straight line code for the shift; this is
1672 used when a straight line shift is about the same size or smaller
1673 than a loop. We allow the inline version to be slightly longer in
1674 some cases as it saves a register. SHIFT_INLINE
1676 * rotate + and -- rotate the value the opposite direction, then
1677 mask off the values we don't need. This is used when only a few
1678 of the bits in the original value will survive in the shifted value.
1679 Again, this is used when it's about the same size or smaller than
1680 a loop. We allow this version to be slightly longer as it is usually
1681 much faster than a loop. SHIFT_ROT_AND
1683 * swap (+ shifts) -- often it's possible to swap bytes/words to
1684 simulate a shift by 8/16. Once swapped a few inline shifts can be
1685 added if the shift count is slightly more than 8 or 16. This is used
1686 when it's about the same size or smaller than a loop. We allow this
1687 version to be slightly longer as it is usually much faster than a loop.
1690 * There other oddballs. Not worth explaining. SHIFT_SPECIAL
1693 Here are some thoughts on what the absolutely positively best code is.
1694 "Best" here means some rational trade-off between code size and speed,
1695 where speed is more preferred but not at the expense of generating 20 insns.
1697 A trailing '*' after the shift count indicates the "best" mode isn't
1700 H8/300 QImode shifts
1701 1-4 - do them inline
1702 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1704 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1705 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1707 H8/300 HImode shifts
1708 1-4 - do them inline
1710 7 - shift 2nd half other way into carry.
1711 copy 1st half into 2nd half
1712 rotate 2nd half other way with carry
1713 rotate 1st half other way (no carry)
1714 mask off bits in 1st half (ASHIFT | LSHIFTRT).
1715 sign extend 1st half (ASHIFTRT)
1716 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1717 9-12 - do shift by 8, inline remaining shifts
1718 13-14* - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1720 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1721 - ASHIFTRT: shll, subx, set other byte
1723 H8/300 SImode shifts
1724 1-2 - do them inline
1726 7* - shift other way once, move bytes into place,
1727 move carry into place (possibly with sign extension)
1728 8 - move bytes into place, zero or sign extend other
1730 15* - shift other way once, move word into place, move carry into place
1731 16 - move word, zero or sign extend other
1733 24* - move bytes into place, zero or sign extend other
1735 28-30* - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,
1738 31 - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,
1740 ASHIFTRT: shll top byte, subx, copy to other bytes
1742 H8/300H QImode shifts (same as H8/300 QImode shifts)
1743 1-4 - do them inline
1744 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1746 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1747 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1750 H8/300H HImode shifts
1751 1-4 - do them inline
1753 7 - shift 2nd half other way into carry.
1754 copy 1st half into 2nd half
1755 rotate entire word other way using carry
1756 mask off remaining bits (ASHIFT | LSHIFTRT)
1757 sign extend remaining bits (ASHIFTRT)
1758 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1759 9-12 - do shift by 8, inline remaining shifts
1760 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1762 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1763 - ASHIFTRT: shll, subx, set other byte
1765 H8/300H SImode shifts
1766 (These are complicated by the fact that we don't have byte level access to
1768 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1769 1-4 - do them inline
1771 15* - shift other way once, move word into place, move carry into place
1772 (with sign extension for ASHIFTRT)
1773 16 - move word into place, zero or sign extend other
1774 17-20 - do 16bit shift, then inline remaining shifts
1776 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1777 move word 0 to word 1, zero word 0
1778 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1779 zero word 1, zero byte 1
1780 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1781 sign extend byte 0, sign extend word 0
1782 25-27* - either loop, or
1783 do 24 bit shift, inline rest
1784 28-30 - ASHIFT: rotate 4/3/2, mask
1785 LSHIFTRT: rotate 4/3/2, mask
1787 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1790 1-6 - do them inline
1791 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1792 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1795 1-7 - do them inline
1796 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1797 9-12 - do shift by 8, inline remaining shifts
1798 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1800 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1801 - ASHIFTRT: shll, subx, set other byte
1804 (These are complicated by the fact that we don't have byte level access to
1806 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1807 1-10 - do them inline
1809 15* - shift other way once, move word into place, move carry into place
1810 (with sign extension for ASHIFTRT)
1811 16 - move word into place, zero or sign extend other
1812 17-20 - do 16bit shift, then inline remaining shifts
1814 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1815 move word 0 to word 1, zero word 0
1816 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1817 zero word 1, zero byte 1
1818 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1819 sign extend byte 0, sign extend word 0
1820 25-27* - either loop, or
1821 do 24 bit shift, inline rest
1822 28-30 - ASHIFT: rotate 4/3/2, mask
1823 LSHIFTRT: rotate 4/3/2, mask
1825 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1830 nshift_operator (x
, mode
)
1832 enum machine_mode mode
;
1834 switch (GET_CODE (x
))
1846 /* Called from the .md file to emit code to do shifts.
1847 Returns a boolean indicating success
1848 (currently this is always TRUE). */
1851 expand_a_shift (mode
, code
, operands
)
1852 enum machine_mode mode
;
1856 emit_move_insn (operands
[0], operands
[1]);
1858 /* need a loop to get all the bits we want - we generate the
1859 code at emit time, but need to allocate a scratch reg now */
1862 (PARALLEL
, VOIDmode
,
1864 gen_rtx (SET
, VOIDmode
, operands
[0],
1865 gen_rtx (code
, mode
, operands
[0], operands
[2])),
1866 gen_rtx (CLOBBER
, VOIDmode
, gen_rtx (SCRATCH
, QImode
, 0)))));
1871 /* Shift algorithm determination.
1873 There are various ways of doing a shift:
1874 SHIFT_INLINE: If the amount is small enough, just generate as many one-bit
1876 SHIFT_ROT_AND: If the amount is large but close to either end, rotate the
1877 necessary bits into position and then set the rest to zero.
1878 SHIFT_SPECIAL: Hand crafted assembler.
1879 SHIFT_LOOP: If the above methods fail, just loop. */
1890 /* Symbols of the various shifts which can be used as indices. */
1894 SHIFT_ASHIFT
, SHIFT_LSHIFTRT
, SHIFT_ASHIFTRT
1897 /* Symbols of the various modes which can be used as indices. */
1901 QIshift
, HIshift
, SIshift
1904 /* For single bit shift insns, record assembler and what bits of the
1905 condition code are valid afterwards (represented as various CC_FOO
1906 bits, 0 means CC isn't left in a usable state). */
1914 /* Assembler instruction shift table.
1916 These tables are used to look up the basic shifts.
1917 They are indexed by cpu, shift_type, and mode.
1920 static const struct shift_insn shift_one
[2][3][3] =
1926 { "shll\t%X0", CC_NO_CARRY
},
1927 { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1928 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }
1930 /* SHIFT_LSHIFTRT */
1932 { "shlr\t%X0", CC_NO_CARRY
},
1933 { "shlr\t%t0\n\trotxr\t%s0", 0 },
1934 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1936 /* SHIFT_ASHIFTRT */
1938 { "shar\t%X0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1939 { "shar\t%t0\n\trotxr\t%s0", 0 },
1940 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1947 { "shll.b\t%X0", CC_NO_CARRY
},
1948 { "shll.w\t%T0", CC_NO_CARRY
},
1949 { "shll.l\t%S0", CC_NO_CARRY
}
1951 /* SHIFT_LSHIFTRT */
1953 { "shlr.b\t%X0", CC_NO_CARRY
},
1954 { "shlr.w\t%T0", CC_NO_CARRY
},
1955 { "shlr.l\t%S0", CC_NO_CARRY
}
1957 /* SHIFT_ASHIFTRT */
1959 { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1960 { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1961 { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
}
1966 static const struct shift_insn shift_two
[3][3] =
1970 { "shll.b\t#2,%X0", CC_NO_CARRY
},
1971 { "shll.w\t#2,%T0", CC_NO_CARRY
},
1972 { "shll.l\t#2,%S0", CC_NO_CARRY
}
1974 /* SHIFT_LSHIFTRT */
1976 { "shlr.b\t#2,%X0", CC_NO_CARRY
},
1977 { "shlr.w\t#2,%T0", CC_NO_CARRY
},
1978 { "shlr.l\t#2,%S0", CC_NO_CARRY
}
1980 /* SHIFT_ASHIFTRT */
1982 { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1983 { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1984 { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
}
1988 /* Rotates are organized by which shift they'll be used in implementing.
1989 There's no need to record whether the cc is valid afterwards because
1990 it is the AND insn that will decide this. */
1992 static const char *const rotate_one
[2][3][3] =
1999 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
2002 /* SHIFT_LSHIFTRT */
2005 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
2008 /* SHIFT_ASHIFTRT */
2011 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
2023 /* SHIFT_LSHIFTRT */
2029 /* SHIFT_ASHIFTRT */
2038 static const char *const rotate_two
[3][3] =
2046 /* SHIFT_LSHIFTRT */
2052 /* SHIFT_ASHIFTRT */
2060 /* Given CPU, MODE, SHIFT_TYPE, and shift count COUNT, determine the best
2061 algorithm for doing the shift. The assembler code is stored in ASSEMBLER.
2062 We don't achieve maximum efficiency in all cases, but the hooks are here
2065 For now we just use lots of switch statements. Since we don't even come
2066 close to supporting all the cases, this is simplest. If this function ever
2067 gets too big, perhaps resort to a more table based lookup. Of course,
2068 at this point you may just wish to do it all in rtl.
2070 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
2071 1,2,3,4 will be inlined (1,2 for SI). */
2073 static enum shift_alg
2074 get_shift_alg (cpu
, shift_type
, mode
, count
, assembler_p
,
2075 assembler2_p
, cc_valid_p
)
2077 enum shift_type shift_type
;
2078 enum machine_mode mode
;
2080 const char **assembler_p
;
2081 const char **assembler2_p
;
2084 /* The default is to loop. */
2085 enum shift_alg alg
= SHIFT_LOOP
;
2086 enum shift_mode shift_mode
;
2088 /* We don't handle negative shifts or shifts greater than the word size,
2089 they should have been handled already. */
2091 if (count
< 0 || count
> GET_MODE_BITSIZE (mode
))
2097 shift_mode
= QIshift
;
2100 shift_mode
= HIshift
;
2103 shift_mode
= SIshift
;
2109 /* Assume either SHIFT_LOOP or SHIFT_INLINE.
2110 It is up to the caller to know that looping clobbers cc. */
2111 *assembler_p
= shift_one
[cpu
][shift_type
][shift_mode
].assembler
;
2113 *assembler2_p
= shift_two
[shift_type
][shift_mode
].assembler
;
2115 *assembler2_p
= NULL
;
2116 *cc_valid_p
= shift_one
[cpu
][shift_type
][shift_mode
].cc_valid
;
2118 /* Now look for cases we want to optimize. */
2124 return SHIFT_INLINE
;
2127 /* Shift by 5/6 are only 3 insns on the H8/S, so it's just as
2128 fast as SHIFT_ROT_AND, plus CC is valid. */
2129 if (TARGET_H8300S
&& count
<= 6)
2130 return SHIFT_INLINE
;
2132 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2133 through the entire value. */
2134 if (shift_type
== SHIFT_ASHIFTRT
&& count
== 7)
2136 *assembler_p
= "shll\t%X0\n\tsubx\t%X0,%X0";
2138 return SHIFT_SPECIAL
;
2141 /* Other ASHIFTRTs are too much of a pain. */
2142 if (shift_type
== SHIFT_ASHIFTRT
)
2145 /* Other shifts by 5, 6, or 7 bits use SHIFT_ROT_AND. */
2146 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2148 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2150 return SHIFT_ROT_AND
;
2155 return SHIFT_INLINE
;
2156 else if (TARGET_H8300S
&& count
<= 7)
2157 return SHIFT_INLINE
;
2158 else if (count
== 7)
2160 if (shift_type
== SHIFT_ASHIFT
&& TARGET_H8300
)
2162 *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";
2164 return SHIFT_SPECIAL
;
2167 if (shift_type
== SHIFT_ASHIFT
&& TARGET_H8300H
)
2169 *assembler_p
= "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
2171 return SHIFT_SPECIAL
;
2174 if (shift_type
== SHIFT_LSHIFTRT
&& TARGET_H8300
)
2176 *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";
2178 return SHIFT_SPECIAL
;
2181 if (shift_type
== SHIFT_LSHIFTRT
&& TARGET_H8300H
)
2183 *assembler_p
= "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
2185 return SHIFT_SPECIAL
;
2188 if (shift_type
== SHIFT_ASHIFTRT
)
2190 *assembler_p
= "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
2192 return SHIFT_SPECIAL
;
2195 else if (count
== 8)
2200 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
2202 return SHIFT_SPECIAL
;
2203 case SHIFT_LSHIFTRT
:
2204 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
2206 return SHIFT_SPECIAL
;
2207 case SHIFT_ASHIFTRT
:
2209 *assembler_p
= "mov.b\t%t0,%s0\n\tshll\t%t0\n\tsubx\t%t0,%t0\t";
2211 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0";
2213 return SHIFT_SPECIAL
;
2216 else if (count
== 9)
2221 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0";
2223 return SHIFT_SPECIAL
;
2224 case SHIFT_LSHIFTRT
:
2225 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0";
2227 return SHIFT_SPECIAL
;
2228 case SHIFT_ASHIFTRT
:
2230 *assembler_p
= "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0";
2232 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0";
2234 return SHIFT_SPECIAL
;
2237 else if (count
== 10)
2243 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\t";
2245 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0\n\tshal.b\t%t0";
2247 return SHIFT_SPECIAL
;
2248 case SHIFT_LSHIFTRT
:
2250 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0";
2252 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0\n\tshlr.b\t%s0";
2254 return SHIFT_SPECIAL
;
2255 case SHIFT_ASHIFTRT
:
2257 *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";
2258 else if (TARGET_H8300H
)
2259 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0\n\tshar.b\t%s0";
2260 else if (TARGET_H8300S
)
2261 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t#2,%s0";
2263 return SHIFT_SPECIAL
;
2266 else if (count
== 11)
2272 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\tshal.b\t%t0";
2274 *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";
2276 return SHIFT_SPECIAL
;
2277 case SHIFT_LSHIFTRT
:
2279 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0\n\tshlr.b\t%s0";
2281 *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";
2283 return SHIFT_SPECIAL
;
2284 case SHIFT_ASHIFTRT
:
2286 *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";
2287 else if (TARGET_H8300H
)
2288 *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";
2289 else if (TARGET_H8300S
)
2290 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t#2,%s0\n\tshar.b\t%s0";
2292 return SHIFT_SPECIAL
;
2295 else if (count
== 12)
2301 *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";
2303 *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";
2305 return SHIFT_SPECIAL
;
2306 case SHIFT_LSHIFTRT
:
2308 *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";
2310 *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";
2312 return SHIFT_SPECIAL
;
2313 case SHIFT_ASHIFTRT
:
2315 *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";
2316 else if (TARGET_H8300H
)
2317 *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";
2318 else if (TARGET_H8300S
)
2319 *assembler_p
= "mov.b\t%t0,%s0\n\textw.w\t%T0\n\tshar.b\t#2,%s0\n\tshar.b\t#2,%s0";
2321 return SHIFT_SPECIAL
;
2324 else if (!TARGET_H8300
&& (count
== 13 || count
== 14)
2327 if (count
== 15 && shift_type
== SHIFT_ASHIFTRT
)
2329 *assembler_p
= "shll\t%t0,%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
2331 return SHIFT_SPECIAL
;
2333 else if (shift_type
!= SHIFT_ASHIFTRT
)
2335 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2337 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2339 *assembler2_p
= NULL
;
2341 return SHIFT_ROT_AND
;
2347 if (count
<= (TARGET_H8300
? 2 : 4))
2348 return SHIFT_INLINE
;
2349 else if (TARGET_H8300S
&& count
<= 10)
2350 return SHIFT_INLINE
;
2351 else if (count
== 8 && TARGET_H8300
)
2356 *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";
2358 return SHIFT_SPECIAL
;
2359 case SHIFT_LSHIFTRT
:
2360 *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";
2362 return SHIFT_SPECIAL
;
2363 case SHIFT_ASHIFTRT
:
2364 *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";
2366 return SHIFT_SPECIAL
;
2369 else if (count
== 8 && !TARGET_H8300
)
2374 *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";
2376 return SHIFT_SPECIAL
;
2377 case SHIFT_LSHIFTRT
:
2378 *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";
2380 return SHIFT_SPECIAL
;
2381 case SHIFT_ASHIFTRT
:
2382 *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";
2384 return SHIFT_SPECIAL
;
2387 else if (count
== 16)
2392 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2394 return SHIFT_SPECIAL
;
2395 case SHIFT_LSHIFTRT
:
2396 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
2398 return SHIFT_SPECIAL
;
2399 case SHIFT_ASHIFTRT
:
2401 *assembler_p
= "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2403 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0";
2405 return SHIFT_SPECIAL
;
2408 else if (count
== 17 && !TARGET_H8300
)
2413 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0";
2415 return SHIFT_SPECIAL
;
2416 case SHIFT_LSHIFTRT
:
2417 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0";
2419 return SHIFT_SPECIAL
;
2420 case SHIFT_ASHIFTRT
:
2421 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0";
2423 return SHIFT_SPECIAL
;
2426 else if (count
== 18 && !TARGET_H8300
)
2432 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0";
2434 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0\n\tshll.l\t%S0";
2436 return SHIFT_SPECIAL
;
2437 case SHIFT_LSHIFTRT
:
2439 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0";
2441 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0\n\tshlr.l\t%S0";
2443 return SHIFT_SPECIAL
;
2444 case SHIFT_ASHIFTRT
:
2446 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0";
2448 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0\n\tshar.l\t%S0";
2450 return SHIFT_SPECIAL
;
2453 else if (count
== 19 && !TARGET_H8300
)
2459 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0\n\tshll.l\t%S0";
2461 *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";
2463 return SHIFT_SPECIAL
;
2464 case SHIFT_LSHIFTRT
:
2466 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0\n\tshlr.l\t%S0";
2468 *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";
2470 return SHIFT_SPECIAL
;
2471 case SHIFT_ASHIFTRT
:
2473 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0\n\tshar.l\t%S0";
2475 *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";
2477 return SHIFT_SPECIAL
;
2480 else if (count
== 20 && TARGET_H8300S
)
2485 *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";
2487 return SHIFT_SPECIAL
;
2488 case SHIFT_LSHIFTRT
:
2489 *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";
2491 return SHIFT_SPECIAL
;
2492 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#2,%S0";
2495 return SHIFT_SPECIAL
;
2498 else if (count
== 24 && !TARGET_H8300
)
2503 *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";
2505 return SHIFT_SPECIAL
;
2506 case SHIFT_LSHIFTRT
:
2507 *assembler_p
= "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
2509 return SHIFT_SPECIAL
;
2510 case SHIFT_ASHIFTRT
:
2511 *assembler_p
= "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
2513 return SHIFT_SPECIAL
;
2516 else if (count
>= 28 && count
<= 30 && !TARGET_H8300
)
2518 if (shift_type
== SHIFT_ASHIFTRT
)
2524 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2526 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2528 *assembler2_p
= NULL
;
2530 return SHIFT_ROT_AND
;
2533 else if (count
== 31)
2535 if (shift_type
== SHIFT_ASHIFTRT
)
2538 *assembler_p
= "shll\t%z0\n\tsubx %w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2540 *assembler_p
= "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2542 return SHIFT_SPECIAL
;
2548 if (shift_type
== SHIFT_ASHIFT
)
2549 *assembler_p
= "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2551 *assembler_p
= "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2553 return SHIFT_SPECIAL
;
2557 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2559 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2561 *assembler2_p
= NULL
;
2563 return SHIFT_ROT_AND
;
2576 /* Emit the assembler code for doing shifts. */
2579 emit_a_shift (insn
, operands
)
2583 static int loopend_lab
;
2587 rtx inside
= PATTERN (insn
);
2588 rtx shift
= operands
[3];
2589 enum machine_mode mode
= GET_MODE (shift
);
2590 enum rtx_code code
= GET_CODE (shift
);
2591 enum shift_type shift_type
;
2592 enum shift_mode shift_mode
;
2599 shift_mode
= QIshift
;
2602 shift_mode
= HIshift
;
2605 shift_mode
= SIshift
;
2614 shift_type
= SHIFT_ASHIFTRT
;
2617 shift_type
= SHIFT_LSHIFTRT
;
2620 shift_type
= SHIFT_ASHIFT
;
2626 if (GET_CODE (operands
[2]) != CONST_INT
)
2628 /* Indexing by reg, so have to loop and test at top */
2629 output_asm_insn ("mov.b %X2,%X4", operands
);
2630 fprintf (asm_out_file
, "\tble .Lle%d\n", loopend_lab
);
2632 /* Get the assembler code to do one shift. */
2633 get_shift_alg (cpu_type
, shift_type
, mode
, 1, &assembler
,
2634 &assembler2
, &cc_valid
);
2638 int n
= INTVAL (operands
[2]);
2641 /* If the count is negative, make it 0. */
2644 /* If the count is too big, truncate it.
2645 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2646 do the intuitive thing. */
2647 else if (n
> GET_MODE_BITSIZE (mode
))
2648 n
= GET_MODE_BITSIZE (mode
);
2650 alg
= get_shift_alg (cpu_type
, shift_type
, mode
, n
, &assembler
,
2651 &assembler2
, &cc_valid
);
2656 /* Emit two bit shifts first. */
2657 while (n
> 1 && assembler2
!= NULL
)
2659 output_asm_insn (assembler2
, operands
);
2663 /* Now emit one bit shifts for any residual. */
2666 output_asm_insn (assembler
, operands
);
2670 /* Keep track of CC. */
2673 cc_status
.value1
= operands
[0];
2674 cc_status
.flags
|= cc_valid
;
2680 int m
= GET_MODE_BITSIZE (mode
) - n
;
2681 int mask
= (shift_type
== SHIFT_ASHIFT
2682 ? ((1 << GET_MODE_BITSIZE (mode
) - n
) - 1) << n
2683 : (1 << GET_MODE_BITSIZE (mode
) - n
) - 1);
2685 /* Not all possibilities of rotate are supported. They shouldn't
2686 be generated, but let's watch for 'em. */
2690 /* Emit two bit rotates first. */
2691 while (m
> 1 && assembler2
!= NULL
)
2693 output_asm_insn (assembler2
, operands
);
2697 /* Now single bit rotates for any residual. */
2700 output_asm_insn (assembler
, operands
);
2704 /* Now mask off the high bits. */
2710 sprintf (insn_buf
, "and #%d,%%X0",
2712 cc_status
.value1
= operands
[0];
2713 cc_status
.flags
|= CC_NO_CARRY
;
2716 sprintf (insn_buf
, "and #%d,%%s0\n\tand #%d,%%t0",
2717 mask
& 255, mask
>> 8, n
);
2725 sprintf (insn_buf
, "and.%c #%d,%%%c0",
2726 "bwl"[shift_mode
], mask
,
2727 mode
== QImode
? 'X' : mode
== HImode
? 'T' : 'S');
2728 cc_status
.value1
= operands
[0];
2729 cc_status
.flags
|= CC_NO_CARRY
;
2731 output_asm_insn (insn_buf
, operands
);
2735 output_asm_insn (assembler
, operands
);
2739 /* A loop to shift by a "large" constant value.
2740 If we have shift-by-2 insns, use them. */
2741 if (assembler2
!= NULL
)
2743 fprintf (asm_out_file
, "\tmov.b #%d,%sl\n", n
/ 2,
2744 names_big
[REGNO (operands
[4])]);
2745 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
2746 output_asm_insn (assembler2
, operands
);
2747 output_asm_insn ("add #0xff,%X4", operands
);
2748 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
2750 output_asm_insn (assembler
, operands
);
2755 fprintf (asm_out_file
, "\tmov.b #%d,%sl\n", n
,
2756 names_big
[REGNO (operands
[4])]);
2757 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
2758 output_asm_insn (assembler
, operands
);
2759 output_asm_insn ("add #0xff,%X4", operands
);
2760 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
2765 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
2766 output_asm_insn (assembler
, operands
);
2767 output_asm_insn ("add #0xff,%X4", operands
);
2768 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
2769 fprintf (asm_out_file
, ".Lle%d:\n", loopend_lab
);
2774 /* Fix the operands of a gen_xxx so that it could become a bit
2778 fix_bit_operand (operands
, what
, type
)
2783 /* The bit_operand predicate accepts any memory during RTL generation, but
2784 only 'U' memory afterwards, so if this is a MEM operand, we must force
2785 it to be valid for 'U' by reloading the address. */
2787 if (GET_CODE (operands
[2]) == CONST_INT
)
2789 if (CONST_OK_FOR_LETTER_P (INTVAL (operands
[2]), what
))
2791 /* Ok to have a memory dest. */
2792 if (GET_CODE (operands
[0]) == MEM
&& !EXTRA_CONSTRAINT (operands
[0], 'U'))
2795 mem
= gen_rtx (MEM
, GET_MODE (operands
[0]),
2796 copy_to_mode_reg (Pmode
, XEXP (operands
[0], 0)));
2797 RTX_UNCHANGING_P (mem
) = RTX_UNCHANGING_P (operands
[0]);
2798 MEM_COPY_ATTRIBUTES (mem
, operands
[0]);
2802 if (GET_CODE (operands
[1]) == MEM
&& !EXTRA_CONSTRAINT (operands
[1], 'U'))
2805 mem
= gen_rtx (MEM
, GET_MODE (operands
[1]),
2806 copy_to_mode_reg (Pmode
, XEXP (operands
[1], 0)));
2807 RTX_UNCHANGING_P (mem
) = RTX_UNCHANGING_P (operands
[1]);
2808 MEM_COPY_ATTRIBUTES (mem
, operands
[0]);
2815 /* Dest and src op must be register. */
2817 operands
[1] = force_reg (QImode
, operands
[1]);
2819 rtx res
= gen_reg_rtx (QImode
);
2820 emit_insn (gen_rtx (SET
, VOIDmode
, res
, gen_rtx (type
, QImode
, operands
[1], operands
[2])));
2821 emit_insn (gen_rtx (SET
, VOIDmode
, operands
[0], res
));
2826 /* Return nonzero if FUNC is an interrupt function as specified
2827 by the "interrupt" attribute. */
2830 h8300_interrupt_function_p (func
)
2835 if (TREE_CODE (func
) != FUNCTION_DECL
)
2838 a
= lookup_attribute ("interrupt_handler", DECL_MACHINE_ATTRIBUTES (func
));
2839 return a
!= NULL_TREE
;
2842 /* Return nonzero if FUNC is an OS_Task function as specified
2843 by the "OS_Task" attribute. */
2846 h8300_os_task_function_p (func
)
2851 if (TREE_CODE (func
) != FUNCTION_DECL
)
2854 a
= lookup_attribute ("OS_Task", DECL_MACHINE_ATTRIBUTES (func
));
2855 return a
!= NULL_TREE
;
2858 /* Return nonzero if FUNC is a monitor function as specified
2859 by the "monitor" attribute. */
2862 h8300_monitor_function_p (func
)
2867 if (TREE_CODE (func
) != FUNCTION_DECL
)
2870 a
= lookup_attribute ("monitor", DECL_MACHINE_ATTRIBUTES (func
));
2871 return a
!= NULL_TREE
;
2874 /* Return nonzero if FUNC is a function that should be called
2875 through the function vector. */
2878 h8300_funcvec_function_p (func
)
2883 if (TREE_CODE (func
) != FUNCTION_DECL
)
2886 a
= lookup_attribute ("function_vector", DECL_MACHINE_ATTRIBUTES (func
));
2887 return a
!= NULL_TREE
;
2890 /* Return nonzero if DECL is a variable that's in the eight bit
2894 h8300_eightbit_data_p (decl
)
2899 if (TREE_CODE (decl
) != VAR_DECL
)
2902 a
= lookup_attribute ("eightbit_data", DECL_MACHINE_ATTRIBUTES (decl
));
2903 return a
!= NULL_TREE
;
2906 /* Return nonzero if DECL is a variable that's in the tiny
2910 h8300_tiny_data_p (decl
)
2915 if (TREE_CODE (decl
) != VAR_DECL
)
2918 a
= lookup_attribute ("tiny_data", DECL_MACHINE_ATTRIBUTES (decl
));
2919 return a
!= NULL_TREE
;
2922 /* Return nonzero if ATTR is a valid attribute for DECL.
2923 ATTRIBUTES are any existing attributes and ARGS are the arguments
2926 Supported attributes:
2928 interrupt_handler: output a prologue and epilogue suitable for an
2931 function_vector: This function should be called through the
2934 eightbit_data: This variable lives in the 8-bit data area and can
2935 be referenced with 8-bit absolute memory addresses.
2937 tiny_data: This variable lives in the tiny data area and can be
2938 referenced with 16-bit absolute memory references. */
2941 h8300_valid_machine_decl_attribute (decl
, attributes
, attr
, args
)
2947 if (args
!= NULL_TREE
)
2950 if (is_attribute_p ("interrupt_handler", attr
)
2951 || is_attribute_p ("OS_Task", attr
)
2952 || is_attribute_p ("monitor", attr
)
2953 || is_attribute_p ("function_vector", attr
))
2954 return TREE_CODE (decl
) == FUNCTION_DECL
;
2956 if (is_attribute_p ("eightbit_data", attr
)
2957 && (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
)))
2959 if (DECL_INITIAL (decl
) == NULL_TREE
)
2961 warning ("Only initialized variables can be placed into the 8-bit area.");
2964 DECL_SECTION_NAME (decl
) = build_string (7, ".eight");
2968 if (is_attribute_p ("tiny_data", attr
)
2969 && (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
)))
2971 if (DECL_INITIAL (decl
) == NULL_TREE
)
2973 warning ("Only initialized variables can be placed into the 8-bit area.");
2976 DECL_SECTION_NAME (decl
) = build_string (6, ".tiny");
2983 extern struct obstack
*saveable_obstack
;
2985 h8300_encode_label (decl
)
2988 char *str
= XSTR (XEXP (DECL_RTL (decl
), 0), 0);
2989 int len
= strlen (str
);
2992 newstr
= obstack_alloc (saveable_obstack
, len
+ 2);
2994 strcpy (newstr
+ 1, str
);
2996 XSTR (XEXP (DECL_RTL (decl
), 0), 0) = newstr
;
3000 output_simode_bld (bild
, log2
, operands
)
3005 /* Clear the destination register. */
3006 if (TARGET_H8300H
|| TARGET_H8300S
)
3007 output_asm_insn ("sub.l\t%S0,%S0", operands
);
3009 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands
);
3011 /* Get the bit number we want to load. */
3013 operands
[2] = GEN_INT (exact_log2 (INTVAL (operands
[2])));
3015 /* Now output the bit load or bit inverse load, and store it in
3018 output_asm_insn ("bild\t%Z2,%Y1\n\tbst\t#0,%w0", operands
);
3020 output_asm_insn ("bld\t%Z2,%Y1\n\tbst\t#0,%w0", operands
);
3026 /* Given INSN and its current length LENGTH, return the adjustment
3027 (in bytes) to correctly compute INSN's length.
3029 We use this to get the lengths of various memory references correct. */
3031 h8300_adjust_insn_length (insn
, length
)
3037 /* We must filter these ou before calling get_attr_adjust_length. */
3038 if (GET_CODE (PATTERN (insn
)) == USE
3039 || GET_CODE (PATTERN (insn
)) == CLOBBER
3040 || GET_CODE (PATTERN (insn
)) == SEQUENCE
3041 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
3042 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
3045 if (get_attr_adjust_length (insn
) == ADJUST_LENGTH_NO
)
3048 pat
= PATTERN (insn
);
3050 /* Adjust length for reg->mem and mem->reg copies. */
3051 if (GET_CODE (pat
) == SET
3052 && (GET_CODE (SET_SRC (pat
)) == MEM
3053 || GET_CODE (SET_DEST (pat
)) == MEM
))
3055 /* This insn might need a length adjustment. */
3058 if (GET_CODE (SET_SRC (pat
)) == MEM
)
3059 addr
= XEXP (SET_SRC (pat
), 0);
3061 addr
= XEXP (SET_DEST (pat
), 0);
3063 /* On the H8/300, only one adjustment is necessary; if the
3064 address mode is register indirect, then this insn is two
3065 bytes shorter than indicated in the machine description. */
3066 if (TARGET_H8300
&& GET_CODE (addr
) == REG
)
3069 /* On the H8/300H and H8/S, register indirect is 6 bytes shorter than
3070 indicated in the machine description. */
3071 if ((TARGET_H8300H
|| TARGET_H8300S
)
3072 && GET_CODE (addr
) == REG
)
3075 /* On the H8/300H and H8/300S, reg + d, for small displacements is 4
3076 bytes shorter than indicated in the machine description. */
3077 if ((TARGET_H8300H
|| TARGET_H8300S
)
3078 && GET_CODE (addr
) == PLUS
3079 && GET_CODE (XEXP (addr
, 0)) == REG
3080 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
3081 && INTVAL (XEXP (addr
, 1)) > -32768
3082 && INTVAL (XEXP (addr
, 1)) < 32767)
3085 /* On the H8/300H and H8/300S, abs:16 is two bytes shorter than the
3086 more general abs:24. */
3087 if ((TARGET_H8300H
|| TARGET_H8300S
)
3088 && GET_CODE (addr
) == SYMBOL_REF
3089 && TINY_DATA_NAME_P (XSTR (addr
, 0)))
3093 /* Loading some constants needs adjustment. */
3094 if (GET_CODE (pat
) == SET
3095 && GET_CODE (SET_SRC (pat
)) == CONST_INT
3096 && GET_MODE (SET_DEST (pat
)) == SImode
3097 && INTVAL (SET_SRC (pat
)) != 0)
3100 && ((INTVAL (SET_SRC (pat
)) & 0xffff) == 0
3101 || ((INTVAL (SET_SRC (pat
)) >> 16) & 0xffff) == 0))
3104 if (TARGET_H8300H
|| TARGET_H8300S
)
3106 int val
= INTVAL (SET_SRC (pat
));
3108 if (val
== (val
& 0xff)
3109 || val
== (val
& 0xff00))
3112 if (val
== -4 || val
== -2 || val
== -1)
3117 /* Shifts need various adjustments. */
3118 if (GET_CODE (pat
) == PARALLEL
3119 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
3120 && (GET_CODE (SET_SRC (XVECEXP (pat
, 0, 0))) == ASHIFTRT
3121 || GET_CODE (SET_SRC (XVECEXP (pat
, 0, 0))) == LSHIFTRT
3122 || GET_CODE (SET_SRC (XVECEXP (pat
, 0, 0))) == ASHIFT
))
3124 rtx src
= SET_SRC (XVECEXP (pat
, 0, 0));
3125 enum machine_mode mode
= GET_MODE (src
);
3128 if (GET_CODE (XEXP (src
, 1)) != CONST_INT
)
3131 shift
= INTVAL (XEXP (src
, 1));
3132 /* According to ANSI, negative shift is undefined. It is
3133 considered to be zero in this case (see function
3134 emit_a_shift above). */
3138 /* QImode shifts by small constants take one insn
3139 per shift. So the adjustment is 20 (md length) -
3141 if (mode
== QImode
&& shift
<= 4)
3142 return -(20 - shift
* 2);
3144 /* Similarly for HImode and SImode shifts by
3145 small constants on the H8/300H and H8/300S. */
3146 if ((TARGET_H8300H
|| TARGET_H8300S
)
3147 && (mode
== HImode
|| mode
== SImode
) && shift
<= 4)
3148 return -(20 - shift
* 2);
3150 /* HImode shifts by small constants for the H8/300. */
3151 if (mode
== HImode
&& shift
<= 4)
3152 return -(20 - (shift
* (GET_CODE (src
) == ASHIFT
? 2 : 4)));
3154 /* SImode shifts by small constants for the H8/300. */
3155 if (mode
== SImode
&& shift
<= 2)
3156 return -(20 - (shift
* (GET_CODE (src
) == ASHIFT
? 6 : 8)));
3158 /* XXX ??? Could check for more shift/rotate cases here. */