]> gcc.gnu.org Git - gcc.git/blob - gcc/config/h8300/h8300.c
h8300-protos.h: Update the prototypes of emit_a_rotate and expand_a_rotate.
[gcc.git] / gcc / config / h8300 / h8300.c
1 /* Subroutines for insn-output.c for Hitachi H8/300.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002 Free Software Foundation, Inc.
4 Contributed by Steve Chamberlain (sac@cygnus.com),
5 Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
6
7 This file is part of GNU CC.
8
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING. If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
23
24 #include "config.h"
25 #include "system.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "output.h"
34 #include "insn-attr.h"
35 #include "flags.h"
36 #include "recog.h"
37 #include "expr.h"
38 #include "function.h"
39 #include "toplev.h"
40 #include "c-pragma.h"
41 #include "tm_p.h"
42 #include "ggc.h"
43 #include "target.h"
44 #include "target-def.h"
45
46 /* Forward declarations. */
47 static int h8300_interrupt_function_p PARAMS ((tree));
48 static int h8300_monitor_function_p PARAMS ((tree));
49 static int h8300_os_task_function_p PARAMS ((tree));
50 static void dosize PARAMS ((FILE *, const char *, unsigned int));
51 static int round_frame_size PARAMS ((int));
52 static unsigned int compute_saved_regs PARAMS ((void));
53 static void push PARAMS ((FILE *, int));
54 static void pop PARAMS ((FILE *, int));
55 static const char *cond_string PARAMS ((enum rtx_code));
56 const struct attribute_spec h8300_attribute_table[];
57 static tree h8300_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
58 static tree h8300_handle_eightbit_data_attribute PARAMS ((tree *, tree, tree, int, bool *));
59 static tree h8300_handle_tiny_data_attribute PARAMS ((tree *, tree, tree, int, bool *));
60 static void h8300_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
61 static void h8300_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
62 #ifndef OBJECT_FORMAT_ELF
63 static void h8300_asm_named_section PARAMS ((const char *, unsigned int));
64 #endif
65
66 /* CPU_TYPE, says what cpu we're compiling for. */
67 int cpu_type;
68
69 /* True if the current function is an interrupt handler
70 (either via #pragma or an attribute specification). */
71 int interrupt_handler;
72
73 /* True if the current function is an OS Task
74 (via an attribute specification). */
75 int os_task;
76
77 /* True if the current function is a monitor
78 (via an attribute specification). */
79 int monitor;
80
81 /* True if a #pragma saveall has been seen for the current function. */
82 int pragma_saveall;
83
84 static const char *const names_big[] =
85 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" };
86
87 static const char *const names_extended[] =
88 { "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" };
89
90 static const char *const names_upper_extended[] =
91 { "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7" };
92
93 /* Points to one of the above. */
94 /* ??? The above could be put in an array indexed by CPU_TYPE. */
95 const char * const *h8_reg_names;
96
97 /* Various operations needed by the following, indexed by CPU_TYPE. */
98
99 static const char *const h8_push_ops[2] = { "push", "push.l" };
100 static const char *const h8_pop_ops[2] = { "pop", "pop.l" };
101 static const char *const h8_mov_ops[2] = { "mov.w", "mov.l" };
102
103 const char *h8_push_op, *h8_pop_op, *h8_mov_op;
104 \f
105 /* Initialize the GCC target structure. */
106 #undef TARGET_ATTRIBUTE_TABLE
107 #define TARGET_ATTRIBUTE_TABLE h8300_attribute_table
108
109 #undef TARGET_ASM_ALIGNED_HI_OP
110 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
111
112 #undef TARGET_ASM_FUNCTION_PROLOGUE
113 #define TARGET_ASM_FUNCTION_PROLOGUE h8300_output_function_prologue
114 #undef TARGET_ASM_FUNCTION_EPILOGUE
115 #define TARGET_ASM_FUNCTION_EPILOGUE h8300_output_function_epilogue
116
117 struct gcc_target targetm = TARGET_INITIALIZER;
118 \f
119 /* Initialize various cpu specific globals at start up. */
120
121 void
122 h8300_init_once ()
123 {
124 if (TARGET_H8300)
125 {
126 cpu_type = (int) CPU_H8300;
127 h8_reg_names = names_big;
128 }
129 else
130 {
131 /* For this we treat the H8/300H and H8/S the same. */
132 cpu_type = (int) CPU_H8300H;
133 h8_reg_names = names_extended;
134 }
135 h8_push_op = h8_push_ops[cpu_type];
136 h8_pop_op = h8_pop_ops[cpu_type];
137 h8_mov_op = h8_mov_ops[cpu_type];
138
139 if (!TARGET_H8300S && TARGET_MAC)
140 {
141 error ("-ms2600 is used without -ms");
142 target_flags |= 1;
143 }
144 }
145
146 const char *
147 byte_reg (x, b)
148 rtx x;
149 int b;
150 {
151 static const char *const names_small[] =
152 {"r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
153 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h"};
154
155 return names_small[REGNO (x) * 2 + b];
156 }
157
158 /* REGNO must be saved/restored across calls if this macro is true. */
159
160 #define WORD_REG_USED(regno) \
161 (regno < 7 \
162 /* No need to save registers if this function will not return. */\
163 && ! TREE_THIS_VOLATILE (current_function_decl) \
164 && (pragma_saveall \
165 /* Save any call saved register that was used. */ \
166 || (regs_ever_live[regno] && !call_used_regs[regno]) \
167 /* Save the frame pointer if it was used. */ \
168 || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno])\
169 /* Save any register used in an interrupt handler. */ \
170 || (interrupt_handler && regs_ever_live[regno]) \
171 /* Save call clobbered registers in non-leaf interrupt \
172 handlers. */ \
173 || (interrupt_handler \
174 && call_used_regs[regno] \
175 && !current_function_is_leaf)))
176
177 /* Output assembly language to FILE for the operation OP with operand size
178 SIZE to adjust the stack pointer. */
179
180 static void
181 dosize (file, op, size)
182 FILE *file;
183 const char *op;
184 unsigned int size;
185 {
186 /* On the H8/300H and H8/S, for sizes <= 8 bytes, it is as good or
187 better to use adds/subs insns rather than add.l/sub.l with an
188 immediate value.
189
190 Also, on the H8/300, if we don't have a temporary to hold the
191 size of the frame in the prologue, we simply emit a sequence of
192 subs since this shouldn't happen often. */
193 if ((TARGET_H8300 && size <= 4)
194 || ((TARGET_H8300H || TARGET_H8300S) && size <= 8)
195 || (TARGET_H8300 && interrupt_handler)
196 || (TARGET_H8300 && current_function_needs_context
197 && ! strcmp (op, "sub")))
198 {
199 unsigned HOST_WIDE_INT amount;
200
201 /* Try different amounts in descending order. */
202 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
203 amount > 0;
204 amount /= 2)
205 {
206 for (; size >= amount; size -= amount)
207 fprintf (file, "\t%ss\t#%d,sp\n", op, amount);
208 }
209 }
210 else
211 {
212 if (TARGET_H8300)
213 fprintf (file, "\tmov.w\t#%d,r3\n\t%s.w\tr3,sp\n", size, op);
214 else
215 fprintf (file, "\t%s.l\t#%d,sp\n", op, size);
216 }
217 }
218
219 /* Round up frame size SIZE. */
220
221 static int
222 round_frame_size (size)
223 int size;
224 {
225 return (size + STACK_BOUNDARY / 8 - 1) & -STACK_BOUNDARY / 8;
226 }
227
228 /* Compute which registers to push/pop.
229 Return a bit vector of registers. */
230
231 static unsigned int
232 compute_saved_regs ()
233 {
234 unsigned int saved_regs = 0;
235 int regno;
236
237 /* Construct a bit vector of registers to be pushed/popped. */
238 for (regno = 0; regno <= 6; regno++)
239 {
240 if (WORD_REG_USED (regno))
241 saved_regs |= 1 << regno;
242 }
243
244 /* Don't push/pop the frame pointer as it is treated separately. */
245 if (frame_pointer_needed)
246 saved_regs &= ~(1 << FRAME_POINTER_REGNUM);
247
248 return saved_regs;
249 }
250
251 /* Output assembly language code to push register RN. */
252
253 static void
254 push (file, rn)
255 FILE *file;
256 int rn;
257 {
258 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[rn]);
259 }
260
261 /* Output assembly language code to pop register RN. */
262
263 static void
264 pop (file, rn)
265 FILE *file;
266 int rn;
267 {
268 fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[rn]);
269 }
270
271 /* This is what the stack looks like after the prolog of
272 a function with a frame has been set up:
273
274 <args>
275 PC
276 FP <- fp
277 <locals>
278 <saved registers> <- sp
279
280 This is what the stack looks like after the prolog of
281 a function which doesn't have a frame:
282
283 <args>
284 PC
285 <locals>
286 <saved registers> <- sp
287 */
288
289 /* Output assembly language code for the function prologue. */
290
291 static void
292 h8300_output_function_prologue (file, size)
293 FILE *file;
294 HOST_WIDE_INT size;
295 {
296 int fsize = round_frame_size (size);
297 int idx;
298 int saved_regs;
299 int n_regs;
300
301 /* Note a function with the interrupt attribute and set interrupt_handler
302 accordingly. */
303 if (h8300_interrupt_function_p (current_function_decl))
304 interrupt_handler = 1;
305
306 /* If the current function has the OS_Task attribute set, then
307 we have a naked prologue. */
308 if (h8300_os_task_function_p (current_function_decl))
309 {
310 fprintf (file, ";OS_Task prologue\n");
311 os_task = 1;
312 return;
313 }
314
315 if (h8300_monitor_function_p (current_function_decl))
316 {
317 /* My understanding of monitor functions is they act just
318 like interrupt functions, except the prologue must
319 mask interrupts. */
320 fprintf (file, ";monitor prologue\n");
321 interrupt_handler = 1;
322 monitor = 1;
323 if (TARGET_H8300)
324 {
325 fprintf (file, "\tsubs\t#2,sp\n");
326 push (file, 0);
327 fprintf (file, "\tstc\tccr,r0l\n");
328 fprintf (file, "\tmov.b\tr0l,@(2,sp)\n");
329 pop (file, 0);
330 fprintf (file, "\torc\t#128,ccr\n");
331 }
332 else if (TARGET_H8300H)
333 {
334 push (file, 0);
335 fprintf (file, "\tstc\tccr,r0l\n");
336 fprintf (file, "\tmov.b\tr0l,@(4,sp)\n");
337 pop (file, 0);
338 fprintf (file, "\torc\t#128,ccr\n");
339 }
340 else if (TARGET_H8300S)
341 {
342 fprintf (file, "\tstc\texr,@-sp\n");
343 push (file, 0);
344 fprintf (file, "\tstc\tccr,r0l\n");
345 fprintf (file, "\tmov.b\tr0l,@(6,sp)\n");
346 pop (file, 0);
347 fprintf (file, "\torc\t#128,ccr\n");
348 }
349 else
350 abort ();
351 }
352
353 if (frame_pointer_needed)
354 {
355 /* Push fp. */
356 push (file, FRAME_POINTER_REGNUM);
357 fprintf (file, "\t%s\t%s,%s\n", h8_mov_op,
358 h8_reg_names[STACK_POINTER_REGNUM],
359 h8_reg_names[FRAME_POINTER_REGNUM]);
360 }
361
362 /* Leave room for locals. */
363 dosize (file, "sub", fsize);
364
365 /* Push the rest of the registers in ascending order. */
366 saved_regs = compute_saved_regs ();
367 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx += n_regs)
368 {
369 int regno = idx;
370
371 n_regs = 1;
372 if (saved_regs & (1 << regno))
373 {
374 if (TARGET_H8300S)
375 {
376 /* See how many registers we can push at the same time. */
377 if ((regno == 0 || regno == 4)
378 && ((saved_regs >> regno) & 0x0f) == 0x0f)
379 n_regs = 4;
380
381 else if ((regno == 0 || regno == 4)
382 && ((saved_regs >> regno) & 0x07) == 0x07)
383 n_regs = 3;
384
385 else if ((regno == 0 || regno == 2 || regno == 4 || regno == 6)
386 && ((saved_regs >> regno) & 0x03) == 0x03)
387 n_regs = 2;
388 }
389
390 if (n_regs == 1)
391 push (file, regno);
392 else
393 fprintf (file, "\tstm.l\t%s-%s,@-sp\n",
394 h8_reg_names[regno],
395 h8_reg_names[regno + (n_regs - 1)]);
396 }
397 }
398 }
399
400 /* Output assembly language code for the function epilogue. */
401
402 static void
403 h8300_output_function_epilogue (file, size)
404 FILE *file;
405 HOST_WIDE_INT size;
406 {
407 int fsize = round_frame_size (size);
408 int idx;
409 rtx insn = get_last_insn ();
410 int saved_regs;
411 int n_regs;
412
413 if (os_task)
414 {
415 /* OS_Task epilogues are nearly naked -- they just have an
416 rts instruction. */
417 fprintf (file, ";OS_task epilogue\n");
418 fprintf (file, "\trts\n");
419 goto out;
420 }
421
422 /* Monitor epilogues are the same as interrupt function epilogues.
423 Just make a note that we're in an monitor epilogue. */
424 if (monitor)
425 fprintf (file, ";monitor epilogue\n");
426
427 /* If the last insn was a BARRIER, we don't have to write any code. */
428 if (GET_CODE (insn) == NOTE)
429 insn = prev_nonnote_insn (insn);
430 if (insn && GET_CODE (insn) == BARRIER)
431 goto out;
432
433 /* Pop the saved registers in descending order. */
434 saved_regs = compute_saved_regs ();
435 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx += n_regs)
436 {
437 int regno = (FIRST_PSEUDO_REGISTER - 1) - idx;
438
439 n_regs = 1;
440 if (saved_regs & (1 << regno))
441 {
442 if (TARGET_H8300S)
443 {
444 /* See how many registers we can pop at the same time. */
445 if ((regno == 7 || regno == 3)
446 && ((saved_regs >> (regno - 3)) & 0x0f) == 0x0f)
447 n_regs = 4;
448
449 else if ((regno == 6 || regno == 2)
450 && ((saved_regs >> (regno - 2)) & 0x07) == 0x07)
451 n_regs = 3;
452
453 else if ((regno == 7 || regno == 5 || regno == 3 || regno == 1)
454 && ((saved_regs >> (regno - 1)) & 0x03) == 0x03)
455 n_regs = 2;
456 }
457
458 if (n_regs == 1)
459 pop (file, regno);
460 else
461 fprintf (file, "\tldm.l\t@sp+,%s-%s\n",
462 h8_reg_names[regno - (n_regs - 1)],
463 h8_reg_names[regno]);
464 }
465 }
466
467 /* Deallocate locals. */
468 dosize (file, "add", fsize);
469
470 /* Pop frame pointer if we had one. */
471 if (frame_pointer_needed)
472 pop (file, FRAME_POINTER_REGNUM);
473
474 if (interrupt_handler)
475 fprintf (file, "\trte\n");
476 else
477 fprintf (file, "\trts\n");
478
479 out:
480 interrupt_handler = 0;
481 os_task = 0;
482 monitor = 0;
483 pragma_saveall = 0;
484 }
485
486 /* Output assembly code for the start of the file. */
487
488 void
489 asm_file_start (file)
490 FILE *file;
491 {
492 fprintf (file, ";\tGCC For the Hitachi H8/300\n");
493 fprintf (file, ";\tBy Hitachi America Ltd and Cygnus Support\n");
494 if (optimize)
495 fprintf (file, "; -O%d\n", optimize);
496 if (TARGET_H8300H)
497 fprintf (file, "\n\t.h8300h\n");
498 else if (TARGET_H8300S)
499 fprintf (file, "\n\t.h8300s\n");
500 else
501 fprintf (file, "\n\n");
502 output_file_directive (file, main_input_filename);
503 }
504
505 /* Output assembly language code for the end of file. */
506
507 void
508 asm_file_end (file)
509 FILE *file;
510 {
511 fprintf (file, "\t.end\n");
512 }
513 \f
514 /* Return true if VALUE is a valid constant for constraint 'P'.
515 IE: VALUE is a power of two <= 2**15. */
516
517 int
518 small_power_of_two (value)
519 HOST_WIDE_INT value;
520 {
521 int power = exact_log2 (value);
522 return power >= 0 && power <= 15;
523 }
524
525 /* Return true if VALUE is a valid constant for constraint 'O', which
526 means that the constant would be ok to use as a bit for a bclr
527 instruction. */
528
529 int
530 ok_for_bclr (value)
531 HOST_WIDE_INT value;
532 {
533 return small_power_of_two ((~value) & 0xff);
534 }
535
536 /* Return true if OP is a valid source operand for an integer move
537 instruction. */
538
539 int
540 general_operand_src (op, mode)
541 rtx op;
542 enum machine_mode mode;
543 {
544 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
545 return 1;
546 return general_operand (op, mode);
547 }
548
549 /* Return true if OP is a valid destination operand for an integer move
550 instruction. */
551
552 int
553 general_operand_dst (op, mode)
554 rtx op;
555 enum machine_mode mode;
556 {
557 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == PRE_DEC)
558 return 1;
559 return general_operand (op, mode);
560 }
561
562 /* Return true if OP is a const valid for a bit clear instruction. */
563
564 int
565 o_operand (operand, mode)
566 rtx operand;
567 enum machine_mode mode ATTRIBUTE_UNUSED;
568 {
569 return (GET_CODE (operand) == CONST_INT
570 && CONST_OK_FOR_O (INTVAL (operand)));
571 }
572
573 /* Return true if OP is a const valid for a bit set or bit xor instruction. */
574
575 int
576 p_operand (operand, mode)
577 rtx operand;
578 enum machine_mode mode ATTRIBUTE_UNUSED;
579 {
580 return (GET_CODE (operand) == CONST_INT
581 && CONST_OK_FOR_P (INTVAL (operand)));
582 }
583
584 /* Return true if OP is a valid call operand. */
585
586 int
587 call_insn_operand (op, mode)
588 rtx op;
589 enum machine_mode mode ATTRIBUTE_UNUSED;
590 {
591 if (GET_CODE (op) == MEM)
592 {
593 rtx inside = XEXP (op, 0);
594 if (register_operand (inside, Pmode))
595 return 1;
596 if (CONSTANT_ADDRESS_P (inside))
597 return 1;
598 }
599 return 0;
600 }
601
602 /* Return 1 if an addition/subtraction of a constant integer can be
603 transformed into two consecutive adds/subs that are faster than the
604 straightforward way. Otherwise, return 0. */
605
606 int
607 two_insn_adds_subs_operand (op, mode)
608 rtx op;
609 enum machine_mode mode;
610 {
611 if (GET_CODE (op) == CONST_INT)
612 {
613 HOST_WIDE_INT value = INTVAL (op);
614
615 /* Force VALUE to be positive so that we do not have to consider
616 the negative case. */
617 if (value < 0)
618 value = -value;
619 if (TARGET_H8300H || TARGET_H8300S)
620 {
621 /* A constant addition/subtraction takes 2 states in QImode,
622 4 states in HImode, and 6 states in SImode. Thus, the
623 only case we can win is when SImode is used, in which
624 case, two adds/subs are used, taking 4 states. */
625 if (mode == SImode
626 && (value == 2 + 1
627 || value == 4 + 1
628 || value == 4 + 2
629 || value == 4 + 4))
630 return 1;
631 }
632 else
633 {
634 /* A constant addition/subtraction takes 2 states in
635 QImode. It takes 6 states in HImode, requiring the
636 constant to be loaded to a register first, and a lot more
637 in SImode. Thus the only case we can win is when either
638 HImode or SImode is used. */
639 if (mode != QImode
640 && (value == 2 + 1
641 || value == 2 + 2))
642 return 1;
643 }
644 }
645
646 return 0;
647 }
648
649 /* Split an add of a small constant into two adds/subs insns. */
650
651 void
652 split_adds_subs (mode, operands)
653 enum machine_mode mode;
654 rtx *operands;
655 {
656 HOST_WIDE_INT val = INTVAL (operands[1]);
657 rtx reg = operands[0];
658 HOST_WIDE_INT sign = 1;
659 HOST_WIDE_INT amount;
660
661 /* Force VAL to be positive so that we do not have to consider the
662 sign. */
663 if (val < 0)
664 {
665 val = -val;
666 sign = -1;
667 }
668
669 /* Try different amounts in descending order. */
670 for (amount = (TARGET_H8300H || TARGET_H8300S) ? 4 : 2;
671 amount > 0;
672 amount /= 2)
673 {
674 for (; val >= amount; val -= amount)
675 {
676 rtx tmp = gen_rtx_PLUS (mode, reg, GEN_INT (sign * amount));
677 emit_insn (gen_rtx_SET (VOIDmode, reg, tmp));
678 }
679 }
680
681 return;
682 }
683
684 /* Return true if OP is a valid call operand, and OP represents
685 an operand for a small call (4 bytes instead of 6 bytes). */
686
687 int
688 small_call_insn_operand (op, mode)
689 rtx op;
690 enum machine_mode mode ATTRIBUTE_UNUSED;
691 {
692 if (GET_CODE (op) == MEM)
693 {
694 rtx inside = XEXP (op, 0);
695
696 /* Register indirect is a small call. */
697 if (register_operand (inside, Pmode))
698 return 1;
699
700 /* A call through the function vector is a small
701 call too. */
702 if (GET_CODE (inside) == SYMBOL_REF
703 && SYMBOL_REF_FLAG (inside))
704 return 1;
705 }
706 /* Otherwise it's a large call. */
707 return 0;
708 }
709
710 /* Return true if OP is a valid jump operand. */
711
712 int
713 jump_address_operand (op, mode)
714 rtx op;
715 enum machine_mode mode;
716 {
717 if (GET_CODE (op) == REG)
718 return mode == Pmode;
719
720 if (GET_CODE (op) == MEM)
721 {
722 rtx inside = XEXP (op, 0);
723 if (register_operand (inside, Pmode))
724 return 1;
725 if (CONSTANT_ADDRESS_P (inside))
726 return 1;
727 }
728 return 0;
729 }
730
731 /* Recognize valid operands for bitfield instructions. */
732
733 extern int rtx_equal_function_value_matters;
734
735 int
736 bit_operand (op, mode)
737 rtx op;
738 enum machine_mode mode;
739 {
740 /* We can except any general operand, expept that MEM operands must
741 be limited to those that use addresses valid for the 'U' constraint. */
742 if (!general_operand (op, mode))
743 return 0;
744
745 /* Accept any mem during RTL generation. Otherwise, the code that does
746 insv and extzv will think that we can not handle memory. However,
747 to avoid reload problems, we only accept 'U' MEM operands after RTL
748 generation. This means that any named pattern which uses this predicate
749 must force its operands to match 'U' before emitting RTL. */
750
751 if (GET_CODE (op) == REG)
752 return 1;
753 if (GET_CODE (op) == SUBREG)
754 return 1;
755 if (!rtx_equal_function_value_matters)
756 /* We're building rtl. */
757 return GET_CODE (op) == MEM;
758 else
759 return (GET_CODE (op) == MEM
760 && EXTRA_CONSTRAINT (op, 'U'));
761 }
762
763 int
764 bit_memory_operand (op, mode)
765 rtx op;
766 enum machine_mode mode ATTRIBUTE_UNUSED;
767 {
768 return (GET_CODE (op) == MEM
769 && EXTRA_CONSTRAINT (op, 'U'));
770 }
771
772 /* Handle machine specific pragmas for compatibility with existing
773 compilers for the H8/300.
774
775 pragma saveall generates prolog/epilog code which saves and
776 restores all the registers on function entry.
777
778 pragma interrupt saves and restores all registers, and exits with
779 an rte instruction rather than an rts. A pointer to a function
780 with this attribute may be safely used in an interrupt vector. */
781
782 void
783 h8300_pr_interrupt (pfile)
784 cpp_reader *pfile ATTRIBUTE_UNUSED;
785 {
786 interrupt_handler = 1;
787 }
788
789 void
790 h8300_pr_saveall (pfile)
791 cpp_reader *pfile ATTRIBUTE_UNUSED;
792 {
793 pragma_saveall = 1;
794 }
795
796 static const char *const hand_list[] =
797 {
798 "__main",
799 "__cmpsi2",
800 "__divhi3",
801 "__modhi3",
802 "__udivhi3",
803 "__umodhi3",
804 "__divsi3",
805 "__modsi3",
806 "__udivsi3",
807 "__umodsi3",
808 "__mulhi3",
809 "__mulsi3",
810 "__reg_memcpy",
811 "__reg_memset",
812 "__ucmpsi2",
813 0,
814 };
815
816 /* If the next function argument with MODE and TYPE is to be passed in
817 a register, return a reg RTX for the hard register in which to pass
818 the argument. CUM represents the state after the last argument.
819 If the argument is to be pushed, NULL_RTX is returned. */
820
821 rtx
822 function_arg (cum, mode, type, named)
823 CUMULATIVE_ARGS *cum;
824 enum machine_mode mode;
825 tree type;
826 int named;
827 {
828 rtx result = NULL_RTX;
829 const char *fname;
830 int regpass = 0;
831
832 /* Never pass unnamed arguments in registers. */
833 if (!named)
834 return NULL_RTX;
835
836 /* Pass 3 regs worth of data in regs when user asked on the command line. */
837 if (TARGET_QUICKCALL)
838 regpass = 3;
839
840 /* If calling hand written assembler, use 4 regs of args. */
841 if (cum->libcall)
842 {
843 const char * const *p;
844
845 fname = XSTR (cum->libcall, 0);
846
847 /* See if this libcall is one of the hand coded ones. */
848 for (p = hand_list; *p && strcmp (*p, fname) != 0; p++)
849 ;
850
851 if (*p)
852 regpass = 4;
853 }
854
855 if (regpass)
856 {
857 int size;
858
859 if (mode == BLKmode)
860 size = int_size_in_bytes (type);
861 else
862 size = GET_MODE_SIZE (mode);
863
864 if (size + cum->nbytes <= regpass * UNITS_PER_WORD
865 && cum->nbytes / UNITS_PER_WORD <= 3)
866 result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
867 }
868
869 return result;
870 }
871 \f
872 /* Return the cost of the rtx R with code CODE. */
873
874 int
875 const_costs (r, c)
876 rtx r;
877 enum rtx_code c;
878 {
879 switch (c)
880 {
881 case CONST_INT:
882 switch (INTVAL (r))
883 {
884 case 0:
885 case 1:
886 case 2:
887 case -1:
888 case -2:
889 return 0;
890 case 4:
891 case -4:
892 if (TARGET_H8300H || TARGET_H8300S)
893 return 0;
894 else
895 return 1;
896 default:
897 return 1;
898 }
899
900 case CONST:
901 case LABEL_REF:
902 case SYMBOL_REF:
903 return 3;
904
905 case CONST_DOUBLE:
906 return 20;
907
908 default:
909 return 4;
910 }
911 }
912 \f
913 /* Documentation for the machine specific operand escapes:
914
915 'E' like s but negative.
916 'F' like t but negative.
917 'G' constant just the negative
918 'R' print operand as a byte:8 address if appropriate, else fall back to
919 'X' handling.
920 'S' print operand as a long word
921 'T' print operand as a word
922 'V' find the set bit, and print its number.
923 'W' find the clear bit, and print its number.
924 'X' print operand as a byte
925 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
926 If this operand isn't a register, fall back to 'R' handling.
927 'Z' print int & 7.
928 'b' print the bit opcode
929 'e' first word of 32 bit value - if reg, then least reg. if mem
930 then least. if const then most sig word
931 'f' second word of 32 bit value - if reg, then biggest reg. if mem
932 then +2. if const then least sig word
933 'j' print operand as condition code.
934 'k' print operand as reverse condition code.
935 's' print as low byte of 16 bit value
936 't' print as high byte of 16 bit value
937 'w' print as low byte of 32 bit value
938 'x' print as 2nd byte of 32 bit value
939 'y' print as 3rd byte of 32 bit value
940 'z' print as msb of 32 bit value
941 */
942
943 /* Return assembly language string which identifies a comparison type. */
944
945 static const char *
946 cond_string (code)
947 enum rtx_code code;
948 {
949 switch (code)
950 {
951 case NE:
952 return "ne";
953 case EQ:
954 return "eq";
955 case GE:
956 return "ge";
957 case GT:
958 return "gt";
959 case LE:
960 return "le";
961 case LT:
962 return "lt";
963 case GEU:
964 return "hs";
965 case GTU:
966 return "hi";
967 case LEU:
968 return "ls";
969 case LTU:
970 return "lo";
971 default:
972 abort ();
973 }
974 }
975
976 /* Print operand X using operand code CODE to assembly language output file
977 FILE. */
978
979 void
980 print_operand (file, x, code)
981 FILE *file;
982 rtx x;
983 int code;
984 {
985 /* This is used for communication between codes V,W,Z and Y. */
986 static int bitint;
987
988 switch (code)
989 {
990 case 'E':
991 switch (GET_CODE (x))
992 {
993 case REG:
994 fprintf (file, "%sl", names_big[REGNO (x)]);
995 break;
996 case CONST_INT:
997 fprintf (file, "#%d", (-INTVAL (x)) & 0xff);
998 break;
999 default:
1000 abort ();
1001 }
1002 break;
1003 case 'F':
1004 switch (GET_CODE (x))
1005 {
1006 case REG:
1007 fprintf (file, "%sh", names_big[REGNO (x)]);
1008 break;
1009 case CONST_INT:
1010 fprintf (file, "#%d", ((-INTVAL (x)) & 0xff00) >> 8);
1011 break;
1012 default:
1013 abort ();
1014 }
1015 break;
1016 case 'G':
1017 if (GET_CODE (x) != CONST_INT)
1018 abort ();
1019 fprintf (file, "#%d", 0xff & (-INTVAL (x)));
1020 break;
1021 case 'S':
1022 if (GET_CODE (x) == REG)
1023 fprintf (file, "%s", names_extended[REGNO (x)]);
1024 else
1025 goto def;
1026 break;
1027 case 'T':
1028 if (GET_CODE (x) == REG)
1029 fprintf (file, "%s", names_big[REGNO (x)]);
1030 else
1031 goto def;
1032 break;
1033 case 'V':
1034 bitint = exact_log2 (INTVAL (x));
1035 if (bitint == -1)
1036 abort ();
1037 fprintf (file, "#%d", bitint & 7);
1038 break;
1039 case 'W':
1040 bitint = exact_log2 ((~INTVAL (x)) & 0xff);
1041 if (bitint == -1)
1042 abort ();
1043 fprintf (file, "#%d", bitint & 7);
1044 break;
1045 case 'R':
1046 case 'X':
1047 if (GET_CODE (x) == REG)
1048 fprintf (file, "%s", byte_reg (x, 0));
1049 else
1050 goto def;
1051 break;
1052 case 'Y':
1053 if (bitint == -1)
1054 abort ();
1055 if (GET_CODE (x) == REG)
1056 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
1057 else
1058 print_operand (file, x, 'R');
1059 bitint = -1;
1060 break;
1061 case 'Z':
1062 bitint = INTVAL (x);
1063 fprintf (file, "#%d", bitint & 7);
1064 break;
1065 case 'b':
1066 switch (GET_CODE (x))
1067 {
1068 case IOR:
1069 fprintf (file, "bor");
1070 break;
1071 case XOR:
1072 fprintf (file, "bxor");
1073 break;
1074 case AND:
1075 fprintf (file, "band");
1076 break;
1077 default:
1078 break;
1079 }
1080 break;
1081 case 'e':
1082 switch (GET_CODE (x))
1083 {
1084 case REG:
1085 if (TARGET_H8300)
1086 fprintf (file, "%s", names_big[REGNO (x)]);
1087 else
1088 fprintf (file, "%s", names_upper_extended[REGNO (x)]);
1089 break;
1090 case MEM:
1091 print_operand (file, x, 0);
1092 break;
1093 case CONST_INT:
1094 fprintf (file, "#%d", ((INTVAL (x) >> 16) & 0xffff));
1095 break;
1096 case CONST_DOUBLE:
1097 {
1098 long val;
1099 REAL_VALUE_TYPE rv;
1100 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1101 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1102 fprintf (file, "#%ld", ((val >> 16) & 0xffff));
1103 break;
1104 }
1105 default:
1106 abort ();
1107 break;
1108 }
1109 break;
1110 case 'f':
1111 switch (GET_CODE (x))
1112 {
1113 case REG:
1114 if (TARGET_H8300)
1115 fprintf (file, "%s", names_big[REGNO (x) + 1]);
1116 else
1117 fprintf (file, "%s", names_big[REGNO (x)]);
1118 break;
1119 case MEM:
1120 x = adjust_address (x, HImode, 2);
1121 print_operand (file, x, 0);
1122 break;
1123 case CONST_INT:
1124 fprintf (file, "#%d", INTVAL (x) & 0xffff);
1125 break;
1126 case CONST_DOUBLE:
1127 {
1128 long val;
1129 REAL_VALUE_TYPE rv;
1130 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1131 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1132 fprintf (file, "#%ld", (val & 0xffff));
1133 break;
1134 }
1135 default:
1136 abort ();
1137 }
1138 break;
1139 case 'j':
1140 asm_fprintf (file, cond_string (GET_CODE (x)));
1141 break;
1142 case 'k':
1143 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
1144 break;
1145 case 's':
1146 if (GET_CODE (x) == CONST_INT)
1147 fprintf (file, "#%d", (INTVAL (x)) & 0xff);
1148 else
1149 fprintf (file, "%s", byte_reg (x, 0));
1150 break;
1151 case 't':
1152 if (GET_CODE (x) == CONST_INT)
1153 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1154 else
1155 fprintf (file, "%s", byte_reg (x, 1));
1156 break;
1157 case 'u':
1158 if (GET_CODE (x) != CONST_INT)
1159 abort ();
1160 fprintf (file, "%d", INTVAL (x));
1161 break;
1162 case 'w':
1163 if (GET_CODE (x) == CONST_INT)
1164 fprintf (file, "#%d", INTVAL (x) & 0xff);
1165 else
1166 fprintf (file, "%s",
1167 byte_reg (x, TARGET_H8300 ? 2 : 0));
1168 break;
1169 case 'x':
1170 if (GET_CODE (x) == CONST_INT)
1171 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1172 else
1173 fprintf (file, "%s",
1174 byte_reg (x, TARGET_H8300 ? 3 : 1));
1175 break;
1176 case 'y':
1177 if (GET_CODE (x) == CONST_INT)
1178 fprintf (file, "#%d", (INTVAL (x) >> 16) & 0xff);
1179 else
1180 fprintf (file, "%s", byte_reg (x, 0));
1181 break;
1182 case 'z':
1183 if (GET_CODE (x) == CONST_INT)
1184 fprintf (file, "#%d", (INTVAL (x) >> 24) & 0xff);
1185 else
1186 fprintf (file, "%s", byte_reg (x, 1));
1187 break;
1188
1189 default:
1190 def:
1191 switch (GET_CODE (x))
1192 {
1193 case REG:
1194 switch (GET_MODE (x))
1195 {
1196 case QImode:
1197 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */
1198 fprintf (file, "%s", byte_reg (x, 0));
1199 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1200 fprintf (file, "%s", names_big[REGNO (x)]);
1201 #endif
1202 break;
1203 case HImode:
1204 fprintf (file, "%s", names_big[REGNO (x)]);
1205 break;
1206 case SImode:
1207 case SFmode:
1208 fprintf (file, "%s", names_extended[REGNO (x)]);
1209 break;
1210 default:
1211 abort ();
1212 }
1213 break;
1214
1215 case MEM:
1216 fprintf (file, "@");
1217 output_address (XEXP (x, 0));
1218
1219 /* If this is an 'R' operand (reference into the 8-bit
1220 area), then specify a symbolic address as "foo:8",
1221 otherwise if operand is still in eight bit section, use
1222 "foo:16". */
1223 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
1224 && SYMBOL_REF_FLAG (XEXP (x, 0)))
1225 fprintf (file, (code == 'R' ? ":8" : ":16"));
1226 else if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
1227 && TINY_DATA_NAME_P (XSTR (XEXP (x, 0), 0)))
1228 fprintf (file, ":16");
1229 else if ((code == 'R')
1230 && EIGHTBIT_CONSTANT_ADDRESS_P (XEXP (x, 0)))
1231 fprintf (file, ":8");
1232 break;
1233
1234 case CONST_INT:
1235 case SYMBOL_REF:
1236 case CONST:
1237 case LABEL_REF:
1238 fprintf (file, "#");
1239 print_operand_address (file, x);
1240 break;
1241 case CONST_DOUBLE:
1242 {
1243 long val;
1244 REAL_VALUE_TYPE rv;
1245 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1246 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1247 fprintf (file, "#%ld", val);
1248 break;
1249 }
1250 default:
1251 break;
1252 }
1253 }
1254 }
1255
1256 /* Output assembly language output for the address ADDR to FILE. */
1257
1258 void
1259 print_operand_address (file, addr)
1260 FILE *file;
1261 rtx addr;
1262 {
1263 switch (GET_CODE (addr))
1264 {
1265 case REG:
1266 fprintf (file, "%s", h8_reg_names[REGNO (addr)]);
1267 break;
1268
1269 case PRE_DEC:
1270 fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
1271 break;
1272
1273 case POST_INC:
1274 fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);
1275 break;
1276
1277 case PLUS:
1278 fprintf (file, "(");
1279 if (GET_CODE (XEXP (addr, 0)) == REG)
1280 {
1281 /* reg,foo */
1282 print_operand_address (file, XEXP (addr, 1));
1283 fprintf (file, ",");
1284 print_operand_address (file, XEXP (addr, 0));
1285 }
1286 else
1287 {
1288 /* foo+k */
1289 print_operand_address (file, XEXP (addr, 0));
1290 fprintf (file, "+");
1291 print_operand_address (file, XEXP (addr, 1));
1292 }
1293 fprintf (file, ")");
1294 break;
1295
1296 case CONST_INT:
1297 {
1298 /* Since the H8/300 only has 16 bit pointers, negative values are also
1299 those >= 32768. This happens for example with pointer minus a
1300 constant. We don't want to turn (char *p - 2) into
1301 (char *p + 65534) because loop unrolling can build upon this
1302 (IE: char *p + 131068). */
1303 int n = INTVAL (addr);
1304 if (TARGET_H8300)
1305 n = (int) (short) n;
1306 if (n < 0)
1307 /* ??? Why the special case for -ve values? */
1308 fprintf (file, "-%d", -n);
1309 else
1310 fprintf (file, "%d", n);
1311 break;
1312 }
1313
1314 default:
1315 output_addr_const (file, addr);
1316 break;
1317 }
1318 }
1319 \f
1320 /* Output all insn addresses and their sizes into the assembly language
1321 output file. This is helpful for debugging whether the length attributes
1322 in the md file are correct. This is not meant to be a user selectable
1323 option. */
1324
1325 void
1326 final_prescan_insn (insn, operand, num_operands)
1327 rtx insn, *operand ATTRIBUTE_UNUSED;
1328 int num_operands ATTRIBUTE_UNUSED;
1329 {
1330 /* This holds the last insn address. */
1331 static int last_insn_address = 0;
1332
1333 int uid = INSN_UID (insn);
1334
1335 if (TARGET_RTL_DUMP)
1336 {
1337 fprintf (asm_out_file, "\n****************");
1338 print_rtl (asm_out_file, PATTERN (insn));
1339 fprintf (asm_out_file, "\n");
1340 }
1341
1342 if (TARGET_ADDRESSES)
1343 {
1344 fprintf (asm_out_file, "; 0x%x %d\n", INSN_ADDRESSES (uid),
1345 INSN_ADDRESSES (uid) - last_insn_address);
1346 last_insn_address = INSN_ADDRESSES (uid);
1347 }
1348 }
1349
1350 /* Prepare for an SI sized move. */
1351
1352 int
1353 do_movsi (operands)
1354 rtx operands[];
1355 {
1356 rtx src = operands[1];
1357 rtx dst = operands[0];
1358 if (!reload_in_progress && !reload_completed)
1359 {
1360 if (!register_operand (dst, GET_MODE (dst)))
1361 {
1362 rtx tmp = gen_reg_rtx (GET_MODE (dst));
1363 emit_move_insn (tmp, src);
1364 operands[1] = tmp;
1365 }
1366 }
1367 return 0;
1368 }
1369
1370 /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
1371 Define the offset between two registers, one to be eliminated, and
1372 the other its replacement, at the start of a routine. */
1373
1374 int
1375 initial_offset (from, to)
1376 int from, to;
1377 {
1378 int offset = 0;
1379
1380 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1381 offset = UNITS_PER_WORD + frame_pointer_needed * UNITS_PER_WORD;
1382 else if (from == RETURN_ADDRESS_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1383 offset = frame_pointer_needed * UNITS_PER_WORD;
1384 else
1385 {
1386 int regno;
1387
1388 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1389 if (WORD_REG_USED (regno))
1390 offset += UNITS_PER_WORD;
1391
1392 /* See the comments for get_frame_size. We need to round it up to
1393 STACK_BOUNDARY. */
1394
1395 offset += ((get_frame_size () + STACK_BOUNDARY / BITS_PER_UNIT - 1)
1396 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
1397
1398 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1399 offset += UNITS_PER_WORD; /* Skip saved PC */
1400 }
1401 return offset;
1402 }
1403
1404 rtx
1405 h8300_return_addr_rtx (count, frame)
1406 int count;
1407 rtx frame;
1408 {
1409 rtx ret;
1410
1411 if (count == 0)
1412 ret = gen_rtx_MEM (Pmode,
1413 gen_rtx_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM));
1414 else if (flag_omit_frame_pointer)
1415 return (rtx) 0;
1416 else
1417 ret = gen_rtx_MEM (Pmode,
1418 memory_address (Pmode,
1419 plus_constant (frame, UNITS_PER_WORD)));
1420 set_mem_alias_set (ret, get_frame_alias_set ());
1421 return ret;
1422 }
1423
1424 /* Update the condition code from the insn. */
1425
1426 void
1427 notice_update_cc (body, insn)
1428 rtx body;
1429 rtx insn;
1430 {
1431 switch (get_attr_cc (insn))
1432 {
1433 case CC_NONE:
1434 /* Insn does not affect CC at all. */
1435 break;
1436
1437 case CC_NONE_0HIT:
1438 /* Insn does not change CC, but the 0'th operand has been changed. */
1439 if (cc_status.value1 != 0
1440 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
1441 cc_status.value1 = 0;
1442 break;
1443
1444 case CC_SET_ZN:
1445 /* Insn sets the Z,N flags of CC to recog_data.operand[0].
1446 The V flag is unusable. The C flag may or may not be known but
1447 that's ok because alter_cond will change tests to use EQ/NE. */
1448 CC_STATUS_INIT;
1449 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
1450 cc_status.value1 = recog_data.operand[0];
1451 break;
1452
1453 case CC_SET_ZNV:
1454 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
1455 The C flag may or may not be known but that's ok because
1456 alter_cond will change tests to use EQ/NE. */
1457 CC_STATUS_INIT;
1458 cc_status.flags |= CC_NO_CARRY;
1459 cc_status.value1 = recog_data.operand[0];
1460 break;
1461
1462 case CC_COMPARE:
1463 /* The insn is a compare instruction. */
1464 CC_STATUS_INIT;
1465 cc_status.value1 = SET_SRC (body);
1466 break;
1467
1468 case CC_CLOBBER:
1469 /* Insn doesn't leave CC in a usable state. */
1470 CC_STATUS_INIT;
1471 break;
1472 }
1473 }
1474
1475 /* Recognize valid operators for bit instructions. */
1476
1477 int
1478 bit_operator (x, mode)
1479 rtx x;
1480 enum machine_mode mode ATTRIBUTE_UNUSED;
1481 {
1482 enum rtx_code code = GET_CODE (x);
1483
1484 return (code == XOR
1485 || code == AND
1486 || code == IOR);
1487 }
1488 \f
1489 const char *
1490 output_logical_op (mode, code, operands)
1491 enum machine_mode mode;
1492 int code;
1493 rtx *operands;
1494 {
1495 /* Pretend that every byte is affected if both operands are registers. */
1496 unsigned HOST_WIDE_INT intval =
1497 (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
1498 ? INTVAL (operands[2]) : 0x55555555);
1499 /* The determinant of the algorithm. If we perform an AND, 0
1500 affects a bit. Otherwise, 1 affects a bit. */
1501 unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
1502 /* The name of an insn. */
1503 const char *opname;
1504 char insn_buf[100];
1505
1506 switch (code)
1507 {
1508 case AND:
1509 opname = "and";
1510 break;
1511 case IOR:
1512 opname = "or";
1513 break;
1514 case XOR:
1515 opname = "xor";
1516 break;
1517 default:
1518 abort ();
1519 }
1520
1521 switch (mode)
1522 {
1523 case HImode:
1524 /* First, see if we can finish with one insn. */
1525 if ((TARGET_H8300H || TARGET_H8300S)
1526 && ((det & 0x00ff) != 0)
1527 && ((det & 0xff00) != 0))
1528 {
1529 sprintf (insn_buf, "%s.w\t%%T2,%%T0", opname);
1530 output_asm_insn (insn_buf, operands);
1531 }
1532 else
1533 {
1534 /* Take care of the lower byte. */
1535 if ((det & 0x00ff) != 0)
1536 {
1537 sprintf (insn_buf, "%s\t%%s2,%%s0", opname);
1538 output_asm_insn (insn_buf, operands);
1539 }
1540 /* Take care of the upper byte. */
1541 if ((det & 0xff00) != 0)
1542 {
1543 sprintf (insn_buf, "%s\t%%t2,%%t0", opname);
1544 output_asm_insn (insn_buf, operands);
1545 }
1546 }
1547 break;
1548 case SImode:
1549 /* First, see if we can finish with one insn.
1550
1551 If code is either AND or XOR, we exclude two special cases,
1552 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
1553 can do a better job. */
1554 if ((TARGET_H8300H || TARGET_H8300S)
1555 && ((det & 0x0000ffff) != 0)
1556 && ((det & 0xffff0000) != 0)
1557 && (code == IOR || det != 0xffffff00)
1558 && (code == IOR || det != 0xffff00ff))
1559 {
1560 sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname);
1561 output_asm_insn (insn_buf, operands);
1562 }
1563 else
1564 {
1565 /* Take care of the lower and upper words individually. For
1566 each word, we try different methods in the order of
1567
1568 1) the special insn (in case of AND or XOR),
1569 2) the word-wise insn, and
1570 3) The byte-wise insn. */
1571 if ((TARGET_H8300H || TARGET_H8300S)
1572 && ((det & 0x0000ffff) == 0x0000ffff)
1573 && code != IOR)
1574 output_asm_insn ((code == AND)
1575 ? "sub.w\t%f0,%f0" : "not.w\t%f0",
1576 operands);
1577 else if ((TARGET_H8300H || TARGET_H8300S)
1578 && ((det & 0x000000ff) != 0)
1579 && ((det & 0x0000ff00) != 0))
1580 {
1581 sprintf (insn_buf, "%s.w\t%%f2,%%f0", opname);
1582 output_asm_insn (insn_buf, operands);
1583 }
1584 else
1585 {
1586 if ((det & 0x000000ff) != 0)
1587 {
1588 sprintf (insn_buf, "%s\t%%w2,%%w0", opname);
1589 output_asm_insn (insn_buf, operands);
1590 }
1591 if ((det & 0x0000ff00) != 0)
1592 {
1593 sprintf (insn_buf, "%s\t%%x2,%%x0", opname);
1594 output_asm_insn (insn_buf, operands);
1595 }
1596 }
1597
1598 if ((TARGET_H8300H || TARGET_H8300S)
1599 && ((det & 0xffff0000) == 0xffff0000)
1600 && code != IOR)
1601 output_asm_insn ((code == AND)
1602 ? "sub.w\t%e0,%e0" : "not.w\t%e0",
1603 operands);
1604 else if (TARGET_H8300H || TARGET_H8300S)
1605 {
1606 if ((det & 0xffff0000) != 0)
1607 {
1608 sprintf (insn_buf, "%s.w\t%%e2,%%e0", opname);
1609 output_asm_insn (insn_buf, operands);
1610 }
1611 }
1612 else
1613 {
1614 if ((det & 0x00ff0000) != 0)
1615 {
1616 sprintf (insn_buf, "%s\t%%y2,%%y0", opname);
1617 output_asm_insn (insn_buf, operands);
1618 }
1619 if ((det & 0xff000000) != 0)
1620 {
1621 sprintf (insn_buf, "%s\t%%z2,%%z0", opname);
1622 output_asm_insn (insn_buf, operands);
1623 }
1624 }
1625 }
1626 break;
1627 default:
1628 abort ();
1629 }
1630 return "";
1631 }
1632 \f
1633 /* Shifts.
1634
1635 We devote a fair bit of code to getting efficient shifts since we
1636 can only shift one bit at a time on the H8/300 and H8/300H and only
1637 one or two bits at a time on the H8/S.
1638
1639 All shift code falls into one of the following ways of
1640 implementation:
1641
1642 o SHIFT_INLINE: Emit straight line code for the shift; this is used
1643 when a straight line shift is about the same size or smaller than
1644 a loop.
1645
1646 o SHIFT_ROT_AND: Rotate the value the opposite direction, then mask
1647 off the bits we don't need. This is used when only a few of the
1648 bits in the original value will survive in the shifted value.
1649
1650 o SHIFT_SPECIAL: Often it's possible to move a byte or a word to
1651 simulate a shift by 8, 16, or 24 bits. Once moved, a few inline
1652 shifts can be added if the shift count is slightly more than 8 or
1653 16. This case also includes other oddballs that are not worth
1654 explaning here.
1655
1656 o SHIFT_LOOP: Emit a loop using one (or two on H8/S) bit shifts.
1657
1658 Here are some thoughts on what the absolutely positively best code
1659 is. "Best" here means some rational trade-off between code size
1660 and speed, where speed is more preferred but not at the expense of
1661 generating 20 insns.
1662
1663 Below, a trailing '*' after the shift count indicates the "best"
1664 mode isn't implemented. We only describe SHIFT_SPECIAL cases to
1665 simplify the table. For other cases, refer to shift_alg_[qhs]i.
1666
1667 H8/300 QImode shifts
1668 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
1669
1670 H8/300 HImode shifts
1671 7 - shift 2nd half other way into carry.
1672 copy 1st half into 2nd half
1673 rotate 2nd half other way with carry
1674 rotate 1st half other way (no carry)
1675 mask off bits in 1st half (ASHIFT | LSHIFTRT).
1676 sign extend 1st half (ASHIFTRT)
1677 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1678 9-12 - do shift by 8, inline remaining shifts
1679 15 - ASHIFTRT: shll, subx, set other byte
1680
1681 H8/300 SImode shifts
1682 7* - shift other way once, move bytes into place,
1683 move carry into place (possibly with sign extension)
1684 8 - move bytes into place, zero or sign extend other
1685 15* - shift other way once, move word into place, move carry into place
1686 16 - move word, zero or sign extend other
1687 24* - move bytes into place, zero or sign extend other
1688 31 - ASHIFTRT: shll top byte, subx, copy to other bytes
1689
1690 H8/300H QImode shifts (same as H8/300 QImode shifts)
1691 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
1692
1693 H8/300H HImode shifts
1694 7 - shift 2nd half other way into carry.
1695 copy 1st half into 2nd half
1696 rotate entire word other way using carry
1697 mask off remaining bits (ASHIFT | LSHIFTRT)
1698 sign extend remaining bits (ASHIFTRT)
1699 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1700 9-12 - do shift by 8, inline remaining shifts
1701 15 - ASHIFTRT: shll, subx, set other byte
1702
1703 H8/300H SImode shifts
1704 (These are complicated by the fact that we don't have byte level access to
1705 the top word.)
1706 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1707 15* - shift other way once, move word into place, move carry into place
1708 (with sign extension for ASHIFTRT)
1709 16 - move word into place, zero or sign extend other
1710 17-20 - do 16bit shift, then inline remaining shifts
1711 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1712 move word 0 to word 1, zero word 0
1713 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1714 zero word 1, zero byte 1
1715 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1716 sign extend byte 0, sign extend word 0
1717 25-27* - either loop, or
1718 do 24 bit shift, inline rest
1719 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1720
1721 H8/S QImode shifts
1722 7 - ASHIFTRT: shll, subx (propagate carry bit to all bits)
1723
1724 H8/S HImode shifts
1725 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1726 9-12 - do shift by 8, inline remaining shifts
1727 15 - ASHIFTRT: shll, subx, set other byte
1728
1729 H8/S SImode shifts
1730 (These are complicated by the fact that we don't have byte level access to
1731 the top word.)
1732 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1733 15* - shift other way once, move word into place, move carry into place
1734 (with sign extension for ASHIFTRT)
1735 16 - move word into place, zero or sign extend other
1736 17-20 - do 16bit shift, then inline remaining shifts
1737 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1738 move word 0 to word 1, zero word 0
1739 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1740 zero word 1, zero byte 1
1741 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1742 sign extend byte 0, sign extend word 0
1743 25-27* - either loop, or
1744 do 24 bit shift, inline rest
1745 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1746
1747 Panic!!! */
1748
1749 int
1750 nshift_operator (x, mode)
1751 rtx x;
1752 enum machine_mode mode ATTRIBUTE_UNUSED;
1753 {
1754 switch (GET_CODE (x))
1755 {
1756 case ASHIFTRT:
1757 case LSHIFTRT:
1758 case ASHIFT:
1759 return 1;
1760
1761 default:
1762 return 0;
1763 }
1764 }
1765
1766 /* Called from the .md file to emit code to do shifts.
1767 Return a boolean indicating success.
1768 (Currently this is always TRUE). */
1769
1770 int
1771 expand_a_shift (mode, code, operands)
1772 enum machine_mode mode;
1773 int code;
1774 rtx operands[];
1775 {
1776 emit_move_insn (operands[0], operands[1]);
1777
1778 /* Need a loop to get all the bits we want - we generate the
1779 code at emit time, but need to allocate a scratch reg now. */
1780
1781 emit_insn (gen_rtx_PARALLEL
1782 (VOIDmode,
1783 gen_rtvec (2,
1784 gen_rtx_SET (VOIDmode, operands[0],
1785 gen_rtx (code, mode, operands[0],
1786 operands[2])),
1787 gen_rtx_CLOBBER (VOIDmode,
1788 gen_rtx_SCRATCH (QImode)))));
1789
1790 return 1;
1791 }
1792
1793 /* See above for explanation of this enum. */
1794
1795 enum shift_alg
1796 {
1797 SHIFT_INLINE,
1798 SHIFT_ROT_AND,
1799 SHIFT_SPECIAL,
1800 SHIFT_LOOP
1801 };
1802
1803 /* Symbols of the various shifts which can be used as indices. */
1804
1805 enum shift_type
1806 {
1807 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
1808 };
1809
1810 /* Symbols of the various modes which can be used as indices. */
1811
1812 enum shift_mode
1813 {
1814 QIshift, HIshift, SIshift
1815 };
1816
1817 /* For single bit shift insns, record assembler and what bits of the
1818 condition code are valid afterwards (represented as various CC_FOO
1819 bits, 0 means CC isn't left in a usable state). */
1820
1821 struct shift_insn
1822 {
1823 const char *const assembler;
1824 const int cc_valid;
1825 };
1826
1827 /* Assembler instruction shift table.
1828
1829 These tables are used to look up the basic shifts.
1830 They are indexed by cpu, shift_type, and mode. */
1831
1832 static const struct shift_insn shift_one[2][3][3] =
1833 {
1834 /* H8/300 */
1835 {
1836 /* SHIFT_ASHIFT */
1837 {
1838 { "shll\t%X0", CC_NO_CARRY },
1839 { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1840 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }
1841 },
1842 /* SHIFT_LSHIFTRT */
1843 {
1844 { "shlr\t%X0", CC_NO_CARRY },
1845 { "shlr\t%t0\n\trotxr\t%s0", 0 },
1846 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1847 },
1848 /* SHIFT_ASHIFTRT */
1849 {
1850 { "shar\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1851 { "shar\t%t0\n\trotxr\t%s0", 0 },
1852 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
1853 }
1854 },
1855 /* H8/300H */
1856 {
1857 /* SHIFT_ASHIFT */
1858 {
1859 { "shll.b\t%X0", CC_NO_CARRY },
1860 { "shll.w\t%T0", CC_NO_CARRY },
1861 { "shll.l\t%S0", CC_NO_CARRY }
1862 },
1863 /* SHIFT_LSHIFTRT */
1864 {
1865 { "shlr.b\t%X0", CC_NO_CARRY },
1866 { "shlr.w\t%T0", CC_NO_CARRY },
1867 { "shlr.l\t%S0", CC_NO_CARRY }
1868 },
1869 /* SHIFT_ASHIFTRT */
1870 {
1871 { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1872 { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1873 { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
1874 }
1875 }
1876 };
1877
1878 static const struct shift_insn shift_two[3][3] =
1879 {
1880 /* SHIFT_ASHIFT */
1881 {
1882 { "shll.b\t#2,%X0", CC_NO_CARRY },
1883 { "shll.w\t#2,%T0", CC_NO_CARRY },
1884 { "shll.l\t#2,%S0", CC_NO_CARRY }
1885 },
1886 /* SHIFT_LSHIFTRT */
1887 {
1888 { "shlr.b\t#2,%X0", CC_NO_CARRY },
1889 { "shlr.w\t#2,%T0", CC_NO_CARRY },
1890 { "shlr.l\t#2,%S0", CC_NO_CARRY }
1891 },
1892 /* SHIFT_ASHIFTRT */
1893 {
1894 { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1895 { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1896 { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
1897 }
1898 };
1899
1900 /* Rotates are organized by which shift they'll be used in implementing.
1901 There's no need to record whether the cc is valid afterwards because
1902 it is the AND insn that will decide this. */
1903
1904 static const char *const rotate_one[2][3][3] =
1905 {
1906 /* H8/300 */
1907 {
1908 /* SHIFT_ASHIFT */
1909 {
1910 "rotr\t%X0",
1911 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
1912 0
1913 },
1914 /* SHIFT_LSHIFTRT */
1915 {
1916 "rotl\t%X0",
1917 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
1918 0
1919 },
1920 /* SHIFT_ASHIFTRT */
1921 {
1922 "rotl\t%X0",
1923 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
1924 0
1925 }
1926 },
1927 /* H8/300H */
1928 {
1929 /* SHIFT_ASHIFT */
1930 {
1931 "rotr.b\t%X0",
1932 "rotr.w\t%T0",
1933 "rotr.l\t%S0"
1934 },
1935 /* SHIFT_LSHIFTRT */
1936 {
1937 "rotl.b\t%X0",
1938 "rotl.w\t%T0",
1939 "rotl.l\t%S0"
1940 },
1941 /* SHIFT_ASHIFTRT */
1942 {
1943 "rotl.b\t%X0",
1944 "rotl.w\t%T0",
1945 "rotl.l\t%S0"
1946 }
1947 }
1948 };
1949
1950 static const char *const rotate_two[3][3] =
1951 {
1952 /* SHIFT_ASHIFT */
1953 {
1954 "rotr.b\t#2,%X0",
1955 "rotr.w\t#2,%T0",
1956 "rotr.l\t#2,%S0"
1957 },
1958 /* SHIFT_LSHIFTRT */
1959 {
1960 "rotl.b\t#2,%X0",
1961 "rotl.w\t#2,%T0",
1962 "rotl.l\t#2,%S0"
1963 },
1964 /* SHIFT_ASHIFTRT */
1965 {
1966 "rotl.b\t#2,%X0",
1967 "rotl.w\t#2,%T0",
1968 "rotl.l\t#2,%S0"
1969 }
1970 };
1971
1972 /* Macros to keep the shift algorithm tables small. */
1973 #define INL SHIFT_INLINE
1974 #define ROT SHIFT_ROT_AND
1975 #define LOP SHIFT_LOOP
1976 #define SPC SHIFT_SPECIAL
1977
1978 /* The shift algorithms for each machine, mode, shift type, and shift
1979 count are defined below. The three tables below correspond to
1980 QImode, HImode, and SImode, respectively. Each table is organized
1981 by, in the order of indecies, machine, shift type, and shift count. */
1982
1983 static const enum shift_alg shift_alg_qi[3][3][8] = {
1984 {
1985 /* TARGET_H8300 */
1986 /* 0 1 2 3 4 5 6 7 */
1987 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
1988 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
1989 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
1990 },
1991 {
1992 /* TARGET_H8300H */
1993 /* 0 1 2 3 4 5 6 7 */
1994 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
1995 { INL, INL, INL, INL, INL, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
1996 { INL, INL, INL, INL, INL, LOP, LOP, SPC } /* SHIFT_ASHIFTRT */
1997 },
1998 {
1999 /* TARGET_H8300S */
2000 /* 0 1 2 3 4 5 6 7 */
2001 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_ASHIFT */
2002 { INL, INL, INL, INL, INL, INL, ROT, ROT }, /* SHIFT_LSHIFTRT */
2003 { INL, INL, INL, INL, INL, INL, INL, SPC } /* SHIFT_ASHIFTRT */
2004 }
2005 };
2006
2007 static const enum shift_alg shift_alg_hi[3][3][16] = {
2008 {
2009 /* TARGET_H8300 */
2010 /* 0 1 2 3 4 5 6 7 */
2011 /* 8 9 10 11 12 13 14 15 */
2012 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2013 SPC, SPC, SPC, SPC, SPC, LOP, LOP, ROT }, /* SHIFT_ASHIFT */
2014 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2015 SPC, SPC, SPC, SPC, SPC, LOP, LOP, ROT }, /* SHIFT_LSHIFTRT */
2016 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2017 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2018 },
2019 {
2020 /* TARGET_H8300H */
2021 /* 0 1 2 3 4 5 6 7 */
2022 /* 8 9 10 11 12 13 14 15 */
2023 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2024 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2025 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2026 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2027 { INL, INL, INL, INL, INL, LOP, LOP, SPC,
2028 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2029 },
2030 {
2031 /* TARGET_H8300S */
2032 /* 0 1 2 3 4 5 6 7 */
2033 /* 8 9 10 11 12 13 14 15 */
2034 { INL, INL, INL, INL, INL, INL, INL, INL,
2035 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
2036 { INL, INL, INL, INL, INL, INL, INL, INL,
2037 SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
2038 { INL, INL, INL, INL, INL, INL, INL, INL,
2039 SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2040 }
2041 };
2042
2043 static const enum shift_alg shift_alg_si[3][3][32] = {
2044 {
2045 /* TARGET_H8300 */
2046 /* 0 1 2 3 4 5 6 7 */
2047 /* 8 9 10 11 12 13 14 15 */
2048 /* 16 17 18 19 20 21 22 23 */
2049 /* 24 25 26 27 28 29 30 31 */
2050 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2051 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2052 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2053 LOP, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
2054 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2055 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2056 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2057 LOP, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
2058 { INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2059 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2060 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2061 LOP, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2062 },
2063 {
2064 /* TARGET_H8300H */
2065 /* 0 1 2 3 4 5 6 7 */
2066 /* 8 9 10 11 12 13 14 15 */
2067 /* 16 17 18 19 20 21 22 23 */
2068 /* 24 25 26 27 28 29 30 31 */
2069 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
2070 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
2071 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
2072 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
2073 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
2074 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC,
2075 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
2076 SPC, LOP, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
2077 { INL, INL, INL, INL, INL, LOP, LOP, LOP,
2078 SPC, LOP, LOP, LOP, LOP, LOP, LOP, LOP,
2079 SPC, SPC, SPC, SPC, LOP, LOP, LOP, LOP,
2080 SPC, LOP, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2081 },
2082 {
2083 /* TARGET_H8300S */
2084 /* 0 1 2 3 4 5 6 7 */
2085 /* 8 9 10 11 12 13 14 15 */
2086 /* 16 17 18 19 20 21 22 23 */
2087 /* 24 25 26 27 28 29 30 31 */
2088 { INL, INL, INL, INL, INL, INL, INL, INL,
2089 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
2090 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
2091 SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_ASHIFT */
2092 { INL, INL, INL, INL, INL, INL, INL, INL,
2093 INL, INL, INL, LOP, LOP, LOP, LOP, SPC,
2094 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
2095 SPC, SPC, LOP, LOP, ROT, ROT, ROT, SPC }, /* SHIFT_LSHIFTRT */
2096 { INL, INL, INL, INL, INL, INL, INL, INL,
2097 INL, INL, INL, LOP, LOP, LOP, LOP, LOP,
2098 SPC, SPC, SPC, SPC, SPC, SPC, LOP, LOP,
2099 SPC, SPC, LOP, LOP, LOP, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
2100 }
2101 };
2102
2103 #undef INL
2104 #undef ROT
2105 #undef LOP
2106 #undef SPC
2107
2108 struct shift_info {
2109 /* Shift algorithm. */
2110 enum shift_alg alg;
2111
2112 /* The number of bits to be shifted by shift1 and shift2. Valid
2113 when ALG is SHIFT_SPECIAL. */
2114 unsigned int remainder;
2115
2116 /* Special insn for a shift. Valid when ALG is SHIFT_SPECIAL. */
2117 const char *special;
2118
2119 /* Insn for a one-bit shift. Valid when ALG is either SHIFT_INLINE
2120 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2121 const char *shift1;
2122
2123 /* Insn for a two-bit shift. Valid when ALG is either SHIFT_INLINE
2124 or SHIFT_SPECIAL, and REMAINDER is non-zero. */
2125 const char *shift2;
2126
2127 /* Valid CC flags. */
2128 int cc_valid_p;
2129 };
2130
2131 static void get_shift_alg PARAMS ((enum shift_type,
2132 enum shift_mode, unsigned int,
2133 struct shift_info *));
2134
2135 /* Given SHIFT_TYPE, SHIFT_MODE, and shift count COUNT, determine the
2136 best algorithm for doing the shift. The assembler code is stored
2137 in the pointers in INFO. We don't achieve maximum efficiency in
2138 all cases, but the hooks are here to do so.
2139
2140 For now we just use lots of switch statements. Since we don't even come
2141 close to supporting all the cases, this is simplest. If this function ever
2142 gets too big, perhaps resort to a more table based lookup. Of course,
2143 at this point you may just wish to do it all in rtl.
2144
2145 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
2146 1,2,3,4 will be inlined (1,2 for SI). */
2147
2148 static void
2149 get_shift_alg (shift_type, shift_mode, count, info)
2150 enum shift_type shift_type;
2151 enum shift_mode shift_mode;
2152 unsigned int count;
2153 struct shift_info *info;
2154 {
2155 int cpu;
2156
2157 /* Find the target CPU. */
2158 if (TARGET_H8300)
2159 cpu = 0;
2160 else if (TARGET_H8300H)
2161 cpu = 1;
2162 else
2163 cpu = 2;
2164
2165 /* Find the shift algorithm. */
2166 switch (shift_mode)
2167 {
2168 case QIshift:
2169 if (GET_MODE_BITSIZE (QImode) <= count)
2170 info->alg = SHIFT_LOOP;
2171 else
2172 info->alg = shift_alg_qi[cpu][shift_type][count];
2173 break;
2174
2175 case HIshift:
2176 if (GET_MODE_BITSIZE (HImode) <= count)
2177 info->alg = SHIFT_LOOP;
2178 else
2179 info->alg = shift_alg_hi[cpu][shift_type][count];
2180 break;
2181
2182 case SIshift:
2183 if (GET_MODE_BITSIZE (SImode) <= count)
2184 info->alg = SHIFT_LOOP;
2185 else
2186 info->alg = shift_alg_si[cpu][shift_type][count];
2187 break;
2188
2189 default:
2190 abort ();
2191 }
2192
2193 /* Fill in INFO. Return unless we have SHIFT_SPECIAL. */
2194 switch (info->alg)
2195 {
2196 case SHIFT_INLINE:
2197 info->remainder = count;
2198 /* Fall through. */
2199
2200 case SHIFT_LOOP:
2201 /* It is up to the caller to know that looping clobbers cc. */
2202 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2203 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2204 info->cc_valid_p = shift_one[cpu_type][shift_type][shift_mode].cc_valid;
2205 goto end;
2206
2207 case SHIFT_ROT_AND:
2208 info->shift1 = rotate_one[cpu_type][shift_type][shift_mode];
2209 info->shift2 = rotate_two[shift_type][shift_mode];
2210 info->cc_valid_p = 0;
2211 goto end;
2212
2213 case SHIFT_SPECIAL:
2214 /* REMAINDER is 0 for most cases, so initialize it to 0. */
2215 info->remainder = 0;
2216 info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler;
2217 info->shift2 = shift_two[shift_type][shift_mode].assembler;
2218 info->cc_valid_p = 0;
2219 break;
2220 }
2221
2222 /* Here we only deal with SHIFT_SPECIAL. */
2223 switch (shift_mode)
2224 {
2225 case QIshift:
2226 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2227 through the entire value. */
2228 if (shift_type == SHIFT_ASHIFTRT && count == 7)
2229 {
2230 info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
2231 goto end;
2232 }
2233 abort ();
2234
2235 case HIshift:
2236 if (count == 7)
2237 {
2238 switch (shift_type)
2239 {
2240 case SHIFT_ASHIFT:
2241 if (TARGET_H8300)
2242 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";
2243 else
2244 info->special = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
2245 goto end;
2246 case SHIFT_LSHIFTRT:
2247 if (TARGET_H8300)
2248 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";
2249 else
2250 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
2251 goto end;
2252 case SHIFT_ASHIFTRT:
2253 info->special = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
2254 goto end;
2255 }
2256 }
2257 else if (8 <= count && count <= 12)
2258 {
2259 info->remainder = count - 8;
2260
2261 switch (shift_type)
2262 {
2263 case SHIFT_ASHIFT:
2264 info->special = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
2265 info->shift1 = "shal.b\t%t0";
2266 info->shift2 = "shal.b\t#2,%t0";
2267 goto end;
2268 case SHIFT_LSHIFTRT:
2269 info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
2270 info->shift1 = "shlr.b\t%s0";
2271 info->shift2 = "shlr.b\t#2,%s0";
2272 goto end;
2273 case SHIFT_ASHIFTRT:
2274 if (TARGET_H8300)
2275 info->special = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0";
2276 else
2277 info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0";
2278 info->shift1 = "shar.b\t%s0";
2279 info->shift2 = "shar.b\t#2,%s0";
2280 goto end;
2281 }
2282 }
2283 else if (count == 15 && shift_type == SHIFT_ASHIFTRT)
2284 {
2285 info->special = "shll\t%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
2286 goto end;
2287 }
2288 abort ();
2289
2290 case SIshift:
2291 if (count == 8 && TARGET_H8300)
2292 {
2293 switch (shift_type)
2294 {
2295 case SHIFT_ASHIFT:
2296 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";
2297 goto end;
2298 case SHIFT_LSHIFTRT:
2299 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";
2300 goto end;
2301 case SHIFT_ASHIFTRT:
2302 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";
2303 goto end;
2304 }
2305 }
2306 else if (count == 8 && !TARGET_H8300)
2307 {
2308 switch (shift_type)
2309 {
2310 case SHIFT_ASHIFT:
2311 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";
2312 goto end;
2313 case SHIFT_LSHIFTRT:
2314 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";
2315 goto end;
2316 case SHIFT_ASHIFTRT:
2317 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";
2318 goto end;
2319 }
2320 }
2321 else if (count == 15 && !TARGET_H8300)
2322 {
2323 switch (shift_type)
2324 {
2325 case SHIFT_ASHIFT:
2326 info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0";
2327 goto end;
2328 case SHIFT_LSHIFTRT:
2329 info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0";
2330 goto end;
2331 case SHIFT_ASHIFTRT:
2332 abort ();
2333 }
2334 }
2335 else if ((TARGET_H8300 && count == 16)
2336 || (TARGET_H8300H && 16 <= count && count <= 19)
2337 || (TARGET_H8300S && 16 <= count && count <= 21))
2338 {
2339 info->remainder = count - 16;
2340
2341 switch (shift_type)
2342 {
2343 case SHIFT_ASHIFT:
2344 info->special = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2345 info->shift1 = "shll.l\t%S0";
2346 info->shift2 = "shll.l\t#2,%S0";
2347 goto end;
2348 case SHIFT_LSHIFTRT:
2349 info->special = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
2350 info->shift1 = "shlr.l\t%S0";
2351 info->shift2 = "shlr.l\t#2,%S0";
2352 goto end;
2353 case SHIFT_ASHIFTRT:
2354 if (TARGET_H8300)
2355 info->special = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2356 else
2357 info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0";
2358 info->shift1 = "shar.l\t%S0";
2359 info->shift2 = "shar.l\t#2,%S0";
2360 goto end;
2361 }
2362 }
2363 else if ((TARGET_H8300H && count == 24)
2364 || (TARGET_H8300S && 24 <= count && count <= 25))
2365 {
2366 info->remainder = count - 24;
2367
2368 switch (shift_type)
2369 {
2370 case SHIFT_ASHIFT:
2371 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";
2372 info->shift1 = "shll.l\t%S0";
2373 info->shift2 = "shll.l\t#2,%S0";
2374 goto end;
2375 case SHIFT_LSHIFTRT:
2376 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
2377 info->shift1 = "shlr.l\t%S0";
2378 info->shift2 = "shlr.l\t#2,%S0";
2379 goto end;
2380 case SHIFT_ASHIFTRT:
2381 info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
2382 info->shift1 = "shar.l\t%S0";
2383 info->shift2 = "shar.l\t#2,%S0";
2384 goto end;
2385 }
2386 }
2387 else if (count == 31)
2388 {
2389 if (TARGET_H8300)
2390 {
2391 switch (shift_type)
2392 {
2393 case SHIFT_ASHIFT:
2394 info->special = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
2395 goto end;
2396 case SHIFT_LSHIFTRT:
2397 info->special = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
2398 goto end;
2399 case SHIFT_ASHIFTRT:
2400 info->special = "shll\t%z0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2401 goto end;
2402 }
2403 }
2404 else
2405 {
2406 switch (shift_type)
2407 {
2408 case SHIFT_ASHIFT:
2409 info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0";
2410 goto end;
2411 case SHIFT_LSHIFTRT:
2412 info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0";
2413 goto end;
2414 case SHIFT_ASHIFTRT:
2415 info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
2416 goto end;
2417 }
2418 }
2419 }
2420 abort ();
2421
2422 default:
2423 abort ();
2424 }
2425
2426 end:
2427 if (!TARGET_H8300S)
2428 info->shift2 = NULL;
2429 }
2430
2431 /* Emit the assembler code for doing shifts. */
2432
2433 const char *
2434 output_a_shift (insn, operands)
2435 rtx insn ATTRIBUTE_UNUSED;
2436 rtx *operands;
2437 {
2438 static int loopend_lab;
2439 rtx shift = operands[3];
2440 enum machine_mode mode = GET_MODE (shift);
2441 enum rtx_code code = GET_CODE (shift);
2442 enum shift_type shift_type;
2443 enum shift_mode shift_mode;
2444 struct shift_info info;
2445
2446 loopend_lab++;
2447
2448 switch (mode)
2449 {
2450 case QImode:
2451 shift_mode = QIshift;
2452 break;
2453 case HImode:
2454 shift_mode = HIshift;
2455 break;
2456 case SImode:
2457 shift_mode = SIshift;
2458 break;
2459 default:
2460 abort ();
2461 }
2462
2463 switch (code)
2464 {
2465 case ASHIFTRT:
2466 shift_type = SHIFT_ASHIFTRT;
2467 break;
2468 case LSHIFTRT:
2469 shift_type = SHIFT_LSHIFTRT;
2470 break;
2471 case ASHIFT:
2472 shift_type = SHIFT_ASHIFT;
2473 break;
2474 default:
2475 abort ();
2476 }
2477
2478 if (GET_CODE (operands[2]) != CONST_INT)
2479 {
2480 /* Indexing by reg, so have to loop and test at top. */
2481 output_asm_insn ("mov.b %X2,%X4", operands);
2482 fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab);
2483
2484 /* Get the assembler code to do one shift. */
2485 get_shift_alg (shift_type, shift_mode, 1, &info);
2486
2487 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2488 output_asm_insn (info.shift1, operands);
2489 output_asm_insn ("add #0xff,%X4", operands);
2490 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2491 fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
2492
2493 return "";
2494 }
2495 else
2496 {
2497 int n = INTVAL (operands[2]);
2498
2499 /* If the count is negative, make it 0. */
2500 if (n < 0)
2501 n = 0;
2502 /* If the count is too big, truncate it.
2503 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2504 do the intuitive thing. */
2505 else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
2506 n = GET_MODE_BITSIZE (mode);
2507
2508 get_shift_alg (shift_type, shift_mode, n, &info);
2509
2510 switch (info.alg)
2511 {
2512 case SHIFT_SPECIAL:
2513 output_asm_insn (info.special, operands);
2514 /* Fall through. */
2515
2516 case SHIFT_INLINE:
2517 n = info.remainder;
2518
2519 /* Emit two bit shifts first. */
2520 while (n > 1 && info.shift2 != NULL)
2521 {
2522 output_asm_insn (info.shift2, operands);
2523 n -= 2;
2524 }
2525
2526 /* Now emit one bit shifts for any residual. */
2527 while (n > 0)
2528 {
2529 output_asm_insn (info.shift1, operands);
2530 n -= 1;
2531 }
2532
2533 /* Keep track of CC. */
2534 if (info.cc_valid_p)
2535 {
2536 cc_status.value1 = operands[0];
2537 cc_status.flags |= info.cc_valid_p;
2538 }
2539 return "";
2540
2541 case SHIFT_ROT_AND:
2542 {
2543 int m = GET_MODE_BITSIZE (mode) - n;
2544 int mask = (shift_type == SHIFT_ASHIFT
2545 ? ((1 << (GET_MODE_BITSIZE (mode) - n)) - 1) << n
2546 : (1 << (GET_MODE_BITSIZE (mode) - n)) - 1);
2547 char insn_buf[200];
2548
2549 /* Not all possibilities of rotate are supported. They shouldn't
2550 be generated, but let's watch for 'em. */
2551 if (info.shift1 == 0)
2552 abort ();
2553
2554 /* Emit two bit rotates first. */
2555 while (m > 1 && info.shift2 != NULL)
2556 {
2557 output_asm_insn (info.shift2, operands);
2558 m -= 2;
2559 }
2560
2561 /* Now single bit rotates for any residual. */
2562 while (m > 0)
2563 {
2564 output_asm_insn (info.shift1, operands);
2565 m -= 1;
2566 }
2567
2568 /* Now mask off the high bits. */
2569 if (TARGET_H8300)
2570 {
2571 switch (mode)
2572 {
2573 case QImode:
2574 sprintf (insn_buf, "and\t#%d,%%X0", mask);
2575 cc_status.value1 = operands[0];
2576 cc_status.flags |= CC_NO_CARRY;
2577 break;
2578 case HImode:
2579 sprintf (insn_buf, "and\t#%d,%%s0\n\tand\t#%d,%%t0",
2580 mask & 255, mask >> 8);
2581 break;
2582 case SImode:
2583 abort ();
2584 default:
2585 break;
2586 }
2587 }
2588 else
2589 {
2590 sprintf (insn_buf, "and.%c\t#%d,%%%c0",
2591 "bwl"[shift_mode], mask,
2592 mode == QImode ? 'X' : mode == HImode ? 'T' : 'S');
2593 cc_status.value1 = operands[0];
2594 cc_status.flags |= CC_NO_CARRY;
2595 }
2596 output_asm_insn (insn_buf, operands);
2597 return "";
2598 }
2599
2600 case SHIFT_LOOP:
2601 /* A loop to shift by a "large" constant value.
2602 If we have shift-by-2 insns, use them. */
2603 if (info.shift2 != NULL)
2604 {
2605 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
2606 names_big[REGNO (operands[4])]);
2607 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2608 output_asm_insn (info.shift2, operands);
2609 output_asm_insn ("add #0xff,%X4", operands);
2610 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2611 if (n % 2)
2612 output_asm_insn (info.shift1, operands);
2613 }
2614 else
2615 {
2616 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
2617 names_big[REGNO (operands[4])]);
2618 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2619 output_asm_insn (info.shift1, operands);
2620 output_asm_insn ("add #0xff,%X4", operands);
2621 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2622 }
2623 return "";
2624
2625 default:
2626 abort ();
2627 }
2628 }
2629 }
2630 \f
2631 /* A rotation by a non-constant will cause a loop to be generated, in
2632 which a rotation by one bit is used. A rotation by a constant,
2633 including the one in the loop, will be taken care of by
2634 emit_a_rotate () at the insn emit time. */
2635
2636 int
2637 expand_a_rotate (code, operands)
2638 enum rtx_code code;
2639 rtx operands[];
2640 {
2641 rtx dst = operands[0];
2642 rtx src = operands[1];
2643 rtx rotate_amount = operands[2];
2644 enum machine_mode mode = GET_MODE (dst);
2645 rtx tmp;
2646
2647 /* We rotate in place. */
2648 emit_move_insn (dst, src);
2649
2650 if (GET_CODE (rotate_amount) != CONST_INT)
2651 {
2652 rtx counter = gen_reg_rtx (QImode);
2653 rtx start_label = gen_label_rtx ();
2654 rtx end_label = gen_label_rtx ();
2655
2656 /* If the rotate amount is less than or equal to 0,
2657 we go out of the loop. */
2658 emit_cmp_and_jump_insns (rotate_amount, GEN_INT (0), LE, NULL_RTX,
2659 QImode, 0, end_label);
2660
2661 /* Initialize the loop counter. */
2662 emit_move_insn (counter, rotate_amount);
2663
2664 emit_label (start_label);
2665
2666 /* Rotate by one bit. */
2667 tmp = gen_rtx (code, mode, dst, GEN_INT (1));
2668 emit_insn (gen_rtx_SET (mode, dst, tmp));
2669
2670 /* Decrement the counter by 1. */
2671 tmp = gen_rtx_PLUS (QImode, counter, GEN_INT (-1));
2672 emit_insn (gen_rtx_SET (VOIDmode, counter, tmp));
2673
2674 /* If the loop counter is non-zero, we go back to the beginning
2675 of the loop. */
2676 emit_cmp_and_jump_insns (counter, GEN_INT (0), NE, NULL_RTX, QImode, 1,
2677 start_label);
2678
2679 emit_label (end_label);
2680 }
2681 else
2682 {
2683 /* Rotate by AMOUNT bits. */
2684 tmp = gen_rtx (code, mode, dst, rotate_amount);
2685 emit_insn (gen_rtx_SET (mode, dst, tmp));
2686 }
2687
2688 return 1;
2689 }
2690
2691 /* Emit rotate insns. */
2692
2693 const char *
2694 emit_a_rotate (code, operands)
2695 enum rtx_code code;
2696 rtx *operands;
2697 {
2698 rtx dst = operands[0];
2699 rtx rotate_amount = operands[2];
2700 enum shift_mode rotate_mode;
2701 enum shift_type rotate_type;
2702 const char *insn_buf;
2703 int bits;
2704 int amount;
2705 enum machine_mode mode = GET_MODE (dst);
2706
2707 if (GET_CODE (rotate_amount) != CONST_INT)
2708 abort ();
2709
2710 switch (mode)
2711 {
2712 case QImode:
2713 rotate_mode = QIshift;
2714 break;
2715 case HImode:
2716 rotate_mode = HIshift;
2717 break;
2718 case SImode:
2719 rotate_mode = SIshift;
2720 break;
2721 default:
2722 abort ();
2723 }
2724
2725 switch (code)
2726 {
2727 case ROTATERT:
2728 rotate_type = SHIFT_ASHIFT;
2729 break;
2730 case ROTATE:
2731 rotate_type = SHIFT_LSHIFTRT;
2732 break;
2733 default:
2734 abort ();
2735 }
2736
2737 amount = INTVAL (rotate_amount);
2738
2739 /* Clean up AMOUNT. */
2740 if (amount < 0)
2741 amount = 0;
2742 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
2743 amount = GET_MODE_BITSIZE (mode);
2744
2745 /* Determine the faster direction. After this phase, amount will be
2746 at most a half of GET_MODE_BITSIZE (mode). */
2747 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / 2U)
2748 {
2749 /* Flip the direction. */
2750 amount = GET_MODE_BITSIZE (mode) - amount;
2751 rotate_type =
2752 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
2753 }
2754
2755 /* See if a byte swap (in HImode) or a word swap (in SImode) can
2756 boost up the rotation. */
2757 if ((mode == HImode && TARGET_H8300 && amount >= 5)
2758 || (mode == HImode && TARGET_H8300H && amount >= 6)
2759 || (mode == HImode && TARGET_H8300S && amount == 8)
2760 || (mode == SImode && TARGET_H8300H && amount >= 10)
2761 || (mode == SImode && TARGET_H8300S && amount >= 13))
2762 {
2763 switch (mode)
2764 {
2765 case HImode:
2766 /* This code works on any family. */
2767 insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
2768 output_asm_insn (insn_buf, operands);
2769 break;
2770
2771 case SImode:
2772 /* This code works on the H8/300H and H8/S. */
2773 insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
2774 output_asm_insn (insn_buf, operands);
2775 break;
2776
2777 default:
2778 abort ();
2779 }
2780
2781 /* Adjust AMOUNT and flip the direction. */
2782 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
2783 rotate_type =
2784 (rotate_type == SHIFT_ASHIFT) ? SHIFT_LSHIFTRT : SHIFT_ASHIFT;
2785 }
2786
2787 /* Emit rotate insns. */
2788 for (bits = TARGET_H8300S ? 2 : 1; bits > 0; bits /= 2)
2789 {
2790 if (bits == 2)
2791 insn_buf = rotate_two[rotate_type][rotate_mode];
2792 else
2793 insn_buf = rotate_one[cpu_type][rotate_type][rotate_mode];
2794
2795 for (; amount >= bits; amount -= bits)
2796 output_asm_insn (insn_buf, operands);
2797 }
2798
2799 return "";
2800 }
2801 \f
2802 /* Fix the operands of a gen_xxx so that it could become a bit
2803 operating insn. */
2804
2805 int
2806 fix_bit_operand (operands, what, type)
2807 rtx *operands;
2808 int what;
2809 enum rtx_code type;
2810 {
2811 /* The bit_operand predicate accepts any memory during RTL generation, but
2812 only 'U' memory afterwards, so if this is a MEM operand, we must force
2813 it to be valid for 'U' by reloading the address. */
2814
2815 if (GET_CODE (operands[2]) == CONST_INT)
2816 {
2817 if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), what))
2818 {
2819 /* Ok to have a memory dest. */
2820 if (GET_CODE (operands[0]) == MEM
2821 && !EXTRA_CONSTRAINT (operands[0], 'U'))
2822 {
2823 rtx mem = gen_rtx_MEM (GET_MODE (operands[0]),
2824 copy_to_mode_reg (Pmode,
2825 XEXP (operands[0], 0)));
2826 MEM_COPY_ATTRIBUTES (mem, operands[0]);
2827 operands[0] = mem;
2828 }
2829
2830 if (GET_CODE (operands[1]) == MEM
2831 && !EXTRA_CONSTRAINT (operands[1], 'U'))
2832 {
2833 rtx mem = gen_rtx_MEM (GET_MODE (operands[1]),
2834 copy_to_mode_reg (Pmode,
2835 XEXP (operands[1], 0)));
2836 MEM_COPY_ATTRIBUTES (mem, operands[0]);
2837 operands[1] = mem;
2838 }
2839 return 0;
2840 }
2841 }
2842
2843 /* Dest and src op must be register. */
2844
2845 operands[1] = force_reg (QImode, operands[1]);
2846 {
2847 rtx res = gen_reg_rtx (QImode);
2848 emit_insn (gen_rtx_SET (VOIDmode, res,
2849 gen_rtx (type, QImode, operands[1], operands[2])));
2850 emit_insn (gen_rtx_SET (VOIDmode, operands[0], res));
2851 }
2852 return 1;
2853 }
2854
2855 /* Return nonzero if FUNC is an interrupt function as specified
2856 by the "interrupt" attribute. */
2857
2858 static int
2859 h8300_interrupt_function_p (func)
2860 tree func;
2861 {
2862 tree a;
2863
2864 if (TREE_CODE (func) != FUNCTION_DECL)
2865 return 0;
2866
2867 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func));
2868 return a != NULL_TREE;
2869 }
2870
2871 /* Return nonzero if FUNC is an OS_Task function as specified
2872 by the "OS_Task" attribute. */
2873
2874 static int
2875 h8300_os_task_function_p (func)
2876 tree func;
2877 {
2878 tree a;
2879
2880 if (TREE_CODE (func) != FUNCTION_DECL)
2881 return 0;
2882
2883 a = lookup_attribute ("OS_Task", DECL_ATTRIBUTES (func));
2884 return a != NULL_TREE;
2885 }
2886
2887 /* Return nonzero if FUNC is a monitor function as specified
2888 by the "monitor" attribute. */
2889
2890 static int
2891 h8300_monitor_function_p (func)
2892 tree func;
2893 {
2894 tree a;
2895
2896 if (TREE_CODE (func) != FUNCTION_DECL)
2897 return 0;
2898
2899 a = lookup_attribute ("monitor", DECL_ATTRIBUTES (func));
2900 return a != NULL_TREE;
2901 }
2902
2903 /* Return nonzero if FUNC is a function that should be called
2904 through the function vector. */
2905
2906 int
2907 h8300_funcvec_function_p (func)
2908 tree func;
2909 {
2910 tree a;
2911
2912 if (TREE_CODE (func) != FUNCTION_DECL)
2913 return 0;
2914
2915 a = lookup_attribute ("function_vector", DECL_ATTRIBUTES (func));
2916 return a != NULL_TREE;
2917 }
2918
2919 /* Return nonzero if DECL is a variable that's in the eight bit
2920 data area. */
2921
2922 int
2923 h8300_eightbit_data_p (decl)
2924 tree decl;
2925 {
2926 tree a;
2927
2928 if (TREE_CODE (decl) != VAR_DECL)
2929 return 0;
2930
2931 a = lookup_attribute ("eightbit_data", DECL_ATTRIBUTES (decl));
2932 return a != NULL_TREE;
2933 }
2934
2935 /* Return nonzero if DECL is a variable that's in the tiny
2936 data area. */
2937
2938 int
2939 h8300_tiny_data_p (decl)
2940 tree decl;
2941 {
2942 tree a;
2943
2944 if (TREE_CODE (decl) != VAR_DECL)
2945 return 0;
2946
2947 a = lookup_attribute ("tiny_data", DECL_ATTRIBUTES (decl));
2948 return a != NULL_TREE;
2949 }
2950
2951 /* Supported attributes:
2952
2953 interrupt_handler: output a prologue and epilogue suitable for an
2954 interrupt handler.
2955
2956 function_vector: This function should be called through the
2957 function vector.
2958
2959 eightbit_data: This variable lives in the 8-bit data area and can
2960 be referenced with 8-bit absolute memory addresses.
2961
2962 tiny_data: This variable lives in the tiny data area and can be
2963 referenced with 16-bit absolute memory references. */
2964
2965 const struct attribute_spec h8300_attribute_table[] =
2966 {
2967 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
2968 { "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
2969 { "OS_Task", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
2970 { "monitor", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
2971 { "function_vector", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
2972 { "eightbit_data", 0, 0, true, false, false, h8300_handle_eightbit_data_attribute },
2973 { "tiny_data", 0, 0, true, false, false, h8300_handle_tiny_data_attribute },
2974 { NULL, 0, 0, false, false, false, NULL }
2975 };
2976
2977
2978 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
2979 struct attribute_spec.handler. */
2980 static tree
2981 h8300_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
2982 tree *node;
2983 tree name;
2984 tree args ATTRIBUTE_UNUSED;
2985 int flags ATTRIBUTE_UNUSED;
2986 bool *no_add_attrs;
2987 {
2988 if (TREE_CODE (*node) != FUNCTION_DECL)
2989 {
2990 warning ("`%s' attribute only applies to functions",
2991 IDENTIFIER_POINTER (name));
2992 *no_add_attrs = true;
2993 }
2994
2995 return NULL_TREE;
2996 }
2997
2998 /* Handle an "eightbit_data" attribute; arguments as in
2999 struct attribute_spec.handler. */
3000 static tree
3001 h8300_handle_eightbit_data_attribute (node, name, args, flags, no_add_attrs)
3002 tree *node;
3003 tree name;
3004 tree args ATTRIBUTE_UNUSED;
3005 int flags ATTRIBUTE_UNUSED;
3006 bool *no_add_attrs;
3007 {
3008 tree decl = *node;
3009
3010 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
3011 {
3012 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
3013 }
3014 else
3015 {
3016 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3017 *no_add_attrs = true;
3018 }
3019
3020 return NULL_TREE;
3021 }
3022
3023 /* Handle an "tiny_data" attribute; arguments as in
3024 struct attribute_spec.handler. */
3025 static tree
3026 h8300_handle_tiny_data_attribute (node, name, args, flags, no_add_attrs)
3027 tree *node;
3028 tree name;
3029 tree args ATTRIBUTE_UNUSED;
3030 int flags ATTRIBUTE_UNUSED;
3031 bool *no_add_attrs;
3032 {
3033 tree decl = *node;
3034
3035 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
3036 {
3037 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
3038 }
3039 else
3040 {
3041 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
3042 *no_add_attrs = true;
3043 }
3044
3045 return NULL_TREE;
3046 }
3047
3048 void
3049 h8300_encode_label (decl)
3050 tree decl;
3051 {
3052 const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
3053 int len = strlen (str);
3054 char *newstr = alloca (len + 2);
3055
3056 newstr[0] = '&';
3057 strcpy (&newstr[1], str);
3058
3059 XSTR (XEXP (DECL_RTL (decl), 0), 0) =
3060 ggc_alloc_string (newstr, len + 1);
3061 }
3062
3063 const char *
3064 output_simode_bld (bild, operands)
3065 int bild;
3066 rtx operands[];
3067 {
3068 /* Clear the destination register. */
3069 if (TARGET_H8300H || TARGET_H8300S)
3070 output_asm_insn ("sub.l\t%S0,%S0", operands);
3071 else
3072 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
3073
3074 /* Now output the bit load or bit inverse load, and store it in
3075 the destination. */
3076 if (bild)
3077 output_asm_insn ("bild\t%Z2,%Y1\n\tbst\t#0,%w0", operands);
3078 else
3079 output_asm_insn ("bld\t%Z2,%Y1\n\tbst\t#0,%w0", operands);
3080
3081 /* All done. */
3082 return "";
3083 }
3084
3085 /* Given INSN and its current length LENGTH, return the adjustment
3086 (in bytes) to correctly compute INSN's length.
3087
3088 We use this to get the lengths of various memory references correct. */
3089
3090 int
3091 h8300_adjust_insn_length (insn, length)
3092 rtx insn;
3093 int length ATTRIBUTE_UNUSED;
3094 {
3095 rtx pat = PATTERN (insn);
3096
3097 /* We must filter these out before calling get_attr_adjust_length. */
3098 if (GET_CODE (pat) == USE
3099 || GET_CODE (pat) == CLOBBER
3100 || GET_CODE (pat) == SEQUENCE
3101 || GET_CODE (pat) == ADDR_VEC
3102 || GET_CODE (pat) == ADDR_DIFF_VEC)
3103 return 0;
3104
3105 if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO)
3106 return 0;
3107
3108 /* Adjust length for reg->mem and mem->reg copies. */
3109 if (GET_CODE (pat) == SET
3110 && (GET_CODE (SET_SRC (pat)) == MEM
3111 || GET_CODE (SET_DEST (pat)) == MEM))
3112 {
3113 /* This insn might need a length adjustment. */
3114 rtx addr;
3115
3116 if (GET_CODE (SET_SRC (pat)) == MEM)
3117 addr = XEXP (SET_SRC (pat), 0);
3118 else
3119 addr = XEXP (SET_DEST (pat), 0);
3120
3121 /* On the H8/300, only one adjustment is necessary; if the
3122 address mode is register indirect, then this insn is two
3123 bytes shorter than indicated in the machine description. */
3124 if (TARGET_H8300 && GET_CODE (addr) == REG)
3125 return -2;
3126
3127 /* On the H8/300H and H8/S, register indirect is 6 bytes shorter than
3128 indicated in the machine description. */
3129 if ((TARGET_H8300H || TARGET_H8300S)
3130 && GET_CODE (addr) == REG)
3131 return -6;
3132
3133 /* On the H8/300H and H8/S, reg + d, for small displacements is
3134 4 bytes shorter than indicated in the machine description. */
3135 if ((TARGET_H8300H || TARGET_H8300S)
3136 && GET_CODE (addr) == PLUS
3137 && GET_CODE (XEXP (addr, 0)) == REG
3138 && GET_CODE (XEXP (addr, 1)) == CONST_INT
3139 && INTVAL (XEXP (addr, 1)) > -32768
3140 && INTVAL (XEXP (addr, 1)) < 32767)
3141 return -4;
3142
3143 /* On the H8/300H and H8/S, abs:16 is two bytes shorter than the
3144 more general abs:24. */
3145 if ((TARGET_H8300H || TARGET_H8300S)
3146 && GET_CODE (addr) == SYMBOL_REF
3147 && TINY_DATA_NAME_P (XSTR (addr, 0)))
3148 return -2;
3149 }
3150
3151 /* Loading some constants needs adjustment. */
3152 if (GET_CODE (pat) == SET
3153 && GET_CODE (SET_SRC (pat)) == CONST_INT
3154 && GET_MODE (SET_DEST (pat)) == SImode
3155 && INTVAL (SET_SRC (pat)) != 0)
3156 {
3157 int val = INTVAL (SET_SRC (pat));
3158
3159 if (TARGET_H8300
3160 && ((val & 0xffff) == 0
3161 || ((val >> 16) & 0xffff) == 0))
3162 return -2;
3163
3164 if (TARGET_H8300H || TARGET_H8300S)
3165 {
3166 if (val == (val & 0xff)
3167 || val == (val & 0xff00))
3168 return -6;
3169
3170 if (val == -4 || val == -2 || val == -1)
3171 return -6;
3172 }
3173 }
3174
3175 /* Shifts need various adjustments. */
3176 if (GET_CODE (pat) == PARALLEL
3177 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
3178 && (GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFTRT
3179 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == LSHIFTRT
3180 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFT))
3181 {
3182 rtx src = SET_SRC (XVECEXP (pat, 0, 0));
3183 enum machine_mode mode = GET_MODE (src);
3184 int shift;
3185
3186 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3187 return 0;
3188
3189 shift = INTVAL (XEXP (src, 1));
3190 /* According to ANSI, negative shift is undefined. It is
3191 considered to be zero in this case (see function
3192 output_a_shift above). */
3193 if (shift < 0)
3194 shift = 0;
3195
3196 /* QImode shifts by small constants take one insn
3197 per shift. So the adjustment is 20 (md length) -
3198 # shifts * 2. */
3199 if (mode == QImode && shift <= 4)
3200 return -(20 - shift * 2);
3201
3202 /* Similarly for HImode and SImode shifts by small constants on
3203 the H8/300H and H8/S. */
3204 if ((TARGET_H8300H || TARGET_H8300S)
3205 && (mode == HImode || mode == SImode) && shift <= 4)
3206 return -(20 - shift * 2);
3207
3208 /* HImode shifts by small constants for the H8/300. */
3209 if (mode == HImode && shift <= 4)
3210 return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 2 : 4)));
3211
3212 /* SImode shifts by small constants for the H8/300. */
3213 if (mode == SImode && shift <= 2)
3214 return -(20 - (shift * (GET_CODE (src) == ASHIFT ? 6 : 8)));
3215
3216 /* XXX ??? Could check for more shift/rotate cases here. */
3217 }
3218
3219 /* Rotations need various adjustments. */
3220 if (GET_CODE (pat) == SET
3221 && (GET_CODE (SET_SRC (pat)) == ROTATE
3222 || GET_CODE (SET_SRC (pat)) == ROTATERT))
3223 {
3224 rtx src = SET_SRC (pat);
3225 enum machine_mode mode = GET_MODE (src);
3226 int amount;
3227 int states = 0;
3228
3229 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3230 return 0;
3231
3232 amount = INTVAL (XEXP (src, 1));
3233
3234 /* Clean up AMOUNT. */
3235 if (amount < 0)
3236 amount = 0;
3237 if ((unsigned int) amount > GET_MODE_BITSIZE (mode))
3238 amount = GET_MODE_BITSIZE (mode);
3239
3240 /* Determine the faster direction. After this phase, amount
3241 will be at most a half of GET_MODE_BITSIZE (mode). */
3242 if ((unsigned int) amount > GET_MODE_BITSIZE (mode) / 2U)
3243 /* Flip the direction. */
3244 amount = GET_MODE_BITSIZE (mode) - amount;
3245
3246 /* See if a byte swap (in HImode) or a word swap (in SImode) can
3247 boost up the rotation. */
3248 if ((mode == HImode && TARGET_H8300 && amount >= 5)
3249 || (mode == HImode && TARGET_H8300H && amount >= 6)
3250 || (mode == HImode && TARGET_H8300S && amount == 8)
3251 || (mode == SImode && TARGET_H8300H && amount >= 10)
3252 || (mode == SImode && TARGET_H8300S && amount >= 13))
3253 {
3254 /* Adjust AMOUNT and flip the direction. */
3255 amount = GET_MODE_BITSIZE (mode) / 2 - amount;
3256 states += 6;
3257 }
3258
3259 /* We use 2-bit rotatations on the H8/S. */
3260 if (TARGET_H8300S)
3261 amount = amount / 2 + amount % 2;
3262
3263 /* The H8/300 uses three insns to rotate one bit, taking 6
3264 states. */
3265 states += amount * ((TARGET_H8300 && mode == HImode) ? 6 : 2);
3266
3267 return -(20 - states);
3268 }
3269
3270 return 0;
3271 }
3272
3273 #ifndef OBJECT_FORMAT_ELF
3274 static void
3275 h8300_asm_named_section (name, flags)
3276 const char *name;
3277 unsigned int flags ATTRIBUTE_UNUSED;
3278 {
3279 /* ??? Perhaps we should be using default_coff_asm_named_section. */
3280 fprintf (asm_out_file, "\t.section %s\n", name);
3281 }
3282 #endif /* ! OBJECT_FORMAT_ELF */
This page took 0.187067 seconds and 6 git commands to generate.