1 /* Subroutines for insn-output.c for Hitachi H8/300.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002 Free Software Foundation, Inc.
4 Contributed by Steve Chamberlain (sac@cygnus.com),
5 Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
7 This file is part of GNU CC.
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING. If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
34 #include "insn-attr.h"
44 #include "target-def.h"
46 /* Forward declarations. */
47 static const char *byte_reg PARAMS ((rtx, int));
48 static int h8300_interrupt_function_p PARAMS ((tree));
49 static int h8300_monitor_function_p PARAMS ((tree));
50 static int h8300_os_task_function_p PARAMS ((tree));
51 static void dosize PARAMS ((FILE *, const char *, unsigned int));
52 static int round_frame_size PARAMS ((int));
53 static unsigned int compute_saved_regs PARAMS ((void));
54 static void push PARAMS ((FILE *, int));
55 static void pop PARAMS ((FILE *, int));
56 static const char *cond_string PARAMS ((enum rtx_code));
57 static unsigned int h8300_asm_insn_count PARAMS ((const char *));
58 const struct attribute_spec h8300_attribute_table[];
59 static tree h8300_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
60 static tree h8300_handle_eightbit_data_attribute PARAMS ((tree *, tree, tree, int, bool *));
61 static tree h8300_handle_tiny_data_attribute PARAMS ((tree *, tree, tree, int, bool *));
62 static void h8300_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
63 static void h8300_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
64 static void h8300_insert_attributes PARAMS ((tree, tree *));
65 #ifndef OBJECT_FORMAT_ELF
66 static void h8300_asm_named_section PARAMS ((const char *, unsigned int));
68 static void h8300_encode_label PARAMS ((tree));
69 static void h8300_encode_section_info PARAMS ((tree, int));
70 static const char *h8300_strip_name_encoding PARAMS ((const char *));
72 /* CPU_TYPE, says what cpu we're compiling for. */
75 /* True if the current function is an interrupt handler
76 (either via #pragma or an attribute specification). */
77 static int interrupt_handler;
79 /* True if the current function is an OS Task
80 (via an attribute specification). */
83 /* True if the current function is a monitor
84 (via an attribute specification). */
87 /* True if a #pragma saveall has been seen for the current function. */
88 static int pragma_saveall;
90 static const char *const names_big[] =
91 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" };
93 static const char *const names_extended[] =
94 { "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" };
96 static const char *const names_upper_extended[] =
97 { "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7" };
99 /* Points to one of the above. */
100 /* ??? The above could be put in an array indexed by CPU_TYPE. */
101 const char * const *h8_reg_names;
103 /* Various operations needed by the following, indexed by CPU_TYPE. */
105 const char *h8_push_op, *h8_pop_op, *h8_mov_op;
107 /* Initialize the GCC target structure. */
108 #undef TARGET_ATTRIBUTE_TABLE
109 #define TARGET_ATTRIBUTE_TABLE h8300_attribute_table
111 #undef TARGET_ASM_ALIGNED_HI_OP
112 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
114 #undef TARGET_ASM_FUNCTION_PROLOGUE
115 #define TARGET_ASM_FUNCTION_PROLOGUE h8300_output_function_prologue
116 #undef TARGET_ASM_FUNCTION_EPILOGUE
117 #define TARGET_ASM_FUNCTION_EPILOGUE h8300_output_function_epilogue
118 #undef TARGET_ENCODE_SECTION_INFO
119 #define TARGET_ENCODE_SECTION_INFO h8300_encode_section_info
120 #undef TARGET_STRIP_NAME_ENCODING
121 #define TARGET_STRIP_NAME_ENCODING h8300_strip_name_encoding
123 #undef TARGET_INSERT_ATTRIBUTES
124 #define TARGET_INSERT_ATTRIBUTES h8300_insert_attributes
126 struct gcc_target targetm = TARGET_INITIALIZER;
128 /* See below where shifts are handled for explanation of this enum. */
138 /* Symbols of the various shifts which can be used as indices. */
142 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
145 /* Macros to keep the shift algorithm tables small. */
146 #define INL SHIFT_INLINE
147 #define ROT SHIFT_ROT_AND
148 #define LOP SHIFT_LOOP
149 #define SPC SHIFT_SPECIAL
151 /* The shift algorithms for each machine, mode, shift type, and shift
152 count are defined below. The three tables below correspond to
153 QImode, HImode, and SImode, respectively. Each table is organized
154 by, in the order of indecies, machine, shift type, and shift count. */
156 static enum shift_alg shift_alg_qi[3][3][8] = {
159 /* 0 1 2 3 4 5 6 7 */
160 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
161 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
162 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
166 /* 0 1 2 3 4 5 6 7 */
167 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
168 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
169 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
173 /* 0 1 2 3 4 5 6 7 */
174 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_ASHIFT */
175 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_LSHIFTRT */
176 { INL, INL, INL, INL, INL, INL, INL, SPC } /* SHIFT_ASHIFTRT */
180 static enum shift_alg shift_alg_hi[3][3][16] = {
183 /* 0 1 2 3 4 5 6 7 */
184 /* 8 9 10 11 12 13 14 15 */
185 { INL, INL, INL, INL, INL, INL, INL, SPC,
186 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */
187 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
188 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */
189 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
190 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
194 /* 0 1 2 3 4 5 6 7 */
195 /* 8 9 10 11 12 13 14 15 */
196 { INL, INL, INL, INL, INL, INL, INL, SPC,
197 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
198 { INL, INL, INL, INL, INL, INL, INL, SPC,
199 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
200 { INL, INL, INL, INL, INL, INL, INL, SPC,
201 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
205 /* 0 1 2 3 4 5 6 7 */
206 /* 8 9 10 11 12 13 14 15 */
207 { INL, INL, INL, INL, INL, INL, INL, INL,
208 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
209 { INL, INL, INL, INL, INL, INL, INL, INL,
210 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
211 { INL, INL, INL, INL, INL, INL, INL, INL,
212 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
216 static enum shift_alg shift_alg_si[3][3][32] = {
219 /* 0 1 2 3 4 5 6 7 */
220 /* 8 9 10 11 12 13 14 15 */
221 /* 16 17 18 19 20 21 22 23 */
222 /* 24 25 26 27 28 29 30 31 */
223 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
224 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
225 SPC, SPC, SPC, SPC, SPC, LOP, LOP, LOP,
226 SPC, SPC, SPC, SPC, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
227 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
228 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC,
229 SPC, SPC, SPC, LOP, LOP, LOP, LOP, LOP,
230 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
231 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
232 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
233 SPC, SPC, LOP, LOP, LOP, LOP, LOP, LOP,
234 SPC, SPC, SPC, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
238 /* 0 1 2 3 4 5 6 7 */
239 /* 8 9 10 11 12 13 14 15 */
240 /* 16 17 18 19 20 21 22 23 */
241 /* 24 25 26 27 28 29 30 31 */
242 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
243 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
244 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
245 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
246 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
247 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
248 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
249 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
250 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
251 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
252 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
253 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
257 /* 0 1 2 3 4 5 6 7 */
258 /* 8 9 10 11 12 13 14 15 */
259 /* 16 17 18 19 20 21 22 23 */
260 /* 24 25 26 27 28 29 30 31 */
261 { INL, INL, INL, INL, INL, INL, INL, INL,
262 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
263 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
264 SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
265 { INL, INL, INL, INL, INL, INL, INL, INL,
266 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
267 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
268 SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
269 { INL, INL, INL, INL, INL, INL, INL, INL,
270 INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
271 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
272 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
288 /* Initialize various cpu specific globals at start up. */
293 static const char *const h8_push_ops[2] = { "push" , "push.l" };
294 static const char *const h8_pop_ops[2] = { "pop" , "pop.l" };
295 static const char *const h8_mov_ops[2] = { "mov.w", "mov.l" };
299 cpu_type = (int) CPU_H8300;
300 h8_reg_names = names_big;
304 /* For this we treat the H8/300H and H8S the same. */
305 cpu_type = (int) CPU_H8300H;
306 h8_reg_names = names_extended;
308 h8_push_op = h8_push_ops[cpu_type];
309 h8_pop_op = h8_pop_ops[cpu_type];
310 h8_mov_op = h8_mov_ops[cpu_type];
312 if (!TARGET_H8300S && TARGET_MAC)
314 error ("-ms2600 is used without -ms");
318 /* Some of the shifts are optimized for speed by default.
319 See http://gcc.gnu.org/ml/gcc-patches/2002-07/msg01858.html
320 If optimizing for size, change shift_alg for those shift to
325 shift_alg_hi[H8_300][SHIFT_ASHIFT][5] = SHIFT_LOOP;
326 shift_alg_hi[H8_300][SHIFT_ASHIFT][6] = SHIFT_LOOP;
327 shift_alg_hi[H8_300][SHIFT_ASHIFT][13] = SHIFT_LOOP;
328 shift_alg_hi[H8_300][SHIFT_ASHIFT][14] = SHIFT_LOOP;
330 shift_alg_hi[H8_300][SHIFT_LSHIFTRT][13] = SHIFT_LOOP;
331 shift_alg_hi[H8_300][SHIFT_LSHIFTRT][14] = SHIFT_LOOP;
333 shift_alg_hi[H8_300][SHIFT_ASHIFTRT][13] = SHIFT_LOOP;
334 shift_alg_hi[H8_300][SHIFT_ASHIFTRT][14] = SHIFT_LOOP;
337 shift_alg_hi[H8_300H][SHIFT_ASHIFT][5] = SHIFT_LOOP;
338 shift_alg_hi[H8_300H][SHIFT_ASHIFT][6] = SHIFT_LOOP;
340 shift_alg_hi[H8_300H][SHIFT_LSHIFTRT][5] = SHIFT_LOOP;
341 shift_alg_hi[H8_300H][SHIFT_LSHIFTRT][6] = SHIFT_LOOP;
343 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][5] = SHIFT_LOOP;
344 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][6] = SHIFT_LOOP;
345 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][13] = SHIFT_LOOP;
346 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][14] = SHIFT_LOOP;
349 shift_alg_hi[H8_S][SHIFT_ASHIFTRT][13] = SHIFT_LOOP;
350 shift_alg_hi[H8_S][SHIFT_ASHIFTRT][14] = SHIFT_LOOP;
359 static const char *const names_small[] = {
360 "r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
361 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h"
364 return names_small[REGNO (x) * 2 + b];
367 /* REGNO must be saved/restored across calls if this macro is true. */
369 #define WORD_REG_USED(regno) \
371 /* No need to save registers if this function will not return. */ \
372 && ! TREE_THIS_VOLATILE (current_function_decl) \
374 /* Save any call saved register that was used. */ \
375 || (regs_ever_live[regno] && !call_used_regs[regno]) \
376 /* Save the frame pointer if it was used. */ \
377 || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno]) \
378 /* Save any register used in an interrupt handler. */ \
379 || (interrupt_handler && regs_ever_live[regno]) \
380 /* Save call clobbered registers in non-leaf interrupt \
382 || (interrupt_handler \
383 && call_used_regs[regno] \
384 && !current_function_is_leaf)))
386 /* Output assembly language to FILE for the operation OP with operand size
387 SIZE to adjust the stack pointer. */
390 dosize (file, op, size)
395 /* On the H8/300H and H8S, for sizes <= 8 bytes, it is as good or
396 better to use adds/subs insns rather than add.l/sub.l with an
399 Also, on the H8/300, if we don't have a temporary to hold the
400 size of the frame in the prologue, we simply emit a sequence of
401 subs since this shouldn't happen often. */
402 if ((TARGET_H8300 && size <= 4)
403 || ((TARGET_H8300H || TARGET_H8300S) && size <= 8)
404 || (TARGET_H8300 && interrupt_handler)
405 || (TARGET_H8300 && current_function_needs_context
406 && ! strcmp (op, "sub")))
408 unsigned HOST_WIDE_INT amount;
410 /* Try different amounts in descending order. */
411 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
415 for (; size >= amount; size -= amount)
416 fprintf (file, "\t%ss\t#%d,sp\n", op, amount);
422 fprintf (file, "\tmov.w\t#%d,r3\n\t%s.w\tr3,sp\n", size, op);
424 fprintf (file, "\t%s.l\t#%d,sp\n", op, size);
428 /* Round up frame size SIZE. */
431 round_frame_size (size)
434 return (size + STACK_BOUNDARY / 8 - 1) & -STACK_BOUNDARY / 8;
437 /* Compute which registers to push/pop.
438 Return a bit vector of registers. */
441 compute_saved_regs ()
443 unsigned int saved_regs = 0;
446 /* Construct a bit vector of registers to be pushed/popped. */
447 for (regno = 0; regno <= FRAME_POINTER_REGNUM; regno++)
449 if (WORD_REG_USED (regno))
450 saved_regs |= 1 << regno;
453 /* Don't push/pop the frame pointer as it is treated separately. */
454 if (frame_pointer_needed)
455 saved_regs &= ~(1 << FRAME_POINTER_REGNUM);
460 /* Output assembly language code to push register RN. */
467 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[rn]);
470 /* Output assembly language code to pop register RN. */
477 fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[rn]);
480 /* This is what the stack looks like after the prolog of
481 a function with a frame has been set up:
487 <saved registers> <- sp
489 This is what the stack looks like after the prolog of
490 a function which doesn't have a frame:
495 <saved registers> <- sp
498 /* Output assembly language code for the function prologue. */
501 h8300_output_function_prologue (file, size)
505 int fsize = round_frame_size (size);
510 /* Note a function with the interrupt attribute and set interrupt_handler
512 if (h8300_interrupt_function_p (current_function_decl))
513 interrupt_handler = 1;
515 /* If the current function has the OS_Task attribute set, then
516 we have a naked prologue. */
517 if (h8300_os_task_function_p (current_function_decl))
519 fprintf (file, ";OS_Task prologue\n");
524 if (h8300_monitor_function_p (current_function_decl))
526 /* My understanding of monitor functions is they act just
527 like interrupt functions, except the prologue must
529 fprintf (file, ";monitor prologue\n");
530 interrupt_handler = 1;
534 fprintf (file, "\tsubs\t#2,sp\n");
536 fprintf (file, "\tstc\tccr,r0l\n");
537 fprintf (file, "\tmov.b\tr0l,@(2,sp)\n");
539 fprintf (file, "\torc\t#128,ccr\n");
541 else if (TARGET_H8300H)
544 fprintf (file, "\tstc\tccr,r0l\n");
545 fprintf (file, "\tmov.b\tr0l,@(4,sp)\n");
547 fprintf (file, "\torc\t#128,ccr\n");
549 else if (TARGET_H8300S)
551 fprintf (file, "\tstc\texr,@-sp\n");
553 fprintf (file, "\tstc\tccr,r0l\n");
554 fprintf (file, "\tmov.b\tr0l,@(6,sp)\n");
556 fprintf (file, "\torc\t#128,ccr\n");
562 if (frame_pointer_needed)
565 push (file, FRAME_POINTER_REGNUM);
566 fprintf (file, "\t%s\t%s,%s\n", h8_mov_op,
567 h8_reg_names[STACK_POINTER_REGNUM],
568 h8_reg_names[FRAME_POINTER_REGNUM]);
571 /* Leave room for locals. */
572 dosize (file, "sub", fsize);
574 /* Push the rest of the registers in ascending order. */
575 saved_regs = compute_saved_regs ();
576 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx += n_regs)
581 if (saved_regs & (1 << regno))
585 /* See how many registers we can push at the same time. */
586 if ((regno == 0 || regno == 4)
587 && ((saved_regs >> regno) & 0x0f) == 0x0f)
590 else if ((regno == 0 || regno == 4)
591 && ((saved_regs >> regno) & 0x07) == 0x07)
594 else if ((regno == 0 || regno == 2 || regno == 4 || regno == 6)
595 && ((saved_regs >> regno) & 0x03) == 0x03)
602 fprintf (file, "\tstm.l\t%s-%s,@-sp\n",
604 h8_reg_names[regno + (n_regs - 1)]);
609 /* Output assembly language code for the function epilogue. */
612 h8300_output_function_epilogue (file, size)
616 int fsize = round_frame_size (size);
618 rtx insn = get_last_insn ();
624 /* OS_Task epilogues are nearly naked -- they just have an
626 fprintf (file, ";OS_task epilogue\n");
627 fprintf (file, "\trts\n");
631 /* Monitor epilogues are the same as interrupt function epilogues.
632 Just make a note that we're in an monitor epilogue. */
634 fprintf (file, ";monitor epilogue\n");
636 /* If the last insn was a BARRIER, we don't have to write any code. */
637 if (GET_CODE (insn) == NOTE)
638 insn = prev_nonnote_insn (insn);
639 if (insn && GET_CODE (insn) == BARRIER)
642 /* Pop the saved registers in descending order. */
643 saved_regs = compute_saved_regs ();
644 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx += n_regs)
646 int regno = (FIRST_PSEUDO_REGISTER - 1) - idx;
649 if (saved_regs & (1 << regno))
653 /* See how many registers we can pop at the same time. */
654 if ((regno == 7 || regno == 3)
655 && ((saved_regs >> (regno - 3)) & 0x0f) == 0x0f)
658 else if ((regno == 6 || regno == 2)
659 && ((saved_regs >> (regno - 2)) & 0x07) == 0x07)
662 else if ((regno == 7 || regno == 5 || regno == 3 || regno == 1)
663 && ((saved_regs >> (regno - 1)) & 0x03) == 0x03)
670 fprintf (file, "\tldm.l\t@sp+,%s-%s\n",
671 h8_reg_names[regno - (n_regs - 1)],
672 h8_reg_names[regno]);
676 /* Deallocate locals. */
677 dosize (file, "add", fsize);
679 /* Pop frame pointer if we had one. */
680 if (frame_pointer_needed)
681 pop (file, FRAME_POINTER_REGNUM);
683 if (interrupt_handler)
684 fprintf (file, "\trte\n");
686 fprintf (file, "\trts\n");
689 interrupt_handler = 0;
695 /* Output assembly code for the start of the file. */
698 asm_file_start (file)
701 fprintf (file, ";\tGCC For the Hitachi H8/300\n");
702 fprintf (file, ";\tBy Hitachi America Ltd and Cygnus Support\n");
705 fprintf (file, "; -Os\n");
707 fprintf (file, "; -O%d\n", optimize);
709 fprintf (file, "\n\t.h8300h\n");
710 else if (TARGET_H8300S)
711 fprintf (file, "\n\t.h8300s\n");
713 fprintf (file, "\n\n");
714 output_file_directive (file, main_input_filename);
717 /* Output assembly language code for the end of file. */
723 fprintf (file, "\t.end\n");
726 /* Return true if OP is a valid source operand for an integer move
730 general_operand_src (op, mode)
732 enum machine_mode mode;
734 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
736 return general_operand (op, mode);
739 /* Return true if OP is a valid destination operand for an integer move
743 general_operand_dst (op, mode)
745 enum machine_mode mode;
747 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == PRE_DEC)
749 return general_operand (op, mode);
752 /* Return true if OP is a constant that contains only one 1 in its
753 binary representation. */
756 single_one_operand (operand, mode)
758 enum machine_mode mode ATTRIBUTE_UNUSED;
760 if (GET_CODE (operand) == CONST_INT)
762 /* We really need to do this masking because 0x80 in QImode is
763 represented as -128 for example. */
764 unsigned HOST_WIDE_INT mask =
765 ((unsigned HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (mode)) - 1;
766 unsigned HOST_WIDE_INT value = INTVAL (operand);
768 if (exact_log2 (value & mask) >= 0)
775 /* Return true if OP is a constant that contains only one 0 in its
776 binary representation. */
779 single_zero_operand (operand, mode)
781 enum machine_mode mode ATTRIBUTE_UNUSED;
783 if (GET_CODE (operand) == CONST_INT)
785 /* We really need to do this masking because 0x80 in QImode is
786 represented as -128 for example. */
787 unsigned HOST_WIDE_INT mask =
788 ((unsigned HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (mode)) - 1;
789 unsigned HOST_WIDE_INT value = INTVAL (operand);
791 if (exact_log2 (~value & mask) >= 0)
798 /* Return true if OP is a valid call operand. */
801 call_insn_operand (op, mode)
803 enum machine_mode mode ATTRIBUTE_UNUSED;
805 if (GET_CODE (op) == MEM)
807 rtx inside = XEXP (op, 0);
808 if (register_operand (inside, Pmode))
810 if (CONSTANT_ADDRESS_P (inside))
816 /* Return 1 if an addition/subtraction of a constant integer can be
817 transformed into two consecutive adds/subs that are faster than the
818 straightforward way. Otherwise, return 0. */
821 two_insn_adds_subs_operand (op, mode)
823 enum machine_mode mode;
825 if (GET_CODE (op) == CONST_INT)
827 HOST_WIDE_INT value = INTVAL (op);
829 /* Force VALUE to be positive so that we do not have to consider
830 the negative case. */
833 if (TARGET_H8300H || TARGET_H8300S)
835 /* A constant addition/subtraction takes 2 states in QImode,
836 4 states in HImode, and 6 states in SImode. Thus, the
837 only case we can win is when SImode is used, in which
838 case, two adds/subs are used, taking 4 states. */
848 /* We do not profit directly by splitting addition or
849 subtraction of 3 and 4. However, since these are
850 implemented as a sequence of adds or subs, they do not
851 clobber (cc0) unlike a sequence of add.b and add.x. */
862 /* Split an add of a small constant into two adds/subs insns. */
865 split_adds_subs (mode, operands)
866 enum machine_mode mode;
869 HOST_WIDE_INT val = INTVAL (operands[1]);
870 rtx reg = operands[0];
871 HOST_WIDE_INT sign = 1;
872 HOST_WIDE_INT amount;
874 /* Force VAL to be positive so that we do not have to consider the
882 /* Try different amounts in descending order. */
883 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
887 for (; val >= amount; val -= amount)
889 rtx tmp = gen_rtx_PLUS (mode, reg, GEN_INT (sign * amount));
890 emit_insn (gen_rtx_SET (VOIDmode, reg, tmp));
897 /* Return true if OP is a valid call operand, and OP represents
898 an operand for a small call (4 bytes instead of 6 bytes). */
901 small_call_insn_operand (op, mode)
903 enum machine_mode mode ATTRIBUTE_UNUSED;
905 if (GET_CODE (op) == MEM)
907 rtx inside = XEXP (op, 0);
909 /* Register indirect is a small call. */
910 if (register_operand (inside, Pmode))
913 /* A call through the function vector is a small
915 if (GET_CODE (inside) == SYMBOL_REF
916 && SYMBOL_REF_FLAG (inside))
919 /* Otherwise it's a large call. */
923 /* Return true if OP is a valid jump operand. */
926 jump_address_operand (op, mode)
928 enum machine_mode mode;
930 if (GET_CODE (op) == REG)
931 return mode == Pmode;
933 if (GET_CODE (op) == MEM)
935 rtx inside = XEXP (op, 0);
936 if (register_operand (inside, Pmode))
938 if (CONSTANT_ADDRESS_P (inside))
944 /* Recognize valid operands for bit-field instructions. */
946 extern int rtx_equal_function_value_matters;
949 bit_operand (op, mode)
951 enum machine_mode mode;
953 /* We can except any general operand, expept that MEM operands must
954 be limited to those that use addresses valid for the 'U' constraint. */
955 if (!general_operand (op, mode))
958 /* Accept any mem during RTL generation. Otherwise, the code that does
959 insv and extzv will think that we can not handle memory. However,
960 to avoid reload problems, we only accept 'U' MEM operands after RTL
961 generation. This means that any named pattern which uses this predicate
962 must force its operands to match 'U' before emitting RTL. */
964 if (GET_CODE (op) == REG)
966 if (GET_CODE (op) == SUBREG)
968 if (!rtx_equal_function_value_matters)
969 /* We're building rtl. */
970 return GET_CODE (op) == MEM;
972 return (GET_CODE (op) == MEM
973 && EXTRA_CONSTRAINT (op, 'U'));
977 bit_memory_operand (op, mode)
979 enum machine_mode mode ATTRIBUTE_UNUSED;
981 return (GET_CODE (op) == MEM
982 && EXTRA_CONSTRAINT (op, 'U'));
985 /* Handle machine specific pragmas for compatibility with existing
986 compilers for the H8/300.
988 pragma saveall generates prolog/epilog code which saves and
989 restores all the registers on function entry.
991 pragma interrupt saves and restores all registers, and exits with
992 an rte instruction rather than an rts. A pointer to a function
993 with this attribute may be safely used in an interrupt vector. */
996 h8300_pr_interrupt (pfile)
997 cpp_reader *pfile ATTRIBUTE_UNUSED;
999 interrupt_handler = 1;
1003 h8300_pr_saveall (pfile)
1004 cpp_reader *pfile ATTRIBUTE_UNUSED;
1009 /* If the next function argument with MODE and TYPE is to be passed in
1010 a register, return a reg RTX for the hard register in which to pass
1011 the argument. CUM represents the state after the last argument.
1012 If the argument is to be pushed, NULL_RTX is returned. */
1015 function_arg (cum, mode, type, named)
1016 CUMULATIVE_ARGS *cum;
1017 enum machine_mode mode;
1021 static const char *const hand_list[] = {
1040 rtx result = NULL_RTX;
1044 /* Never pass unnamed arguments in registers. */
1048 /* Pass 3 regs worth of data in regs when user asked on the command line. */
1049 if (TARGET_QUICKCALL)
1052 /* If calling hand written assembler, use 4 regs of args. */
1055 const char * const *p;
1057 fname = XSTR (cum->libcall, 0);
1059 /* See if this libcall is one of the hand coded ones. */
1060 for (p = hand_list; *p && strcmp (*p, fname) != 0; p++)
1071 if (mode == BLKmode)
1072 size = int_size_in_bytes (type);
1074 size = GET_MODE_SIZE (mode);
1076 if (size + cum->nbytes <= regpass * UNITS_PER_WORD
1077 && cum->nbytes / UNITS_PER_WORD <= 3)
1078 result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
1084 /* Return the cost of the rtx R with code CODE. */
1087 const_costs (r, c, outer_code)
1090 enum rtx_code outer_code;
1103 return 0 + (outer_code == SET);
1106 if (TARGET_H8300H || TARGET_H8300S)
1107 return 0 + (outer_code == SET);
1127 /* Documentation for the machine specific operand escapes:
1129 'E' like s but negative.
1130 'F' like t but negative.
1131 'G' constant just the negative
1132 'R' print operand as a byte:8 address if appropriate, else fall back to
1134 'S' print operand as a long word
1135 'T' print operand as a word
1136 'V' find the set bit, and print its number.
1137 'W' find the clear bit, and print its number.
1138 'X' print operand as a byte
1139 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
1140 If this operand isn't a register, fall back to 'R' handling.
1142 'b' print the bit opcode
1143 'e' first word of 32 bit value - if reg, then least reg. if mem
1144 then least. if const then most sig word
1145 'f' second word of 32 bit value - if reg, then biggest reg. if mem
1146 then +2. if const then least sig word
1147 'j' print operand as condition code.
1148 'k' print operand as reverse condition code.
1149 's' print as low byte of 16 bit value
1150 't' print as high byte of 16 bit value
1151 'w' print as low byte of 32 bit value
1152 'x' print as 2nd byte of 32 bit value
1153 'y' print as 3rd byte of 32 bit value
1154 'z' print as msb of 32 bit value
1157 /* Return assembly language string which identifies a comparison type. */
1190 /* Print operand X using operand code CODE to assembly language output file
1194 print_operand (file, x, code)
1199 /* This is used for communication between codes V,W,Z and Y. */
1205 switch (GET_CODE (x))
1208 fprintf (file, "%sl", names_big[REGNO (x)]);
1211 fprintf (file, "#%d", (-INTVAL (x)) & 0xff);
1218 switch (GET_CODE (x))
1221 fprintf (file, "%sh", names_big[REGNO (x)]);
1224 fprintf (file, "#%d", ((-INTVAL (x)) & 0xff00) >> 8);
1231 if (GET_CODE (x) != CONST_INT)
1233 fprintf (file, "#%d", 0xff & (-INTVAL (x)));
1236 if (GET_CODE (x) == REG)
1237 fprintf (file, "%s", names_extended[REGNO (x)]);
1242 if (GET_CODE (x) == REG)
1243 fprintf (file, "%s", names_big[REGNO (x)]);
1248 bitint = exact_log2 (INTVAL (x) & 0xff);
1251 fprintf (file, "#%d", bitint);
1254 bitint = exact_log2 ((~INTVAL (x)) & 0xff);
1257 fprintf (file, "#%d", bitint);
1261 if (GET_CODE (x) == REG)
1262 fprintf (file, "%s", byte_reg (x, 0));
1269 if (GET_CODE (x) == REG)
1270 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
1272 print_operand (file, x, 'R');
1276 bitint = INTVAL (x);
1277 fprintf (file, "#%d", bitint & 7);
1280 switch (GET_CODE (x))
1283 fprintf (file, "bor");
1286 fprintf (file, "bxor");
1289 fprintf (file, "band");
1296 switch (GET_CODE (x))
1300 fprintf (file, "%s", names_big[REGNO (x)]);
1302 fprintf (file, "%s", names_upper_extended[REGNO (x)]);
1305 print_operand (file, x, 0);
1308 fprintf (file, "#%d", ((INTVAL (x) >> 16) & 0xffff));
1314 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1315 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1316 fprintf (file, "#%ld", ((val >> 16) & 0xffff));
1325 switch (GET_CODE (x))
1329 fprintf (file, "%s", names_big[REGNO (x) + 1]);
1331 fprintf (file, "%s", names_big[REGNO (x)]);
1334 x = adjust_address (x, HImode, 2);
1335 print_operand (file, x, 0);
1338 fprintf (file, "#%d", INTVAL (x) & 0xffff);
1344 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1345 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1346 fprintf (file, "#%ld", (val & 0xffff));
1354 fputs (cond_string (GET_CODE (x)), file);
1357 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1360 if (GET_CODE (x) == CONST_INT)
1361 fprintf (file, "#%d", (INTVAL (x)) & 0xff);
1363 fprintf (file, "%s", byte_reg (x, 0));
1366 if (GET_CODE (x) == CONST_INT)
1367 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1369 fprintf (file, "%s", byte_reg (x, 1));
1372 if (GET_CODE (x) != CONST_INT)
1374 fprintf (file, "%d", INTVAL (x));
1377 if (GET_CODE (x) == CONST_INT)
1378 fprintf (file, "#%d", INTVAL (x) & 0xff);
1380 fprintf (file, "%s",
1381 byte_reg (x, TARGET_H8300 ? 2 : 0));
1384 if (GET_CODE (x) == CONST_INT)
1385 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1387 fprintf (file, "%s",
1388 byte_reg (x, TARGET_H8300 ? 3 : 1));
1391 if (GET_CODE (x) == CONST_INT)
1392 fprintf (file, "#%d", (INTVAL (x) >> 16) & 0xff);
1394 fprintf (file, "%s", byte_reg (x, 0));
1397 if (GET_CODE (x) == CONST_INT)
1398 fprintf (file, "#%d", (INTVAL (x) >> 24) & 0xff);
1400 fprintf (file, "%s", byte_reg (x, 1));
1405 switch (GET_CODE (x))
1408 switch (GET_MODE (x))
1411 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */
1412 fprintf (file, "%s", byte_reg (x, 0));
1413 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1414 fprintf (file, "%s", names_big[REGNO (x)]);
1418 fprintf (file, "%s", names_big[REGNO (x)]);
1422 fprintf (file, "%s", names_extended[REGNO (x)]);
1431 rtx addr = XEXP (x, 0);
1432 int eightbit_ok = ((GET_CODE (addr) == SYMBOL_REF
1433 && SYMBOL_REF_FLAG (addr))
1434 || EIGHTBIT_CONSTANT_ADDRESS_P (addr));
1435 int tiny_ok = ((GET_CODE (addr) == SYMBOL_REF
1436 && TINY_DATA_NAME_P (XSTR (addr, 0)))
1437 || TINY_CONSTANT_ADDRESS_P (addr));
1439 fprintf (file, "@");
1440 output_address (addr);
1442 /* We fall back from smaller addressing to larger
1443 addressing in various ways depending on CODE. */
1447 /* Used for mov.b and bit operations. */
1450 fprintf (file, ":8");
1454 /* Fall through. We should not get here if we are
1455 processing bit operations on H8/300 or H8/300H
1456 because 'U' constraint does not allow bit
1457 operations on the tiny area on these machines. */
1461 /* Used for mov.w and mov.l. */
1463 fprintf (file, ":16");
1475 fprintf (file, "#");
1476 print_operand_address (file, x);
1482 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1483 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1484 fprintf (file, "#%ld", val);
1493 /* Output assembly language output for the address ADDR to FILE. */
1496 print_operand_address (file, addr)
1500 switch (GET_CODE (addr))
1503 fprintf (file, "%s", h8_reg_names[REGNO (addr)]);
1507 fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
1511 fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);
1515 fprintf (file, "(");
1516 if (GET_CODE (XEXP (addr, 0)) == REG)
1519 print_operand_address (file, XEXP (addr, 1));
1520 fprintf (file, ",");
1521 print_operand_address (file, XEXP (addr, 0));
1526 print_operand_address (file, XEXP (addr, 0));
1527 fprintf (file, "+");
1528 print_operand_address (file, XEXP (addr, 1));
1530 fprintf (file, ")");
1535 /* Since the H8/300 only has 16 bit pointers, negative values are also
1536 those >= 32768. This happens for example with pointer minus a
1537 constant. We don't want to turn (char *p - 2) into
1538 (char *p + 65534) because loop unrolling can build upon this
1539 (IE: char *p + 131068). */
1540 int n = INTVAL (addr);
1542 n = (int) (short) n;
1544 /* ??? Why the special case for -ve values? */
1545 fprintf (file, "-%d", -n);
1547 fprintf (file, "%d", n);
1552 output_addr_const (file, addr);
1557 /* Output all insn addresses and their sizes into the assembly language
1558 output file. This is helpful for debugging whether the length attributes
1559 in the md file are correct. This is not meant to be a user selectable
1563 final_prescan_insn (insn, operand, num_operands)
1564 rtx insn, *operand ATTRIBUTE_UNUSED;
1565 int num_operands ATTRIBUTE_UNUSED;
1567 /* This holds the last insn address. */
1568 static int last_insn_address = 0;
1570 int uid = INSN_UID (insn);
1572 if (TARGET_RTL_DUMP)
1574 fprintf (asm_out_file, "\n****************");
1575 print_rtl (asm_out_file, PATTERN (insn));
1576 fprintf (asm_out_file, "\n");
1579 if (TARGET_ADDRESSES)
1581 fprintf (asm_out_file, "; 0x%x %d\n", INSN_ADDRESSES (uid),
1582 INSN_ADDRESSES (uid) - last_insn_address);
1583 last_insn_address = INSN_ADDRESSES (uid);
1587 /* Prepare for an SI sized move. */
1593 rtx src = operands[1];
1594 rtx dst = operands[0];
1595 if (!reload_in_progress && !reload_completed)
1597 if (!register_operand (dst, GET_MODE (dst)))
1599 rtx tmp = gen_reg_rtx (GET_MODE (dst));
1600 emit_move_insn (tmp, src);
1607 /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
1608 Define the offset between two registers, one to be eliminated, and
1609 the other its replacement, at the start of a routine. */
1612 initial_offset (from, to)
1617 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1618 offset = UNITS_PER_WORD + frame_pointer_needed * UNITS_PER_WORD;
1619 else if (from == RETURN_ADDRESS_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1620 offset = frame_pointer_needed * UNITS_PER_WORD;
1625 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1626 if (WORD_REG_USED (regno))
1627 offset += UNITS_PER_WORD;
1629 /* See the comments for get_frame_size. We need to round it up to
1632 offset += ((get_frame_size () + STACK_BOUNDARY / BITS_PER_UNIT - 1)
1633 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
1635 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1636 offset += UNITS_PER_WORD; /* Skip saved PC */
1642 h8300_return_addr_rtx (count, frame)
1649 ret = gen_rtx_MEM (Pmode,
1650 gen_rtx_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM));
1651 else if (flag_omit_frame_pointer)
1654 ret = gen_rtx_MEM (Pmode,
1655 memory_address (Pmode,
1656 plus_constant (frame, UNITS_PER_WORD)));
1657 set_mem_alias_set (ret, get_frame_alias_set ());
1661 /* Update the condition code from the insn. */
1664 notice_update_cc (body, insn)
1668 switch (get_attr_cc (insn))
1671 /* Insn does not affect CC at all. */
1675 /* Insn does not change CC, but the 0'th operand has been changed. */
1676 if (cc_status.value1 != 0
1677 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
1678 cc_status.value1 = 0;
1679 if (cc_status.value2 != 0
1680 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value2))
1681 cc_status.value2 = 0;
1685 /* Insn sets the Z,N flags of CC to recog_data.operand[0].
1686 The V flag is unusable. The C flag may or may not be known but
1687 that's ok because alter_cond will change tests to use EQ/NE. */
1689 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
1690 cc_status.value1 = recog_data.operand[0];
1694 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
1695 The C flag may or may not be known but that's ok because
1696 alter_cond will change tests to use EQ/NE. */
1698 cc_status.flags |= CC_NO_CARRY;
1699 cc_status.value1 = recog_data.operand[0];
1700 if (GET_CODE (body) == SET && REG_P (SET_SRC (body)))
1701 cc_status.value2 = SET_SRC (body);
1705 /* The insn is a compare instruction. */
1707 cc_status.value1 = SET_SRC (body);
1711 /* Insn doesn't leave CC in a usable state. */
1717 /* Recognize valid operators for bit instructions. */
1720 bit_operator (x, mode)
1722 enum machine_mode mode ATTRIBUTE_UNUSED;
1724 enum rtx_code code = GET_CODE (x);
1732 output_logical_op (mode, operands)
1733 enum machine_mode mode;
1736 /* Figure out the logical op that we need to perform. */
1737 enum rtx_code code = GET_CODE (operands[3]);
1738 /* Pretend that every byte is affected if both operands are registers. */
1739 unsigned HOST_WIDE_INT intval =
1740 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
1741 ? INTVAL (operands[2]) : 0x55555555);
1742 /* The determinant of the algorithm. If we perform an AND, 0
1743 affects a bit. Otherwise, 1 affects a bit. */
1744 unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
1745 /* The name of an insn. */
1767 /* First, see if we can finish with one insn. */
1768 if ((TARGET_H8300H || TARGET_H8300S)
1769 && ((det & 0x00ff) != 0)
1770 && ((det & 0xff00) != 0))
1772 sprintf (insn_buf, "%s.w\t%%T2,%%T0", opname);
1773 output_asm_insn (insn_buf, operands);
1777 /* Take care of the lower byte. */
1778 if ((det & 0x00ff) != 0)
1780 sprintf (insn_buf, "%s\t%%s2,%%s0", opname);
1781 output_asm_insn (insn_buf, operands);
1783 /* Take care of the upper byte. */
1784 if ((det & 0xff00) != 0)
1786 sprintf (insn_buf, "%s\t%%t2,%%t0", opname);
1787 output_asm_insn (insn_buf, operands);
1792 /* First, see if we can finish with one insn.
1794 If code is either AND or XOR, we exclude two special cases,
1795 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
1796 can do a better job. */
1797 if ((TARGET_H8300H || TARGET_H8300S)
1798 && ((det & 0x0000ffff) != 0)
1799 && ((det & 0xffff0000) != 0)
1800 && (code == IOR || det != 0xffffff00)
1801 && (code == IOR || det != 0xffff00ff))
1803 sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname);
1804 output_asm_insn (insn_buf, operands);
1808 /* Take care of the lower and upper words individually. For
1809 each word, we try different methods in the order of
1811 1) the special insn (in case of AND or XOR),
1812 2) the word-wise insn, and
1813 3) The byte-wise insn. */
1814 if ((det & 0x0000ffff) == 0x0000ffff
1815 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
1816 output_asm_insn ((code == AND)
1817 ? "sub.w\t%f0,%f0" : "not.w\t%f0",
1819 else if ((TARGET_H8300H || TARGET_H8300S)
1820 && ((det & 0x000000ff) != 0)
1821 && ((det & 0x0000ff00) != 0))
1823 sprintf (insn_buf, "%s.w\t%%f2,%%f0", opname);
1824 output_asm_insn (insn_buf, operands);
1828 if ((det & 0x000000ff) != 0)
1830 sprintf (insn_buf, "%s\t%%w2,%%w0", opname);
1831 output_asm_insn (insn_buf, operands);
1833 if ((det & 0x0000ff00) != 0)
1835 sprintf (insn_buf, "%s\t%%x2,%%x0", opname);
1836 output_asm_insn (insn_buf, operands);
1840 if ((det & 0xffff0000) == 0xffff0000
1841 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
1842 output_asm_insn ((code == AND)
1843 ? "sub.w\t%e0,%e0" : "not.w\t%e0",
1845 else if (TARGET_H8300H || TARGET_H8300S)
1847 if ((det & 0xffff0000) != 0)
1849 sprintf (insn_buf, "%s.w\t%%e2,%%e0", opname);
1850 output_asm_insn (insn_buf, operands);
1855 if ((det & 0x00ff0000) != 0)
1857 sprintf (insn_buf, "%s\t%%y2,%%y0", opname);
1858 output_asm_insn (insn_buf, operands);
1860 if ((det & 0xff000000) != 0)
1862 sprintf (insn_buf, "%s\t%%z2,%%z0", opname);
1863 output_asm_insn (insn_buf, operands);
1875 compute_logical_op_length (mode, operands)
1876 enum machine_mode mode;
1879 /* Figure out the logical op that we need to perform. */
1880 enum rtx_code code = GET_CODE (operands[3]);
1881 /* Pretend that every byte is affected if both operands are registers. */
1882 unsigned HOST_WIDE_INT intval =
1883 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
1884 ? INTVAL (operands[2]) : 0x55555555);
1885 /* The determinant of the algorithm. If we perform an AND, 0
1886 affects a bit. Otherwise, 1 affects a bit. */
1887 unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
1889 unsigned int length = 0;
1894 /* First, see if we can finish with one insn. */
1895 if ((TARGET_H8300H || TARGET_H8300S)
1896 && ((det & 0x00ff) != 0)
1897 && ((det & 0xff00) != 0))
1899 if (REG_P (operands[2]))
1906 /* Take care of the lower byte. */
1907 if ((det & 0x00ff) != 0)
1910 /* Take care of the upper byte. */
1911 if ((det & 0xff00) != 0)
1916 /* First, see if we can finish with one insn.
1918 If code is either AND or XOR, we exclude two special cases,
1919 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
1920 can do a better job. */
1921 if ((TARGET_H8300H || TARGET_H8300S)
1922 && ((det & 0x0000ffff) != 0)
1923 && ((det & 0xffff0000) != 0)
1924 && (code == IOR || det != 0xffffff00)
1925 && (code == IOR || det != 0xffff00ff))
1927 if (REG_P (operands[2]))
1934 /* Take care of the lower and upper words individually. For
1935 each word, we try different methods in the order of
1937 1) the special insn (in case of AND or XOR),
1938 2) the word-wise insn, and
1939 3) The byte-wise insn. */
1940 if ((det & 0x0000ffff) == 0x0000ffff
1941 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
1945 else if ((TARGET_H8300H || TARGET_H8300S)
1946 && ((det & 0x000000ff) != 0)
1947 && ((det & 0x0000ff00) != 0))
1953 if ((det & 0x000000ff) != 0)
1956 if ((det & 0x0000ff00) != 0)
1960 if ((det & 0xffff0000) == 0xffff0000
1961 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
1965 else if (TARGET_H8300H || TARGET_H8300S)
1967 if ((det & 0xffff0000) != 0)
1972 if ((det & 0x00ff0000) != 0)
1975 if ((det & 0xff000000) != 0)
1987 compute_logical_op_cc (mode, operands)
1988 enum machine_mode mode;
1991 /* Figure out the logical op that we need to perform. */
1992 enum rtx_code code = GET_CODE (operands[3]);
1993 /* Pretend that every byte is affected if both operands are registers. */
1994 unsigned HOST_WIDE_INT intval =
1995 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
1996 ? INTVAL (operands[2]) : 0x55555555);
1997 /* The determinant of the algorithm. If we perform an AND, 0
1998 affects a bit. Otherwise, 1 affects a bit. */
1999 unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
2000 /* Condition code. */
2001 enum attr_cc cc = CC_CLOBBER;
2006 /* First, see if we can finish with one insn. */
2007 if ((TARGET_H8300H || TARGET_H8300S)
2008 && ((det & 0x00ff) != 0)
2009 && ((det & 0xff00) != 0))
2015 /* First, see if we can finish with one insn.
2017 If code is either AND or XOR, we exclude two special cases,
2018 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
2019 can do a better job. */
2020 if ((TARGET_H8300H || TARGET_H8300S)
2021 && ((det & 0x0000ffff) != 0)
2022 && ((det & 0xffff0000) != 0)
2023 && (code == IOR || det != 0xffffff00)
2024 && (code == IOR || det != 0xffff00ff))
2037 We devote a fair bit of code to getting efficient shifts since we
2038 can only shift one bit at a time on the H8/300 and H8/300H and only
2039 one or two bits at a time on the H8S.
2041 All shift code falls into one of the following ways of
2044 o SHIFT_INLINE: Emit straight line code for the shift; this is used
2045 when a straight line shift is about the same size or smaller than
2048 o SHIFT_ROT_AND: Rotate the value the opposite direction, then mask
2049 off the bits we don't need. This is used when only a few of the
2050 bits in the original value will survive in the shifted value.
2052 o SHIFT_SPECIAL: Often it's possible to move a byte or a word to
2053 simulate a shift by 8, 16, or 24 bits. Once moved, a few inline
2054 shifts can be added if the shift count is slightly more than 8 or
2055 16. This case also includes other oddballs that are not worth
2058 o SHIFT_LOOP: Emit a loop using one (or two on H8S) bit shifts.
2060 Here are some thoughts on what the absolutely positively best code
2061 is. "Best" here means some rational trade-off between code size
2062 and speed, where speed is more preferred but not at the expense of
2063 generating 20 insns.
2065 Below, a trailing '*' after the shift count indicates the "best"
2066 mode isn't implemented. We only describe SHIFT_SPECIAL cases to
2067 simplify the table. For other cases, refer to shift_alg_[qhs]i.
2069 H8/300 QImode shifts
2070 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
2072 H8/300 HImode shifts
2073 7 - shift 2nd half other way into carry.
2074 copy 1st half into 2nd half
2075 rotate 2nd half other way with carry
2076 rotate 1st half other way (no carry)
2077 mask off bits in 1st half (ASHIFT | LSHIFTRT).
2078 sign extend 1st half (ASHIFTRT)
2079 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
2080 9-12 - do shift by 8, inline remaining shifts
2081 15 - ASHIFTRT: shll, subx, set other byte
2083 H8/300 SImode shifts
2084 7* - shift other way once, move bytes into place,
2085 move carry into place (possibly with sign extension)
2086 8 - move bytes into place, zero or sign extend other
2087 15* - shift other way once, move word into place, move carry into place
2088 16 - move word, zero or sign extend other
2089 24* - move bytes into place, zero or sign extend other
2090 31 - ASHIFTRT: shll top byte, subx, copy to other bytes
2092 H8/300H QImode shifts (same as H8/300 QImode shifts)
2093 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
2095 H8/300H HImode shifts
2096 7 - shift 2nd half other way into carry.
2097 copy 1st half into 2nd half
2098 rotate entire word other way using carry
2099 mask off remaining bits (ASHIFT | LSHIFTRT)
2100 sign extend remaining bits (ASHIFTRT)
2101 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
2102 9-12 - do shift by 8, inline remaining shifts
2103 15 - ASHIFTRT: shll, subx, set other byte
2105 H8/300H SImode shifts
2106 (These are complicated by the fact that we don't have byte level access to
2108 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
2109 15* - shift other way once, move word into place, move carry into place
2110 (with sign extension for ASHIFTRT)
2111 16 - move word into place, zero or sign extend other
2112 17-20 - do 16bit shift, then inline remaining shifts
2113 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
2114 move word 0 to word 1, zero word 0
2115 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
2116 zero word 1, zero byte 1
2117 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
2118 sign extend byte 0, sign extend word 0
2119 25-27* - either loop, or
2120 do 24 bit shift, inline rest
2121 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
2124 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
2127 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
2128 9-12 - do shift by 8, inline remaining shifts
2129 15 - ASHIFTRT: shll, subx, set other byte
2132 (These are complicated by the fact that we don't have byte level access to
2134 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
2135 15* - shift other way once, move word into place, move carry into place
2136 (with sign extension for ASHIFTRT)
2137 16 - move word into place, zero or sign extend other
2138 17-20 - do 16bit shift, then inline remaining shifts
2139 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
2140 move word 0 to word 1, zero word 0
2141 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
2142 zero word 1, zero byte 1
2143 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
2144 sign extend byte 0, sign extend word 0
2145 25-27* - either loop, or
2146 do 24 bit shift, inline rest
2147 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
2152 nshift_operator (x, mode)
2154 enum machine_mode mode ATTRIBUTE_UNUSED;
2156 switch (GET_CODE (x))
2168 /* Called from the .md file to emit code to do shifts.
2169 Return a boolean indicating success.
2170 (Currently this is always TRUE). */
2173 expand_a_shift (mode, code, operands)
2174 enum machine_mode mode;
2178 emit_move_insn (operands[0], operands[1]);
2180 /* Need a loop to get all the bits we want - we generate the
2181 code at emit time, but need to allocate a scratch reg now. */
2183 emit_insn (gen_rtx_PARALLEL
2186 gen_rtx_SET (VOIDmode, operands[0],
2187 gen_rtx (code, mode, operands[0],
2189 gen_rtx_CLOBBER (VOIDmode,
2190 gen_rtx_SCRATCH (QImode)))));
2195 /* Symbols of the various modes which can be used as indices. */
2199 QIshift, HIshift, SIshift
2202 /* For single bit shift insns, record assembler and what bits of the
2203 condition code are valid afterwards (represented as various CC_FOO
2204 bits, 0 means CC isn't left in a usable state). */
2208 const char *const assembler;
2212 /* Assembler instruction shift table.
2214 These tables are used to look up the basic shifts.
2215 They are indexed by cpu, shift_type, and mode. */
2217 static const struct shift_insn shift_one[2][3][3] =
2223 { "shll\t%X0", CC_NO_CARRY },
2224 { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2225 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }
2227 /* SHIFT_LSHIFTRT */
2229 { "shlr\t%X0", CC_NO_CARRY },
2230 { "shlr\t%t0\n\trotxr\t%s0", 0 },
2231 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
2233 /* SHIFT_ASHIFTRT */
2235 { "shar\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2236 { "shar\t%t0\n\trotxr\t%s0", 0 },
2237 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
2244 { "shll.b\t%X0", CC_NO_CARRY },
2245 { "shll.w\t%T0", CC_NO_CARRY },
2246 { "shll.l\t%S0", CC_NO_CARRY }
2248 /* SHIFT_LSHIFTRT */
2250 { "shlr.b\t%X0", CC_NO_CARRY },
2251 { "shlr.w\t%T0", CC_NO_CARRY },
2252 { "shlr.l\t%S0", CC_NO_CARRY }
2254 /* SHIFT_ASHIFTRT */
2256 { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2257 { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2258 { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
2263 static const struct shift_insn shift_two[3][3] =
2267 { "shll.b\t#2,%X0", CC_NO_CARRY },
2268 { "shll.w\t#2,%T0", CC_NO_CARRY },
2269 { "shll.l\t#2,%S0", CC_NO_CARRY }
2271 /* SHIFT_LSHIFTRT */
2273 { "shlr.b\t#2,%X0", CC_NO_CARRY },
2274 { "shlr.w\t#2,%T0", CC_NO_CARRY },
2275 { "shlr.l\t#2,%S0", CC_NO_CARRY }
2277 /* SHIFT_ASHIFTRT */
2279 { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2280 { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
2281 { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
2285 /* Rotates are organized by which shift they'll be used in implementing.
2286 There's no need to record whether the cc is valid afterwards because
2287 it is the AND insn that will decide this. */
2289 static const char *const rotate_one[2][3][3] =
2296 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
2299 /* SHIFT_LSHIFTRT */
2302 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
2305 /* SHIFT_ASHIFTRT */
2308 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
2320 /* SHIFT_LSHIFTRT */
2326 /* SHIFT_ASHIFTRT */
2335 static const char *const rotate_two[3][3] =
2343 /* SHIFT_LSHIFTRT */
2349 /* SHIFT_ASHIFTRT */
2358 /* Shift algorithm. */
2361 /* The number of bits to be shifted by shift1 and shift2. Valid
2362 when ALG is SHIFT_SPECIAL. */
2363 unsigned int remainder;
2365 /* Special insn for a shift. Valid when ALG is SHIFT_SPECIAL. */
2366 const char *special;
2368 /* Insn for a one-bit shift. Valid when ALG is either SHIFT_INLINE
2369 or SHIFT_SPECIAL, and REMAINDER is nonzero. */
2372 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
2373 or SHIFT_SPECIAL, and REMAINDER is nonzero. */
2376 /* Valid CC flags. */
2380 static void get_shift_alg PARAMS ((enum shift_type,
2381 enum shift_mode, unsigned int,
2382 struct shift_info *));
2384 /* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
2385 best algorithm for doing the shift. The assembler code is stored
2386 in the pointers in INFO. We don't achieve maximum efficiency in
2387 all cases, but the hooks are here to do so.
2389 For now we just use lots of switch statements. Since we don't even come
2390 close to supporting all the cases, this is simplest. If this function ever
2391 gets too big, perhaps resort to a more table based lookup. Of course,
2392 at this point you may just wish to do it all in rtl.
2394 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
2395 1,2,3,4 will be inlined (1,2 for SI). */
2398 get_shift_alg (shift_type, shift_mode, count, info)
2399 enum shift_type shift_type;
2400 enum shift_mode shift_mode;
2402 struct shift_info *info;
2406 /* Find the target CPU. */
2409 else if (TARGET_H8300H)
2414 /* Find the shift algorithm. */
2415 info->alg = SHIFT_LOOP;
2419 if (count < GET_MODE_BITSIZE (QImode))
2420 info->alg = shift_alg_qi[cpu][shift_type][count];
2424 if (count < GET_MODE_BITSIZE (HImode))
2425 info->alg = shift_alg_hi[cpu][shift_type][count];
2429 if (count < GET_MODE_BITSIZE (SImode))
2430 info->alg = shift_alg_si[cpu][shift_type][count];
2437 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
2441 info->remainder = count;
2445 /* It is up to the caller to know that looping clobbers cc. */
2446 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2447 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2448 info->cc_valid_p = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
2452 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
2453 info->shift2 = rotate_two[shift_type][shift_mode];
2454 info->cc_valid_p = 0;
2458 /* REMAINDER is 0 for most cases, so initialize it to 0. */
2459 info->remainder = 0;
2460 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2461 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2462 info->cc_valid_p = 0;
2466 /* Here we only deal with SHIFT_SPECIAL. */
2470 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2471 through the entire value. */
2472 if (shift_type == SHIFT_ASHIFTRT && count == 7)
2474 info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
2486 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.b\t%t0\n\trotr.b\t%s0\n\tand.b\t#0x80,%s0";
2488 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
2490 case SHIFT_LSHIFTRT:
2492 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\trotl.b\t%t0\n\tand.b\t#0x01,%t0";
2494 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
2496 case SHIFT_ASHIFTRT:
2497 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
2501 else if (8 <= count && count <= 13)
2503 info->remainder = count - 8;
2508 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
2509 info->shift1 = "shal.b\t%t0";
2510 info->shift2 = "shal.b\t#2,%t0";
2512 case SHIFT_LSHIFTRT:
2513 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
2514 info->shift1 = "shlr.b\t%s0";
2515 info->shift2 = "shlr.b\t#2,%s0";
2517 case SHIFT_ASHIFTRT:
2519 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
2521 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
2522 info->shift1 = "shar.b\t%s0";
2523 info->shift2 = "shar.b\t#2,%s0";
2527 else if (count == 14)
2533 info->special = "mov.b\t%s0,%t0\n\trotr.b\t%t0\n\trotr.b\t%t0\n\tand.b\t#0xC0,%t0\n\tsub.b\t%s0,%s0";
2535 case SHIFT_LSHIFTRT:
2537 info->special = "mov.b\t%t0,%s0\n\trotl.b\t%s0\n\trotl.b\t%s0\n\tand.b\t#3,%s0\n\tsub.b\t%t0,%t0";
2539 case SHIFT_ASHIFTRT:
2541 info->special = "mov.b\t%t0,%s0\n\tshll.b\t%s0\n\tsubx.b\t%t0,%t0\n\tshll.b\t%s0\n\tmov.b\t%t0,%s0\n\tbst.b\t#0,%s0";
2542 else if (TARGET_H8300H)
2543 info->special = "shll.b\t%t0\n\tsubx.b\t%s0,%s0\n\tshll.b\t%t0\n\trotxl.b\t%s0\n\texts.w\t%T0";
2544 else /* TARGET_H8300S */
2545 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.w\t#2,%T0\n\tshar.w\t#2,%T0\n\tshar.w\t#2,%T0";
2549 else if (count == 15)
2554 info->special = "bld\t#0,%s0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#7,%t0";
2556 case SHIFT_LSHIFTRT:
2557 info->special = "bld\t#7,%t0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#0,%s0";
2559 case SHIFT_ASHIFTRT:
2560 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
2567 if (TARGET_H8300 && 8 <= count && count <= 9)
2569 info->remainder = count - 8;
2574 info->special = "mov.b\t%y0,%z0\n\tmov.b\t%x0,%y0\n\tmov.b\t%w0,%x0\n\tsub.b\t%w0,%w0";
2576 case SHIFT_LSHIFTRT:
2577 info->special = "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tsub.b\t%z0,%z0";
2578 info->shift1 = "shlr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0";
2580 case SHIFT_ASHIFTRT:
2581 info->special = "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tshll\t%z0\n\tsubx\t%z0,%z0";
2585 else if (count == 8 && !TARGET_H8300)
2590 info->special = "mov.w\t%e0,%f4\n\tmov.b\t%s4,%t4\n\tmov.b\t%t0,%s4\n\tmov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f4,%e0";
2592 case SHIFT_LSHIFTRT:
2593 info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\textu.w\t%f4\n\tmov.w\t%f4,%e0";
2595 case SHIFT_ASHIFTRT:
2596 info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\texts.w\t%f4\n\tmov.w\t%f4,%e0";
2600 else if (count == 15 && TARGET_H8300)
2606 case SHIFT_LSHIFTRT:
2607 info->special = "bld\t#7,%z0\n\tmov.w\t%e0,%f0\n\txor\t%y0,%y0\n\txor\t%z0,%z0\n\trotxl\t%w0,%w0\n\trotxl\t%x0,%x0\n\trotxl\t%y0,%y0";
2609 case SHIFT_ASHIFTRT:
2610 info->special = "bld\t#7,%z0\n\tmov.w\t%e0,%f0\n\trotxl\t%w0,%w0\n\trotxl\t%x0,%x0\n\tsubx\t%y0,%y0\n\tsubx\t%z0,%z0";
2614 else if (count == 15 && !TARGET_H8300)
2619 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
2621 case SHIFT_LSHIFTRT:
2622 info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
2624 case SHIFT_ASHIFTRT:
2628 else if ((TARGET_H8300 && 16 <= count && count <= 20)
2629 || (TARGET_H8300H && 16 <= count && count <= 19)
2630 || (TARGET_H8300S && 16 <= count && count <= 21))
2632 info->remainder = count - 16;
2637 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2640 info->shift1 = "add.w\t%e0,%e0";
2644 info->shift1 = "shll.l\t%S0";
2645 info->shift2 = "shll.l\t#2,%S0";
2648 case SHIFT_LSHIFTRT:
2649 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
2652 info->shift1 = "shlr\t%x0\n\trotxr\t%w0";
2656 info->shift1 = "shlr.l\t%S0";
2657 info->shift2 = "shlr.l\t#2,%S0";
2660 case SHIFT_ASHIFTRT:
2663 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2664 info->shift1 = "shar\t%x0\n\trotxr\t%w0";
2668 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
2669 info->shift1 = "shar.l\t%S0";
2670 info->shift2 = "shar.l\t#2,%S0";
2675 else if (TARGET_H8300 && 24 <= count && count <= 28)
2677 info->remainder = count - 24;
2682 info->special = "mov.b\t%w0,%z0\n\tsub.b\t%y0,%y0\n\tsub.w\t%f0,%f0";
2683 info->shift1 = "shll.b\t%z0";
2685 case SHIFT_LSHIFTRT:
2686 info->special = "mov.b\t%z0,%w0\n\tsub.b\t%x0,%x0\n\tsub.w\t%e0,%e0";
2687 info->shift1 = "shlr.b\t%w0";
2689 case SHIFT_ASHIFTRT:
2690 info->special = "mov.b\t%z0,%w0\n\tbld\t#7,%w0\n\tsubx\t%x0,%x0\n\tsubx\t%x0,%x0\n\tsubx\t%x0,%x0";
2691 info->shift1 = "shar.b\t%w0";
2695 else if ((TARGET_H8300H && count == 24)
2696 || (TARGET_H8300S && 24 <= count && count <= 25))
2698 info->remainder = count - 24;
2703 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2704 info->shift1 = "shll.l\t%S0";
2705 info->shift2 = "shll.l\t#2,%S0";
2707 case SHIFT_LSHIFTRT:
2708 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
2709 info->shift1 = "shlr.l\t%S0";
2710 info->shift2 = "shlr.l\t#2,%S0";
2712 case SHIFT_ASHIFTRT:
2713 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
2714 info->shift1 = "shar.l\t%S0";
2715 info->shift2 = "shar.l\t#2,%S0";
2719 else if (count == 31)
2726 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2728 case SHIFT_LSHIFTRT:
2729 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2731 case SHIFT_ASHIFTRT:
2732 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2741 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
2743 case SHIFT_LSHIFTRT:
2744 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
2746 case SHIFT_ASHIFTRT:
2747 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2760 info->shift2 = NULL;
2763 /* Given COUNT and MODE of a shift, return 1 if a scratch reg may be
2764 needed for some shift with COUNT and MODE. Return 0 otherwise. */
2767 h8300_shift_needs_scratch_p (count, mode)
2769 enum machine_mode mode;
2774 if (GET_MODE_BITSIZE (mode) <= count)
2777 /* Find out the target CPU. */
2780 else if (TARGET_H8300H)
2785 /* Find the shift algorithm. */
2789 a = shift_alg_qi[cpu][SHIFT_ASHIFT][count];
2790 lr = shift_alg_qi[cpu][SHIFT_LSHIFTRT][count];
2791 ar = shift_alg_qi[cpu][SHIFT_ASHIFTRT][count];
2795 a = shift_alg_hi[cpu][SHIFT_ASHIFT][count];
2796 lr = shift_alg_hi[cpu][SHIFT_LSHIFTRT][count];
2797 ar = shift_alg_hi[cpu][SHIFT_ASHIFTRT][count];
2801 a = shift_alg_si[cpu][SHIFT_ASHIFT][count];
2802 lr = shift_alg_si[cpu][SHIFT_LSHIFTRT][count];
2803 ar = shift_alg_si[cpu][SHIFT_ASHIFTRT][count];
2810 /* On H8/300H and H8S, count == 8 uses the scratch register. */
2811 return (a == SHIFT_LOOP || lr == SHIFT_LOOP || ar == SHIFT_LOOP
2812 || (!TARGET_H8300 && mode == SImode && count == 8));
2815 /* Emit the assembler code for doing shifts. */
2818 output_a_shift (operands)
2821 static int loopend_lab;
2822 rtx shift = operands[3];
2823 enum machine_mode mode = GET_MODE (shift);
2824 enum rtx_code code = GET_CODE (shift);
2825 enum shift_type shift_type;
2826 enum shift_mode shift_mode;
2827 struct shift_info info;
2834 shift_mode = QIshift;
2837 shift_mode = HIshift;
2840 shift_mode = SIshift;
2849 shift_type = SHIFT_ASHIFTRT;
2852 shift_type = SHIFT_LSHIFTRT;
2855 shift_type = SHIFT_ASHIFT;
2861 if (GET_CODE (operands[2]) != CONST_INT)
2863 /* Indexing by reg, so have to loop and test at top. */
2864 output_asm_insn ("mov.b %X2,%X4", operands);
2865 fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab);
2867 /* Get the assembler code to do one shift. */
2868 get_shift_alg (shift_type, shift_mode, 1, &info);
2870 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2871 output_asm_insn (info.shift1, operands);
2872 output_asm_insn ("add #0xff,%X4", operands);
2873 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2874 fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
2880 int n = INTVAL (operands[2]);
2882 /* If the count is negative, make it 0. */
2885 /* If the count is too big, truncate it.
2886 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2887 do the intuitive thing. */
2888 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
2889 n = GET_MODE_BITSIZE (mode);
2891 get_shift_alg (shift_type, shift_mode, n, &info);
2896 output_asm_insn (info.special, operands);
2902 /* Emit two bit shifts first. */
2903 if (info.shift2 != NULL)
2905 for (; n > 1; n -= 2)
2906 output_asm_insn (info.shift2, operands);
2909 /* Now emit one bit shifts for any residual. */
2911 output_asm_insn (info.shift1, operands);
2913 /* Keep track of CC. */
2914 if (info.cc_valid_p)
2916 cc_status.value1 = operands[0];
2917 cc_status.flags |= info.cc_valid_p;
2923 int m = GET_MODE_BITSIZE (mode) - n;
2924 int mask = (shift_type == SHIFT_ASHIFT
2925 ? ((1 << m) - 1) << n
2929 /* Not all possibilities of rotate are supported. They shouldn't
2930 be generated, but let's watch for 'em. */
2931 if (info.shift1 == 0)
2934 /* Emit two bit rotates first. */
2935 if (info.shift2 != NULL)
2937 for (; m > 1; m -= 2)
2938 output_asm_insn (info.shift2, operands);
2941 /* Now single bit rotates for any residual. */
2943 output_asm_insn (info.shift1, operands);
2945 /* Now mask off the high bits. */
2951 sprintf (insn_buf, "and\t#%d,%%X0", mask);
2952 cc_status.value1 = operands[0];
2953 cc_status.flags |= CC_NO_CARRY;
2956 sprintf (insn_buf, "and\t#%d,%%s0\n\tand\t#%d,%%t0",
2957 mask & 255, mask >> 8);
2965 sprintf (insn_buf, "and.%c\t#%d,%%%c0",
2966 "bwl"[shift_mode], mask,
2967 mode == QImode ? 'X' : mode == HImode ? 'T' : 'S');
2968 cc_status.value1 = operands[0];
2969 cc_status.flags |= CC_NO_CARRY;
2971 output_asm_insn (insn_buf, operands);
2976 /* A loop to shift by a "large" constant value.
2977 If we have shift-by-2 insns, use them. */
2978 if (info.shift2 != NULL)
2980 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
2981 names_big[REGNO (operands[4])]);
2982 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2983 output_asm_insn (info.shift2, operands);
2984 output_asm_insn ("add #0xff,%X4", operands);
2985 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2987 output_asm_insn (info.shift1, operands);
2991 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
2992 names_big[REGNO (operands[4])]);
2993 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2994 output_asm_insn (info.shift1, operands);
2995 output_asm_insn ("add #0xff,%X4", operands);
2996 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
3007 h8300_asm_insn_count (template)
3008 const char *template;
3010 unsigned int count = 1;
3012 for (; *template; template++)
3013 if (*template == '\n')
3020 compute_a_shift_length (insn, operands)
3021 rtx insn ATTRIBUTE_UNUSED;
3024 rtx shift = operands[3];
3025 enum machine_mode mode = GET_MODE (shift);
3026 enum rtx_code code = GET_CODE (shift);
3027 enum shift_type shift_type;
3028 enum shift_mode shift_mode;
3029 struct shift_info info;
3030 unsigned int wlength = 0;
3035 shift_mode = QIshift;
3038 shift_mode = HIshift;
3041 shift_mode = SIshift;
3050 shift_type = SHIFT_ASHIFTRT;
3053 shift_type = SHIFT_LSHIFTRT;
3056 shift_type = SHIFT_ASHIFT;
3062 if (GET_CODE (operands[2]) != CONST_INT)
3064 /* Get the assembler code to do one shift. */
3065 get_shift_alg (shift_type, shift_mode, 1, &info);
3067 return (4 + h8300_asm_insn_count (info.shift1)) * 2;
3071 int n = INTVAL (operands[2]);
3073 /* If the count is negative, make it 0. */
3076 /* If the count is too big, truncate it.
3077 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
3078 do the intuitive thing. */
3079 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
3080 n = GET_MODE_BITSIZE (mode);
3082 get_shift_alg (shift_type, shift_mode, n, &info);
3087 wlength += h8300_asm_insn_count (info.special);
3093 if (info.shift2 != NULL)
3095 wlength += h8300_asm_insn_count (info.shift2) * (n / 2);
3099 wlength += h8300_asm_insn_count (info.shift1) * n;
3105 int m = GET_MODE_BITSIZE (mode) - n;
3107 /* Not all possibilities of rotate are supported. They shouldn't
3108 be generated, but let's watch for 'em. */
3109 if (info.shift1 == 0)
3112 if (info.shift2 != NULL)
3114 wlength += h8300_asm_insn_count (info.shift2) * (m / 2);
3118 wlength += h8300_asm_insn_count (info.shift1) * m;
3120 /* Now mask off the high bits. */
3141 /* A loop to shift by a "large" constant value.
3142 If we have shift-by-2 insns, use them. */
3143 if (info.shift2 != NULL)
3145 wlength += 3 + h8300_asm_insn_count (info.shift2);
3147 wlength += h8300_asm_insn_count (info.shift1);
3151 wlength += 3 + h8300_asm_insn_count (info.shift1);
3161 /* A rotation by a non-constant will cause a loop to be generated, in
3162 which a rotation by one bit is used. A rotation by a constant,
3163 including the one in the loop, will be taken care of by
3164 emit_a_rotate () at the insn emit time. */
3167 expand_a_rotate (code, operands)
3171 rtx dst = operands[0];
3172 rtx src = operands[1];
3173 rtx rotate_amount = operands[2];
3174 enum machine_mode mode = GET_MODE (dst);
3177 /* We rotate in place. */
3178 emit_move_insn (dst, src);
3180 if (GET_CODE (rotate_amount) != CONST_INT)
3182 rtx counter = gen_reg_rtx (QImode);
3183 rtx start_label = gen_label_rtx ();
3184 rtx end_label = gen_label_rtx ();
3186 /* If the rotate amount is less than or equal to 0,
3187 we go out of the loop. */
3188 emit_cmp_and_jump_insns (rotate_amount, GEN_INT (0), LE, NULL_RTX,
3189 QImode, 0, end_label);
3191 /* Initialize the loop counter. */
3192 emit_move_insn (counter, rotate_amount);
3194 emit_label (start_label);
3196 /* Rotate by one bit. */
3197 tmp = gen_rtx (code, mode, dst, GEN_INT (1));
3198 emit_insn (gen_rtx_SET (mode, dst, tmp));
3200 /* Decrement the counter by 1. */
3201 tmp = gen_rtx_PLUS (QImode, counter, GEN_INT (-1));
3202 emit_insn (gen_rtx_SET (VOIDmode, counter, tmp));
3204 /* If the loop counter is nonzero, we go back to the beginning
3206 emit_cmp_and_jump_insns (counter, GEN_INT (0), NE, NULL_RTX, QImode, 1,
3209 emit_label (end_label);
3213 /* Rotate by AMOUNT bits. */
3214 tmp = gen_rtx (code, mode, dst, rotate_amount);
3215 emit_insn (gen_rtx_SET (mode, dst, tmp));
3221 /* Emit rotate insns. */
3224 emit_a_rotate (code, operands)
3228 rtx dst = operands[0];
3229 rtx rotate_amount = operands[2];
3230 enum shift_mode rotate_mode;
3231 enum shift_type rotate_type;
3232 const char *insn_buf;
3235 enum machine_mode mode = GET_MODE (dst);
3237 if (GET_CODE (rotate_amount) != CONST_INT)
3243 rotate_mode = QIshift;
3246 rotate_mode = HIshift;
3249 rotate_mode = SIshift;
3258 rotate_type = SHIFT_ASHIFT;
3261 rotate_type = SHIFT_LSHIFTRT;
3267 amount = INTVAL (rotate_amount);
3269 /* Clean up AMOUNT. */
3272 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3273 amount = GET_MODE_BITSIZE (mode);
3275 /* Determine the faster direction. After this phase, amount will be
3276 at most a half of GET_MODE_BITSIZE (mode). */
3277 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
3279 /* Flip the direction. */
3280 amount = GET_MODE_BITSIZE (mode) - amount;
3282 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
3285 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3286 boost up the rotation. */
3287 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3288 || (mode == HImode && TARGET_H8300H && amount >= 6)
3289 || (mode == HImode && TARGET_H8300S && amount == 8)
3290 || (mode == SImode && TARGET_H8300H && amount >= 10)
3291 || (mode == SImode && TARGET_H8300S && amount >= 13))
3296 /* This code works on any family. */
3297 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
3298 output_asm_insn (insn_buf, operands);
3302 /* This code works on the H8/300H and H8S. */
3303 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
3304 output_asm_insn (insn_buf, operands);
3311 /* Adjust AMOUNT and flip the direction. */
3312 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3314 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
3317 /* Emit rotate insns. */
3318 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2)
3321 insn_buf = rotate_two[rotate_type][rotate_mode];
3323 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode];
3325 for (; amount >= bits; amount -= bits)
3326 output_asm_insn (insn_buf, operands);
3332 /* Fix the operands of a gen_xxx so that it could become a bit
3336 fix_bit_operand (operands, what, type)
3341 /* The bit_operand predicate accepts any memory during RTL generation, but
3342 only 'U' memory afterwards, so if this is a MEM operand, we must force
3343 it to be valid for 'U' by reloading the address. */
3345 if ((what == 0 && single_zero_operand (operands[2], QImode))
3346 || (what == 1 && single_one_operand (operands[2], QImode)))
3348 /* OK to have a memory dest. */
3349 if (GET_CODE (operands[0]) == MEM
3350 && !EXTRA_CONSTRAINT (operands[0], 'U'))
3352 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
3353 copy_to_mode_reg (Pmode,
3354 XEXP (operands[0], 0)));
3355 MEM_COPY_ATTRIBUTES (mem, operands[0]);
3359 if (GET_CODE (operands[1]) == MEM
3360 && !EXTRA_CONSTRAINT (operands[1], 'U'))
3362 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
3363 copy_to_mode_reg (Pmode,
3364 XEXP (operands[1], 0)));
3365 MEM_COPY_ATTRIBUTES (mem, operands[0]);
3371 /* Dest and src op must be register. */
3373 operands[1] = force_reg (QImode, operands[1]);
3375 rtx res = gen_reg_rtx (QImode);
3376 emit_insn (gen_rtx_SET (VOIDmode, res,
3377 gen_rtx (type, QImode, operands[1], operands[2])));
3378 emit_insn (gen_rtx_SET (VOIDmode, operands[0], res));
3383 /* Return nonzero if FUNC is an interrupt function as specified
3384 by the "interrupt" attribute. */
3387 h8300_interrupt_function_p (func)
3392 if (TREE_CODE (func) != FUNCTION_DECL)
3395 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
3396 return a != NULL_TREE;
3399 /* Return nonzero if FUNC is an OS_Task function as specified
3400 by the "OS_Task" attribute. */
3403 h8300_os_task_function_p (func)
3408 if (TREE_CODE (func) != FUNCTION_DECL)
3411 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func));
3412 return a != NULL_TREE;
3415 /* Return nonzero if FUNC is a monitor function as specified
3416 by the "monitor" attribute. */
3419 h8300_monitor_function_p (func)
3424 if (TREE_CODE (func) != FUNCTION_DECL)
3427 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func));
3428 return a != NULL_TREE;
3431 /* Return nonzero if FUNC is a function that should be called
3432 through the function vector. */
3435 h8300_funcvec_function_p (func)
3440 if (TREE_CODE (func) != FUNCTION_DECL)
3443 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func));
3444 return a != NULL_TREE;
3447 /* Return nonzero if DECL is a variable that's in the eight bit
3451 h8300_eightbit_data_p (decl)
3456 if (TREE_CODE (decl) != VAR_DECL)
3459 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl));
3460 return a != NULL_TREE;
3463 /* Return nonzero if DECL is a variable that's in the tiny
3467 h8300_tiny_data_p (decl)
3472 if (TREE_CODE (decl) != VAR_DECL)
3475 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl));
3476 return a != NULL_TREE;
3479 /* Generate an 'interrupt_handler' attribute for decls. */
3482 h8300_insert_attributes (node, attributes)
3486 if (!interrupt_handler
3487 || TREE_CODE (node) != FUNCTION_DECL)
3490 /* Add an 'interrupt_handler' attribute. */
3491 *attributes = tree_cons (get_identifier ("interrupt_handler"),
3495 /* Supported attributes:
3497 interrupt_handler: output a prologue and epilogue suitable for an
3500 function_vector: This function should be called through the
3503 eightbit_data: This variable lives in the 8-bit data area and can
3504 be referenced with 8-bit absolute memory addresses.
3506 tiny_data: This variable lives in the tiny data area and can be
3507 referenced with 16-bit absolute memory references. */
3509 const struct attribute_spec h8300_attribute_table[] =
3511 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
3512 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3513 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3514 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3515 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3516 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute },
3517 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute },
3518 { NULL, 0, 0, false, false, false, NULL }
3522 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
3523 struct attribute_spec.handler. */
3525 h8300_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
3528 tree args ATTRIBUTE_UNUSED;
3529 int flags ATTRIBUTE_UNUSED;
3532 if (TREE_CODE (*node) != FUNCTION_DECL)
3534 warning ("`%s' attribute only applies to functions",
3535 IDENTIFIER_POINTER (name));
3536 *no_add_attrs = true;
3542 /* Handle an "eightbit_data" attribute; arguments as in
3543 struct attribute_spec.handler. */
3545 h8300_handle_eightbit_data_attribute (node, name, args, flags, no_add_attrs)
3548 tree args ATTRIBUTE_UNUSED;
3549 int flags ATTRIBUTE_UNUSED;
3554 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
3556 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
3560 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3561 *no_add_attrs = true;
3567 /* Handle an "tiny_data" attribute; arguments as in
3568 struct attribute_spec.handler. */
3570 h8300_handle_tiny_data_attribute (node, name, args, flags, no_add_attrs)
3573 tree args ATTRIBUTE_UNUSED;
3574 int flags ATTRIBUTE_UNUSED;
3579 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
3581 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
3585 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3586 *no_add_attrs = true;
3593 h8300_encode_label (decl)
3596 const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
3597 int len = strlen (str);
3598 char *newstr = alloca (len + 2);
3601 strcpy (&newstr[1], str);
3603 XSTR (XEXP (DECL_RTL (decl), 0), 0) =
3604 ggc_alloc_string (newstr, len + 1);
3607 /* If we are referencing a function that is supposed to be called
3608 through the function vector, the SYMBOL_REF_FLAG in the rtl
3609 so the call patterns can generate the correct code. */
3612 h8300_encode_section_info (decl, first)
3616 if (TREE_CODE (decl) == FUNCTION_DECL
3617 && h8300_funcvec_function_p (decl))
3618 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
3619 else if (TREE_CODE (decl) == VAR_DECL
3620 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
3622 if (h8300_eightbit_data_p (decl))
3623 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
3624 else if (first && h8300_tiny_data_p (decl))
3625 h8300_encode_label (decl);
3629 /* Undo the effects of the above. */
3632 h8300_strip_name_encoding (str)
3635 return str + (*str == '*' || *str == '@' || *str == '&');
3639 output_simode_bld (bild, operands)
3645 /* Clear the destination register. */
3646 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
3648 /* Now output the bit load or bit inverse load, and store it in
3651 output_asm_insn ("bild\t%Z2,%Y1", operands);
3653 output_asm_insn ("bld\t%Z2,%Y1", operands);
3655 output_asm_insn ("bst\t#0,%w0", operands);
3659 /* Output the bit load or bit inverse load. */
3661 output_asm_insn ("bild\t%Z2,%Y1", operands);
3663 output_asm_insn ("bld\t%Z2,%Y1", operands);
3665 /* Clear the destination register and perform the bit store. */
3666 output_asm_insn ("xor.l\t%S0,%S0\n\tbst\t#0,%w0", operands);
3673 /* Given INSN and its current length LENGTH, return the adjustment
3674 (in bytes) to correctly compute INSN's length.
3676 We use this to get the lengths of various memory references correct. */
3679 h8300_adjust_insn_length (insn, length)
3681 int length ATTRIBUTE_UNUSED;
3683 rtx pat = PATTERN (insn);
3685 /* We must filter these out before calling get_attr_adjust_length. */
3686 if (GET_CODE (pat) == USE
3687 || GET_CODE (pat) == CLOBBER
3688 || GET_CODE (pat) == SEQUENCE
3689 || GET_CODE (pat) == ADDR_VEC
3690 || GET_CODE (pat) == ADDR_DIFF_VEC)
3693 if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO)
3696 /* Adjust length for reg->mem and mem->reg copies. */
3697 if (GET_CODE (pat) == SET
3698 && (GET_CODE (SET_SRC (pat)) == MEM
3699 || GET_CODE (SET_DEST (pat)) == MEM))
3701 /* This insn might need a length adjustment. */
3704 if (GET_CODE (SET_SRC (pat)) == MEM)
3705 addr = XEXP (SET_SRC (pat), 0);
3707 addr = XEXP (SET_DEST (pat), 0);
3711 /* On the H8/300, we subtract the difference between the
3712 actual length and the longest one, which is @(d:16,ERs). */
3714 /* @Rs is 2 bytes shorter than the longest. */
3715 if (GET_CODE (addr) == REG)
3718 /* @aa:8 is 2 bytes shorter than the longest. */
3719 if (GET_MODE (SET_SRC (pat)) == QImode
3720 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
3721 || EIGHTBIT_CONSTANT_ADDRESS_P (addr)))
3726 /* On the H8/300H and H8S, we subtract the difference
3727 between the actual length and the longest one, which is
3730 /* @ERs is 6 bytes shorter than the longest. */
3731 if (GET_CODE (addr) == REG)
3734 /* @(d:16,ERs) is 6 bytes shorter than the longest. */
3735 if (GET_CODE (addr) == PLUS
3736 && GET_CODE (XEXP (addr, 0)) == REG
3737 && GET_CODE (XEXP (addr, 1)) == CONST_INT
3738 && INTVAL (XEXP (addr, 1)) > -32768
3739 && INTVAL (XEXP (addr, 1)) < 32767)
3742 /* @aa:8 is 6 bytes shorter than the longest. */
3743 if (GET_MODE (SET_SRC (pat)) == QImode
3744 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
3745 || EIGHTBIT_CONSTANT_ADDRESS_P (addr)))
3748 /* @aa:16 is 4 bytes shorter than the longest. */
3749 if ((GET_CODE (addr) == SYMBOL_REF
3750 && TINY_DATA_NAME_P (XSTR (addr, 0)))
3751 || TINY_CONSTANT_ADDRESS_P (addr))
3754 /* @aa:24 is 2 bytes shorter than the longest. */
3755 if (GET_CODE (addr) == CONST_INT)
3760 /* Loading some constants needs adjustment. */
3761 if (GET_CODE (pat) == SET
3762 && GET_CODE (SET_SRC (pat)) == CONST_INT
3763 && GET_MODE (SET_DEST (pat)) == SImode
3764 && INTVAL (SET_SRC (pat)) != 0)
3766 int val = INTVAL (SET_SRC (pat));
3769 && ((val & 0xffff) == 0
3770 || ((val >> 16) & 0xffff) == 0))
3773 if (TARGET_H8300H || TARGET_H8300S)
3775 if (val == (val & 0xff)
3776 || val == (val & 0xff00))
3779 switch (val & 0xffffffff)
3795 /* Rotations need various adjustments. */
3796 if (GET_CODE (pat) == SET
3797 && (GET_CODE (SET_SRC (pat)) == ROTATE
3798 || GET_CODE (SET_SRC (pat)) == ROTATERT))
3800 rtx src = SET_SRC (pat);
3801 enum machine_mode mode = GET_MODE (src);
3805 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3808 amount = INTVAL (XEXP (src, 1));
3810 /* Clean up AMOUNT. */
3813 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3814 amount = GET_MODE_BITSIZE (mode);
3816 /* Determine the faster direction. After this phase, amount
3817 will be at most a half of GET_MODE_BITSIZE (mode). */
3818 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
3819 /* Flip the direction. */
3820 amount = GET_MODE_BITSIZE (mode) - amount;
3822 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3823 boost up the rotation. */
3824 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3825 || (mode == HImode && TARGET_H8300H && amount >= 6)
3826 || (mode == HImode && TARGET_H8300S && amount == 8)
3827 || (mode == SImode && TARGET_H8300H && amount >= 10)
3828 || (mode == SImode && TARGET_H8300S && amount >= 13))
3830 /* Adjust AMOUNT and flip the direction. */
3831 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3835 /* We use 2-bit rotatations on the H8S. */
3837 amount = amount / 2 + amount % 2;
3839 /* The H8/300 uses three insns to rotate one bit, taking 6
3841 states += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2);
3843 return -(20 - states);
3849 #ifndef OBJECT_FORMAT_ELF
3851 h8300_asm_named_section (name, flags)
3853 unsigned int flags ATTRIBUTE_UNUSED;
3855 /* ??? Perhaps we should be using default_coff_asm_named_section. */
3856 fprintf (asm_out_file, "\t.section %s\n", name);
3858 #endif /* ! OBJECT_FORMAT_ELF */