*** empty log message ***

From-SVN: r7101
This commit is contained in:
Steve Chamberlain 1994-04-20 19:17:23 +00:00
parent 6fcc9690b3
commit d3ae8277eb
2 changed files with 308 additions and 127 deletions

View File

@ -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)
if (TARGET_BSR)
{
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, 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;
}

View File

@ -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;