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 #define MSW (TARGET_LITTLE_ENDIAN ? 1 : 0)
42 #define LSW (TARGET_LITTLE_ENDIAN ? 0 : 1)
45 static rtx add_constant ();
50 int current_function_anonymous_args;
51 extern int current_function_pretend_args_size;
52 extern char *version_string;
53 extern int flag_traditional;
55 static rtx shiftsyms[32];
56 struct rtx_def *table_lab;
57 enum attr_cpu sh_cpu; /* target cpu */
65 /* Global variables for machine-dependent things. */
67 /* Saved operands from the last compare to use when we generate an scc
73 /* Provides the class number of the smallest class containing
76 int regno_reg_class[FIRST_PSEUDO_REGISTER] =
78 R0_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
79 GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
80 GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
81 GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
82 GENERAL_REGS, PR_REGS, T_REGS, NO_REGS,
86 /* Provide reg_class from a letter such as appears in the machine
89 enum reg_class reg_class_from_letter[] =
91 /* a */ NO_REGS, /* b */ NO_REGS, /* c */ NO_REGS, /* d */ NO_REGS,
92 /* e */ NO_REGS, /* f */ NO_REGS, /* g */ NO_REGS, /* h */ NO_REGS,
93 /* i */ NO_REGS, /* j */ NO_REGS, /* k */ NO_REGS, /* l */ PR_REGS,
94 /* m */ NO_REGS, /* n */ NO_REGS, /* o */ NO_REGS, /* p */ NO_REGS,
95 /* q */ NO_REGS, /* r */ NO_REGS, /* s */ NO_REGS, /* t */ T_REGS,
96 /* u */ NO_REGS, /* v */ NO_REGS, /* w */ NO_REGS, /* x */ MAC_REGS,
97 /* y */ NO_REGS, /* z */ R0_REGS
100 /* Value is 1 if register/mode pair is acceptable on SH. Even
101 registers can hold DIs and DF values. The rest can only hold
106 ( (1 << (int) QImode) | (1 << (int) HImode) | (1 << (int) SImode) \
107 | (1 << (int) QFmode) | (1 << (int) HFmode) | (1 << (int) SFmode) \
108 | (1 << (int) CQImode) | (1 << (int) CHImode)| (1<< (int)DFmode) | (1<<(int)DImode))
111 (REG_ODD | (1 << (int) CSImode) | (1 << (int) SCmode))
113 #define SI_ONLY (1<<(int)SImode)
115 int hard_regno_mode_ok[] =
117 REG_EVEN, REG_ODD, REG_EVEN, REG_ODD,
118 REG_EVEN, REG_ODD, REG_EVEN, REG_ODD,
119 REG_EVEN, REG_ODD, REG_EVEN, REG_ODD,
120 REG_EVEN, REG_ODD, REG_EVEN, REG_ODD,
121 REG, 0, SI_ONLY, SI_ONLY,
125 /* Local label counter, used for constants in the pool and inside
130 /* Number of bytes pushed for anonymous args, used to pass information
131 between expand_prologue and expand_epilogue. */
132 static int extra_push;
141 x= emit_insn (gen_push (gen_rtx (REG, SImode, rn)));
142 REG_NOTES (x) = gen_rtx (EXPR_LIST, REG_INC,
143 gen_rtx(REG, SImode, STACK_POINTER_REGNUM), 0);
151 x = emit_insn (gen_pop (gen_rtx (REG, SImode, rn)));
152 REG_NOTES (x) = gen_rtx (EXPR_LIST, REG_INC,
153 gen_rtx(REG, SImode, STACK_POINTER_REGNUM), 0);
157 /* Adjust the stack and return the number of bytes taken to do it */
161 output_stack_adjust (size)
166 rtx val = GEN_INT (size);
169 if (!CONST_OK_FOR_I (size))
171 lastreg = gen_rtx (REG, SImode, 3);
173 emit_insn (gen_movsi (lastreg, val));
178 insn = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, val);
184 /* Generate code to push the regs specified in the mask, and return
185 the number of bytes the insns take. */
193 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
203 /* Print an instruction which would have gone into a delay slot after
204 an instructiuon, but couldn't because the instruction expanded into a
205 sequence where putting the slot insn at the end wouldn't work. */
211 final_scan_insn (XVECEXP (insn, 0, 1), asm_out_file, optimize, 0, 1);
213 INSN_DELETED_P (XVECEXP (insn, 0, 1)) = 1;
217 /* Work out the registers which need to be saved, both as a mask and a
220 If doing a pragma interrupt function, then push all regs used by the function,
221 and if we call another function (we can tell by looking at PR), make sure that all the
222 regs it clobbers are safe too.
225 calc_live_regs (count_ptr)
229 int live_regs_mask = 0;
231 for (reg = 0; reg < FIRST_PSEUDO_REGISTER; reg++)
233 if (reg == ARG_POINTER_REGNUM)
240 if (pragma_interrupt && !pragma_trapa)
242 /* Need to save all the regs ever live */
243 if ((regs_ever_live[reg]
244 || (call_used_regs[reg] && regs_ever_live[PR_REG]))
247 live_regs_mask |= 1 << reg;
251 else if (TARGET_SMALLCALL)
253 /* Don't need to push anthing, but count the regs which have
254 been pushed by the wrapper */
255 if (call_used_regs[reg])
260 /* Only push those regs which are used and need to be saved */
261 if (regs_ever_live[reg] && !call_used_regs[reg])
264 live_regs_mask |= (1 << reg);
271 return live_regs_mask;
279 return (insn && !INSN_ANNULLED_BRANCH_P (XVECEXP (insn, 0, 0)));
282 /* Print the operand address in x to the stream */
285 print_operand_address (stream, x)
289 switch (GET_CODE (x))
292 fprintf (stream, "@%s", reg_names[REGNO (x)]);
296 rtx base = XEXP (x, 0);
297 rtx index = XEXP (x, 1);
299 if (GET_CODE (base) != REG)
301 /* Ensure that BASE is a register (one of them must be). */
307 switch (GET_CODE (index))
310 fprintf (stream, "@(%d,%s)",
312 reg_names[REGNO (base)]);
316 fprintf (stream, "@(r0,%s)",
317 reg_names[MAX (REGNO (base), REGNO (index))]);
329 fprintf (stream, "@-%s", reg_names[REGNO (XEXP (x, 0))]);
333 fprintf (stream, "@%s+", reg_names[REGNO (XEXP (x, 0))]);
337 output_addr_const (stream, x);
342 /* Print operand x (an rtx) in assembler syntax to file stream
343 according to modifier code.
345 '.' print a .s if insn needs delay slot
346 '*' print a local label
347 '^' increment the local label number
348 '!' dump the constant table
349 '#' output a nop if there is nothing to put in the delay slot
350 '@' print rte or rts depending upon pragma interruptness
351 'R' print the LSW of a dp value - changes if in little endian
352 'T' print the next word of a dp value - same as 'R' in big endian mode.
353 'S' print the MSW of a dp value - changes if in little endian
354 'O' print a constant without the #
355 'M' print a constant as its negative
356 'N' print insides of a @++ or @-- o */
359 print_operand (stream, x, code)
367 if (need_slot (final_sequence))
368 fprintf (stream, ".s");
371 fprintf (stream, "LF%d", lf);
377 if (pragma_interrupt)
378 fprintf (stream, "rte");
380 fprintf (stream, "rts");
383 /* Output a nop if there's nothing in the delay slot */
384 if (dbr_sequence_length () == 0)
386 fprintf (stream, "\n\tnop");
390 output_addr_const (stream, x);
393 fprintf (asm_out_file, "#%d", -INTVAL (x));
396 fputs (reg_names[REGNO (XEXP (XEXP (x, 0), 0))], (stream));
399 /* LSW of a double */
400 switch (GET_CODE (x))
403 fputs (reg_names[REGNO (x) + LSW], (stream));
406 print_operand_address (stream, XEXP (adj_offsettable_operand (x, LSW *4), 0));
411 /* Next word of a double */
412 switch (GET_CODE (x))
415 fputs (reg_names[REGNO (x) + 1], (stream));
418 print_operand_address (stream, XEXP (adj_offsettable_operand (x,1 *4), 0));
423 /* MSW of a double */
424 switch (GET_CODE (x))
427 fputs (reg_names[REGNO (x) + MSW], (stream));
430 print_operand_address (stream, XEXP (adj_offsettable_operand (x, MSW *4), 0));
435 switch (GET_CODE (x))
438 fputs (reg_names[REGNO (x)], (stream));
441 output_address (XEXP (x, 0));
445 output_addr_const (stream, x);
467 /* Take a move with integer constant source in OPERANDS, see if it can be generated by
468 devious shifting. If so, generate the instruction sequence and return 1, otherwise
471 OPERANDS[0] Destination register
472 OPERANDS[1] Source constant
474 00000000 00000000 00000000 0NNNNNNNN simple load
475 00000000 00000000 00000000 NNNNNNNN0 load and shift by 1
476 00000000 00000000 0000000N NNNNNNN00 load and shift by 2
477 00000000 00000000 0NNNNNNN 000000000 load and shift by 8
478 00000000 0NNNNNNN 00000000 000000000 load and shift by 16
479 N0000000 00000000 00000000 00NNNNNNN load and rotate right
481 11111111 11111111 11111111 1NNNNNNNN simple load
482 11111111 11111111 11111111 NNNNNNNN0 load and shift by 1
483 11111111 11111111 1111111N NNNNNNN00 load and shift by 2
484 11111111 11111111 1NNNNNNN 000000000 load and shift by 8
485 11111111 1NNNNNNN 00000000 000000000 load and shift by 16
486 N1111111 11111111 11111111 11NNNNNNN load and rotate right
488 00000000 00000000 00000000 1NNNNNNNN load and zero extend byte
489 00000000 00000000 11111111 1NNNNNNNN load and zero extend word
495 synth_constant (operands, mode)
497 enum machine_mode mode;
500 int i = INTVAL (operands[1]) & 0xffffffff;
502 if (CONST_OK_FOR_I (i))
505 if (TARGET_CLEN0 && mode != QImode)
510 if (reload_in_progress)
512 dst = gen_reg_rtx (SImode);
520 /* 00000000 00000000 11111111 1NNNNNNNN load and zero extend word */
521 if ((i & 0xffffff80) == 0x0000ff80)
523 emit_move_insn (dst, GEN_INT (sextb (i)));
524 emit_insn (gen_and_ffff (dst, dst));
526 /* 00000000 00000000 00000000 1NNNNNNNN load and zero extend byte */
527 else if ((i & 0xffffff80) == 0x00000080)
529 emit_move_insn (dst, GEN_INT (sextb (i)));
530 emit_insn (gen_and_ff (dst, dst));
532 /* 00000000 00000000 00000000 NNNNNNNN0 load and shift by 1
533 11111111 11111111 11111111 NNNNNNNN0 load and shift by 1 */
534 else if ((i & 0xffffff01) == 0
535 || (i & 0xffffff01) == 0xffffff00)
537 emit_move_insn (dst, GEN_INT (sextb (i >> 1)));
538 emit_insn (gen_ashlsi3_n (dst, dst, GEN_INT (1)));
540 /* 00000000 00000000 0000000N NNNNNNN00 load and shift by 2
541 11111111 11111111 1111111N NNNNNNN00 load and shift by 2*/
542 else if ((i & 0xfffffe03) == 0
543 || (i & 0xfffffe03) == 0xfffffe00)
545 emit_move_insn (dst, GEN_INT (sextb (i >> 2)));
546 emit_insn (gen_ashlsi3_n (dst, dst, GEN_INT (2)));
548 /* 00000000 00000000 0NNNNNNN 000000000 load and shift by 8
549 11111111 11111111 1NNNNNNN 000000000 load and shift by 8 */
551 else if ((i & 0xffff80ff) == 0
552 || (i & 0xffff80ff) == 0xffff8000)
554 emit_move_insn (dst, GEN_INT (sextb (i >> 8)));
555 emit_insn (gen_ashlsi3_n (dst, dst, GEN_INT (8)));
557 /* 00000000 0NNNNNNN 00000000 000000000 load and shift by 16
558 11111111 1NNNNNNN 00000000 000000000 load and shift by 16 */
559 else if ((i & 0xff80ffff) == 0x00000000
560 || (i & 0xff80ffff) == 0xff800000)
562 emit_move_insn (dst, GEN_INT (sextb (i >> 16)));
563 emit_insn (gen_ashlsi3_n (dst, dst, GEN_INT (16)));
565 /* 00000000 00000000 0NNNNNNN 0NNNNNNNN load shift 8 and add */
566 else if ((i & 0xffff8080) == 0 && TARGET_CLEN3)
568 emit_move_insn (dst, GEN_INT (sextb (i >> 8)));
569 emit_insn (gen_ashlsi3_n (dst, dst, GEN_INT (8)));
570 emit_insn (gen_addsi3 (dst, dst, GEN_INT (i & 0x7f)));
577 /* Moving from SI to DI, we've got to zero out the high part */
579 emit_insn (gen_rtx (SET, VOIDmode,
580 gen_rtx (SUBREG, SImode, operands[0], 0),
582 emit_insn (gen_rtx (SET, VOIDmode,
583 gen_rtx (SUBREG, SImode, operands[0], 1),
587 else if (mode != SImode)
589 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
590 gen_rtx (SUBREG, mode, dst, 0)));
597 /* Emit code to perform a block move. Choose the best method.
599 OPERANDS[0] is the destination.
600 OPERANDS[1] is the source.
601 OPERANDS[2] is the size.
602 OPERANDS[3] is the alignment safe to use. */
606 expand_block_move (operands)
609 int align = INTVAL (operands[3]);
610 int constp = (GET_CODE (operands[2]) == CONST_INT);
611 int bytes = (constp ? INTVAL (operands[2]) : 0);
612 enum machine_mode mode;
614 /* IF odd then fail */
615 if (!constp || bytes <= 0)
618 /* Don't expand if we'd make the code bigger and we don't want big code */
620 if (bytes > 8 && TARGET_SMALLCODE)
636 if (mode == SImode && constp && bytes < 64 && (bytes % 4 == 0))
641 rtx r4 = gen_rtx (REG, SImode, 4);
642 rtx r5 = gen_rtx (REG, SImode, 5);
643 sprintf (entry, "__movstr%s%d", GET_MODE_NAME (mode), bytes);
644 entry_name = get_identifier (entry);
646 func_addr_rtx = copy_to_mode_reg (Pmode,
647 gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (entry_name)));
648 emit_insn (gen_move_insn (r4, XEXP (operands[0], 0)));
649 emit_insn (gen_move_insn (r5, XEXP (operands[1], 0)));
650 emit_insn (gen_block_move_real (func_addr_rtx));
653 if (mode == SImode && constp && (bytes % 4 == 0))
657 rtx r4 = gen_rtx (REG, SImode, 4);
658 rtx r5 = gen_rtx (REG, SImode, 5);
659 rtx r6 = gen_rtx (REG, SImode, 6);
660 entry_name = get_identifier ("__movstr");
662 func_addr_rtx = copy_to_mode_reg (Pmode,
663 gen_rtx (SYMBOL_REF, Pmode,
664 IDENTIFIER_POINTER (entry_name)));
665 emit_insn (gen_move_insn (r4, XEXP (operands[0], 0)));
666 emit_insn (gen_move_insn (r5, XEXP (operands[1], 0)));
668 /* r6 controls the size of the move, 16 is decremented from it
669 for each 64 bytes moved, then the -ve bit is used as an index into a
670 list of move instructions like this:
699 eg, a 72 byte move would be set up with size(r6) = 14, for one
700 iteration through the big while loop, and a switch of -2 for the last part */
703 int final_switch = 16 - ((bytes / 4) % 16);
704 int while_loop = ((bytes / 4) / 16 - 1) * 16;
705 emit_insn (gen_move_insn (r6, GEN_INT (while_loop + final_switch)));
706 emit_insn (gen_block_lump_real (func_addr_rtx));
714 /* Prepare operands for a move define_expand; specifically, one of the
715 operands must be in a register. Take this chance to remove
716 addressing modes which can't be coped with very well. */
719 prepare_move_operands (operands, mode)
721 enum machine_mode mode;
723 if (!(reload_in_progress || reload_completed)
724 && ((!register_operand (operands[0], mode)
725 && !register_operand (operands[1], mode))
726 || GET_CODE (operands[1]) == PLUS))
728 /* copy the source to a register */
729 operands[1] = copy_to_mode_reg (mode, operands[1]);
731 if ((mode == SImode || mode == HImode || mode == QImode)
732 && GET_CODE (operands[1]) == CONST_INT)
734 return synth_constant (operands, mode);
736 if (mode == DFmode || mode == DImode)
738 rtx src = operands[1];
739 rtx dst = operands[0];
744 emit_insn (gen_rtx (SET, VOIDmode, dst, src));
748 if (GET_CODE (src) == REG &&
749 REGNO (src) >= FIRST_PSEUDO_REGISTER)
752 if (GET_CODE (dst) == REG &&
753 REGNO (dst) >= FIRST_PSEUDO_REGISTER)
756 if (push_operand (dst, mode))
759 if (GET_CODE (src) == CONST_DOUBLE)
760 src = force_const_mem (DFmode, src);
762 if (reload_in_progress)
764 if (!(offsettable_memref_p (src) || register_operand (src, mode)))
766 if (!(offsettable_memref_p (dst) || register_operand (dst,
771 if (GET_CODE (operands[0]) != REG
772 || !refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, operands[1], 0))
774 emit_move_insn (operand_subword (dst, 0, 1, mode),
775 operand_subword_force (src, 0, mode));
776 emit_move_insn (operand_subword (dst, 1, 1, mode),
777 operand_subword_force (src, 1, mode));
781 emit_move_insn (operand_subword (dst, 1, 1, mode),
782 operand_subword_force (src, 1, mode));
783 emit_move_insn (operand_subword (dst, 0, 1, mode),
784 operand_subword_force (src, 0, mode));
787 insns = get_insns ();
790 emit_no_conflict_block (insns, dst, src, 0, src);
797 /* Prepare the operands for an scc instruction; make sure that the
798 compare has been done. */
800 prepare_scc_operands (code)
803 if (GET_CODE (sh_compare_op0) != REG
804 || REGNO (sh_compare_op0) != T_REG)
807 /* First need a compare insn */
828 rtx tmp = sh_compare_op0;
829 sh_compare_op0 = sh_compare_op1;
830 sh_compare_op1 = tmp;
834 sh_compare_op0 = force_reg (SImode, sh_compare_op0);
835 emit_insn (gen_rtx (SET, VOIDmode,
836 gen_rtx (REG, SImode, T_REG),
837 gen_rtx (code, SImode, sh_compare_op0, sh_compare_op1)));
839 return gen_rtx (REG, SImode, T_REG);
843 /* Functions to output assembly code. */
845 /* Return a sequence of instructions to perform DI or DF move.
847 Since the SH cannot move a DI or DF in one instruction, we have
848 to take care when we see overlapping source and dest registers.
853 output_movedouble (insn, operands, mode)
856 enum machine_mode mode;
858 rtx dst = operands[0];
859 rtx src = operands[1];
861 /* fprintf (asm_out_file, "! move double \n");
862 fprintf (asm_out_file, "! pc %04x\n", insn_addresses[INSN_UID (insn)]);*/
863 if (GET_CODE (dst) == MEM
864 && GET_CODE (XEXP (dst, 0)) == POST_INC)
866 operands[0] = XEXP (XEXP (dst, 0), 0);
867 return "mov.l %T1,@(4,%0)\n\tmov.l %1,@%0\n\tadd #8,%0";
869 if (register_operand (dst, mode)
870 && register_operand (src, mode))
872 if (REGNO (src) == MACH_REG)
873 return "sts mach,%S0\n\tsts macl,%R0";
876 when mov.d r1,r2 do r2->r3 then r1->r2
877 when mov.d r1,r0 do r1->r0 then r2->r1
880 if (REGNO (src) + 1 == REGNO (dst))
881 return "mov %T1,%T0\n\tmov %1,%0 ! cra";
883 return "mov %1,%0\n\tmov %T1,%T0 ! crb";
885 else if (GET_CODE (src) == CONST_INT)
887 HOST_WIDE_INT val = INTVAL (src);
888 int rn = REGNO (operands[0]);
893 fprintf (asm_out_file, "\tmov #-1,r%d\n", msw);
897 fprintf (asm_out_file, "\tmov #0,r%d\n", msw);
900 fprintf (asm_out_file, "\tmov #%d,r%d\n", val, lsw);
903 else if (GET_CODE (src) == MEM)
907 int dreg = REGNO (dst);
908 rtx inside = XEXP (src, 0);
910 if (GET_CODE (inside) == REG)
912 ptrreg1 = REGNO (inside);
914 else if (GET_CODE (inside) == PLUS)
916 rtx lhs = XEXP (inside, 0);
917 rtx rhs = XEXP (inside, 1);
918 if (GET_CODE (lhs) == REG)
919 ptrreg1 = REGNO (lhs);
920 if (GET_CODE (rhs) == REG)
921 ptrreg2 = REGNO (rhs);
923 else if (GET_CODE (inside) == LABEL_REF)
925 return "mov.l %1,%0\n\tmov.l %1+4,%T0";
927 else if (GET_CODE (inside) == POST_INC)
929 return "mov.l %1,%0\n\tmov.l %1,%T0 !mdi\n";
934 if ((ptrreg1 >= 0 && ptrreg2 >= 0)
937 || dreg + 1 == ptrreg1
938 || dreg + 1 == ptrreg2))
940 /* This move clobbers both index registers,
941 calculate the sum in one register. */
942 fprintf (asm_out_file, " add %s,%s ! special fix\n",
943 reg_names[ptrreg2], reg_names[ptrreg1]);
947 /* Copy into dreg+1 first. */
948 fprintf (asm_out_file, " mov.l @(4,%s),%s\n",
950 reg_names[dreg + 1]);
952 fprintf (asm_out_file, " mov.l @(%s),%s\n",
958 /* Copy into dreg first. */
959 fprintf (asm_out_file, " mov.l @(%s),%s\n",
963 fprintf (asm_out_file, " mov.l @(4,%s),%s\n",
965 reg_names[dreg + 1]);
968 warning ("generated complex amode");
972 /* Work out the safe way to copy */
975 /* Copy into the second half first */
976 return "mov.l %T1,%T0\n\tmov.l %1,%0 ! cr";
980 return "mov.l %1,%0\n\tmov.l %T1,%T0";
983 /* Emit assembly to shift reg by k bits */
986 output_shift (string, reg, k, code)
1010 if (code == ASHIFT && s == 31)
1012 /* Shift left by 31 moving into the t bit, clearing and rotating the other way */
1014 fprintf (asm_out_file, "\trotr r%d\n", REGNO (reg));
1015 fprintf (asm_out_file, "\tmov #0,r%d\n", REGNO (reg));
1016 fprintf (asm_out_file, "\trotcr r%d\n", REGNO (reg));
1020 if (code == LSHIFTRT && s == 31)
1022 fprintf (asm_out_file, "\trotl r%d\n", REGNO (reg));
1023 fprintf (asm_out_file, "\tmov #0,r%d\n", REGNO (reg));
1024 fprintf (asm_out_file, "\trotcl r%d\n", REGNO (reg));
1053 fprintf (asm_out_file, "\t%s%s\tr%d\n", string, out, REGNO (reg));
1061 function_epilogue (stream, size)
1065 pragma_interrupt = pragma_trapa = 0;
1069 /* Return the text of the branch instruction which matches its length
1072 This gets tricky if we have an insn in the delay slot of a branch
1073 and the branch needs more than 1 insn to complete. */
1075 int pending_const_table;
1077 /* We can't tell if we need a register as a scratch for the jump
1078 until after branch shortening, and then it's too late to allocate a
1079 register the 'proper' way. These instruction sequences are rare
1080 anyway, so to avoid always using a reg up from our limited set, we'll
1081 grab one when we need one on output. */
1084 output_far_jump (insn, op)
1088 rtx thislab = gen_label_rtx ();
1090 if (dbr_sequence_length ())
1092 /* Something to go in what would have been the delay
1093 slot if this had been a short branch. Make sure the
1094 reg we use to generate the branch target address
1101 for (i = 0; i < 8; i++)
1103 vec[1] = gen_rtx (REG, SImode, i);
1104 if (!reg_referenced_p (vec[1],
1105 PATTERN (XVECEXP (final_sequence, 0, 1))))
1110 print_slot (final_sequence);
1111 output_asm_insn ("mov.l %1,@-r15", vec);
1112 output_asm_insn ("mov.l %O0,%1", vec);
1114 output_asm_insn ("jmp @%1 ! 32 xcond", vec);
1115 output_asm_insn ("mov.l @r15+,%1", vec);
1119 output_asm_insn ("mov.l r13,@-r15", 0);
1120 output_asm_insn ("mov.l %O0,r13", &thislab);
1121 output_asm_insn ("jmp @r13 ! 32 zcond", 0);
1122 output_asm_insn ("mov.l @r15+,r13", 0);
1125 output_asm_insn (".align 2", 0);
1126 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (thislab));
1127 output_asm_insn (".long %O0", &op);
1132 output_branch (logic, insn)
1136 extern rtx recog_operand[];
1139 /* fprintf (asm_out_file, "! pc %04x\n", insn_addresses[INSN_UID (insn)]);*/
1141 switch (get_attr_length (insn))
1144 /* Simple branch in range -200..+200 bytes */
1145 return logic ? "bt%. %l0" : "bf%. %l0";
1148 /* Branch in range -4000..+4000 bytes */
1150 rtx oldop = recog_operand[0];
1153 if (need_slot (final_sequence))
1155 fprintf (asm_out_file, "\tb%c.s\tLF%d\n", logic ? 'f' : 't',
1158 print_slot (final_sequence);
1163 fprintf (asm_out_file, "\tb%c\tLF%d\n", logic ? 'f' : 't',
1166 recog_operand[0] = oldop;
1168 output_asm_insn ("bra %l0 ! 12 bit cond ", recog_operand);
1169 fprintf (asm_out_file, "\tor r0,r0\n");
1170 fprintf (asm_out_file, "LF%d:\n", label);
1175 /* Branches a long way away */
1177 rtx oldop = recog_operand[0];
1179 if (need_slot (final_sequence))
1181 fprintf (asm_out_file, "\tb%c.s\tLF%d\n", logic ? 'f' : 't', label);
1182 print_slot (final_sequence);
1187 fprintf (asm_out_file, "\tb%c\tLF%d\n", logic ? 'f' : 't', label);
1190 output_far_jump (insn, oldop);
1191 fprintf (asm_out_file, "LF%d:\n", label);
1199 /* The SH cannot load a large constant into a register, constants have to
1200 come from a pc relative load. The reference of a pc relative load
1201 instruction must be less than 1k infront of the instruction. This
1202 means that we often have to dump a constant inside a function, and
1203 generate code to branch around it.
1205 It is important to minimize this, since the branches will slow things
1206 down and make things bigger.
1208 Worst case code looks like:
1226 We fix this by performing a scan before scheduling, which notices which
1227 instructions need to have their operands fetched from the constant table
1228 and builds the table.
1233 scan, find an instruction which needs a pcrel move. Look forward, find the
1234 last barrier which is within MAX_COUNT bytes of the requirement.
1235 If there isn't one, make one. Process all the instructions between
1236 the find and the barrier.
1238 In the above example, we can tell that L3 is within 1k of L1, so
1239 the first move can be shrunk from the 3 insn+constant sequence into
1240 just 1 insn, and the constant moved to L3 to make:
1251 Then the second move becomes the target for the shortening process.
1257 rtx value; /* Value in table */
1258 rtx label; /* Label of value */
1259 enum machine_mode mode; /* Mode of value */
1264 /* The maximum number of constants that can fit into one pool, since
1265 the pc relative range is 0...1020 bytes and constants are at least 4
1268 #define MAX_POOL_SIZE (1020/4)
1269 static pool_node pool_vector[MAX_POOL_SIZE];
1270 static int pool_size;
1272 /* Add a constant to the pool and return its label. */
1275 add_constant (x, mode)
1277 enum machine_mode mode;
1281 /* First see if we've already got it */
1283 for (i = 0; i < pool_size; i++)
1285 if (x->code == pool_vector[i].value->code
1286 && mode == pool_vector[i].mode)
1288 if (x->code == CODE_LABEL)
1290 if (XINT (x, 3) != XINT (pool_vector[i].value, 3))
1293 if (rtx_equal_p (x, pool_vector[i].value))
1294 return pool_vector[i].label;
1298 /* Need a new one */
1300 pool_vector[pool_size].value = x;
1301 lab = gen_label_rtx ();
1302 pool_vector[pool_size].mode = mode;
1303 pool_vector[pool_size].label = lab;
1308 /* Dump out interesting debug info */
1311 final_prescan_insn (insn, opvec, noperands)
1316 if (target_flags & ISIZE_BIT)
1318 extern int *insn_addresses;
1319 fprintf (asm_out_file, "\n! at %04x\n",
1320 insn_addresses[INSN_UID (insn)]);
1327 /* Stuff taken from m88k.c */
1329 /* Output to FILE the start of the assembler file. */
1339 output_option (file, sep, type, name, indent, pos, max)
1348 if (strlen (sep) + strlen (type) + strlen (name) + pos > max)
1350 fprintf (file, indent);
1351 return fprintf (file, "%s%s", type, name);
1353 return pos + fprintf (file, "%s%s%s", sep, type, name);
1362 m_options[] = TARGET_SWITCHES;
1365 output_options (file, f_options, f_len, W_options, W_len,
1366 pos, max, sep, indent, term)
1368 struct option *f_options;
1369 struct option *W_options;
1381 pos = output_option (file, sep, "-O", "", indent, pos, max);
1382 if (write_symbols != NO_DEBUG)
1383 pos = output_option (file, sep, "-g", "", indent, pos, max);
1384 if (flag_traditional)
1385 pos = output_option (file, sep, "-traditional", "", indent, pos, max);
1387 pos = output_option (file, sep, "-p", "", indent, pos, max);
1388 if (profile_block_flag)
1389 pos = output_option (file, sep, "-a", "", indent, pos, max);
1391 for (j = 0; j < f_len; j++)
1392 if (*f_options[j].variable == f_options[j].on_value)
1393 pos = output_option (file, sep, "-f", f_options[j].string,
1396 for (j = 0; j < W_len; j++)
1397 if (*W_options[j].variable == W_options[j].on_value)
1398 pos = output_option (file, sep, "-W", W_options[j].string,
1401 for (j = 0; j < sizeof m_options / sizeof m_options[0]; j++)
1402 if (m_options[j].name[0] != '\0'
1403 && m_options[j].value > 0
1404 && ((m_options[j].value & target_flags)
1405 == m_options[j].value))
1406 pos = output_option (file, sep, "-m", m_options[j].name,
1410 fprintf (file, term);
1411 fprintf (file, "! %d %d\n", max_count_si, max_count_hi);
1413 if (TARGET_LITTLE_ENDIAN)
1414 fprintf (file, "\t.little\n");
1418 output_file_start (file, f_options, f_len, W_options, W_len)
1420 struct option *f_options;
1421 struct option *W_options;
1426 output_file_directive (file, main_input_filename);
1428 /* Switch to the data section so that the coffsem symbol and the
1429 gcc2_compiled. symbol aren't in the text section. */
1433 pos = fprintf (file, "\n! Hitachi SH cc1 (%s) arguments:", version_string);
1434 output_options (file, f_options, f_len, W_options, W_len,
1435 pos, 75, " ", "\n! ", "\n\n");
1439 /* Actual number of instructions used to make a shift by N */
1440 char ashiftrt_insns[] = { 0,1,2,3,4,5,8,8,8,8,8,8,8,8,8,8,2,3,4,5,8,8,8,8,8,8,8,8,8,8,8,2};
1441 char lshiftrt_insns[] = { 0,1,1,2,2,3,3,4,1,2,2,3,3,4,4,5,1,2,2,3,3,4,4,5,2,3,3,4,4,5,5,6};
1442 char shift_insns[] = { 0,1,1,2,2,3,3,4,1,2,2,3,3,4,4,5,1,2,2,3,3,4,4,5,2,3,3,4,4,5,5,6};
1445 shiftinsns (shift, n)
1446 enum rtx_code shift;
1452 return ashiftrt_insns[n];
1454 return lshiftrt_insns[n];
1456 return shift_insns[n];
1464 /* Return the cost of a shift */
1470 /* If shift by a non constant, then this will be expensive. */
1471 if (GET_CODE (XEXP (RTX, 1)) != CONST_INT)
1476 /* otherwise, it will be very cheap if by one of the constants
1477 we can cope with. */
1479 if (CONST_OK_FOR_K (INTVAL (XEXP (RTX, 1))))
1481 /* otherwise it will be several insns, but we pretend that it will be more than
1482 just the components, so that combine doesn't glue together a load of shifts into
1483 one shift which has to be emitted as a bunch anyway - breaking scheduling */
1492 if (GET_CODE (XEXP (RTX, 1)) != CONST_INT)
1494 i = INTVAL (XEXP (RTX, 1));
1495 /* And can use the extend insns cheaply */
1496 if (i == 0xff || i == 0xffff)
1498 /* Any small constant is reasonably cheap - but requires r0 */
1499 if (CONST_OK_FOR_I (i))
1535 /* Return the cost of a multiply */
1542 /* We have a mul insn, so we can never take more than the mul and the
1543 read of the mac reg, but count more because of the latency and extra
1545 if (TARGET_SMALLCODE)
1550 /* If we're aiming at small code, then just count the number of
1551 insns in a multiply call sequence */
1552 if (TARGET_SMALLCODE)
1555 /* Otherwise count all the insns in the routine we'd be calling too */
1559 /* Code to expand a shift */
1562 gen_ashift (type, n, reg)
1570 emit_insn (gen_ashrsi3_k (reg, reg, GEN_INT (n)));
1573 emit_insn (gen_lshrsi3_k (reg, reg, GEN_INT (n)));
1577 emit_insn (gen_addsi3 (reg, reg, reg));
1579 emit_insn (gen_ashlsi3_k (reg, reg, GEN_INT (n)));
1585 gen_shifty_op (code, operands)
1589 rtx wrk = gen_reg_rtx (SImode);
1593 if (GET_CODE (operands[2]) == CONST_INT)
1595 int value = INTVAL (operands[2]);
1609 emit_insn (gen_ashrsi2_31 (operands[0], operands[1]));
1612 else if (value >= 16 && value <= 19)
1614 emit_insn (gen_ashrsi2_16 (wrk, operands[1]));
1617 gen_ashift (ASHIFTRT,1, wrk);
1618 emit_move_insn (operands[0], wrk);
1621 /* Expand a short sequence inline, longer call a magic routine */
1624 emit_move_insn (wrk, operands[1]);
1627 gen_ashift (ASHIFTRT, 1, wrk);
1629 emit_move_insn (operands[0], wrk);
1632 t = gen_reg_rtx (Pmode);
1633 /* Load the value into an arg reg and call a helper */
1634 emit_move_insn (gen_rtx (REG, SImode, 4), operands[1]);
1635 if (!shiftsyms[value])
1637 func = xmalloc (18);
1638 sprintf (func, "__ashiftrt_r4_%d", value);
1639 shiftsyms[value] = gen_rtx (SYMBOL_REF, Pmode, func);
1641 emit_move_insn (t, shiftsyms[value]);
1642 emit_insn (gen_ashrsi3_n (GEN_INT (value), t));
1643 emit_move_insn (operands[0], gen_rtx (REG, SImode, 4));
1663 emit_move_insn (wrk, operands[1]);
1668 gen_ashift (code, 16, wrk);
1671 else if (value >= 8)
1673 gen_ashift (code, 8, wrk);
1676 else if (value >= 2)
1678 gen_ashift (code, 2, wrk);
1683 gen_ashift (code, 1, wrk);
1687 emit_move_insn (operands[0], wrk);
1696 /* Dump out any constants accumulated in the final pass -
1697 which will only be labels */
1699 output_jump_label_table ()
1704 fprintf (asm_out_file, "\t.align 2\n");
1705 for (i = 0; i < pool_size; i++)
1707 pool_node *p = pool_vector + i;
1709 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (p->label));
1710 output_asm_insn (".long %O0", &p->value);
1717 /* Output the literal table */
1727 /* Do two passes, first time dump out the HI sized constants */
1729 for (i = 0; i < pool_size; i++)
1731 pool_node *p = pool_vector + i;
1732 if (p->mode == HImode)
1736 scan = emit_insn_after (gen_align_2 (), scan);
1739 scan = emit_label_after (p->label, scan);
1740 scan = emit_insn_after (gen_consttable_2 (p->value), scan);
1745 for (i = 0; i < pool_size; i++)
1747 pool_node *p = pool_vector + i;
1757 scan = emit_label_after (gen_label_rtx (), scan);
1758 scan = emit_insn_after (gen_align_4 (), scan);
1760 scan = emit_label_after (p->label, scan);
1761 scan = emit_insn_after (gen_consttable_4 (p->value), scan);
1767 scan = emit_label_after (gen_label_rtx (), scan);
1768 scan = emit_insn_after (gen_align_4 (), scan);
1770 scan = emit_label_after (p->label, scan);
1771 scan = emit_insn_after (gen_consttable_8 (p->value), scan);
1779 scan = emit_insn_after (gen_consttable_end (), scan);
1780 scan = emit_barrier_after (scan);
1786 /* Non zero if the src operand needs to be fixed up */
1791 enum machine_mode mode;
1794 return 0; /* QIs never need to be fixed */
1795 if (GET_CODE (src) == CONST)
1798 if (GET_CODE (src) == SYMBOL_REF)
1802 if (GET_CODE (src) == LABEL_REF)
1806 if (GET_CODE (src) == CONST_INT)
1808 /* All QI insns are ok */
1811 /* The rest may need to be fixed */
1812 return !CONST_OK_FOR_I (INTVAL (src));
1817 /* Return Non-zero if constant would be an ok source for a
1818 mov.w instead of a mov.l */
1823 if (GET_CODE (src) == CONST
1824 && GET_CODE (XEXP (src, 0)) == SIGN_EXTEND
1825 && GET_CODE (XEXP (XEXP (src, 0), 0)) == SYMBOL_REF)
1828 if (TARGET_SHORTADDR
1829 && GET_CODE (src) == SYMBOL_REF)
1832 return (GET_CODE (src) == CONST_INT
1833 && INTVAL (src) >= -32768
1834 && INTVAL (src) <= 32767);
1837 /* Find the last barrier less than MAX_COUNT bytes from FROM, or create one.
1838 If an HI move is found, then make sure that MAX_COUNT_HI isn't broken from that one. */
1849 rtx found_barrier = 0;
1851 && count_si < max_count_si
1852 && count_hi < max_count_hi)
1855 if (GET_CODE (from) == BARRIER)
1857 found_barrier = from;
1859 /* Count the length of this insn - we assume that all moves will
1860 be 2 bytes long, except the DIs */
1862 if (GET_CODE (from) == INSN &&
1863 GET_CODE (PATTERN (from)) == SET)
1865 rtx src = SET_SRC (PATTERN (from));
1870 inc = (GET_MODE_SIZE (GET_MODE (src)) > 4) ? 4 : 2;
1874 inc = get_attr_length (from);
1880 from = NEXT_INSN (from);
1885 /* We didn't find a barrier in time to
1886 dump our stuff, so we'll make one */
1887 rtx label = gen_label_rtx ();
1888 /* Walk back to be just before any jump */
1889 from = PREV_INSN (from);
1890 while (GET_CODE (from) == JUMP_INSN
1891 || GET_CODE (from) == NOTE
1892 || GET_CODE (from) == CODE_LABEL)
1894 from = PREV_INSN (from);
1896 from = emit_jump_insn_after (gen_jump (label), from);
1897 JUMP_LABEL (from) = label;
1898 found_barrier = emit_barrier_after (from);
1899 emit_label_after (label, found_barrier);
1900 return found_barrier;
1902 return found_barrier;
1905 /* Non zero if the insn is a move instruction which needs to be fixed. */
1912 if (!INSN_DELETED_P (insn)
1913 && GET_CODE (insn) == INSN
1914 && GET_CODE (PATTERN (insn)) == SET)
1916 rtx pat = PATTERN (insn);
1917 rtx src = SET_SRC (pat);
1918 rtx dst = SET_DEST (pat);
1919 enum machine_mode mode = GET_MODE (dst);
1922 return fixit (src, mode);
1928 /* Exported to toplev.c
1930 Scan the function looking for move instructions which have to be changed to
1931 pcrel loads and insert the literal tables. */
1934 machine_dependent_reorg (first)
1938 for (insn = first; insn; insn = NEXT_INSN (insn))
1940 if (broken_move (insn))
1942 /* This is a broken move instruction, scan ahead looking for
1943 a barrier to stick the constant table behind */
1945 rtx barrier = find_barrier (insn);
1947 /* Now find all the moves between the points and modify them */
1948 for (scan = insn; scan != barrier; scan = NEXT_INSN (scan))
1950 if (broken_move (scan))
1952 rtx pat = PATTERN (scan);
1953 rtx src = SET_SRC (pat);
1954 rtx dst = SET_DEST (pat);
1955 enum machine_mode mode = GET_MODE (dst);
1959 /* This is a broken move instruction, add it to the pool */
1961 if (mode == SImode && hi_const (src))
1963 /* This is an HI source, clobber the dest to get the mode right too */
1966 while (GET_CODE (dst) == SUBREG)
1968 offset += SUBREG_WORD (dst);
1969 dst = SUBREG_REG (dst);
1971 dst = gen_rtx (REG, HImode, REGNO (dst) + offset);
1973 lab = add_constant (src, mode);
1974 newsrc = gen_rtx (MEM, mode,
1975 gen_rtx (LABEL_REF, VOIDmode, lab));
1977 /* Build a jump insn wrapper around the move instead
1978 of an ordinary insn, because we want to have room for
1979 the target label rtx in fld[7], which an ordinary
1980 insn doesn't have. */
1981 newinsn = emit_jump_insn_after (gen_rtx (SET, VOIDmode,
1982 dst, newsrc), scan);
1983 JUMP_LABEL (newinsn) = lab;
1985 /* But it's still an ordinary insn */
1986 PUT_CODE (newinsn, INSN);
1993 dump_table (barrier);
1998 /* Called from the md file, set up the operands of a compare instruction */
2001 from_compare (operands, code)
2005 if (code != EQ && code != NE)
2007 /* Force args into regs, since we can't use constants here */
2008 sh_compare_op0 = force_reg (SImode, sh_compare_op0);
2009 if (sh_compare_op1 != const0_rtx)
2010 sh_compare_op1 = force_reg (SImode, sh_compare_op1);
2012 operands[1] = sh_compare_op0;
2013 operands[2] = sh_compare_op1;
2016 /* Non-zero if x is EQ or NE */
2019 equality_operator (x, mode)
2021 enum machine_mode mode;
2023 enum rtx_code code = GET_CODE (x);
2024 return (code == EQ || code == NE);
2028 /* Add this function to the list of ones seen - temporary
2029 gross hack to try out bsrs. */
2041 struct flist *n = (struct flist *) xmalloc (sizeof (struct flist));
2042 int l = strlen (name) + 1;
2043 n->name = xmalloc (l);
2044 memcpy (n->name, name, l);
2050 seen_function (name)
2053 struct flist *p = head;
2054 for (p = head; p; p = p->next)
2056 if (strcmp (p->name, name) == 0)
2062 /* Framefull frame looks like:
2066 [ if current_function_anonymous_args
2079 local-0 <- fp points here
2082 If TARGET_SMALLCALL, then the preserved registers are pushed by a
2083 wrapper before the routine is entered, so the regs are always pushed
2084 and there are two pr's on the stack - the caller and the wrapper.
2088 /* Code to generate prologue and epilogue sequences */
2092 sh_expand_prologue ()
2096 extern tree current_function_decl;
2097 live_regs_mask = calc_live_regs (&d);
2099 /* We have pretend args if we had an object sent partially in registers
2100 and partially on the stack - eg a large structure */
2101 output_stack_adjust (-current_function_pretend_args_size);
2105 /* This is set by SETUP_VARARGS to indicate that this is a varargs
2106 routine. Clear it here so that the next function isn't affected. */
2107 if (current_function_anonymous_args)
2109 current_function_anonymous_args = 0;
2111 /* Push arg regs as if they'd been provided by caller in stack */
2112 for (i = 0; i < NPARM_REGS; i++)
2114 int rn = NPARM_REGS + FIRST_PARM_REG - i - 1;
2115 if (i > NPARM_REGS - current_function_args_info)
2121 push_regs (live_regs_mask);
2122 output_stack_adjust (-get_frame_size ());
2124 if (frame_pointer_needed)
2126 emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
2130 add_function (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
2133 /* ??? Hack. Clear out the table set up by gen_shifty_op since this
2134 info does not apply to the next function. */
2135 for (i = 0; i < 32; i++)
2140 sh_expand_epilogue ()
2145 live_regs_mask = calc_live_regs (&d);
2147 if (frame_pointer_needed)
2149 emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx));
2151 output_stack_adjust (get_frame_size ());
2153 /* Pop all the registers */
2155 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2157 int j = (FIRST_PSEUDO_REGISTER - 1) - i;
2158 if (live_regs_mask & (1 << j))
2164 output_stack_adjust (extra_push + current_function_pretend_args_size);
2167 /* Define the offset between two registers, one to be eliminated, and
2168 the other its replacement, at the start of a routine. */
2171 initial_elimination_offset (from, to)
2176 int total_saved_regs_space;
2177 int total_auto_space = get_frame_size ();
2179 calc_live_regs (®s_saved);
2180 total_saved_regs_space = (regs_saved) * 4;
2182 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
2184 return total_saved_regs_space + total_auto_space;
2186 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
2188 return total_saved_regs_space + total_auto_space;
2190 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
2192 /* Initial gap between fp and sp is 0 */
2198 /* Handle machine specific pragmas to be semi-compatible with Hitachi
2202 handle_pragma (file)
2210 while (c == ' ' || c == '\t')
2213 if (c == '\n' || c == EOF)
2216 while (psize < sizeof (pbuf) - 1 && c != '\n')
2219 if (psize == 9 && strncmp (pbuf, "interrupt", 9) == 0)
2221 pragma_interrupt = 1;
2224 if (psize == 5 && strncmp (pbuf, "trapa", 5) == 0)
2226 pragma_interrupt = pragma_trapa = 1;
2234 /* insn expand helpers */
2236 /* Emit insns to perform a call.
2237 If TARGET_SHORTADDR then use a bsr. If TARGET_SMALLCALL, then load the
2238 target address into r1 and call __saveargs, otherwise
2239 perform the standard call sequence */
2242 expand_acall (isa_retval, operands)
2247 rtx ret = operands[0];
2248 rtx call_target = operands[isa_retval + 0];
2249 rtx numargs = operands[isa_retval + 1];
2251 if (TARGET_BSR && bsr_operand (call_target, VOIDmode))
2253 call = gen_rtx (CALL, VOIDmode, call_target, numargs);
2257 if (GET_CODE (call_target) == MEM)
2259 call_target = force_reg (Pmode,
2260 XEXP (call_target, 0));
2262 if (TARGET_SMALLCALL)
2264 rtx tmp = gen_reg_rtx (SImode);
2265 rtx r1 = gen_rtx (REG, SImode, 1);
2266 emit_move_insn (tmp, gen_rtx (SYMBOL_REF, SImode, "__saveargs"));
2267 emit_move_insn (r1, call_target);
2268 emit_insn (gen_rtx (USE, VOIDmode, r1));
2272 call = gen_rtx (CALL, VOIDmode, gen_rtx (MEM, SImode, call_target), numargs);
2276 call = gen_rtx (SET, VOIDmode, ret, call);
2279 emit_call_insn (gen_rtx (PARALLEL, VOIDmode,
2282 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 17)))));
2287 /* Predicates used by the templates */
2290 /* Returns 1 if OP can be source of a simple move operation.
2291 Same as general_operand, but a LABEL_REF is valid, PRE_DEC is
2292 invalid as are subregs of system registers. */
2295 general_movsrc_operand (op, mode)
2297 enum machine_mode mode;
2299 /* Any MEM(label_ref) is ok, that's a pcrel load */
2300 if (GET_CODE (op) == MEM
2301 && GET_CODE (XEXP (op, 0)) == LABEL_REF)
2304 if (GET_CODE (op) == MEM)
2306 rtx inside = XEXP (op, 0);
2307 if (GET_CODE (inside) == CONST)
2308 inside = XEXP (inside, 0);
2310 if (GET_CODE (inside) == LABEL_REF)
2313 if (GET_CODE (inside) == PLUS
2314 && GET_CODE (XEXP (inside,0)) == LABEL_REF
2315 && GET_CODE (XEXP (inside,1)) == CONST_INT)
2318 /* No post inc allowed */
2319 if (GET_CODE (inside) == POST_DEC
2320 || GET_CODE (inside) == PRE_INC
2321 || GET_CODE (inside) == PRE_DEC)
2324 /* Can't do that with large modes */
2325 if (GET_CODE (inside) == POST_INC
2326 && GET_MODE_SIZE (mode) > 4)
2330 if ((mode == QImode || mode == HImode)
2331 && (GET_CODE (op) == SUBREG
2332 && GET_CODE (XEXP (op, 0)) == REG
2333 && system_reg_operand (XEXP (op, 0), mode)))
2336 if (GET_CODE (op) == CONST_INT)
2338 int i = INTVAL (op);
2339 return CONST_OK_FOR_I (i);
2341 return general_operand (op, mode);
2345 /* Returns 1 if OP can be a destination of a move.
2346 Same as general_operand, but no preinc allowed. */
2349 general_movdst_operand (op, mode)
2351 enum machine_mode mode;
2353 /* No pre dec allowed */
2354 if (GET_CODE (op) == MEM
2355 && (GET_CODE (XEXP (op, 0)) == PRE_INC
2356 || GET_CODE (XEXP (op, 0)) == POST_INC
2357 || GET_CODE (XEXP (op, 0)) == POST_DEC))
2360 if (GET_CODE (op) == MEM
2361 && GET_CODE (XEXP (op, 0)) == PRE_DEC
2362 && GET_MODE_SIZE (mode) > 4)
2365 return general_operand (op, mode);
2370 /* Returns 1 if OP is valid destination for a bsr. */
2373 bsr_operand (op, mode)
2375 enum machine_mode mode;
2379 if (GET_CODE (op) == SYMBOL_REF)
2381 if (!strcmp (XSTR (op, 0),
2382 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))))
2384 return (seen_function (XSTR (op, 0)));
2390 /* Returns 1 if OP is an immediate ok for a byte index. */
2393 byte_index_operand (op, mode)
2395 enum machine_mode mode;
2397 return (GET_CODE (op) == CONST_INT
2399 && INTVAL (op) <= 15);
2402 /* Returns 1 if OP is a pop operand. */
2405 pop_operand (op, mode)
2407 enum machine_mode mode;
2409 if (GET_CODE (op) != MEM)
2412 if (GET_MODE (op) != mode)
2417 if (GET_CODE (op) != POST_INC)
2420 return XEXP (op, 0) == stack_pointer_rtx;
2424 /* Returns 1 if OP is a normal arithmetic register. */
2427 arith_reg_operand (op, mode)
2429 enum machine_mode mode;
2431 if (register_operand (op, mode))
2433 if (GET_CODE (op) == REG)
2434 return (REGNO (op) != T_REG
2435 && REGNO (op) != PR_REG
2436 && REGNO (op) != MACH_REG
2437 && REGNO (op) != MACL_REG);
2443 /* Returns 1 if OP is MACL, MACH or PR. */
2446 system_reg_operand (op, mode)
2448 enum machine_mode mode;
2450 if (GET_CODE (op) == REG)
2464 /* Returns 1 if OP is a valid source operand for an arithmetic insn. */
2467 arith_operand (op, mode)
2469 enum machine_mode mode;
2471 if (arith_reg_operand (op, mode))
2474 if (GET_CODE (op) == CONST_INT)
2476 if (CONST_OK_FOR_I (INTVAL (op)))
2483 /* Returns 1 if OP is a valid count operand for a shift operation. */
2485 shiftby_operand (op, mode)
2487 enum machine_mode mode;
2489 if (immediate_operand (op, mode))
2494 /* Returns 1 if OP is a valid source operand for a logical operation. */
2497 logical_operand (op, mode)
2499 enum machine_mode mode;
2501 if (arith_reg_operand (op, mode))
2504 if (GET_CODE (op) == CONST_INT)
2506 if (CONST_OK_FOR_L (INTVAL (op)))
2512 /* Returns 1 if OP is a valid operand for a MAC instruction,
2513 either a register or indirect memory. For now we don't
2514 try and recognise a mac insn */
2517 mac_operand (op, mode)
2519 enum machine_mode mode;
2521 if (arith_reg_operand (op, mode))
2524 Turned off till mac is understood
2525 if (GET_CODE (op) == MEM)
2531 /* Determine where to put an argument to a function.
2532 Value is zero to push the argument on the stack,
2533 or a hard register in which to store the argument.
2535 MODE is the argument's machine mode.
2536 TYPE is the data type of the argument (as a tree).
2537 This is null for libcalls where that information may
2539 CUM is a variable of type CUMULATIVE_ARGS which gives info about
2540 the preceding args and about the function being called.
2541 NAMED is nonzero if this argument is a named parameter
2542 (otherwise it is an extra parameter matching an ellipsis). */
2545 sh_function_arg (cum, mode, type, named)
2546 CUMULATIVE_ARGS cum;
2547 enum machine_mode mode;
2553 int rr = (ROUND_REG ((cum), (mode)));
2555 if (rr < NPARM_REGS)
2557 return (((type) == 0 || !TREE_ADDRESSABLE ((tree) (type)))
2558 && ((type) == 0 || (mode) != BLKmode
2559 || (TYPE_ALIGN ((type)) % PARM_BOUNDARY == 0))
2560 ? gen_rtx (REG, (mode),
2561 (FIRST_PARM_REG + rr))
2569 /* For an arg passed partly in registers and partly in memory,
2570 this is the number of registers used.
2571 For args passed entirely in registers or entirely in memory, zero.
2572 Any arg that starts in the first 4 regs but won't entirely fit in them
2573 needs partial registers on the SH. */
2576 sh_function_arg_partial_nregs (CUM, MODE, TYPE, NAMED)
2577 CUMULATIVE_ARGS CUM;
2578 enum machine_mode MODE;
2582 if ((CUM) < NPARM_REGS)
2584 if (((TYPE) == 0 || !TREE_ADDRESSABLE ((tree) (TYPE)))
2585 && ((TYPE) == 0 || (TYPE_ALIGN ((TYPE)) % PARM_BOUNDARY == 0))
2586 && ((CUM) + ((MODE) == BLKmode
2587 ? ROUND_ADVANCE (int_size_in_bytes (TYPE))
2588 : ROUND_ADVANCE (GET_MODE_SIZE (MODE))) - NPARM_REGS > 0))
2590 return NPARM_REGS - CUM;
2598 /* Turn this on to recognise shift insns which aren't supported in the
2599 hardware. This will allow the combiner to notice more patterns,
2600 but the down side is that the asm outputter will have to emit
2601 several instructions for each shift which isn't possible in the
2602 hardware, this makes scheduling perform badly .*/