]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/h8300/h8300.c
Fix signal prototype on SunOS to avoid C++ pedantic error
[thirdparty/gcc.git] / gcc / config / h8300 / h8300.c
CommitLineData
07aae5c2 1/* Subroutines for insn-output.c for Hitachi H8/300.
3c71736a 2 Copyright (C) 1992, 1993, 1994, 1995, 1996 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
SC
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"
38
39/* Forward declarations. */
40void print_operand_address ();
41char *index ();
42
f5b65a56
JL
43static int h8300_interrupt_function_p PROTO ((tree));
44static int h8300_funcvec_function_p PROTO ((tree));
45
48837e29
DE
46/* CPU_TYPE, says what cpu we're compiling for. */
47int cpu_type;
48
f5b65a56
JL
49/* True if the current function is an interrupt handler
50 (either via #pragma or an attribute specification). */
51int interrupt_handler;
52
07aae5c2
SC
53
54/* True if a #pragma saveall has been seen for the current function. */
55int pragma_saveall;
56
48837e29
DE
57static char *names_big[] =
58{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7"};
59
60static char *names_extended[] =
61{"er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"};
62
63static char *names_upper_extended[] =
64{"e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"};
65
66/* Points to one of the above. */
67/* ??? The above could be put in an array indexed by CPU_TYPE. */
68char **h8_reg_names;
69
70/* Various operations needed by the following, indexed by CPU_TYPE. */
71/* ??? The h8/300 assembler doesn't understand pop.w (yet). */
72
73static char *h8_push_ops[2] =
74{"push", "push.l"};
75static char *h8_pop_ops[2] =
76{"pop", "pop.l"};
77static char *h8_mov_ops[2] =
78{"mov.w", "mov.l"};
79
80char *h8_push_op, *h8_pop_op, *h8_mov_op;
81
82/* Initialize various cpu specific globals at start up. */
83
84void
85h8300_init_once ()
86{
87 if (TARGET_H8300)
88 {
89 cpu_type = (int) CPU_H8300;
90 h8_reg_names = names_big;
91 }
92 else
93 {
94 cpu_type = (int) CPU_H8300H;
95 h8_reg_names = names_extended;
96 }
97 h8_push_op = h8_push_ops[cpu_type];
98 h8_pop_op = h8_pop_ops[cpu_type];
99 h8_mov_op = h8_mov_ops[cpu_type];
100}
07aae5c2
SC
101
102char *
103byte_reg (x, b)
104 rtx x;
105 int b;
106{
48837e29
DE
107 static char *names_small[] =
108 {"r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
109 "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7lBAD", "r7hBAD"};
07aae5c2
SC
110
111 return names_small[REGNO (x) * 2 + b];
112}
113
114/* REGNO must be saved/restored across calls if this macro is true. */
48837e29
DE
115
116#define WORD_REG_USED(regno) \
117 (regno < 7 && \
f5b65a56 118 (interrupt_handler \
48837e29
DE
119 || pragma_saveall \
120 || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno]) \
121 || (regs_ever_live[regno] & !call_used_regs[regno])))
07aae5c2
SC
122
123/* Output assembly language to FILE for the operation OP with operand size
48837e29
DE
124 SIZE to adjust the stack pointer. */
125/* ??? FPED is currently unused. */
126
07aae5c2
SC
127static void
128dosize (file, op, size, fped)
129 FILE *file;
130 char *op;
131 unsigned int size;
132 int fped;
133{
134 switch (size)
135 {
136 case 4:
48837e29 137 /* ??? TARGET_H8300H can do this in one insn. */
07aae5c2
SC
138 case 3:
139 fprintf (file, "\t%ss\t#%d,sp\n", op, 2);
140 size -= 2;
141 /* Fall through... */
142 case 2:
143 case 1:
144 fprintf (file, "\t%ss\t#%d,sp\n", op, size);
145 size = 0;
146 break;
147 case 0:
148 break;
149 default:
48837e29
DE
150 if (TARGET_H8300)
151 fprintf (file, "\tmov.w\t#%d,r3\n\t%s.w\tr3,sp\n", size, op);
152 else
153 fprintf (file, "\t%s\t#%d,sp\n", op, size);
07aae5c2
SC
154 size = 0;
155 break;
156 }
157}
158
159/* Output assembly language code for the function prologue. */
48837e29
DE
160static int push_order[FIRST_PSEUDO_REGISTER] =
161{6, 5, 4, 3, 2, 1, 0, -1, -1};
162static int pop_order[FIRST_PSEUDO_REGISTER] =
163{0, 1, 2, 3, 4, 5, 6, -1, -1};
07aae5c2
SC
164
165/* This is what the stack looks like after the prolog of
166 a function with a frame has been set up:
167
48837e29
DE
168 <args>
169 PC
170 FP <- fp
171 <locals>
172 <saved registers> <- sp
07aae5c2
SC
173
174 This is what the stack looks like after the prolog of
175 a function which doesn't have a frame:
176
48837e29
DE
177 <args>
178 PC
179 <locals>
180 <saved registers> <- sp
07aae5c2
SC
181*/
182
48837e29
DE
183int current_function_anonymous_args;
184
185/* Extra arguments to pop, in words (IE: 2 bytes for 300, 4 for 300h */
186static int extra_pop;
187
07aae5c2
SC
188void
189function_prologue (file, size)
190 FILE *file;
191 int size;
192{
193 register int mask = 0;
48837e29 194 int fsize = (size + STACK_BOUNDARY / 8 - 1) & -STACK_BOUNDARY / 8;
07aae5c2 195 int idx;
48837e29 196 extra_pop = 0;
07aae5c2 197
f5b65a56
JL
198 if (h8300_interrupt_function_p (current_function_decl))
199 interrupt_handler = 1;
200
48837e29 201 if (current_function_anonymous_args && TARGET_QUICKCALL)
07aae5c2 202 {
48837e29
DE
203 /* Push regs as if done by caller, and move around return address. */
204
205 switch (current_function_args_info.nbytes / UNITS_PER_WORD)
206 {
207 case 0:
208 /* get ret addr */
209 fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[3]);
210 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[2]);
211 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[1]);
212 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[0]);
213 /* push it again */
214 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[3]);
215 extra_pop = 3;
216 break;
217 case 1:
218 /* get ret addr */
219 fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[3]);
220 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[2]);
221 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[1]);
222 /* push it again */
223 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[3]);
224 extra_pop = 2;
225 break;
226 case 2:
227 /* get ret addr */
228 fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[3]);
229 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[2]);
230 /* push it again */
231 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[3]);
232 extra_pop = 1;
233 break;
234 default:
235 fprintf (file, "; varargs\n");
236 break;
237 }
238 }
07aae5c2 239
48837e29
DE
240 if (frame_pointer_needed)
241 {
242 /* Push fp */
243 fprintf (file, "\t%s\t%s\n", h8_push_op,
244 h8_reg_names[FRAME_POINTER_REGNUM]);
245 fprintf (file, "\t%s\t%s,%s\n", h8_mov_op,
246 h8_reg_names[STACK_POINTER_REGNUM],
247 h8_reg_names[FRAME_POINTER_REGNUM]);
248
249 /* leave room for locals */
07aae5c2
SC
250 dosize (file, "sub", fsize, 1);
251
48837e29
DE
252 /* Push the rest of the registers */
253 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
07aae5c2
SC
254 {
255 int regno = push_order[idx];
256
48837e29
DE
257 if (regno >= 0 && WORD_REG_USED (regno) && regno != FRAME_POINTER_REGNUM)
258 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[regno]);
07aae5c2
SC
259 }
260 }
261 else
262 {
263 dosize (file, "sub", fsize, 0);
264 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
265 {
266 int regno = push_order[idx];
267
48837e29
DE
268 if (regno >= 0 && WORD_REG_USED (regno))
269 fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[regno]);
07aae5c2
SC
270 }
271 }
272}
273
274/* Output assembly language code for the function epilogue. */
275
276void
277function_epilogue (file, size)
278 FILE *file;
279 int size;
280{
281 register int regno;
282 register int mask = 0;
48837e29 283 int fsize = (size + STACK_BOUNDARY / 8 - 1) & -STACK_BOUNDARY / 8;
07aae5c2
SC
284 int nregs;
285 int offset;
286 int idx;
287 rtx insn = get_last_insn ();
288
289 /* If the last insn was a BARRIER, we don't have to write any code. */
290 if (GET_CODE (insn) == NOTE)
291 insn = prev_nonnote_insn (insn);
292 if (insn && GET_CODE (insn) == BARRIER)
293 return;
294
295 nregs = 0;
296
297 if (frame_pointer_needed)
298 {
48837e29 299 /* Pop saved registers */
07aae5c2
SC
300 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
301 {
302 regno = pop_order[idx];
48837e29
DE
303 if (regno >= 0 && regno != FRAME_POINTER_REGNUM && WORD_REG_USED (regno))
304 fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[regno]);
07aae5c2 305 }
48837e29 306 /* deallocate locals */
07aae5c2 307 dosize (file, "add", fsize, 1);
48837e29
DE
308 /* pop frame pointer */
309 fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[FRAME_POINTER_REGNUM]);
07aae5c2
SC
310 }
311 else
312 {
48837e29 313 /* pop saved registers */
07aae5c2
SC
314 for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
315 {
316 regno = pop_order[idx];
48837e29
DE
317 if (regno >= 0 && WORD_REG_USED (regno))
318 fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[regno]);
07aae5c2 319 }
48837e29 320 /* deallocate locals */
07aae5c2
SC
321 dosize (file, "add", fsize, 0);
322 }
48837e29
DE
323
324 if (extra_pop)
325 {
326 fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[3]);
327 while (extra_pop)
328 {
329 fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[2]);
330 extra_pop--;
331 }
332 fprintf (file, "\tjmp @%s\n", h8_reg_names[3]);
333 }
07aae5c2 334 else
48837e29 335 {
f5b65a56 336 if (interrupt_handler)
48837e29
DE
337 fprintf (file, "\trte\n");
338 else
339 fprintf (file, "\trts\n");
340 }
07aae5c2 341
f5b65a56 342 interrupt_handler = 0;
07aae5c2 343 pragma_saveall = 0;
48837e29
DE
344
345 current_function_anonymous_args = 0;
346}
347
348/* Output assembly code for the start of the file. */
349
350asm_file_start (file)
351 FILE *file;
352{
353 fprintf (file, ";\tGCC For the Hitachi H8/300\n");
354 fprintf (file, ";\tBy Hitachi America Ltd and Cygnus Support\n");
355 fprintf (file, ";\trelease F-1\n");
356 if (optimize)
357 fprintf (file, "; -O%d\n", optimize);
358 if (TARGET_H8300H)
359 fprintf (file, "\n\t.h8300h\n");
360 else
361 fprintf (file, "\n\n");
362 output_file_directive (file, main_input_filename);
363}
364
365/* Output assembly language code for the end of file. */
366
367void
368asm_file_end (file)
369 FILE *file;
370{
371 fprintf (file, "\t.end\n");
07aae5c2
SC
372}
373\f
48837e29
DE
374/* Return true if VALUE is a valid constant for constraint 'P'.
375 IE: VALUE is a power of two <= 2**15. */
07aae5c2
SC
376
377int
48837e29
DE
378small_power_of_two (value)
379 int value;
07aae5c2
SC
380{
381 switch (value)
382 {
383 case 1:
384 case 2:
385 case 4:
386 case 8:
387 case 16:
388 case 32:
389 case 64:
390 case 128:
07aae5c2
SC
391 case 256:
392 case 512:
393 case 1024:
394 case 2048:
395 case 4096:
396 case 8192:
397 case 16384:
398 case 32768:
399 return 1;
400 }
401 return 0;
402}
403
48837e29
DE
404/* Return true if VALUE is a valid constant for constraint 'O', which
405 means that the constant would be ok to use as a bit for a bclr
406 instruction. */
407
408int
409ok_for_bclr (value)
410 int value;
411{
412 return small_power_of_two ((~value) & 0xff);
413}
414
07aae5c2
SC
415/* Return true is OP is a valid source operand for an integer move
416 instruction. */
48837e29 417
07aae5c2
SC
418int
419general_operand_src (op, mode)
420 rtx op;
421 enum machine_mode mode;
422{
48837e29
DE
423 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
424 return 1;
07aae5c2
SC
425 return general_operand (op, mode);
426}
427
428/* Return true if OP is a valid destination operand for an integer move
429 instruction. */
48837e29 430
07aae5c2
SC
431int
432general_operand_dst (op, mode)
433 rtx op;
434 enum machine_mode mode;
435{
48837e29
DE
436 if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == PRE_DEC)
437 return 1;
07aae5c2
SC
438 return general_operand (op, mode);
439}
48837e29
DE
440
441/* Return true if OP is a const valid for a bit clear instruction. */
442
443int
444o_operand (operand, mode)
445 rtx operand;
446 enum machine_mode mode;
447{
448 return (GET_CODE (operand) == CONST_INT
449 && CONST_OK_FOR_O (INTVAL (operand)));
450}
451
452/* Return true if OP is a const valid for a bit set or bit xor instruction. */
453
454int
455p_operand (operand, mode)
456 rtx operand;
457 enum machine_mode mode;
458{
459 return (GET_CODE (operand) == CONST_INT
460 && CONST_OK_FOR_P (INTVAL (operand)));
461}
462
463/* Return true if OP is a valid call operand. */
464
465int
466call_insn_operand (op, mode)
467 rtx op;
468 enum machine_mode mode;
469{
470 if (GET_CODE (op) == MEM)
471 {
472 rtx inside = XEXP (op, 0);
473 if (register_operand (inside, Pmode))
474 return 1;
475 if (CONSTANT_ADDRESS_P (inside))
476 return 1;
477 }
478 return 0;
479}
480
f5b65a56
JL
481/* Return true if OP is a valid call operand, and OP represents
482 an operand for a small call (4 bytes instead of 6 bytes). */
483
484int
485small_call_insn_operand (op, mode)
486 rtx op;
487 enum machine_mode mode;
488{
489 if (GET_CODE (op) == MEM)
490 {
491 rtx inside = XEXP (op, 0);
492
493 /* Register indirect is a small call. */
494 if (register_operand (inside, Pmode))
495 return 1;
496
497 /* A call through the function vector is a small
498 call too. */
499 if (GET_CODE (inside) == SYMBOL_REF
500 && SYMBOL_REF_FLAG (inside))
501 return 1;
502 }
503 /* Otherwise it's a large call. */
504 return 0;
505}
506
48837e29
DE
507/* Return true if OP is a valid jump operand. */
508
509int
510jump_address_operand (op, mode)
511 rtx op;
512 enum machine_mode mode;
513{
514 if (GET_CODE (op) == REG)
515 return mode == Pmode;
516
517 if (GET_CODE (op) == MEM)
518 {
519 rtx inside = XEXP (op, 0);
520 if (register_operand (inside, Pmode))
521 return 1;
522 if (CONSTANT_ADDRESS_P (inside))
523 return 1;
524 }
525 return 0;
526}
527
528/* Recognize valid operands for bitfield instructions. */
529
530extern int rtx_equal_function_value_matters;
531
532int
533bit_operand (op, mode)
534 rtx op;
535 enum machine_mode mode;
536{
537 /* We can except any general operand, expept that MEM operands must
538 be limited to those that use addresses valid for the 'U' constraint. */
539 if (!general_operand (op, mode))
540 return 0;
541
542 /* Accept any mem during RTL generation. Otherwise, the code that does
543 insv and extzv will think that we can not handle memory. However,
544 to avoid reload problems, we only accept 'U' MEM operands after RTL
545 generation. This means that any named pattern which uses this predicate
546 must force its operands to match 'U' before emitting RTL. */
547
548 if (GET_CODE (op) == REG)
549 return 1;
550 if (GET_CODE (op) == SUBREG)
551 return 1;
552 if (!rtx_equal_function_value_matters)
553 {
554 /* We're building rtl */
555 return GET_CODE (op) == MEM;
556 }
557 else
558 {
559 return (GET_CODE (op) == MEM
560 && EXTRA_CONSTRAINT (op, 'U'));
561 }
562}
563
564/* Recognize valid operators for bit test. */
565
566int
567eq_operator (x, mode)
568 rtx x;
569 enum machine_mode mode;
570{
571 return (GET_CODE (x) == EQ || GET_CODE (x) == NE);
572}
573
07aae5c2 574/* Handle machine specific pragmas for compatibility with existing
48837e29 575 compilers for the H8/300.
07aae5c2
SC
576
577 pragma saveall generates prolog/epilog code which saves and
578 restores all the registers on function entry.
48837e29 579
07aae5c2
SC
580 pragma interrupt saves and restores all registers, and exits with
581 an rte instruction rather than an rts. A pointer to a function
582 with this attribute may be safely used in an interrupt vector. */
48837e29 583
07aae5c2 584int
05a81fe5 585handle_pragma (file, c)
07aae5c2 586 FILE *file;
05a81fe5 587 int c;
07aae5c2 588{
07aae5c2 589 char pbuf[20];
48837e29 590 int psize = 0;
07aae5c2 591
07aae5c2
SC
592 while (c == ' ' || c == '\t')
593 c = getc (file);
594
05a81fe5 595 if (c != '\n' & c != EOF)
07aae5c2 596 {
48837e29 597 while (psize < sizeof (pbuf) - 1
05a81fe5 598 && isalpha (c))
48837e29
DE
599 {
600 pbuf[psize++] = c;
601 c = getc (file);
602 }
603 pbuf[psize] = 0;
05a81fe5
DE
604
605 if (strcmp (pbuf, "interrupt") == 0)
f5b65a56 606 interrupt_handler = 1;
05a81fe5
DE
607 else if (strcmp (pbuf, "saveall") == 0)
608 pragma_saveall = 1;
609
610 while (c != '\n' && c != EOF)
611 c = getc (file);
48837e29 612 }
05a81fe5 613
07aae5c2
SC
614 return c;
615}
616\f
617/* If the next arg with MODE and TYPE is to be passed in a register, return
618 the rtx to represent where it is passed. CUM represents the state after
619 the last argument. NAMED is not used. */
620
48837e29
DE
621static char *hand_list[] =
622{
623 "__main",
624 "__cmpsi2",
625 "__divhi3",
626 "__modhi3",
627 "__udivhi3",
628 "__umodhi3",
629 "__divsi3",
630 "__modsi3",
631 "__udivsi3",
632 "__umodsi3",
633 "__mulhi3",
634 "__mulsi3",
635 "__reg_memcpy",
636 "__reg_memset",
637 "__ucmpsi2",
638 0,
639};
640
641/* Return an RTX to represent where a value with mode MODE will be returned
642 from a function. If the result is 0, the argument is pushed. */
643
07aae5c2
SC
644rtx
645function_arg (cum, mode, type, named)
646 CUMULATIVE_ARGS *cum;
647 enum machine_mode mode;
648 tree type;
649 int named;
650{
651 rtx result = 0;
48837e29
DE
652 char *fname;
653 int regpass = 0;
654
655 /* Pass 3 regs worth of data in regs when user asked on the command line. */
656 if (TARGET_QUICKCALL)
657 regpass = 3;
658
659 /* If calling hand written assembler, use 4 regs of args. */
660
661 if (cum->libcall)
662 {
663 char **p;
664
665 fname = XSTR (cum->libcall, 0);
666
667 /* See if this libcall is one of the hand coded ones. */
07aae5c2 668
48837e29
DE
669 for (p = hand_list; *p && strcmp (*p, fname) != 0; p++)
670 ;
07aae5c2 671
48837e29
DE
672 if (*p)
673 regpass = 4;
674 }
675
676 if (regpass)
677 {
678 int size;
679
680 if (mode == BLKmode)
681 size = int_size_in_bytes (type);
682 else
683 size = GET_MODE_SIZE (mode);
684
685 if (size + cum->nbytes > regpass * UNITS_PER_WORD)
686 {
687 result = 0;
688 }
689 else
690 {
691 switch (cum->nbytes / UNITS_PER_WORD)
692 {
693 case 0:
694 result = gen_rtx (REG, mode, 0);
695 break;
696 case 1:
697 result = gen_rtx (REG, mode, 1);
698 break;
699 case 2:
700 result = gen_rtx (REG, mode, 2);
701 break;
702 case 3:
703 result = gen_rtx (REG, mode, 3);
704 break;
705 default:
706 result = 0;
707 }
708 }
709 }
07aae5c2 710
48837e29
DE
711 return result;
712}
713\f
714/* Return the cost of the rtx R with code CODE. */
07aae5c2 715
48837e29
DE
716int
717const_costs (r, c)
718 rtx r;
719 enum rtx_code c;
720{
721 switch (c)
07aae5c2 722 {
48837e29
DE
723 case CONST_INT:
724 switch (INTVAL (r))
07aae5c2
SC
725 {
726 case 0:
48837e29 727 case 1:
07aae5c2 728 case 2:
48837e29
DE
729 case -1:
730 case -2:
07aae5c2 731 return 0;
48837e29
DE
732 default:
733 return 1;
07aae5c2 734 }
48837e29
DE
735
736 case CONST:
737 case LABEL_REF:
738 case SYMBOL_REF:
739 return 3;
740
741 case CONST_DOUBLE:
742 return 20;
743
744 default:
745 return 4;
07aae5c2 746 }
07aae5c2 747}
48837e29 748\f
07aae5c2
SC
749/* Documentation for the machine specific operand escapes:
750
48837e29 751 'A' print rn in h8/300 mode, erN in H8/300H mode
07aae5c2 752 'C' print (operand - 2).
48837e29
DE
753 'E' like s but negative.
754 'F' like t but negative.
755 'G' constant just the negative
07aae5c2
SC
756 'L' fake label, changed after used twice.
757 'M' turn a 'M' constant into its negative mod 2.
48837e29
DE
758 'P' if operand is incing/decing sp, print .w, otherwise .b.
759 'S' print operand as a long word
07aae5c2 760 'T' print operand as a word
48837e29
DE
761 'U' if operand is incing/decing sp, print l, otherwise nothing.
762 'V' find the set bit, and print its number.
763 'W' find the clear bit, and print its number.
764 'X' print operand as a byte
07aae5c2 765 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
48837e29
DE
766 'Z' print int & 7.
767 'b' print the bit opcode
768 'c' print the ibit opcode
769 'd' bcc if EQ, bcs if NE
770 'e' first word of 32 bit value - if reg, then least reg. if mem
771 then least. if const then most sig word
772 'f' second word of 32 bit value - if reg, then biggest reg. if mem
773 then +2. if const then least sig word
774 'g' bcs if EQ, bcc if NE
07aae5c2
SC
775 'j' print operand as condition code.
776 'k' print operand as reverse condition code.
48837e29
DE
777 's' print as low byte of 16 bit value
778 't' print as high byte of 16 bit value
779 'w' print as low byte of 32 bit value
780 'x' print as 2nd byte of 32 bit value
781 'y' print as 3rd byte of 32 bit value
782 'z' print as msb of 32 bit value
783*/
07aae5c2
SC
784
785/* Return assembly language string which identifies a comparison type. */
786
48837e29 787static char *
07aae5c2
SC
788cond_string (code)
789 enum rtx_code code;
790{
791 switch (code)
792 {
793 case NE:
794 return "ne";
795 case EQ:
796 return "eq";
797 case GE:
798 return "ge";
799 case GT:
800 return "gt";
801 case LE:
802 return "le";
803 case LT:
804 return "lt";
805 case GEU:
806 return "hs";
807 case GTU:
808 return "hi";
809 case LEU:
810 return "ls";
811 case LTU:
812 return "lo";
813 default:
814 abort ();
815 }
816}
817
818/* Print operand X using operand code CODE to assembly language output file
819 FILE. */
820
821void
822print_operand (file, x, code)
823 FILE *file;
824 rtx x;
825 int code;
826{
827 /* This is used to general unique labels for the 'L' code. */
828 static int lab = 1000;
829
830 /* This is used for communication between the 'P' and 'U' codes. */
831 static char *last_p;
832
269c14e1 833 /* This is used for communication between codes V,W,Z and Y. */
07aae5c2
SC
834 static int bitint;
835
836 switch (code)
837 {
48837e29 838 case 'A':
07aae5c2 839 if (GET_CODE (x) == REG)
48837e29 840 fprintf (file, "%s", h8_reg_names[REGNO (x)]);
07aae5c2
SC
841 else
842 goto def;
843 break;
48837e29
DE
844 case 'C':
845 fprintf (file, "#%d", INTVAL (x) - 2);
846 break;
847 case 'E':
848 switch (GET_CODE (x))
849 {
850 case REG:
851 fprintf (file, "%sl", names_big[REGNO (x)]);
852 break;
853 case CONST_INT:
854 fprintf (file, "#%d", (-INTVAL (x)) & 0xff);
855 break;
856 default:
857 abort ();
858 }
859 break;
860 case 'F':
861 switch (GET_CODE (x))
862 {
863 case REG:
864 fprintf (file, "%sh", names_big[REGNO (x)]);
865 break;
866 case CONST_INT:
867 fprintf (file, "#%d", ((-INTVAL (x)) & 0xff00) >> 8);
868 break;
869 default:
870 abort ();
871 }
872 break;
07aae5c2
SC
873 case 'G':
874 if (GET_CODE (x) != CONST_INT)
875 abort ();
876 fprintf (file, "#%d", 0xff & (-INTVAL (x)));
877 break;
48837e29
DE
878 case 'L':
879 /* 'L' must always be used twice in a single pattern. It generates
ddd5a7c1 880 the same label twice, and then will generate a unique label the
48837e29
DE
881 next time it is used. */
882 asm_fprintf (file, "tl%d", (lab++) / 2);
07aae5c2 883 break;
48837e29
DE
884 case 'M':
885 /* For 3/-3 and 4/-4, the other 2 is handled separately. */
886 switch (INTVAL (x))
887 {
888 case 2:
889 case 4:
890 case -2:
891 case -4:
892 fprintf (file, "#2");
893 break;
894 case 1:
895 case 3:
896 case -1:
897 case -3:
898 fprintf (file, "#1");
899 break;
900 default:
901 abort ();
902 }
07aae5c2 903 break;
48837e29
DE
904 case 'P':
905 if (REGNO (XEXP (XEXP (x, 0), 0)) == STACK_POINTER_REGNUM)
906 {
907 last_p = "";
908 fprintf (file, ".w");
909 }
07aae5c2 910 else
48837e29
DE
911 {
912 last_p = "l";
913 fprintf (file, ".b");
914 }
07aae5c2 915 break;
48837e29
DE
916 case 'S':
917 if (GET_CODE (x) == REG)
918 fprintf (file, "%s", names_extended[REGNO (x)]);
07aae5c2 919 else
48837e29 920 goto def;
07aae5c2 921 break;
48837e29
DE
922 case 'T':
923 if (GET_CODE (x) == REG)
924 fprintf (file, "%s", names_big[REGNO (x)]);
07aae5c2 925 else
48837e29 926 goto def;
07aae5c2 927 break;
48837e29
DE
928 case 'U':
929 fprintf (file, "%s%s", names_big[REGNO (x)], last_p);
07aae5c2 930 break;
48837e29
DE
931 case 'V':
932 bitint = exact_log2 (INTVAL (x));
933 if (bitint == -1)
07aae5c2 934 abort ();
07aae5c2
SC
935 fprintf (file, "#%d", bitint & 7);
936 break;
48837e29 937 case 'W':
07aae5c2
SC
938 bitint = exact_log2 ((~INTVAL (x)) & 0xff);
939 if (bitint == -1)
940 abort ();
941 fprintf (file, "#%d", bitint & 7);
942 break;
48837e29
DE
943 case 'X':
944 if (GET_CODE (x) == REG)
945 fprintf (file, "%s", byte_reg (x, 0));
946 else
947 goto def;
948 break;
949 case 'Y':
07aae5c2
SC
950 if (bitint == -1)
951 abort ();
48837e29
DE
952 if (GET_CODE (x) == REG)
953 fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
954 else
955 print_operand (file, x, 0);
956 bitint = -1;
957 break;
958 case 'Z':
959 bitint = INTVAL (x);
07aae5c2
SC
960 fprintf (file, "#%d", bitint & 7);
961 break;
48837e29
DE
962 case 'b':
963 switch (GET_CODE (x))
07aae5c2 964 {
48837e29
DE
965 case IOR:
966 fprintf (file, "bor");
967 break;
968 case XOR:
969 fprintf (file, "bxor");
970 break;
971 case AND:
972 fprintf (file, "band");
973 break;
07aae5c2 974 }
48837e29
DE
975 break;
976 case 'c':
977 switch (GET_CODE (x))
07aae5c2 978 {
48837e29
DE
979 case IOR:
980 fprintf (file, "bior");
981 break;
982 case XOR:
983 fprintf (file, "bixor");
984 break;
985 case AND:
986 fprintf (file, "biand");
987 break;
07aae5c2
SC
988 }
989 break;
48837e29
DE
990 case 'd':
991 switch (GET_CODE (x))
07aae5c2 992 {
48837e29
DE
993 case EQ:
994 fprintf (file, "bcc");
07aae5c2 995 break;
48837e29
DE
996 case NE:
997 fprintf (file, "bcs");
07aae5c2 998 break;
07aae5c2
SC
999 default:
1000 abort ();
1001 }
1002 break;
07aae5c2
SC
1003 case 'e':
1004 switch (GET_CODE (x))
1005 {
1006 case REG:
48837e29
DE
1007 if (TARGET_H8300)
1008 fprintf (file, "%s", names_big[REGNO (x)]);
1009 else
1010 fprintf (file, "%s", names_upper_extended[REGNO (x)]);
07aae5c2
SC
1011 break;
1012 case MEM:
1013 x = adj_offsettable_operand (x, 0);
1014 print_operand (file, x, 0);
1015 break;
1016 case CONST_INT:
1017 fprintf (file, "#%d", ((INTVAL (x) >> 16) & 0xffff));
1018 break;
1019 default:
1020 abort ();
1021 break;
1022 }
1023 break;
07aae5c2
SC
1024 case 'f':
1025 switch (GET_CODE (x))
1026 {
1027 case REG:
48837e29
DE
1028 if (TARGET_H8300)
1029 fprintf (file, "%s", names_big[REGNO (x) + 1]);
1030 else
1031 fprintf (file, "%s", names_big[REGNO (x)]);
07aae5c2 1032 break;
07aae5c2
SC
1033 case MEM:
1034 x = adj_offsettable_operand (x, 2);
1035 print_operand (file, x, 0);
1036 break;
07aae5c2
SC
1037 case CONST_INT:
1038 fprintf (file, "#%d", INTVAL (x) & 0xffff);
1039 break;
07aae5c2
SC
1040 default:
1041 abort ();
1042 }
1043 break;
48837e29 1044 case 'g':
07aae5c2
SC
1045 switch (GET_CODE (x))
1046 {
48837e29
DE
1047 case NE:
1048 fprintf (file, "bcc");
07aae5c2 1049 break;
48837e29
DE
1050 case EQ:
1051 fprintf (file, "bcs");
07aae5c2 1052 break;
07aae5c2
SC
1053 default:
1054 abort ();
1055 }
1056 break;
07aae5c2
SC
1057 case 'j':
1058 asm_fprintf (file, cond_string (GET_CODE (x)));
1059 break;
07aae5c2
SC
1060 case 'k':
1061 asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
1062 break;
48837e29
DE
1063 case 's':
1064 if (GET_CODE (x) == CONST_INT)
1065 fprintf (file, "#%d", (INTVAL (x)) & 0xff);
1066 else
1067 fprintf (file, "%s", byte_reg (x, 0));
1068 break;
1069 case 't':
1070 if (GET_CODE (x) == CONST_INT)
1071 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1072 else
1073 fprintf (file, "%s", byte_reg (x, 1));
1074 break;
1075 case 'u':
1076 if (GET_CODE (x) != CONST_INT)
1077 abort ();
1078 fprintf (file, "%d", INTVAL (x));
1079 break;
1080 case 'w':
1081 if (GET_CODE (x) == CONST_INT)
1082 fprintf (file, "#%d", INTVAL (x) & 0xff);
1083 else
1084 fprintf (file, "%s", byte_reg (x, TARGET_H8300 ? 2 : 0));
1085 break;
1086 case 'x':
1087 if (GET_CODE (x) == CONST_INT)
1088 fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
1089 else
1090 fprintf (file, "%s", byte_reg (x, TARGET_H8300 ? 3 : 1));
1091 break;
1092 case 'y':
1093 if (GET_CODE (x) == CONST_INT)
1094 fprintf (file, "#%d", (INTVAL (x) >> 16) & 0xff);
1095 else
1096 fprintf (file, "%s", byte_reg (x, 0));
1097 break;
1098 case 'z':
1099 if (GET_CODE (x) == CONST_INT)
1100 fprintf (file, "#%d", (INTVAL (x) >> 24) & 0xff);
1101 else
1102 fprintf (file, "%s", byte_reg (x, 1));
1103 break;
1104
07aae5c2 1105 default:
48837e29 1106 def:
07aae5c2
SC
1107 switch (GET_CODE (x))
1108 {
1109 case REG:
48837e29
DE
1110 switch (GET_MODE (x))
1111 {
1112 case QImode:
269c14e1 1113#if 0 /* Is it asm ("mov.b %0,r2l", ...) */
48837e29
DE
1114 fprintf (file, "%s", byte_reg (x, 0));
1115#else /* ... or is it asm ("mov.b %0l,r2l", ...) */
1116 fprintf (file, "%s", names_big[REGNO (x)]);
1117#endif
1118 break;
1119 case HImode:
1120 fprintf (file, "%s", names_big[REGNO (x)]);
1121 break;
1122 case SImode:
8977e8a7 1123 case SFmode:
48837e29
DE
1124 fprintf (file, "%s", names_extended[REGNO (x)]);
1125 break;
1126 default:
1127 abort ();
1128 }
07aae5c2
SC
1129 break;
1130
1131 case MEM:
1132 fprintf (file, "@");
1133 output_address (XEXP (x, 0));
1134 break;
1135
1136 case CONST_INT:
1137 case SYMBOL_REF:
1138 case CONST:
1139 case LABEL_REF:
1140 fprintf (file, "#");
1141 print_operand_address (file, x);
1142 break;
1143 }
1144 }
1145}
1146
1147/* Output assembly language output for the address ADDR to FILE. */
1148
1149void
1150print_operand_address (file, addr)
1151 FILE *file;
1152 rtx addr;
1153{
1154 switch (GET_CODE (addr))
1155 {
1156 case REG:
48837e29 1157 fprintf (file, "%s", h8_reg_names[REGNO (addr)]);
07aae5c2
SC
1158 break;
1159
1160 case PRE_DEC:
48837e29 1161 fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
07aae5c2
SC
1162 break;
1163
1164 case POST_INC:
48837e29 1165 fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);
07aae5c2
SC
1166 break;
1167
1168 case PLUS:
1169 fprintf (file, "(");
1170 if (GET_CODE (XEXP (addr, 0)) == REG)
1171 {
1172 /* reg,foo */
1173 print_operand_address (file, XEXP (addr, 1));
1174 fprintf (file, ",");
1175 print_operand_address (file, XEXP (addr, 0));
1176 }
1177 else
1178 {
1179 /* foo+k */
1180 print_operand_address (file, XEXP (addr, 0));
1181 fprintf (file, "+");
1182 print_operand_address (file, XEXP (addr, 1));
1183 }
1184 fprintf (file, ")");
1185 break;
1186
1187 case CONST_INT:
48837e29
DE
1188 {
1189 /* Since the h8/300 only has 16 bit pointers, negative values are also
1190 those >= 32768. This happens for example with pointer minus a
1191 constant. We don't want to turn (char *p - 2) into
1192 (char *p + 65534) because loop unrolling can build upon this
1193 (IE: char *p + 131068). */
1194 int n = INTVAL (addr);
1195 if (TARGET_H8300)
1196 n = (int) (short) n;
1197 if (n < 0)
1198 /* ??? Why the special case for -ve values? */
1199 fprintf (file, "-%d", -n);
1200 else
1201 fprintf (file, "%d", n);
1202 break;
1203 }
07aae5c2
SC
1204
1205 default:
1206 output_addr_const (file, addr);
1207 break;
1208 }
1209}
1210\f
07aae5c2
SC
1211/* Output all insn addresses and their sizes into the assembly language
1212 output file. This is helpful for debugging whether the length attributes
1213 in the md file are correct. This is not meant to be a user selectable
1214 option. */
1215
1216void
1217final_prescan_insn (insn, operand, num_operands)
1218 rtx insn, *operand;
1219 int num_operands;
1220{
1221 /* This holds the last insn address. */
1222 static int last_insn_address = 0;
1223
1224 int uid = INSN_UID (insn);
1225
48837e29
DE
1226 if (TARGET_RTL_DUMP)
1227 {
1228 fprintf (asm_out_file, "\n****************");
1229 print_rtl (asm_out_file, PATTERN (insn));
1230 fprintf (asm_out_file, "\n");
1231 }
1232
07aae5c2
SC
1233 if (TARGET_ADDRESSES)
1234 {
48837e29 1235 fprintf (asm_out_file, "; 0x%x %d\n", insn_addresses[uid],
07aae5c2
SC
1236 insn_addresses[uid] - last_insn_address);
1237 last_insn_address = insn_addresses[uid];
1238 }
1239}
1240
48837e29
DE
1241/* Prepare for an SI sized move. */
1242
1243int
1244do_movsi (operands)
1245 rtx operands[];
07aae5c2 1246{
48837e29
DE
1247 rtx src = operands[1];
1248 rtx dst = operands[0];
1249 if (!reload_in_progress && !reload_completed)
1250 {
1251 if (!register_operand (dst, GET_MODE (dst)))
1252 {
1253 rtx tmp = gen_reg_rtx (GET_MODE (dst));
1254 emit_move_insn (tmp, src);
1255 operands[1] = tmp;
1256 }
1257 }
1258 return 0;
1259}
1260
1261/* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
1262 Define the offset between two registers, one to be eliminated, and the other
1263 its replacement, at the start of a routine. */
07aae5c2 1264
48837e29
DE
1265int
1266initial_offset (from, to)
1267{
1268 int offset = 0;
1269
1270 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1271 offset = UNITS_PER_WORD + frame_pointer_needed * UNITS_PER_WORD;
1272 else
07aae5c2 1273 {
48837e29
DE
1274 int regno;
1275
1276 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1277 if ((regs_ever_live[regno]
1278 && (!call_used_regs[regno] || regno == FRAME_POINTER_REGNUM)))
1279 offset += UNITS_PER_WORD;
1280
1281 /* See the comments for get_frame_size. We need to round it up to
1282 STACK_BOUNDARY. */
1283
1284 offset += ((get_frame_size () + STACK_BOUNDARY / BITS_PER_UNIT - 1)
1285 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
1286
1287 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1288 offset += UNITS_PER_WORD; /* Skip saved PC */
1289 }
1290 return offset;
1291}
1292
1293/* Update the condition code from the insn. */
1294
1295int
1296notice_update_cc (body, insn)
1297 rtx body;
1298 rtx insn;
1299{
1300 switch (get_attr_cc (insn))
1301 {
1302 case CC_NONE:
269c14e1 1303 /* Insn does not affect CC at all. */
48837e29
DE
1304 break;
1305
1306 case CC_NONE_0HIT:
269c14e1 1307 /* Insn does not change CC, but the 0'th operand has been changed. */
48837e29
DE
1308 if (cc_status.value1 != 0
1309 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
1310 cc_status.value1 = 0;
269c14e1 1311 /* ??? Is value2 ever set?. */
48837e29
DE
1312 if (cc_status.value2 != 0
1313 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value2))
1314 cc_status.value2 = 0;
48837e29
DE
1315 break;
1316
1317 case CC_SET:
269c14e1
DE
1318 /* Insn sets the Z,N flags of CC to recog_operand[0].
1319 V is always set to 0. C may or may not be set to 0 but that's ok
1320 because alter_cond will change tests to use EQ/NE. */
48837e29 1321 CC_STATUS_INIT;
269c14e1 1322 cc_status.flags |= CC_OVERFLOW_0 | CC_NO_CARRY;
48837e29
DE
1323 cc_status.value1 = recog_operand[0];
1324 break;
1325
269c14e1
DE
1326 case CC_SET_ZN_C0:
1327 /* Insn sets the Z,N flags of CC to recog_operand[0].
1328 The V flag is unusable. The C flag may or may not be known but
1329 that's ok because alter_cond will change tests to use EQ/NE. */
48837e29 1330 CC_STATUS_INIT;
269c14e1
DE
1331 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
1332 cc_status.value1 = recog_operand[0];
48837e29
DE
1333 break;
1334
269c14e1
DE
1335 case CC_COMPARE:
1336 /* The insn is a compare instruction. */
48837e29 1337 CC_STATUS_INIT;
269c14e1 1338 cc_status.value1 = SET_SRC (body);
48837e29
DE
1339 break;
1340
48837e29 1341 case CC_CLOBBER:
269c14e1 1342 /* Insn doesn't leave CC in a usable state. */
48837e29
DE
1343 CC_STATUS_INIT;
1344 break;
07aae5c2 1345 }
48837e29
DE
1346}
1347
269c14e1
DE
1348/* Return 1 if a previous compare needs to be re-issued. This will happen
1349 if the compare was deleted because the previous insn set it, but the
1350 branch needs CC flags not set.
1351
1352 OP is the comparison being performed. */
1353
1354int
1355restore_compare_p (op)
1356 rtx op;
1357{
1358 switch (GET_CODE (op))
1359 {
1360 case EQ:
1361 case NE:
1362 break;
1363 case LT:
1364 case LE:
1365 case GT:
1366 case GE:
1367 if (cc_status.flags & CC_OVERFLOW_UNUSABLE)
1368 return 1;
1369 break;
1370 case LTU:
1371 case LEU:
1372 case GTU:
1373 case GEU:
1374 /* If the carry flag isn't usable, the test should have been changed
1375 by alter_cond. */
1376 if (cc_status.flags & CC_NO_CARRY)
1377 abort ();
1378 break;
1379 default:
1380 abort ();
1381 }
1382
1383 return 0;
1384}
1385
48837e29
DE
1386/* Recognize valid operators for bit instructions */
1387
1388int
1389bit_operator (x, mode)
1390 rtx x;
1391 enum machine_mode mode;
1392{
1393 enum rtx_code code = GET_CODE (x);
07aae5c2 1394
48837e29
DE
1395 return (code == XOR
1396 || code == AND
1397 || code == IOR);
07aae5c2 1398}
48837e29
DE
1399\f
1400/* Shifts.
1401
1402 We devote a fair bit of code to getting efficient shifts since we can only
1403 shift one bit at a time. See the .md file for more comments.
1404
1405 Here are some thoughts on what the absolutely positively best code is.
1406 "Best" here means some rational trade-off between code size and speed,
1407 where speed is more preferred but not at the expense of generating 20 insns.
1408
1409 H8/300 QImode shifts
1410 1-4 - do them inline
1411 5-6 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1412 ASHIFTRT: loop
1413 7 - ASHIFT | LSHIFTRT: rotate, mask off other bits
1414 ASHIFTRT: shll, subx (propagate carry bit to all bits)
1415
1416 H8/300 HImode shifts
1417 1-4 - do them inline
1418 5-6 - loop
1419 7 - shift other way once, move byte into place, move carry bit into place
1420 8 - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
1421 9 - inline shift 1-4, move byte, set other byte
1422 13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
1423 - ASHIFTRT: loop
1424 15 - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
1425 - ASHIFTRT: shll, subx, set other byte
1426
1427 H8/300 SImode shifts
1428 1-2 - do them inline
1429 3-6 - loop
1430 7 - shift other way once, move bytes into place,
1431 move carry into place (possibly with sign extension)
1432 8 - move bytes into place, zero or sign extend other
1433 9-14 - loop
1434 15 - shift other way once, move word into place, move carry into place
1435 16 - move word, zero or sign extend other
1436 17-23 - loop
1437 24 - move bytes into place, zero or sign extend other
1438 25-27 - loop
1439 28-30 - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,
1440 zero others
1441 ASHIFTRT: loop
1442 31 - ASHIFT | LSHIFTRT: rotate top byte, mask, byte byte into place,
1443 zero others
1444 ASHIFTRT: shll top byte, subx, copy to other bytes
1445
1446 H8/300H QImode shifts
1447 - same as H8/300
1448
1449 H8/300H HImode shifts
1450 - same as H8/300
1451
1452 H8/300H SImode shifts
1453 (These are complicated by the fact that we don't have byte level access to
1454 the top word.)
1455 A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
1456 1-4 - do them inline
1457 5-14 - loop
1458 15 - shift other way once, move word into place, move carry into place
1459 (with sign extension for ASHIFTRT)
1460 16 - move word into place, zero or sign extend other
1461 17-23 - loop
1462 24 - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
1463 move word 0 to word 1, zero word 0
1464 LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1465 zero word 1, zero byte 1
1466 ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
1467 sign extend byte 0, sign extend word 0
1468 25-27 - either loop, or
1469 do 24 bit shift, inline rest
1470 28-30 - ASHIFT: rotate 4/3/2, mask
1471 LSHIFTRT: rotate 4/3/2, mask
1472 ASHIFTRT: loop
1473 31 - shll, subx byte 0, sign extend byte 0, sign extend word 0
1474
1475 Don't Panic!!!
1476
1477 All of these haven't been implemented. I've just documented them and
1478 provided hooks so they can be.
1479*/
07aae5c2
SC
1480
1481int
48837e29
DE
1482nshift_operator (x, mode)
1483 rtx x;
1484 enum machine_mode mode;
1485{
1486 switch (GET_CODE (x))
1487 {
1488 case ASHIFTRT:
1489 case LSHIFTRT:
1490 case ASHIFT:
1491 return 1;
1492
1493 default:
1494 return 0;
1495 }
1496}
1497
1498/* Called from the .md file to emit code to do shifts.
1499 Returns a boolean indicating success
1500 (currently this is always TRUE). */
1501
1502int
1503expand_a_shift (mode, code, operands)
1504 enum machine_mode mode;
07aae5c2
SC
1505 int code;
1506 rtx operands[];
07aae5c2
SC
1507{
1508 extern int rtx_equal_function_value_matters;
1509
1510 emit_move_insn (operands[0], operands[1]);
1511
48837e29
DE
1512 /* need a loop to get all the bits we want - we generate the
1513 code at emit time, but need to allocate a scratch reg now */
1514
1515 emit_insn (gen_rtx
1516 (PARALLEL, VOIDmode,
1517 gen_rtvec (2,
1518 gen_rtx (SET, VOIDmode, operands[0],
1519 gen_rtx (code, mode, operands[0], operands[2])),
1520 gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, QImode, 0)))));
1521
1522 return 1;
1523}
1524
1525/* Shift algorithm determination.
1526
1527 There are various ways of doing a shift:
1528 SHIFT_INLINE: If the amount is small enough, just generate as many one-bit
1529 shifts as we need.
1530 SHIFT_ROT_AND: If the amount is large but close to either end, rotate the
1531 necessary bits into position and then set the rest to zero.
1532 SHIFT_SPECIAL: Hand crafted assembler.
1533 SHIFT_LOOP: If the above methods fail, just loop. */
1534
1535enum shift_alg
1536{
1537 SHIFT_INLINE,
1538 SHIFT_ROT_AND,
1539 SHIFT_SPECIAL,
1540 SHIFT_LOOP,
1541 SHIFT_MAX
1542};
1543
1544/* Symbols of the various shifts which can be used as indices. */
1545
1546enum shift_type
1547 {
1548 SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
1549 };
1550
1551/* Symbols of the various modes which can be used as indices. */
1552
1553enum shift_mode
1554 {
1555 QIshift, HIshift, SIshift
1556 };
1557
269c14e1
DE
1558/* For single bit shift insns, record assembler and what bits of the
1559 condition code are valid afterwards (represented as various CC_FOO
1560 bits, 0 means CC isn't left in a usable state). */
48837e29
DE
1561
1562struct shift_insn
1563{
1564 char *assembler;
1565 int cc_valid;
1566};
1567
1568/* Assembler instruction shift table.
1569
1570 These tables are used to look up the basic shifts.
1571 They are indexed by cpu, shift_type, and mode.
1572*/
07aae5c2 1573
48837e29
DE
1574static const struct shift_insn shift_one[2][3][3] =
1575{
1576/* H8/300 */
1577 {
1578/* SHIFT_ASHIFT */
1579 {
269c14e1
DE
1580 { "shll %X0", CC_OVERFLOW_0 | CC_NO_CARRY },
1581 { "add.w %T0,%T0\t; shal.w", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
48837e29
DE
1582 { "add.w %f0,%f0\t; shal.l\n\taddx %y0,%y0\n\taddx %z0,%z0\t; end shal.l", 0 }
1583 },
1584/* SHIFT_LSHIFTRT */
1585 {
269c14e1 1586 { "shlr %X0", CC_OVERFLOW_0 | CC_NO_CARRY },
48837e29
DE
1587 { "shlr %t0\t; shlr.w\n\trotxr %s0\t; end shlr.w", 0 },
1588 { "shlr %z0\t; shlr.l\n\trotxr %y0\n\trotxr %x0\n\trotxr %w0\t; end shlr.l", 0 }
1589 },
1590/* SHIFT_ASHIFTRT */
1591 {
269c14e1 1592 { "shar %X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
48837e29
DE
1593 { "shar %t0\t; shar.w\n\trotxr %s0\t; end shar.w", 0 },
1594 { "shar %z0\t; shar.l\n\trotxr %y0\n\trotxr %x0\n\trotxr %w0\t; end shar.l", 0 }
1595 }
1596 },
1597/* H8/300H */
1598 {
1599/* SHIFT_ASHIFT */
1600 {
269c14e1
DE
1601 { "shll.b %X0", CC_OVERFLOW_0 | CC_NO_CARRY },
1602 { "shll.w %T0", CC_OVERFLOW_0 | CC_NO_CARRY },
1603 { "shll.l %S0", CC_OVERFLOW_0 | CC_NO_CARRY }
48837e29
DE
1604 },
1605/* SHIFT_LSHIFTRT */
1606 {
269c14e1
DE
1607 { "shlr.b %X0", CC_OVERFLOW_0 | CC_NO_CARRY },
1608 { "shlr.w %T0", CC_OVERFLOW_0 | CC_NO_CARRY },
1609 { "shlr.l %S0", CC_OVERFLOW_0 | CC_NO_CARRY }
48837e29
DE
1610 },
1611/* SHIFT_ASHIFTRT */
1612 {
269c14e1
DE
1613 { "shar.b %X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1614 { "shar.w %T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
1615 { "shar.l %S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }
48837e29
DE
1616 }
1617 }
1618};
07aae5c2 1619
48837e29
DE
1620/* Rotates are organized by which shift they'll be used in implementing.
1621 There's no need to record whether the cc is valid afterwards because
1622 it is the AND insn that will decide this. */
07aae5c2 1623
48837e29
DE
1624static const char *const rotate_one[2][3][3] =
1625{
1626/* H8/300 */
1627 {
1628/* SHIFT_ASHIFT */
1629 {
1630 "rotr %X0",
1631 "shlr %t0\t; rotr.w\n\trotxr %s0\n\tbst #7,%t0\t; end rotr.w",
1632 0
1633 },
1634/* SHIFT_LSHIFTRT */
1635 {
1636 "rotl %X0",
1637 "shll %s0\t; rotl.w\n\trotxl %t0\n\tbst #0,%s0\t; end rotl.w",
1638 0
1639 },
1640/* SHIFT_ASHIFTRT */
1641 {
1642 "rotl %X0",
1643 "shll %s0\t; rotl.w\n\trotxl %t0\n\tbst #0,%s0\t; end rotl.w",
1644 0
07aae5c2 1645 }
48837e29
DE
1646 },
1647/* H8/300H */
1648 {
1649/* SHIFT_ASHIFT */
1650 {
1651 "rotr.b %X0",
1652 "rotr.w %T0",
1653 "rotr.l %S0"
1654 },
1655/* SHIFT_LSHIFTRT */
07aae5c2 1656 {
48837e29
DE
1657 "rotl.b %X0",
1658 "rotl.w %T0",
1659 "rotl.l %S0"
1660 },
1661/* SHIFT_ASHIFTRT */
1662 {
1663 "rotl.b %X0",
1664 "rotl.w %T0",
1665 "rotl.l %S0"
1666 }
1667 }
1668};
1669
1670/* Given CPU, MODE, SHIFT_TYPE, and shift count COUNT, determine the best
1671 algorithm for doing the shift. The assembler code is stored in ASSEMBLER.
1672 We don't achieve maximum efficiency in all cases, but the hooks are here
1673 to do so.
1674
1675 For now we just use lots of switch statements. Since we don't even come
1676 close to supporting all the cases, this is simplest. If this function ever
1677 gets too big, perhaps resort to a more table based lookup. Of course,
1678 at this point you may just wish to do it all in rtl.
1679
1680 WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
1681 1,2,3,4 will be inlined (1,2 for SI). */
1682
1683static enum shift_alg
1684get_shift_alg (cpu, shift_type, mode, count, assembler_p, cc_valid_p)
1685 enum attr_cpu cpu;
1686 enum shift_type shift_type;
1687 enum machine_mode mode;
1688 int count;
1689 const char **assembler_p;
1690 int *cc_valid_p;
1691{
1692 /* The default is to loop. */
1693 enum shift_alg alg = SHIFT_LOOP;
1694 enum shift_mode shift_mode;
1695
1696 /* We don't handle negative shifts or shifts greater than the word size,
1697 they should have been handled already. */
07aae5c2 1698
48837e29
DE
1699 if (count < 0 || count > GET_MODE_BITSIZE (mode))
1700 abort ();
1701
1702 switch (mode)
1703 {
1704 case QImode:
1705 shift_mode = QIshift;
1706 break;
1707 case HImode:
1708 shift_mode = HIshift;
1709 break;
1710 case SImode:
1711 shift_mode = SIshift;
1712 break;
1713 default:
1714 abort ();
1715 }
1716
1717 /* Assume either SHIFT_LOOP or SHIFT_INLINE.
1718 It is up to the caller to know that looping clobbers cc. */
1719 *assembler_p = shift_one[cpu][shift_type][shift_mode].assembler;
1720 *cc_valid_p = shift_one[cpu][shift_type][shift_mode].cc_valid;
1721
1722 /* Now look for cases we want to optimize. */
1723
1724 switch (shift_mode)
1725 {
1726 case QIshift:
1727 if (count <= 4)
1728 return SHIFT_INLINE;
1729 else if (count <= 6)
07aae5c2 1730 {
48837e29
DE
1731 if (shift_type == SHIFT_ASHIFTRT)
1732 {
1733 return SHIFT_LOOP;
1734 }
1735 else
1736 {
1737 *assembler_p = rotate_one[cpu][shift_type][shift_mode];
1738 *cc_valid_p = 0;
1739 return SHIFT_ROT_AND;
1740 }
07aae5c2 1741 }
48837e29 1742 else if (count == 7)
07aae5c2 1743 {
48837e29
DE
1744 if (shift_type == SHIFT_ASHIFTRT)
1745 {
1746 *assembler_p = "shll %X0\t; shar.b(7)\n\tsubx %X0,%X0\t; end shar.b(7)";
1747 *cc_valid_p = 0;
1748 return SHIFT_SPECIAL;
1749 }
1750 else
1751 {
1752 *assembler_p = rotate_one[cpu][shift_type][shift_mode];
1753 *cc_valid_p = 0;
1754 return SHIFT_ROT_AND;
1755 }
07aae5c2 1756 }
48837e29
DE
1757 break;
1758 case HIshift:
1759 if (count <= 4)
1760 return SHIFT_INLINE;
1761 else if (count == 8)
1762 {
1763 switch (shift_type)
1764 {
1765 case SHIFT_ASHIFT:
1766 *assembler_p = "mov.b %s0,%t0\t; shal.w(8)\n\tsub.b %s0,%s0\t; end shal.w(8)";
1767 *cc_valid_p = 0;
1768 return SHIFT_SPECIAL;
1769 case SHIFT_LSHIFTRT:
1770 *assembler_p = "mov.b %t0,%s0\t; shlr.w(8)\n\tsub.b %t0,%t0\t; end shlr.w(8)";
1771 *cc_valid_p = 0;
1772 return SHIFT_SPECIAL;
1773 case SHIFT_ASHIFTRT:
1774 if (cpu == CPU_H8300)
1775 *assembler_p = "mov.b %t0,%s0\t; shar.w(8)\n\tshll %t0\n\tsubx %t0,%t0\t; end shar.w(8)";
1776 else
1777 *assembler_p = "mov.b %t0,%s0\t; shar.w(8)\n\texts.w %T0\t; end shar.w(8)";
1778 *cc_valid_p = 0;
1779 return SHIFT_SPECIAL;
1780 }
1781 abort ();
1782 }
1783 else if (count == 15)
07aae5c2 1784 {
48837e29
DE
1785 if (shift_type == SHIFT_ASHIFTRT)
1786 {
1787 *assembler_p = "shll %t0,%t0\t; shar.w(15)\n\tsubx %t0,%t0\n\tmov.b %t0,%s0\t; end shar.w(15)";
1788 *cc_valid_p = 0;
1789 return SHIFT_SPECIAL;
1790 }
1791 else
1792 {
1793 *assembler_p = rotate_one[cpu][shift_type][shift_mode];
1794 *cc_valid_p = 0;
1795 return SHIFT_ROT_AND;
1796 }
07aae5c2 1797 }
48837e29
DE
1798 break;
1799 case SIshift:
1800 if (count <= (cpu == CPU_H8300 ? 2 : 4))
1801 return SHIFT_INLINE;
1802 else if (count == 8)
1803 {
1804 if (cpu == CPU_H8300)
1805 {
1806 switch (shift_type)
1807 {
1808 case SHIFT_ASHIFT:
1809 *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)";
1810 *cc_valid_p = 0;
1811 return SHIFT_SPECIAL;
1812 case SHIFT_LSHIFTRT:
1813 *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)";
1814 *cc_valid_p = 0;
1815 return SHIFT_SPECIAL;
1816 case SHIFT_ASHIFTRT:
1817 *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)";
1818 *cc_valid_p = 0;
1819 return SHIFT_SPECIAL;
1820 }
1821 }
1822 else /* CPU_H8300H */
1823 /* We don't have byte level access to the high word so this isn't
1824 easy to do. For now, just loop. */
1825 ;
1826 }
1827 else if (count == 16)
1828 {
1829 switch (shift_type)
1830 {
1831 case SHIFT_ASHIFT:
1832 *assembler_p = "mov.w %f0,%e0\t; shal.l(16)\n\tsub.w %f0,%f0\t; end shal.l(16)";
1833 *cc_valid_p = 0;
1834 return SHIFT_SPECIAL;
1835 case SHIFT_LSHIFTRT:
1836 *assembler_p = "mov.w %e0,%f0\t; shlr.l(16)\n\tsub.w %e0,%e0\t; end shlr.l(16)";
1837 *cc_valid_p = 0;
1838 return SHIFT_SPECIAL;
1839 case SHIFT_ASHIFTRT:
1840 if (cpu == CPU_H8300)
1841 *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)";
1842 else
1843 *assembler_p = "mov.w %e0,%f0\t; shar.l(16)\n\texts.l %S0\t; end shar.l(16)";
1844 *cc_valid_p = 0;
1845 return SHIFT_SPECIAL;
1846 }
1847 }
1848 else if (count >= 28 && count <= 30)
1849 {
1850 if (shift_type == SHIFT_ASHIFTRT)
1851 {
1852 return SHIFT_LOOP;
1853 }
1854 else
1855 {
1856 if (cpu == CPU_H8300)
1857 return SHIFT_LOOP;
1858 else
1859 {
1860 *assembler_p = rotate_one[cpu][shift_type][shift_mode];
1861 *cc_valid_p = 0;
1862 return SHIFT_ROT_AND;
1863 }
1864 }
1865 }
1866 else if (count == 31)
1867 {
1868 if (shift_type == SHIFT_ASHIFTRT)
1869 {
1870 if (cpu == CPU_H8300)
1871 *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)";
1872 else
1873 *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)";
1874 *cc_valid_p = 0;
1875 return SHIFT_SPECIAL;
1876 }
1877 else
1878 {
1879 if (cpu == CPU_H8300)
1880 {
1881 if (shift_type == SHIFT_ASHIFT)
1882 *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)";
1883 else
1884 *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)";
1885 *cc_valid_p = 0;
1886 return SHIFT_SPECIAL;
1887 }
1888 else
1889 {
1890 *assembler_p = rotate_one[cpu][shift_type][shift_mode];
1891 *cc_valid_p = 0;
1892 return SHIFT_ROT_AND;
1893 }
1894 }
1895 }
1896 break;
1897 default:
1898 abort ();
07aae5c2 1899 }
48837e29
DE
1900
1901 return alg;
07aae5c2
SC
1902}
1903
48837e29
DE
1904/* Emit the assembler code for doing shifts. */
1905
1906char *
1907emit_a_shift (insn, operands)
1908 rtx insn;
1909 rtx *operands;
07aae5c2 1910{
48837e29
DE
1911 static int loopend_lab;
1912 char *assembler;
1913 int cc_valid;
1914 rtx inside = PATTERN (insn);
1915 rtx shift = operands[3];
1916 enum machine_mode mode = GET_MODE (shift);
1917 enum rtx_code code = GET_CODE (shift);
1918 enum shift_type shift_type;
1919 enum shift_mode shift_mode;
1920
1921 loopend_lab++;
1922
1923 switch (mode)
1924 {
1925 case QImode:
1926 shift_mode = QIshift;
1927 break;
1928 case HImode:
1929 shift_mode = HIshift;
1930 break;
1931 case SImode:
1932 shift_mode = SIshift;
1933 break;
1934 default:
1935 abort ();
1936 }
07aae5c2 1937
48837e29 1938 switch (code)
07aae5c2 1939 {
48837e29
DE
1940 case ASHIFTRT:
1941 shift_type = SHIFT_ASHIFTRT;
1942 break;
1943 case LSHIFTRT:
1944 shift_type = SHIFT_LSHIFTRT;
1945 break;
1946 case ASHIFT:
1947 shift_type = SHIFT_ASHIFT;
1948 break;
1949 default:
1950 abort ();
1951 }
07aae5c2 1952
48837e29
DE
1953 if (GET_CODE (operands[2]) != CONST_INT)
1954 {
1955 /* Indexing by reg, so have to loop and test at top */
1956 output_asm_insn ("mov.b %X2,%X4", operands);
1957 fprintf (asm_out_file, "\tble .Lle%d\n", loopend_lab);
1958
1959 /* Get the assembler code to do one shift. */
1960 get_shift_alg (cpu_type, shift_type, mode, 1, &assembler, &cc_valid);
1961 }
1962 else
1963 {
1964 int n = INTVAL (operands[2]);
1965 enum shift_alg alg;
1966
1967 /* If the count is negative, make it 0. */
1968 if (n < 0)
1969 n = 0;
1970 /* If the count is too big, truncate it.
1971 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
1972 do the intuitive thing. */
1973 else if (n > GET_MODE_BITSIZE (mode))
1974 n = GET_MODE_BITSIZE (mode);
1975
1976 alg = get_shift_alg (cpu_type, shift_type, mode, n, &assembler, &cc_valid);
1977
1978 switch (alg)
1979 {
1980 case SHIFT_INLINE:
1981 while (--n >= 0)
1982 output_asm_insn (assembler, operands);
1983 if (cc_valid)
269c14e1
DE
1984 {
1985 cc_status.value1 = operands[0];
1986 cc_status.flags |= cc_valid;
1987 }
48837e29
DE
1988 return "";
1989 case SHIFT_ROT_AND:
1990 {
1991 int m = GET_MODE_BITSIZE (mode) - n;
1992 int mask = (shift_type == SHIFT_ASHIFT
1993 ? ((1 << GET_MODE_BITSIZE (mode) - n) - 1) << n
1994 : (1 << GET_MODE_BITSIZE (mode) - n) - 1);
1995 char insn_buf[200];
1996 /* Not all possibilities of rotate are supported. They shouldn't
1997 be generated, but let's watch for 'em. */
1998 if (assembler == 0)
1999 abort ();
2000 while (--m >= 0)
2001 output_asm_insn (assembler, operands);
2002 if (TARGET_H8300)
2003 {
2004 switch (mode)
2005 {
2006 case QImode:
2007 sprintf (insn_buf, "and #%d,%%X0\t; end shift %d via rotate+and",
2008 mask, n);
2009 cc_status.value1 = operands[0];
269c14e1 2010 cc_status.flags |= CC_OVERFLOW_0 | CC_NO_CARRY;
48837e29
DE
2011 break;
2012 case HImode:
2013 sprintf (insn_buf, "and #%d,%%s0\n\tand #%d,%%t0\t; end shift %d via rotate+and",
2014 mask & 255, mask >> 8, n);
2015 break;
2016 case SImode:
2017 abort ();
2018 }
2019 }
2020 else
2021 {
2022 sprintf (insn_buf, "and.%c #%d,%%%c0",
2023 "bwl"[shift_mode], mask,
2024 mode == QImode ? 'X' : mode == HImode ? 'T' : 'S');
2025 cc_status.value1 = operands[0];
269c14e1 2026 cc_status.flags |= CC_OVERFLOW_0 | CC_NO_CARRY;
48837e29
DE
2027 }
2028 output_asm_insn (insn_buf, operands);
2029 return "";
2030 }
2031 case SHIFT_SPECIAL:
2032 output_asm_insn (assembler, operands);
2033 return "";
07aae5c2 2034 }
48837e29
DE
2035
2036 /* Need a loop, move limit to tmp reg */
2037 fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n, names_big[REGNO (operands[4])]);
07aae5c2 2038 }
48837e29
DE
2039
2040 fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
2041 output_asm_insn (assembler, operands);
2042 output_asm_insn ("add #0xff,%X4", operands);
2043 fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
2044 fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
2045
2046 return "";
07aae5c2 2047}
48837e29
DE
2048\f
2049/* Fix the operands of a gen_xxx so that it could become a bit
2050 operating insn. */
07aae5c2
SC
2051
2052int
48837e29
DE
2053fix_bit_operand (operands, what, type)
2054 rtx *operands;
2055 char what;
2056 enum rtx_code type;
07aae5c2 2057{
abc95ed3 2058 /* The bit_operand predicate accepts any memory during RTL generation, but
48837e29
DE
2059 only 'U' memory afterwards, so if this is a MEM operand, we must force
2060 it to be valid for 'U' by reloading the address. */
07aae5c2 2061
48837e29 2062 if (GET_CODE (operands[2]) == CONST_INT)
07aae5c2 2063 {
48837e29
DE
2064 if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), what))
2065 {
2066 /* Ok to have a memory dest. */
2067 if (GET_CODE (operands[0]) == MEM && !EXTRA_CONSTRAINT (operands[0], 'U'))
2068 {
2069 rtx mem;
2070 mem = gen_rtx (MEM, GET_MODE (operands[0]),
2071 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2072 RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[0]);
2073 MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[0]);
2074 MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[0]);
2075 operands[0] = mem;
2076 }
2077
2078 if (GET_CODE (operands[1]) == MEM && !EXTRA_CONSTRAINT (operands[1], 'U'))
2079 {
2080 rtx mem;
2081 mem = gen_rtx (MEM, GET_MODE (operands[1]),
2082 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2083 RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[1]);
2084 MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[1]);
2085 MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[1]);
2086 operands[1] = mem;
2087 }
2088 return 0;
2089 }
2090 }
07aae5c2 2091
48837e29 2092 /* Dest and src op must be register. */
07aae5c2 2093
48837e29
DE
2094 operands[1] = force_reg (QImode, operands[1]);
2095 {
2096 rtx res = gen_reg_rtx (QImode);
2097 emit_insn (gen_rtx (SET, VOIDmode, res, gen_rtx (type, QImode, operands[1], operands[2])));
2098 emit_insn (gen_rtx (SET, VOIDmode, operands[0], res));
2099 }
2100 return 1;
07aae5c2 2101}
f5b65a56
JL
2102
2103
2104/* Return nonzero if FUNC is an interrupt function as specified
2105 by the "interrupt" attribute. */
2106
2107static int
2108h8300_interrupt_function_p (func)
2109 tree func;
2110{
2111 tree a;
2112
2113 if (TREE_CODE (func) != FUNCTION_DECL)
2114 return 0;
2115
2116 a = lookup_attribute ("interrupt-handler", DECL_MACHINE_ATTRIBUTES (func));
2117 return a != NULL_TREE;
2118}
2119
2120/* Return nonzero if FUNC is a function that should be called
2121 through the function vector. */
2122
2123int
2124h8300_funcvec_function_p (func)
2125 tree func;
2126{
2127 tree a;
2128
2129 if (TREE_CODE (func) != FUNCTION_DECL)
2130 return 0;
2131
2132 a = lookup_attribute ("function-vector", DECL_MACHINE_ATTRIBUTES (func));
2133 return a != NULL_TREE;
2134}
2135
2136/* Return nonzero if ATTR is a valid attribute for DECL.
2137 ATTRIBUTES are any existing attributes and ARGS are the arguments
2138 supplied with ATTR.
2139
2140 Supported attributes:
2141
2142 interrupt-handler: output a prologue and epilogue suitable for an
2143 interrupt handler.
2144
2145 function-vector: This function should be called through the
2146 function vector. */
2147
2148int
2149h8300_valid_machine_decl_attribute (decl, attributes, attr, args)
2150 tree decl;
2151 tree attributes;
2152 tree attr;
2153 tree args;
2154{
2155 if (args != NULL_TREE)
2156 return 0;
2157
2158 if (is_attribute_p ("interrupt-handler", attr)
2159 || is_attribute_p ("function-vector", attr))
2160 return TREE_CODE (decl) == FUNCTION_DECL;
2161 return 0;
2162}
2163