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 <= 6; 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 bitfield 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 non-zero. */
2372 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
2373 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
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. */
2418 if (GET_MODE_BITSIZE (QImode) <= count)
2419 info->alg = SHIFT_LOOP;
2421 info->alg = shift_alg_qi[cpu][shift_type][count];
2425 if (GET_MODE_BITSIZE (HImode) <= count)
2426 info->alg = SHIFT_LOOP;
2428 info->alg = shift_alg_hi[cpu][shift_type][count];
2432 if (GET_MODE_BITSIZE (SImode) <= count)
2433 info->alg = SHIFT_LOOP;
2435 info->alg = shift_alg_si[cpu][shift_type][count];
2442 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
2446 info->remainder = count;
2450 /* It is up to the caller to know that looping clobbers cc. */
2451 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2452 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2453 info->cc_valid_p = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
2457 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
2458 info->shift2 = rotate_two[shift_type][shift_mode];
2459 info->cc_valid_p = 0;
2463 /* REMAINDER is 0 for most cases, so initialize it to 0. */
2464 info->remainder = 0;
2465 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2466 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2467 info->cc_valid_p = 0;
2471 /* Here we only deal with SHIFT_SPECIAL. */
2475 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2476 through the entire value. */
2477 if (shift_type == SHIFT_ASHIFTRT && count == 7)
2479 info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
2491 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";
2493 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
2495 case SHIFT_LSHIFTRT:
2497 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";
2499 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
2501 case SHIFT_ASHIFTRT:
2502 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
2506 else if (8 <= count && count <= 13)
2508 info->remainder = count - 8;
2513 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
2514 info->shift1 = "shal.b\t%t0";
2515 info->shift2 = "shal.b\t#2,%t0";
2517 case SHIFT_LSHIFTRT:
2518 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
2519 info->shift1 = "shlr.b\t%s0";
2520 info->shift2 = "shlr.b\t#2,%s0";
2522 case SHIFT_ASHIFTRT:
2524 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
2526 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
2527 info->shift1 = "shar.b\t%s0";
2528 info->shift2 = "shar.b\t#2,%s0";
2532 else if (count == 14)
2538 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";
2540 case SHIFT_LSHIFTRT:
2542 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";
2544 case SHIFT_ASHIFTRT:
2546 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";
2547 else if (TARGET_H8300H)
2548 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";
2549 else /* TARGET_H8300S */
2550 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";
2554 else if (count == 15)
2559 info->special = "bld\t#0,%s0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#7,%t0";
2561 case SHIFT_LSHIFTRT:
2562 info->special = "bld\t#7,%t0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#0,%s0";
2564 case SHIFT_ASHIFTRT:
2565 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
2572 if (TARGET_H8300 && 8 <= count && count <= 9)
2574 info->remainder = count - 8;
2579 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";
2581 case SHIFT_LSHIFTRT:
2582 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";
2583 info->shift1 = "shlr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0";
2585 case SHIFT_ASHIFTRT:
2586 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";
2590 else if (count == 8 && !TARGET_H8300)
2595 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";
2597 case SHIFT_LSHIFTRT:
2598 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";
2600 case SHIFT_ASHIFTRT:
2601 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";
2605 else if (count == 15 && TARGET_H8300)
2611 case SHIFT_LSHIFTRT:
2612 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";
2614 case SHIFT_ASHIFTRT:
2615 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";
2619 else if (count == 15 && !TARGET_H8300)
2624 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
2626 case SHIFT_LSHIFTRT:
2627 info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
2629 case SHIFT_ASHIFTRT:
2633 else if ((TARGET_H8300 && 16 <= count && count <= 20)
2634 || (TARGET_H8300H && 16 <= count && count <= 19)
2635 || (TARGET_H8300S && 16 <= count && count <= 21))
2637 info->remainder = count - 16;
2642 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2645 info->shift1 = "add.w\t%e0,%e0";
2649 info->shift1 = "shll.l\t%S0";
2650 info->shift2 = "shll.l\t#2,%S0";
2653 case SHIFT_LSHIFTRT:
2654 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
2657 info->shift1 = "shlr\t%x0\n\trotxr\t%w0";
2661 info->shift1 = "shlr.l\t%S0";
2662 info->shift2 = "shlr.l\t#2,%S0";
2665 case SHIFT_ASHIFTRT:
2668 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2669 info->shift1 = "shar\t%x0\n\trotxr\t%w0";
2673 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
2674 info->shift1 = "shar.l\t%S0";
2675 info->shift2 = "shar.l\t#2,%S0";
2680 else if (TARGET_H8300 && 24 <= count && count <= 28)
2682 info->remainder = count - 24;
2687 info->special = "mov.b\t%w0,%z0\n\tsub.b\t%y0,%y0\n\tsub.w\t%f0,%f0";
2688 info->shift1 = "shll.b\t%z0";
2690 case SHIFT_LSHIFTRT:
2691 info->special = "mov.b\t%z0,%w0\n\tsub.b\t%x0,%x0\n\tsub.w\t%e0,%e0";
2692 info->shift1 = "shlr.b\t%w0";
2694 case SHIFT_ASHIFTRT:
2695 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";
2696 info->shift1 = "shar.b\t%w0";
2700 else if ((TARGET_H8300H && count == 24)
2701 || (TARGET_H8300S && 24 <= count && count <= 25))
2703 info->remainder = count - 24;
2708 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";
2709 info->shift1 = "shll.l\t%S0";
2710 info->shift2 = "shll.l\t#2,%S0";
2712 case SHIFT_LSHIFTRT:
2713 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
2714 info->shift1 = "shlr.l\t%S0";
2715 info->shift2 = "shlr.l\t#2,%S0";
2717 case SHIFT_ASHIFTRT:
2718 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
2719 info->shift1 = "shar.l\t%S0";
2720 info->shift2 = "shar.l\t#2,%S0";
2724 else if (count == 31)
2731 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2733 case SHIFT_LSHIFTRT:
2734 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2736 case SHIFT_ASHIFTRT:
2737 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2746 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
2748 case SHIFT_LSHIFTRT:
2749 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
2751 case SHIFT_ASHIFTRT:
2752 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2765 info->shift2 = NULL;
2768 /* Given COUNT and MODE of a shift, return 1 if a scratch reg may be
2769 needed for some shift with COUNT and MODE. Return 0 otherwise. */
2772 h8300_shift_needs_scratch_p (count, mode)
2774 enum machine_mode mode;
2779 if (GET_MODE_BITSIZE (mode) <= count)
2782 /* Find out the target CPU. */
2785 else if (TARGET_H8300H)
2790 /* Find the shift algorithm. */
2794 a = shift_alg_qi[cpu][SHIFT_ASHIFT][count];
2795 lr = shift_alg_qi[cpu][SHIFT_LSHIFTRT][count];
2796 ar = shift_alg_qi[cpu][SHIFT_ASHIFTRT][count];
2800 a = shift_alg_hi[cpu][SHIFT_ASHIFT][count];
2801 lr = shift_alg_hi[cpu][SHIFT_LSHIFTRT][count];
2802 ar = shift_alg_hi[cpu][SHIFT_ASHIFTRT][count];
2806 a = shift_alg_si[cpu][SHIFT_ASHIFT][count];
2807 lr = shift_alg_si[cpu][SHIFT_LSHIFTRT][count];
2808 ar = shift_alg_si[cpu][SHIFT_ASHIFTRT][count];
2815 /* On H8/300H and H8S, count == 8 uses the scratch register. */
2816 return (a == SHIFT_LOOP || lr == SHIFT_LOOP || ar == SHIFT_LOOP
2817 || (!TARGET_H8300 && mode == SImode && count == 8));
2820 /* Emit the assembler code for doing shifts. */
2823 output_a_shift (operands)
2826 static int loopend_lab;
2827 rtx shift = operands[3];
2828 enum machine_mode mode = GET_MODE (shift);
2829 enum rtx_code code = GET_CODE (shift);
2830 enum shift_type shift_type;
2831 enum shift_mode shift_mode;
2832 struct shift_info info;
2839 shift_mode = QIshift;
2842 shift_mode = HIshift;
2845 shift_mode = SIshift;
2854 shift_type = SHIFT_ASHIFTRT;
2857 shift_type = SHIFT_LSHIFTRT;
2860 shift_type = SHIFT_ASHIFT;
2866 if (GET_CODE (operands[2]) != CONST_INT)
2868 /* Indexing by reg, so have to loop and test at top. */
2869 output_asm_insn ("mov.b %X2,%X4", operands);
2870 fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab);
2872 /* Get the assembler code to do one shift. */
2873 get_shift_alg (shift_type, shift_mode, 1, &info);
2875 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2876 output_asm_insn (info.shift1, operands);
2877 output_asm_insn ("add #0xff,%X4", operands);
2878 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2879 fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
2885 int n = INTVAL (operands[2]);
2887 /* If the count is negative, make it 0. */
2890 /* If the count is too big, truncate it.
2891 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2892 do the intuitive thing. */
2893 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
2894 n = GET_MODE_BITSIZE (mode);
2896 get_shift_alg (shift_type, shift_mode, n, &info);
2901 output_asm_insn (info.special, operands);
2907 /* Emit two bit shifts first. */
2908 if (info.shift2 != NULL)
2910 for (; n > 1; n -= 2)
2911 output_asm_insn (info.shift2, operands);
2914 /* Now emit one bit shifts for any residual. */
2916 output_asm_insn (info.shift1, operands);
2918 /* Keep track of CC. */
2919 if (info.cc_valid_p)
2921 cc_status.value1 = operands[0];
2922 cc_status.flags |= info.cc_valid_p;
2928 int m = GET_MODE_BITSIZE (mode) - n;
2929 int mask = (shift_type == SHIFT_ASHIFT
2930 ? ((1 << m) - 1) << n
2934 /* Not all possibilities of rotate are supported. They shouldn't
2935 be generated, but let's watch for 'em. */
2936 if (info.shift1 == 0)
2939 /* Emit two bit rotates first. */
2940 if (info.shift2 != NULL)
2942 for (; m > 1; m -= 2)
2943 output_asm_insn (info.shift2, operands);
2946 /* Now single bit rotates for any residual. */
2948 output_asm_insn (info.shift1, operands);
2950 /* Now mask off the high bits. */
2956 sprintf (insn_buf, "and\t#%d,%%X0", mask);
2957 cc_status.value1 = operands[0];
2958 cc_status.flags |= CC_NO_CARRY;
2961 sprintf (insn_buf, "and\t#%d,%%s0\n\tand\t#%d,%%t0",
2962 mask & 255, mask >> 8);
2970 sprintf (insn_buf, "and.%c\t#%d,%%%c0",
2971 "bwl"[shift_mode], mask,
2972 mode == QImode ? 'X' : mode == HImode ? 'T' : 'S');
2973 cc_status.value1 = operands[0];
2974 cc_status.flags |= CC_NO_CARRY;
2976 output_asm_insn (insn_buf, operands);
2981 /* A loop to shift by a "large" constant value.
2982 If we have shift-by-2 insns, use them. */
2983 if (info.shift2 != NULL)
2985 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
2986 names_big[REGNO (operands[4])]);
2987 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2988 output_asm_insn (info.shift2, operands);
2989 output_asm_insn ("add #0xff,%X4", operands);
2990 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2992 output_asm_insn (info.shift1, operands);
2996 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
2997 names_big[REGNO (operands[4])]);
2998 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2999 output_asm_insn (info.shift1, operands);
3000 output_asm_insn ("add #0xff,%X4", operands);
3001 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
3012 h8300_asm_insn_count (template)
3013 const char *template;
3015 unsigned int count = 1;
3017 for (; *template; template++)
3018 if (*template == '\n')
3025 compute_a_shift_length (insn, operands)
3026 rtx insn ATTRIBUTE_UNUSED;
3029 rtx shift = operands[3];
3030 enum machine_mode mode = GET_MODE (shift);
3031 enum rtx_code code = GET_CODE (shift);
3032 enum shift_type shift_type;
3033 enum shift_mode shift_mode;
3034 struct shift_info info;
3035 unsigned int wlength = 0;
3040 shift_mode = QIshift;
3043 shift_mode = HIshift;
3046 shift_mode = SIshift;
3055 shift_type = SHIFT_ASHIFTRT;
3058 shift_type = SHIFT_LSHIFTRT;
3061 shift_type = SHIFT_ASHIFT;
3067 if (GET_CODE (operands[2]) != CONST_INT)
3069 /* Get the assembler code to do one shift. */
3070 get_shift_alg (shift_type, shift_mode, 1, &info);
3072 return (4 + h8300_asm_insn_count (info.shift1)) * 2;
3076 int n = INTVAL (operands[2]);
3078 /* If the count is negative, make it 0. */
3081 /* If the count is too big, truncate it.
3082 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
3083 do the intuitive thing. */
3084 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
3085 n = GET_MODE_BITSIZE (mode);
3087 get_shift_alg (shift_type, shift_mode, n, &info);
3092 wlength += h8300_asm_insn_count (info.special);
3098 if (info.shift2 != NULL)
3100 wlength += h8300_asm_insn_count (info.shift2) * (n / 2);
3104 wlength += h8300_asm_insn_count (info.shift1) * n;
3110 int m = GET_MODE_BITSIZE (mode) - n;
3112 /* Not all possibilities of rotate are supported. They shouldn't
3113 be generated, but let's watch for 'em. */
3114 if (info.shift1 == 0)
3117 if (info.shift2 != NULL)
3119 wlength += h8300_asm_insn_count (info.shift2) * (m / 2);
3123 wlength += h8300_asm_insn_count (info.shift1) * m;
3125 /* Now mask off the high bits. */
3146 /* A loop to shift by a "large" constant value.
3147 If we have shift-by-2 insns, use them. */
3148 if (info.shift2 != NULL)
3150 wlength += 3 + h8300_asm_insn_count (info.shift2);
3152 wlength += h8300_asm_insn_count (info.shift1);
3156 wlength += 3 + h8300_asm_insn_count (info.shift1);
3166 /* A rotation by a non-constant will cause a loop to be generated, in
3167 which a rotation by one bit is used. A rotation by a constant,
3168 including the one in the loop, will be taken care of by
3169 emit_a_rotate () at the insn emit time. */
3172 expand_a_rotate (code, operands)
3176 rtx dst = operands[0];
3177 rtx src = operands[1];
3178 rtx rotate_amount = operands[2];
3179 enum machine_mode mode = GET_MODE (dst);
3182 /* We rotate in place. */
3183 emit_move_insn (dst, src);
3185 if (GET_CODE (rotate_amount) != CONST_INT)
3187 rtx counter = gen_reg_rtx (QImode);
3188 rtx start_label = gen_label_rtx ();
3189 rtx end_label = gen_label_rtx ();
3191 /* If the rotate amount is less than or equal to 0,
3192 we go out of the loop. */
3193 emit_cmp_and_jump_insns (rotate_amount, GEN_INT (0), LE, NULL_RTX,
3194 QImode, 0, end_label);
3196 /* Initialize the loop counter. */
3197 emit_move_insn (counter, rotate_amount);
3199 emit_label (start_label);
3201 /* Rotate by one bit. */
3202 tmp = gen_rtx (code, mode, dst, GEN_INT (1));
3203 emit_insn (gen_rtx_SET (mode, dst, tmp));
3205 /* Decrement the counter by 1. */
3206 tmp = gen_rtx_PLUS (QImode, counter, GEN_INT (-1));
3207 emit_insn (gen_rtx_SET (VOIDmode, counter, tmp));
3209 /* If the loop counter is non-zero, we go back to the beginning
3211 emit_cmp_and_jump_insns (counter, GEN_INT (0), NE, NULL_RTX, QImode, 1,
3214 emit_label (end_label);
3218 /* Rotate by AMOUNT bits. */
3219 tmp = gen_rtx (code, mode, dst, rotate_amount);
3220 emit_insn (gen_rtx_SET (mode, dst, tmp));
3226 /* Emit rotate insns. */
3229 emit_a_rotate (code, operands)
3233 rtx dst = operands[0];
3234 rtx rotate_amount = operands[2];
3235 enum shift_mode rotate_mode;
3236 enum shift_type rotate_type;
3237 const char *insn_buf;
3240 enum machine_mode mode = GET_MODE (dst);
3242 if (GET_CODE (rotate_amount) != CONST_INT)
3248 rotate_mode = QIshift;
3251 rotate_mode = HIshift;
3254 rotate_mode = SIshift;
3263 rotate_type = SHIFT_ASHIFT;
3266 rotate_type = SHIFT_LSHIFTRT;
3272 amount = INTVAL (rotate_amount);
3274 /* Clean up AMOUNT. */
3277 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3278 amount = GET_MODE_BITSIZE (mode);
3280 /* Determine the faster direction. After this phase, amount will be
3281 at most a half of GET_MODE_BITSIZE (mode). */
3282 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
3284 /* Flip the direction. */
3285 amount = GET_MODE_BITSIZE (mode) - amount;
3287 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
3290 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3291 boost up the rotation. */
3292 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3293 || (mode == HImode && TARGET_H8300H && amount >= 6)
3294 || (mode == HImode && TARGET_H8300S && amount == 8)
3295 || (mode == SImode && TARGET_H8300H && amount >= 10)
3296 || (mode == SImode && TARGET_H8300S && amount >= 13))
3301 /* This code works on any family. */
3302 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
3303 output_asm_insn (insn_buf, operands);
3307 /* This code works on the H8/300H and H8S. */
3308 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
3309 output_asm_insn (insn_buf, operands);
3316 /* Adjust AMOUNT and flip the direction. */
3317 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3319 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
3322 /* Emit rotate insns. */
3323 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2)
3326 insn_buf = rotate_two[rotate_type][rotate_mode];
3328 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode];
3330 for (; amount >= bits; amount -= bits)
3331 output_asm_insn (insn_buf, operands);
3337 /* Fix the operands of a gen_xxx so that it could become a bit
3341 fix_bit_operand (operands, what, type)
3346 /* The bit_operand predicate accepts any memory during RTL generation, but
3347 only 'U' memory afterwards, so if this is a MEM operand, we must force
3348 it to be valid for 'U' by reloading the address. */
3350 if ((what == 0 && single_zero_operand (operands[2], QImode))
3351 || (what == 1 && single_one_operand (operands[2], QImode)))
3353 /* OK to have a memory dest. */
3354 if (GET_CODE (operands[0]) == MEM
3355 && !EXTRA_CONSTRAINT (operands[0], 'U'))
3357 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
3358 copy_to_mode_reg (Pmode,
3359 XEXP (operands[0], 0)));
3360 MEM_COPY_ATTRIBUTES (mem, operands[0]);
3364 if (GET_CODE (operands[1]) == MEM
3365 && !EXTRA_CONSTRAINT (operands[1], 'U'))
3367 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
3368 copy_to_mode_reg (Pmode,
3369 XEXP (operands[1], 0)));
3370 MEM_COPY_ATTRIBUTES (mem, operands[0]);
3376 /* Dest and src op must be register. */
3378 operands[1] = force_reg (QImode, operands[1]);
3380 rtx res = gen_reg_rtx (QImode);
3381 emit_insn (gen_rtx_SET (VOIDmode, res,
3382 gen_rtx (type, QImode, operands[1], operands[2])));
3383 emit_insn (gen_rtx_SET (VOIDmode, operands[0], res));
3388 /* Return nonzero if FUNC is an interrupt function as specified
3389 by the "interrupt" attribute. */
3392 h8300_interrupt_function_p (func)
3397 if (TREE_CODE (func) != FUNCTION_DECL)
3400 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
3401 return a != NULL_TREE;
3404 /* Return nonzero if FUNC is an OS_Task function as specified
3405 by the "OS_Task" attribute. */
3408 h8300_os_task_function_p (func)
3413 if (TREE_CODE (func) != FUNCTION_DECL)
3416 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func));
3417 return a != NULL_TREE;
3420 /* Return nonzero if FUNC is a monitor function as specified
3421 by the "monitor" attribute. */
3424 h8300_monitor_function_p (func)
3429 if (TREE_CODE (func) != FUNCTION_DECL)
3432 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func));
3433 return a != NULL_TREE;
3436 /* Return nonzero if FUNC is a function that should be called
3437 through the function vector. */
3440 h8300_funcvec_function_p (func)
3445 if (TREE_CODE (func) != FUNCTION_DECL)
3448 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func));
3449 return a != NULL_TREE;
3452 /* Return nonzero if DECL is a variable that's in the eight bit
3456 h8300_eightbit_data_p (decl)
3461 if (TREE_CODE (decl) != VAR_DECL)
3464 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl));
3465 return a != NULL_TREE;
3468 /* Return nonzero if DECL is a variable that's in the tiny
3472 h8300_tiny_data_p (decl)
3477 if (TREE_CODE (decl) != VAR_DECL)
3480 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl));
3481 return a != NULL_TREE;
3484 /* Generate an 'interrupt_handler' attribute for decls. */
3487 h8300_insert_attributes (node, attributes)
3491 if (!interrupt_handler
3492 || TREE_CODE (node) != FUNCTION_DECL)
3495 /* Add an 'interrupt_handler' attribute. */
3496 *attributes = tree_cons (get_identifier ("interrupt_handler"),
3500 /* Supported attributes:
3502 interrupt_handler: output a prologue and epilogue suitable for an
3505 function_vector: This function should be called through the
3508 eightbit_data: This variable lives in the 8-bit data area and can
3509 be referenced with 8-bit absolute memory addresses.
3511 tiny_data: This variable lives in the tiny data area and can be
3512 referenced with 16-bit absolute memory references. */
3514 const struct attribute_spec h8300_attribute_table[] =
3516 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
3517 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3518 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3519 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3520 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
3521 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute },
3522 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute },
3523 { NULL, 0, 0, false, false, false, NULL }
3527 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
3528 struct attribute_spec.handler. */
3530 h8300_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
3533 tree args ATTRIBUTE_UNUSED;
3534 int flags ATTRIBUTE_UNUSED;
3537 if (TREE_CODE (*node) != FUNCTION_DECL)
3539 warning ("`%s' attribute only applies to functions",
3540 IDENTIFIER_POINTER (name));
3541 *no_add_attrs = true;
3547 /* Handle an "eightbit_data" attribute; arguments as in
3548 struct attribute_spec.handler. */
3550 h8300_handle_eightbit_data_attribute (node, name, args, flags, no_add_attrs)
3553 tree args ATTRIBUTE_UNUSED;
3554 int flags ATTRIBUTE_UNUSED;
3559 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
3561 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
3565 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3566 *no_add_attrs = true;
3572 /* Handle an "tiny_data" attribute; arguments as in
3573 struct attribute_spec.handler. */
3575 h8300_handle_tiny_data_attribute (node, name, args, flags, no_add_attrs)
3578 tree args ATTRIBUTE_UNUSED;
3579 int flags ATTRIBUTE_UNUSED;
3584 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
3586 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
3590 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3591 *no_add_attrs = true;
3598 h8300_encode_label (decl)
3601 const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
3602 int len = strlen (str);
3603 char *newstr = alloca (len + 2);
3606 strcpy (&newstr[1], str);
3608 XSTR (XEXP (DECL_RTL (decl), 0), 0) =
3609 ggc_alloc_string (newstr, len + 1);
3612 /* If we are referencing a function that is supposed to be called
3613 through the function vector, the SYMBOL_REF_FLAG in the rtl
3614 so the call patterns can generate the correct code. */
3617 h8300_encode_section_info (decl, first)
3621 if (TREE_CODE (decl) == FUNCTION_DECL
3622 && h8300_funcvec_function_p (decl))
3623 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
3624 else if (TREE_CODE (decl) == VAR_DECL
3625 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
3627 if (h8300_eightbit_data_p (decl))
3628 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
3629 else if (first && h8300_tiny_data_p (decl))
3630 h8300_encode_label (decl);
3634 /* Undo the effects of the above. */
3637 h8300_strip_name_encoding (str)
3640 return str + (*str == '*' || *str == '@' || *str == '&');
3644 output_simode_bld (bild, operands)
3650 /* Clear the destination register. */
3651 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
3653 /* Now output the bit load or bit inverse load, and store it in
3656 output_asm_insn ("bild\t%Z2,%Y1", operands);
3658 output_asm_insn ("bld\t%Z2,%Y1", operands);
3660 output_asm_insn ("bst\t#0,%w0", operands);
3664 /* Output the bit load or bit inverse load. */
3666 output_asm_insn ("bild\t%Z2,%Y1", operands);
3668 output_asm_insn ("bld\t%Z2,%Y1", operands);
3670 /* Clear the destination register and perform the bit store. */
3671 output_asm_insn ("xor.l\t%S0,%S0\n\tbst\t#0,%w0", operands);
3678 /* Given INSN and its current length LENGTH, return the adjustment
3679 (in bytes) to correctly compute INSN's length.
3681 We use this to get the lengths of various memory references correct. */
3684 h8300_adjust_insn_length (insn, length)
3686 int length ATTRIBUTE_UNUSED;
3688 rtx pat = PATTERN (insn);
3690 /* We must filter these out before calling get_attr_adjust_length. */
3691 if (GET_CODE (pat) == USE
3692 || GET_CODE (pat) == CLOBBER
3693 || GET_CODE (pat) == SEQUENCE
3694 || GET_CODE (pat) == ADDR_VEC
3695 || GET_CODE (pat) == ADDR_DIFF_VEC)
3698 if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO)
3701 /* Adjust length for reg->mem and mem->reg copies. */
3702 if (GET_CODE (pat) == SET
3703 && (GET_CODE (SET_SRC (pat)) == MEM
3704 || GET_CODE (SET_DEST (pat)) == MEM))
3706 /* This insn might need a length adjustment. */
3709 if (GET_CODE (SET_SRC (pat)) == MEM)
3710 addr = XEXP (SET_SRC (pat), 0);
3712 addr = XEXP (SET_DEST (pat), 0);
3716 /* On the H8/300, we subtract the difference between the
3717 actual length and the longest one, which is @(d:16,ERs). */
3719 /* @Rs is 2 bytes shorter than the longest. */
3720 if (GET_CODE (addr) == REG)
3723 /* @aa:8 is 2 bytes shorter than the longest. */
3724 if (GET_MODE (SET_SRC (pat)) == QImode
3725 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
3726 || EIGHTBIT_CONSTANT_ADDRESS_P (addr)))
3731 /* On the H8/300H and H8S, we subtract the difference
3732 between the actual length and the longest one, which is
3735 /* @ERs is 6 bytes shorter than the longest. */
3736 if (GET_CODE (addr) == REG)
3739 /* @(d:16,ERs) is 6 bytes shorter than the longest. */
3740 if (GET_CODE (addr) == PLUS
3741 && GET_CODE (XEXP (addr, 0)) == REG
3742 && GET_CODE (XEXP (addr, 1)) == CONST_INT
3743 && INTVAL (XEXP (addr, 1)) > -32768
3744 && INTVAL (XEXP (addr, 1)) < 32767)
3747 /* @aa:8 is 6 bytes shorter than the longest. */
3748 if (GET_MODE (SET_SRC (pat)) == QImode
3749 && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
3750 || EIGHTBIT_CONSTANT_ADDRESS_P (addr)))
3753 /* @aa:16 is 4 bytes shorter than the longest. */
3754 if ((GET_CODE (addr) == SYMBOL_REF
3755 && TINY_DATA_NAME_P (XSTR (addr, 0)))
3756 || TINY_CONSTANT_ADDRESS_P (addr))
3759 /* @aa:24 is 2 bytes shorter than the longest. */
3760 if (GET_CODE (addr) == CONST_INT)
3765 /* Loading some constants needs adjustment. */
3766 if (GET_CODE (pat) == SET
3767 && GET_CODE (SET_SRC (pat)) == CONST_INT
3768 && GET_MODE (SET_DEST (pat)) == SImode
3769 && INTVAL (SET_SRC (pat)) != 0)
3771 int val = INTVAL (SET_SRC (pat));
3774 && ((val & 0xffff) == 0
3775 || ((val >> 16) & 0xffff) == 0))
3778 if (TARGET_H8300H || TARGET_H8300S)
3780 if (val == (val & 0xff)
3781 || val == (val & 0xff00))
3784 switch (val & 0xffffffff)
3800 /* Rotations need various adjustments. */
3801 if (GET_CODE (pat) == SET
3802 && (GET_CODE (SET_SRC (pat)) == ROTATE
3803 || GET_CODE (SET_SRC (pat)) == ROTATERT))
3805 rtx src = SET_SRC (pat);
3806 enum machine_mode mode = GET_MODE (src);
3810 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3813 amount = INTVAL (XEXP (src, 1));
3815 /* Clean up AMOUNT. */
3818 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3819 amount = GET_MODE_BITSIZE (mode);
3821 /* Determine the faster direction. After this phase, amount
3822 will be at most a half of GET_MODE_BITSIZE (mode). */
3823 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
3824 /* Flip the direction. */
3825 amount = GET_MODE_BITSIZE (mode) - amount;
3827 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3828 boost up the rotation. */
3829 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3830 || (mode == HImode && TARGET_H8300H && amount >= 6)
3831 || (mode == HImode && TARGET_H8300S && amount == 8)
3832 || (mode == SImode && TARGET_H8300H && amount >= 10)
3833 || (mode == SImode && TARGET_H8300S && amount >= 13))
3835 /* Adjust AMOUNT and flip the direction. */
3836 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3840 /* We use 2-bit rotatations on the H8S. */
3842 amount = amount / 2 + amount % 2;
3844 /* The H8/300 uses three insns to rotate one bit, taking 6
3846 states += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2);
3848 return -(20 - states);
3854 #ifndef OBJECT_FORMAT_ELF
3856 h8300_asm_named_section (name, flags)
3858 unsigned int flags ATTRIBUTE_UNUSED;
3860 /* ??? Perhaps we should be using default_coff_asm_named_section. */
3861 fprintf (asm_out_file, "\t.section %s\n", name);
3863 #endif /* ! OBJECT_FORMAT_ELF */