Improve support for arm-wince-pe target:
[official-gcc.git] / gcc / config / h8300 / h8300.c
blobae01d281795609637cd81bf69bdf948a9494f443
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, 2003 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 GCC.
9 GCC 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)
12 any later version.
14 GCC 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 GCC; see the file COPYING. If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "regs.h"
31 #include "hard-reg-set.h"
32 #include "real.h"
33 #include "insn-config.h"
34 #include "conditions.h"
35 #include "output.h"
36 #include "insn-attr.h"
37 #include "flags.h"
38 #include "recog.h"
39 #include "expr.h"
40 #include "function.h"
41 #include "toplev.h"
42 #include "c-pragma.h"
43 #include "tm_p.h"
44 #include "ggc.h"
45 #include "target.h"
46 #include "target-def.h"
48 /* Forward declarations. */
49 static const char *byte_reg PARAMS ((rtx, int));
50 static int h8300_interrupt_function_p PARAMS ((tree));
51 static int h8300_monitor_function_p PARAMS ((tree));
52 static int h8300_os_task_function_p PARAMS ((tree));
53 static void dosize PARAMS ((int, unsigned int));
54 static int round_frame_size PARAMS ((int));
55 static unsigned int compute_saved_regs PARAMS ((void));
56 static void push PARAMS ((int));
57 static void pop PARAMS ((int));
58 static const char *cond_string PARAMS ((enum rtx_code));
59 static unsigned int h8300_asm_insn_count PARAMS ((const char *));
60 const struct attribute_spec h8300_attribute_table[];
61 static tree h8300_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
62 static tree h8300_handle_eightbit_data_attribute PARAMS ((tree *, tree, tree, int, bool *));
63 static tree h8300_handle_tiny_data_attribute PARAMS ((tree *, tree, tree, int, bool *));
64 static void h8300_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
65 static void h8300_insert_attributes PARAMS ((tree, tree *));
66 static void h8300_file_end PARAMS ((void));
67 #ifndef OBJECT_FORMAT_ELF
68 static void h8300_asm_named_section PARAMS ((const char *, unsigned int));
69 #endif
70 static void h8300_encode_section_info PARAMS ((tree, rtx, int));
71 static int const_costs PARAMS ((rtx, enum rtx_code, enum rtx_code));
72 static int h8300_and_costs PARAMS ((rtx));
73 static int h8300_shift_costs PARAMS ((rtx));
74 static bool h8300_rtx_costs PARAMS ((rtx, int, int, int *));
76 /* CPU_TYPE, says what cpu we're compiling for. */
77 int cpu_type;
79 /* True if a #pragma interrupt has been seen for the current function. */
80 static int pragma_interrupt;
82 /* True if a #pragma saveall has been seen for the current function. */
83 static int pragma_saveall;
85 static const char *const names_big[] =
86 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" };
88 static const char *const names_extended[] =
89 { "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" };
91 static const char *const names_upper_extended[] =
92 { "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7" };
94 /* Points to one of the above. */
95 /* ??? The above could be put in an array indexed by CPU_TYPE. */
96 const char * const *h8_reg_names;
98 /* Various operations needed by the following, indexed by CPU_TYPE. */
100 const char *h8_push_op, *h8_pop_op, *h8_mov_op;
102 /* Machine-specific symbol_ref flags. */
103 #define SYMBOL_FLAG_FUNCVEC_FUNCTION (SYMBOL_FLAG_MACH_DEP << 0)
104 #define SYMBOL_FLAG_EIGHTBIT_DATA (SYMBOL_FLAG_MACH_DEP << 1)
105 #define SYMBOL_FLAG_TINY_DATA (SYMBOL_FLAG_MACH_DEP << 2)
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_EPILOGUE
115 #define TARGET_ASM_FUNCTION_EPILOGUE h8300_output_function_epilogue
117 #undef TARGET_ASM_FILE_END
118 #define TARGET_ASM_FILE_END h8300_file_end
120 #undef TARGET_ENCODE_SECTION_INFO
121 #define TARGET_ENCODE_SECTION_INFO h8300_encode_section_info
123 #undef TARGET_INSERT_ATTRIBUTES
124 #define TARGET_INSERT_ATTRIBUTES h8300_insert_attributes
126 #undef TARGET_RTX_COSTS
127 #define TARGET_RTX_COSTS h8300_rtx_costs
129 struct gcc_target targetm = TARGET_INITIALIZER;
131 /* See below where shifts are handled for explanation of this enum. */
133 enum shift_alg
135 SHIFT_INLINE,
136 SHIFT_ROT_AND,
137 SHIFT_SPECIAL,
138 SHIFT_LOOP
141 /* Symbols of the various shifts which can be used as indices. */
143 enum shift_type
145 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
148 /* Macros to keep the shift algorithm tables small. */
149 #define INL SHIFT_INLINE
150 #define ROT SHIFT_ROT_AND
151 #define LOP SHIFT_LOOP
152 #define SPC SHIFT_SPECIAL
154 /* The shift algorithms for each machine, mode, shift type, and shift
155 count are defined below. The three tables below correspond to
156 QImode, HImode, and SImode, respectively. Each table is organized
157 by, in the order of indices, machine, shift type, and shift count. */
159 static enum shift_alg shift_alg_qi[3][3][8] = {
161 /* TARGET_H8300 */
162 /* 0 1 2 3 4 5 6 7 */
163 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
164 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
165 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
168 /* TARGET_H8300H */
169 /* 0 1 2 3 4 5 6 7 */
170 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
171 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
172 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
175 /* TARGET_H8300S */
176 /* 0 1 2 3 4 5 6 7 */
177 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_ASHIFT */
178 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_LSHIFTRT */
179 { INL, INL, INL, INL, INL, INL, INL, SPC } /* SHIFT_ASHIFTRT */
183 static enum shift_alg shift_alg_hi[3][3][16] = {
185 /* TARGET_H8300 */
186 /* 0 1 2 3 4 5 6 7 */
187 /* 8 9 10 11 12 13 14 15 */
188 { INL, INL, INL, INL, INL, INL, INL, SPC,
189 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */
190 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
191 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */
192 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
193 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
196 /* TARGET_H8300H */
197 /* 0 1 2 3 4 5 6 7 */
198 /* 8 9 10 11 12 13 14 15 */
199 { INL, INL, INL, INL, INL, INL, INL, SPC,
200 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
201 { INL, INL, INL, INL, INL, INL, INL, SPC,
202 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
203 { INL, INL, INL, INL, INL, INL, INL, SPC,
204 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
207 /* TARGET_H8300S */
208 /* 0 1 2 3 4 5 6 7 */
209 /* 8 9 10 11 12 13 14 15 */
210 { INL, INL, INL, INL, INL, INL, INL, INL,
211 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
212 { INL, INL, INL, INL, INL, INL, INL, INL,
213 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
214 { INL, INL, INL, INL, INL, INL, INL, INL,
215 SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
219 static enum shift_alg shift_alg_si[3][3][32] = {
221 /* TARGET_H8300 */
222 /* 0 1 2 3 4 5 6 7 */
223 /* 8 9 10 11 12 13 14 15 */
224 /* 16 17 18 19 20 21 22 23 */
225 /* 24 25 26 27 28 29 30 31 */
226 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
227 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
228 SPC, SPC, SPC, SPC, SPC, LOP, LOP, LOP,
229 SPC, SPC, SPC, SPC, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
230 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
231 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC,
232 SPC, SPC, SPC, LOP, LOP, LOP, LOP, LOP,
233 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
234 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
235 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
236 SPC, SPC, LOP, LOP, LOP, LOP, LOP, LOP,
237 SPC, SPC, SPC, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
240 /* TARGET_H8300H */
241 /* 0 1 2 3 4 5 6 7 */
242 /* 8 9 10 11 12 13 14 15 */
243 /* 16 17 18 19 20 21 22 23 */
244 /* 24 25 26 27 28 29 30 31 */
245 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
246 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
247 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
248 SPC, LOP, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */
249 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
250 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
251 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
252 SPC, LOP, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */
253 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
254 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
255 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
256 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
259 /* TARGET_H8300S */
260 /* 0 1 2 3 4 5 6 7 */
261 /* 8 9 10 11 12 13 14 15 */
262 /* 16 17 18 19 20 21 22 23 */
263 /* 24 25 26 27 28 29 30 31 */
264 { INL, INL, INL, INL, INL, INL, INL, INL,
265 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
266 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
267 SPC, SPC, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */
268 { INL, INL, INL, INL, INL, INL, INL, INL,
269 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
270 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
271 SPC, SPC, LOP, LOP, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */
272 { INL, INL, INL, INL, INL, INL, INL, INL,
273 INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
274 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
275 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
279 #undef INL
280 #undef ROT
281 #undef LOP
282 #undef SPC
284 enum h8_cpu
286 H8_300,
287 H8_300H,
288 H8_S
291 /* Initialize various cpu specific globals at start up. */
293 void
294 h8300_init_once ()
296 static const char *const h8_push_ops[2] = { "push" , "push.l" };
297 static const char *const h8_pop_ops[2] = { "pop" , "pop.l" };
298 static const char *const h8_mov_ops[2] = { "mov.w", "mov.l" };
300 if (TARGET_H8300)
302 cpu_type = (int) CPU_H8300;
303 h8_reg_names = names_big;
305 else
307 /* For this we treat the H8/300H and H8S the same. */
308 cpu_type = (int) CPU_H8300H;
309 h8_reg_names = names_extended;
311 h8_push_op = h8_push_ops[cpu_type];
312 h8_pop_op = h8_pop_ops[cpu_type];
313 h8_mov_op = h8_mov_ops[cpu_type];
315 if (!TARGET_H8300S && TARGET_MAC)
317 error ("-ms2600 is used without -ms");
318 target_flags |= MASK_H8300S;
321 if (TARGET_H8300 && TARGET_NORMAL_MODE)
323 error ("-mn is used without -mh or -ms");
324 target_flags ^= MASK_NORMAL_MODE;
327 /* Some of the shifts are optimized for speed by default.
328 See http://gcc.gnu.org/ml/gcc-patches/2002-07/msg01858.html
329 If optimizing for size, change shift_alg for those shift to
330 SHIFT_LOOP. */
331 if (optimize_size)
333 /* H8/300 */
334 shift_alg_hi[H8_300][SHIFT_ASHIFT][5] = SHIFT_LOOP;
335 shift_alg_hi[H8_300][SHIFT_ASHIFT][6] = SHIFT_LOOP;
336 shift_alg_hi[H8_300][SHIFT_ASHIFT][13] = SHIFT_LOOP;
337 shift_alg_hi[H8_300][SHIFT_ASHIFT][14] = SHIFT_LOOP;
339 shift_alg_hi[H8_300][SHIFT_LSHIFTRT][13] = SHIFT_LOOP;
340 shift_alg_hi[H8_300][SHIFT_LSHIFTRT][14] = SHIFT_LOOP;
342 shift_alg_hi[H8_300][SHIFT_ASHIFTRT][13] = SHIFT_LOOP;
343 shift_alg_hi[H8_300][SHIFT_ASHIFTRT][14] = SHIFT_LOOP;
345 /* H8/300H */
346 shift_alg_hi[H8_300H][SHIFT_ASHIFT][5] = SHIFT_LOOP;
347 shift_alg_hi[H8_300H][SHIFT_ASHIFT][6] = SHIFT_LOOP;
349 shift_alg_hi[H8_300H][SHIFT_LSHIFTRT][5] = SHIFT_LOOP;
350 shift_alg_hi[H8_300H][SHIFT_LSHIFTRT][6] = SHIFT_LOOP;
352 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][5] = SHIFT_LOOP;
353 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][6] = SHIFT_LOOP;
354 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][13] = SHIFT_LOOP;
355 shift_alg_hi[H8_300H][SHIFT_ASHIFTRT][14] = SHIFT_LOOP;
357 /* H8S */
358 shift_alg_hi[H8_S][SHIFT_ASHIFTRT][14] = SHIFT_LOOP;
362 static const char *
363 byte_reg (x, b)
364 rtx x;
365 int b;
367 static const char *const names_small[] = {
368 "r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
369 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h"
372 return names_small[REGNO (x) * 2 + b];
375 /* REGNO must be saved/restored across calls if this macro is true. */
377 #define WORD_REG_USED(regno) \
378 (regno < 7 \
379 /* No need to save registers if this function will not return. */ \
380 && ! TREE_THIS_VOLATILE (current_function_decl) \
381 && (pragma_saveall \
382 /* Save any call saved register that was used. */ \
383 || (regs_ever_live[regno] && !call_used_regs[regno]) \
384 /* Save the frame pointer if it was used. */ \
385 || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno]) \
386 /* Save any register used in an interrupt handler. */ \
387 || (h8300_current_function_interrupt_function_p () \
388 && regs_ever_live[regno]) \
389 /* Save call clobbered registers in non-leaf interrupt \
390 handlers. */ \
391 || (h8300_current_function_interrupt_function_p () \
392 && call_used_regs[regno] \
393 && !current_function_is_leaf)))
395 /* Output assembly language to FILE for the operation OP with operand size
396 SIZE to adjust the stack pointer. */
398 static void
399 dosize (sign, size)
400 int sign;
401 unsigned int size;
403 /* H8/300 cannot add/subtract a large constant with a single
404 instruction. If a temporary register is available, load the
405 constant to it and then do the addition. */
406 if (TARGET_H8300
407 && size > 4
408 && !h8300_current_function_interrupt_function_p ()
409 && !(current_function_needs_context && sign < 0))
411 rtx new_sp;
412 rtx r3 = gen_rtx_REG (Pmode, 3);
413 emit_insn (gen_rtx_SET (Pmode, r3, GEN_INT (sign * size)));
414 new_sp = gen_rtx_PLUS (Pmode, stack_pointer_rtx, r3);
415 emit_insn (gen_rtx_SET (Pmode, stack_pointer_rtx, new_sp));
417 else
419 /* The stack adjustment made here is further optimized by the
420 splitter. In case of H8/300, the splitter always splits the
421 addition emitted here to make the adjustment
422 interrupt-safe. */
423 rtx new_sp = plus_constant (stack_pointer_rtx, sign * size);
424 emit_insn (gen_rtx_SET (Pmode, stack_pointer_rtx, new_sp));
428 /* Round up frame size SIZE. */
430 static int
431 round_frame_size (size)
432 int size;
434 return ((size + STACK_BOUNDARY / BITS_PER_UNIT - 1)
435 & -STACK_BOUNDARY / BITS_PER_UNIT);
438 /* Compute which registers to push/pop.
439 Return a bit vector of registers. */
441 static unsigned int
442 compute_saved_regs ()
444 unsigned int saved_regs = 0;
445 int regno;
447 /* Construct a bit vector of registers to be pushed/popped. */
448 for (regno = 0; regno <= FRAME_POINTER_REGNUM; regno++)
450 if (WORD_REG_USED (regno))
451 saved_regs |= 1 << regno;
454 /* Don't push/pop the frame pointer as it is treated separately. */
455 if (frame_pointer_needed)
456 saved_regs &= ~(1 << FRAME_POINTER_REGNUM);
458 return saved_regs;
461 /* Emit an insn to push register RN. */
463 static void
464 push (rn)
465 int rn;
467 rtx reg = gen_rtx_REG (word_mode, rn);
468 rtx x;
470 if (TARGET_H8300)
471 x = gen_push_h8300 (reg);
472 else
473 x = gen_push_h8300hs (reg);
474 x = emit_insn (x);
475 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, 0);
478 /* Emit an insn to pop register RN. */
480 static void
481 pop (rn)
482 int rn;
484 rtx reg = gen_rtx_REG (word_mode, rn);
485 rtx x;
487 if (TARGET_H8300)
488 x = gen_pop_h8300 (reg);
489 else
490 x = gen_pop_h8300hs (reg);
491 x = emit_insn (x);
492 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, 0);
495 /* This is what the stack looks like after the prolog of
496 a function with a frame has been set up:
498 <args>
500 FP <- fp
501 <locals>
502 <saved registers> <- sp
504 This is what the stack looks like after the prolog of
505 a function which doesn't have a frame:
507 <args>
509 <locals>
510 <saved registers> <- sp
513 /* Generate RTL code for the function prologue. */
515 void
516 h8300_expand_prologue ()
518 int regno;
519 int saved_regs;
520 int n_regs;
522 /* If the current function has the OS_Task attribute set, then
523 we have a naked prologue. */
524 if (h8300_os_task_function_p (current_function_decl))
525 return;
527 if (h8300_monitor_function_p (current_function_decl))
528 /* My understanding of monitor functions is they act just like
529 interrupt functions, except the prologue must mask
530 interrupts. */
531 emit_insn (gen_monitor_prologue ());
533 if (frame_pointer_needed)
535 /* Push fp. */
536 push (FRAME_POINTER_REGNUM);
537 emit_insn (gen_rtx_SET (Pmode, frame_pointer_rtx, stack_pointer_rtx));
540 /* Leave room for locals. */
541 dosize (-1, round_frame_size (get_frame_size ()));
543 /* Push the rest of the registers in ascending order. */
544 saved_regs = compute_saved_regs ();
545 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno += n_regs)
547 n_regs = 1;
548 if (saved_regs & (1 << regno))
550 if (TARGET_H8300S)
552 /* See how many registers we can push at the same time. */
553 if ((regno == 0 || regno == 4)
554 && ((saved_regs >> regno) & 0x0f) == 0x0f)
555 n_regs = 4;
557 else if ((regno == 0 || regno == 4)
558 && ((saved_regs >> regno) & 0x07) == 0x07)
559 n_regs = 3;
561 else if ((regno == 0 || regno == 2 || regno == 4 || regno == 6)
562 && ((saved_regs >> regno) & 0x03) == 0x03)
563 n_regs = 2;
566 switch (n_regs)
568 case 1:
569 push (regno);
570 break;
571 case 2:
572 emit_insn (gen_stm_h8300s_2 (gen_rtx_REG (SImode, regno),
573 gen_rtx_REG (SImode, regno + 1)));
574 break;
575 case 3:
576 emit_insn (gen_stm_h8300s_3 (gen_rtx_REG (SImode, regno),
577 gen_rtx_REG (SImode, regno + 1),
578 gen_rtx_REG (SImode, regno + 2)));
579 break;
580 case 4:
581 emit_insn (gen_stm_h8300s_4 (gen_rtx_REG (SImode, regno),
582 gen_rtx_REG (SImode, regno + 1),
583 gen_rtx_REG (SImode, regno + 2),
584 gen_rtx_REG (SImode, regno + 3)));
585 break;
586 default:
587 abort ();
594 h8300_can_use_return_insn_p ()
596 return (reload_completed
597 && !frame_pointer_needed
598 && get_frame_size () == 0
599 && compute_saved_regs () == 0);
602 /* Generate RTL code for the function epilogue. */
604 void
605 h8300_expand_epilogue ()
607 int regno;
608 int saved_regs;
609 int n_regs;
611 if (h8300_os_task_function_p (current_function_decl))
612 /* OS_Task epilogues are nearly naked -- they just have an
613 rts instruction. */
614 return;
616 /* Pop the saved registers in descending order. */
617 saved_regs = compute_saved_regs ();
618 for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno -= n_regs)
620 n_regs = 1;
621 if (saved_regs & (1 << regno))
623 if (TARGET_H8300S)
625 /* See how many registers we can pop at the same time. */
626 if ((regno == 7 || regno == 3)
627 && ((saved_regs >> (regno - 3)) & 0x0f) == 0x0f)
628 n_regs = 4;
630 else if ((regno == 6 || regno == 2)
631 && ((saved_regs >> (regno - 2)) & 0x07) == 0x07)
632 n_regs = 3;
634 else if ((regno == 7 || regno == 5 || regno == 3 || regno == 1)
635 && ((saved_regs >> (regno - 1)) & 0x03) == 0x03)
636 n_regs = 2;
639 switch (n_regs)
641 case 1:
642 pop (regno);
643 break;
644 case 2:
645 emit_insn (gen_ldm_h8300s_2 (gen_rtx_REG (SImode, regno - 1),
646 gen_rtx_REG (SImode, regno)));
647 break;
648 case 3:
649 emit_insn (gen_ldm_h8300s_3 (gen_rtx_REG (SImode, regno - 2),
650 gen_rtx_REG (SImode, regno - 1),
651 gen_rtx_REG (SImode, regno)));
652 break;
653 case 4:
654 emit_insn (gen_ldm_h8300s_4 (gen_rtx_REG (SImode, regno - 3),
655 gen_rtx_REG (SImode, regno - 2),
656 gen_rtx_REG (SImode, regno - 1),
657 gen_rtx_REG (SImode, regno)));
658 break;
659 default:
660 abort ();
665 /* Deallocate locals. */
666 dosize (1, round_frame_size (get_frame_size ()));
668 /* Pop frame pointer if we had one. */
669 if (frame_pointer_needed)
670 pop (FRAME_POINTER_REGNUM);
673 /* Output assembly language code for the function epilogue. */
675 static void
676 h8300_output_function_epilogue (file, size)
677 FILE *file ATTRIBUTE_UNUSED;
678 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
680 pragma_saveall = 0;
683 /* Return nonzero if the current function is an interrupt
684 function. */
687 h8300_current_function_interrupt_function_p ()
689 return (h8300_interrupt_function_p (current_function_decl)
690 || h8300_monitor_function_p (current_function_decl));
693 /* Output assembly code for the start of the file. */
695 void
696 asm_file_start (file)
697 FILE *file;
699 fprintf (file, ";\tGCC For the Hitachi H8/300\n");
700 fprintf (file, ";\tBy Hitachi America Ltd and Cygnus Support\n");
702 if (optimize_size)
703 fprintf (file, "; -Os\n");
704 else if (optimize)
705 fprintf (file, "; -O%d\n", optimize);
706 if (TARGET_H8300H)
707 if (TARGET_NORMAL_MODE)
708 fprintf (file, "\n\t.h8300hn\n");
709 else
710 fprintf (file, "\n\t.h8300h\n");
711 else if (TARGET_H8300S)
712 if (TARGET_NORMAL_MODE)
713 fprintf (file, "\n\t.h8300sn\n");
714 else
715 fprintf (file, "\n\t.h8300s\n");
716 else
717 fprintf (file, "\n\n");
718 output_file_directive (file, main_input_filename);
721 /* Output assembly language code for the end of file. */
723 static void
724 h8300_file_end ()
726 fputs ("\t.end\n", asm_out_file);
729 /* Return true if OP is a valid source operand for an integer move
730 instruction. */
733 general_operand_src (op, mode)
734 rtx op;
735 enum machine_mode mode;
737 if (GET_MODE (op) == mode
738 && GET_CODE (op) == MEM
739 && GET_CODE (XEXP (op, 0)) == POST_INC)
740 return 1;
741 return general_operand (op, mode);
744 /* Return true if OP is a valid destination operand for an integer move
745 instruction. */
748 general_operand_dst (op, mode)
749 rtx op;
750 enum machine_mode mode;
752 if (GET_MODE (op) == mode
753 && GET_CODE (op) == MEM
754 && GET_CODE (XEXP (op, 0)) == PRE_DEC)
755 return 1;
756 return general_operand (op, mode);
759 /* Return true if OP is a constant that contains only one 1 in its
760 binary representation. */
763 single_one_operand (operand, mode)
764 rtx operand;
765 enum machine_mode mode ATTRIBUTE_UNUSED;
767 if (GET_CODE (operand) == CONST_INT)
769 /* We really need to do this masking because 0x80 in QImode is
770 represented as -128 for example. */
771 if (exact_log2 (INTVAL (operand) & GET_MODE_MASK (mode)) >= 0)
772 return 1;
775 return 0;
778 /* Return true if OP is a constant that contains only one 0 in its
779 binary representation. */
782 single_zero_operand (operand, mode)
783 rtx operand;
784 enum machine_mode mode ATTRIBUTE_UNUSED;
786 if (GET_CODE (operand) == CONST_INT)
788 /* We really need to do this masking because 0x80 in QImode is
789 represented as -128 for example. */
790 if (exact_log2 (~INTVAL (operand) & GET_MODE_MASK (mode)) >= 0)
791 return 1;
794 return 0;
797 /* Return true if OP is a valid call operand. */
800 call_insn_operand (op, mode)
801 rtx op;
802 enum machine_mode mode ATTRIBUTE_UNUSED;
804 if (GET_CODE (op) == MEM)
806 rtx inside = XEXP (op, 0);
807 if (register_operand (inside, Pmode))
808 return 1;
809 if (CONSTANT_ADDRESS_P (inside))
810 return 1;
812 return 0;
815 /* Return 1 if an addition/subtraction of a constant integer can be
816 transformed into two consecutive adds/subs that are faster than the
817 straightforward way. Otherwise, return 0. */
820 two_insn_adds_subs_operand (op, mode)
821 rtx op;
822 enum machine_mode mode;
824 if (GET_CODE (op) == CONST_INT)
826 HOST_WIDE_INT value = INTVAL (op);
828 /* Force VALUE to be positive so that we do not have to consider
829 the negative case. */
830 if (value < 0)
831 value = -value;
832 if (TARGET_H8300H || TARGET_H8300S)
834 /* A constant addition/subtraction takes 2 states in QImode,
835 4 states in HImode, and 6 states in SImode. Thus, the
836 only case we can win is when SImode is used, in which
837 case, two adds/subs are used, taking 4 states. */
838 if (mode == SImode
839 && (value == 2 + 1
840 || value == 4 + 1
841 || value == 4 + 2
842 || value == 4 + 4))
843 return 1;
845 else
847 /* We do not profit directly by splitting addition or
848 subtraction of 3 and 4. However, since these are
849 implemented as a sequence of adds or subs, they do not
850 clobber (cc0) unlike a sequence of add.b and add.x. */
851 if (mode == HImode
852 && (value == 2 + 1
853 || value == 2 + 2))
854 return 1;
858 return 0;
861 /* Split an add of a small constant into two adds/subs insns.
863 If USE_INCDEC_P is nonzero, we generate the last insn using inc/dec
864 instead of adds/subs. */
866 void
867 split_adds_subs (mode, operands)
868 enum machine_mode mode;
869 rtx *operands;
871 HOST_WIDE_INT val = INTVAL (operands[1]);
872 rtx reg = operands[0];
873 HOST_WIDE_INT sign = 1;
874 HOST_WIDE_INT amount;
875 rtx (*gen_add) (rtx, rtx, rtx);
877 /* Force VAL to be positive so that we do not have to consider the
878 sign. */
879 if (val < 0)
881 val = -val;
882 sign = -1;
885 switch (mode)
887 case HImode:
888 gen_add = gen_addhi3;
889 break;
891 case SImode:
892 gen_add = gen_addsi3;
893 break;
895 default:
896 abort ();
899 /* Try different amounts in descending order. */
900 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
901 amount > 0;
902 amount /= 2)
904 for (; val >= amount; val -= amount)
905 emit_insn (gen_add (reg, reg, GEN_INT (sign * amount)));
908 return;
911 /* Return true if OP is a valid call operand, and OP represents
912 an operand for a small call (4 bytes instead of 6 bytes). */
915 small_call_insn_operand (op, mode)
916 rtx op;
917 enum machine_mode mode ATTRIBUTE_UNUSED;
919 if (GET_CODE (op) == MEM)
921 rtx inside = XEXP (op, 0);
923 /* Register indirect is a small call. */
924 if (register_operand (inside, Pmode))
925 return 1;
927 /* A call through the function vector is a small call too. */
928 if (GET_CODE (inside) == SYMBOL_REF
929 && (SYMBOL_REF_FLAGS (inside) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
930 return 1;
932 /* Otherwise it's a large call. */
933 return 0;
936 /* Return true if OP is a valid jump operand. */
939 jump_address_operand (op, mode)
940 rtx op;
941 enum machine_mode mode;
943 if (GET_CODE (op) == REG)
944 return mode == Pmode;
946 if (GET_CODE (op) == MEM)
948 rtx inside = XEXP (op, 0);
949 if (register_operand (inside, Pmode))
950 return 1;
951 if (CONSTANT_ADDRESS_P (inside))
952 return 1;
954 return 0;
957 /* Recognize valid operands for bit-field instructions. */
959 extern int rtx_equal_function_value_matters;
962 bit_operand (op, mode)
963 rtx op;
964 enum machine_mode mode;
966 /* We can accept any general operand, except that MEM operands must
967 be limited to those that use addresses valid for the 'U' constraint. */
968 if (!general_operand (op, mode))
969 return 0;
971 /* Accept any mem during RTL generation. Otherwise, the code that does
972 insv and extzv will think that we can not handle memory. However,
973 to avoid reload problems, we only accept 'U' MEM operands after RTL
974 generation. This means that any named pattern which uses this predicate
975 must force its operands to match 'U' before emitting RTL. */
977 if (GET_CODE (op) == REG)
978 return 1;
979 if (GET_CODE (op) == SUBREG)
980 return 1;
981 return (GET_CODE (op) == MEM
982 && EXTRA_CONSTRAINT (op, 'U'));
986 bit_memory_operand (op, mode)
987 rtx op;
988 enum machine_mode mode ATTRIBUTE_UNUSED;
990 return (GET_CODE (op) == MEM
991 && EXTRA_CONSTRAINT (op, 'U'));
994 /* Handle machine specific pragmas for compatibility with existing
995 compilers for the H8/300.
997 pragma saveall generates prologue/epilogue code which saves and
998 restores all the registers on function entry.
1000 pragma interrupt saves and restores all registers, and exits with
1001 an rte instruction rather than an rts. A pointer to a function
1002 with this attribute may be safely used in an interrupt vector. */
1004 void
1005 h8300_pr_interrupt (pfile)
1006 struct cpp_reader *pfile ATTRIBUTE_UNUSED;
1008 pragma_interrupt = 1;
1011 void
1012 h8300_pr_saveall (pfile)
1013 struct cpp_reader *pfile ATTRIBUTE_UNUSED;
1015 pragma_saveall = 1;
1018 /* If the next function argument with MODE and TYPE is to be passed in
1019 a register, return a reg RTX for the hard register in which to pass
1020 the argument. CUM represents the state after the last argument.
1021 If the argument is to be pushed, NULL_RTX is returned. */
1024 function_arg (cum, mode, type, named)
1025 CUMULATIVE_ARGS *cum;
1026 enum machine_mode mode;
1027 tree type;
1028 int named;
1030 static const char *const hand_list[] = {
1031 "__main",
1032 "__cmpsi2",
1033 "__divhi3",
1034 "__modhi3",
1035 "__udivhi3",
1036 "__umodhi3",
1037 "__divsi3",
1038 "__modsi3",
1039 "__udivsi3",
1040 "__umodsi3",
1041 "__mulhi3",
1042 "__mulsi3",
1043 "__reg_memcpy",
1044 "__reg_memset",
1045 "__ucmpsi2",
1049 rtx result = NULL_RTX;
1050 const char *fname;
1051 int regpass = 0;
1053 /* Never pass unnamed arguments in registers. */
1054 if (!named)
1055 return NULL_RTX;
1057 /* Pass 3 regs worth of data in regs when user asked on the command line. */
1058 if (TARGET_QUICKCALL)
1059 regpass = 3;
1061 /* If calling hand written assembler, use 4 regs of args. */
1062 if (cum->libcall)
1064 const char * const *p;
1066 fname = XSTR (cum->libcall, 0);
1068 /* See if this libcall is one of the hand coded ones. */
1069 for (p = hand_list; *p && strcmp (*p, fname) != 0; p++)
1072 if (*p)
1073 regpass = 4;
1076 if (regpass)
1078 int size;
1080 if (mode == BLKmode)
1081 size = int_size_in_bytes (type);
1082 else
1083 size = GET_MODE_SIZE (mode);
1085 if (size + cum->nbytes <= regpass * UNITS_PER_WORD
1086 && cum->nbytes / UNITS_PER_WORD <= 3)
1087 result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
1090 return result;
1093 /* Return the cost of the rtx R with code CODE. */
1095 static int
1096 const_costs (r, c, outer_code)
1097 rtx r;
1098 enum rtx_code c;
1099 enum rtx_code outer_code;
1101 switch (c)
1103 case CONST_INT:
1105 HOST_WIDE_INT n = INTVAL (r);
1107 if (-4 <= n || n <= 4)
1109 switch ((int) n)
1111 case 0:
1112 return 0;
1113 case 1:
1114 case 2:
1115 case -1:
1116 case -2:
1117 return 0 + (outer_code == SET);
1118 case 4:
1119 case -4:
1120 if (TARGET_H8300H || TARGET_H8300S)
1121 return 0 + (outer_code == SET);
1122 else
1123 return 1;
1126 return 1;
1129 case CONST:
1130 case LABEL_REF:
1131 case SYMBOL_REF:
1132 return 3;
1134 case CONST_DOUBLE:
1135 return 20;
1137 default:
1138 return 4;
1142 static int
1143 h8300_and_costs (x)
1144 rtx x;
1146 rtx operands[4];
1148 if (GET_MODE (x) == QImode)
1149 return 1;
1151 if (GET_MODE (x) != HImode
1152 && GET_MODE (x) != SImode)
1153 return 100;
1155 operands[0] = NULL;
1156 operands[1] = NULL;
1157 operands[2] = XEXP (x, 1);
1158 operands[3] = x;
1159 return compute_logical_op_length (GET_MODE (x), operands) / 2;
1162 static int
1163 h8300_shift_costs (x)
1164 rtx x;
1166 rtx operands[4];
1168 if (GET_MODE (x) != QImode
1169 && GET_MODE (x) != HImode
1170 && GET_MODE (x) != SImode)
1171 return 100;
1173 operands[0] = NULL;
1174 operands[1] = NULL;
1175 operands[2] = XEXP (x, 1);
1176 operands[3] = x;
1177 return compute_a_shift_length (NULL, operands) / 2;
1180 static bool
1181 h8300_rtx_costs (x, code, outer_code, total)
1182 rtx x;
1183 int code, outer_code;
1184 int *total;
1186 switch (code)
1188 case AND:
1189 *total = COSTS_N_INSNS (h8300_and_costs (x));
1190 return true;
1192 /* We say that MOD and DIV are so expensive because otherwise we'll
1193 generate some really horrible code for division of a power of two. */
1194 case MOD:
1195 case DIV:
1196 *total = 60;
1197 return true;
1199 case MULT:
1200 *total = 20;
1201 return true;
1203 case ASHIFT:
1204 case ASHIFTRT:
1205 case LSHIFTRT:
1206 *total = COSTS_N_INSNS (h8300_shift_costs (x));
1207 return true;
1209 case ROTATE:
1210 case ROTATERT:
1211 if (GET_MODE (x) == HImode)
1212 *total = 2;
1213 else
1214 *total = 8;
1215 return true;
1217 default:
1218 *total = const_costs (x, code, outer_code);
1219 return true;
1223 /* Documentation for the machine specific operand escapes:
1225 'E' like s but negative.
1226 'F' like t but negative.
1227 'G' constant just the negative
1228 'R' print operand as a byte:8 address if appropriate, else fall back to
1229 'X' handling.
1230 'S' print operand as a long word
1231 'T' print operand as a word
1232 'V' find the set bit, and print its number.
1233 'W' find the clear bit, and print its number.
1234 'X' print operand as a byte
1235 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
1236 If this operand isn't a register, fall back to 'R' handling.
1237 'Z' print int & 7.
1238 'b' print the bit opcode
1239 'c' print the opcode corresponding to rtl
1240 'e' first word of 32 bit value - if reg, then least reg. if mem
1241 then least. if const then most sig word
1242 'f' second word of 32 bit value - if reg, then biggest reg. if mem
1243 then +2. if const then least sig word
1244 'j' print operand as condition code.
1245 'k' print operand as reverse condition code.
1246 's' print as low byte of 16 bit value
1247 't' print as high byte of 16 bit value
1248 'w' print as low byte of 32 bit value
1249 'x' print as 2nd byte of 32 bit value
1250 'y' print as 3rd byte of 32 bit value
1251 'z' print as msb of 32 bit value
1254 /* Return assembly language string which identifies a comparison type. */
1256 static const char *
1257 cond_string (code)
1258 enum rtx_code code;
1260 switch (code)
1262 case NE:
1263 return "ne";
1264 case EQ:
1265 return "eq";
1266 case GE:
1267 return "ge";
1268 case GT:
1269 return "gt";
1270 case LE:
1271 return "le";
1272 case LT:
1273 return "lt";
1274 case GEU:
1275 return "hs";
1276 case GTU:
1277 return "hi";
1278 case LEU:
1279 return "ls";
1280 case LTU:
1281 return "lo";
1282 default:
1283 abort ();
1287 /* Print operand X using operand code CODE to assembly language output file
1288 FILE. */
1290 void
1291 print_operand (file, x, code)
1292 FILE *file;
1293 rtx x;
1294 int code;
1296 /* This is used for communication between codes V,W,Z and Y. */
1297 static int bitint;
1299 switch (code)
1301 case 'E':
1302 switch (GET_CODE (x))
1304 case REG:
1305 fprintf (file, "%sl", names_big[REGNO (x)]);
1306 break;
1307 case CONST_INT:
1308 fprintf (file, "#%ld", (-INTVAL (x)) & 0xff);
1309 break;
1310 default:
1311 abort ();
1313 break;
1314 case 'F':
1315 switch (GET_CODE (x))
1317 case REG:
1318 fprintf (file, "%sh", names_big[REGNO (x)]);
1319 break;
1320 case CONST_INT:
1321 fprintf (file, "#%ld", ((-INTVAL (x)) & 0xff00) >> 8);
1322 break;
1323 default:
1324 abort ();
1326 break;
1327 case 'G':
1328 if (GET_CODE (x) != CONST_INT)
1329 abort ();
1330 fprintf (file, "#%ld", 0xff & (-INTVAL (x)));
1331 break;
1332 case 'S':
1333 if (GET_CODE (x) == REG)
1334 fprintf (file, "%s", names_extended[REGNO (x)]);
1335 else
1336 goto def;
1337 break;
1338 case 'T':
1339 if (GET_CODE (x) == REG)
1340 fprintf (file, "%s", names_big[REGNO (x)]);
1341 else
1342 goto def;
1343 break;
1344 case 'V':
1345 bitint = exact_log2 (INTVAL (x) & 0xff);
1346 if (bitint == -1)
1347 abort ();
1348 fprintf (file, "#%d", bitint);
1349 break;
1350 case 'W':
1351 bitint = exact_log2 ((~INTVAL (x)) & 0xff);
1352 if (bitint == -1)
1353 abort ();
1354 fprintf (file, "#%d", bitint);
1355 break;
1356 case 'R':
1357 case 'X':
1358 if (GET_CODE (x) == REG)
1359 fprintf (file, "%s", byte_reg (x, 0));
1360 else
1361 goto def;
1362 break;
1363 case 'Y':
1364 if (bitint == -1)
1365 abort ();
1366 if (GET_CODE (x) == REG)
1367 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
1368 else
1369 print_operand (file, x, 'R');
1370 bitint = -1;
1371 break;
1372 case 'Z':
1373 bitint = INTVAL (x);
1374 fprintf (file, "#%d", bitint & 7);
1375 break;
1376 case 'b':
1377 switch (GET_CODE (x))
1379 case IOR:
1380 fprintf (file, "bor");
1381 break;
1382 case XOR:
1383 fprintf (file, "bxor");
1384 break;
1385 case AND:
1386 fprintf (file, "band");
1387 break;
1388 default:
1389 break;
1391 break;
1392 case 'c':
1393 switch (GET_CODE (x))
1395 case IOR:
1396 fprintf (file, "or");
1397 break;
1398 case XOR:
1399 fprintf (file, "xor");
1400 break;
1401 default:
1402 break;
1404 break;
1405 case 'e':
1406 switch (GET_CODE (x))
1408 case REG:
1409 if (TARGET_H8300)
1410 fprintf (file, "%s", names_big[REGNO (x)]);
1411 else
1412 fprintf (file, "%s", names_upper_extended[REGNO (x)]);
1413 break;
1414 case MEM:
1415 print_operand (file, x, 0);
1416 break;
1417 case CONST_INT:
1418 fprintf (file, "#%ld", ((INTVAL (x) >> 16) & 0xffff));
1419 break;
1420 case CONST_DOUBLE:
1422 long val;
1423 REAL_VALUE_TYPE rv;
1424 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1425 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1426 fprintf (file, "#%ld", ((val >> 16) & 0xffff));
1427 break;
1429 default:
1430 abort ();
1431 break;
1433 break;
1434 case 'f':
1435 switch (GET_CODE (x))
1437 case REG:
1438 if (TARGET_H8300)
1439 fprintf (file, "%s", names_big[REGNO (x) + 1]);
1440 else
1441 fprintf (file, "%s", names_big[REGNO (x)]);
1442 break;
1443 case MEM:
1444 x = adjust_address (x, HImode, 2);
1445 print_operand (file, x, 0);
1446 break;
1447 case CONST_INT:
1448 fprintf (file, "#%ld", INTVAL (x) & 0xffff);
1449 break;
1450 case CONST_DOUBLE:
1452 long val;
1453 REAL_VALUE_TYPE rv;
1454 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1455 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1456 fprintf (file, "#%ld", (val & 0xffff));
1457 break;
1459 default:
1460 abort ();
1462 break;
1463 case 'j':
1464 fputs (cond_string (GET_CODE (x)), file);
1465 break;
1466 case 'k':
1467 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1468 break;
1469 case 's':
1470 if (GET_CODE (x) == CONST_INT)
1471 fprintf (file, "#%ld", (INTVAL (x)) & 0xff);
1472 else
1473 fprintf (file, "%s", byte_reg (x, 0));
1474 break;
1475 case 't':
1476 if (GET_CODE (x) == CONST_INT)
1477 fprintf (file, "#%ld", (INTVAL (x) >> 8) & 0xff);
1478 else
1479 fprintf (file, "%s", byte_reg (x, 1));
1480 break;
1481 case 'u':
1482 if (GET_CODE (x) != CONST_INT)
1483 abort ();
1484 fprintf (file, "%ld", INTVAL (x));
1485 break;
1486 case 'w':
1487 if (GET_CODE (x) == CONST_INT)
1488 fprintf (file, "#%ld", INTVAL (x) & 0xff);
1489 else
1490 fprintf (file, "%s",
1491 byte_reg (x, TARGET_H8300 ? 2 : 0));
1492 break;
1493 case 'x':
1494 if (GET_CODE (x) == CONST_INT)
1495 fprintf (file, "#%ld", (INTVAL (x) >> 8) & 0xff);
1496 else
1497 fprintf (file, "%s",
1498 byte_reg (x, TARGET_H8300 ? 3 : 1));
1499 break;
1500 case 'y':
1501 if (GET_CODE (x) == CONST_INT)
1502 fprintf (file, "#%ld", (INTVAL (x) >> 16) & 0xff);
1503 else
1504 fprintf (file, "%s", byte_reg (x, 0));
1505 break;
1506 case 'z':
1507 if (GET_CODE (x) == CONST_INT)
1508 fprintf (file, "#%ld", (INTVAL (x) >> 24) & 0xff);
1509 else
1510 fprintf (file, "%s", byte_reg (x, 1));
1511 break;
1513 default:
1514 def:
1515 switch (GET_CODE (x))
1517 case REG:
1518 switch (GET_MODE (x))
1520 case QImode:
1521 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */
1522 fprintf (file, "%s", byte_reg (x, 0));
1523 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1524 fprintf (file, "%s", names_big[REGNO (x)]);
1525 #endif
1526 break;
1527 case HImode:
1528 fprintf (file, "%s", names_big[REGNO (x)]);
1529 break;
1530 case SImode:
1531 case SFmode:
1532 fprintf (file, "%s", names_extended[REGNO (x)]);
1533 break;
1534 default:
1535 abort ();
1537 break;
1539 case MEM:
1541 rtx addr = XEXP (x, 0);
1543 fprintf (file, "@");
1544 output_address (addr);
1546 /* We fall back from smaller addressing to larger
1547 addressing in various ways depending on CODE. */
1548 switch (code)
1550 case 'R':
1551 /* Used for mov.b and bit operations. */
1552 if (h8300_eightbit_constant_address_p (addr))
1554 fprintf (file, ":8");
1555 break;
1558 /* Fall through. We should not get here if we are
1559 processing bit operations on H8/300 or H8/300H
1560 because 'U' constraint does not allow bit
1561 operations on the tiny area on these machines. */
1563 case 'T':
1564 case 'S':
1565 /* Used for mov.w and mov.l. */
1566 if (h8300_tiny_constant_address_p (addr))
1567 fprintf (file, ":16");
1568 break;
1569 default:
1570 break;
1573 break;
1575 case CONST_INT:
1576 case SYMBOL_REF:
1577 case CONST:
1578 case LABEL_REF:
1579 fprintf (file, "#");
1580 print_operand_address (file, x);
1581 break;
1582 case CONST_DOUBLE:
1584 long val;
1585 REAL_VALUE_TYPE rv;
1586 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1587 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1588 fprintf (file, "#%ld", val);
1589 break;
1591 default:
1592 break;
1597 /* Output assembly language output for the address ADDR to FILE. */
1599 void
1600 print_operand_address (file, addr)
1601 FILE *file;
1602 rtx addr;
1604 switch (GET_CODE (addr))
1606 case REG:
1607 fprintf (file, "%s", h8_reg_names[REGNO (addr)]);
1608 break;
1610 case PRE_DEC:
1611 fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
1612 break;
1614 case POST_INC:
1615 fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);
1616 break;
1618 case PLUS:
1619 fprintf (file, "(");
1620 if (GET_CODE (XEXP (addr, 0)) == REG)
1622 /* reg,foo */
1623 print_operand_address (file, XEXP (addr, 1));
1624 fprintf (file, ",");
1625 print_operand_address (file, XEXP (addr, 0));
1627 else
1629 /* foo+k */
1630 print_operand_address (file, XEXP (addr, 0));
1631 fprintf (file, "+");
1632 print_operand_address (file, XEXP (addr, 1));
1634 fprintf (file, ")");
1635 break;
1637 case CONST_INT:
1639 /* Since the H8/300 only has 16 bit pointers, negative values are also
1640 those >= 32768. This happens for example with pointer minus a
1641 constant. We don't want to turn (char *p - 2) into
1642 (char *p + 65534) because loop unrolling can build upon this
1643 (IE: char *p + 131068). */
1644 int n = INTVAL (addr);
1645 if (TARGET_H8300)
1646 n = (int) (short) n;
1647 fprintf (file, "%d", n);
1648 break;
1651 default:
1652 output_addr_const (file, addr);
1653 break;
1657 /* Output all insn addresses and their sizes into the assembly language
1658 output file. This is helpful for debugging whether the length attributes
1659 in the md file are correct. This is not meant to be a user selectable
1660 option. */
1662 void
1663 final_prescan_insn (insn, operand, num_operands)
1664 rtx insn, *operand ATTRIBUTE_UNUSED;
1665 int num_operands ATTRIBUTE_UNUSED;
1667 /* This holds the last insn address. */
1668 static int last_insn_address = 0;
1670 const int uid = INSN_UID (insn);
1672 if (TARGET_RTL_DUMP)
1674 fprintf (asm_out_file, "\n****************");
1675 print_rtl (asm_out_file, PATTERN (insn));
1676 fprintf (asm_out_file, "\n");
1679 if (TARGET_ADDRESSES)
1681 fprintf (asm_out_file, "; 0x%x %d\n", INSN_ADDRESSES (uid),
1682 INSN_ADDRESSES (uid) - last_insn_address);
1683 last_insn_address = INSN_ADDRESSES (uid);
1687 /* Prepare for an SI sized move. */
1690 do_movsi (operands)
1691 rtx operands[];
1693 rtx src = operands[1];
1694 rtx dst = operands[0];
1695 if (!reload_in_progress && !reload_completed)
1697 if (!register_operand (dst, GET_MODE (dst)))
1699 rtx tmp = gen_reg_rtx (GET_MODE (dst));
1700 emit_move_insn (tmp, src);
1701 operands[1] = tmp;
1704 return 0;
1707 /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
1708 Define the offset between two registers, one to be eliminated, and
1709 the other its replacement, at the start of a routine. */
1712 h8300_initial_elimination_offset (from, to)
1713 int from, to;
1715 int offset = 0;
1716 /* The number of bytes that the return address takes on the stack. */
1717 int pc_size = POINTER_SIZE / BITS_PER_UNIT;
1719 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1720 offset = pc_size + frame_pointer_needed * UNITS_PER_WORD;
1721 else if (from == RETURN_ADDRESS_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1722 offset = frame_pointer_needed * UNITS_PER_WORD;
1723 else
1725 int regno;
1727 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1728 if (WORD_REG_USED (regno))
1729 offset += UNITS_PER_WORD;
1731 /* See the comments for get_frame_size. We need to round it up to
1732 STACK_BOUNDARY. */
1734 offset += round_frame_size (get_frame_size ());
1736 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1737 /* Skip saved PC. */
1738 offset += pc_size;
1741 return offset;
1745 h8300_return_addr_rtx (count, frame)
1746 int count;
1747 rtx frame;
1749 rtx ret;
1751 if (count == 0)
1752 ret = gen_rtx_MEM (Pmode,
1753 gen_rtx_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM));
1754 else if (flag_omit_frame_pointer)
1755 return (rtx) 0;
1756 else
1757 ret = gen_rtx_MEM (Pmode,
1758 memory_address (Pmode,
1759 plus_constant (frame, UNITS_PER_WORD)));
1760 set_mem_alias_set (ret, get_frame_alias_set ());
1761 return ret;
1764 /* Update the condition code from the insn. */
1766 void
1767 notice_update_cc (body, insn)
1768 rtx body;
1769 rtx insn;
1771 rtx set;
1773 switch (get_attr_cc (insn))
1775 case CC_NONE:
1776 /* Insn does not affect CC at all. */
1777 break;
1779 case CC_NONE_0HIT:
1780 /* Insn does not change CC, but the 0'th operand has been changed. */
1781 if (cc_status.value1 != 0
1782 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
1783 cc_status.value1 = 0;
1784 if (cc_status.value2 != 0
1785 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value2))
1786 cc_status.value2 = 0;
1787 break;
1789 case CC_SET_ZN:
1790 /* Insn sets the Z,N flags of CC to recog_data.operand[0].
1791 The V flag is unusable. The C flag may or may not be known but
1792 that's ok because alter_cond will change tests to use EQ/NE. */
1793 CC_STATUS_INIT;
1794 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
1795 set = single_set (insn);
1796 cc_status.value1 = SET_SRC (set);
1797 if (SET_DEST (set) != cc0_rtx)
1798 cc_status.value2 = SET_DEST (set);
1799 break;
1801 case CC_SET_ZNV:
1802 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
1803 The C flag may or may not be known but that's ok because
1804 alter_cond will change tests to use EQ/NE. */
1805 CC_STATUS_INIT;
1806 cc_status.flags |= CC_NO_CARRY;
1807 set = single_set (insn);
1808 cc_status.value1 = SET_SRC (set);
1809 if (SET_DEST (set) != cc0_rtx)
1811 /* If the destination is STRICT_LOW_PART, strip off
1812 STRICT_LOW_PART. */
1813 if (GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
1814 cc_status.value2 = XEXP (SET_DEST (set), 0);
1815 else
1816 cc_status.value2 = SET_DEST (set);
1818 break;
1820 case CC_COMPARE:
1821 /* The insn is a compare instruction. */
1822 CC_STATUS_INIT;
1823 cc_status.value1 = SET_SRC (body);
1824 break;
1826 case CC_CLOBBER:
1827 /* Insn doesn't leave CC in a usable state. */
1828 CC_STATUS_INIT;
1829 break;
1833 /* Return nonzero if X is a stack pointer. */
1836 stack_pointer_operand (x, mode)
1837 rtx x;
1838 enum machine_mode mode ATTRIBUTE_UNUSED;
1840 return x == stack_pointer_rtx;
1843 /* Return nonzero if X is a constant whose absolute value is greater
1844 than 2. */
1847 const_int_gt_2_operand (x, mode)
1848 rtx x;
1849 enum machine_mode mode ATTRIBUTE_UNUSED;
1851 return (GET_CODE (x) == CONST_INT
1852 && abs (INTVAL (x)) > 2);
1855 /* Return nonzero if X is a constant whose absolute value is no
1856 smaller than 8. */
1859 const_int_ge_8_operand (x, mode)
1860 rtx x;
1861 enum machine_mode mode ATTRIBUTE_UNUSED;
1863 return (GET_CODE (x) == CONST_INT
1864 && abs (INTVAL (x)) >= 8);
1867 /* Return nonzero if X is a constant expressible in QImode. */
1870 const_int_qi_operand (x, mode)
1871 rtx x;
1872 enum machine_mode mode ATTRIBUTE_UNUSED;
1874 return (GET_CODE (x) == CONST_INT
1875 && (INTVAL (x) & 0xff) == INTVAL (x));
1878 /* Return nonzero if X is a constant expressible in HImode. */
1881 const_int_hi_operand (x, mode)
1882 rtx x;
1883 enum machine_mode mode ATTRIBUTE_UNUSED;
1885 return (GET_CODE (x) == CONST_INT
1886 && (INTVAL (x) & 0xffff) == INTVAL (x));
1889 /* Return nonzero if X is a constant suitable for inc/dec. */
1892 incdec_operand (x, mode)
1893 rtx x;
1894 enum machine_mode mode ATTRIBUTE_UNUSED;
1896 return (GET_CODE (x) == CONST_INT
1897 && (CONST_OK_FOR_M (INTVAL (x))
1898 || CONST_OK_FOR_O (INTVAL (x))));
1901 /* Return nonzero if X is either EQ or NE. */
1904 eqne_operator (x, mode)
1905 rtx x;
1906 enum machine_mode mode ATTRIBUTE_UNUSED;
1908 enum rtx_code code = GET_CODE (x);
1910 return (code == EQ || code == NE);
1913 /* Return nonzero if X is GT, LE, GTU, or LEU. */
1916 gtle_operator (x, mode)
1917 rtx x;
1918 enum machine_mode mode ATTRIBUTE_UNUSED;
1920 enum rtx_code code = GET_CODE (x);
1922 return (code == GT || code == LE || code == GTU || code == LEU);
1925 /* Return nonzero if X is either GTU or LEU. */
1928 gtuleu_operator (x, mode)
1929 rtx x;
1930 enum machine_mode mode ATTRIBUTE_UNUSED;
1932 enum rtx_code code = GET_CODE (x);
1934 return (code == GTU || code == LEU);
1937 /* Return nonzero if X is either IOR or XOR. */
1940 iorxor_operator (x, mode)
1941 rtx x;
1942 enum machine_mode mode ATTRIBUTE_UNUSED;
1944 enum rtx_code code = GET_CODE (x);
1946 return (code == IOR || code == XOR);
1949 /* Recognize valid operators for bit instructions. */
1952 bit_operator (x, mode)
1953 rtx x;
1954 enum machine_mode mode ATTRIBUTE_UNUSED;
1956 enum rtx_code code = GET_CODE (x);
1958 return (code == XOR
1959 || code == AND
1960 || code == IOR);
1963 const char *
1964 output_plussi (operands)
1965 rtx *operands;
1967 enum machine_mode mode = GET_MODE (operands[0]);
1969 if (mode != SImode)
1970 abort ();
1972 if (TARGET_H8300)
1974 if (GET_CODE (operands[2]) == REG)
1975 return "add.w\t%f2,%f0\n\taddx\t%y2,%y0\n\taddx\t%z2,%z0";
1977 if (GET_CODE (operands[2]) == CONST_INT)
1979 HOST_WIDE_INT n = INTVAL (operands[2]);
1981 if ((n & 0xffffff) == 0)
1982 return "add\t%z2,%z0";
1983 if ((n & 0xffff) == 0)
1984 return "add\t%y2,%y0\n\taddx\t%z2,%z0";
1985 if ((n & 0xff) == 0)
1986 return "add\t%x2,%x0\n\taddx\t%y2,%y0\n\taddx\t%z2,%z0";
1989 return "add\t%w2,%w0\n\taddx\t%x2,%x0\n\taddx\t%y2,%y0\n\taddx\t%z2,%z0";
1991 else
1993 if (GET_CODE (operands[2]) == REG)
1994 return "add.l\t%S2,%S0";
1996 if (GET_CODE (operands[2]) == CONST_INT)
1998 HOST_WIDE_INT intval = INTVAL (operands[2]);
2000 /* See if we can finish with 2 bytes. */
2002 switch ((unsigned int) intval & 0xffffffff)
2004 case 0x00000001:
2005 case 0x00000002:
2006 case 0x00000004:
2007 return "adds\t%2,%S0";
2009 case 0xffffffff:
2010 case 0xfffffffe:
2011 case 0xfffffffc:
2012 return "subs\t%G2,%S0";
2014 case 0x00010000:
2015 case 0x00020000:
2016 operands[2] = GEN_INT (intval >> 16);
2017 return "inc.w\t%2,%e0";
2019 case 0xffff0000:
2020 case 0xfffe0000:
2021 operands[2] = GEN_INT (intval >> 16);
2022 return "dec.w\t%G2,%e0";
2025 /* See if we can finish with 4 bytes. */
2026 if ((intval & 0xffff) == 0)
2028 operands[2] = GEN_INT (intval >> 16);
2029 return "add.w\t%2,%e0";
2033 return "add.l\t%S2,%S0";
2037 unsigned int
2038 compute_plussi_length (operands)
2039 rtx *operands;
2041 enum machine_mode mode = GET_MODE (operands[0]);
2043 if (mode != SImode)
2044 abort ();
2046 if (TARGET_H8300)
2048 if (GET_CODE (operands[2]) == REG)
2049 return 6;
2051 if (GET_CODE (operands[2]) == CONST_INT)
2053 HOST_WIDE_INT n = INTVAL (operands[2]);
2055 if ((n & 0xffffff) == 0)
2056 return 2;
2057 if ((n & 0xffff) == 0)
2058 return 4;
2059 if ((n & 0xff) == 0)
2060 return 6;
2063 return 8;
2065 else
2067 if (GET_CODE (operands[2]) == REG)
2068 return 2;
2070 if (GET_CODE (operands[2]) == CONST_INT)
2072 HOST_WIDE_INT intval = INTVAL (operands[2]);
2074 /* See if we can finish with 2 bytes. */
2076 switch ((unsigned int) intval & 0xffffffff)
2078 case 0x00000001:
2079 case 0x00000002:
2080 case 0x00000004:
2081 return 2;
2083 case 0xffffffff:
2084 case 0xfffffffe:
2085 case 0xfffffffc:
2086 return 2;
2088 case 0x00010000:
2089 case 0x00020000:
2090 return 2;
2092 case 0xffff0000:
2093 case 0xfffe0000:
2094 return 2;
2097 /* See if we can finish with 4 bytes. */
2098 if ((intval & 0xffff) == 0)
2099 return 4;
2102 return 6;
2107 compute_plussi_cc (operands)
2108 rtx *operands;
2110 enum machine_mode mode = GET_MODE (operands[0]);
2112 if (mode != SImode)
2113 abort ();
2115 if (TARGET_H8300)
2117 return CC_CLOBBER;
2119 else
2121 if (GET_CODE (operands[2]) == REG)
2122 return CC_SET_ZN;
2124 if (GET_CODE (operands[2]) == CONST_INT)
2126 HOST_WIDE_INT intval = INTVAL (operands[2]);
2128 /* See if we can finish with 2 bytes. */
2130 switch ((unsigned int) intval & 0xffffffff)
2132 case 0x00000001:
2133 case 0x00000002:
2134 case 0x00000004:
2135 return CC_NONE_0HIT;
2137 case 0xffffffff:
2138 case 0xfffffffe:
2139 case 0xfffffffc:
2140 return CC_NONE_0HIT;
2142 case 0x00010000:
2143 case 0x00020000:
2144 return CC_CLOBBER;
2146 case 0xffff0000:
2147 case 0xfffe0000:
2148 return CC_CLOBBER;
2151 /* See if we can finish with 4 bytes. */
2152 if ((intval & 0xffff) == 0)
2153 return CC_CLOBBER;
2156 return CC_SET_ZN;
2160 const char *
2161 output_logical_op (mode, operands)
2162 enum machine_mode mode;
2163 rtx *operands;
2165 /* Figure out the logical op that we need to perform. */
2166 enum rtx_code code = GET_CODE (operands[3]);
2167 /* Pretend that every byte is affected if both operands are registers. */
2168 const unsigned HOST_WIDE_INT intval =
2169 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
2170 ? INTVAL (operands[2]) : 0x55555555);
2171 /* The determinant of the algorithm. If we perform an AND, 0
2172 affects a bit. Otherwise, 1 affects a bit. */
2173 const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
2174 /* Break up DET into pieces. */
2175 const unsigned HOST_WIDE_INT b0 = (det >> 0) & 0xff;
2176 const unsigned HOST_WIDE_INT b1 = (det >> 8) & 0xff;
2177 const unsigned HOST_WIDE_INT b2 = (det >> 16) & 0xff;
2178 const unsigned HOST_WIDE_INT b3 = (det >> 24) & 0xff;
2179 const unsigned HOST_WIDE_INT w0 = (det >> 0) & 0xffff;
2180 const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff;
2181 int lower_half_easy_p = 0;
2182 int upper_half_easy_p = 0;
2183 /* The name of an insn. */
2184 const char *opname;
2185 char insn_buf[100];
2187 switch (code)
2189 case AND:
2190 opname = "and";
2191 break;
2192 case IOR:
2193 opname = "or";
2194 break;
2195 case XOR:
2196 opname = "xor";
2197 break;
2198 default:
2199 abort ();
2202 switch (mode)
2204 case HImode:
2205 /* First, see if we can finish with one insn. */
2206 if ((TARGET_H8300H || TARGET_H8300S)
2207 && b0 != 0
2208 && b1 != 0)
2210 sprintf (insn_buf, "%s.w\t%%T2,%%T0", opname);
2211 output_asm_insn (insn_buf, operands);
2213 else
2215 /* Take care of the lower byte. */
2216 if (b0 != 0)
2218 sprintf (insn_buf, "%s\t%%s2,%%s0", opname);
2219 output_asm_insn (insn_buf, operands);
2221 /* Take care of the upper byte. */
2222 if (b1 != 0)
2224 sprintf (insn_buf, "%s\t%%t2,%%t0", opname);
2225 output_asm_insn (insn_buf, operands);
2228 break;
2229 case SImode:
2230 if (TARGET_H8300H || TARGET_H8300S)
2232 /* Determine if the lower half can be taken care of in no more
2233 than two bytes. */
2234 lower_half_easy_p = (b0 == 0
2235 || b1 == 0
2236 || (code != IOR && w0 == 0xffff));
2238 /* Determine if the upper half can be taken care of in no more
2239 than two bytes. */
2240 upper_half_easy_p = ((code != IOR && w1 == 0xffff)
2241 || (code == AND && w1 == 0xff00));
2244 /* Check if doing everything with one insn is no worse than
2245 using multiple insns. */
2246 if ((TARGET_H8300H || TARGET_H8300S)
2247 && w0 != 0 && w1 != 0
2248 && !(lower_half_easy_p && upper_half_easy_p)
2249 && !(code == IOR && w1 == 0xffff
2250 && (w0 & 0x8000) != 0 && lower_half_easy_p))
2252 sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname);
2253 output_asm_insn (insn_buf, operands);
2255 else
2257 /* Take care of the lower and upper words individually. For
2258 each word, we try different methods in the order of
2260 1) the special insn (in case of AND or XOR),
2261 2) the word-wise insn, and
2262 3) The byte-wise insn. */
2263 if (w0 == 0xffff
2264 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
2265 output_asm_insn ((code == AND)
2266 ? "sub.w\t%f0,%f0" : "not.w\t%f0",
2267 operands);
2268 else if ((TARGET_H8300H || TARGET_H8300S)
2269 && (b0 != 0)
2270 && (b1 != 0))
2272 sprintf (insn_buf, "%s.w\t%%f2,%%f0", opname);
2273 output_asm_insn (insn_buf, operands);
2275 else
2277 if (b0 != 0)
2279 sprintf (insn_buf, "%s\t%%w2,%%w0", opname);
2280 output_asm_insn (insn_buf, operands);
2282 if (b1 != 0)
2284 sprintf (insn_buf, "%s\t%%x2,%%x0", opname);
2285 output_asm_insn (insn_buf, operands);
2289 if ((w1 == 0xffff)
2290 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
2291 output_asm_insn ((code == AND)
2292 ? "sub.w\t%e0,%e0" : "not.w\t%e0",
2293 operands);
2294 else if ((TARGET_H8300H || TARGET_H8300S)
2295 && code == IOR
2296 && w1 == 0xffff
2297 && (w0 & 0x8000) != 0)
2299 output_asm_insn ("exts.l\t%S0", operands);
2301 else if ((TARGET_H8300H || TARGET_H8300S)
2302 && code == AND
2303 && w1 == 0xff00)
2305 output_asm_insn ("extu.w\t%e0", operands);
2307 else if (TARGET_H8300H || TARGET_H8300S)
2309 if (w1 != 0)
2311 sprintf (insn_buf, "%s.w\t%%e2,%%e0", opname);
2312 output_asm_insn (insn_buf, operands);
2315 else
2317 if (b2 != 0)
2319 sprintf (insn_buf, "%s\t%%y2,%%y0", opname);
2320 output_asm_insn (insn_buf, operands);
2322 if (b3 != 0)
2324 sprintf (insn_buf, "%s\t%%z2,%%z0", opname);
2325 output_asm_insn (insn_buf, operands);
2329 break;
2330 default:
2331 abort ();
2333 return "";
2336 unsigned int
2337 compute_logical_op_length (mode, operands)
2338 enum machine_mode mode;
2339 rtx *operands;
2341 /* Figure out the logical op that we need to perform. */
2342 enum rtx_code code = GET_CODE (operands[3]);
2343 /* Pretend that every byte is affected if both operands are registers. */
2344 const unsigned HOST_WIDE_INT intval =
2345 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
2346 ? INTVAL (operands[2]) : 0x55555555);
2347 /* The determinant of the algorithm. If we perform an AND, 0
2348 affects a bit. Otherwise, 1 affects a bit. */
2349 const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
2350 /* Break up DET into pieces. */
2351 const unsigned HOST_WIDE_INT b0 = (det >> 0) & 0xff;
2352 const unsigned HOST_WIDE_INT b1 = (det >> 8) & 0xff;
2353 const unsigned HOST_WIDE_INT b2 = (det >> 16) & 0xff;
2354 const unsigned HOST_WIDE_INT b3 = (det >> 24) & 0xff;
2355 const unsigned HOST_WIDE_INT w0 = (det >> 0) & 0xffff;
2356 const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff;
2357 int lower_half_easy_p = 0;
2358 int upper_half_easy_p = 0;
2359 /* Insn length. */
2360 unsigned int length = 0;
2362 switch (mode)
2364 case HImode:
2365 /* First, see if we can finish with one insn. */
2366 if ((TARGET_H8300H || TARGET_H8300S)
2367 && b0 != 0
2368 && b1 != 0)
2370 if (REG_P (operands[2]))
2371 length += 2;
2372 else
2373 length += 4;
2375 else
2377 /* Take care of the lower byte. */
2378 if (b0 != 0)
2379 length += 2;
2381 /* Take care of the upper byte. */
2382 if (b1 != 0)
2383 length += 2;
2385 break;
2386 case SImode:
2387 if (TARGET_H8300H || TARGET_H8300S)
2389 /* Determine if the lower half can be taken care of in no more
2390 than two bytes. */
2391 lower_half_easy_p = (b0 == 0
2392 || b1 == 0
2393 || (code != IOR && w0 == 0xffff));
2395 /* Determine if the upper half can be taken care of in no more
2396 than two bytes. */
2397 upper_half_easy_p = ((code != IOR && w1 == 0xffff)
2398 || (code == AND && w1 == 0xff00));
2401 /* Check if doing everything with one insn is no worse than
2402 using multiple insns. */
2403 if ((TARGET_H8300H || TARGET_H8300S)
2404 && w0 != 0 && w1 != 0
2405 && !(lower_half_easy_p && upper_half_easy_p)
2406 && !(code == IOR && w1 == 0xffff
2407 && (w0 & 0x8000) != 0 && lower_half_easy_p))
2409 if (REG_P (operands[2]))
2410 length += 4;
2411 else
2412 length += 6;
2414 else
2416 /* Take care of the lower and upper words individually. For
2417 each word, we try different methods in the order of
2419 1) the special insn (in case of AND or XOR),
2420 2) the word-wise insn, and
2421 3) The byte-wise insn. */
2422 if (w0 == 0xffff
2423 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
2425 length += 2;
2427 else if ((TARGET_H8300H || TARGET_H8300S)
2428 && (b0 != 0)
2429 && (b1 != 0))
2431 length += 4;
2433 else
2435 if (b0 != 0)
2436 length += 2;
2438 if (b1 != 0)
2439 length += 2;
2442 if (w1 == 0xffff
2443 && (TARGET_H8300 ? (code == AND) : (code != IOR)))
2445 length += 2;
2447 else if ((TARGET_H8300H || TARGET_H8300S)
2448 && code == IOR
2449 && w1 == 0xffff
2450 && (w0 & 0x8000) != 0)
2452 length += 2;
2454 else if ((TARGET_H8300H || TARGET_H8300S)
2455 && code == AND
2456 && w1 == 0xff00)
2458 length += 2;
2460 else if (TARGET_H8300H || TARGET_H8300S)
2462 if (w1 != 0)
2463 length += 4;
2465 else
2467 if (b2 != 0)
2468 length += 2;
2470 if (b3 != 0)
2471 length += 2;
2474 break;
2475 default:
2476 abort ();
2478 return length;
2482 compute_logical_op_cc (mode, operands)
2483 enum machine_mode mode;
2484 rtx *operands;
2486 /* Figure out the logical op that we need to perform. */
2487 enum rtx_code code = GET_CODE (operands[3]);
2488 /* Pretend that every byte is affected if both operands are registers. */
2489 const unsigned HOST_WIDE_INT intval =
2490 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
2491 ? INTVAL (operands[2]) : 0x55555555);
2492 /* The determinant of the algorithm. If we perform an AND, 0
2493 affects a bit. Otherwise, 1 affects a bit. */
2494 const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
2495 /* Break up DET into pieces. */
2496 const unsigned HOST_WIDE_INT b0 = (det >> 0) & 0xff;
2497 const unsigned HOST_WIDE_INT b1 = (det >> 8) & 0xff;
2498 const unsigned HOST_WIDE_INT w0 = (det >> 0) & 0xffff;
2499 const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff;
2500 int lower_half_easy_p = 0;
2501 int upper_half_easy_p = 0;
2502 /* Condition code. */
2503 enum attr_cc cc = CC_CLOBBER;
2505 switch (mode)
2507 case HImode:
2508 /* First, see if we can finish with one insn. */
2509 if ((TARGET_H8300H || TARGET_H8300S)
2510 && b0 != 0
2511 && b1 != 0)
2513 cc = CC_SET_ZNV;
2515 break;
2516 case SImode:
2517 if (TARGET_H8300H || TARGET_H8300S)
2519 /* Determine if the lower half can be taken care of in no more
2520 than two bytes. */
2521 lower_half_easy_p = (b0 == 0
2522 || b1 == 0
2523 || (code != IOR && w0 == 0xffff));
2525 /* Determine if the upper half can be taken care of in no more
2526 than two bytes. */
2527 upper_half_easy_p = ((code != IOR && w1 == 0xffff)
2528 || (code == AND && w1 == 0xff00));
2531 /* Check if doing everything with one insn is no worse than
2532 using multiple insns. */
2533 if ((TARGET_H8300H || TARGET_H8300S)
2534 && w0 != 0 && w1 != 0
2535 && !(lower_half_easy_p && upper_half_easy_p)
2536 && !(code == IOR && w1 == 0xffff
2537 && (w0 & 0x8000) != 0 && lower_half_easy_p))
2539 cc = CC_SET_ZNV;
2541 else
2543 if ((TARGET_H8300H || TARGET_H8300S)
2544 && code == IOR
2545 && w1 == 0xffff
2546 && (w0 & 0x8000) != 0)
2548 cc = CC_SET_ZNV;
2551 break;
2552 default:
2553 abort ();
2555 return cc;
2558 /* Shifts.
2560 We devote a fair bit of code to getting efficient shifts since we
2561 can only shift one bit at a time on the H8/300 and H8/300H and only
2562 one or two bits at a time on the H8S.
2564 All shift code falls into one of the following ways of
2565 implementation:
2567 o SHIFT_INLINE: Emit straight line code for the shift; this is used
2568 when a straight line shift is about the same size or smaller than
2569 a loop.
2571 o SHIFT_ROT_AND: Rotate the value the opposite direction, then mask
2572 off the bits we don't need. This is used when only a few of the
2573 bits in the original value will survive in the shifted value.
2575 o SHIFT_SPECIAL: Often it's possible to move a byte or a word to
2576 simulate a shift by 8, 16, or 24 bits. Once moved, a few inline
2577 shifts can be added if the shift count is slightly more than 8 or
2578 16. This case also includes other oddballs that are not worth
2579 explaining here.
2581 o SHIFT_LOOP: Emit a loop using one (or two on H8S) bit shifts.
2583 For each shift count, we try to use code that has no trade-off
2584 between code size and speed whenever possible.
2586 If the trade-off is unavoidable, we try to be reasonable.
2587 Specifically, the fastest version is one instruction longer than
2588 the shortest version, we take the fastest version. We also provide
2589 the use a way to switch back to the shortest version with -Os.
2591 For the details of the shift algorithms for various shift counts,
2592 refer to shift_alg_[qhs]i. */
2595 nshift_operator (x, mode)
2596 rtx x;
2597 enum machine_mode mode ATTRIBUTE_UNUSED;
2599 switch (GET_CODE (x))
2601 case ASHIFTRT:
2602 case LSHIFTRT:
2603 case ASHIFT:
2604 return 1;
2606 default:
2607 return 0;
2611 /* Emit code to do shifts. */
2613 void
2614 expand_a_shift (mode, code, operands)
2615 enum machine_mode mode;
2616 int code;
2617 rtx operands[];
2619 emit_move_insn (operands[0], operands[1]);
2621 /* Need a loop to get all the bits we want - we generate the
2622 code at emit time, but need to allocate a scratch reg now. */
2624 emit_insn (gen_rtx_PARALLEL
2625 (VOIDmode,
2626 gen_rtvec (2,
2627 gen_rtx_SET (VOIDmode, operands[0],
2628 gen_rtx (code, mode, operands[0],
2629 operands[2])),
2630 gen_rtx_CLOBBER (VOIDmode,
2631 gen_rtx_SCRATCH (QImode)))));
2634 /* Symbols of the various modes which can be used as indices. */
2636 enum shift_mode
2638 QIshift, HIshift, SIshift
2641 /* For single bit shift insns, record assembler and what bits of the
2642 condition code are valid afterwards (represented as various CC_FOO
2643 bits, 0 means CC isn't left in a usable state). */
2645 struct shift_insn
2647 const char *const assembler;
2648 const int cc_valid;
2651 /* Assembler instruction shift table.
2653 These tables are used to look up the basic shifts.
2654 They are indexed by cpu, shift_type, and mode. */
2656 static const struct shift_insn shift_one[2][3][3] =
2658 /* H8/300 */
2660 /* SHIFT_ASHIFT */
2662 { "shll\t%X0", CC_SET_ZNV },
2663 { "add.w\t%T0,%T0", CC_SET_ZN },
2664 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", CC_CLOBBER }
2666 /* SHIFT_LSHIFTRT */
2668 { "shlr\t%X0", CC_SET_ZNV },
2669 { "shlr\t%t0\n\trotxr\t%s0", CC_CLOBBER },
2670 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", CC_CLOBBER }
2672 /* SHIFT_ASHIFTRT */
2674 { "shar\t%X0", CC_SET_ZNV },
2675 { "shar\t%t0\n\trotxr\t%s0", CC_CLOBBER },
2676 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", CC_CLOBBER }
2679 /* H8/300H */
2681 /* SHIFT_ASHIFT */
2683 { "shll.b\t%X0", CC_SET_ZNV },
2684 { "shll.w\t%T0", CC_SET_ZNV },
2685 { "shll.l\t%S0", CC_SET_ZNV }
2687 /* SHIFT_LSHIFTRT */
2689 { "shlr.b\t%X0", CC_SET_ZNV },
2690 { "shlr.w\t%T0", CC_SET_ZNV },
2691 { "shlr.l\t%S0", CC_SET_ZNV }
2693 /* SHIFT_ASHIFTRT */
2695 { "shar.b\t%X0", CC_SET_ZNV },
2696 { "shar.w\t%T0", CC_SET_ZNV },
2697 { "shar.l\t%S0", CC_SET_ZNV }
2702 static const struct shift_insn shift_two[3][3] =
2704 /* SHIFT_ASHIFT */
2706 { "shll.b\t#2,%X0", CC_SET_ZNV },
2707 { "shll.w\t#2,%T0", CC_SET_ZNV },
2708 { "shll.l\t#2,%S0", CC_SET_ZNV }
2710 /* SHIFT_LSHIFTRT */
2712 { "shlr.b\t#2,%X0", CC_SET_ZNV },
2713 { "shlr.w\t#2,%T0", CC_SET_ZNV },
2714 { "shlr.l\t#2,%S0", CC_SET_ZNV }
2716 /* SHIFT_ASHIFTRT */
2718 { "shar.b\t#2,%X0", CC_SET_ZNV },
2719 { "shar.w\t#2,%T0", CC_SET_ZNV },
2720 { "shar.l\t#2,%S0", CC_SET_ZNV }
2724 /* Rotates are organized by which shift they'll be used in implementing.
2725 There's no need to record whether the cc is valid afterwards because
2726 it is the AND insn that will decide this. */
2728 static const char *const rotate_one[2][3][3] =
2730 /* H8/300 */
2732 /* SHIFT_ASHIFT */
2734 "rotr\t%X0",
2735 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
2738 /* SHIFT_LSHIFTRT */
2740 "rotl\t%X0",
2741 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
2744 /* SHIFT_ASHIFTRT */
2746 "rotl\t%X0",
2747 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
2751 /* H8/300H */
2753 /* SHIFT_ASHIFT */
2755 "rotr.b\t%X0",
2756 "rotr.w\t%T0",
2757 "rotr.l\t%S0"
2759 /* SHIFT_LSHIFTRT */
2761 "rotl.b\t%X0",
2762 "rotl.w\t%T0",
2763 "rotl.l\t%S0"
2765 /* SHIFT_ASHIFTRT */
2767 "rotl.b\t%X0",
2768 "rotl.w\t%T0",
2769 "rotl.l\t%S0"
2774 static const char *const rotate_two[3][3] =
2776 /* SHIFT_ASHIFT */
2778 "rotr.b\t#2,%X0",
2779 "rotr.w\t#2,%T0",
2780 "rotr.l\t#2,%S0"
2782 /* SHIFT_LSHIFTRT */
2784 "rotl.b\t#2,%X0",
2785 "rotl.w\t#2,%T0",
2786 "rotl.l\t#2,%S0"
2788 /* SHIFT_ASHIFTRT */
2790 "rotl.b\t#2,%X0",
2791 "rotl.w\t#2,%T0",
2792 "rotl.l\t#2,%S0"
2796 struct shift_info {
2797 /* Shift algorithm. */
2798 enum shift_alg alg;
2800 /* The number of bits to be shifted by shift1 and shift2. Valid
2801 when ALG is SHIFT_SPECIAL. */
2802 unsigned int remainder;
2804 /* Special insn for a shift. Valid when ALG is SHIFT_SPECIAL. */
2805 const char *special;
2807 /* Insn for a one-bit shift. Valid when ALG is either SHIFT_INLINE
2808 or SHIFT_SPECIAL, and REMAINDER is nonzero. */
2809 const char *shift1;
2811 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
2812 or SHIFT_SPECIAL, and REMAINDER is nonzero. */
2813 const char *shift2;
2815 /* CC status for SHIFT_INLINE. */
2816 int cc_inline;
2818 /* CC status for SHIFT_SPECIAL. */
2819 int cc_special;
2822 static void get_shift_alg PARAMS ((enum shift_type,
2823 enum shift_mode, unsigned int,
2824 struct shift_info *));
2826 /* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
2827 best algorithm for doing the shift. The assembler code is stored
2828 in the pointers in INFO. We achieve the maximum efficiency in most
2829 cases when !TARGET_H8300. In case of TARGET_H8300, shifts in
2830 SImode in particular have a lot of room to optimize.
2832 We first determine the strategy of the shift algorithm by a table
2833 lookup. If that tells us to use a hand crafted assembly code, we
2834 go into the big switch statement to find what that is. Otherwise,
2835 we resort to a generic way, such as inlining. In either case, the
2836 result is returned through INFO. */
2838 static void
2839 get_shift_alg (shift_type, shift_mode, count, info)
2840 enum shift_type shift_type;
2841 enum shift_mode shift_mode;
2842 unsigned int count;
2843 struct shift_info *info;
2845 enum h8_cpu cpu;
2847 /* Find the target CPU. */
2848 if (TARGET_H8300)
2849 cpu = H8_300;
2850 else if (TARGET_H8300H)
2851 cpu = H8_300H;
2852 else
2853 cpu = H8_S;
2855 /* Find the shift algorithm. */
2856 info->alg = SHIFT_LOOP;
2857 switch (shift_mode)
2859 case QIshift:
2860 if (count < GET_MODE_BITSIZE (QImode))
2861 info->alg = shift_alg_qi[cpu][shift_type][count];
2862 break;
2864 case HIshift:
2865 if (count < GET_MODE_BITSIZE (HImode))
2866 info->alg = shift_alg_hi[cpu][shift_type][count];
2867 break;
2869 case SIshift:
2870 if (count < GET_MODE_BITSIZE (SImode))
2871 info->alg = shift_alg_si[cpu][shift_type][count];
2872 break;
2874 default:
2875 abort ();
2878 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
2879 switch (info->alg)
2881 case SHIFT_INLINE:
2882 info->remainder = count;
2883 /* Fall through. */
2885 case SHIFT_LOOP:
2886 /* It is up to the caller to know that looping clobbers cc. */
2887 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2888 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2889 info->cc_inline = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
2890 goto end;
2892 case SHIFT_ROT_AND:
2893 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
2894 info->shift2 = rotate_two[shift_type][shift_mode];
2895 info->cc_inline = CC_CLOBBER;
2896 goto end;
2898 case SHIFT_SPECIAL:
2899 /* REMAINDER is 0 for most cases, so initialize it to 0. */
2900 info->remainder = 0;
2901 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2902 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2903 info->cc_inline = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
2904 info->cc_special = CC_CLOBBER;
2905 break;
2908 /* Here we only deal with SHIFT_SPECIAL. */
2909 switch (shift_mode)
2911 case QIshift:
2912 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2913 through the entire value. */
2914 if (shift_type == SHIFT_ASHIFTRT && count == 7)
2916 info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
2917 goto end;
2919 abort ();
2921 case HIshift:
2922 if (count == 7)
2924 switch (shift_type)
2926 case SHIFT_ASHIFT:
2927 if (TARGET_H8300)
2928 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";
2929 else
2930 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
2931 goto end;
2932 case SHIFT_LSHIFTRT:
2933 if (TARGET_H8300)
2934 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";
2935 else
2936 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
2937 goto end;
2938 case SHIFT_ASHIFTRT:
2939 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
2940 goto end;
2943 else if ((8 <= count && count <= 13)
2944 || (TARGET_H8300S && count == 14))
2946 info->remainder = count - 8;
2948 switch (shift_type)
2950 case SHIFT_ASHIFT:
2951 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
2952 goto end;
2953 case SHIFT_LSHIFTRT:
2954 if (TARGET_H8300)
2956 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
2957 info->shift1 = "shlr.b\t%s0";
2958 info->cc_inline = CC_SET_ZNV;
2960 else
2962 info->special = "mov.b\t%t0,%s0\n\textu.w\t%T0";
2963 info->cc_special = CC_SET_ZNV;
2965 goto end;
2966 case SHIFT_ASHIFTRT:
2967 if (TARGET_H8300)
2969 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
2970 info->shift1 = "shar.b\t%s0";
2972 else
2974 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
2975 info->cc_special = CC_SET_ZNV;
2977 goto end;
2980 else if (count == 14)
2982 switch (shift_type)
2984 case SHIFT_ASHIFT:
2985 if (TARGET_H8300)
2986 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";
2987 goto end;
2988 case SHIFT_LSHIFTRT:
2989 if (TARGET_H8300)
2990 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";
2991 goto end;
2992 case SHIFT_ASHIFTRT:
2993 if (TARGET_H8300)
2994 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";
2995 else if (TARGET_H8300H)
2997 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";
2998 info->cc_special = CC_SET_ZNV;
3000 else /* TARGET_H8300S */
3001 abort ();
3002 goto end;
3005 else if (count == 15)
3007 switch (shift_type)
3009 case SHIFT_ASHIFT:
3010 info->special = "bld\t#0,%s0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#7,%t0";
3011 goto end;
3012 case SHIFT_LSHIFTRT:
3013 info->special = "bld\t#7,%t0\n\txor\t%s0,%s0\n\txor\t%t0,%t0\n\tbst\t#0,%s0";
3014 goto end;
3015 case SHIFT_ASHIFTRT:
3016 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
3017 goto end;
3020 abort ();
3022 case SIshift:
3023 if (TARGET_H8300 && 8 <= count && count <= 9)
3025 info->remainder = count - 8;
3027 switch (shift_type)
3029 case SHIFT_ASHIFT:
3030 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";
3031 goto end;
3032 case SHIFT_LSHIFTRT:
3033 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";
3034 info->shift1 = "shlr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0";
3035 goto end;
3036 case SHIFT_ASHIFTRT:
3037 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";
3038 goto end;
3041 else if (count == 8 && !TARGET_H8300)
3043 switch (shift_type)
3045 case SHIFT_ASHIFT:
3046 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";
3047 goto end;
3048 case SHIFT_LSHIFTRT:
3049 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";
3050 goto end;
3051 case SHIFT_ASHIFTRT:
3052 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";
3053 goto end;
3056 else if (count == 15 && TARGET_H8300)
3058 switch (shift_type)
3060 case SHIFT_ASHIFT:
3061 abort ();
3062 case SHIFT_LSHIFTRT:
3063 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\n\trotxl\t%x0\n\trotxl\t%y0";
3064 goto end;
3065 case SHIFT_ASHIFTRT:
3066 info->special = "bld\t#7,%z0\n\tmov.w\t%e0,%f0\n\trotxl\t%w0\n\trotxl\t%x0\n\tsubx\t%y0,%y0\n\tsubx\t%z0,%z0";
3067 goto end;
3070 else if (count == 15 && !TARGET_H8300)
3072 switch (shift_type)
3074 case SHIFT_ASHIFT:
3075 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
3076 info->cc_special = CC_SET_ZNV;
3077 goto end;
3078 case SHIFT_LSHIFTRT:
3079 info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
3080 info->cc_special = CC_SET_ZNV;
3081 goto end;
3082 case SHIFT_ASHIFTRT:
3083 abort ();
3086 else if ((TARGET_H8300 && 16 <= count && count <= 20)
3087 || (TARGET_H8300H && 16 <= count && count <= 19)
3088 || (TARGET_H8300S && 16 <= count && count <= 21))
3090 info->remainder = count - 16;
3092 switch (shift_type)
3094 case SHIFT_ASHIFT:
3095 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
3096 if (TARGET_H8300)
3097 info->shift1 = "add.w\t%e0,%e0";
3098 goto end;
3099 case SHIFT_LSHIFTRT:
3100 if (TARGET_H8300)
3102 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
3103 info->shift1 = "shlr\t%x0\n\trotxr\t%w0";
3105 else
3107 info->special = "mov.w\t%e0,%f0\n\textu.l\t%S0";
3108 info->cc_special = CC_SET_ZNV;
3110 goto end;
3111 case SHIFT_ASHIFTRT:
3112 if (TARGET_H8300)
3114 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
3115 info->shift1 = "shar\t%x0\n\trotxr\t%w0";
3117 else
3119 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
3120 info->cc_special = CC_SET_ZNV;
3122 goto end;
3125 else if (TARGET_H8300 && 24 <= count && count <= 28)
3127 info->remainder = count - 24;
3129 switch (shift_type)
3131 case SHIFT_ASHIFT:
3132 info->special = "mov.b\t%w0,%z0\n\tsub.b\t%y0,%y0\n\tsub.w\t%f0,%f0";
3133 info->shift1 = "shll.b\t%z0";
3134 info->cc_inline = CC_SET_ZNV;
3135 goto end;
3136 case SHIFT_LSHIFTRT:
3137 info->special = "mov.b\t%z0,%w0\n\tsub.b\t%x0,%x0\n\tsub.w\t%e0,%e0";
3138 info->shift1 = "shlr.b\t%w0";
3139 info->cc_inline = CC_SET_ZNV;
3140 goto end;
3141 case SHIFT_ASHIFTRT:
3142 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";
3143 info->shift1 = "shar.b\t%w0";
3144 info->cc_inline = CC_SET_ZNV;
3145 goto end;
3148 else if ((TARGET_H8300H && count == 24)
3149 || (TARGET_H8300S && 24 <= count && count <= 25))
3151 info->remainder = count - 24;
3153 switch (shift_type)
3155 case SHIFT_ASHIFT:
3156 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";
3157 goto end;
3158 case SHIFT_LSHIFTRT:
3159 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
3160 info->cc_special = CC_SET_ZNV;
3161 goto end;
3162 case SHIFT_ASHIFTRT:
3163 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
3164 info->cc_special = CC_SET_ZNV;
3165 goto end;
3168 else if (!TARGET_H8300 && count == 28)
3170 switch (shift_type)
3172 case SHIFT_ASHIFT:
3173 if (TARGET_H8300H)
3174 info->special = "sub.w\t%e0,%e0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0";
3175 else
3176 info->special = "sub.w\t%e0,%e0\n\trotr.l\t#2,%S0\n\trotr.l\t#2,%S0\n\tsub.w\t%f0,%f0";
3177 goto end;
3178 case SHIFT_LSHIFTRT:
3179 if (TARGET_H8300H)
3181 info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0";
3182 info->cc_special = CC_SET_ZNV;
3184 else
3185 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t#2,%S0\n\textu.l\t%S0";
3186 goto end;
3187 case SHIFT_ASHIFTRT:
3188 abort ();
3191 else if (!TARGET_H8300 && count == 29)
3193 switch (shift_type)
3195 case SHIFT_ASHIFT:
3196 if (TARGET_H8300H)
3197 info->special = "sub.w\t%e0,%e0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0";
3198 else
3199 info->special = "sub.w\t%e0,%e0\n\trotr.l\t#2,%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0";
3200 goto end;
3201 case SHIFT_LSHIFTRT:
3202 if (TARGET_H8300H)
3204 info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0";
3205 info->cc_special = CC_SET_ZNV;
3207 else
3209 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t%S0\n\textu.l\t%S0";
3210 info->cc_special = CC_SET_ZNV;
3212 goto end;
3213 case SHIFT_ASHIFTRT:
3214 abort ();
3217 else if (!TARGET_H8300 && count == 30)
3219 switch (shift_type)
3221 case SHIFT_ASHIFT:
3222 if (TARGET_H8300H)
3223 info->special = "sub.w\t%e0,%e0\n\trotr.l\t%S0\n\trotr.l\t%S0\n\tsub.w\t%f0,%f0";
3224 else
3225 info->special = "sub.w\t%e0,%e0\n\trotr.l\t#2,%S0\n\tsub.w\t%f0,%f0";
3226 goto end;
3227 case SHIFT_LSHIFTRT:
3228 if (TARGET_H8300H)
3229 info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0";
3230 else
3231 info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\textu.l\t%S0";
3232 goto end;
3233 case SHIFT_ASHIFTRT:
3234 abort ();
3237 else if (count == 31)
3239 if (TARGET_H8300)
3241 switch (shift_type)
3243 case SHIFT_ASHIFT:
3244 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
3245 goto end;
3246 case SHIFT_LSHIFTRT:
3247 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
3248 goto end;
3249 case SHIFT_ASHIFTRT:
3250 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
3251 goto end;
3254 else
3256 switch (shift_type)
3258 case SHIFT_ASHIFT:
3259 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
3260 info->cc_special = CC_SET_ZNV;
3261 goto end;
3262 case SHIFT_LSHIFTRT:
3263 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
3264 info->cc_special = CC_SET_ZNV;
3265 goto end;
3266 case SHIFT_ASHIFTRT:
3267 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\texts.w\t%T0\n\texts.l\t%S0";
3268 info->cc_special = CC_SET_ZNV;
3269 goto end;
3273 abort ();
3275 default:
3276 abort ();
3279 end:
3280 if (!TARGET_H8300S)
3281 info->shift2 = NULL;
3284 /* Given COUNT and MODE of a shift, return 1 if a scratch reg may be
3285 needed for some shift with COUNT and MODE. Return 0 otherwise. */
3288 h8300_shift_needs_scratch_p (count, mode)
3289 int count;
3290 enum machine_mode mode;
3292 enum h8_cpu cpu;
3293 int a, lr, ar;
3295 if (GET_MODE_BITSIZE (mode) <= count)
3296 return 1;
3298 /* Find out the target CPU. */
3299 if (TARGET_H8300)
3300 cpu = H8_300;
3301 else if (TARGET_H8300H)
3302 cpu = H8_300H;
3303 else
3304 cpu = H8_S;
3306 /* Find the shift algorithm. */
3307 switch (mode)
3309 case QImode:
3310 a = shift_alg_qi[cpu][SHIFT_ASHIFT][count];
3311 lr = shift_alg_qi[cpu][SHIFT_LSHIFTRT][count];
3312 ar = shift_alg_qi[cpu][SHIFT_ASHIFTRT][count];
3313 break;
3315 case HImode:
3316 a = shift_alg_hi[cpu][SHIFT_ASHIFT][count];
3317 lr = shift_alg_hi[cpu][SHIFT_LSHIFTRT][count];
3318 ar = shift_alg_hi[cpu][SHIFT_ASHIFTRT][count];
3319 break;
3321 case SImode:
3322 a = shift_alg_si[cpu][SHIFT_ASHIFT][count];
3323 lr = shift_alg_si[cpu][SHIFT_LSHIFTRT][count];
3324 ar = shift_alg_si[cpu][SHIFT_ASHIFTRT][count];
3325 break;
3327 default:
3328 abort ();
3331 /* On H8/300H, count == 8 uses a scratch register. */
3332 return (a == SHIFT_LOOP || lr == SHIFT_LOOP || ar == SHIFT_LOOP
3333 || (TARGET_H8300H && mode == SImode && count == 8));
3336 /* Emit the assembler code for doing shifts. */
3338 const char *
3339 output_a_shift (operands)
3340 rtx *operands;
3342 static int loopend_lab;
3343 rtx shift = operands[3];
3344 enum machine_mode mode = GET_MODE (shift);
3345 enum rtx_code code = GET_CODE (shift);
3346 enum shift_type shift_type;
3347 enum shift_mode shift_mode;
3348 struct shift_info info;
3350 loopend_lab++;
3352 switch (mode)
3354 case QImode:
3355 shift_mode = QIshift;
3356 break;
3357 case HImode:
3358 shift_mode = HIshift;
3359 break;
3360 case SImode:
3361 shift_mode = SIshift;
3362 break;
3363 default:
3364 abort ();
3367 switch (code)
3369 case ASHIFTRT:
3370 shift_type = SHIFT_ASHIFTRT;
3371 break;
3372 case LSHIFTRT:
3373 shift_type = SHIFT_LSHIFTRT;
3374 break;
3375 case ASHIFT:
3376 shift_type = SHIFT_ASHIFT;
3377 break;
3378 default:
3379 abort ();
3382 if (GET_CODE (operands[2]) != CONST_INT)
3384 /* This case must be taken care of by one of the two splitters
3385 that convert a variable shift into a loop. */
3386 abort ();
3388 else
3390 int n = INTVAL (operands[2]);
3392 /* If the count is negative, make it 0. */
3393 if (n < 0)
3394 n = 0;
3395 /* If the count is too big, truncate it.
3396 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
3397 do the intuitive thing. */
3398 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
3399 n = GET_MODE_BITSIZE (mode);
3401 get_shift_alg (shift_type, shift_mode, n, &info);
3403 switch (info.alg)
3405 case SHIFT_SPECIAL:
3406 output_asm_insn (info.special, operands);
3407 /* Fall through. */
3409 case SHIFT_INLINE:
3410 n = info.remainder;
3412 /* Emit two bit shifts first. */
3413 if (info.shift2 != NULL)
3415 for (; n > 1; n -= 2)
3416 output_asm_insn (info.shift2, operands);
3419 /* Now emit one bit shifts for any residual. */
3420 for (; n > 0; n--)
3421 output_asm_insn (info.shift1, operands);
3422 return "";
3424 case SHIFT_ROT_AND:
3426 int m = GET_MODE_BITSIZE (mode) - n;
3427 const int mask = (shift_type == SHIFT_ASHIFT
3428 ? ((1 << m) - 1) << n
3429 : (1 << m) - 1);
3430 char insn_buf[200];
3432 /* Not all possibilities of rotate are supported. They shouldn't
3433 be generated, but let's watch for 'em. */
3434 if (info.shift1 == 0)
3435 abort ();
3437 /* Emit two bit rotates first. */
3438 if (info.shift2 != NULL)
3440 for (; m > 1; m -= 2)
3441 output_asm_insn (info.shift2, operands);
3444 /* Now single bit rotates for any residual. */
3445 for (; m > 0; m--)
3446 output_asm_insn (info.shift1, operands);
3448 /* Now mask off the high bits. */
3449 if (mode == QImode)
3450 sprintf (insn_buf, "and\t#%d,%%X0", mask);
3451 else if (mode == HImode && (TARGET_H8300H || TARGET_H8300S))
3452 sprintf (insn_buf, "and.w\t#%d,%%T0", mask);
3453 else
3454 abort ();
3456 output_asm_insn (insn_buf, operands);
3457 return "";
3460 case SHIFT_LOOP:
3461 /* A loop to shift by a "large" constant value.
3462 If we have shift-by-2 insns, use them. */
3463 if (info.shift2 != NULL)
3465 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
3466 names_big[REGNO (operands[4])]);
3467 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
3468 output_asm_insn (info.shift2, operands);
3469 output_asm_insn ("add #0xff,%X4", operands);
3470 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
3471 if (n % 2)
3472 output_asm_insn (info.shift1, operands);
3474 else
3476 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
3477 names_big[REGNO (operands[4])]);
3478 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
3479 output_asm_insn (info.shift1, operands);
3480 output_asm_insn ("add #0xff,%X4", operands);
3481 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
3483 return "";
3485 default:
3486 abort ();
3491 static unsigned int
3492 h8300_asm_insn_count (template)
3493 const char *template;
3495 unsigned int count = 1;
3497 for (; *template; template++)
3498 if (*template == '\n')
3499 count++;
3501 return count;
3504 unsigned int
3505 compute_a_shift_length (insn, operands)
3506 rtx insn ATTRIBUTE_UNUSED;
3507 rtx *operands;
3509 rtx shift = operands[3];
3510 enum machine_mode mode = GET_MODE (shift);
3511 enum rtx_code code = GET_CODE (shift);
3512 enum shift_type shift_type;
3513 enum shift_mode shift_mode;
3514 struct shift_info info;
3515 unsigned int wlength = 0;
3517 switch (mode)
3519 case QImode:
3520 shift_mode = QIshift;
3521 break;
3522 case HImode:
3523 shift_mode = HIshift;
3524 break;
3525 case SImode:
3526 shift_mode = SIshift;
3527 break;
3528 default:
3529 abort ();
3532 switch (code)
3534 case ASHIFTRT:
3535 shift_type = SHIFT_ASHIFTRT;
3536 break;
3537 case LSHIFTRT:
3538 shift_type = SHIFT_LSHIFTRT;
3539 break;
3540 case ASHIFT:
3541 shift_type = SHIFT_ASHIFT;
3542 break;
3543 default:
3544 abort ();
3547 if (GET_CODE (operands[2]) != CONST_INT)
3549 /* Get the assembler code to do one shift. */
3550 get_shift_alg (shift_type, shift_mode, 1, &info);
3552 return (4 + h8300_asm_insn_count (info.shift1)) * 2;
3554 else
3556 int n = INTVAL (operands[2]);
3558 /* If the count is negative, make it 0. */
3559 if (n < 0)
3560 n = 0;
3561 /* If the count is too big, truncate it.
3562 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
3563 do the intuitive thing. */
3564 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
3565 n = GET_MODE_BITSIZE (mode);
3567 get_shift_alg (shift_type, shift_mode, n, &info);
3569 switch (info.alg)
3571 case SHIFT_SPECIAL:
3572 wlength += h8300_asm_insn_count (info.special);
3574 /* Every assembly instruction used in SHIFT_SPECIAL case
3575 takes 2 bytes except xor.l, which takes 4 bytes, so if we
3576 see xor.l, we just pretend that xor.l counts as two insns
3577 so that the insn length will be computed correctly. */
3578 if (strstr (info.special, "xor.l") != NULL)
3579 wlength++;
3581 /* Fall through. */
3583 case SHIFT_INLINE:
3584 n = info.remainder;
3586 if (info.shift2 != NULL)
3588 wlength += h8300_asm_insn_count (info.shift2) * (n / 2);
3589 n = n % 2;
3592 wlength += h8300_asm_insn_count (info.shift1) * n;
3594 return 2 * wlength;
3596 case SHIFT_ROT_AND:
3598 int m = GET_MODE_BITSIZE (mode) - n;
3600 /* Not all possibilities of rotate are supported. They shouldn't
3601 be generated, but let's watch for 'em. */
3602 if (info.shift1 == 0)
3603 abort ();
3605 if (info.shift2 != NULL)
3607 wlength += h8300_asm_insn_count (info.shift2) * (m / 2);
3608 m = m % 2;
3611 wlength += h8300_asm_insn_count (info.shift1) * m;
3613 /* Now mask off the high bits. */
3614 switch (mode)
3616 case QImode:
3617 wlength += 1;
3618 break;
3619 case HImode:
3620 wlength += 2;
3621 break;
3622 case SImode:
3623 if (TARGET_H8300)
3624 abort ();
3625 wlength += 3;
3626 break;
3627 default:
3628 abort ();
3630 return 2 * wlength;
3633 case SHIFT_LOOP:
3634 /* A loop to shift by a "large" constant value.
3635 If we have shift-by-2 insns, use them. */
3636 if (info.shift2 != NULL)
3638 wlength += 3 + h8300_asm_insn_count (info.shift2);
3639 if (n % 2)
3640 wlength += h8300_asm_insn_count (info.shift1);
3642 else
3644 wlength += 3 + h8300_asm_insn_count (info.shift1);
3646 return 2 * wlength;
3648 default:
3649 abort ();
3655 compute_a_shift_cc (insn, operands)
3656 rtx insn ATTRIBUTE_UNUSED;
3657 rtx *operands;
3659 rtx shift = operands[3];
3660 enum machine_mode mode = GET_MODE (shift);
3661 enum rtx_code code = GET_CODE (shift);
3662 enum shift_type shift_type;
3663 enum shift_mode shift_mode;
3664 struct shift_info info;
3666 switch (mode)
3668 case QImode:
3669 shift_mode = QIshift;
3670 break;
3671 case HImode:
3672 shift_mode = HIshift;
3673 break;
3674 case SImode:
3675 shift_mode = SIshift;
3676 break;
3677 default:
3678 abort ();
3681 switch (code)
3683 case ASHIFTRT:
3684 shift_type = SHIFT_ASHIFTRT;
3685 break;
3686 case LSHIFTRT:
3687 shift_type = SHIFT_LSHIFTRT;
3688 break;
3689 case ASHIFT:
3690 shift_type = SHIFT_ASHIFT;
3691 break;
3692 default:
3693 abort ();
3696 if (GET_CODE (operands[2]) != CONST_INT)
3698 /* This case must be taken care of by one of the two splitters
3699 that convert a variable shift into a loop. */
3700 abort ();
3702 else
3704 int n = INTVAL (operands[2]);
3706 /* If the count is negative, make it 0. */
3707 if (n < 0)
3708 n = 0;
3709 /* If the count is too big, truncate it.
3710 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
3711 do the intuitive thing. */
3712 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
3713 n = GET_MODE_BITSIZE (mode);
3715 get_shift_alg (shift_type, shift_mode, n, &info);
3717 switch (info.alg)
3719 case SHIFT_SPECIAL:
3720 if (info.remainder == 0)
3721 return info.cc_special;
3723 /* Fall through. */
3725 case SHIFT_INLINE:
3726 return info.cc_inline;
3728 case SHIFT_ROT_AND:
3729 /* This case always ends with an and instruction. */
3730 return CC_SET_ZNV;
3732 case SHIFT_LOOP:
3733 /* A loop to shift by a "large" constant value.
3734 If we have shift-by-2 insns, use them. */
3735 if (info.shift2 != NULL)
3737 if (n % 2)
3738 return info.cc_inline;
3740 return CC_CLOBBER;
3742 default:
3743 abort ();
3748 /* A rotation by a non-constant will cause a loop to be generated, in
3749 which a rotation by one bit is used. A rotation by a constant,
3750 including the one in the loop, will be taken care of by
3751 emit_a_rotate () at the insn emit time. */
3754 expand_a_rotate (code, operands)
3755 enum rtx_code code;
3756 rtx operands[];
3758 rtx dst = operands[0];
3759 rtx src = operands[1];
3760 rtx rotate_amount = operands[2];
3761 enum machine_mode mode = GET_MODE (dst);
3762 rtx tmp;
3764 /* We rotate in place. */
3765 emit_move_insn (dst, src);
3767 if (GET_CODE (rotate_amount) != CONST_INT)
3769 rtx counter = gen_reg_rtx (QImode);
3770 rtx start_label = gen_label_rtx ();
3771 rtx end_label = gen_label_rtx ();
3773 /* If the rotate amount is less than or equal to 0,
3774 we go out of the loop. */
3775 emit_cmp_and_jump_insns (rotate_amount, GEN_INT (0), LE, NULL_RTX,
3776 QImode, 0, end_label);
3778 /* Initialize the loop counter. */
3779 emit_move_insn (counter, rotate_amount);
3781 emit_label (start_label);
3783 /* Rotate by one bit. */
3784 tmp = gen_rtx (code, mode, dst, GEN_INT (1));
3785 emit_insn (gen_rtx_SET (mode, dst, tmp));
3787 /* Decrement the counter by 1. */
3788 tmp = gen_rtx_PLUS (QImode, counter, GEN_INT (-1));
3789 emit_insn (gen_rtx_SET (VOIDmode, counter, tmp));
3791 /* If the loop counter is nonzero, we go back to the beginning
3792 of the loop. */
3793 emit_cmp_and_jump_insns (counter, GEN_INT (0), NE, NULL_RTX, QImode, 1,
3794 start_label);
3796 emit_label (end_label);
3798 else
3800 /* Rotate by AMOUNT bits. */
3801 tmp = gen_rtx (code, mode, dst, rotate_amount);
3802 emit_insn (gen_rtx_SET (mode, dst, tmp));
3805 return 1;
3808 /* Emit rotate insns. */
3810 const char *
3811 emit_a_rotate (code, operands)
3812 enum rtx_code code;
3813 rtx *operands;
3815 rtx dst = operands[0];
3816 rtx rotate_amount = operands[2];
3817 enum shift_mode rotate_mode;
3818 enum shift_type rotate_type;
3819 const char *insn_buf;
3820 int bits;
3821 int amount;
3822 enum machine_mode mode = GET_MODE (dst);
3824 if (GET_CODE (rotate_amount) != CONST_INT)
3825 abort ();
3827 switch (mode)
3829 case QImode:
3830 rotate_mode = QIshift;
3831 break;
3832 case HImode:
3833 rotate_mode = HIshift;
3834 break;
3835 case SImode:
3836 rotate_mode = SIshift;
3837 break;
3838 default:
3839 abort ();
3842 switch (code)
3844 case ROTATERT:
3845 rotate_type = SHIFT_ASHIFT;
3846 break;
3847 case ROTATE:
3848 rotate_type = SHIFT_LSHIFTRT;
3849 break;
3850 default:
3851 abort ();
3854 amount = INTVAL (rotate_amount);
3856 /* Clean up AMOUNT. */
3857 if (amount < 0)
3858 amount = 0;
3859 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3860 amount = GET_MODE_BITSIZE (mode);
3862 /* Determine the faster direction. After this phase, amount will be
3863 at most a half of GET_MODE_BITSIZE (mode). */
3864 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
3866 /* Flip the direction. */
3867 amount = GET_MODE_BITSIZE (mode) - amount;
3868 rotate_type =
3869 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
3872 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3873 boost up the rotation. */
3874 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3875 || (mode == HImode && TARGET_H8300H && amount >= 6)
3876 || (mode == HImode && TARGET_H8300S && amount == 8)
3877 || (mode == SImode && TARGET_H8300H && amount >= 10)
3878 || (mode == SImode && TARGET_H8300S && amount >= 13))
3880 switch (mode)
3882 case HImode:
3883 /* This code works on any family. */
3884 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
3885 output_asm_insn (insn_buf, operands);
3886 break;
3888 case SImode:
3889 /* This code works on the H8/300H and H8S. */
3890 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
3891 output_asm_insn (insn_buf, operands);
3892 break;
3894 default:
3895 abort ();
3898 /* Adjust AMOUNT and flip the direction. */
3899 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3900 rotate_type =
3901 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
3904 /* Emit rotate insns. */
3905 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2)
3907 if (bits == 2)
3908 insn_buf = rotate_two[rotate_type][rotate_mode];
3909 else
3910 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode];
3912 for (; amount >= bits; amount -= bits)
3913 output_asm_insn (insn_buf, operands);
3916 return "";
3919 /* Fix the operands of a gen_xxx so that it could become a bit
3920 operating insn. */
3923 fix_bit_operand (operands, what, type)
3924 rtx *operands;
3925 int what;
3926 enum rtx_code type;
3928 /* The bit_operand predicate accepts any memory during RTL generation, but
3929 only 'U' memory afterwards, so if this is a MEM operand, we must force
3930 it to be valid for 'U' by reloading the address. */
3932 if ((what == 0 && single_zero_operand (operands[2], QImode))
3933 || (what == 1 && single_one_operand (operands[2], QImode)))
3935 /* OK to have a memory dest. */
3936 if (GET_CODE (operands[0]) == MEM
3937 && !EXTRA_CONSTRAINT (operands[0], 'U'))
3939 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
3940 copy_to_mode_reg (Pmode,
3941 XEXP (operands[0], 0)));
3942 MEM_COPY_ATTRIBUTES (mem, operands[0]);
3943 operands[0] = mem;
3946 if (GET_CODE (operands[1]) == MEM
3947 && !EXTRA_CONSTRAINT (operands[1], 'U'))
3949 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
3950 copy_to_mode_reg (Pmode,
3951 XEXP (operands[1], 0)));
3952 MEM_COPY_ATTRIBUTES (mem, operands[0]);
3953 operands[1] = mem;
3955 return 0;
3958 /* Dest and src op must be register. */
3960 operands[1] = force_reg (QImode, operands[1]);
3962 rtx res = gen_reg_rtx (QImode);
3963 emit_insn (gen_rtx_SET (VOIDmode, res,
3964 gen_rtx (type, QImode, operands[1], operands[2])));
3965 emit_insn (gen_rtx_SET (VOIDmode, operands[0], res));
3967 return 1;
3970 /* Return nonzero if FUNC is an interrupt function as specified
3971 by the "interrupt" attribute. */
3973 static int
3974 h8300_interrupt_function_p (func)
3975 tree func;
3977 tree a;
3979 if (TREE_CODE (func) != FUNCTION_DECL)
3980 return 0;
3982 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
3983 return a != NULL_TREE;
3986 /* Return nonzero if FUNC is an OS_Task function as specified
3987 by the "OS_Task" attribute. */
3989 static int
3990 h8300_os_task_function_p (func)
3991 tree func;
3993 tree a;
3995 if (TREE_CODE (func) != FUNCTION_DECL)
3996 return 0;
3998 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func));
3999 return a != NULL_TREE;
4002 /* Return nonzero if FUNC is a monitor function as specified
4003 by the "monitor" attribute. */
4005 static int
4006 h8300_monitor_function_p (func)
4007 tree func;
4009 tree a;
4011 if (TREE_CODE (func) != FUNCTION_DECL)
4012 return 0;
4014 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func));
4015 return a != NULL_TREE;
4018 /* Return nonzero if FUNC is a function that should be called
4019 through the function vector. */
4022 h8300_funcvec_function_p (func)
4023 tree func;
4025 tree a;
4027 if (TREE_CODE (func) != FUNCTION_DECL)
4028 return 0;
4030 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func));
4031 return a != NULL_TREE;
4034 /* Return nonzero if DECL is a variable that's in the eight bit
4035 data area. */
4038 h8300_eightbit_data_p (decl)
4039 tree decl;
4041 tree a;
4043 if (TREE_CODE (decl) != VAR_DECL)
4044 return 0;
4046 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl));
4047 return a != NULL_TREE;
4050 /* Return nonzero if DECL is a variable that's in the tiny
4051 data area. */
4054 h8300_tiny_data_p (decl)
4055 tree decl;
4057 tree a;
4059 if (TREE_CODE (decl) != VAR_DECL)
4060 return 0;
4062 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl));
4063 return a != NULL_TREE;
4066 /* Generate an 'interrupt_handler' attribute for decls. */
4068 static void
4069 h8300_insert_attributes (node, attributes)
4070 tree node;
4071 tree *attributes;
4073 if (!pragma_interrupt
4074 || TREE_CODE (node) != FUNCTION_DECL)
4075 return;
4077 pragma_interrupt = 0;
4079 /* Add an 'interrupt_handler' attribute. */
4080 *attributes = tree_cons (get_identifier ("interrupt_handler"),
4081 NULL, *attributes);
4084 /* Supported attributes:
4086 interrupt_handler: output a prologue and epilogue suitable for an
4087 interrupt handler.
4089 function_vector: This function should be called through the
4090 function vector.
4092 eightbit_data: This variable lives in the 8-bit data area and can
4093 be referenced with 8-bit absolute memory addresses.
4095 tiny_data: This variable lives in the tiny data area and can be
4096 referenced with 16-bit absolute memory references. */
4098 const struct attribute_spec h8300_attribute_table[] =
4100 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4101 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
4102 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
4103 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
4104 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
4105 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute },
4106 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute },
4107 { NULL, 0, 0, false, false, false, NULL }
4111 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4112 struct attribute_spec.handler. */
4113 static tree
4114 h8300_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
4115 tree *node;
4116 tree name;
4117 tree args ATTRIBUTE_UNUSED;
4118 int flags ATTRIBUTE_UNUSED;
4119 bool *no_add_attrs;
4121 if (TREE_CODE (*node) != FUNCTION_DECL)
4123 warning ("`%s' attribute only applies to functions",
4124 IDENTIFIER_POINTER (name));
4125 *no_add_attrs = true;
4128 return NULL_TREE;
4131 /* Handle an "eightbit_data" attribute; arguments as in
4132 struct attribute_spec.handler. */
4133 static tree
4134 h8300_handle_eightbit_data_attribute (node, name, args, flags, no_add_attrs)
4135 tree *node;
4136 tree name;
4137 tree args ATTRIBUTE_UNUSED;
4138 int flags ATTRIBUTE_UNUSED;
4139 bool *no_add_attrs;
4141 tree decl = *node;
4143 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
4145 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
4147 else
4149 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4150 *no_add_attrs = true;
4153 return NULL_TREE;
4156 /* Handle an "tiny_data" attribute; arguments as in
4157 struct attribute_spec.handler. */
4158 static tree
4159 h8300_handle_tiny_data_attribute (node, name, args, flags, no_add_attrs)
4160 tree *node;
4161 tree name;
4162 tree args ATTRIBUTE_UNUSED;
4163 int flags ATTRIBUTE_UNUSED;
4164 bool *no_add_attrs;
4166 tree decl = *node;
4168 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
4170 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
4172 else
4174 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4175 *no_add_attrs = true;
4178 return NULL_TREE;
4181 /* Mark function vectors, and various small data objects. */
4183 static void
4184 h8300_encode_section_info (decl, rtl, first)
4185 tree decl;
4186 rtx rtl;
4187 int first;
4189 int extra_flags = 0;
4191 default_encode_section_info (decl, rtl, first);
4193 if (TREE_CODE (decl) == FUNCTION_DECL
4194 && h8300_funcvec_function_p (decl))
4195 extra_flags = SYMBOL_FLAG_FUNCVEC_FUNCTION;
4196 else if (TREE_CODE (decl) == VAR_DECL
4197 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
4199 if (h8300_eightbit_data_p (decl))
4200 extra_flags = SYMBOL_FLAG_EIGHTBIT_DATA;
4201 else if (first && h8300_tiny_data_p (decl))
4202 extra_flags = SYMBOL_FLAG_TINY_DATA;
4205 if (extra_flags)
4206 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= extra_flags;
4209 const char *
4210 output_simode_bld (bild, operands)
4211 int bild;
4212 rtx operands[];
4214 if (TARGET_H8300)
4216 /* Clear the destination register. */
4217 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
4219 /* Now output the bit load or bit inverse load, and store it in
4220 the destination. */
4221 if (bild)
4222 output_asm_insn ("bild\t%Z2,%Y1", operands);
4223 else
4224 output_asm_insn ("bld\t%Z2,%Y1", operands);
4226 output_asm_insn ("bst\t#0,%w0", operands);
4228 else
4230 /* Determine if we can clear the destination first. */
4231 int clear_first = (REG_P (operands[0]) && REG_P (operands[1])
4232 && REGNO (operands[0]) != REGNO (operands[1]));
4234 if (clear_first)
4235 output_asm_insn ("sub.l\t%S0,%S0", operands);
4237 /* Output the bit load or bit inverse load. */
4238 if (bild)
4239 output_asm_insn ("bild\t%Z2,%Y1", operands);
4240 else
4241 output_asm_insn ("bld\t%Z2,%Y1", operands);
4243 if (!clear_first)
4244 output_asm_insn ("xor.l\t%S0,%S0", operands);
4246 /* Perform the bit store. */
4247 output_asm_insn ("bst\t#0,%w0", operands);
4250 /* All done. */
4251 return "";
4254 /* Given INSN and its current length LENGTH, return the adjustment
4255 (in bytes) to correctly compute INSN's length.
4257 We use this to get the lengths of various memory references correct. */
4260 h8300_adjust_insn_length (insn, length)
4261 rtx insn;
4262 int length ATTRIBUTE_UNUSED;
4264 rtx pat = PATTERN (insn);
4266 /* We must filter these out before calling get_attr_adjust_length. */
4267 if (GET_CODE (pat) == USE
4268 || GET_CODE (pat) == CLOBBER
4269 || GET_CODE (pat) == SEQUENCE
4270 || GET_CODE (pat) == ADDR_VEC
4271 || GET_CODE (pat) == ADDR_DIFF_VEC)
4272 return 0;
4274 if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO)
4275 return 0;
4277 /* Adjust length for reg->mem and mem->reg copies. */
4278 if (GET_CODE (pat) == SET
4279 && (GET_CODE (SET_SRC (pat)) == MEM
4280 || GET_CODE (SET_DEST (pat)) == MEM))
4282 /* This insn might need a length adjustment. */
4283 rtx addr;
4285 if (GET_CODE (SET_SRC (pat)) == MEM)
4286 addr = XEXP (SET_SRC (pat), 0);
4287 else
4288 addr = XEXP (SET_DEST (pat), 0);
4290 if (TARGET_H8300)
4292 /* On the H8/300, we subtract the difference between the
4293 actual length and the longest one, which is @(d:16,ERs). */
4295 /* @Rs is 2 bytes shorter than the longest. */
4296 if (GET_CODE (addr) == REG)
4297 return -2;
4299 /* @aa:8 is 2 bytes shorter than the longest. */
4300 if (GET_MODE (SET_SRC (pat)) == QImode
4301 && h8300_eightbit_constant_address_p (addr))
4302 return -2;
4304 else
4306 /* On the H8/300H and H8S, we subtract the difference
4307 between the actual length and the longest one, which is
4308 @(d:24,ERs). */
4310 /* @ERs is 6 bytes shorter than the longest. */
4311 if (GET_CODE (addr) == REG)
4312 return -6;
4314 /* @(d:16,ERs) is 6 bytes shorter than the longest. */
4315 if (GET_CODE (addr) == PLUS
4316 && GET_CODE (XEXP (addr, 0)) == REG
4317 && GET_CODE (XEXP (addr, 1)) == CONST_INT
4318 && INTVAL (XEXP (addr, 1)) > -32768
4319 && INTVAL (XEXP (addr, 1)) < 32767)
4320 return -4;
4322 /* @aa:8 is 6 bytes shorter than the longest. */
4323 if (GET_MODE (SET_SRC (pat)) == QImode
4324 && h8300_eightbit_constant_address_p (addr))
4325 return -6;
4327 /* @aa:16 is 4 bytes shorter than the longest. */
4328 if (h8300_tiny_constant_address_p (addr))
4329 return -4;
4331 /* @aa:24 is 2 bytes shorter than the longest. */
4332 if (GET_CODE (addr) == CONST_INT)
4333 return -2;
4337 /* Loading some constants needs adjustment. */
4338 if (GET_CODE (pat) == SET
4339 && GET_CODE (SET_SRC (pat)) == CONST_INT
4340 && GET_MODE (SET_DEST (pat)) == SImode
4341 && INTVAL (SET_SRC (pat)) != 0)
4343 int val = INTVAL (SET_SRC (pat));
4345 if (TARGET_H8300
4346 && ((val & 0xffff) == 0
4347 || ((val >> 16) & 0xffff) == 0))
4348 return -2;
4350 if (TARGET_H8300H || TARGET_H8300S)
4352 if (val == (val & 0xff)
4353 || val == (val & 0xff00))
4354 return 4 - 6;
4356 switch (val & 0xffffffff)
4358 case 0xffffffff:
4359 case 0xfffffffe:
4360 case 0xfffffffc:
4361 case 0x0000ffff:
4362 case 0x0000fffe:
4363 case 0xffff0000:
4364 case 0xfffe0000:
4365 case 0x00010000:
4366 case 0x00020000:
4367 return 4 - 6;
4372 /* Rotations need various adjustments. */
4373 if (GET_CODE (pat) == SET
4374 && (GET_CODE (SET_SRC (pat)) == ROTATE
4375 || GET_CODE (SET_SRC (pat)) == ROTATERT))
4377 rtx src = SET_SRC (pat);
4378 enum machine_mode mode = GET_MODE (src);
4379 int amount;
4380 int states = 0;
4382 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
4383 return 0;
4385 amount = INTVAL (XEXP (src, 1));
4387 /* Clean up AMOUNT. */
4388 if (amount < 0)
4389 amount = 0;
4390 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
4391 amount = GET_MODE_BITSIZE (mode);
4393 /* Determine the faster direction. After this phase, amount
4394 will be at most a half of GET_MODE_BITSIZE (mode). */
4395 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / (unsigned) 2)
4396 /* Flip the direction. */
4397 amount = GET_MODE_BITSIZE (mode) - amount;
4399 /* See if a byte swap (in HImode) or a word swap (in SImode) can
4400 boost up the rotation. */
4401 if ((mode == HImode && TARGET_H8300 && amount >= 5)
4402 || (mode == HImode && TARGET_H8300H && amount >= 6)
4403 || (mode == HImode && TARGET_H8300S && amount == 8)
4404 || (mode == SImode && TARGET_H8300H && amount >= 10)
4405 || (mode == SImode && TARGET_H8300S && amount >= 13))
4407 /* Adjust AMOUNT and flip the direction. */
4408 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
4409 states += 6;
4412 /* We use 2-bit rotations on the H8S. */
4413 if (TARGET_H8300S)
4414 amount = amount / 2 + amount % 2;
4416 /* The H8/300 uses three insns to rotate one bit, taking 6
4417 states. */
4418 states += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2);
4420 return -(20 - states);
4423 return 0;
4426 #ifndef OBJECT_FORMAT_ELF
4427 static void
4428 h8300_asm_named_section (name, flags)
4429 const char *name;
4430 unsigned int flags ATTRIBUTE_UNUSED;
4432 /* ??? Perhaps we should be using default_coff_asm_named_section. */
4433 fprintf (asm_out_file, "\t.section %s\n", name);
4435 #endif /* ! OBJECT_FORMAT_ELF */
4437 /* Nonzero if X is a constant address suitable as an 8-bit absolute,
4438 which is a special case of the 'R' operand. */
4441 h8300_eightbit_constant_address_p (x)
4442 rtx x;
4444 /* The ranges of the 8-bit area. */
4445 const unsigned HOST_WIDE_INT n1 = trunc_int_for_mode (0xff00, HImode);
4446 const unsigned HOST_WIDE_INT n2 = trunc_int_for_mode (0xffff, HImode);
4447 const unsigned HOST_WIDE_INT h1 = trunc_int_for_mode (0x00ffff00, SImode);
4448 const unsigned HOST_WIDE_INT h2 = trunc_int_for_mode (0x00ffffff, SImode);
4449 const unsigned HOST_WIDE_INT s1 = trunc_int_for_mode (0xffffff00, SImode);
4450 const unsigned HOST_WIDE_INT s2 = trunc_int_for_mode (0xffffffff, SImode);
4452 unsigned HOST_WIDE_INT addr;
4454 /* We accept symbols declared with eightbit_data. */
4455 if (GET_CODE (x) == SYMBOL_REF)
4456 return (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_EIGHTBIT_DATA) != 0;
4458 if (GET_CODE (x) != CONST_INT)
4459 return 0;
4461 addr = INTVAL (x);
4463 return (0
4464 || ((TARGET_H8300 || TARGET_NORMAL_MODE) && IN_RANGE (addr, n1, n2))
4465 || (TARGET_H8300H && IN_RANGE (addr, h1, h2))
4466 || (TARGET_H8300S && IN_RANGE (addr, s1, s2)));
4469 /* Nonzero if X is a constant address suitable as an 16-bit absolute
4470 on H8/300H and H8S. */
4473 h8300_tiny_constant_address_p (x)
4474 rtx x;
4476 /* The ranges of the 16-bit area. */
4477 const unsigned HOST_WIDE_INT h1 = trunc_int_for_mode (0x00000000, SImode);
4478 const unsigned HOST_WIDE_INT h2 = trunc_int_for_mode (0x00007fff, SImode);
4479 const unsigned HOST_WIDE_INT h3 = trunc_int_for_mode (0x00ff8000, SImode);
4480 const unsigned HOST_WIDE_INT h4 = trunc_int_for_mode (0x00ffffff, SImode);
4481 const unsigned HOST_WIDE_INT s1 = trunc_int_for_mode (0x00000000, SImode);
4482 const unsigned HOST_WIDE_INT s2 = trunc_int_for_mode (0x00007fff, SImode);
4483 const unsigned HOST_WIDE_INT s3 = trunc_int_for_mode (0xffff8000, SImode);
4484 const unsigned HOST_WIDE_INT s4 = trunc_int_for_mode (0xffffffff, SImode);
4486 unsigned HOST_WIDE_INT addr;
4488 /* We accept symbols declared with tiny_data. */
4489 if (GET_CODE (x) == SYMBOL_REF)
4490 return (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_TINY_DATA) != 0;
4492 if (GET_CODE (x) != CONST_INT)
4493 return 0;
4495 addr = INTVAL (x);
4497 return (0
4498 || TARGET_NORMAL_MODE
4499 || (TARGET_H8300H
4500 && (IN_RANGE (addr, h1, h2) || IN_RANGE (addr, h3, h4)))
4501 || (TARGET_H8300S
4502 && (IN_RANGE (addr, s1, s2) || IN_RANGE (addr, s3, s4))));
4506 byte_accesses_mergeable_p (addr1, addr2)
4507 rtx addr1, addr2;
4509 HOST_WIDE_INT offset1, offset2;
4510 rtx reg1, reg2;
4512 if (REG_P (addr1))
4514 reg1 = addr1;
4515 offset1 = 0;
4517 else if (GET_CODE (addr1) == PLUS
4518 && REG_P (XEXP (addr1, 0))
4519 && GET_CODE (XEXP (addr1, 1)) == CONST_INT)
4521 reg1 = XEXP (addr1, 0);
4522 offset1 = INTVAL (XEXP (addr1, 1));
4524 else
4525 return 0;
4527 if (REG_P (addr2))
4529 reg2 = addr2;
4530 offset2 = 0;
4532 else if (GET_CODE (addr2) == PLUS
4533 && REG_P (XEXP (addr2, 0))
4534 && GET_CODE (XEXP (addr2, 1)) == CONST_INT)
4536 reg2 = XEXP (addr2, 0);
4537 offset2 = INTVAL (XEXP (addr2, 1));
4539 else
4540 return 0;
4542 if (((reg1 == stack_pointer_rtx && reg2 == stack_pointer_rtx)
4543 || (reg1 == frame_pointer_rtx && reg2 == frame_pointer_rtx))
4544 && offset1 % 2 == 0
4545 && offset1 + 1 == offset2)
4546 return 1;
4548 return 0;