From: Steve Chamberlain Date: Wed, 20 Apr 1994 19:17:23 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d3ae8277eb0e9bf19536a1b0916c23bb55edbc59;p=gcc.git *** empty log message *** From-SVN: r7101 --- diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index ccb366e5b0d..5999f8a0137 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -95,13 +95,13 @@ enum reg_class reg_class_from_letter[] = #define REG_ODD \ ( (1 << (int) QImode) | (1 << (int) HImode) | (1 << (int) SImode) \ | (1 << (int) QFmode) | (1 << (int) HFmode) | (1 << (int) SFmode) \ - | (1 << (int) CQImode) | (1 << (int) CHImode)) + | (1 << (int) CQImode) | (1 << (int) CHImode)| (1<< (int)DFmode) | (1<<(int)DImode)) #define REG_EVEN \ - (REG_ODD | (1 << (int) DImode) | (1 << (int) DFmode) \ - | (1 << (int) CSImode) | (1 << (int) SCmode)) + (REG_ODD | (1 << (int) CSImode) | (1 << (int) SCmode)) #define SI_ONLY (1<<(int)SImode) + int hard_regno_mode_ok[] = { REG_EVEN, REG_ODD, REG_EVEN, REG_ODD, @@ -327,6 +327,7 @@ print_operand_address (stream, x) '^' increment the local label number '!' dump the constant table '#' output a nop if there is nothing to put in the delay slot + '@' print rte or rts depending upon pragma interruptness 'R' print the next register or memory location along, ie the lsw in a double word value 'O' print a constant without the # @@ -351,11 +352,17 @@ print_operand (stream, x, code) case '^': lf++; break; + case '@': + if (pragma_interrupt) + fprintf (stream,"rte"); + else + fprintf (stream,"rts"); + break; case '#': /* Output a nop if there's nothing in the delay slot */ if (dbr_sequence_length () == 0) { - fprintf (stream, "\n\tor r0,r0\t!wasted slot"); + fprintf (stream, "\n\tnop"); } break; case 'O': @@ -445,10 +452,22 @@ synth_constant (operands, mode) rtx dst; int i = INTVAL (operands[1]) & 0xffffffff; - if (CONST_OK_FOR_I (i)) + if (CONST_OK_FOR_I (i)) return 0; - dst = mode == SImode ? operands[0] : gen_reg_rtx (SImode); + if (TARGET_CLEN0 && mode != QImode) + return 0; + + if (mode != SImode) + { + if (reload_in_progress) + return 0; + dst = gen_reg_rtx (SImode); + } + else + { + dst = operands[0]; + } /* 00000000 00000000 11111111 1NNNNNNNN load and zero extend word */ if ((i & 0xffffff80) == 0x0000ff80) @@ -531,10 +550,16 @@ expand_block_move (operands) int constp = (GET_CODE (operands[2]) == CONST_INT); int bytes = (constp ? INTVAL (operands[2]) : 0); enum machine_mode mode; + /* IF odd then fail */ if (!constp || bytes <= 0) return 0; + /* Don't expand if we'd make the code bigger and we don't want big code */ + + if (bytes > 8 && TARGET_SMALLCODE) + return 0; + switch (align) { case 1: @@ -547,6 +572,7 @@ expand_block_move (operands) mode = SImode; align = 4; } + if (mode == SImode && constp && bytes < 64 && (bytes % 4 == 0)) { char entry[30]; @@ -623,8 +649,8 @@ expand_block_move (operands) return 1; } } - return 0; + return 0; } /* Prepare operands for a move define_expand; specifically, one of the @@ -669,7 +695,6 @@ prepare_move_operands (operands, mode) REGNO (dst) >= FIRST_PSEUDO_REGISTER) return 0; - if (push_operand (dst, mode)) return 0; @@ -711,56 +736,6 @@ prepare_move_operands (operands, mode) return 0; } -/* Work out the subword parts to split up a double move - into two SI moves - take care to do it in the right order - */ - -int -prepare_split_double_ops (operands, mode) - rtx operands[]; - enum machine_mode mode; -{ - if (GET_CODE (operands[1]) == REG - && REGNO (operands[1]) > FIRST_PSEUDO_REGISTER) - return 0; - - if (GET_CODE (operands[0]) == REG - && REGNO (operands[0]) > FIRST_PSEUDO_REGISTER) - return 0; - - /* If we split move insns from memory, it confuses scheduling - later on. */ - if (GET_CODE (operands[1]) == MEM) - return 0; - if (GET_CODE (operands[0]) == MEM) - return 0; - - if (GET_CODE (operands[0]) != REG - || !refers_to_regno_p (REGNO (operands[0]), - REGNO (operands[0]) + 1, operands[1], 0)) - { - operands[2] = operand_subword (operands[0], 0, 0, mode); - operands[3] = operand_subword (operands[1], 0, 0, mode); - operands[4] = operand_subword (operands[0], 1, 0, mode); - operands[5] = operand_subword (operands[1], 1, 0, mode); - } - else - { - operands[2] = operand_subword (operands[0], 1, 0, mode); - operands[3] = operand_subword (operands[1], 1, 0, mode); - operands[4] = operand_subword (operands[0], 0, 0, mode); - operands[5] = operand_subword (operands[1], 0, 0, mode); - } - - if (operands[2] == 0 || operands[3] == 0 - || operands[4] == 0 || operands[5] == 0) - return 0; - - emit_move_insn (operands[2], operands[3]); - emit_move_insn (operands[4], operands[5]); - return 1; -} - /* Prepare the operands for an scc instruction; make sure that the compare has been done. */ rtx @@ -824,8 +799,8 @@ output_movedouble (insn, operands, mode) rtx dst = operands[0]; rtx src = operands[1]; - fprintf (asm_out_file, "! move double \n"); - fprintf (asm_out_file, "! pc %04x\n", insn_addresses[INSN_UID (insn)]); +/* fprintf (asm_out_file, "! move double \n"); + fprintf (asm_out_file, "! pc %04x\n", insn_addresses[INSN_UID (insn)]);*/ if (GET_CODE (dst) == MEM && GET_CODE (XEXP (dst, 0)) == POST_INC) { @@ -1022,8 +997,7 @@ function_epilogue (stream, size) FILE *stream; int size; { - fprintf (stream, "\trts\n"); - fprintf (stream, "\tor r0,r0\n"); + pragma_interrupt = pragma_trapa = 0; } @@ -1085,8 +1059,8 @@ output_far_jump (insn, op) output_asm_insn ("mov.l @r15+,r13", 0); } - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (thislab)); output_asm_insn (".align 2", 0); + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (thislab)); output_asm_insn (".long %O0", &op); return ""; } @@ -1100,7 +1074,7 @@ output_branch (logic, insn) int label = lf++; int rn = -1; int need_save; - fprintf (asm_out_file, "! pc %04x\n", insn_addresses[INSN_UID (insn)]); +/* fprintf (asm_out_file, "! pc %04x\n", insn_addresses[INSN_UID (insn)]);*/ switch (get_attr_length (insn)) { @@ -1391,7 +1365,7 @@ output_file_start (file, f_options, f_len, W_options, W_len) data_section (); - pos = fprintf (file, "\n! Hitachi SH cc1 (%s) arguments:", version_string); + pos = fprintf (file, "\n! Hitachi SH cc1 (%s) (release D-1) arguments:", version_string); output_options (file, f_options, f_len, W_options, W_len, pos, 75, " ", "\n! ", "\n\n"); } @@ -1416,7 +1390,7 @@ shiftcosts (RTX) /* otherwise it will be several insns, but we pretend that it will be more than just the components, so that combine doesn't glue together a load of shifts into one shift which has to be emitted as a bunch anyway - breaking scheduling */ - return 100; + return 1; } int @@ -1435,19 +1409,73 @@ andcosts (RTX) return 3; return 5; } + +int howshift (i) +int i; +{ + int total = 0; + while (i > 0) + { + if (i >= 16) { + total++; + i -= 16; + } + else if (i >= 8) { + total++; + i -= 8; + } + else if (i >= 2) { + total++; + i -= 2; + } + else if (i>=1) { + total++; + i--; + } + } + return total; +} + /* Return the cost of a multiply */ int multcosts (RTX) rtx RTX; { + /* If mult by a power of 2 then work out how we'd shift to make it */ + int insn_cost; + + if (GET_CODE (XEXP (RTX, 1)) == CONST_INT) + { + int i = exact_log2 (INTVAL (XEXP (RTX, 1))); + if (i >= 0) + insn_cost = howshift (i); + else + insn_cost = 100000; + } if (TARGET_SH2) - return 2; + { + /* We have a mul insn, so we can never take more than the mul and the + read of the mac reg, but count more because of the latency and extra reg + usage */ + if (TARGET_SMALLCODE) + return 2; + if (insn_cost > 5) + return 5; + return insn_cost; + } + /* If we we're aiming at small code, then just count the number of - insns in a multiply call sequence, otherwise, count all the insnsn - inside the call. */ - if (TARGET_SMALLCODE) - return 3; - return 30; + insns in a multiply call sequence */ + + if (TARGET_SMALLCODE) + { + if (insn_cost > 6) + return 6; + return insn_cost; + } + + /* Otherwise count all the insns in the routine we'd be calling too */ + return 20; } /* Code to expand a shift */ @@ -1498,7 +1526,7 @@ gen_shifty_op (code, operands) } /* Expand a short sequence inline, longer call a magic routine */ - if (value < 4) + if (value <= 5) { emit_move_insn (wrk, operands[1]); while (value--) @@ -1621,7 +1649,6 @@ dump_table (scan) } need_align = 1; - for (i = 0; i < pool_size; i++) { pool_node *p = pool_vector + i; @@ -1634,6 +1661,7 @@ dump_table (scan) if (need_align) { need_align = 0; + scan = emit_label_after (gen_label_rtx (), scan); scan = emit_insn_after (gen_align_4 (), scan); } scan = emit_label_after (p->label, scan); @@ -1643,6 +1671,7 @@ dump_table (scan) if (need_align) { need_align = 0; + scan = emit_label_after (gen_label_rtx (), scan); scan = emit_insn_after (gen_align_4 (), scan); } scan = emit_label_after (p->label, scan); @@ -1694,6 +1723,15 @@ int hi_const (src) rtx src; { + if (GET_CODE (src) == CONST + && GET_CODE (XEXP (src, 0)) == SIGN_EXTEND + && GET_CODE (XEXP (XEXP (src, 0), 0)) == SYMBOL_REF) + return 1; + + if (TARGET_SHORTADDR + && GET_CODE (src) == SYMBOL_REF) + return 1; + return (GET_CODE (src) == CONST_INT && INTVAL (src) >= -32768 && INTVAL (src) <= 32767); @@ -1826,6 +1864,8 @@ machine_dependent_reorg (first) { /* This is an HI source, clobber the dest to get the mode right too */ mode = HImode; + while (GET_CODE (dst) == SUBREG) + dst = SUBREG_REG (dst); dst = gen_rtx (REG, HImode, REGNO (dst)); } lab = add_constant (src, mode); @@ -1860,9 +1900,15 @@ from_compare (operands, code) rtx *operands; int code; { + if (code != EQ && code != NE) + { + /* Force args into regs, since we can't use constants here */ + sh_compare_op0 = force_reg (SImode, sh_compare_op0); + if (sh_compare_op1 != const0_rtx) + sh_compare_op1 = force_reg (SImode, sh_compare_op1); + } operands[1] = sh_compare_op0; - operands[2] = force_reg (SImode, sh_compare_op1); - operands[1] = force_reg (SImode, operands[1]); + operands[2] = sh_compare_op1; } /* Non-zero if x is EQ or NE */ @@ -1973,6 +2019,7 @@ sh_expand_epilogue () current_function_anonymous_args = 0; for (i = 0; i < 32; i++) shiftsyms[i] = 0; + } /* Define the offset between two registers, one to be eliminated, and @@ -2041,7 +2088,8 @@ handle_pragma (file) /* insn expand helpers */ -/* Emit insns to perform a call. If TARGET_SMALLCALL, then load the +/* Emit insns to perform a call. + If TARGET_SHORTADDR then use a bsr. If TARGET_SMALLCALL, then load the target address into r1 and call __saveargs, otherwise perform the standard call sequence */ @@ -2055,23 +2103,29 @@ expand_acall (isa_retval, operands) rtx call_target = operands[isa_retval + 0]; rtx numargs = operands[isa_retval + 1]; - if (GET_CODE (call_target) == MEM) - { - call_target = force_reg (Pmode, - XEXP (call_target, 0)); - } - if (TARGET_SMALLCALL) + if (TARGET_BSR) { - rtx tmp = gen_reg_rtx (SImode); - rtx r1 = gen_rtx (REG, SImode, 1); - emit_move_insn (tmp, gen_rtx (SYMBOL_REF, SImode, "__saveargs")); - emit_move_insn (r1, call_target); - emit_insn (gen_rtx (USE, VOIDmode, r1)); - call_target = tmp; + call = gen_rtx (CALL, VOIDmode, call_target, numargs); } + else { - call = gen_rtx (CALL, VOIDmode, gen_rtx (MEM, SImode, call_target), numargs); + if (GET_CODE (call_target) == MEM) + { + call_target = force_reg (Pmode, + XEXP (call_target, 0)); + } + if (TARGET_SMALLCALL) + { + rtx tmp = gen_reg_rtx (SImode); + rtx r1 = gen_rtx (REG, SImode, 1); + emit_move_insn (tmp, gen_rtx (SYMBOL_REF, SImode, "__saveargs")); + emit_move_insn (r1, call_target); + emit_insn (gen_rtx (USE, VOIDmode, r1)); + call_target = tmp; + } + call = gen_rtx (CALL, VOIDmode, gen_rtx (MEM, SImode, call_target), numargs); + } if (isa_retval) { call = gen_rtx (SET, VOIDmode, ret, call); @@ -2080,7 +2134,7 @@ expand_acall (isa_retval, operands) emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, call, - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 17))))); + gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 17))))); } @@ -2132,12 +2186,28 @@ general_movdst_operand (op, mode) enum machine_mode mode; { if (GET_CODE (op) == MEM - && GET_CODE (XEXP (op, 0)) == PRE_INC) + && (GET_CODE (XEXP (op, 0)) == PRE_INC + || GET_CODE (XEXP (op, 0)) == POST_INC + || GET_CODE (XEXP (op, 0)) == POST_DEC)) return 0; + return general_operand (op, mode); } + +/* Returns 1 if OP is valid destination for a bsr. */ + +int +bsr_operand (op, mode) +rtx op; +enum machine_mode mode; +{ + if (GET_CODE (op) == SYMBOL_REF) + return 1; + return 0; +} + /* Returns 1 if OP is an immediate ok for a byte index. */ int @@ -2247,3 +2317,88 @@ logical_operand (op, mode) return 0; } +/* Returns 1 if OP is a valid operand for a MAC instruction, + either a register or indirect memory. For now we don't + try and recognise a mac insn */ + +int +mac_operand (op, mode) + rtx op; + enum machine_mode mode; +{ + if (arith_reg_operand (op, mode)) + return 1; +#if 0 + Turned off till mac is understood + if (GET_CODE (op) == MEM) + return 1; +#endif + return 0; +} + +/* Determine where to put an argument to a function. + Value is zero to push the argument on the stack, + or a hard register in which to store the argument. + + MODE is the argument's machine mode. + TYPE is the data type of the argument (as a tree). + This is null for libcalls where that information may + not be available. + CUM is a variable of type CUMULATIVE_ARGS which gives info about + the preceding args and about the function being called. + NAMED is nonzero if this argument is a named parameter + (otherwise it is an extra parameter matching an ellipsis). */ + +rtx +sh_function_arg (cum, mode, type, named) +CUMULATIVE_ARGS cum; +enum machine_mode mode; +tree type; +int named; +{ + if (named) + { + int rr = (ROUND_REG ((cum), (mode))); + + if (rr < NPARM_REGS) + { + return ((((mode) != BLKmode + && ((type)==0 || ! TREE_ADDRESSABLE ((tree)(type))) + && ((type)==0 || (mode) != BLKmode + || (TYPE_ALIGN ((type)) % PARM_BOUNDARY == 0)) + ? gen_rtx (REG, (mode), + (FIRST_PARM_REG + rr)): 0))); + + } + } + return 0; +} + +/* For an arg passed partly in registers and partly in memory, + this is the number of registers used. + For args passed entirely in registers or entirely in memory, zero. + Any arg that starts in the first 4 regs but won't entirely fit in them + needs partial registers on the SH. */ + +int +sh_function_arg_partial_nregs (CUM, MODE, TYPE, NAMED) + CUMULATIVE_ARGS CUM; + enum machine_mode MODE; + tree TYPE; + int NAMED; +{ + if ((CUM) < NPARM_REGS) + { + if (((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE))) + && ((TYPE)==0 || (MODE) != BLKmode + || (TYPE_ALIGN ((TYPE)) % PARM_BOUNDARY == 0)) + && ((CUM) + ((MODE) == BLKmode + ? ROUND_ADVANCE (int_size_in_bytes (TYPE)) + : ROUND_ADVANCE (GET_MODE_SIZE (MODE))) - NPARM_REGS > 0)) + { + return NPARM_REGS - CUM; + } + } + return 0; +} + diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index 3b5953cd24b..23259cbfac7 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -78,6 +78,11 @@ extern int target_flags; #define CONSTLEN_2_BIT (1<<20) #define CONSTLEN_3_BIT (1<<21) #define HITACHI_BIT (1<<22) +#define PARANOID_BIT (1<<23) +#define RETR2_BIT (1<<24) +#define CONSTLEN_0_BIT (1<<25) +#define BSR_BIT (1<<26) +#define SHORTADDR_BIT (1<<27) /* Nonzero if we should generate code using type 0 insns */ #define TARGET_SH0 (target_flags & SH0_BIT) @@ -131,8 +136,16 @@ extern int target_flags; /* Select max size of computed constant code sequences to be 3 insns */ #define TARGET_CLEN3 (target_flags & CONSTLEN_3_BIT) +/* Select max size of computed constant code sequences to be 0 insns - ie don't do it */ +#define TARGET_CLEN0 (target_flags & CONSTLEN_0_BIT) + /* Nonzero if using Hitachi's calling convention */ -#define TARGET_HITACHI (target_flags & HITACHI_BIT) +#define TARGET_HITACHI (target_flags & HITACHI_BIT) +#define TARGET_PARANOID (target_flags & PARANOID_BIT) +#define TARGET_RETR2 (target_flags & RETR2_BIT) +#define TARGET_SHORTADDR (target_flags & SHORTADDR_BIT) +#define TARGET_BSR (target_flags & BSR_BIT) + #define TARGET_SWITCHES \ { {"isize", ( ISIZE_BIT) }, \ @@ -150,8 +163,13 @@ extern int target_flags; {"R", ( R_BIT) }, \ {"nosave", ( NOSAVE_BIT) }, \ {"clen3", ( CONSTLEN_3_BIT) }, \ + {"clen0", ( CONSTLEN_0_BIT) }, \ {"smallcall", ( SMALLCALL_BIT) }, \ {"hitachi", ( HITACHI_BIT) }, \ + {"paranoid", ( PARANOID_BIT) }, \ + {"r2", ( RETR2_BIT) }, \ + {"shortaddr", ( SHORTADDR_BIT) }, \ + {"bsr", ( BSR_BIT) }, \ {"", TARGET_DEFAULT} \ } @@ -177,7 +195,10 @@ do { \ \ optimize = 1; \ flag_delayed_branch = 1; \ - \ + /* But never run scheduling before reload, since than can \ + break global alloc, and generates slower code anyway due \ + to the pressure on R0. */ \ + flag_schedule_insns = 0; \ if (max_si) \ max_count_si = atoi (max_si); \ else \ @@ -186,6 +207,8 @@ do { \ max_count_hi = atoi (max_hi); \ else \ max_count_hi = 505; \ + if (TARGET_BSR) \ + flag_no_function_cse = 1; \ } while (0) @@ -296,7 +319,10 @@ do { \ #define FIRST_PSEUDO_REGISTER 22 /* 1 for registers that have pervasive standard uses - and are not available for the register allocator. */ + and are not available for the register allocator. + + mach register is fixed 'cause it's only 10 bits wide */ + /* r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 @@ -312,6 +338,7 @@ do { \ 1, 1, 1, 1, \ 1, 1} + /* 1 for registers not available across function calls. These must include the FIXED_REGISTERS and also any registers that can be used without being saved. @@ -591,7 +618,7 @@ extern enum reg_class reg_class_from_letter[]; These two macros are used only in other macro definitions below. */ #define NPARM_REGS 4 #define FIRST_PARM_REG 4 -#define FIRST_RET_REG 0 +#define FIRST_RET_REG (TARGET_RETR2 ? 2 : 0) /* Define this if pushing a word on the stack makes the stack pointer a smaller address. */ @@ -671,7 +698,8 @@ extern enum reg_class reg_class_from_letter[]; /* Round a register number up to a proper boundary for an arg of mode MODE. - We round to an even reg for things larger than a word */ + The SH doesn't care about double alignment, so we only + round doubles to even regs when asked to explicitly. */ #define ROUND_REG(X, MODE) \ ((TARGET_ALIGN_DOUBLE \ @@ -718,23 +746,20 @@ extern enum reg_class reg_class_from_letter[]; NPARM_REGS words is at least partially passed in a register unless its data type forbids. */ -#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ - (NAMED && ROUND_REG ((CUM), (MODE)) < NPARM_REGS \ - && (MODE) != BLKmode \ - && ((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE))) \ - && ((TYPE)==0 || (MODE) != BLKmode \ - || (TYPE_ALIGN ((TYPE)) % PARM_BOUNDARY == 0)) \ - ? gen_rtx (REG, (MODE), \ - (FIRST_PARM_REG + ROUND_REG ((CUM), (MODE)))) \ - : 0) + +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ + sh_function_arg (CUM, MODE, TYPE, NAMED) + +extern struct rtx_def *sh_function_arg(); /* For an arg passed partly in registers and partly in memory, this is the number of registers used. For args passed entirely in registers or entirely in memory, zero. - We never split args */ + We sometimes split args */ -#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0 +#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ + sh_function_arg_partial_nregs (CUM, MODE, TYPE, NAMED) extern int current_function_anonymous_args; @@ -809,10 +834,10 @@ extern int current_function_anonymous_args; /* Addressing modes, and classification of registers for them. */ -/*#define HAVE_POST_INCREMENT 1*/ +#define HAVE_POST_INCREMENT 1 /*#define HAVE_PRE_INCREMENT 1*/ /*#define HAVE_POST_DECREMENT 1*/ -/*#define HAVE_PRE_DECREMENT 1*/ +#define HAVE_PRE_DECREMENT 1 /* Macros to check register numbers against specific register classes. */ @@ -853,6 +878,7 @@ extern int current_function_anonymous_args; The symbol REG_OK_STRICT causes the latter definition to be used. */ #define MODE_DISP_OK_4(X,MODE) ((GET_MODE_SIZE(MODE)==4) && ((unsigned)INTVAL(X)<64)) +#define MODE_DISP_OK_8(X,MODE) ((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60)) #define MODE_DISP_OK_2(X,MODE) ((GET_MODE_SIZE(MODE)==2) && ((unsigned)INTVAL(X)<32) && TARGET_TRYR0) #define MODE_DISP_OK_1(X,MODE) ((GET_MODE_SIZE(MODE)==1) && ((unsigned)INTVAL(X)<16) && TARGET_TRYR0) @@ -870,7 +896,7 @@ extern int current_function_anonymous_args; (REGNO (X) == 0 || REGNO(X) >= FIRST_PSEUDO_REGISTER) #define REG_OK_FOR_PRE_POST_P(X) \ - (REGNO (X) <= 16) + (REG_OK_FOR_INDEX_P (X)) #else /* Nonzero if X is a hard reg that can be used as a base reg. */ @@ -882,7 +908,7 @@ extern int current_function_anonymous_args; REGNO_OK_FOR_INDEX_P (REGNO (X)) #define REG_OK_FOR_PRE_POST_P(X) \ - (REGNO (X) <= 16) + (REGNO_OK_FOR_INDEX_P (REGNO (X))) #endif /* The Q is a pc relative load operand */ @@ -943,6 +969,7 @@ extern int current_function_anonymous_args; if (GET_CODE (OP) == CONST_INT) \ { \ if (MODE_DISP_OK_4 (OP, MODE)) goto LABEL; \ + if (MODE_DISP_OK_8 (OP, MODE)) goto LABEL; \ if (MODE_DISP_OK_2 (OP, MODE)) goto LABEL; \ if (MODE_DISP_OK_1 (OP, MODE)) goto LABEL; \ } \ @@ -961,11 +988,11 @@ extern int current_function_anonymous_args; { \ rtx xop0 = XEXP(X,0); \ rtx xop1 = XEXP(X,1); \ - if (GET_MODE_SIZE(MODE) <= 4 && BASE_REGISTER_RTX_P (xop0)) \ + if (GET_MODE_SIZE(MODE) <= 8 && BASE_REGISTER_RTX_P (xop0)) \ GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL); \ - if (GET_MODE_SIZE(MODE) <= 4 && BASE_REGISTER_RTX_P (xop1)) \ + if (GET_MODE_SIZE(MODE) <= 8 && BASE_REGISTER_RTX_P (xop1)) \ GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL); \ - if (GET_MODE_SIZE(MODE)<=4) { \ + if (GET_MODE_SIZE(MODE)<= 4) { \ if(BASE_REGISTER_RTX_P(xop1) && \ INDEX_REGISTER_RTX_P(xop0)) goto LABEL; \ if(INDEX_REGISTER_RTX_P(xop1) && \ @@ -992,9 +1019,9 @@ extern int current_function_anonymous_args; It is always safe for this macro to do nothing. It exists to recognize opportunities to optimize the output. - On the SH we don't try anything */ + */ -#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) ; +#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) ; /* Go to LABEL if ADDR (a legitimate address expression) has an effect that depends on the machine mode it is used for. */ @@ -1102,7 +1129,6 @@ extern int current_function_anonymous_args; return COSTS_N_INSNS (multcosts (X)); \ case ASHIFT: \ case ASHIFTRT: \ - case LSHIFTRT: \ return COSTS_N_INSNS (shiftcosts (X)) ; \ case DIV: \ case UDIV: \ @@ -1174,13 +1200,6 @@ extern int current_function_anonymous_args; #define CTORS_SECTION_ASM_OP "\t.section\t.ctors\n" #define DTORS_SECTION_ASM_OP "\t.section\t.dtors\n" #define INIT_SECTION_ASM_OP "\t.section\t.init\n" - -/* Assemble generic sections. - This is currently only used to support section attributes. */ - -#define ASM_OUTPUT_SECTION_NAME(FILE, NAME) \ - fprintf (FILE, ".section\t%s\n", NAME) - #define EXTRA_SECTIONS in_ctors, in_dtors #define EXTRA_SECTION_FUNCTIONS \ @@ -1203,6 +1222,12 @@ dtors_section() \ } \ } +/* Assemble generic sections. + This is currently only used to support section attributes. */ + +#define ASM_OUTPUT_SECTION_NAME(FILE, NAME) \ + do { fprintf (FILE, ".section\t%s\n", NAME); } while (0) + #define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ do { ctors_section(); fprintf(FILE,"\t.long\t_%s\n", NAME); } while (0) @@ -1410,7 +1435,7 @@ do { char dstr[30]; \ #define PRINT_OPERAND_ADDRESS(STREAM,X) print_operand_address (STREAM, X) #define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \ - ((CHAR)=='.' || (CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR)=='!') + ((CHAR)=='.' || (CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR)=='!' || (CHAR)=='@') extern struct rtx_def *sh_compare_op0; @@ -1418,6 +1443,7 @@ extern struct rtx_def *sh_compare_op1; extern struct rtx_def *prepare_scc_operands(); extern struct rtx_def *table_lab; + extern enum attr_cpu sh_cpu; /* target cpu */ /* Declare functions defined in sh.c and used in templates. */ @@ -1441,7 +1467,7 @@ extern char *output_far_jump(); /* Set when processing a function with pragma interrupt turned on. */ extern int pragma_interrupt; -#define MOVE_RATIO 16 +#define MOVE_RATIO (TARGET_SMALLCODE ? 4 : 16) char *max_si; char *max_hi;