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