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