1 /* Output routines for GCC for Hitachi Super-H
2 Copyright (C) 1993, 1994 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* Contributed by Steve Chamberlain (sac@cygnus.com) */
28 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-flags.h"
36 #include "insn-attr.h"
41 static rtx add_constant ();
46 int current_function_anonymous_args;
47 extern int current_function_pretend_args_size;
48 extern char *version_string;
49 extern int flag_traditional;
51 static rtx shiftsyms[32];
52 struct rtx_def *table_lab;
53 enum attr_cpu sh_cpu; /* target cpu */
55 /* Global variables for machine-dependent things. */
57 /* Saved operands from the last compare to use when we generate an scc
63 /* Provides the class number of the smallest class containing
66 int regno_reg_class[FIRST_PSEUDO_REGISTER] =
68 R0_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
69 GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
70 GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
71 GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
72 GENERAL_REGS, PR_REGS, T_REGS, NO_REGS,
76 /* Provide reg_class from a letter such as appears in the machine
79 enum reg_class reg_class_from_letter[] =
81 /* a */ NO_REGS, /* b */ NO_REGS, /* c */ NO_REGS, /* d */ NO_REGS,
82 /* e */ NO_REGS, /* f */ NO_REGS, /* g */ NO_REGS, /* h */ NO_REGS,
83 /* i */ NO_REGS, /* j */ NO_REGS, /* k */ NO_REGS, /* l */ PR_REGS,
84 /* m */ NO_REGS, /* n */ NO_REGS, /* o */ NO_REGS, /* p */ NO_REGS,
85 /* q */ NO_REGS, /* r */ NO_REGS, /* s */ NO_REGS, /* t */ T_REGS,
86 /* u */ NO_REGS, /* v */ NO_REGS, /* w */ NO_REGS, /* x */ MAC_REGS,
87 /* y */ NO_REGS, /* z */ R0_REGS
90 /* Value is 1 if register/mode pair is acceptable on SH. Even
91 registers can hold DIs and DF values. The rest can only hold
96 ( (1 << (int) QImode) | (1 << (int) HImode) | (1 << (int) SImode) \
97 | (1 << (int) QFmode) | (1 << (int) HFmode) | (1 << (int) SFmode) \
98 | (1 << (int) CQImode) | (1 << (int) CHImode))
101 (REG_ODD | (1 << (int) DImode) | (1 << (int) DFmode) \
102 | (1 << (int) CSImode) | (1 << (int) SCmode))
104 #define SI_ONLY (1<<(int)SImode)
105 int hard_regno_mode_ok[] =
107 REG_EVEN, REG_ODD, REG_EVEN, REG_ODD,
108 REG_EVEN, REG_ODD, REG_EVEN, REG_ODD,
109 REG_EVEN, REG_ODD, REG_EVEN, REG_ODD,
110 REG_EVEN, REG_ODD, REG_EVEN, REG_ODD,
111 REG, 0, SI_ONLY, SI_ONLY,
115 /* Local label counter, used for constants in the pool and inside
120 /* Number of bytes pushed for anonymous args, used to pass information
121 between expand_prologue and expand_epilogue. */
122 static int extra_push;
130 emit_insn (gen_push (gen_rtx (REG, SImode, rn)));
136 emit_insn (gen_pop (gen_rtx (REG, SImode, rn)));
140 /* Adjust the stack and return the number of bytes taken to do it */
143 output_stack_adjust (size)
148 rtx val = GEN_INT (size);
151 if (!CONST_OK_FOR_I (size))
153 rtx nval = gen_rtx (REG, SImode, 3);
154 emit_insn (gen_movsi (nval, val));
158 insn = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, val);
163 /* Generate code to push the regs specified in the mask, and return
164 the number of bytes the insns take. */
172 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
182 /* Print an instruction which would have gone into a delay slot after
183 an instructiuon, but couldn't because the instruction expanded into a
184 sequence where putting the slot insn at the end wouldn't work. */
190 final_scan_insn (XVECEXP (insn, 0, 1), asm_out_file, optimize, 0, 1);
192 INSN_DELETED_P (XVECEXP (insn, 0, 1)) = 1;
196 /* Work out the registers which need to be saved, both as a mask and a
199 If doing a pragma interrupt function, then push all regs used by the function,
200 and if we call another function (we can tell by looking at PR), make sure that all the
201 regs it clobbers are safe too.
204 calc_live_regs (count_ptr)
208 int live_regs_mask = 0;
210 for (reg = 0; reg < FIRST_PSEUDO_REGISTER; reg++)
212 if (reg == ARG_POINTER_REGNUM)
219 if (pragma_interrupt && !pragma_trapa)
221 /* Need to save all the regs ever live */
222 if ((regs_ever_live[reg]
223 || (call_used_regs[reg] && regs_ever_live[PR_REG]))
226 live_regs_mask |= 1 << reg;
230 else if (TARGET_SMALLCALL)
232 /* Don't need to push anthing, but count the regs which have
233 been pushed by the wrapper */
234 if (call_used_regs[reg])
239 /* Only push those regs which are used and need to be saved */
240 if (regs_ever_live[reg] && !call_used_regs[reg])
243 live_regs_mask |= (1 << reg);
250 return live_regs_mask;
258 return (insn && !INSN_ANNULLED_BRANCH_P (XVECEXP (insn, 0, 0)));
261 /* Print the operand address in x to the stream */
264 print_operand_address (stream, x)
268 switch (GET_CODE (x))
271 fprintf (stream, "@%s", reg_names[REGNO (x)]);
275 rtx base = XEXP (x, 0);
276 rtx index = XEXP (x, 1);
278 if (GET_CODE (base) != REG)
280 /* Ensure that BASE is a register (one of them must be). */
286 switch (GET_CODE (index))
289 fprintf (stream, "@(%d,%s)",
291 reg_names[REGNO (base)]);
295 fprintf (stream, "@(r0,%s)",
296 reg_names[MAX (REGNO (base), REGNO (index))]);
309 fprintf (stream, "@-%s", reg_names[REGNO (XEXP (x, 0))]);
313 fprintf (stream, "@%s+", reg_names[REGNO (XEXP (x, 0))]);
317 output_addr_const (stream, x);
322 /* Print operand x (an rtx) in assembler syntax to file stream
323 according to modifier code.
325 '.' print a .s if insn needs delay slot
326 '*' print a local label
327 '^' increment the local label number
328 '!' dump the constant table
329 '#' output a nop if there is nothing to put in the delay slot
330 'R' print the next register or memory location along, ie the lsw in
332 'O' print a constant without the #
333 'M' print a constant as its negative
334 'N' print insides of a @++ or @-- o */
337 print_operand (stream, x, code)
345 if (need_slot (final_sequence))
346 fprintf (stream, ".s");
349 fprintf (stream, "LF%d", lf);
355 /* Output a nop if there's nothing in the delay slot */
356 if (dbr_sequence_length () == 0)
358 fprintf (stream, "\n\tor r0,r0\t!wasted slot");
362 output_addr_const (stream, x);
365 fprintf (asm_out_file, "#%d", -INTVAL (x));
368 fputs (reg_names[REGNO (XEXP (XEXP (x, 0), 0))], (stream));
371 /* Next location along in memory or register */
372 switch (GET_CODE (x))
375 fputs (reg_names[REGNO (x) + 1], (stream));
378 print_operand_address (stream, XEXP (adj_offsettable_operand (x, 4), 0));
383 switch (GET_CODE (x))
386 fputs (reg_names[REGNO (x)], (stream));
389 output_address (XEXP (x, 0));
393 output_addr_const (stream, x);
413 /* Take a move with integer constant source in OPERANDS, see if it can be generated by
414 devious shifting. If so, generate the instruction sequence and return 1, otherwise
417 OPERANDS[0] Destination register
418 OPERANDS[1] Source constant
420 00000000 00000000 00000000 0NNNNNNNN simple load
421 00000000 00000000 00000000 NNNNNNNN0 load and shift by 1
422 00000000 00000000 0000000N NNNNNNN00 load and shift by 2
423 00000000 00000000 0NNNNNNN 000000000 load and shift by 8
424 00000000 0NNNNNNN 00000000 000000000 load and shift by 16
425 N0000000 00000000 00000000 00NNNNNNN load and rotate right
427 11111111 11111111 11111111 1NNNNNNNN simple load
428 11111111 11111111 11111111 NNNNNNNN0 load and shift by 1
429 11111111 11111111 1111111N NNNNNNN00 load and shift by 2
430 11111111 11111111 1NNNNNNN 000000000 load and shift by 8
431 11111111 1NNNNNNN 00000000 000000000 load and shift by 16
432 N1111111 11111111 11111111 11NNNNNNN load and rotate right
434 00000000 00000000 00000000 1NNNNNNNN load and zero extend byte
435 00000000 00000000 11111111 1NNNNNNNN load and zero extend word
441 synth_constant (operands, mode)
443 enum machine_mode mode;
446 int i = INTVAL (operands[1]) & 0xffffffff;
448 if (CONST_OK_FOR_I (i))
451 dst = mode == SImode ? operands[0] : gen_reg_rtx (SImode);
453 /* 00000000 00000000 11111111 1NNNNNNNN load and zero extend word */
454 if ((i & 0xffffff80) == 0x0000ff80)
456 emit_move_insn (dst, GEN_INT (sextb (i)));
457 emit_insn (gen_and_ffff (dst, dst));
459 /* 00000000 00000000 00000000 1NNNNNNNN load and zero extend byte */
460 else if ((i & 0xffffff80) == 0x00000080)
462 emit_move_insn (dst, GEN_INT (sextb (i)));
463 emit_insn (gen_and_ff (dst, dst));
465 /* 00000000 00000000 00000000 NNNNNNNN0 load and shift by 1
466 11111111 11111111 11111111 NNNNNNNN0 load and shift by 1 */
467 else if ((i & 0xffffff01) == 0
468 || (i & 0xffffff01) == 0xffffff00)
470 emit_move_insn (dst, GEN_INT (sextb (i >> 1)));
471 emit_insn (gen_ashlsi3_n (dst, dst, GEN_INT (1)));
473 /* 00000000 00000000 0000000N NNNNNNN00 load and shift by 2
474 11111111 11111111 1111111N NNNNNNN00 load and shift by 2*/
475 else if ((i & 0xfffffe03) == 0
476 || (i & 0xfffffe03) == 0xfffffe00)
478 emit_move_insn (dst, GEN_INT (sextb (i >> 2)));
479 emit_insn (gen_ashlsi3_n (dst, dst, GEN_INT (2)));
481 /* 00000000 00000000 0NNNNNNN 000000000 load and shift by 8
482 11111111 11111111 1NNNNNNN 000000000 load and shift by 8 */
484 else if ((i & 0xffff80ff) == 0
485 || (i & 0xffff80ff) == 0xffff8000)
487 emit_move_insn (dst, GEN_INT (sextb (i >> 8)));
488 emit_insn (gen_ashlsi3_n (dst, dst, GEN_INT (8)));
490 /* 00000000 0NNNNNNN 00000000 000000000 load and shift by 16
491 11111111 1NNNNNNN 00000000 000000000 load and shift by 16 */
492 else if ((i & 0xff80ffff) == 0
493 || (i & 0xff80ffff) == 0xff80ffff)
495 emit_move_insn (dst, GEN_INT (sextb (i >> 16)));
496 emit_insn (gen_ashlsi3_n (dst, dst, GEN_INT (16)));
498 /* 00000000 00000000 0NNNNNNN 0NNNNNNNN load shift 8 and add */
499 else if ((i & 0xffff8080) == 0 && TARGET_CLEN3)
501 emit_move_insn (dst, GEN_INT (sextb (i >> 8)));
502 emit_insn (gen_ashlsi3_n (dst, dst, GEN_INT (8)));
503 emit_insn (gen_addsi3 (dst, dst, GEN_INT (i & 0x7f)));
510 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
511 gen_rtx (SUBREG, mode, dst, 0)));
518 /* Emit code to perform a block move. Choose the best method.
520 OPERANDS[0] is the destination.
521 OPERANDS[1] is the source.
522 OPERANDS[2] is the size.
523 OPERANDS[3] is the alignment safe to use. */
527 expand_block_move (operands)
530 int align = INTVAL (operands[3]);
531 int constp = (GET_CODE (operands[2]) == CONST_INT);
532 int bytes = (constp ? INTVAL (operands[2]) : 0);
533 enum machine_mode mode;
534 /* IF odd then fail */
535 if (!constp || bytes <= 0)
550 if (mode == SImode && constp && bytes < 64 && (bytes % 4 == 0))
555 rtx r4 = gen_rtx (REG, SImode, 4);
556 rtx r5 = gen_rtx (REG, SImode, 5);
557 sprintf (entry, "__movstr%s%d", GET_MODE_NAME (mode), bytes);
558 entry_name = get_identifier (entry);
560 func_addr_rtx = copy_to_mode_reg (Pmode,
561 gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (entry_name)));
562 emit_insn (gen_move_insn (r4, XEXP (operands[0], 0)));
563 emit_insn (gen_move_insn (r5, XEXP (operands[1], 0)));
564 emit_insn (gen_block_move_real (func_addr_rtx));
567 if (mode == SImode && constp && (bytes % 4 == 0))
573 rtx r4 = gen_rtx (REG, SImode, 4);
574 rtx r5 = gen_rtx (REG, SImode, 5);
575 rtx r6 = gen_rtx (REG, SImode, 6);
576 entry_name = get_identifier ("__movstr");
578 func_addr_rtx = copy_to_mode_reg (Pmode,
579 gen_rtx (SYMBOL_REF, Pmode,
580 IDENTIFIER_POINTER (entry_name)));
581 emit_insn (gen_move_insn (r4, XEXP (operands[0], 0)));
582 emit_insn (gen_move_insn (r5, XEXP (operands[1], 0)));
584 /* r6 controls the size of the move, 16 is decremented from it
585 for each 64 bytes moved, then the -ve bit is used as an index into a
586 list of move instructions like this:
615 eg, a 72 byte move would be set up with size(r6) = 14, for one
616 iteration through the big while loop, and a switch of -2 for the last part */
619 int final_switch = 16 - ((bytes / 4) % 16);
620 int while_loop = ((bytes / 4) / 16 - 1) * 16;
621 emit_insn (gen_move_insn (r6, GEN_INT (while_loop + final_switch)));
622 emit_insn (gen_block_lump_real (func_addr_rtx));
630 /* Prepare operands for a move define_expand; specifically, one of the
631 operands must be in a register. Take this chance to remove
632 addressing modes which can't be coped with very well. */
635 prepare_move_operands (operands, mode)
637 enum machine_mode mode;
639 if (!(reload_in_progress || reload_completed)
640 && ((!register_operand (operands[0], mode)
641 && !register_operand (operands[1], mode))
642 || GET_CODE (operands[1]) == PLUS))
644 /* copy the source to a register */
645 operands[1] = copy_to_mode_reg (mode, operands[1]);
647 if ((mode == DImode || mode == SImode || mode == HImode || mode == QImode)
648 && GET_CODE (operands[1]) == CONST_INT)
650 return synth_constant (operands, mode);
652 if (mode == DFmode || mode == DImode)
654 rtx src = operands[1];
655 rtx dst = operands[0];
660 emit_insn (gen_rtx (SET, VOIDmode, dst, src));
664 if (GET_CODE (src) == REG &&
665 REGNO (src) >= FIRST_PSEUDO_REGISTER)
668 if (GET_CODE (dst) == REG &&
669 REGNO (dst) >= FIRST_PSEUDO_REGISTER)
673 if (push_operand (dst, mode))
676 if (GET_CODE (src) == CONST_DOUBLE)
677 src = force_const_mem (DFmode, src);
679 if (reload_in_progress)
681 if (!(offsettable_memref_p (src) || register_operand (src, mode)))
683 if (!(offsettable_memref_p (dst) || register_operand (dst,
688 if (GET_CODE (operands[0]) != REG
689 || !refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, operands[1], 0))
691 emit_move_insn (operand_subword (dst, 0, 1, mode),
692 operand_subword_force (src, 0, mode));
693 emit_move_insn (operand_subword (dst, 1, 1, mode),
694 operand_subword_force (src, 1, mode));
698 emit_move_insn (operand_subword (dst, 1, 1, mode),
699 operand_subword_force (src, 1, mode));
700 emit_move_insn (operand_subword (dst, 0, 1, mode),
701 operand_subword_force (src, 0, mode));
704 insns = get_insns ();
707 emit_no_conflict_block (insns, dst, src, 0, src);
714 /* Work out the subword parts to split up a double move
715 into two SI moves - take care to do it in the right order
719 prepare_split_double_ops (operands, mode)
721 enum machine_mode mode;
723 if (GET_CODE (operands[1]) == REG
724 && REGNO (operands[1]) > FIRST_PSEUDO_REGISTER)
727 if (GET_CODE (operands[0]) == REG
728 && REGNO (operands[0]) > FIRST_PSEUDO_REGISTER)
731 /* If we split move insns from memory, it confuses scheduling
733 if (GET_CODE (operands[1]) == MEM)
735 if (GET_CODE (operands[0]) == MEM)
738 if (GET_CODE (operands[0]) != REG
739 || !refers_to_regno_p (REGNO (operands[0]),
740 REGNO (operands[0]) + 1, operands[1], 0))
742 operands[2] = operand_subword (operands[0], 0, 0, mode);
743 operands[3] = operand_subword (operands[1], 0, 0, mode);
744 operands[4] = operand_subword (operands[0], 1, 0, mode);
745 operands[5] = operand_subword (operands[1], 1, 0, mode);
749 operands[2] = operand_subword (operands[0], 1, 0, mode);
750 operands[3] = operand_subword (operands[1], 1, 0, mode);
751 operands[4] = operand_subword (operands[0], 0, 0, mode);
752 operands[5] = operand_subword (operands[1], 0, 0, mode);
755 if (operands[2] == 0 || operands[3] == 0
756 || operands[4] == 0 || operands[5] == 0)
759 emit_move_insn (operands[2], operands[3]);
760 emit_move_insn (operands[4], operands[5]);
764 /* Prepare the operands for an scc instruction; make sure that the
765 compare has been done. */
767 prepare_scc_operands (code)
769 if (GET_CODE (sh_compare_op0) != REG
770 || REGNO (sh_compare_op0) != T_REG)
773 /* First need a compare insn */
794 rtx tmp = sh_compare_op0;
795 sh_compare_op0 = sh_compare_op1;
796 sh_compare_op1 = tmp;
800 sh_compare_op0 = force_reg (SImode, sh_compare_op0);
801 emit_insn (gen_rtx (SET, VOIDmode,
802 gen_rtx (REG, SImode, T_REG),
803 gen_rtx (code, SImode, sh_compare_op0, sh_compare_op1)));
805 return gen_rtx (REG, SImode, T_REG);
809 /* Functions to output assembly code. */
811 /* Return a sequence of instructions to perform DI or DF move.
813 Since the SH cannot move a DI or DF in one instruction, we have
814 to take care when we see overlapping source and dest registers.
819 output_movedouble (insn, operands, mode)
822 enum machine_mode mode;
824 rtx dst = operands[0];
825 rtx src = operands[1];
827 fprintf (asm_out_file, "! move double \n");
828 fprintf (asm_out_file, "! pc %04x\n", insn_addresses[INSN_UID (insn)]);
829 if (GET_CODE (dst) == MEM
830 && GET_CODE (XEXP (dst, 0)) == POST_INC)
832 operands[0] = XEXP (XEXP (dst, 0), 0);
833 return "mov.l %R1,@(4,%0)\n\tmov.l %1,@%0\n\tadd #8,%0";
835 if (register_operand (dst, mode)
836 && register_operand (src, mode))
838 if (REGNO (src) == MACH_REG)
839 return "sts mach,%0\n\tsts macl,%R0";
842 when mov.d r1,r2 do r2->r3 then r1->r2
843 when mov.d r1,r0 do r1->r0 then r2->r1
846 if (REGNO (src) + 1 == REGNO (dst))
847 return "mov %R1,%R0\n\tmov %1,%0 ! cra";
849 return "mov %1,%0\n\tmov %R1,%R0 ! crb";
851 else if (GET_CODE (src) == CONST_INT)
853 HOST_WIDE_INT val = INTVAL (src);
854 int rn = REGNO (operands[0]);
857 fprintf (asm_out_file, "\tmov #-1,r%d\n", rn);
861 fprintf (asm_out_file, "\tmov #0,r%d\n", rn);
864 fprintf (asm_out_file, "\tmov #%d,r%d\n", val, rn + 1);
867 else if (GET_CODE (src) == MEM)
871 int dreg = REGNO (dst);
872 rtx inside = XEXP (src, 0);
874 if (GET_CODE (inside) == REG)
876 ptrreg1 = REGNO (inside);
878 else if (GET_CODE (inside) == PLUS)
880 rtx lhs = XEXP (inside, 0);
881 rtx rhs = XEXP (inside, 1);
882 if (GET_CODE (lhs) == REG)
883 ptrreg1 = REGNO (lhs);
884 if (GET_CODE (rhs) == REG)
885 ptrreg2 = REGNO (rhs);
887 else if (GET_CODE (inside) == LABEL_REF)
889 return "mov.l %1,%0\n\tmov.l %1+4,%R0";
894 if ((ptrreg1 >= 0 && ptrreg2 >= 0)
897 || dreg + 1 == ptrreg1
898 || dreg + 1 == ptrreg2))
900 /* This move clobbers both index registers,
901 calculate the sum in one register. */
902 fprintf (asm_out_file, " add %s,%s ! special fix\n",
903 reg_names[ptrreg2], reg_names[ptrreg1]);
907 /* Copy into dreg+1 first. */
908 fprintf (asm_out_file, " mov.l @(4,%s),%s\n",
910 reg_names[dreg + 1]);
912 fprintf (asm_out_file, " mov.l @(%s),%s\n",
918 /* Copy into dreg first. */
919 fprintf (asm_out_file, " mov.l @(%s),%s\n",
923 fprintf (asm_out_file, " mov.l @(4,%s),%s\n",
925 reg_names[dreg + 1]);
928 warning ("generated complex amode");
932 /* Work out the safe way to copy */
935 /* Copy into the second half first */
936 return "mov.l %R1,%R0\n\tmov.l %1,%0 ! cr";
940 return "mov.l %1,%0\n\tmov.l %R1,%R0";
943 /* Emit assembly to shift reg by k bits */
946 output_shift (string, reg, k, code)
972 if (code == ASHIFT && s == 31)
974 /* Shift left by 31 moving into the t bit, clearing and rotating the other way */
976 fprintf (asm_out_file, "\trotr r%d\n", REGNO (reg));
977 fprintf (asm_out_file, "\tmov #0,r%d\n", REGNO (reg));
978 fprintf (asm_out_file, "\trotcr r%d\n", REGNO (reg));
982 if (code == LSHIFTRT && s == 31)
984 fprintf (asm_out_file, "\trotl r%d\n", REGNO (reg));
985 fprintf (asm_out_file, "\tmov #0,r%d\n", REGNO (reg));
986 fprintf (asm_out_file, "\trotcl r%d\n", REGNO (reg));
1015 fprintf (asm_out_file, "\t%s%s\tr%d\n", string, out, REGNO (reg));
1023 function_epilogue (stream, size)
1027 fprintf (stream, "\trts\n");
1028 fprintf (stream, "\tor r0,r0\n");
1032 /* Return the text of the branch instruction which matches its length
1035 This gets tricky if we have an insn in the delay slot of a branch
1036 and the branch needs more than 1 insn to complete. */
1038 int pending_const_table;
1040 /* We can't tell if we need a register as a scratch for the jump
1041 until after branch shortening, and then it's too late to allocate a
1042 register the 'proper' way. These instruction sequences are rare
1043 anyway, so to avoid always using a reg up from our limited set, we'll
1044 grab one when we need one on output. */
1047 output_far_jump (insn, op)
1051 rtx thislab = gen_label_rtx ();
1053 /* See if we can grab a reg from the prev insn */
1055 rtx prev = PREV_INSN (insn);
1058 if (dbr_sequence_length ())
1060 /* Something to go in what would have been the delay
1061 slot if this had been a short branch. Make sure the
1062 reg we use to generate the branch target address
1069 for (i = 0; i < 8; i++)
1071 vec[1] = gen_rtx (REG, SImode, i);
1072 if (!reg_referenced_p (vec[1], PATTERN (XVECEXP (final_sequence, 0, 1))))
1076 output_asm_insn ("mov.l %1,@-r15", vec);
1077 output_asm_insn ("mov.l %O0,%1", vec);
1078 print_slot (final_sequence);
1079 output_asm_insn ("jmp @%1 ! 32 xcond", vec);
1080 output_asm_insn ("mov.l @r15+,%1", vec);
1084 output_asm_insn ("mov.l r13,@-r15", 0);
1085 output_asm_insn ("mov.l %O0,r13", &thislab);
1086 output_asm_insn ("jmp @r13 ! 32 zcond", 0);
1087 output_asm_insn ("mov.l @r15+,r13", 0);
1090 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (thislab));
1091 output_asm_insn (".align 2", 0);
1092 output_asm_insn (".long %O0", &op);
1097 output_branch (logic, insn)
1101 extern rtx recog_operand[];
1105 fprintf (asm_out_file, "! pc %04x\n", insn_addresses[INSN_UID (insn)]);
1107 switch (get_attr_length (insn))
1110 /* Simple branch in range -200..+200 bytes */
1111 return logic ? "bt%. %l0" : "bf%. %l0";
1114 /* Branch in range -4000..+4000 bytes */
1116 rtx oldop = recog_operand[0];
1119 if (need_slot (final_sequence))
1121 fprintf (asm_out_file, "\tb%c.s\tLF%d\n", logic ? 'f' : 't',
1124 print_slot (final_sequence);
1129 fprintf (asm_out_file, "\tb%c\tLF%d\n", logic ? 'f' : 't',
1132 recog_operand[0] = oldop;
1134 output_asm_insn ("bra %l0 ! 12 bit cond ", recog_operand);
1135 fprintf (asm_out_file, "\tor r0,r0\n");
1136 fprintf (asm_out_file, "LF%d:\n", label);
1141 /* Branches a long way away */
1143 rtx oldop = recog_operand[0];
1145 if (need_slot (final_sequence))
1147 fprintf (asm_out_file, "\tb%c.s\tLF%d\n", logic ? 'f' : 't', label);
1148 print_slot (final_sequence);
1153 fprintf (asm_out_file, "\tb%c\tLF%d\n", logic ? 'f' : 't', label);
1156 output_far_jump (insn, oldop);
1157 fprintf (asm_out_file, "LF%d:\n", label);
1165 /* The SH cannot load a large constant into a register, constants have to
1166 come from a pc relative load. The reference of a pc relative load
1167 instruction must be less than 1k infront of the instruction. This
1168 means that we often have to dump a constant inside a function, and
1169 generate code to branch around it.
1171 It is important to minimize this, since the branches will slow things
1172 down and make things bigger.
1174 Worst case code looks like:
1192 We fix this by performing a scan before scheduling, which notices which
1193 instructions need to have their operands fetched from the constant table
1194 and builds the table.
1199 scan, find an instruction which needs a pcrel move. Look forward, find the
1200 last barrier which is within MAX_COUNT bytes of the requirement.
1201 If there isn't one, make one. Process all the instructions between
1202 the find and the barrier.
1204 In the above example, we can tell that L3 is within 1k of L1, so
1205 the first move can be shrunk from the 3 insn+constant sequence into
1206 just 1 insn, and the constant moved to L3 to make:
1217 Then the second move becomes the target for the shortening process.
1223 rtx value; /* Value in table */
1224 rtx label; /* Label of value */
1225 enum machine_mode mode; /* Mode of value */
1230 /* The maximum number of constants that can fit into one pool, since
1231 the pc relative range is 0...1020 bytes and constants are at least 4
1234 #define MAX_POOL_SIZE (1020/4)
1235 static pool_node pool_vector[MAX_POOL_SIZE];
1236 static int pool_size;
1238 /* Add a constant to the pool and return its label. */
1241 add_constant (x, mode)
1243 enum machine_mode mode;
1247 /* First see if we've already got it */
1249 for (i = 0; i < pool_size; i++)
1251 if (x->code == pool_vector[i].value->code
1252 && mode == pool_vector[i].mode)
1254 if (x->code == CODE_LABEL)
1256 if (XINT (x, 3) != XINT (pool_vector[i].value, 3))
1260 if (rtx_equal_p (x, pool_vector[i].value))
1261 return pool_vector[i].label;
1264 /* Need a new one */
1266 pool_vector[pool_size].value = x;
1267 lab = gen_label_rtx ();
1268 pool_vector[pool_size].mode = mode;
1269 pool_vector[pool_size].label = lab;
1274 /* Dump out interesting debug info */
1277 final_prescan_insn (insn, opvec, noperands)
1282 if (target_flags & ISIZE_BIT)
1284 extern int *insn_addresses;
1285 fprintf (asm_out_file, "\n! at %04x\n",
1286 insn_addresses[INSN_UID (insn)]);
1293 /* Stuff taken from m88k.c */
1295 /* Output to FILE the start of the assembler file. */
1305 output_option (file, sep, type, name, indent, pos, max)
1314 if (strlen (sep) + strlen (type) + strlen (name) + pos > max)
1316 fprintf (file, indent);
1317 return fprintf (file, "%s%s", type, name);
1319 return pos + fprintf (file, "%s%s%s", sep, type, name);
1328 m_options[] = TARGET_SWITCHES;
1331 output_options (file, f_options, f_len, W_options, W_len,
1332 pos, max, sep, indent, term)
1334 struct option *f_options;
1335 struct option *W_options;
1347 pos = output_option (file, sep, "-O", "", indent, pos, max);
1348 if (write_symbols != NO_DEBUG)
1349 pos = output_option (file, sep, "-g", "", indent, pos, max);
1350 if (flag_traditional)
1351 pos = output_option (file, sep, "-traditional", "", indent, pos, max);
1353 pos = output_option (file, sep, "-p", "", indent, pos, max);
1354 if (profile_block_flag)
1355 pos = output_option (file, sep, "-a", "", indent, pos, max);
1357 for (j = 0; j < f_len; j++)
1358 if (*f_options[j].variable == f_options[j].on_value)
1359 pos = output_option (file, sep, "-f", f_options[j].string,
1362 for (j = 0; j < W_len; j++)
1363 if (*W_options[j].variable == W_options[j].on_value)
1364 pos = output_option (file, sep, "-W", W_options[j].string,
1367 for (j = 0; j < sizeof m_options / sizeof m_options[0]; j++)
1368 if (m_options[j].name[0] != '\0'
1369 && m_options[j].value > 0
1370 && ((m_options[j].value & target_flags)
1371 == m_options[j].value))
1372 pos = output_option (file, sep, "-m", m_options[j].name,
1376 fprintf (file, term);
1377 fprintf (file, "! %d %d\n", max_count_si, max_count_hi);
1381 output_file_start (file, f_options, f_len, W_options, W_len)
1383 struct option *f_options;
1384 struct option *W_options;
1389 output_file_directive (file, main_input_filename);
1391 /* Switch to the data section so that the coffsem symbol and the
1392 gcc2_compiled. symbol aren't in the text section. */
1396 pos = fprintf (file, "\n! Hitachi SH cc1 (%s) arguments:", version_string);
1397 output_options (file, f_options, f_len, W_options, W_len,
1398 pos, 75, " ", "\n! ", "\n\n");
1403 /* Return the cost of a shift */
1409 /* If shift by a non constant, then this will be expensive. */
1410 if (GET_CODE (XEXP (RTX, 1)) != CONST_INT)
1413 /* otherwise, it will be very cheap if by one of the constants
1414 we can cope with. */
1415 if (CONST_OK_FOR_K (INTVAL (XEXP (RTX, 1))))
1418 /* otherwise it will be several insns, but we pretend that it will be more than
1419 just the components, so that combine doesn't glue together a load of shifts into
1420 one shift which has to be emitted as a bunch anyway - breaking scheduling */
1429 if (GET_CODE (XEXP (RTX, 1)) != CONST_INT)
1431 i = INTVAL (XEXP (RTX, 1));
1432 /* And can use the extend insns cheaply */
1433 if (i == 0xff || i == 0xffff)
1435 /* Any small constant is reasonably cheap - but requires r0 */
1436 if (CONST_OK_FOR_I (i))
1440 /* Return the cost of a multiply */
1447 /* If we we're aiming at small code, then just count the number of
1448 insns in a multiply call sequence, otherwise, count all the insnsn
1450 if (TARGET_SMALLCODE)
1455 /* Code to expand a shift */
1458 gen_ashift (type, n, reg)
1466 emit_insn (gen_ashrsi3_k (reg, reg, GEN_INT (n)));
1469 emit_insn (gen_lshrsi3_k (reg, reg, GEN_INT (n)));
1473 emit_insn (gen_addsi3 (reg, reg, reg));
1475 emit_insn (gen_ashlsi3_k (reg, reg, GEN_INT (n)));
1481 gen_shifty_op (code, operands)
1485 rtx wrk = gen_reg_rtx (SImode);
1488 if (GET_CODE (operands[2]) == CONST_INT)
1490 int value = INTVAL (operands[2]);
1502 /* Expand a short sequence inline, longer call a magic routine */
1505 emit_move_insn (wrk, operands[1]);
1508 gen_ashift (ASHIFTRT, 1, wrk);
1510 emit_move_insn (operands[0], wrk);
1513 t = gen_reg_rtx (Pmode);
1514 /* Load the value into an arg reg and call a helper */
1515 emit_move_insn (gen_rtx (REG, SImode, 4), operands[1]);
1516 if (!shiftsyms[value])
1518 func = xmalloc (18);
1519 sprintf (func, "__ashiftrt_r4_%d", value);
1520 shiftsyms[value] = gen_rtx (SYMBOL_REF, Pmode, func);
1522 emit_move_insn (t, shiftsyms[value]);
1523 emit_insn (gen_ashrsi3_n (GEN_INT (value), t));
1524 emit_move_insn (operands[0], gen_rtx (REG, SImode, 4));
1544 emit_move_insn (wrk, operands[1]);
1549 gen_ashift (code, 16, wrk);
1552 else if (value >= 8)
1554 gen_ashift (code, 8, wrk);
1557 else if (value >= 2)
1559 gen_ashift (code, 2, wrk);
1564 gen_ashift (code, 1, wrk);
1568 emit_move_insn (operands[0], wrk);
1576 /* Dump out any constants accumulated in the final pass -
1577 which will only be labels */
1579 output_jump_label_table ()
1584 fprintf (asm_out_file, "\t.align 2\n");
1585 for (i = 0; i < pool_size; i++)
1587 pool_node *p = pool_vector + i;
1589 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (p->label));
1590 output_asm_insn (".long %O0", &p->value);
1597 /* Output the literal table */
1608 /* Do two passes, first time dump out the HI sized constants */
1610 for (i = 0; i < pool_size; i++)
1612 pool_node *p = pool_vector + i;
1613 if (p->mode == HImode)
1617 scan = emit_insn_after (gen_align_2 (), scan);
1620 scan = emit_label_after (p->label, scan);
1621 scan = emit_insn_after (gen_consttable_2 (p->value), scan);
1627 for (i = 0; i < pool_size; i++)
1629 pool_node *p = pool_vector + i;
1639 scan = emit_insn_after (gen_align_4 (), scan);
1641 scan = emit_label_after (p->label, scan);
1642 scan = emit_insn_after (gen_consttable_4 (p->value), scan);
1648 scan = emit_insn_after (gen_align_4 (), scan);
1650 scan = emit_label_after (p->label, scan);
1651 scan = emit_insn_after (gen_consttable_8 (p->value), scan);
1659 scan = emit_insn_after (gen_consttable_end (), scan);
1660 scan = emit_barrier_after (scan);
1666 /* Non zero if the src operand needs to be fixed up */
1671 enum machine_mode mode;
1674 return 0; /* QIs never need to be fixed */
1675 if (GET_CODE (src) == CONST)
1678 if (GET_CODE (src) == SYMBOL_REF)
1682 if (GET_CODE (src) == CONST_INT)
1684 /* All QI insns are ok */
1687 /* The rest may need to be fixed */
1688 return !CONST_OK_FOR_I (INTVAL (src));
1693 /* Return Non-zero if constant would be an ok source for a
1694 mov.w instead of a mov.l */
1699 return (GET_CODE (src) == CONST_INT
1700 && INTVAL (src) >= -32768
1701 && INTVAL (src) <= 32767);
1704 /* Find the last barrier less than MAX_COUNT bytes from FROM, or create one.
1705 If an HI move is found, then make sure that MAX_COUNT_HI isn't broken from that one. */
1716 rtx found_barrier = 0;
1719 && count_si < max_count_si
1720 && count_hi < max_count_hi)
1723 if (GET_CODE (from) == BARRIER)
1725 found_barrier = from;
1727 /* Count the length of this insn - we assume that all the pcrelloads
1728 will work out to be only 2 bytes long */
1730 if (GET_CODE (from) == INSN &&
1731 GET_CODE (PATTERN (from)) == SET)
1733 rtx src = SET_SRC (PATTERN (from));
1742 inc = get_attr_length (from);
1748 from = NEXT_INSN (from);
1753 /* Insert a jump around the barrier here */
1754 rtx label = gen_label_rtx ();
1755 /* Walk back to be just before any jump */
1756 while (GET_CODE (from) == JUMP_INSN
1757 || GET_CODE (from) == NOTE)
1759 from = PREV_INSN (from);
1761 from = emit_jump_insn_after (gen_jump (label), from);
1762 JUMP_LABEL (from) = label;
1763 found_barrier = emit_barrier_after (from);
1764 emit_label_after (label, found_barrier);
1765 return found_barrier;
1767 return found_barrier;
1770 /* Non zero if the insn is a move instruction which needs to be fixed. */
1777 if (!INSN_DELETED_P (insn)
1778 && GET_CODE (insn) == INSN
1779 && GET_CODE (PATTERN (insn)) == SET)
1781 rtx pat = PATTERN (insn);
1782 rtx src = SET_SRC (pat);
1783 rtx dst = SET_DEST (pat);
1784 enum machine_mode mode = GET_MODE (dst);
1787 return fixit (src, mode);
1793 /* Exported to toplev.c
1795 Scan the function looking for move instructions which have to be changed to
1796 pcrel loads and insert the literal tables. */
1799 machine_dependent_reorg (first)
1804 for (insn = first; insn; insn = NEXT_INSN (insn))
1806 if (broken_move (insn))
1808 /* This is a broken move instruction, scan ahead looking for
1809 a barrier to stick the constant table behind */
1811 rtx barrier = find_barrier (insn);
1813 /* Now find all the moves between the points and modify them */
1814 for (scan = insn; scan != barrier; scan = NEXT_INSN (scan))
1816 if (broken_move (scan))
1818 rtx pat = PATTERN (scan);
1819 rtx src = SET_SRC (pat);
1820 rtx dst = SET_DEST (pat);
1821 enum machine_mode mode = GET_MODE (dst);
1825 /* This is a broken move instruction, add it to the pool */
1827 if (mode == SImode && hi_const (src))
1829 /* This is an HI source, clobber the dest to get the mode right too */
1831 dst = gen_rtx (REG, HImode, REGNO (dst));
1833 lab = add_constant (src, mode);
1834 newsrc = gen_rtx (MEM, mode,
1835 gen_rtx (LABEL_REF, VOIDmode, lab));
1837 /* Build a jump insn wrapper around the move instead
1838 of an ordinary insn, because we want to have room for
1839 the target label rtx in fld[7], which an ordinary
1840 insn doesn't have. */
1841 newinsn = emit_jump_insn_after (gen_rtx (SET, VOIDmode,
1842 dst, newsrc), scan);
1843 JUMP_LABEL (newinsn) = lab;
1845 /* But it's still an ordinary insn */
1846 PUT_CODE (newinsn, INSN);
1853 dump_table (barrier);
1858 /* Called from the md file, set up the operands of a compare instruction */
1861 from_compare (operands, code)
1865 operands[1] = sh_compare_op0;
1866 operands[2] = force_reg (SImode, sh_compare_op1);
1867 operands[1] = force_reg (SImode, operands[1]);
1870 /* Non-zero if x is EQ or NE */
1873 equality_operator (x, mode)
1875 enum machine_mode mode;
1877 enum rtx_code code = GET_CODE (x);
1878 return (code == EQ || code == NE);
1882 /* Framefull frame looks like:
1886 [ if current_function_anonymous_args
1899 local-0 <- fp points here
1902 If TARGET_SMALLCALL, then the preserved registers are pushed by a
1903 wrapper before the routine is entered, so the regs are always pushed
1904 and there are two pr's on the stack - the caller and the wrapper.
1908 /* Code to generate prologue and epilogue sequences */
1912 sh_expand_prologue ()
1917 live_regs_mask = calc_live_regs (&d);
1919 /* We have pretend args if we had an object sent partially in registers
1920 and partially on the stack - eg a large structure */
1921 output_stack_adjust (-current_function_pretend_args_size);
1923 if (current_function_anonymous_args)
1925 /* Push arg regs as if they'd been provided by caller in stack */
1927 for (i = 0; i < NPARM_REGS; i++)
1929 int rn = NPARM_REGS + FIRST_PARM_REG - i - 1;
1930 if (i > NPARM_REGS - current_function_args_info)
1936 push_regs (live_regs_mask);
1937 output_stack_adjust (-get_frame_size ());
1939 if (frame_pointer_needed)
1941 emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
1946 sh_expand_epilogue ()
1952 live_regs_mask = calc_live_regs (&d);
1954 if (frame_pointer_needed)
1956 emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx));
1958 output_stack_adjust (get_frame_size ());
1960 /* Pop all the registers */
1962 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1964 int j = (FIRST_PSEUDO_REGISTER - 1) - i;
1965 if (live_regs_mask & (1 << j))
1971 output_stack_adjust (extra_push + current_function_pretend_args_size);
1974 current_function_pretend_args_size = 0;
1975 current_function_anonymous_args = 0;
1976 for (i = 0; i < 32; i++)
1980 /* Define the offset between two registers, one to be eliminated, and
1981 the other its replacement, at the start of a routine. */
1984 initial_elimination_offset (from, to)
1987 int regs_saved_mask = calc_live_regs (®s_saved);
1988 int total_saved_regs_space;
1989 int total_auto_space = get_frame_size ();
1990 total_saved_regs_space = (regs_saved) * 4;
1992 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1994 return total_saved_regs_space + total_auto_space;
1996 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1998 return total_saved_regs_space + total_auto_space;
2000 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
2002 /* Initial gap between fp and sp is 0 */
2008 /* Handle machine specific pragmas to be semi-compatible with Hitachi
2012 handle_pragma (file)
2020 while (c == ' ' || c == '\t')
2023 if (c == '\n' || c == EOF)
2026 while (psize < sizeof (pbuf) - 1 && c != '\n')
2029 if (psize == 9 && strncmp (pbuf, "interrupt", 9) == 0)
2031 pragma_interrupt = 1;
2034 if (psize == 5 && strncmp (pbuf, "trapa", 5) == 0)
2036 pragma_interrupt = pragma_trapa = 1;
2044 /* insn expand helpers */
2046 /* Emit insns to perform a call. If TARGET_SMALLCALL, then load the
2047 target address into r1 and call __saveargs, otherwise
2048 perform the standard call sequence */
2051 expand_acall (isa_retval, operands)
2056 rtx ret = operands[0];
2057 rtx call_target = operands[isa_retval + 0];
2058 rtx numargs = operands[isa_retval + 1];
2060 if (GET_CODE (call_target) == MEM)
2062 call_target = force_reg (Pmode,
2063 XEXP (call_target, 0));
2065 if (TARGET_SMALLCALL)
2067 rtx tmp = gen_reg_rtx (SImode);
2068 rtx r1 = gen_rtx (REG, SImode, 1);
2069 emit_move_insn (tmp, gen_rtx (SYMBOL_REF, SImode, "__saveargs"));
2070 emit_move_insn (r1, call_target);
2071 emit_insn (gen_rtx (USE, VOIDmode, r1));
2075 call = gen_rtx (CALL, VOIDmode, gen_rtx (MEM, SImode, call_target), numargs);
2079 call = gen_rtx (SET, VOIDmode, ret, call);
2082 emit_call_insn (gen_rtx (PARALLEL, VOIDmode,
2085 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 17)))));
2090 /* Predicates used by the templates */
2093 /* Returns 1 if OP can be source of a simple move operation.
2094 Same as general_operand, but a LABEL_REF is valid, PRE_DEC is
2095 invalid as are subregs of system registers. */
2098 general_movsrc_operand (op, mode)
2100 enum machine_mode mode;
2102 /* Any MEM(label_ref) is ok, that's a pcrel load */
2103 if (GET_CODE (op) == MEM &&
2104 GET_CODE (XEXP (op, 0)) == LABEL_REF)
2107 /* No predec allowed */
2109 if (GET_CODE (op) == MEM
2110 && GET_CODE (XEXP (op, 0)) == PRE_DEC)
2113 if ((mode == QImode || mode == HImode)
2114 && (GET_CODE (op) == SUBREG
2115 && GET_CODE (XEXP (op, 0)) == REG
2116 && system_reg_operand (XEXP (op, 0), mode)))
2119 if (GET_CODE (op) == CONST_INT)
2121 int i = INTVAL (op);
2122 return CONST_OK_FOR_I (i);
2124 return general_operand (op, mode);
2128 /* Returns 1 if OP can be a destination of a move.
2129 Same as general_operand, but no preinc allowed. */
2132 general_movdst_operand (op, mode)
2134 enum machine_mode mode;
2136 if (GET_CODE (op) == MEM
2137 && GET_CODE (XEXP (op, 0)) == PRE_INC)
2139 return general_operand (op, mode);
2143 /* Returns 1 if OP is an immediate ok for a byte index. */
2146 byte_index_operand (op, mode)
2148 enum machine_mode mode;
2150 return (GET_CODE (op) == CONST_INT
2152 && INTVAL (op) <= 15);
2155 /* Returns 1 if OP is a pop operand. */
2158 pop_operand (op, mode)
2160 enum machine_mode mode;
2162 if (GET_CODE (op) != MEM)
2165 if (GET_MODE (op) != mode)
2170 if (GET_CODE (op) != POST_INC)
2173 return XEXP (op, 0) == stack_pointer_rtx;
2177 /* Returns 1 if OP is a normal arithmetic register. */
2180 arith_reg_operand (op, mode)
2182 enum machine_mode mode;
2184 if (register_operand (op, mode))
2186 if (GET_CODE (op) == REG)
2187 return (REGNO (op) != T_REG
2188 && REGNO (op) != PR_REG);
2194 /* Returns 1 if OP is MACL, MACH or PR. */
2197 system_reg_operand (op, mode)
2199 enum machine_mode mode;
2201 if (GET_CODE (op) == REG)
2215 /* Returns 1 if OP is a valid source operand for an arithmetic insn. */
2218 arith_operand (op, mode)
2220 enum machine_mode mode;
2222 if (arith_reg_operand (op, mode))
2225 if (GET_CODE (op) == CONST_INT)
2227 if (CONST_OK_FOR_I (INTVAL (op)))
2234 /* Returns 1 if OP is a valid source operand for a logical operation. */
2237 logical_operand (op, mode)
2239 enum machine_mode mode;
2241 if (arith_reg_operand (op, mode))
2244 if (GET_CODE (op) == CONST_INT)
2246 if (CONST_OK_FOR_L (INTVAL (op)))