1 /* Subroutines for insn-output.c for Hitachi H8/300.
2 Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
3 Contributed by Steve Chamberlain (sac@cygnus.com),
4 Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
27 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
33 #include "insn-attr.h"
40 /* Forward declarations. */
41 void print_operand_address ();
44 static int h8300_interrupt_function_p
PROTO ((tree
));
45 static int h8300_monitor_function_p
PROTO ((tree
));
46 static int h8300_os_task_function_p
PROTO ((tree
));
48 /* CPU_TYPE, says what cpu we're compiling for. */
51 /* True if the current function is an interrupt handler
52 (either via #pragma or an attribute specification). */
53 int interrupt_handler
;
55 /* True if the current function is an OS Task
56 (via an attribute specification). */
59 /* True if the current function is a monitor
60 (via an attribute specification). */
63 /* True if a #pragma saveall has been seen for the current function. */
66 static char *names_big
[] =
67 {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7"};
69 static char *names_extended
[] =
70 {"er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"};
72 static char *names_upper_extended
[] =
73 {"e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"};
75 /* Points to one of the above. */
76 /* ??? The above could be put in an array indexed by CPU_TYPE. */
79 /* Various operations needed by the following, indexed by CPU_TYPE. */
81 static char *h8_push_ops
[2] =
83 static char *h8_pop_ops
[2] =
85 static char *h8_mov_ops
[2] =
88 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 char *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) \
129 || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno]) \
130 || (regs_ever_live[regno] & !call_used_regs[regno])))
132 /* Output assembly language to FILE for the operation OP with operand size
133 SIZE to adjust the stack pointer. */
136 dosize (file
, op
, size
)
141 /* On the h8300h and h8300s, for sizes <= 8 bytes it is as good or
142 better to use adds/subs insns rather than add.l/sub.l
143 with an immediate value. */
144 if (size
> 4 && size
<= 8 && (TARGET_H8300H
|| TARGET_H8300S
))
146 /* Crank the size down to <= 4 */
147 fprintf (file
, "\t%ss\t#%d,sp\n", op
, 4);
154 if (TARGET_H8300H
|| TARGET_H8300S
)
156 fprintf (file
, "\t%ss\t#%d,sp\n", op
, 4);
161 fprintf (file
, "\t%ss\t#%d,sp\n", op
, 2);
163 /* Fall through... */
166 fprintf (file
, "\t%ss\t#%d,sp\n", op
, size
);
174 if (current_function_needs_context
175 && strcmp (op
, "sub") == 0)
177 /* Egad. We don't have a temporary to hold the
178 size of the frame in the prologue! Just inline
179 the bastard since this shouldn't happen often. */
182 fprintf (file
, "\tsubs\t#2,sp\n");
187 fprintf (file
, "\tsubs\t#1,sp\n");
192 fprintf (file
, "\tmov.w\t#%d,r3\n\t%s.w\tr3,sp\n", size
, op
);
195 fprintf (file
, "\t%s\t#%d,sp\n", op
, size
);
201 /* Output assembly language code for the function prologue. */
202 static int push_order
[FIRST_PSEUDO_REGISTER
] =
203 {0, 1, 2, 3, 4, 5, 6, -1, -1, -1};
204 static int pop_order
[FIRST_PSEUDO_REGISTER
] =
205 {6, 5, 4, 3, 2, 1, 0, -1, -1, -1};
207 /* This is what the stack looks like after the prolog of
208 a function with a frame has been set up:
214 <saved registers> <- sp
216 This is what the stack looks like after the prolog of
217 a function which doesn't have a frame:
222 <saved registers> <- sp
226 function_prologue (file
, size
)
230 register int mask
= 0;
231 int fsize
= (size
+ STACK_BOUNDARY
/ 8 - 1) & -STACK_BOUNDARY
/ 8;
234 /* Note a function with the interrupt attribute and set interrupt_handler
236 if (h8300_interrupt_function_p (current_function_decl
))
237 interrupt_handler
= 1;
239 /* If the current function has the OS_Task attribute set, then
240 we have a naked prologue. */
241 if (h8300_os_task_function_p (current_function_decl
))
243 fprintf (file
, ";OS_Task prologue\n");
248 if (h8300_monitor_function_p (current_function_decl
))
250 /* My understanding of monitor functions is they act just
251 like interrupt functions, except the prologue must
253 fprintf (file
, ";monitor prologue\n");
254 interrupt_handler
= 1;
258 fprintf (file
, "\tsubs\t#2,sp\n");
259 fprintf (file
, "\tpush\tr0\n");
260 fprintf (file
, "\tstc\tccr,r0l\n");
261 fprintf (file
, "\torc\t#128,ccr\n");
262 fprintf (file
, "\tmov.b\tr0l,@(4,sp)\n");
266 fprintf (file
, "\tpush\ter0\n");
267 fprintf (file
, "\tstc\tccr,r0l\n");
268 fprintf (file
, "\torc\t#128,ccr\n");
269 fprintf (file
, "\tmov.b\tr0l,@(4,sp)\n");
273 if (frame_pointer_needed
)
276 fprintf (file
, "\t%s\t%s\n", h8_push_op
,
277 h8_reg_names
[FRAME_POINTER_REGNUM
]);
278 fprintf (file
, "\t%s\t%s,%s\n", h8_mov_op
,
279 h8_reg_names
[STACK_POINTER_REGNUM
],
280 h8_reg_names
[FRAME_POINTER_REGNUM
]);
283 /* leave room for locals */
284 dosize (file
, "sub", fsize
);
286 /* Push the rest of the registers */
287 for (idx
= 0; idx
< FIRST_PSEUDO_REGISTER
; idx
++)
289 int regno
= push_order
[idx
];
292 && WORD_REG_USED (regno
)
293 && (!frame_pointer_needed
|| regno
!= FRAME_POINTER_REGNUM
))
297 /* Try to push multiple registers. */
298 if (regno
== 0 || regno
== 4)
300 int second_regno
= push_order
[idx
+ 1];
301 int third_regno
= push_order
[idx
+ 2];
302 int fourth_regno
= push_order
[idx
+ 3];
304 if (fourth_regno
>= 0
305 && WORD_REG_USED (fourth_regno
)
306 && (!frame_pointer_needed
307 || fourth_regno
!= FRAME_POINTER_REGNUM
)
309 && WORD_REG_USED (third_regno
)
310 && (!frame_pointer_needed
311 || third_regno
!= FRAME_POINTER_REGNUM
)
313 && WORD_REG_USED (second_regno
)
314 && (!frame_pointer_needed
315 || second_regno
!= FRAME_POINTER_REGNUM
))
317 fprintf (file
, "\tstm.l %s-%s,@-sp\n",
319 h8_reg_names
[fourth_regno
]);
324 if (regno
== 0 || regno
== 4)
326 int second_regno
= push_order
[idx
+ 1];
327 int third_regno
= push_order
[idx
+ 2];
330 && WORD_REG_USED (third_regno
)
331 && (!frame_pointer_needed
332 || third_regno
!= FRAME_POINTER_REGNUM
)
334 && WORD_REG_USED (second_regno
)
335 && (!frame_pointer_needed
336 || second_regno
!= FRAME_POINTER_REGNUM
))
338 fprintf (file
, "\tstm.l %s-%s,@-sp\n",
340 h8_reg_names
[third_regno
]);
345 if (regno
== 0 || regno
== 2 || regno
== 4 || regno
== 6)
347 int second_regno
= push_order
[idx
+ 1];
349 if (second_regno
>= 0
350 && WORD_REG_USED (second_regno
)
351 && (!frame_pointer_needed
352 || second_regno
!= FRAME_POINTER_REGNUM
))
354 fprintf (file
, "\tstm.l %s-%s,@-sp\n",
356 h8_reg_names
[second_regno
]);
362 fprintf (file
, "\t%s\t%s\n", h8_push_op
, h8_reg_names
[regno
]);
367 /* Output assembly language code for the function epilogue. */
370 function_epilogue (file
, size
)
375 register int mask
= 0;
376 int fsize
= (size
+ STACK_BOUNDARY
/ 8 - 1) & -STACK_BOUNDARY
/ 8;
378 rtx insn
= get_last_insn ();
382 /* OS_Task epilogues are nearly naked -- they just have an
384 fprintf (file
, ";OS_task epilogue\n");
385 fprintf (file
, "\trts\n");
389 /* monitor epilogues are the same as interrupt function epilogues.
390 Just make a note that we're in an monitor epilogue. */
392 fprintf(file
, ";monitor epilogue\n");
394 /* If the last insn was a BARRIER, we don't have to write any code. */
395 if (GET_CODE (insn
) == NOTE
)
396 insn
= prev_nonnote_insn (insn
);
397 if (insn
&& GET_CODE (insn
) == BARRIER
)
400 /* Pop the saved registers. */
401 for (idx
= 0; idx
< FIRST_PSEUDO_REGISTER
; idx
++)
403 int regno
= pop_order
[idx
];
406 && WORD_REG_USED (regno
)
407 && (!frame_pointer_needed
|| regno
!= FRAME_POINTER_REGNUM
))
411 /* Try to pop multiple registers. */
412 if (regno
== 7 || regno
== 3)
414 int second_regno
= pop_order
[idx
+ 1];
415 int third_regno
= pop_order
[idx
+ 2];
416 int fourth_regno
= pop_order
[idx
+ 3];
418 if (fourth_regno
>= 0
419 && WORD_REG_USED (fourth_regno
)
420 && (!frame_pointer_needed
421 || fourth_regno
!= FRAME_POINTER_REGNUM
)
423 && WORD_REG_USED (third_regno
)
424 && (!frame_pointer_needed
425 || third_regno
!= FRAME_POINTER_REGNUM
)
427 && WORD_REG_USED (second_regno
)
428 && (!frame_pointer_needed
429 || second_regno
!= FRAME_POINTER_REGNUM
))
431 fprintf (file
, "\tldm.l @sp+,%s-%s\n",
432 h8_reg_names
[fourth_regno
],
433 h8_reg_names
[regno
]);
438 if (regno
== 6 || regno
== 2)
440 int second_regno
= pop_order
[idx
+ 1];
441 int third_regno
= pop_order
[idx
+ 2];
444 && WORD_REG_USED (third_regno
)
445 && (!frame_pointer_needed
446 || third_regno
!= FRAME_POINTER_REGNUM
)
448 && WORD_REG_USED (second_regno
)
449 && (!frame_pointer_needed
450 || second_regno
!= FRAME_POINTER_REGNUM
))
452 fprintf (file
, "\tldm.l @sp+,%s-%s\n",
453 h8_reg_names
[third_regno
],
454 h8_reg_names
[regno
]);
459 if (regno
== 7 || regno
== 5 || regno
== 3 || regno
== 1)
461 int second_regno
= pop_order
[idx
+ 1];
463 if (second_regno
>= 0
464 && WORD_REG_USED (second_regno
)
465 && (!frame_pointer_needed
466 || second_regno
!= FRAME_POINTER_REGNUM
))
468 fprintf (file
, "\tldm.l @sp+,%s-%s\n",
469 h8_reg_names
[second_regno
],
470 h8_reg_names
[regno
]);
476 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[regno
]);
480 /* deallocate locals */
481 dosize (file
, "add", fsize
);
483 /* pop frame pointer if we had one. */
484 if (frame_pointer_needed
)
485 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[FRAME_POINTER_REGNUM
]);
487 /* If this is a monitor function, there is one register still left on
490 fprintf (file
, "\t%s\t%s\n", h8_pop_op
, h8_reg_names
[0]);
492 if (interrupt_handler
)
493 fprintf (file
, "\trte\n");
495 fprintf (file
, "\trts\n");
498 interrupt_handler
= 0;
504 /* Output assembly code for the start of the file. */
506 asm_file_start (file
)
509 fprintf (file
, ";\tGCC For the Hitachi H8/300\n");
510 fprintf (file
, ";\tBy Hitachi America Ltd and Cygnus Support\n");
511 fprintf (file
, ";\trelease F-1\n");
513 fprintf (file
, "; -O%d\n", optimize
);
515 fprintf (file
, "\n\t.h8300h\n");
516 else if (TARGET_H8300S
)
517 fprintf (file
, "\n\t.h8300s\n");
519 fprintf (file
, "\n\n");
520 output_file_directive (file
, main_input_filename
);
523 /* Output assembly language code for the end of file. */
529 fprintf (file
, "\t.end\n");
532 /* Return true if VALUE is a valid constant for constraint 'P'.
533 IE: VALUE is a power of two <= 2**15. */
536 small_power_of_two (value
)
562 /* Return true if VALUE is a valid constant for constraint 'O', which
563 means that the constant would be ok to use as a bit for a bclr
570 return small_power_of_two ((~value
) & 0xff);
573 /* Return true is OP is a valid source operand for an integer move
577 general_operand_src (op
, mode
)
579 enum machine_mode mode
;
581 if (GET_CODE (op
) == MEM
&& GET_CODE (XEXP (op
, 0)) == POST_INC
)
583 return general_operand (op
, mode
);
586 /* Return true if OP is a valid destination operand for an integer move
590 general_operand_dst (op
, mode
)
592 enum machine_mode mode
;
594 if (GET_CODE (op
) == MEM
&& GET_CODE (XEXP (op
, 0)) == PRE_DEC
)
596 return general_operand (op
, mode
);
599 /* Return true if OP is a const valid for a bit clear instruction. */
602 o_operand (operand
, mode
)
604 enum machine_mode mode
;
606 return (GET_CODE (operand
) == CONST_INT
607 && CONST_OK_FOR_O (INTVAL (operand
)));
610 /* Return true if OP is a const valid for a bit set or bit xor instruction. */
613 p_operand (operand
, mode
)
615 enum machine_mode mode
;
617 return (GET_CODE (operand
) == CONST_INT
618 && CONST_OK_FOR_P (INTVAL (operand
)));
621 /* Return true if OP is a valid call operand. */
624 call_insn_operand (op
, mode
)
626 enum machine_mode mode
;
628 if (GET_CODE (op
) == MEM
)
630 rtx inside
= XEXP (op
, 0);
631 if (register_operand (inside
, Pmode
))
633 if (CONSTANT_ADDRESS_P (inside
))
640 adds_subs_operand (op
, mode
)
642 enum machine_mode mode
;
644 if (GET_CODE (op
) == CONST_INT
)
646 if (INTVAL (op
) <= 4 && INTVAL (op
) >= 0)
648 if (INTVAL (op
) >= -4 && INTVAL (op
) <= 0)
650 if ((TARGET_H8300H
|| TARGET_H8300S
)
652 && (INTVAL (op
) <= 8 && INTVAL (op
) >= 0))
654 if ((TARGET_H8300H
|| TARGET_H8300S
)
656 && (INTVAL (op
) >= -8 && INTVAL (op
) <= 0))
662 /* Return nonzero if op is an adds/subs operand which only requires
663 one insn to implement. It is assumed that OP is already an adds/subs
666 one_insn_adds_subs_operand (op
, mode
)
668 enum machine_mode mode
;
670 int val
= INTVAL (op
);
672 if (val
== 1 || val
== -1
673 || val
== 2 || val
== -2
674 || ((TARGET_H8300H
|| TARGET_H8300S
)
675 && (val
== 4 || val
== -4)))
681 output_adds_subs (operands
)
684 int val
= INTVAL (operands
[2]);
686 /* First get the value into the range -4..4 inclusive.
688 The only way it can be out of this range is when TARGET_H8300H
689 or TARGET_H8300S is true, thus it is safe to use adds #4 and subs #4. */
692 output_asm_insn ("adds #4,%A0", operands
);
698 output_asm_insn ("subs #4,%A0", operands
);
702 /* Handle case were val == 4 or val == -4 and we're compiling
703 for TARGET_H8300H or TARGET_H8300S. */
704 if ((TARGET_H8300H
|| TARGET_H8300S
)
706 return "adds #4,%A0";
708 if ((TARGET_H8300H
|| TARGET_H8300S
)
710 return "subs #4,%A0";
714 output_asm_insn ("adds #2,%A0", operands
);
720 output_asm_insn ("subs #2,%A0", operands
);
724 /* val should be one or two now. */
726 return "adds #2,%A0";
729 return "subs #2,%A0";
731 /* val should be one now. */
733 return "adds #1,%A0";
736 return "subs #1,%A0";
738 /* If not optimizing, we might be asked to add 0. */
742 /* In theory, this can't happen. */
746 /* Return true if OP is a valid call operand, and OP represents
747 an operand for a small call (4 bytes instead of 6 bytes). */
750 small_call_insn_operand (op
, mode
)
752 enum machine_mode mode
;
754 if (GET_CODE (op
) == MEM
)
756 rtx inside
= XEXP (op
, 0);
758 /* Register indirect is a small call. */
759 if (register_operand (inside
, Pmode
))
762 /* A call through the function vector is a small
764 if (GET_CODE (inside
) == SYMBOL_REF
765 && SYMBOL_REF_FLAG (inside
))
768 /* Otherwise it's a large call. */
772 /* Return true if OP is a valid jump operand. */
775 jump_address_operand (op
, mode
)
777 enum machine_mode mode
;
779 if (GET_CODE (op
) == REG
)
780 return mode
== Pmode
;
782 if (GET_CODE (op
) == MEM
)
784 rtx inside
= XEXP (op
, 0);
785 if (register_operand (inside
, Pmode
))
787 if (CONSTANT_ADDRESS_P (inside
))
793 /* Recognize valid operands for bitfield instructions. */
795 extern int rtx_equal_function_value_matters
;
798 bit_operand (op
, mode
)
800 enum machine_mode mode
;
802 /* We can except any general operand, expept that MEM operands must
803 be limited to those that use addresses valid for the 'U' constraint. */
804 if (!general_operand (op
, mode
))
807 /* Accept any mem during RTL generation. Otherwise, the code that does
808 insv and extzv will think that we can not handle memory. However,
809 to avoid reload problems, we only accept 'U' MEM operands after RTL
810 generation. This means that any named pattern which uses this predicate
811 must force its operands to match 'U' before emitting RTL. */
813 if (GET_CODE (op
) == REG
)
815 if (GET_CODE (op
) == SUBREG
)
817 if (!rtx_equal_function_value_matters
)
819 /* We're building rtl */
820 return GET_CODE (op
) == MEM
;
824 return (GET_CODE (op
) == MEM
825 && EXTRA_CONSTRAINT (op
, 'U'));
830 bit_memory_operand (op
, mode
)
832 enum machine_mode mode
;
834 return (GET_CODE (op
) == MEM
835 && EXTRA_CONSTRAINT (op
, 'U'));
838 /* Recognize valid operators for bit test. */
841 eq_operator (x
, mode
)
843 enum machine_mode mode
;
845 return (GET_CODE (x
) == EQ
|| GET_CODE (x
) == NE
);
848 /* Handle machine specific pragmas for compatibility with existing
849 compilers for the H8/300.
851 pragma saveall generates prolog/epilog code which saves and
852 restores all the registers on function entry.
854 pragma interrupt saves and restores all registers, and exits with
855 an rte instruction rather than an rts. A pointer to a function
856 with this attribute may be safely used in an interrupt vector. */
859 handle_pragma (file
, t
)
864 register char *pname
;
866 if (TREE_CODE (t
) != IDENTIFIER_NODE
)
869 pname
= IDENTIFIER_POINTER (t
);
870 if (strcmp (pname
, "interrupt") == 0)
871 interrupt_handler
= retval
= 1;
872 else if (strcmp (pname
, "saveall") == 0)
873 pragma_saveall
= retval
= 1;
878 /* If the next arg with MODE and TYPE is to be passed in a register, return
879 the rtx to represent where it is passed. CUM represents the state after
880 the last argument. NAMED is not used. */
882 static char *hand_list
[] =
902 /* Return an RTX to represent where a value with mode MODE will be returned
903 from a function. If the result is 0, the argument is pushed. */
906 function_arg (cum
, mode
, type
, named
)
907 CUMULATIVE_ARGS
*cum
;
908 enum machine_mode mode
;
916 /* Never pass unnamed arguments in registers. */
920 /* Pass 3 regs worth of data in regs when user asked on the command line. */
921 if (TARGET_QUICKCALL
)
924 /* If calling hand written assembler, use 4 regs of args. */
930 fname
= XSTR (cum
->libcall
, 0);
932 /* See if this libcall is one of the hand coded ones. */
934 for (p
= hand_list
; *p
&& strcmp (*p
, fname
) != 0; p
++)
946 size
= int_size_in_bytes (type
);
948 size
= GET_MODE_SIZE (mode
);
950 if (size
+ cum
->nbytes
> regpass
* UNITS_PER_WORD
)
956 switch (cum
->nbytes
/ UNITS_PER_WORD
)
959 result
= gen_rtx (REG
, mode
, 0);
962 result
= gen_rtx (REG
, mode
, 1);
965 result
= gen_rtx (REG
, mode
, 2);
968 result
= gen_rtx (REG
, mode
, 3);
979 /* Return the cost of the rtx R with code CODE. */
999 if (TARGET_H8300H
|| TARGET_H8300S
)
1020 /* Documentation for the machine specific operand escapes:
1022 'A' print rn in h8/300 mode, erN in H8/300H mode
1023 'C' print (operand - 2).
1024 'E' like s but negative.
1025 'F' like t but negative.
1026 'G' constant just the negative
1027 'M' turn a 'M' constant into its negative mod 2.
1028 'P' if operand is incing/decing sp, print .w, otherwise .b.
1029 'R' print operand as a byte:8 address if appropriate, else fall back to
1031 'S' print operand as a long word
1032 'T' print operand as a word
1033 'U' if operand is incing/decing sp, print l, otherwise nothing.
1034 'V' find the set bit, and print its number.
1035 'W' find the clear bit, and print its number.
1036 'X' print operand as a byte
1037 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
1038 If this operand isn't a register, fall back to 'R' handling.
1040 'b' print the bit opcode
1041 'c' print the ibit opcode
1042 'd' bcc if EQ, bcs if NE
1043 'e' first word of 32 bit value - if reg, then least reg. if mem
1044 then least. if const then most sig word
1045 'f' second word of 32 bit value - if reg, then biggest reg. if mem
1046 then +2. if const then least sig word
1047 'g' bcs if EQ, bcc if NE
1048 'j' print operand as condition code.
1049 'k' print operand as reverse condition code.
1050 's' print as low byte of 16 bit value
1051 't' print as high byte of 16 bit value
1052 'w' print as low byte of 32 bit value
1053 'x' print as 2nd byte of 32 bit value
1054 'y' print as 3rd byte of 32 bit value
1055 'z' print as msb of 32 bit value
1058 /* Return assembly language string which identifies a comparison type. */
1091 /* Print operand X using operand code CODE to assembly language output file
1095 print_operand (file
, x
, code
)
1100 /* This is used for communication between the 'P' and 'U' codes. */
1101 static char *last_p
;
1103 /* This is used for communication between codes V,W,Z and Y. */
1109 if (GET_CODE (x
) == REG
)
1110 fprintf (file
, "%s", h8_reg_names
[REGNO (x
)]);
1115 fprintf (file
, "#%d", INTVAL (x
) - 2);
1118 switch (GET_CODE (x
))
1121 fprintf (file
, "%sl", names_big
[REGNO (x
)]);
1124 fprintf (file
, "#%d", (-INTVAL (x
)) & 0xff);
1131 switch (GET_CODE (x
))
1134 fprintf (file
, "%sh", names_big
[REGNO (x
)]);
1137 fprintf (file
, "#%d", ((-INTVAL (x
)) & 0xff00) >> 8);
1144 if (GET_CODE (x
) != CONST_INT
)
1146 fprintf (file
, "#%d", 0xff & (-INTVAL (x
)));
1149 /* For 3/-3 and 4/-4, the other 2 is handled separately. */
1156 fprintf (file
, "#2");
1162 fprintf (file
, "#1");
1169 if (REGNO (XEXP (XEXP (x
, 0), 0)) == STACK_POINTER_REGNUM
)
1172 fprintf (file
, ".w");
1177 fprintf (file
, ".b");
1181 if (GET_CODE (x
) == REG
)
1182 fprintf (file
, "%s", names_extended
[REGNO (x
)]);
1187 if (GET_CODE (x
) == REG
)
1188 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1193 fprintf (file
, "%s%s", names_big
[REGNO (x
)], last_p
);
1196 bitint
= exact_log2 (INTVAL (x
));
1199 fprintf (file
, "#%d", bitint
& 7);
1202 bitint
= exact_log2 ((~INTVAL (x
)) & 0xff);
1205 fprintf (file
, "#%d", bitint
& 7);
1209 if (GET_CODE (x
) == REG
)
1210 fprintf (file
, "%s", byte_reg (x
, 0));
1217 if (GET_CODE (x
) == REG
)
1218 fprintf (file
, "%s%c", names_big
[REGNO (x
)], bitint
> 7 ? 'h' : 'l');
1220 print_operand (file
, x
, 'R');
1224 bitint
= INTVAL (x
);
1225 fprintf (file
, "#%d", bitint
& 7);
1228 switch (GET_CODE (x
))
1231 fprintf (file
, "bor");
1234 fprintf (file
, "bxor");
1237 fprintf (file
, "band");
1242 switch (GET_CODE (x
))
1245 fprintf (file
, "bior");
1248 fprintf (file
, "bixor");
1251 fprintf (file
, "biand");
1256 switch (GET_CODE (x
))
1259 fprintf (file
, "bcc");
1262 fprintf (file
, "bcs");
1269 switch (GET_CODE (x
))
1273 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1275 fprintf (file
, "%s", names_upper_extended
[REGNO (x
)]);
1278 x
= adj_offsettable_operand (x
, 0);
1279 print_operand (file
, x
, 0);
1282 fprintf (file
, "#%d", ((INTVAL (x
) >> 16) & 0xffff));
1288 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
1289 REAL_VALUE_TO_TARGET_SINGLE (rv
, val
);
1290 fprintf (file
, "#%d", ((val
>> 16) & 0xffff));
1299 switch (GET_CODE (x
))
1303 fprintf (file
, "%s", names_big
[REGNO (x
) + 1]);
1305 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1308 x
= adj_offsettable_operand (x
, 2);
1309 print_operand (file
, x
, 0);
1312 fprintf (file
, "#%d", INTVAL (x
) & 0xffff);
1318 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
1319 REAL_VALUE_TO_TARGET_SINGLE (rv
, val
);
1320 fprintf (file
, "#%d", (val
& 0xffff));
1328 switch (GET_CODE (x
))
1331 fprintf (file
, "bcc");
1334 fprintf (file
, "bcs");
1341 asm_fprintf (file
, cond_string (GET_CODE (x
)));
1344 asm_fprintf (file
, cond_string (reverse_condition (GET_CODE (x
))));
1347 if (GET_CODE (x
) == CONST_INT
)
1348 fprintf (file
, "#%d", (INTVAL (x
)) & 0xff);
1350 fprintf (file
, "%s", byte_reg (x
, 0));
1353 if (GET_CODE (x
) == CONST_INT
)
1354 fprintf (file
, "#%d", (INTVAL (x
) >> 8) & 0xff);
1356 fprintf (file
, "%s", byte_reg (x
, 1));
1359 if (GET_CODE (x
) != CONST_INT
)
1361 fprintf (file
, "%d", INTVAL (x
));
1364 if (GET_CODE (x
) == CONST_INT
)
1365 fprintf (file
, "#%d", INTVAL (x
) & 0xff);
1367 fprintf (file
, "%s",
1368 byte_reg (x
, TARGET_H8300
? 2 : 0));
1371 if (GET_CODE (x
) == CONST_INT
)
1372 fprintf (file
, "#%d", (INTVAL (x
) >> 8) & 0xff);
1374 fprintf (file
, "%s",
1375 byte_reg (x
, TARGET_H8300
? 3 : 1));
1378 if (GET_CODE (x
) == CONST_INT
)
1379 fprintf (file
, "#%d", (INTVAL (x
) >> 16) & 0xff);
1381 fprintf (file
, "%s", byte_reg (x
, 0));
1384 if (GET_CODE (x
) == CONST_INT
)
1385 fprintf (file
, "#%d", (INTVAL (x
) >> 24) & 0xff);
1387 fprintf (file
, "%s", byte_reg (x
, 1));
1392 switch (GET_CODE (x
))
1395 switch (GET_MODE (x
))
1398 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */
1399 fprintf (file
, "%s", byte_reg (x
, 0));
1400 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1401 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1405 fprintf (file
, "%s", names_big
[REGNO (x
)]);
1409 fprintf (file
, "%s", names_extended
[REGNO (x
)]);
1417 fprintf (file
, "@");
1418 output_address (XEXP (x
, 0));
1420 /* If this is an 'R' operand (reference into the 8-bit area),
1421 then specify a symbolic address as "foo:8". */
1423 && GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
1424 && SYMBOL_REF_FLAG (XEXP (x
, 0)))
1425 fprintf (file
, ":8");
1426 if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
1427 && TINY_DATA_NAME_P (XSTR (XEXP (x
, 0), 0)))
1428 fprintf (file
, ":16");
1435 fprintf (file
, "#");
1436 print_operand_address (file
, x
);
1442 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
1443 REAL_VALUE_TO_TARGET_SINGLE (rv
, val
);
1444 fprintf (file
, "#%d", val
);
1451 /* Output assembly language output for the address ADDR to FILE. */
1454 print_operand_address (file
, addr
)
1458 switch (GET_CODE (addr
))
1461 fprintf (file
, "%s", h8_reg_names
[REGNO (addr
)]);
1465 fprintf (file
, "-%s", h8_reg_names
[REGNO (XEXP (addr
, 0))]);
1469 fprintf (file
, "%s+", h8_reg_names
[REGNO (XEXP (addr
, 0))]);
1473 fprintf (file
, "(");
1474 if (GET_CODE (XEXP (addr
, 0)) == REG
)
1477 print_operand_address (file
, XEXP (addr
, 1));
1478 fprintf (file
, ",");
1479 print_operand_address (file
, XEXP (addr
, 0));
1484 print_operand_address (file
, XEXP (addr
, 0));
1485 fprintf (file
, "+");
1486 print_operand_address (file
, XEXP (addr
, 1));
1488 fprintf (file
, ")");
1493 /* Since the h8/300 only has 16 bit pointers, negative values are also
1494 those >= 32768. This happens for example with pointer minus a
1495 constant. We don't want to turn (char *p - 2) into
1496 (char *p + 65534) because loop unrolling can build upon this
1497 (IE: char *p + 131068). */
1498 int n
= INTVAL (addr
);
1500 n
= (int) (short) n
;
1502 /* ??? Why the special case for -ve values? */
1503 fprintf (file
, "-%d", -n
);
1505 fprintf (file
, "%d", n
);
1510 output_addr_const (file
, addr
);
1515 /* Output all insn addresses and their sizes into the assembly language
1516 output file. This is helpful for debugging whether the length attributes
1517 in the md file are correct. This is not meant to be a user selectable
1521 final_prescan_insn (insn
, operand
, num_operands
)
1525 /* This holds the last insn address. */
1526 static int last_insn_address
= 0;
1528 int uid
= INSN_UID (insn
);
1530 if (TARGET_RTL_DUMP
)
1532 fprintf (asm_out_file
, "\n****************");
1533 print_rtl (asm_out_file
, PATTERN (insn
));
1534 fprintf (asm_out_file
, "\n");
1537 if (TARGET_ADDRESSES
)
1539 fprintf (asm_out_file
, "; 0x%x %d\n", insn_addresses
[uid
],
1540 insn_addresses
[uid
] - last_insn_address
);
1541 last_insn_address
= insn_addresses
[uid
];
1545 /* Prepare for an SI sized move. */
1551 rtx src
= operands
[1];
1552 rtx dst
= operands
[0];
1553 if (!reload_in_progress
&& !reload_completed
)
1555 if (!register_operand (dst
, GET_MODE (dst
)))
1557 rtx tmp
= gen_reg_rtx (GET_MODE (dst
));
1558 emit_move_insn (tmp
, src
);
1565 /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
1566 Define the offset between two registers, one to be eliminated, and the other
1567 its replacement, at the start of a routine. */
1570 initial_offset (from
, to
)
1574 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
1575 offset
= UNITS_PER_WORD
+ frame_pointer_needed
* UNITS_PER_WORD
;
1580 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1581 if ((regs_ever_live
[regno
]
1582 && (!call_used_regs
[regno
] || regno
== FRAME_POINTER_REGNUM
)))
1583 offset
+= UNITS_PER_WORD
;
1585 /* See the comments for get_frame_size. We need to round it up to
1588 offset
+= ((get_frame_size () + STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
1589 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
1591 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
1592 offset
+= UNITS_PER_WORD
; /* Skip saved PC */
1597 /* Update the condition code from the insn. */
1600 notice_update_cc (body
, insn
)
1604 switch (get_attr_cc (insn
))
1607 /* Insn does not affect CC at all. */
1611 /* Insn does not change CC, but the 0'th operand has been changed. */
1612 if (cc_status
.value1
!= 0
1613 && reg_overlap_mentioned_p (recog_operand
[0], cc_status
.value1
))
1614 cc_status
.value1
= 0;
1618 /* Insn sets the Z,N flags of CC to recog_operand[0].
1619 The V flag is unusable. The C flag may or may not be known but
1620 that's ok because alter_cond will change tests to use EQ/NE. */
1622 cc_status
.flags
|= CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
;
1623 cc_status
.value1
= recog_operand
[0];
1627 /* Insn sets the Z,N,V flags of CC to recog_operand[0].
1628 The C flag may or may not be known but that's ok because
1629 alter_cond will change tests to use EQ/NE. */
1631 cc_status
.flags
|= CC_NO_CARRY
;
1632 cc_status
.value1
= recog_operand
[0];
1636 /* The insn is a compare instruction. */
1638 cc_status
.value1
= SET_SRC (body
);
1642 /* Insn doesn't leave CC in a usable state. */
1648 /* Recognize valid operators for bit instructions */
1651 bit_operator (x
, mode
)
1653 enum machine_mode mode
;
1655 enum rtx_code code
= GET_CODE (x
);
1664 We devote a fair bit of code to getting efficient shifts since we can only
1665 shift one bit at a time on the H8/300 and H8/300H and only one or two
1666 bits at a time on the H8/S.
1668 The basic shift methods:
1670 * loop shifts -- emit a loop using one (or two on H8/S) bit shifts;
1671 this is the default. SHIFT_LOOP
1673 * inlined shifts -- emit straight line code for the shift; this is
1674 used when a straight line shift is about the same size or smaller
1675 than a loop. We allow the inline version to be slightly longer in
1676 some cases as it saves a register. SHIFT_INLINE
1678 * rotate + and -- rotate the value the opposite direction, then
1679 mask off the values we don't need. This is used when only a few
1680 of the bits in the original value will survive in the shifted value.
1681 Again, this is used when it's about the same size or smaller than
1682 a loop. We allow this version to be slightly longer as it is usually
1683 much faster than a loop. SHIFT_ROT_AND
1685 * swap (+ shifts) -- often it's possible to swap bytes/words to
1686 simulate a shift by 8/16. Once swapped a few inline shifts can be
1687 added if the shift count is slightly more than 8 or 16. This is used
1688 when it's about the same size or smaller than a loop. We allow this
1689 version to be slightly longer as it is usually much faster than a loop.
1692 * There other oddballs. Not worth explaining. SHIFT_SPECIAL
1695 Here are some thoughts on what the absolutely positively best code is.
1696 "Best" here means some rational trade-off between code size and speed,
1697 where speed is more preferred but not at the expense of generating 20 insns.
1699 A trailing '*' after the shift count indicates the "best" mode isn't
1702 H8/300 QImode shifts
1703 1-4 - do them inline
1704 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1706 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1707 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1709 H8/300 HImode shifts
1710 1-4 - do them inline
1712 7 - shift 2nd half other way into carry.
1713 copy 1st half into 2nd half
1714 rotate 2nd half other way with carry
1715 rotate 1st half other way (no carry)
1716 mask off bits in 1st half (ASHIFT | LSHIFTRT).
1717 sign extend 1st half (ASHIFTRT)
1718 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1719 9-12 - do shift by 8, inline remaining shifts
1720 13-14* - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1722 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1723 - ASHIFTRT: shll, subx, set other byte
1725 H8/300 SImode shifts
1726 1-2 - do them inline
1728 7* - shift other way once, move bytes into place,
1729 move carry into place (possibly with sign extension)
1730 8 - move bytes into place, zero or sign extend other
1732 15* - shift other way once, move word into place, move carry into place
1733 16 - move word, zero or sign extend other
1735 24* - move bytes into place, zero or sign extend other
1737 28-30* - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,
1740 31 - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,
1742 ASHIFTRT: shll top byte, subx, copy to other bytes
1744 H8/300H QImode shifts (same as H8/300 QImode shifts)
1745 1-4 - do them inline
1746 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1748 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1749 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1752 H8/300H HImode shifts
1753 1-4 - do them inline
1755 7 - shift 2nd half other way into carry.
1756 copy 1st half into 2nd half
1757 rotate entire word other way using carry
1758 mask off remaining bits (ASHIFT | LSHIFTRT)
1759 sign extend remaining bits (ASHIFTRT)
1760 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1761 9-12 - do shift by 8, inline remaining shifts
1762 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1764 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1765 - ASHIFTRT: shll, subx, set other byte
1767 H8/300H SImode shifts
1768 (These are complicated by the fact that we don't have byte level access to
1770 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1771 1-4 - do them inline
1773 15* - shift other way once, move word into place, move carry into place
1774 (with sign extension for ASHIFTRT)
1775 16 - move word into place, zero or sign extend other
1776 17-20 - do 16bit shift, then inline remaining shifts
1778 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1779 move word 0 to word 1, zero word 0
1780 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1781 zero word 1, zero byte 1
1782 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1783 sign extend byte 0, sign extend word 0
1784 25-27* - either loop, or
1785 do 24 bit shift, inline rest
1786 28-30 - ASHIFT: rotate 4/3/2, mask
1787 LSHIFTRT: rotate 4/3/2, mask
1789 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1792 1-6 - do them inline
1793 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1794 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1797 1-7 - do them inline
1798 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1799 9-12 - do shift by 8, inline remaining shifts
1800 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1802 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1803 - ASHIFTRT: shll, subx, set other byte
1806 (These are complicated by the fact that we don't have byte level access to
1808 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1809 1-10 - do them inline
1811 15* - shift other way once, move word into place, move carry into place
1812 (with sign extension for ASHIFTRT)
1813 16 - move word into place, zero or sign extend other
1814 17-20 - do 16bit shift, then inline remaining shifts
1816 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1817 move word 0 to word 1, zero word 0
1818 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1819 zero word 1, zero byte 1
1820 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1821 sign extend byte 0, sign extend word 0
1822 25-27* - either loop, or
1823 do 24 bit shift, inline rest
1824 28-30 - ASHIFT: rotate 4/3/2, mask
1825 LSHIFTRT: rotate 4/3/2, mask
1827 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1832 nshift_operator (x
, mode
)
1834 enum machine_mode mode
;
1836 switch (GET_CODE (x
))
1848 /* Called from the .md file to emit code to do shifts.
1849 Returns a boolean indicating success
1850 (currently this is always TRUE). */
1853 expand_a_shift (mode
, code
, operands
)
1854 enum machine_mode mode
;
1858 emit_move_insn (operands
[0], operands
[1]);
1860 /* need a loop to get all the bits we want - we generate the
1861 code at emit time, but need to allocate a scratch reg now */
1864 (PARALLEL
, VOIDmode
,
1866 gen_rtx (SET
, VOIDmode
, operands
[0],
1867 gen_rtx (code
, mode
, operands
[0], operands
[2])),
1868 gen_rtx (CLOBBER
, VOIDmode
, gen_rtx (SCRATCH
, QImode
, 0)))));
1873 /* Shift algorithm determination.
1875 There are various ways of doing a shift:
1876 SHIFT_INLINE: If the amount is small enough, just generate as many one-bit
1878 SHIFT_ROT_AND: If the amount is large but close to either end, rotate the
1879 necessary bits into position and then set the rest to zero.
1880 SHIFT_SPECIAL: Hand crafted assembler.
1881 SHIFT_LOOP: If the above methods fail, just loop. */
1892 /* Symbols of the various shifts which can be used as indices. */
1896 SHIFT_ASHIFT
, SHIFT_LSHIFTRT
, SHIFT_ASHIFTRT
1899 /* Symbols of the various modes which can be used as indices. */
1903 QIshift
, HIshift
, SIshift
1906 /* For single bit shift insns, record assembler and what bits of the
1907 condition code are valid afterwards (represented as various CC_FOO
1908 bits, 0 means CC isn't left in a usable state). */
1916 /* Assembler instruction shift table.
1918 These tables are used to look up the basic shifts.
1919 They are indexed by cpu, shift_type, and mode.
1922 static const struct shift_insn shift_one
[2][3][3] =
1928 { "shll\t%X0", CC_NO_CARRY
},
1929 { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1930 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }
1932 /* SHIFT_LSHIFTRT */
1934 { "shlr\t%X0", CC_NO_CARRY
},
1935 { "shlr\t%t0\n\trotxr\t%s0", 0 },
1936 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1938 /* SHIFT_ASHIFTRT */
1940 { "shar\t%X0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1941 { "shar\t%t0\n\trotxr\t%s0", 0 },
1942 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1949 { "shll.b\t%X0", CC_NO_CARRY
},
1950 { "shll.w\t%T0", CC_NO_CARRY
},
1951 { "shll.l\t%S0", CC_NO_CARRY
}
1953 /* SHIFT_LSHIFTRT */
1955 { "shlr.b\t%X0", CC_NO_CARRY
},
1956 { "shlr.w\t%T0", CC_NO_CARRY
},
1957 { "shlr.l\t%S0", CC_NO_CARRY
}
1959 /* SHIFT_ASHIFTRT */
1961 { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1962 { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1963 { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
}
1968 static const struct shift_insn shift_two
[3][3] =
1972 { "shll.b\t#2,%X0", CC_NO_CARRY
},
1973 { "shll.w\t#2,%T0", CC_NO_CARRY
},
1974 { "shll.l\t#2,%S0", CC_NO_CARRY
}
1976 /* SHIFT_LSHIFTRT */
1978 { "shlr.b\t#2,%X0", CC_NO_CARRY
},
1979 { "shlr.w\t#2,%T0", CC_NO_CARRY
},
1980 { "shlr.l\t#2,%S0", CC_NO_CARRY
}
1982 /* SHIFT_ASHIFTRT */
1984 { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1985 { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
},
1986 { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE
| CC_NO_CARRY
}
1990 /* Rotates are organized by which shift they'll be used in implementing.
1991 There's no need to record whether the cc is valid afterwards because
1992 it is the AND insn that will decide this. */
1994 static const char *const rotate_one
[2][3][3] =
2001 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
2004 /* SHIFT_LSHIFTRT */
2007 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
2010 /* SHIFT_ASHIFTRT */
2013 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
2025 /* SHIFT_LSHIFTRT */
2031 /* SHIFT_ASHIFTRT */
2040 static const char *const rotate_two
[3][3] =
2048 /* SHIFT_LSHIFTRT */
2054 /* SHIFT_ASHIFTRT */
2062 /* Given CPU, MODE, SHIFT_TYPE, and shift count COUNT, determine the best
2063 algorithm for doing the shift. The assembler code is stored in ASSEMBLER.
2064 We don't achieve maximum efficiency in all cases, but the hooks are here
2067 For now we just use lots of switch statements. Since we don't even come
2068 close to supporting all the cases, this is simplest. If this function ever
2069 gets too big, perhaps resort to a more table based lookup. Of course,
2070 at this point you may just wish to do it all in rtl.
2072 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
2073 1,2,3,4 will be inlined (1,2 for SI). */
2075 static enum shift_alg
2076 get_shift_alg (cpu
, shift_type
, mode
, count
, assembler_p
,
2077 assembler2_p
, cc_valid_p
)
2079 enum shift_type shift_type
;
2080 enum machine_mode mode
;
2082 const char **assembler_p
;
2083 const char **assembler2_p
;
2086 /* The default is to loop. */
2087 enum shift_alg alg
= SHIFT_LOOP
;
2088 enum shift_mode shift_mode
;
2090 /* We don't handle negative shifts or shifts greater than the word size,
2091 they should have been handled already. */
2093 if (count
< 0 || count
> GET_MODE_BITSIZE (mode
))
2099 shift_mode
= QIshift
;
2102 shift_mode
= HIshift
;
2105 shift_mode
= SIshift
;
2111 /* Assume either SHIFT_LOOP or SHIFT_INLINE.
2112 It is up to the caller to know that looping clobbers cc. */
2113 *assembler_p
= shift_one
[cpu
][shift_type
][shift_mode
].assembler
;
2115 *assembler2_p
= shift_two
[shift_type
][shift_mode
].assembler
;
2117 *assembler2_p
= NULL
;
2118 *cc_valid_p
= shift_one
[cpu
][shift_type
][shift_mode
].cc_valid
;
2120 /* Now look for cases we want to optimize. */
2126 return SHIFT_INLINE
;
2129 /* Shift by 5/6 are only 3 insns on the H8/S, so it's just as
2130 fast as SHIFT_ROT_AND, plus CC is valid. */
2131 if (TARGET_H8300S
&& count
<= 6)
2132 return SHIFT_INLINE
;
2134 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2135 through the entire value. */
2136 if (shift_type
== SHIFT_ASHIFTRT
&& count
== 7)
2138 *assembler_p
= "shll\t%X0\n\tsubx\t%X0,%X0";
2140 return SHIFT_SPECIAL
;
2143 /* Other ASHIFTRTs are too much of a pain. */
2144 if (shift_type
== SHIFT_ASHIFTRT
)
2147 /* Other shifts by 5, 6, or 7 bits use SHIFT_ROT_AND. */
2148 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2150 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2152 return SHIFT_ROT_AND
;
2157 return SHIFT_INLINE
;
2158 else if (TARGET_H8300S
&& count
<= 7)
2159 return SHIFT_INLINE
;
2160 else if (count
== 7)
2162 if (shift_type
== SHIFT_ASHIFT
&& TARGET_H8300
)
2164 *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";
2166 return SHIFT_SPECIAL
;
2169 if (shift_type
== SHIFT_ASHIFT
&& TARGET_H8300H
)
2171 *assembler_p
= "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
2173 return SHIFT_SPECIAL
;
2176 if (shift_type
== SHIFT_LSHIFTRT
&& TARGET_H8300
)
2178 *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";
2180 return SHIFT_SPECIAL
;
2183 if (shift_type
== SHIFT_LSHIFTRT
&& TARGET_H8300H
)
2185 *assembler_p
= "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
2187 return SHIFT_SPECIAL
;
2190 if (shift_type
== SHIFT_ASHIFTRT
)
2192 *assembler_p
= "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
2194 return SHIFT_SPECIAL
;
2197 else if (count
== 8)
2202 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
2204 return SHIFT_SPECIAL
;
2205 case SHIFT_LSHIFTRT
:
2206 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
2208 return SHIFT_SPECIAL
;
2209 case SHIFT_ASHIFTRT
:
2211 *assembler_p
= "mov.b\t%t0,%s0\n\tshll\t%t0\n\tsubx\t%t0,%t0\t";
2213 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0";
2215 return SHIFT_SPECIAL
;
2218 else if (count
== 9)
2223 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0";
2225 return SHIFT_SPECIAL
;
2226 case SHIFT_LSHIFTRT
:
2227 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0";
2229 return SHIFT_SPECIAL
;
2230 case SHIFT_ASHIFTRT
:
2232 *assembler_p
= "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0";
2234 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0";
2236 return SHIFT_SPECIAL
;
2239 else if (count
== 10)
2245 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\t";
2247 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0\n\tshal.b\t%t0";
2249 return SHIFT_SPECIAL
;
2250 case SHIFT_LSHIFTRT
:
2252 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0";
2254 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0\n\tshlr.b\t%s0";
2256 return SHIFT_SPECIAL
;
2257 case SHIFT_ASHIFTRT
:
2259 *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";
2260 else if (TARGET_H8300H
)
2261 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0\n\tshar.b\t%s0";
2262 else if (TARGET_H8300S
)
2263 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t#2,%s0";
2265 return SHIFT_SPECIAL
;
2268 else if (count
== 11)
2274 *assembler_p
= "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\tshal.b\t%t0";
2276 *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";
2278 return SHIFT_SPECIAL
;
2279 case SHIFT_LSHIFTRT
:
2281 *assembler_p
= "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0\n\tshlr.b\t%s0";
2283 *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";
2285 return SHIFT_SPECIAL
;
2286 case SHIFT_ASHIFTRT
:
2288 *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";
2289 else if (TARGET_H8300H
)
2290 *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";
2291 else if (TARGET_H8300S
)
2292 *assembler_p
= "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t#2,%s0\n\tshar.b\t%s0";
2294 return SHIFT_SPECIAL
;
2297 else if (count
== 12)
2303 *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";
2305 *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";
2307 return SHIFT_SPECIAL
;
2308 case SHIFT_LSHIFTRT
:
2310 *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";
2312 *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";
2314 return SHIFT_SPECIAL
;
2315 case SHIFT_ASHIFTRT
:
2317 *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";
2318 else if (TARGET_H8300H
)
2319 *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";
2320 else if (TARGET_H8300S
)
2321 *assembler_p
= "mov.b\t%t0,%s0\n\textw.w\t%T0\n\tshar.b\t#2,%s0\n\tshar.b\t#2,%s0";
2323 return SHIFT_SPECIAL
;
2326 else if (!TARGET_H8300
&& (count
== 13 || count
== 14)
2329 if (count
== 15 && shift_type
== SHIFT_ASHIFTRT
)
2331 *assembler_p
= "shll\t%t0,%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
2333 return SHIFT_SPECIAL
;
2335 else if (shift_type
!= SHIFT_ASHIFTRT
)
2337 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2339 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2341 *assembler2_p
= NULL
;
2343 return SHIFT_ROT_AND
;
2349 if (count
<= (TARGET_H8300
? 2 : 4))
2350 return SHIFT_INLINE
;
2351 else if (TARGET_H8300S
&& count
<= 10)
2352 return SHIFT_INLINE
;
2353 else if (count
== 8 && TARGET_H8300
)
2358 *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";
2360 return SHIFT_SPECIAL
;
2361 case SHIFT_LSHIFTRT
:
2362 *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";
2364 return SHIFT_SPECIAL
;
2365 case SHIFT_ASHIFTRT
:
2366 *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";
2368 return SHIFT_SPECIAL
;
2371 else if (count
== 8 && !TARGET_H8300
)
2376 *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";
2378 return SHIFT_SPECIAL
;
2379 case SHIFT_LSHIFTRT
:
2380 *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";
2382 return SHIFT_SPECIAL
;
2383 case SHIFT_ASHIFTRT
:
2384 *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";
2386 return SHIFT_SPECIAL
;
2389 else if (count
== 16)
2394 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2396 return SHIFT_SPECIAL
;
2397 case SHIFT_LSHIFTRT
:
2398 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
2400 return SHIFT_SPECIAL
;
2401 case SHIFT_ASHIFTRT
:
2403 *assembler_p
= "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2405 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0";
2407 return SHIFT_SPECIAL
;
2410 else if (count
== 17 && !TARGET_H8300
)
2415 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0";
2417 return SHIFT_SPECIAL
;
2418 case SHIFT_LSHIFTRT
:
2419 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0";
2421 return SHIFT_SPECIAL
;
2422 case SHIFT_ASHIFTRT
:
2423 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0";
2425 return SHIFT_SPECIAL
;
2428 else if (count
== 18 && !TARGET_H8300
)
2434 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0";
2436 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0\n\tshll.l\t%S0";
2438 return SHIFT_SPECIAL
;
2439 case SHIFT_LSHIFTRT
:
2441 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0";
2443 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0\n\tshlr.l\t%S0";
2445 return SHIFT_SPECIAL
;
2446 case SHIFT_ASHIFTRT
:
2448 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0";
2450 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0\n\tshar.l\t%S0";
2452 return SHIFT_SPECIAL
;
2455 else if (count
== 19 && !TARGET_H8300
)
2461 *assembler_p
= "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0\n\tshll.l\t%S0";
2463 *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";
2465 return SHIFT_SPECIAL
;
2466 case SHIFT_LSHIFTRT
:
2468 *assembler_p
= "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0\n\tshlr.l\t%S0";
2470 *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";
2472 return SHIFT_SPECIAL
;
2473 case SHIFT_ASHIFTRT
:
2475 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0\n\tshar.l\t%S0";
2477 *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";
2479 return SHIFT_SPECIAL
;
2482 else if (count
== 20 && TARGET_H8300S
)
2487 *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";
2489 return SHIFT_SPECIAL
;
2490 case SHIFT_LSHIFTRT
:
2491 *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";
2493 return SHIFT_SPECIAL
;
2494 case SHIFT_ASHIFTRT
:
2495 *assembler_p
= "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0\n\tshar.l\t#2,%S0";
2497 return SHIFT_SPECIAL
;
2500 else if (count
== 24 && !TARGET_H8300
)
2505 *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";
2507 return SHIFT_SPECIAL
;
2508 case SHIFT_LSHIFTRT
:
2509 *assembler_p
= "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
2511 return SHIFT_SPECIAL
;
2512 case SHIFT_ASHIFTRT
:
2513 *assembler_p
= "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
2515 return SHIFT_SPECIAL
;
2518 else if (count
>= 28 && count
<= 30 && !TARGET_H8300
)
2520 if (shift_type
== SHIFT_ASHIFTRT
)
2526 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2528 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2530 *assembler2_p
= NULL
;
2532 return SHIFT_ROT_AND
;
2535 else if (count
== 31)
2537 if (shift_type
== SHIFT_ASHIFTRT
)
2540 *assembler_p
= "shll\t%z0\n\tsubx %w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2542 *assembler_p
= "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2544 return SHIFT_SPECIAL
;
2550 if (shift_type
== SHIFT_ASHIFT
)
2551 *assembler_p
= "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2553 *assembler_p
= "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2555 return SHIFT_SPECIAL
;
2559 *assembler_p
= rotate_one
[cpu
][shift_type
][shift_mode
];
2561 *assembler2_p
= rotate_two
[shift_type
][shift_mode
];
2563 *assembler2_p
= NULL
;
2565 return SHIFT_ROT_AND
;
2578 /* Emit the assembler code for doing shifts. */
2581 emit_a_shift (insn
, operands
)
2585 static int loopend_lab
;
2589 rtx inside
= PATTERN (insn
);
2590 rtx shift
= operands
[3];
2591 enum machine_mode mode
= GET_MODE (shift
);
2592 enum rtx_code code
= GET_CODE (shift
);
2593 enum shift_type shift_type
;
2594 enum shift_mode shift_mode
;
2601 shift_mode
= QIshift
;
2604 shift_mode
= HIshift
;
2607 shift_mode
= SIshift
;
2616 shift_type
= SHIFT_ASHIFTRT
;
2619 shift_type
= SHIFT_LSHIFTRT
;
2622 shift_type
= SHIFT_ASHIFT
;
2628 if (GET_CODE (operands
[2]) != CONST_INT
)
2630 /* Indexing by reg, so have to loop and test at top */
2631 output_asm_insn ("mov.b %X2,%X4", operands
);
2632 fprintf (asm_out_file
, "\tble .Lle%d\n", loopend_lab
);
2634 /* Get the assembler code to do one shift. */
2635 get_shift_alg (cpu_type
, shift_type
, mode
, 1, &assembler
,
2636 &assembler2
, &cc_valid
);
2640 int n
= INTVAL (operands
[2]);
2643 /* If the count is negative, make it 0. */
2646 /* If the count is too big, truncate it.
2647 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2648 do the intuitive thing. */
2649 else if (n
> GET_MODE_BITSIZE (mode
))
2650 n
= GET_MODE_BITSIZE (mode
);
2652 alg
= get_shift_alg (cpu_type
, shift_type
, mode
, n
, &assembler
,
2653 &assembler2
, &cc_valid
);
2658 /* Emit two bit shifts first. */
2659 while (n
> 1 && assembler2
!= NULL
)
2661 output_asm_insn (assembler2
, operands
);
2665 /* Now emit one bit shifts for any residual. */
2668 output_asm_insn (assembler
, operands
);
2672 /* Keep track of CC. */
2675 cc_status
.value1
= operands
[0];
2676 cc_status
.flags
|= cc_valid
;
2682 int m
= GET_MODE_BITSIZE (mode
) - n
;
2683 int mask
= (shift_type
== SHIFT_ASHIFT
2684 ? ((1 << GET_MODE_BITSIZE (mode
) - n
) - 1) << n
2685 : (1 << GET_MODE_BITSIZE (mode
) - n
) - 1);
2687 /* Not all possibilities of rotate are supported. They shouldn't
2688 be generated, but let's watch for 'em. */
2692 /* Emit two bit rotates first. */
2693 while (m
> 1 && assembler2
!= NULL
)
2695 output_asm_insn (assembler2
, operands
);
2699 /* Now single bit rotates for any residual. */
2702 output_asm_insn (assembler
, operands
);
2706 /* Now mask off the high bits. */
2712 sprintf (insn_buf
, "and #%d,%%X0",
2714 cc_status
.value1
= operands
[0];
2715 cc_status
.flags
|= CC_NO_CARRY
;
2718 sprintf (insn_buf
, "and #%d,%%s0\n\tand #%d,%%t0",
2719 mask
& 255, mask
>> 8, n
);
2727 sprintf (insn_buf
, "and.%c #%d,%%%c0",
2728 "bwl"[shift_mode
], mask
,
2729 mode
== QImode
? 'X' : mode
== HImode
? 'T' : 'S');
2730 cc_status
.value1
= operands
[0];
2731 cc_status
.flags
|= CC_NO_CARRY
;
2733 output_asm_insn (insn_buf
, operands
);
2737 output_asm_insn (assembler
, operands
);
2741 /* A loop to shift by a "large" constant value.
2742 If we have shift-by-2 insns, use them. */
2743 if (assembler2
!= NULL
)
2745 fprintf (asm_out_file
, "\tmov.b #%d,%sl\n", n
/ 2,
2746 names_big
[REGNO (operands
[4])]);
2747 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
2748 output_asm_insn (assembler2
, operands
);
2749 output_asm_insn ("add #0xff,%X4", operands
);
2750 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
2752 output_asm_insn (assembler
, operands
);
2757 fprintf (asm_out_file
, "\tmov.b #%d,%sl\n", n
,
2758 names_big
[REGNO (operands
[4])]);
2759 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
2760 output_asm_insn (assembler
, operands
);
2761 output_asm_insn ("add #0xff,%X4", operands
);
2762 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
2767 fprintf (asm_out_file
, ".Llt%d:\n", loopend_lab
);
2768 output_asm_insn (assembler
, operands
);
2769 output_asm_insn ("add #0xff,%X4", operands
);
2770 fprintf (asm_out_file
, "\tbne .Llt%d\n", loopend_lab
);
2771 fprintf (asm_out_file
, ".Lle%d:\n", loopend_lab
);
2776 /* Fix the operands of a gen_xxx so that it could become a bit
2780 fix_bit_operand (operands
, what
, type
)
2785 /* The bit_operand predicate accepts any memory during RTL generation, but
2786 only 'U' memory afterwards, so if this is a MEM operand, we must force
2787 it to be valid for 'U' by reloading the address. */
2789 if (GET_CODE (operands
[2]) == CONST_INT
)
2791 if (CONST_OK_FOR_LETTER_P (INTVAL (operands
[2]), what
))
2793 /* Ok to have a memory dest. */
2794 if (GET_CODE (operands
[0]) == MEM
&& !EXTRA_CONSTRAINT (operands
[0], 'U'))
2797 mem
= gen_rtx (MEM
, GET_MODE (operands
[0]),
2798 copy_to_mode_reg (Pmode
, XEXP (operands
[0], 0)));
2799 RTX_UNCHANGING_P (mem
) = RTX_UNCHANGING_P (operands
[0]);
2800 MEM_IN_STRUCT_P (mem
) = MEM_IN_STRUCT_P (operands
[0]);
2801 MEM_VOLATILE_P (mem
) = MEM_VOLATILE_P (operands
[0]);
2805 if (GET_CODE (operands
[1]) == MEM
&& !EXTRA_CONSTRAINT (operands
[1], 'U'))
2808 mem
= gen_rtx (MEM
, GET_MODE (operands
[1]),
2809 copy_to_mode_reg (Pmode
, XEXP (operands
[1], 0)));
2810 RTX_UNCHANGING_P (mem
) = RTX_UNCHANGING_P (operands
[1]);
2811 MEM_IN_STRUCT_P (mem
) = MEM_IN_STRUCT_P (operands
[1]);
2812 MEM_VOLATILE_P (mem
) = MEM_VOLATILE_P (operands
[1]);
2819 /* Dest and src op must be register. */
2821 operands
[1] = force_reg (QImode
, operands
[1]);
2823 rtx res
= gen_reg_rtx (QImode
);
2824 emit_insn (gen_rtx (SET
, VOIDmode
, res
, gen_rtx (type
, QImode
, operands
[1], operands
[2])));
2825 emit_insn (gen_rtx (SET
, VOIDmode
, operands
[0], res
));
2830 /* Return nonzero if FUNC is an interrupt function as specified
2831 by the "interrupt" attribute. */
2834 h8300_interrupt_function_p (func
)
2839 if (TREE_CODE (func
) != FUNCTION_DECL
)
2842 a
= lookup_attribute ("interrupt_handler", DECL_MACHINE_ATTRIBUTES (func
));
2843 return a
!= NULL_TREE
;
2846 /* Return nonzero if FUNC is an OS_Task function as specified
2847 by the "OS_Task" attribute. */
2850 h8300_os_task_function_p (func
)
2855 if (TREE_CODE (func
) != FUNCTION_DECL
)
2858 a
= lookup_attribute ("OS_Task", DECL_MACHINE_ATTRIBUTES (func
));
2859 return a
!= NULL_TREE
;
2862 /* Return nonzero if FUNC is a monitor function as specified
2863 by the "monitor" attribute. */
2866 h8300_monitor_function_p (func
)
2871 if (TREE_CODE (func
) != FUNCTION_DECL
)
2874 a
= lookup_attribute ("monitor", DECL_MACHINE_ATTRIBUTES (func
));
2875 return a
!= NULL_TREE
;
2878 /* Return nonzero if FUNC is a function that should be called
2879 through the function vector. */
2882 h8300_funcvec_function_p (func
)
2887 if (TREE_CODE (func
) != FUNCTION_DECL
)
2890 a
= lookup_attribute ("function_vector", DECL_MACHINE_ATTRIBUTES (func
));
2891 return a
!= NULL_TREE
;
2894 /* Return nonzero if DECL is a variable that's in the eight bit
2898 h8300_eightbit_data_p (decl
)
2903 if (TREE_CODE (decl
) != VAR_DECL
)
2906 a
= lookup_attribute ("eightbit_data", DECL_MACHINE_ATTRIBUTES (decl
));
2907 return a
!= NULL_TREE
;
2910 /* Return nonzero if DECL is a variable that's in the tiny
2914 h8300_tiny_data_p (decl
)
2919 if (TREE_CODE (decl
) != VAR_DECL
)
2922 a
= lookup_attribute ("tiny_data", DECL_MACHINE_ATTRIBUTES (decl
));
2923 return a
!= NULL_TREE
;
2926 /* Return nonzero if ATTR is a valid attribute for DECL.
2927 ATTRIBUTES are any existing attributes and ARGS are the arguments
2930 Supported attributes:
2932 interrupt_handler: output a prologue and epilogue suitable for an
2935 function_vector: This function should be called through the
2938 eightbit_data: This variable lives in the 8-bit data area and can
2939 be referenced with 8-bit absolute memory addresses.
2941 tiny_data: This variable lives in the tiny data area and can be
2942 referenced with 16-bit absolute memory references. */
2945 h8300_valid_machine_decl_attribute (decl
, attributes
, attr
, args
)
2951 if (args
!= NULL_TREE
)
2954 if (is_attribute_p ("interrupt_handler", attr
)
2955 || is_attribute_p ("OS_Task", attr
)
2956 || is_attribute_p ("monitor", attr
)
2957 || is_attribute_p ("function_vector", attr
))
2958 return TREE_CODE (decl
) == FUNCTION_DECL
;
2960 if (is_attribute_p ("eightbit_data", attr
)
2961 && (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
)))
2963 if (DECL_INITIAL (decl
) == NULL_TREE
)
2965 warning ("Only initialized variables can be placed into the 8-bit area.");
2968 DECL_SECTION_NAME (decl
) = build_string (7, ".eight");
2972 if (is_attribute_p ("tiny_data", attr
)
2973 && (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
)))
2975 if (DECL_INITIAL (decl
) == NULL_TREE
)
2977 warning ("Only initialized variables can be placed into the 8-bit area.");
2980 DECL_SECTION_NAME (decl
) = build_string (6, ".tiny");
2987 extern struct obstack
*saveable_obstack
;
2989 h8300_encode_label (decl
)
2992 char *str
= XSTR (XEXP (DECL_RTL (decl
), 0), 0);
2993 int len
= strlen (str
);
2996 newstr
= obstack_alloc (saveable_obstack
, len
+ 2);
2998 strcpy (newstr
+ 1, str
);
3000 XSTR (XEXP (DECL_RTL (decl
), 0), 0) = newstr
;
3004 output_simode_bld (bild
, log2
, operands
)
3009 /* Clear the destination register. */
3010 if (TARGET_H8300H
|| TARGET_H8300S
)
3011 output_asm_insn ("sub.l\t%S0,%S0", operands
);
3013 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands
);
3015 /* Get the bit number we want to load. */
3017 operands
[2] = GEN_INT (exact_log2 (INTVAL (operands
[2])));
3019 /* Now output the bit load or bit inverse load, and store it in
3022 output_asm_insn ("bild\t%Z2,%Y1\n\tbst\t#0,%w0", operands
);
3024 output_asm_insn ("bld\t%Z2,%Y1\n\tbst\t#0,%w0", operands
);
3030 /* Given INSN and its current length LENGTH, return the adjustment
3031 (in bytes) to correctly compute INSN's length.
3033 We use this to get the lengths of various memory references correct. */
3035 h8300_adjust_insn_length (insn
, length
)
3039 rtx pat
= PATTERN (insn
);
3041 /* Adjust length for reg->mem and mem->reg copies. */
3042 if (GET_CODE (pat
) == SET
3043 && (GET_CODE (SET_SRC (pat
)) == MEM
3044 || GET_CODE (SET_DEST (pat
)) == MEM
))
3046 /* This insn might need a length adjustment. */
3049 if (GET_CODE (SET_SRC (pat
)) == MEM
)
3050 addr
= XEXP (SET_SRC (pat
), 0);
3052 addr
= XEXP (SET_DEST (pat
), 0);
3054 /* On the H8/300, only one adjustment is necessary; if the
3055 address mode is register indirect, then this insn is two
3056 bytes shorter than indicated in the machine description. */
3057 if (TARGET_H8300
&& GET_CODE (addr
) == REG
)
3060 /* On the H8/300H and H8/S, register indirect is 6 bytes shorter than
3061 indicated in the machine description. */
3062 if ((TARGET_H8300H
|| TARGET_H8300S
)
3063 && GET_CODE (addr
) == REG
)
3066 /* On the H8/300H and H8/300S, reg + d, for small displacements is 4
3067 bytes shorter than indicated in the machine description. */
3068 if ((TARGET_H8300H
|| TARGET_H8300S
)
3069 && GET_CODE (addr
) == PLUS
3070 && GET_CODE (XEXP (addr
, 0)) == REG
3071 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
3072 && INTVAL (XEXP (addr
, 1)) > -32768
3073 && INTVAL (XEXP (addr
, 1)) < 32767)
3076 /* On the H8/300H and H8/300S, abs:16 is two bytes shorter than the
3077 more general abs:24. */
3078 if ((TARGET_H8300H
|| TARGET_H8300S
)
3079 && GET_CODE (addr
) == SYMBOL_REF
3080 && TINY_DATA_NAME_P (XSTR (addr
, 0)))
3084 /* Loading some constants needs adjustment. */
3085 if (GET_CODE (pat
) == SET
3086 && GET_CODE (SET_SRC (pat
)) == CONST_INT
3087 && GET_MODE (SET_DEST (pat
)) == SImode
3088 && INTVAL (SET_SRC (pat
)) != 0)
3091 && ((INTVAL (SET_SRC (pat
)) & 0xffff) == 0
3092 || ((INTVAL (SET_SRC (pat
)) >> 16) & 0xffff) == 0))
3095 if (TARGET_H8300H
|| TARGET_H8300S
)
3097 int val
= INTVAL (SET_SRC (pat
));
3099 if (val
== (val
& 0xff)
3100 || val
== (val
& 0xff00))
3103 if (val
== -4 || val
== -2 || val
== -1)
3108 /* Shifts need various adjustments. */
3109 if (GET_CODE (pat
) == PARALLEL
3110 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
3111 && (GET_CODE (SET_SRC (XVECEXP (pat
, 0, 0))) == ASHIFTRT
3112 || GET_CODE (SET_SRC (XVECEXP (pat
, 0, 0))) == LSHIFTRT
3113 || GET_CODE (SET_SRC (XVECEXP (pat
, 0, 0))) == ASHIFT
))
3115 rtx src
= SET_SRC (XVECEXP (pat
, 0, 0));
3116 enum machine_mode mode
= GET_MODE (src
);
3118 if (GET_CODE (XEXP (src
, 1)) != CONST_INT
)
3121 /* QImode shifts by small constants take one insn
3122 per shift. So the adjustment is 20 (md length) -
3124 if (mode
== QImode
&& INTVAL (XEXP (src
, 1)) <= 4)
3125 return -(20 - INTVAL (XEXP (src
, 1)) * 2);
3127 /* Similarly for HImode and SImode shifts by
3128 small constants on the H8/300H and H8/300S. */
3129 if ((TARGET_H8300H
|| TARGET_H8300S
)
3130 && (mode
== HImode
|| mode
== SImode
)
3131 && INTVAL (XEXP (src
, 1)) <= 4)
3132 return -(20 - INTVAL (XEXP (src
, 1)) * 2);
3134 /* HImode shifts by small constants for the H8/300. */
3136 && INTVAL (XEXP (src
, 1)) <= 4)
3137 return -(20 - (INTVAL (XEXP (src
, 1))
3138 * (GET_CODE (src
) == ASHIFT
? 2 : 4)));
3140 /* SImode shifts by small constants for the H8/300. */
3142 && INTVAL (XEXP (src
, 1)) <= 2)
3143 return -(20 - (INTVAL (XEXP (src
, 1))
3144 * (GET_CODE (src
) == ASHIFT
? 6 : 8)));
3146 /* XXX ??? Could check for more shift/rotate cases here. */