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