]> gcc.gnu.org Git - gcc.git/blame - gcc/config/h8300/h8300.c
Change HANDLE_PRAGMA macro so that it supports USE_CPPLIB
[gcc.git] / gcc / config / h8300 / h8300.c
CommitLineData
07aae5c2 1/* Subroutines for insn-output.c for Hitachi H8/300.
e6bcfef9 2 Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 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 1027 'M' turn a 'M' constant into its negative mod 2.
48837e29 1028 'P' if operand is incing/decing sp, print .w, otherwise .b.
15dc331e
JL
1029 'R' print operand as a byte:8 address if appropriate, else fall back to
1030 'X' handling.
48837e29 1031 'S' print operand as a long word
07aae5c2 1032 'T' print operand as a word
48837e29
DE
1033 'U' if operand is incing/decing sp, print l, otherwise nothing.
1034 'V' find the set bit, and print its number.
1035 'W' find the clear bit, and print its number.
1036 'X' print operand as a byte
07aae5c2 1037 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
15dc331e 1038 If this operand isn't a register, fall back to 'R' handling.
48837e29
DE
1039 'Z' print int & 7.
1040 'b' print the bit opcode
1041 'c' print the ibit opcode
1042 'd' bcc if EQ, bcs if NE
1043 'e' first word of 32 bit value - if reg, then least reg. if mem
1044 then least. if const then most sig word
1045 'f' second word of 32 bit value - if reg, then biggest reg. if mem
1046 then +2. if const then least sig word
1047 'g' bcs if EQ, bcc if NE
07aae5c2
SC
1048 'j' print operand as condition code.
1049 'k' print operand as reverse condition code.
48837e29
DE
1050 's' print as low byte of 16 bit value
1051 't' print as high byte of 16 bit value
1052 'w' print as low byte of 32 bit value
1053 'x' print as 2nd byte of 32 bit value
1054 'y' print as 3rd byte of 32 bit value
1055 'z' print as msb of 32 bit value
1056*/
07aae5c2
SC
1057
1058/* Return assembly language string which identifies a comparison type. */
1059
48837e29 1060static char *
07aae5c2
SC
1061cond_string (code)
1062 enum rtx_code code;
1063{
1064 switch (code)
1065 {
1066 case NE:
1067 return "ne";
1068 case EQ:
1069 return "eq";
1070 case GE:
1071 return "ge";
1072 case GT:
1073 return "gt";
1074 case LE:
1075 return "le";
1076 case LT:
1077 return "lt";
1078 case GEU:
1079 return "hs";
1080 case GTU:
1081 return "hi";
1082 case LEU:
1083 return "ls";
1084 case LTU:
1085 return "lo";
1086 default:
1087 abort ();
1088 }
1089}
1090
1091/* Print operand X using operand code CODE to assembly language output file
1092 FILE. */
1093
1094void
1095print_operand (file, x, code)
1096 FILE *file;
1097 rtx x;
1098 int code;
1099{
07aae5c2
SC
1100 /* This is used for communication between the 'P' and 'U' codes. */
1101 static char *last_p;
1102
269c14e1 1103 /* This is used for communication between codes V,W,Z and Y. */
07aae5c2
SC
1104 static int bitint;
1105
1106 switch (code)
1107 {
48837e29 1108 case 'A':
07aae5c2 1109 if (GET_CODE (x) == REG)
48837e29 1110 fprintf (file, "%s", h8_reg_names[REGNO (x)]);
07aae5c2
SC
1111 else
1112 goto def;
1113 break;
48837e29
DE
1114 case 'C':
1115 fprintf (file, "#%d", INTVAL (x) - 2);
1116 break;
1117 case 'E':
1118 switch (GET_CODE (x))
1119 {
1120 case REG:
1121 fprintf (file, "%sl", names_big[REGNO (x)]);
1122 break;
1123 case CONST_INT:
1124 fprintf (file, "#%d", (-INTVAL (x)) & 0xff);
1125 break;
1126 default:
1127 abort ();
1128 }
1129 break;
1130 case 'F':
1131 switch (GET_CODE (x))
1132 {
1133 case REG:
1134 fprintf (file, "%sh", names_big[REGNO (x)]);
1135 break;
1136 case CONST_INT:
1137 fprintf (file, "#%d", ((-INTVAL (x)) & 0xff00) >> 8);
1138 break;
1139 default:
1140 abort ();
1141 }
1142 break;
07aae5c2
SC
1143 case 'G':
1144 if (GET_CODE (x) != CONST_INT)
1145 abort ();
1146 fprintf (file, "#%d", 0xff & (-INTVAL (x)));
1147 break;
48837e29
DE
1148 case 'M':
1149 /* For 3/-3 and 4/-4, the other 2 is handled separately. */
1150 switch (INTVAL (x))
1151 {
1152 case 2:
1153 case 4:
1154 case -2:
1155 case -4:
1156 fprintf (file, "#2");
1157 break;
1158 case 1:
1159 case 3:
1160 case -1:
1161 case -3:
1162 fprintf (file, "#1");
1163 break;
1164 default:
1165 abort ();
1166 }
07aae5c2 1167 break;
48837e29
DE
1168 case 'P':
1169 if (REGNO (XEXP (XEXP (x, 0), 0)) == STACK_POINTER_REGNUM)
1170 {
1171 last_p = "";
1172 fprintf (file, ".w");
1173 }
07aae5c2 1174 else
48837e29
DE
1175 {
1176 last_p = "l";
1177 fprintf (file, ".b");
1178 }
07aae5c2 1179 break;
48837e29
DE
1180 case 'S':
1181 if (GET_CODE (x) == REG)
1182 fprintf (file, "%s", names_extended[REGNO (x)]);
07aae5c2 1183 else
48837e29 1184 goto def;
07aae5c2 1185 break;
48837e29
DE
1186 case 'T':
1187 if (GET_CODE (x) == REG)
1188 fprintf (file, "%s", names_big[REGNO (x)]);
07aae5c2 1189 else
48837e29 1190 goto def;
07aae5c2 1191 break;
48837e29
DE
1192 case 'U':
1193 fprintf (file, "%s%s", names_big[REGNO (x)], last_p);
07aae5c2 1194 break;
48837e29
DE
1195 case 'V':
1196 bitint = exact_log2 (INTVAL (x));
1197 if (bitint == -1)
07aae5c2 1198 abort ();
07aae5c2
SC
1199 fprintf (file, "#%d", bitint & 7);
1200 break;
48837e29 1201 case 'W':
07aae5c2
SC
1202 bitint = exact_log2 ((~INTVAL (x)) & 0xff);
1203 if (bitint == -1)
1204 abort ();
1205 fprintf (file, "#%d", bitint & 7);
1206 break;
15dc331e 1207 case 'R':
48837e29
DE
1208 case 'X':
1209 if (GET_CODE (x) == REG)
1210 fprintf (file, "%s", byte_reg (x, 0));
1211 else
1212 goto def;
1213 break;
1214 case 'Y':
07aae5c2
SC
1215 if (bitint == -1)
1216 abort ();
48837e29
DE
1217 if (GET_CODE (x) == REG)
1218 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
1219 else
15dc331e 1220 print_operand (file, x, 'R');
48837e29
DE
1221 bitint = -1;
1222 break;
1223 case 'Z':
1224 bitint = INTVAL (x);
07aae5c2
SC
1225 fprintf (file, "#%d", bitint & 7);
1226 break;
48837e29
DE
1227 case 'b':
1228 switch (GET_CODE (x))
07aae5c2 1229 {
48837e29
DE
1230 case IOR:
1231 fprintf (file, "bor");
1232 break;
1233 case XOR:
1234 fprintf (file, "bxor");
1235 break;
1236 case AND:
1237 fprintf (file, "band");
1238 break;
07aae5c2 1239 }
48837e29
DE
1240 break;
1241 case 'c':
1242 switch (GET_CODE (x))
07aae5c2 1243 {
48837e29
DE
1244 case IOR:
1245 fprintf (file, "bior");
1246 break;
1247 case XOR:
1248 fprintf (file, "bixor");
1249 break;
1250 case AND:
1251 fprintf (file, "biand");
1252 break;
07aae5c2
SC
1253 }
1254 break;
48837e29
DE
1255 case 'd':
1256 switch (GET_CODE (x))
07aae5c2 1257 {
48837e29
DE
1258 case EQ:
1259 fprintf (file, "bcc");
07aae5c2 1260 break;
48837e29
DE
1261 case NE:
1262 fprintf (file, "bcs");
07aae5c2 1263 break;
07aae5c2
SC
1264 default:
1265 abort ();
1266 }
1267 break;
07aae5c2
SC
1268 case 'e':
1269 switch (GET_CODE (x))
1270 {
1271 case REG:
48837e29
DE
1272 if (TARGET_H8300)
1273 fprintf (file, "%s", names_big[REGNO (x)]);
1274 else
1275 fprintf (file, "%s", names_upper_extended[REGNO (x)]);
07aae5c2
SC
1276 break;
1277 case MEM:
1278 x = adj_offsettable_operand (x, 0);
1279 print_operand (file, x, 0);
1280 break;
1281 case CONST_INT:
1282 fprintf (file, "#%d", ((INTVAL (x) >> 16) & 0xffff));
1283 break;
808fbfac
JL
1284 case CONST_DOUBLE:
1285 {
1286 long val;
1287 REAL_VALUE_TYPE rv;
1288 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1289 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1290 fprintf (file, "#%d", ((val >> 16) & 0xffff));
1291 break;
1292 }
07aae5c2
SC
1293 default:
1294 abort ();
1295 break;
1296 }
1297 break;
07aae5c2
SC
1298 case 'f':
1299 switch (GET_CODE (x))
1300 {
1301 case REG:
48837e29
DE
1302 if (TARGET_H8300)
1303 fprintf (file, "%s", names_big[REGNO (x) + 1]);
1304 else
1305 fprintf (file, "%s", names_big[REGNO (x)]);
07aae5c2 1306 break;
07aae5c2
SC
1307 case MEM:
1308 x = adj_offsettable_operand (x, 2);
1309 print_operand (file, x, 0);
1310 break;
07aae5c2
SC
1311 case CONST_INT:
1312 fprintf (file, "#%d", INTVAL (x) & 0xffff);
1313 break;
808fbfac
JL
1314 case CONST_DOUBLE:
1315 {
1316 long val;
1317 REAL_VALUE_TYPE rv;
1318 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1319 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1320 fprintf (file, "#%d", (val & 0xffff));
1321 break;
1322 }
07aae5c2
SC
1323 default:
1324 abort ();
1325 }
1326 break;
48837e29 1327 case 'g':
07aae5c2
SC
1328 switch (GET_CODE (x))
1329 {
48837e29
DE
1330 case NE:
1331 fprintf (file, "bcc");
07aae5c2 1332 break;
48837e29
DE
1333 case EQ:
1334 fprintf (file, "bcs");
07aae5c2 1335 break;
07aae5c2
SC
1336 default:
1337 abort ();
1338 }
1339 break;
07aae5c2
SC
1340 case 'j':
1341 asm_fprintf (file, cond_string (GET_CODE (x)));
1342 break;
07aae5c2
SC
1343 case 'k':
1344 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
1345 break;
48837e29
DE
1346 case 's':
1347 if (GET_CODE (x) == CONST_INT)
1348 fprintf (file, "#%d", (INTVAL (x)) & 0xff);
1349 else
1350 fprintf (file, "%s", byte_reg (x, 0));
1351 break;
1352 case 't':
1353 if (GET_CODE (x) == CONST_INT)
1354 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1355 else
1356 fprintf (file, "%s", byte_reg (x, 1));
1357 break;
1358 case 'u':
1359 if (GET_CODE (x) != CONST_INT)
1360 abort ();
1361 fprintf (file, "%d", INTVAL (x));
1362 break;
1363 case 'w':
1364 if (GET_CODE (x) == CONST_INT)
1365 fprintf (file, "#%d", INTVAL (x) & 0xff);
1366 else
a1616dd9
JL
1367 fprintf (file, "%s",
1368 byte_reg (x, TARGET_H8300 ? 2 : 0));
48837e29
DE
1369 break;
1370 case 'x':
1371 if (GET_CODE (x) == CONST_INT)
1372 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1373 else
a1616dd9
JL
1374 fprintf (file, "%s",
1375 byte_reg (x, TARGET_H8300 ? 3 : 1));
48837e29
DE
1376 break;
1377 case 'y':
1378 if (GET_CODE (x) == CONST_INT)
1379 fprintf (file, "#%d", (INTVAL (x) >> 16) & 0xff);
1380 else
1381 fprintf (file, "%s", byte_reg (x, 0));
1382 break;
1383 case 'z':
1384 if (GET_CODE (x) == CONST_INT)
1385 fprintf (file, "#%d", (INTVAL (x) >> 24) & 0xff);
1386 else
1387 fprintf (file, "%s", byte_reg (x, 1));
1388 break;
1389
07aae5c2 1390 default:
48837e29 1391 def:
07aae5c2
SC
1392 switch (GET_CODE (x))
1393 {
1394 case REG:
48837e29
DE
1395 switch (GET_MODE (x))
1396 {
1397 case QImode:
269c14e1 1398#if 0 /* Is it asm ("mov.b %0,r2l", ...) */
48837e29
DE
1399 fprintf (file, "%s", byte_reg (x, 0));
1400#else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1401 fprintf (file, "%s", names_big[REGNO (x)]);
1402#endif
1403 break;
1404 case HImode:
1405 fprintf (file, "%s", names_big[REGNO (x)]);
1406 break;
1407 case SImode:
8977e8a7 1408 case SFmode:
48837e29
DE
1409 fprintf (file, "%s", names_extended[REGNO (x)]);
1410 break;
1411 default:
1412 abort ();
1413 }
07aae5c2
SC
1414 break;
1415
1416 case MEM:
1417 fprintf (file, "@");
1418 output_address (XEXP (x, 0));
15dc331e
JL
1419
1420 /* If this is an 'R' operand (reference into the 8-bit area),
1421 then specify a symbolic address as "foo:8". */
1422 if (code == 'R'
1423 && GET_CODE (XEXP (x, 0)) == SYMBOL_REF
1424 && SYMBOL_REF_FLAG (XEXP (x, 0)))
1425 fprintf (file, ":8");
887a8bd9
JL
1426 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
1427 && TINY_DATA_NAME_P (XSTR (XEXP (x, 0), 0)))
1428 fprintf (file, ":16");
07aae5c2
SC
1429 break;
1430
1431 case CONST_INT:
1432 case SYMBOL_REF:
1433 case CONST:
1434 case LABEL_REF:
1435 fprintf (file, "#");
1436 print_operand_address (file, x);
1437 break;
808fbfac
JL
1438 case CONST_DOUBLE:
1439 {
1440 long val;
1441 REAL_VALUE_TYPE rv;
1442 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1443 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1444 fprintf (file, "#%d", val);
1445 break;
1446 }
07aae5c2
SC
1447 }
1448 }
1449}
1450
1451/* Output assembly language output for the address ADDR to FILE. */
1452
1453void
1454print_operand_address (file, addr)
1455 FILE *file;
1456 rtx addr;
1457{
1458 switch (GET_CODE (addr))
1459 {
1460 case REG:
48837e29 1461 fprintf (file, "%s", h8_reg_names[REGNO (addr)]);
07aae5c2
SC
1462 break;
1463
1464 case PRE_DEC:
48837e29 1465 fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
07aae5c2
SC
1466 break;
1467
1468 case POST_INC:
48837e29 1469 fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);
07aae5c2
SC
1470 break;
1471
1472 case PLUS:
1473 fprintf (file, "(");
1474 if (GET_CODE (XEXP (addr, 0)) == REG)
1475 {
1476 /* reg,foo */
1477 print_operand_address (file, XEXP (addr, 1));
1478 fprintf (file, ",");
1479 print_operand_address (file, XEXP (addr, 0));
1480 }
1481 else
1482 {
1483 /* foo+k */
1484 print_operand_address (file, XEXP (addr, 0));
1485 fprintf (file, "+");
1486 print_operand_address (file, XEXP (addr, 1));
1487 }
1488 fprintf (file, ")");
1489 break;
1490
1491 case CONST_INT:
48837e29
DE
1492 {
1493 /* Since the h8/300 only has 16 bit pointers, negative values are also
1494 those >= 32768. This happens for example with pointer minus a
1495 constant. We don't want to turn (char *p - 2) into
1496 (char *p + 65534) because loop unrolling can build upon this
1497 (IE: char *p + 131068). */
1498 int n = INTVAL (addr);
1499 if (TARGET_H8300)
1500 n = (int) (short) n;
1501 if (n < 0)
1502 /* ??? Why the special case for -ve values? */
1503 fprintf (file, "-%d", -n);
1504 else
1505 fprintf (file, "%d", n);
1506 break;
1507 }
07aae5c2
SC
1508
1509 default:
1510 output_addr_const (file, addr);
1511 break;
1512 }
1513}
1514\f
07aae5c2
SC
1515/* Output all insn addresses and their sizes into the assembly language
1516 output file. This is helpful for debugging whether the length attributes
1517 in the md file are correct. This is not meant to be a user selectable
1518 option. */
1519
1520void
1521final_prescan_insn (insn, operand, num_operands)
1522 rtx insn, *operand;
1523 int num_operands;
1524{
1525 /* This holds the last insn address. */
1526 static int last_insn_address = 0;
1527
1528 int uid = INSN_UID (insn);
1529
48837e29
DE
1530 if (TARGET_RTL_DUMP)
1531 {
1532 fprintf (asm_out_file, "\n****************");
1533 print_rtl (asm_out_file, PATTERN (insn));
1534 fprintf (asm_out_file, "\n");
1535 }
1536
07aae5c2
SC
1537 if (TARGET_ADDRESSES)
1538 {
48837e29 1539 fprintf (asm_out_file, "; 0x%x %d\n", insn_addresses[uid],
07aae5c2
SC
1540 insn_addresses[uid] - last_insn_address);
1541 last_insn_address = insn_addresses[uid];
1542 }
1543}
1544
48837e29
DE
1545/* Prepare for an SI sized move. */
1546
1547int
1548do_movsi (operands)
1549 rtx operands[];
07aae5c2 1550{
48837e29
DE
1551 rtx src = operands[1];
1552 rtx dst = operands[0];
1553 if (!reload_in_progress && !reload_completed)
1554 {
1555 if (!register_operand (dst, GET_MODE (dst)))
1556 {
1557 rtx tmp = gen_reg_rtx (GET_MODE (dst));
1558 emit_move_insn (tmp, src);
1559 operands[1] = tmp;
1560 }
1561 }
1562 return 0;
1563}
1564
1565/* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
1566 Define the offset between two registers, one to be eliminated, and the other
1567 its replacement, at the start of a routine. */
07aae5c2 1568
48837e29
DE
1569int
1570initial_offset (from, to)
1571{
1572 int offset = 0;
1573
1574 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1575 offset = UNITS_PER_WORD + frame_pointer_needed * UNITS_PER_WORD;
1576 else
07aae5c2 1577 {
48837e29
DE
1578 int regno;
1579
1580 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1581 if ((regs_ever_live[regno]
1582 && (!call_used_regs[regno] || regno == FRAME_POINTER_REGNUM)))
1583 offset += UNITS_PER_WORD;
1584
1585 /* See the comments for get_frame_size. We need to round it up to
1586 STACK_BOUNDARY. */
1587
1588 offset += ((get_frame_size () + STACK_BOUNDARY / BITS_PER_UNIT - 1)
1589 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
1590
1591 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1592 offset += UNITS_PER_WORD; /* Skip saved PC */
1593 }
1594 return offset;
1595}
1596
1597/* Update the condition code from the insn. */
1598
1599int
1600notice_update_cc (body, insn)
1601 rtx body;
1602 rtx insn;
1603{
1604 switch (get_attr_cc (insn))
1605 {
1606 case CC_NONE:
269c14e1 1607 /* Insn does not affect CC at all. */
48837e29
DE
1608 break;
1609
1610 case CC_NONE_0HIT:
269c14e1 1611 /* Insn does not change CC, but the 0'th operand has been changed. */
48837e29
DE
1612 if (cc_status.value1 != 0
1613 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
1614 cc_status.value1 = 0;
48837e29
DE
1615 break;
1616
065bbfe6 1617 case CC_SET_ZN:
269c14e1
DE
1618 /* Insn sets the Z,N flags of CC to recog_operand[0].
1619 The V flag is unusable. The C flag may or may not be known but
1620 that's ok because alter_cond will change tests to use EQ/NE. */
48837e29 1621 CC_STATUS_INIT;
269c14e1
DE
1622 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
1623 cc_status.value1 = recog_operand[0];
48837e29
DE
1624 break;
1625
065bbfe6
JL
1626 case CC_SET_ZNV:
1627 /* Insn sets the Z,N,V flags of CC to recog_operand[0].
1628 The C flag may or may not be known but that's ok because
1629 alter_cond will change tests to use EQ/NE. */
1630 CC_STATUS_INIT;
1631 cc_status.flags |= CC_NO_CARRY;
1632 cc_status.value1 = recog_operand[0];
1633 break;
1634
269c14e1
DE
1635 case CC_COMPARE:
1636 /* The insn is a compare instruction. */
48837e29 1637 CC_STATUS_INIT;
269c14e1 1638 cc_status.value1 = SET_SRC (body);
48837e29
DE
1639 break;
1640
48837e29 1641 case CC_CLOBBER:
269c14e1 1642 /* Insn doesn't leave CC in a usable state. */
48837e29
DE
1643 CC_STATUS_INIT;
1644 break;
07aae5c2 1645 }
48837e29
DE
1646}
1647
1648/* Recognize valid operators for bit instructions */
1649
1650int
1651bit_operator (x, mode)
1652 rtx x;
1653 enum machine_mode mode;
1654{
1655 enum rtx_code code = GET_CODE (x);
07aae5c2 1656
48837e29
DE
1657 return (code == XOR
1658 || code == AND
1659 || code == IOR);
07aae5c2 1660}
48837e29
DE
1661\f
1662/* Shifts.
1663
1664 We devote a fair bit of code to getting efficient shifts since we can only
51c0c1d7
JL
1665 shift one bit at a time on the H8/300 and H8/300H and only one or two
1666 bits at a time on the H8/S.
1667
1668 The basic shift methods:
1669
1670 * loop shifts -- emit a loop using one (or two on H8/S) bit shifts;
1671 this is the default. SHIFT_LOOP
1672
1673 * inlined shifts -- emit straight line code for the shift; this is
1674 used when a straight line shift is about the same size or smaller
1675 than a loop. We allow the inline version to be slightly longer in
1676 some cases as it saves a register. SHIFT_INLINE
1677
1678 * rotate + and -- rotate the value the opposite direction, then
1679 mask off the values we don't need. This is used when only a few
1680 of the bits in the original value will survive in the shifted value.
1681 Again, this is used when it's about the same size or smaller than
1682 a loop. We allow this version to be slightly longer as it is usually
1683 much faster than a loop. SHIFT_ROT_AND
1684
1685 * swap (+ shifts) -- often it's possible to swap bytes/words to
1686 simulate a shift by 8/16. Once swapped a few inline shifts can be
1687 added if the shift count is slightly more than 8 or 16. This is used
1688 when it's about the same size or smaller than a loop. We allow this
1689 version to be slightly longer as it is usually much faster than a loop.
1690 SHIFT_SPECIAL
1691
1692 * There other oddballs. Not worth explaining. SHIFT_SPECIAL
1693
48837e29
DE
1694
1695 Here are some thoughts on what the absolutely positively best code is.
1696 "Best" here means some rational trade-off between code size and speed,
1697 where speed is more preferred but not at the expense of generating 20 insns.
1698
51c0c1d7
JL
1699 A trailing '*' after the shift count indicates the "best" mode isn't
1700 implemented.
1701
48837e29 1702 H8/300 QImode shifts
51c0c1d7
JL
1703 1-4 - do them inline
1704 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1705 ASHIFTRT: loop
1706 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1707 ASHIFTRT: shll, subx (propagate carry bit to all bits)
48837e29
DE
1708
1709 H8/300 HImode shifts
51c0c1d7
JL
1710 1-4 - do them inline
1711 5-6 - loop
1712 7 - shift 2nd half other way into carry.
1713 copy 1st half into 2nd half
1714 rotate 2nd half other way with carry
1715 rotate 1st half other way (no carry)
1716 mask off bits in 1st half (ASHIFT | LSHIFTRT).
1717 sign extend 1st half (ASHIFTRT)
1718 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1719 9-12 - do shift by 8, inline remaining shifts
1720 13-14* - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1721 - ASHIFTRT: loop
1722 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1723 - ASHIFTRT: shll, subx, set other byte
48837e29
DE
1724
1725 H8/300 SImode shifts
51c0c1d7
JL
1726 1-2 - do them inline
1727 3-6 - loop
1728 7* - shift other way once, move bytes into place,
1729 move carry into place (possibly with sign extension)
1730 8 - move bytes into place, zero or sign extend other
1731 9-14 - loop
1732 15* - shift other way once, move word into place, move carry into place
1733 16 - move word, zero or sign extend other
1734 17-23 - loop
1735 24* - move bytes into place, zero or sign extend other
1736 25-27 - loop
1737 28-30* - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,
1738 zero others
1739 ASHIFTRT: loop
38e01259 1740 31 - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,
51c0c1d7
JL
1741 zero others
1742 ASHIFTRT: shll top byte, subx, copy to other bytes
1743
1744 H8/300H QImode shifts (same as H8/300 QImode shifts)
1745 1-4 - do them inline
1746 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1747 ASHIFTRT: loop
1748 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1749 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1750
48837e29
DE
1751
1752 H8/300H HImode shifts
51c0c1d7
JL
1753 1-4 - do them inline
1754 5-6 - loop
1755 7 - shift 2nd half other way into carry.
1756 copy 1st half into 2nd half
1757 rotate entire word other way using carry
1758 mask off remaining bits (ASHIFT | LSHIFTRT)
1759 sign extend remaining bits (ASHIFTRT)
1760 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1761 9-12 - do shift by 8, inline remaining shifts
1762 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1763 - ASHIFTRT: loop
1764 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1765 - ASHIFTRT: shll, subx, set other byte
48837e29
DE
1766
1767 H8/300H SImode shifts
1768 (These are complicated by the fact that we don't have byte level access to
1769 the top word.)
1770 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
51c0c1d7
JL
1771 1-4 - do them inline
1772 5-14 - loop
1773 15* - shift other way once, move word into place, move carry into place
1774 (with sign extension for ASHIFTRT)
1775 16 - move word into place, zero or sign extend other
1776 17-20 - do 16bit shift, then inline remaining shifts
1777 20-23 - loop
1778 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1779 move word 0 to word 1, zero word 0
1780 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1781 zero word 1, zero byte 1
1782 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1783 sign extend byte 0, sign extend word 0
1784 25-27* - either loop, or
1785 do 24 bit shift, inline rest
1786 28-30 - ASHIFT: rotate 4/3/2, mask
1787 LSHIFTRT: rotate 4/3/2, mask
1788 ASHIFTRT: loop
1789 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1790
1791 H8/S QImode shifts
1792 1-6 - do them inline
1793 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1794 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1795
1796 H8/S HImode shifts
1797 1-7 - do them inline
1798 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1799 9-12 - do shift by 8, inline remaining shifts
1800 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1801 - ASHIFTRT: loop
1802 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1803 - ASHIFTRT: shll, subx, set other byte
1804
1805 H8/S SImode shifts
1806 (These are complicated by the fact that we don't have byte level access to
1807 the top word.)
1808 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1809 1-10 - do them inline
1810 11-14 - loop
1811 15* - shift other way once, move word into place, move carry into place
1812 (with sign extension for ASHIFTRT)
1813 16 - move word into place, zero or sign extend other
1814 17-20 - do 16bit shift, then inline remaining shifts
1815 20-23 - loop
1816 24* - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1817 move word 0 to word 1, zero word 0
1818 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1819 zero word 1, zero byte 1
1820 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1821 sign extend byte 0, sign extend word 0
1822 25-27* - either loop, or
1823 do 24 bit shift, inline rest
1824 28-30 - ASHIFT: rotate 4/3/2, mask
1825 LSHIFTRT: rotate 4/3/2, mask
1826 ASHIFTRT: loop
1827 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1828
1829 Panic!!! */
07aae5c2
SC
1830
1831int
48837e29
DE
1832nshift_operator (x, mode)
1833 rtx x;
1834 enum machine_mode mode;
1835{
1836 switch (GET_CODE (x))
1837 {
1838 case ASHIFTRT:
1839 case LSHIFTRT:
1840 case ASHIFT:
1841 return 1;
1842
1843 default:
1844 return 0;
1845 }
1846}
1847
1848/* Called from the .md file to emit code to do shifts.
1849 Returns a boolean indicating success
1850 (currently this is always TRUE). */
1851
1852int
1853expand_a_shift (mode, code, operands)
1854 enum machine_mode mode;
07aae5c2
SC
1855 int code;
1856 rtx operands[];
07aae5c2 1857{
07aae5c2
SC
1858 emit_move_insn (operands[0], operands[1]);
1859
48837e29
DE
1860 /* need a loop to get all the bits we want - we generate the
1861 code at emit time, but need to allocate a scratch reg now */
1862
1863 emit_insn (gen_rtx
1864 (PARALLEL, VOIDmode,
1865 gen_rtvec (2,
1866 gen_rtx (SET, VOIDmode, operands[0],
1867 gen_rtx (code, mode, operands[0], operands[2])),
1868 gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, QImode, 0)))));
1869
1870 return 1;
1871}
1872
1873/* Shift algorithm determination.
1874
1875 There are various ways of doing a shift:
1876 SHIFT_INLINE: If the amount is small enough, just generate as many one-bit
1877 shifts as we need.
1878 SHIFT_ROT_AND: If the amount is large but close to either end, rotate the
1879 necessary bits into position and then set the rest to zero.
1880 SHIFT_SPECIAL: Hand crafted assembler.
1881 SHIFT_LOOP: If the above methods fail, just loop. */
1882
1883enum shift_alg
1884{
1885 SHIFT_INLINE,
1886 SHIFT_ROT_AND,
1887 SHIFT_SPECIAL,
1888 SHIFT_LOOP,
1889 SHIFT_MAX
1890};
1891
1892/* Symbols of the various shifts which can be used as indices. */
1893
1894enum shift_type
1895 {
1896 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
1897 };
1898
1899/* Symbols of the various modes which can be used as indices. */
1900
1901enum shift_mode
1902 {
1903 QIshift, HIshift, SIshift
1904 };
1905
269c14e1
DE
1906/* For single bit shift insns, record assembler and what bits of the
1907 condition code are valid afterwards (represented as various CC_FOO
1908 bits, 0 means CC isn't left in a usable state). */
48837e29
DE
1909
1910struct shift_insn
1911{
1912 char *assembler;
1913 int cc_valid;
1914};
1915
1916/* Assembler instruction shift table.
1917
1918 These tables are used to look up the basic shifts.
1919 They are indexed by cpu, shift_type, and mode.
1920*/
07aae5c2 1921
48837e29
DE
1922static const struct shift_insn shift_one[2][3][3] =
1923{
1924/* H8/300 */
1925 {
1926/* SHIFT_ASHIFT */
1927 {
065bbfe6 1928 { "shll\t%X0", CC_NO_CARRY },
51c0c1d7
JL
1929 { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1930 { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }
48837e29
DE
1931 },
1932/* SHIFT_LSHIFTRT */
1933 {
065bbfe6 1934 { "shlr\t%X0", CC_NO_CARRY },
51c0c1d7
JL
1935 { "shlr\t%t0\n\trotxr\t%s0", 0 },
1936 { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
48837e29
DE
1937 },
1938/* SHIFT_ASHIFTRT */
1939 {
51c0c1d7
JL
1940 { "shar\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1941 { "shar\t%t0\n\trotxr\t%s0", 0 },
1942 { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }
48837e29
DE
1943 }
1944 },
1945/* H8/300H */
1946 {
1947/* SHIFT_ASHIFT */
1948 {
065bbfe6
JL
1949 { "shll.b\t%X0", CC_NO_CARRY },
1950 { "shll.w\t%T0", CC_NO_CARRY },
1951 { "shll.l\t%S0", CC_NO_CARRY }
48837e29
DE
1952 },
1953/* SHIFT_LSHIFTRT */
1954 {
065bbfe6
JL
1955 { "shlr.b\t%X0", CC_NO_CARRY },
1956 { "shlr.w\t%T0", CC_NO_CARRY },
1957 { "shlr.l\t%S0", CC_NO_CARRY }
48837e29
DE
1958 },
1959/* SHIFT_ASHIFTRT */
1960 {
51c0c1d7
JL
1961 { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1962 { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1963 { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
48837e29
DE
1964 }
1965 }
1966};
07aae5c2 1967
51c0c1d7
JL
1968static const struct shift_insn shift_two[3][3] =
1969{
1970/* SHIFT_ASHIFT */
1971 {
065bbfe6
JL
1972 { "shll.b\t#2,%X0", CC_NO_CARRY },
1973 { "shll.w\t#2,%T0", CC_NO_CARRY },
1974 { "shll.l\t#2,%S0", CC_NO_CARRY }
51c0c1d7
JL
1975 },
1976/* SHIFT_LSHIFTRT */
1977 {
065bbfe6
JL
1978 { "shlr.b\t#2,%X0", CC_NO_CARRY },
1979 { "shlr.w\t#2,%T0", CC_NO_CARRY },
1980 { "shlr.l\t#2,%S0", CC_NO_CARRY }
51c0c1d7
JL
1981 },
1982/* SHIFT_ASHIFTRT */
1983 {
1984 { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1985 { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1986 { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
1987 }
1988};
1989
48837e29
DE
1990/* Rotates are organized by which shift they'll be used in implementing.
1991 There's no need to record whether the cc is valid afterwards because
1992 it is the AND insn that will decide this. */
07aae5c2 1993
48837e29
DE
1994static const char *const rotate_one[2][3][3] =
1995{
1996/* H8/300 */
1997 {
1998/* SHIFT_ASHIFT */
1999 {
51c0c1d7
JL
2000 "rotr\t%X0",
2001 "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",
48837e29
DE
2002 0
2003 },
2004/* SHIFT_LSHIFTRT */
2005 {
51c0c1d7
JL
2006 "rotl\t%X0",
2007 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
48837e29
DE
2008 0
2009 },
2010/* SHIFT_ASHIFTRT */
2011 {
51c0c1d7
JL
2012 "rotl\t%X0",
2013 "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",
48837e29 2014 0
07aae5c2 2015 }
48837e29
DE
2016 },
2017/* H8/300H */
2018 {
2019/* SHIFT_ASHIFT */
2020 {
51c0c1d7
JL
2021 "rotr.b\t%X0",
2022 "rotr.w\t%T0",
2023 "rotr.l\t%S0"
48837e29
DE
2024 },
2025/* SHIFT_LSHIFTRT */
07aae5c2 2026 {
51c0c1d7
JL
2027 "rotl.b\t%X0",
2028 "rotl.w\t%T0",
2029 "rotl.l\t%S0"
48837e29
DE
2030 },
2031/* SHIFT_ASHIFTRT */
2032 {
51c0c1d7
JL
2033 "rotl.b\t%X0",
2034 "rotl.w\t%T0",
2035 "rotl.l\t%S0"
48837e29
DE
2036 }
2037 }
2038};
2039
51c0c1d7
JL
2040static const char *const rotate_two[3][3] =
2041{
2042/* SHIFT_ASHIFT */
2043 {
2044 "rotr.b\t#2,%X0",
2045 "rotr.w\t#2,%T0",
2046 "rotr.l\t#2,%S0"
2047 },
2048/* SHIFT_LSHIFTRT */
2049 {
2050 "rotl.b\t#2,%X0",
2051 "rotl.w\t#2,%T0",
2052 "rotl.l\t#2,%S0"
2053 },
2054/* SHIFT_ASHIFTRT */
2055 {
2056 "rotl.b\t#2,%X0",
2057 "rotl.w\t#2,%T0",
2058 "rotl.l\t#2,%S0"
2059 }
2060};
2061
48837e29
DE
2062/* Given CPU, MODE, SHIFT_TYPE, and shift count COUNT, determine the best
2063 algorithm for doing the shift. The assembler code is stored in ASSEMBLER.
2064 We don't achieve maximum efficiency in all cases, but the hooks are here
2065 to do so.
2066
2067 For now we just use lots of switch statements. Since we don't even come
2068 close to supporting all the cases, this is simplest. If this function ever
2069 gets too big, perhaps resort to a more table based lookup. Of course,
2070 at this point you may just wish to do it all in rtl.
2071
2072 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
2073 1,2,3,4 will be inlined (1,2 for SI). */
2074
2075static enum shift_alg
51c0c1d7
JL
2076get_shift_alg (cpu, shift_type, mode, count, assembler_p,
2077 assembler2_p, cc_valid_p)
48837e29
DE
2078 enum attr_cpu cpu;
2079 enum shift_type shift_type;
2080 enum machine_mode mode;
2081 int count;
2082 const char **assembler_p;
51c0c1d7 2083 const char **assembler2_p;
48837e29
DE
2084 int *cc_valid_p;
2085{
2086 /* The default is to loop. */
2087 enum shift_alg alg = SHIFT_LOOP;
2088 enum shift_mode shift_mode;
2089
2090 /* We don't handle negative shifts or shifts greater than the word size,
2091 they should have been handled already. */
07aae5c2 2092
48837e29
DE
2093 if (count < 0 || count > GET_MODE_BITSIZE (mode))
2094 abort ();
2095
2096 switch (mode)
2097 {
2098 case QImode:
2099 shift_mode = QIshift;
2100 break;
2101 case HImode:
2102 shift_mode = HIshift;
2103 break;
2104 case SImode:
2105 shift_mode = SIshift;
2106 break;
2107 default:
2108 abort ();
2109 }
2110
2111 /* Assume either SHIFT_LOOP or SHIFT_INLINE.
2112 It is up to the caller to know that looping clobbers cc. */
2113 *assembler_p = shift_one[cpu][shift_type][shift_mode].assembler;
51c0c1d7
JL
2114 if (TARGET_H8300S)
2115 *assembler2_p = shift_two[shift_type][shift_mode].assembler;
2116 else
2117 *assembler2_p = NULL;
48837e29
DE
2118 *cc_valid_p = shift_one[cpu][shift_type][shift_mode].cc_valid;
2119
2120 /* Now look for cases we want to optimize. */
2121
2122 switch (shift_mode)
2123 {
2124 case QIshift:
2125 if (count <= 4)
2126 return SHIFT_INLINE;
51c0c1d7 2127 else
07aae5c2 2128 {
51c0c1d7
JL
2129 /* Shift by 5/6 are only 3 insns on the H8/S, so it's just as
2130 fast as SHIFT_ROT_AND, plus CC is valid. */
2131 if (TARGET_H8300S && count <= 6)
2132 return SHIFT_INLINE;
2133
2134 /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
2135 through the entire value. */
2136 if (shift_type == SHIFT_ASHIFTRT && count == 7)
2137 {
2138 *assembler_p = "shll\t%X0\n\tsubx\t%X0,%X0";
2139 *cc_valid_p = 0;
2140 return SHIFT_SPECIAL;
2141 }
2142
2143 /* Other ASHIFTRTs are too much of a pain. */
48837e29 2144 if (shift_type == SHIFT_ASHIFTRT)
51c0c1d7
JL
2145 return SHIFT_LOOP;
2146
2147 /* Other shifts by 5, 6, or 7 bits use SHIFT_ROT_AND. */
2148 *assembler_p = rotate_one[cpu][shift_type][shift_mode];
2149 if (TARGET_H8300S)
2150 *assembler2_p = rotate_two[shift_type][shift_mode];
2151 *cc_valid_p = 0;
2152 return SHIFT_ROT_AND;
2153 }
2154
2155 case HIshift:
2156 if (count <= 4)
2157 return SHIFT_INLINE;
2158 else if (TARGET_H8300S && count <= 7)
2159 return SHIFT_INLINE;
2160 else if (count == 7)
2161 {
2162 if (shift_type == SHIFT_ASHIFT && TARGET_H8300)
48837e29 2163 {
51c0c1d7
JL
2164 *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";
2165 *cc_valid_p = 0;
2166 return SHIFT_SPECIAL;
48837e29 2167 }
51c0c1d7
JL
2168
2169 if (shift_type == SHIFT_ASHIFT && TARGET_H8300H)
48837e29 2170 {
51c0c1d7 2171 *assembler_p = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0";
48837e29 2172 *cc_valid_p = 0;
51c0c1d7
JL
2173 return SHIFT_SPECIAL;
2174 }
2175
2176 if (shift_type == SHIFT_LSHIFTRT && TARGET_H8300)
2177 {
2178 *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";
2179 *cc_valid_p = 0;
2180 return SHIFT_SPECIAL;
2181 }
2182
2183 if (shift_type == SHIFT_LSHIFTRT && TARGET_H8300H)
2184 {
2185 *assembler_p = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0";
2186 *cc_valid_p = 0;
2187 return SHIFT_SPECIAL;
2188 }
2189
2190 if (shift_type == SHIFT_ASHIFTRT)
2191 {
2192 *assembler_p = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0";
2193 *cc_valid_p = 0;
2194 return SHIFT_SPECIAL;
48837e29 2195 }
07aae5c2 2196 }
51c0c1d7 2197 else if (count == 8)
07aae5c2 2198 {
51c0c1d7 2199 switch (shift_type)
48837e29 2200 {
51c0c1d7
JL
2201 case SHIFT_ASHIFT:
2202 *assembler_p = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0";
2203 *cc_valid_p = 0;
2204 return SHIFT_SPECIAL;
2205 case SHIFT_LSHIFTRT:
2206 *assembler_p = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0";
2207 *cc_valid_p = 0;
2208 return SHIFT_SPECIAL;
2209 case SHIFT_ASHIFTRT:
2210 if (TARGET_H8300)
2211 *assembler_p = "mov.b\t%t0,%s0\n\tshll\t%t0\n\tsubx\t%t0,%t0\t";
2212 else
2213 *assembler_p = "mov.b\t%t0,%s0\n\texts.w\t%T0";
48837e29
DE
2214 *cc_valid_p = 0;
2215 return SHIFT_SPECIAL;
2216 }
51c0c1d7
JL
2217 }
2218 else if (count == 9)
2219 {
2220 switch (shift_type)
48837e29 2221 {
51c0c1d7
JL
2222 case SHIFT_ASHIFT:
2223 *assembler_p = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0";
48837e29 2224 *cc_valid_p = 0;
51c0c1d7
JL
2225 return SHIFT_SPECIAL;
2226 case SHIFT_LSHIFTRT:
2227 *assembler_p = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0";
2228 *cc_valid_p = 0;
2229 return SHIFT_SPECIAL;
2230 case SHIFT_ASHIFTRT:
2231 if (TARGET_H8300)
2232 *assembler_p = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0";
2233 else
2234 *assembler_p = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0";
2235 *cc_valid_p = 0;
2236 return SHIFT_SPECIAL;
48837e29 2237 }
07aae5c2 2238 }
51c0c1d7 2239 else if (count == 10)
48837e29
DE
2240 {
2241 switch (shift_type)
2242 {
2243 case SHIFT_ASHIFT:
51c0c1d7
JL
2244 if (TARGET_H8300S)
2245 *assembler_p = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\t";
2246 else
2247 *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
2248 *cc_valid_p = 0;
2249 return SHIFT_SPECIAL;
2250 case SHIFT_LSHIFTRT:
51c0c1d7
JL
2251 if (TARGET_H8300S)
2252 *assembler_p = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0";
2253 else
2254 *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
2255 *cc_valid_p = 0;
2256 return SHIFT_SPECIAL;
2257 case SHIFT_ASHIFTRT:
51c0c1d7
JL
2258 if (TARGET_H8300)
2259 *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";
2260 else if (TARGET_H8300H)
2261 *assembler_p = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0\n\tshar.b\t%s0";
2262 else if (TARGET_H8300S)
2263 *assembler_p = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t#2,%s0";
2264 *cc_valid_p = 0;
2265 return SHIFT_SPECIAL;
2266 }
2267 }
2268 else if (count == 11)
2269 {
2270 switch (shift_type)
2271 {
2272 case SHIFT_ASHIFT:
2273 if (TARGET_H8300S)
2274 *assembler_p = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\tshal.b\t%t0";
2275 else
2276 *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";
2277 *cc_valid_p = 0;
2278 return SHIFT_SPECIAL;
2279 case SHIFT_LSHIFTRT:
2280 if (TARGET_H8300S)
2281 *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 2282 else
51c0c1d7
JL
2283 *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";
2284 *cc_valid_p = 0;
2285 return SHIFT_SPECIAL;
2286 case SHIFT_ASHIFTRT:
2287 if (TARGET_H8300)
2288 *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";
2289 else if (TARGET_H8300H)
2290 *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";
2291 else if (TARGET_H8300S)
2292 *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
2293 *cc_valid_p = 0;
2294 return SHIFT_SPECIAL;
2295 }
48837e29 2296 }
51c0c1d7 2297 else if (count == 12)
07aae5c2 2298 {
51c0c1d7
JL
2299 switch (shift_type)
2300 {
2301 case SHIFT_ASHIFT:
2302 if (TARGET_H8300S)
2303 *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";
2304 else
2305 *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";
2306 *cc_valid_p = 0;
2307 return SHIFT_SPECIAL;
2308 case SHIFT_LSHIFTRT:
2309 if (TARGET_H8300S)
2310 *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";
2311 else
2312 *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";
2313 *cc_valid_p = 0;
2314 return SHIFT_SPECIAL;
2315 case SHIFT_ASHIFTRT:
2316 if (TARGET_H8300)
2317 *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";
2318 else if (TARGET_H8300H)
2319 *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";
2320 else if (TARGET_H8300S)
2321 *assembler_p = "mov.b\t%t0,%s0\n\textw.w\t%T0\n\tshar.b\t#2,%s0\n\tshar.b\t#2,%s0";
2322 *cc_valid_p = 0;
2323 return SHIFT_SPECIAL;
2324 }
2325 }
2326 else if (!TARGET_H8300 && (count == 13 || count == 14)
2327 || count == 15)
2328 {
2329 if (count == 15 && shift_type == SHIFT_ASHIFTRT)
48837e29 2330 {
51c0c1d7 2331 *assembler_p = "shll\t%t0,%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0";
48837e29
DE
2332 *cc_valid_p = 0;
2333 return SHIFT_SPECIAL;
2334 }
7d9f07f4 2335 else if (shift_type != SHIFT_ASHIFTRT)
48837e29
DE
2336 {
2337 *assembler_p = rotate_one[cpu][shift_type][shift_mode];
51c0c1d7
JL
2338 if (TARGET_H8300S)
2339 *assembler2_p = rotate_two[shift_type][shift_mode];
2340 else
2341 *assembler2_p = NULL;
48837e29
DE
2342 *cc_valid_p = 0;
2343 return SHIFT_ROT_AND;
2344 }
07aae5c2 2345 }
48837e29 2346 break;
51c0c1d7 2347
48837e29 2348 case SIshift:
51c0c1d7 2349 if (count <= (TARGET_H8300 ? 2 : 4))
48837e29 2350 return SHIFT_INLINE;
51c0c1d7
JL
2351 else if (TARGET_H8300S && count <= 10)
2352 return SHIFT_INLINE;
2353 else if (count == 8 && TARGET_H8300)
48837e29 2354 {
51c0c1d7 2355 switch (shift_type)
48837e29 2356 {
51c0c1d7 2357 case SHIFT_ASHIFT:
808fbfac 2358 *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
2359 *cc_valid_p = 0;
2360 return SHIFT_SPECIAL;
2361 case SHIFT_LSHIFTRT:
2362 *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";
2363 *cc_valid_p = 0;
2364 return SHIFT_SPECIAL;
2365 case SHIFT_ASHIFTRT:
2366 *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";
2367 *cc_valid_p = 0;
2368 return SHIFT_SPECIAL;
48837e29 2369 }
48837e29 2370 }
e6bcfef9
JS
2371 else if (count == 8 && !TARGET_H8300)
2372 {
2373 switch (shift_type)
2374 {
2375 case SHIFT_ASHIFT:
2376 *assembler_p = "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";
2377 *cc_valid_p = 0;
2378 return SHIFT_SPECIAL;
2379 case SHIFT_LSHIFTRT:
2380 *assembler_p = "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";
2381 *cc_valid_p = 0;
2382 return SHIFT_SPECIAL;
2383 case SHIFT_ASHIFTRT:
2384 *assembler_p = "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";
2385 *cc_valid_p = 0;
2386 return SHIFT_SPECIAL;
2387 }
2388 }
48837e29
DE
2389 else if (count == 16)
2390 {
2391 switch (shift_type)
2392 {
2393 case SHIFT_ASHIFT:
51c0c1d7
JL
2394 *assembler_p = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2395 *cc_valid_p = 0;
2396 return SHIFT_SPECIAL;
2397 case SHIFT_LSHIFTRT:
2398 *assembler_p = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0";
2399 *cc_valid_p = 0;
2400 return SHIFT_SPECIAL;
2401 case SHIFT_ASHIFTRT:
2402 if (TARGET_H8300)
2403 *assembler_p = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0";
2404 else
2405 *assembler_p = "mov.w\t%e0,%f0\n\texts.l\t%S0";
2406 *cc_valid_p = 0;
2407 return SHIFT_SPECIAL;
2408 }
2409 }
2410 else if (count == 17 && !TARGET_H8300)
2411 {
2412 switch (shift_type)
2413 {
2414 case SHIFT_ASHIFT:
2415 *assembler_p = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0";
2416 *cc_valid_p = 0;
2417 return SHIFT_SPECIAL;
2418 case SHIFT_LSHIFTRT:
2419 *assembler_p = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0";
2420 *cc_valid_p = 0;
2421 return SHIFT_SPECIAL;
2422 case SHIFT_ASHIFTRT:
2423 *assembler_p = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0";
2424 *cc_valid_p = 0;
2425 return SHIFT_SPECIAL;
2426 }
2427 }
2428 else if (count == 18 && !TARGET_H8300)
2429 {
2430 switch (shift_type)
2431 {
2432 case SHIFT_ASHIFT:
2433 if (TARGET_H8300S)
2434 *assembler_p = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0";
2435 else
2436 *assembler_p = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0\n\tshll.l\t%S0";
2437 *cc_valid_p = 0;
2438 return SHIFT_SPECIAL;
2439 case SHIFT_LSHIFTRT:
2440 if (TARGET_H8300S)
2441 *assembler_p = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0";
2442 else
2443 *assembler_p = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0\n\tshlr.l\t%S0";
2444 *cc_valid_p = 0;
2445 return SHIFT_SPECIAL;
2446 case SHIFT_ASHIFTRT:
2447 if (TARGET_H8300S)
2448 *assembler_p = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0";
2449 else
2450 *assembler_p = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0\n\tshar.l\t%S0";
2451 *cc_valid_p = 0;
2452 return SHIFT_SPECIAL;
2453 }
2454 }
2455 else if (count == 19 && !TARGET_H8300)
2456 {
2457 switch (shift_type)
2458 {
2459 case SHIFT_ASHIFT:
2460 if (TARGET_H8300S)
2461 *assembler_p = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0\n\tshll.l\t%S0";
2462 else
2463 *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
2464 *cc_valid_p = 0;
2465 return SHIFT_SPECIAL;
2466 case SHIFT_LSHIFTRT:
51c0c1d7
JL
2467 if (TARGET_H8300S)
2468 *assembler_p = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0\n\tshlr.l\t%S0";
2469 else
2470 *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
2471 *cc_valid_p = 0;
2472 return SHIFT_SPECIAL;
2473 case SHIFT_ASHIFTRT:
51c0c1d7
JL
2474 if (TARGET_H8300S)
2475 *assembler_p = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0\n\tshar.l\t%S0";
48837e29 2476 else
51c0c1d7 2477 *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
2478 *cc_valid_p = 0;
2479 return SHIFT_SPECIAL;
2480 }
2481 }
51c0c1d7
JL
2482 else if (count == 20 && TARGET_H8300S)
2483 {
2484 switch (shift_type)
2485 {
2486 case SHIFT_ASHIFT:
2487 *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";
2488 *cc_valid_p = 0;
2489 return SHIFT_SPECIAL;
2490 case SHIFT_LSHIFTRT:
2491 *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";
2492 *cc_valid_p = 0;
2493 return SHIFT_SPECIAL;
2494 case SHIFT_ASHIFTRT:
2495 *assembler_p = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0\n\tshar.l\t#2,%S0";
2496 *cc_valid_p = 0;
2497 return SHIFT_SPECIAL;
2498 }
2499 }
e6bcfef9
JS
2500 else if (count == 24 && !TARGET_H8300)
2501 {
2502 switch (shift_type)
2503 {
2504 case SHIFT_ASHIFT:
2505 *assembler_p = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f0,%e0\n\tsub.w\t%f0,%f0";
2506 *cc_valid_p = 0;
2507 return SHIFT_SPECIAL;
2508 case SHIFT_LSHIFTRT:
2509 *assembler_p = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0";
2510 *cc_valid_p = 0;
2511 return SHIFT_SPECIAL;
2512 case SHIFT_ASHIFTRT:
2513 *assembler_p = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0";
2514 *cc_valid_p = 0;
2515 return SHIFT_SPECIAL;
2516 }
2517 }
51c0c1d7 2518 else if (count >= 28 && count <= 30 && !TARGET_H8300)
48837e29
DE
2519 {
2520 if (shift_type == SHIFT_ASHIFTRT)
2521 {
2522 return SHIFT_LOOP;
2523 }
2524 else
2525 {
51c0c1d7
JL
2526 *assembler_p = rotate_one[cpu][shift_type][shift_mode];
2527 if (TARGET_H8300S)
2528 *assembler2_p = rotate_two[shift_type][shift_mode];
48837e29 2529 else
51c0c1d7
JL
2530 *assembler2_p = NULL;
2531 *cc_valid_p = 0;
2532 return SHIFT_ROT_AND;
48837e29
DE
2533 }
2534 }
2535 else if (count == 31)
2536 {
2537 if (shift_type == SHIFT_ASHIFTRT)
2538 {
51c0c1d7
JL
2539 if (TARGET_H8300)
2540 *assembler_p = "shll\t%z0\n\tsubx %w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
48837e29 2541 else
51c0c1d7 2542 *assembler_p = "shll\t%e0\n\tsubx\t%w0,%w0\n\tmov.b\t%w0,%x0\n\tmov.w\t%f0,%e0";
48837e29
DE
2543 *cc_valid_p = 0;
2544 return SHIFT_SPECIAL;
2545 }
2546 else
2547 {
51c0c1d7 2548 if (TARGET_H8300)
48837e29
DE
2549 {
2550 if (shift_type == SHIFT_ASHIFT)
51c0c1d7 2551 *assembler_p = "sub.w\t%e0,%e0\n\tshlr\t%w0\n\tmov.w\t%e0,%f0\n\trotxr\t%z0";
48837e29 2552 else
51c0c1d7 2553 *assembler_p = "sub.w\t%f0,%f0\n\tshll\t%z0\n\tmov.w\t%f0,%e0\n\trotxl\t%w0";
48837e29
DE
2554 *cc_valid_p = 0;
2555 return SHIFT_SPECIAL;
2556 }
2557 else
2558 {
2559 *assembler_p = rotate_one[cpu][shift_type][shift_mode];
51c0c1d7
JL
2560 if (TARGET_H8300S)
2561 *assembler2_p = rotate_two[shift_type][shift_mode];
2562 else
2563 *assembler2_p = NULL;
48837e29
DE
2564 *cc_valid_p = 0;
2565 return SHIFT_ROT_AND;
2566 }
2567 }
2568 }
2569 break;
51c0c1d7 2570
48837e29
DE
2571 default:
2572 abort ();
07aae5c2 2573 }
48837e29
DE
2574
2575 return alg;
07aae5c2
SC
2576}
2577
48837e29
DE
2578/* Emit the assembler code for doing shifts. */
2579
2580char *
2581emit_a_shift (insn, operands)
2582 rtx insn;
2583 rtx *operands;
07aae5c2 2584{
48837e29
DE
2585 static int loopend_lab;
2586 char *assembler;
51c0c1d7 2587 char *assembler2;
48837e29
DE
2588 int cc_valid;
2589 rtx inside = PATTERN (insn);
2590 rtx shift = operands[3];
2591 enum machine_mode mode = GET_MODE (shift);
2592 enum rtx_code code = GET_CODE (shift);
2593 enum shift_type shift_type;
2594 enum shift_mode shift_mode;
2595
2596 loopend_lab++;
2597
2598 switch (mode)
2599 {
2600 case QImode:
2601 shift_mode = QIshift;
2602 break;
2603 case HImode:
2604 shift_mode = HIshift;
2605 break;
2606 case SImode:
2607 shift_mode = SIshift;
2608 break;
2609 default:
2610 abort ();
2611 }
07aae5c2 2612
48837e29 2613 switch (code)
07aae5c2 2614 {
48837e29
DE
2615 case ASHIFTRT:
2616 shift_type = SHIFT_ASHIFTRT;
2617 break;
2618 case LSHIFTRT:
2619 shift_type = SHIFT_LSHIFTRT;
2620 break;
2621 case ASHIFT:
2622 shift_type = SHIFT_ASHIFT;
2623 break;
2624 default:
2625 abort ();
2626 }
07aae5c2 2627
48837e29
DE
2628 if (GET_CODE (operands[2]) != CONST_INT)
2629 {
2630 /* Indexing by reg, so have to loop and test at top */
2631 output_asm_insn ("mov.b %X2,%X4", operands);
2632 fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab);
2633
2634 /* Get the assembler code to do one shift. */
51c0c1d7
JL
2635 get_shift_alg (cpu_type, shift_type, mode, 1, &assembler,
2636 &assembler2, &cc_valid);
48837e29
DE
2637 }
2638 else
2639 {
2640 int n = INTVAL (operands[2]);
2641 enum shift_alg alg;
2642
2643 /* If the count is negative, make it 0. */
2644 if (n < 0)
2645 n = 0;
2646 /* If the count is too big, truncate it.
2647 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
2648 do the intuitive thing. */
2649 else if (n > GET_MODE_BITSIZE (mode))
2650 n = GET_MODE_BITSIZE (mode);
2651
51c0c1d7
JL
2652 alg = get_shift_alg (cpu_type, shift_type, mode, n, &assembler,
2653 &assembler2, &cc_valid);
48837e29
DE
2654
2655 switch (alg)
2656 {
2657 case SHIFT_INLINE:
51c0c1d7
JL
2658 /* Emit two bit shifts first. */
2659 while (n > 1 && assembler2 != NULL)
2660 {
2661 output_asm_insn (assembler2, operands);
2662 n -= 2;
2663 }
2664
2665 /* Now emit one bit shifts for any residual. */
2666 while (n > 0)
2667 {
2668 output_asm_insn (assembler, operands);
2669 n -= 1;
2670 }
2671
2672 /* Keep track of CC. */
48837e29 2673 if (cc_valid)
269c14e1
DE
2674 {
2675 cc_status.value1 = operands[0];
2676 cc_status.flags |= cc_valid;
2677 }
48837e29 2678 return "";
51c0c1d7 2679
48837e29
DE
2680 case SHIFT_ROT_AND:
2681 {
2682 int m = GET_MODE_BITSIZE (mode) - n;
2683 int mask = (shift_type == SHIFT_ASHIFT
2684 ? ((1 << GET_MODE_BITSIZE (mode) - n) - 1) << n
2685 : (1 << GET_MODE_BITSIZE (mode) - n) - 1);
2686 char insn_buf[200];
2687 /* Not all possibilities of rotate are supported. They shouldn't
2688 be generated, but let's watch for 'em. */
2689 if (assembler == 0)
2690 abort ();
51c0c1d7
JL
2691
2692 /* Emit two bit rotates first. */
2693 while (m > 1 && assembler2 != NULL)
2694 {
2695 output_asm_insn (assembler2, operands);
2696 m -= 2;
2697 }
2698
2699 /* Now single bit rotates for any residual. */
2700 while (m > 0)
2701 {
2702 output_asm_insn (assembler, operands);
2703 m -= 1;
2704 }
2705
2706 /* Now mask off the high bits. */
48837e29
DE
2707 if (TARGET_H8300)
2708 {
2709 switch (mode)
2710 {
2711 case QImode:
51c0c1d7 2712 sprintf (insn_buf, "and #%d,%%X0",
48837e29
DE
2713 mask, n);
2714 cc_status.value1 = operands[0];
065bbfe6 2715 cc_status.flags |= CC_NO_CARRY;
48837e29
DE
2716 break;
2717 case HImode:
51c0c1d7 2718 sprintf (insn_buf, "and #%d,%%s0\n\tand #%d,%%t0",
48837e29
DE
2719 mask & 255, mask >> 8, n);
2720 break;
2721 case SImode:
2722 abort ();
2723 }
2724 }
2725 else
2726 {
2727 sprintf (insn_buf, "and.%c #%d,%%%c0",
2728 "bwl"[shift_mode], mask,
2729 mode == QImode ? 'X' : mode == HImode ? 'T' : 'S');
2730 cc_status.value1 = operands[0];
065bbfe6 2731 cc_status.flags |= CC_NO_CARRY;
48837e29
DE
2732 }
2733 output_asm_insn (insn_buf, operands);
2734 return "";
2735 }
2736 case SHIFT_SPECIAL:
2737 output_asm_insn (assembler, operands);
2738 return "";
07aae5c2 2739 }
48837e29 2740
51c0c1d7
JL
2741 /* A loop to shift by a "large" constant value.
2742 If we have shift-by-2 insns, use them. */
2743 if (assembler2 != NULL)
2744 {
2745 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2,
2746 names_big[REGNO (operands[4])]);
2747 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2748 output_asm_insn (assembler2, operands);
2749 output_asm_insn ("add #0xff,%X4", operands);
2750 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2751 if (n % 2)
2752 output_asm_insn (assembler, operands);
2753 return "";
2754 }
2755 else
2756 {
2757 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n,
2758 names_big[REGNO (operands[4])]);
2759 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2760 output_asm_insn (assembler, operands);
2761 output_asm_insn ("add #0xff,%X4", operands);
2762 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2763 return "";
2764 }
07aae5c2 2765 }
48837e29
DE
2766
2767 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2768 output_asm_insn (assembler, operands);
2769 output_asm_insn ("add #0xff,%X4", operands);
2770 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2771 fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
2772
2773 return "";
07aae5c2 2774}
48837e29
DE
2775\f
2776/* Fix the operands of a gen_xxx so that it could become a bit
2777 operating insn. */
07aae5c2
SC
2778
2779int
48837e29
DE
2780fix_bit_operand (operands, what, type)
2781 rtx *operands;
2782 char what;
2783 enum rtx_code type;
07aae5c2 2784{
abc95ed3 2785 /* The bit_operand predicate accepts any memory during RTL generation, but
48837e29
DE
2786 only 'U' memory afterwards, so if this is a MEM operand, we must force
2787 it to be valid for 'U' by reloading the address. */
07aae5c2 2788
48837e29 2789 if (GET_CODE (operands[2]) == CONST_INT)
07aae5c2 2790 {
48837e29
DE
2791 if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), what))
2792 {
2793 /* Ok to have a memory dest. */
2794 if (GET_CODE (operands[0]) == MEM && !EXTRA_CONSTRAINT (operands[0], 'U'))
2795 {
2796 rtx mem;
2797 mem = gen_rtx (MEM, GET_MODE (operands[0]),
2798 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2799 RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[0]);
2800 MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[0]);
2801 MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[0]);
2802 operands[0] = mem;
2803 }
2804
2805 if (GET_CODE (operands[1]) == MEM && !EXTRA_CONSTRAINT (operands[1], 'U'))
2806 {
2807 rtx mem;
2808 mem = gen_rtx (MEM, GET_MODE (operands[1]),
2809 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2810 RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[1]);
2811 MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[1]);
2812 MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[1]);
2813 operands[1] = mem;
2814 }
2815 return 0;
2816 }
2817 }
07aae5c2 2818
48837e29 2819 /* Dest and src op must be register. */
07aae5c2 2820
48837e29
DE
2821 operands[1] = force_reg (QImode, operands[1]);
2822 {
2823 rtx res = gen_reg_rtx (QImode);
2824 emit_insn (gen_rtx (SET, VOIDmode, res, gen_rtx (type, QImode, operands[1], operands[2])));
2825 emit_insn (gen_rtx (SET, VOIDmode, operands[0], res));
2826 }
2827 return 1;
07aae5c2 2828}
f5b65a56 2829
f5b65a56
JL
2830/* Return nonzero if FUNC is an interrupt function as specified
2831 by the "interrupt" attribute. */
2832
2833static int
2834h8300_interrupt_function_p (func)
2835 tree func;
2836{
2837 tree a;
2838
2839 if (TREE_CODE (func) != FUNCTION_DECL)
2840 return 0;
2841
97c5ec1d 2842 a = lookup_attribute ("interrupt_handler", DECL_MACHINE_ATTRIBUTES (func));
f5b65a56
JL
2843 return a != NULL_TREE;
2844}
2845
fabe72bb
JL
2846/* Return nonzero if FUNC is an OS_Task function as specified
2847 by the "OS_Task" attribute. */
2848
2849static int
2850h8300_os_task_function_p (func)
2851 tree func;
2852{
2853 tree a;
2854
2855 if (TREE_CODE (func) != FUNCTION_DECL)
2856 return 0;
2857
2858 a = lookup_attribute ("OS_Task", DECL_MACHINE_ATTRIBUTES (func));
2859 return a != NULL_TREE;
2860}
2861
2862/* Return nonzero if FUNC is a monitor function as specified
2863 by the "monitor" attribute. */
2864
2865static int
2866h8300_monitor_function_p (func)
2867 tree func;
2868{
2869 tree a;
2870
2871 if (TREE_CODE (func) != FUNCTION_DECL)
2872 return 0;
2873
2874 a = lookup_attribute ("monitor", DECL_MACHINE_ATTRIBUTES (func));
2875 return a != NULL_TREE;
2876}
2877
f5b65a56
JL
2878/* Return nonzero if FUNC is a function that should be called
2879 through the function vector. */
2880
2881int
2882h8300_funcvec_function_p (func)
2883 tree func;
2884{
2885 tree a;
2886
2887 if (TREE_CODE (func) != FUNCTION_DECL)
2888 return 0;
2889
97c5ec1d 2890 a = lookup_attribute ("function_vector", DECL_MACHINE_ATTRIBUTES (func));
f5b65a56
JL
2891 return a != NULL_TREE;
2892}
2893
887a8bd9 2894/* Return nonzero if DECL is a variable that's in the eight bit
15dc331e
JL
2895 data area. */
2896
2897int
fabdc32d 2898h8300_eightbit_data_p (decl)
15dc331e
JL
2899 tree decl;
2900{
2901 tree a;
2902
2903 if (TREE_CODE (decl) != VAR_DECL)
2904 return 0;
2905
fabdc32d 2906 a = lookup_attribute ("eightbit_data", DECL_MACHINE_ATTRIBUTES (decl));
15dc331e
JL
2907 return a != NULL_TREE;
2908}
2909
887a8bd9
JL
2910/* Return nonzero if DECL is a variable that's in the tiny
2911 data area. */
2912
2913int
2914h8300_tiny_data_p (decl)
2915 tree decl;
2916{
2917 tree a;
2918
2919 if (TREE_CODE (decl) != VAR_DECL)
2920 return 0;
2921
2922 a = lookup_attribute ("tiny_data", DECL_MACHINE_ATTRIBUTES (decl));
2923 return a != NULL_TREE;
2924}
2925
f5b65a56
JL
2926/* Return nonzero if ATTR is a valid attribute for DECL.
2927 ATTRIBUTES are any existing attributes and ARGS are the arguments
2928 supplied with ATTR.
2929
2930 Supported attributes:
2931
97c5ec1d 2932 interrupt_handler: output a prologue and epilogue suitable for an
f5b65a56
JL
2933 interrupt handler.
2934
97c5ec1d 2935 function_vector: This function should be called through the
887a8bd9
JL
2936 function vector.
2937
2938 eightbit_data: This variable lives in the 8-bit data area and can
2939 be referenced with 8-bit absolute memory addresses.
2940
2941 tiny_data: This variable lives in the tiny data area and can be
2942 referenced with 16-bit absolute memory references. */
f5b65a56
JL
2943
2944int
2945h8300_valid_machine_decl_attribute (decl, attributes, attr, args)
2946 tree decl;
2947 tree attributes;
2948 tree attr;
2949 tree args;
2950{
2951 if (args != NULL_TREE)
2952 return 0;
2953
97c5ec1d 2954 if (is_attribute_p ("interrupt_handler", attr)
fabe72bb
JL
2955 || is_attribute_p ("OS_Task", attr)
2956 || is_attribute_p ("monitor", attr)
97c5ec1d 2957 || is_attribute_p ("function_vector", attr))
f5b65a56 2958 return TREE_CODE (decl) == FUNCTION_DECL;
15dc331e 2959
fabdc32d 2960 if (is_attribute_p ("eightbit_data", attr)
15dc331e
JL
2961 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
2962 {
2963 if (DECL_INITIAL (decl) == NULL_TREE)
2964 {
2965 warning ("Only initialized variables can be placed into the 8-bit area.");
2966 return 0;
2967 }
887a8bd9
JL
2968 DECL_SECTION_NAME (decl) = build_string (7, ".eight");
2969 return 1;
2970 }
2971
2972 if (is_attribute_p ("tiny_data", attr)
2973 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
2974 {
2975 if (DECL_INITIAL (decl) == NULL_TREE)
2976 {
2977 warning ("Only initialized variables can be placed into the 8-bit area.");
2978 return 0;
2979 }
2980 DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
15dc331e
JL
2981 return 1;
2982 }
2983
f5b65a56
JL
2984 return 0;
2985}
2986
887a8bd9
JL
2987extern struct obstack *saveable_obstack;
2988
2989h8300_encode_label (decl)
2990 tree decl;
2991{
2992 char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
2993 int len = strlen (str);
2994 char *newstr;
2995
2996 newstr = obstack_alloc (saveable_obstack, len + 2);
2997
2998 strcpy (newstr + 1, str);
f24b26ed 2999 *newstr = '&';
887a8bd9
JL
3000 XSTR (XEXP (DECL_RTL (decl), 0), 0) = newstr;
3001}
3002
bd93f126
JL
3003char *
3004output_simode_bld (bild, log2, operands)
3005 int bild;
3006 int log2;
3007 rtx operands[];
3008{
3009 /* Clear the destination register. */
a1616dd9 3010 if (TARGET_H8300H || TARGET_H8300S)
bd93f126
JL
3011 output_asm_insn ("sub.l\t%S0,%S0", operands);
3012 else
3013 output_asm_insn ("sub.w\t%e0,%e0\n\tsub.w\t%f0,%f0", operands);
3014
3015 /* Get the bit number we want to load. */
3016 if (log2)
3017 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));
3018
3019 /* Now output the bit load or bit inverse load, and store it in
3020 the destination. */
3021 if (bild)
3022 output_asm_insn ("bild\t%Z2,%Y1\n\tbst\t#0,%w0", operands);
3023 else
3024 output_asm_insn ("bld\t%Z2,%Y1\n\tbst\t#0,%w0", operands);
3025
3026 /* All done. */
3027 return "";
3028}
e6219736 3029
9ec36da5 3030/* Given INSN and its current length LENGTH, return the adjustment
e6219736
JL
3031 (in bytes) to correctly compute INSN's length.
3032
3033 We use this to get the lengths of various memory references correct. */
3034
3035h8300_adjust_insn_length (insn, length)
3036 rtx insn;
3037 int length;
3038{
3039 rtx pat = PATTERN (insn);
3040
3041 /* Adjust length for reg->mem and mem->reg copies. */
3042 if (GET_CODE (pat) == SET
3043 && (GET_CODE (SET_SRC (pat)) == MEM
3044 || GET_CODE (SET_DEST (pat)) == MEM))
3045 {
3046 /* This insn might need a length adjustment. */
3047 rtx addr;
3048
3049 if (GET_CODE (SET_SRC (pat)) == MEM)
3050 addr = XEXP (SET_SRC (pat), 0);
3051 else
3052 addr = XEXP (SET_DEST (pat), 0);
3053
3054 /* On the H8/300, only one adjustment is necessary; if the
3055 address mode is register indirect, then this insn is two
3056 bytes shorter than indicated in the machine description. */
3057 if (TARGET_H8300 && GET_CODE (addr) == REG)
3058 return -2;
3059
a1616dd9 3060 /* On the H8/300H and H8/S, register indirect is 6 bytes shorter than
e6219736 3061 indicated in the machine description. */
a1616dd9
JL
3062 if ((TARGET_H8300H || TARGET_H8300S)
3063 && GET_CODE (addr) == REG)
e6219736
JL
3064 return -6;
3065
a1616dd9
JL
3066 /* On the H8/300H and H8/300S, reg + d, for small displacements is 4
3067 bytes shorter than indicated in the machine description. */
3068 if ((TARGET_H8300H || TARGET_H8300S)
e6219736
JL
3069 && GET_CODE (addr) == PLUS
3070 && GET_CODE (XEXP (addr, 0)) == REG
3071 && GET_CODE (XEXP (addr, 1)) == CONST_INT
3072 && INTVAL (XEXP (addr, 1)) > -32768
3073 && INTVAL (XEXP (addr, 1)) < 32767)
3074 return -4;
887a8bd9 3075
a1616dd9 3076 /* On the H8/300H and H8/300S, abs:16 is two bytes shorter than the
887a8bd9 3077 more general abs:24. */
a1616dd9 3078 if ((TARGET_H8300H || TARGET_H8300S)
887a8bd9
JL
3079 && GET_CODE (addr) == SYMBOL_REF
3080 && TINY_DATA_NAME_P (XSTR (addr, 0)))
3081 return -2;
e6219736
JL
3082 }
3083
3084 /* Loading some constants needs adjustment. */
3085 if (GET_CODE (pat) == SET
3086 && GET_CODE (SET_SRC (pat)) == CONST_INT
3087 && GET_MODE (SET_DEST (pat)) == SImode
3088 && INTVAL (SET_SRC (pat)) != 0)
3089 {
3090 if (TARGET_H8300
3091 && ((INTVAL (SET_SRC (pat)) & 0xffff) == 0
3092 || ((INTVAL (SET_SRC (pat)) >> 16) & 0xffff) == 0))
3093 return -2;
3094
a1616dd9 3095 if (TARGET_H8300H || TARGET_H8300S)
e6219736
JL
3096 {
3097 int val = INTVAL (SET_SRC (pat));
3098
3099 if (val == (val & 0xff)
3100 || val == (val & 0xff00))
3101 return -6;
3102
3103 if (val == -4 || val == -2 || val == -1)
3104 return -6;
3105 }
3106 }
3107
dd4fd0a0
JL
3108 /* Shifts need various adjustments. */
3109 if (GET_CODE (pat) == PARALLEL
3110 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
3111 && (GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFTRT
3112 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == LSHIFTRT
3113 || GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASHIFT))
3114 {
3115 rtx src = SET_SRC (XVECEXP (pat, 0, 0));
3116 enum machine_mode mode = GET_MODE (src);
3117
3118 if (GET_CODE (XEXP (src, 1)) != CONST_INT)
3119 return 0;
3120
3121 /* QImode shifts by small constants take one insn
3122 per shift. So the adjustment is 20 (md length) -
3123 # shifts * 2. */
3124 if (mode == QImode && INTVAL (XEXP (src, 1)) <= 4)
3125 return -(20 - INTVAL (XEXP (src, 1)) * 2);
3126
3127 /* Similarly for HImode and SImode shifts by
a1616dd9
JL
3128 small constants on the H8/300H and H8/300S. */
3129 if ((TARGET_H8300H || TARGET_H8300S)
dd4fd0a0
JL
3130 && (mode == HImode || mode == SImode)
3131 && INTVAL (XEXP (src, 1)) <= 4)
3132 return -(20 - INTVAL (XEXP (src, 1)) * 2);
3133
3134 /* HImode shifts by small constants for the H8/300. */
3135 if (mode == HImode
3136 && INTVAL (XEXP (src, 1)) <= 4)
3137 return -(20 - (INTVAL (XEXP (src, 1))
3138 * (GET_CODE (src) == ASHIFT ? 2 : 4)));
3139
3140 /* SImode shifts by small constants for the H8/300. */
3141 if (mode == SImode
3142 && INTVAL (XEXP (src, 1)) <= 2)
3143 return -(20 - (INTVAL (XEXP (src, 1))
3144 * (GET_CODE (src) == ASHIFT ? 6 : 8)));
3145
3146 /* XXX ??? Could check for more shift/rotate cases here. */
3147 }
3148
e6219736
JL
3149 return 0;
3150}
This page took 0.744716 seconds and 5 git commands to generate.