Commit 8e87e161 by Steve Chamberlain

*** empty log message ***

From-SVN: r7790
parent b1cf6cee
...@@ -65,12 +65,12 @@ rtx sh_compare_op1; ...@@ -65,12 +65,12 @@ rtx sh_compare_op1;
int regno_reg_class[FIRST_PSEUDO_REGISTER] = int regno_reg_class[FIRST_PSEUDO_REGISTER] =
{ {
R0_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, R0_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
GENERAL_REGS, PR_REGS, T_REGS, NO_REGS, GENERAL_REGS, PR_REGS, T_REGS, NO_REGS,
MAC_REGS, MAC_REGS, MAC_REGS, MAC_REGS,
}; };
/* Provide reg_class from a letter such as appears in the machine /* Provide reg_class from a letter such as appears in the machine
...@@ -104,12 +104,12 @@ enum reg_class reg_class_from_letter[] = ...@@ -104,12 +104,12 @@ enum reg_class reg_class_from_letter[] =
int hard_regno_mode_ok[] = int hard_regno_mode_ok[] =
{ {
REG_EVEN, REG_ODD, REG_EVEN, REG_ODD, REG_EVEN, REG_ODD, REG_EVEN, REG_ODD,
REG_EVEN, REG_ODD, REG_EVEN, REG_ODD, REG_EVEN, REG_ODD, REG_EVEN, REG_ODD,
REG_EVEN, REG_ODD, REG_EVEN, REG_ODD, REG_EVEN, REG_ODD, REG_EVEN, REG_ODD,
REG_EVEN, REG_ODD, REG_EVEN, REG_ODD, REG_EVEN, REG_ODD, REG_EVEN, REG_ODD,
REG, 0, SI_ONLY, SI_ONLY, REG, 0, SI_ONLY, SI_ONLY,
SI_ONLY, SI_ONLY SI_ONLY, SI_ONLY
}; };
/* Local label counter, used for constants in the pool and inside /* Local label counter, used for constants in the pool and inside
...@@ -120,9 +120,9 @@ static int lf = 100; ...@@ -120,9 +120,9 @@ static int lf = 100;
/* Number of bytes pushed for anonymous args, used to pass information /* Number of bytes pushed for anonymous args, used to pass information
between expand_prologue and expand_epilogue. */ between expand_prologue and expand_epilogue. */
static int extra_push; static int extra_push;
void void
push (rn) push (rn)
int rn; int rn;
...@@ -132,6 +132,7 @@ push (rn) ...@@ -132,6 +132,7 @@ push (rn)
void void
pop (rn) pop (rn)
int rn;
{ {
emit_insn (gen_pop (gen_rtx (REG, SImode, rn))); emit_insn (gen_pop (gen_rtx (REG, SImode, rn)));
} }
...@@ -299,7 +300,6 @@ print_operand_address (stream, x) ...@@ -299,7 +300,6 @@ print_operand_address (stream, x)
default: default:
debug_rtx (x); debug_rtx (x);
abort (); abort ();
} }
} }
...@@ -354,9 +354,9 @@ print_operand (stream, x, code) ...@@ -354,9 +354,9 @@ print_operand (stream, x, code)
break; break;
case '@': case '@':
if (pragma_interrupt) if (pragma_interrupt)
fprintf (stream,"rte"); fprintf (stream, "rte");
else else
fprintf (stream,"rts"); fprintf (stream, "rts");
break; break;
case '#': case '#':
/* Output a nop if there's nothing in the delay slot */ /* Output a nop if there's nothing in the delay slot */
...@@ -405,7 +405,9 @@ print_operand (stream, x, code) ...@@ -405,7 +405,9 @@ print_operand (stream, x, code)
} }
static int
sextb (x) sextb (x)
int x;
{ {
x &= 0xff; x &= 0xff;
if (x > 127) if (x > 127)
...@@ -420,7 +422,7 @@ sextb (x) ...@@ -420,7 +422,7 @@ sextb (x)
/* Take a move with integer constant source in OPERANDS, see if it can be generated by /* Take a move with integer constant source in OPERANDS, see if it can be generated by
devious shifting. If so, generate the instruction sequence and return 1, otherwise devious shifting. If so, generate the instruction sequence and return 1, otherwise
return 0. return 0.
OPERANDS[0] Destination register OPERANDS[0] Destination register
OPERANDS[1] Source constant OPERANDS[1] Source constant
...@@ -442,7 +444,7 @@ sextb (x) ...@@ -442,7 +444,7 @@ sextb (x)
00000000 00000000 11111111 1NNNNNNNN load and zero extend word 00000000 00000000 11111111 1NNNNNNNN load and zero extend word
*/ */
static int static int
synth_constant (operands, mode) synth_constant (operands, mode)
...@@ -452,7 +454,7 @@ synth_constant (operands, mode) ...@@ -452,7 +454,7 @@ synth_constant (operands, mode)
rtx dst; rtx dst;
int i = INTVAL (operands[1]) & 0xffffffff; int i = INTVAL (operands[1]) & 0xffffffff;
if (CONST_OK_FOR_I (i)) if (CONST_OK_FOR_I (i))
return 0; return 0;
if (TARGET_CLEN0 && mode != QImode) if (TARGET_CLEN0 && mode != QImode)
...@@ -460,11 +462,11 @@ synth_constant (operands, mode) ...@@ -460,11 +462,11 @@ synth_constant (operands, mode)
if (mode != SImode) if (mode != SImode)
{ {
if (reload_in_progress) if (reload_in_progress)
return 0; return 0;
dst = gen_reg_rtx (SImode); dst = gen_reg_rtx (SImode);
} }
else else
{ {
dst = operands[0]; dst = operands[0];
} }
...@@ -592,10 +594,8 @@ expand_block_move (operands) ...@@ -592,10 +594,8 @@ expand_block_move (operands)
} }
if (mode == SImode && constp && (bytes % 4 == 0)) if (mode == SImode && constp && (bytes % 4 == 0))
{ {
char entry[30];
tree entry_name; tree entry_name;
rtx func_addr_rtx; rtx func_addr_rtx;
int groups;
rtx r4 = gen_rtx (REG, SImode, 4); rtx r4 = gen_rtx (REG, SImode, 4);
rtx r5 = gen_rtx (REG, SImode, 5); rtx r5 = gen_rtx (REG, SImode, 5);
rtx r6 = gen_rtx (REG, SImode, 6); rtx r6 = gen_rtx (REG, SImode, 6);
...@@ -670,7 +670,7 @@ prepare_move_operands (operands, mode) ...@@ -670,7 +670,7 @@ prepare_move_operands (operands, mode)
/* copy the source to a register */ /* copy the source to a register */
operands[1] = copy_to_mode_reg (mode, operands[1]); operands[1] = copy_to_mode_reg (mode, operands[1]);
} }
if ((mode == DImode || mode == SImode || mode == HImode || mode == QImode) if ((mode == DImode || mode == SImode || mode == HImode || mode == QImode)
&& GET_CODE (operands[1]) == CONST_INT) && GET_CODE (operands[1]) == CONST_INT)
{ {
return synth_constant (operands, mode); return synth_constant (operands, mode);
...@@ -740,6 +740,7 @@ prepare_move_operands (operands, mode) ...@@ -740,6 +740,7 @@ prepare_move_operands (operands, mode)
compare has been done. */ compare has been done. */
rtx rtx
prepare_scc_operands (code) prepare_scc_operands (code)
int code;
{ {
if (GET_CODE (sh_compare_op0) != REG if (GET_CODE (sh_compare_op0) != REG
|| REGNO (sh_compare_op0) != T_REG) || REGNO (sh_compare_op0) != T_REG)
...@@ -863,6 +864,10 @@ output_movedouble (insn, operands, mode) ...@@ -863,6 +864,10 @@ output_movedouble (insn, operands, mode)
{ {
return "mov.l %1,%0\n\tmov.l %1+4,%R0"; return "mov.l %1,%0\n\tmov.l %1+4,%R0";
} }
else if (GET_CODE (inside) == POST_INC)
{
return "mov.l %1,%0\n\tmov.l %1,%R0 !mdi\n";
}
else else
abort (); abort ();
...@@ -1022,11 +1027,6 @@ output_far_jump (insn, op) ...@@ -1022,11 +1027,6 @@ output_far_jump (insn, op)
{ {
rtx thislab = gen_label_rtx (); rtx thislab = gen_label_rtx ();
/* See if we can grab a reg from the prev insn */
rtx gotone = 0;
rtx prev = PREV_INSN (insn);
rtx link;
if (dbr_sequence_length ()) if (dbr_sequence_length ())
{ {
/* Something to go in what would have been the delay /* Something to go in what would have been the delay
...@@ -1041,7 +1041,8 @@ output_far_jump (insn, op) ...@@ -1041,7 +1041,8 @@ output_far_jump (insn, op)
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
vec[1] = gen_rtx (REG, SImode, i); vec[1] = gen_rtx (REG, SImode, i);
if (!reg_referenced_p (vec[1], PATTERN (XVECEXP (final_sequence, 0, 1)))) if (!reg_referenced_p (vec[1],
PATTERN (XVECEXP (final_sequence, 0, 1))))
break; break;
} }
...@@ -1072,9 +1073,8 @@ output_branch (logic, insn) ...@@ -1072,9 +1073,8 @@ output_branch (logic, insn)
{ {
extern rtx recog_operand[]; extern rtx recog_operand[];
int label = lf++; 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)) switch (get_attr_length (insn))
{ {
...@@ -1245,7 +1245,7 @@ add_constant (x, mode) ...@@ -1245,7 +1245,7 @@ add_constant (x, mode)
/* Dump out interesting debug info */ /* Dump out interesting debug info */
rtx void
final_prescan_insn (insn, opvec, noperands) final_prescan_insn (insn, opvec, noperands)
rtx insn; rtx insn;
rtx *opvec; rtx *opvec;
...@@ -1258,9 +1258,9 @@ final_prescan_insn (insn, opvec, noperands) ...@@ -1258,9 +1258,9 @@ final_prescan_insn (insn, opvec, noperands)
insn_addresses[INSN_UID (insn)]); insn_addresses[INSN_UID (insn)]);
} }
} }
/* Stuff taken from m88k.c */ /* Stuff taken from m88k.c */
...@@ -1365,7 +1365,7 @@ output_file_start (file, f_options, f_len, W_options, W_len) ...@@ -1365,7 +1365,7 @@ output_file_start (file, f_options, f_len, W_options, W_len)
data_section (); data_section ();
pos = fprintf (file, "\n! Hitachi SH cc1 (%s) (release D-1) arguments:", version_string); pos = fprintf (file, "\n! Hitachi SH cc1 (%s) (release E-2) arguments:", version_string);
output_options (file, f_options, f_len, W_options, W_len, output_options (file, f_options, f_len, W_options, W_len,
pos, 75, " ", "\n! ", "\n\n"); pos, 75, " ", "\n! ", "\n\n");
} }
...@@ -1393,7 +1393,7 @@ shiftcosts (RTX) ...@@ -1393,7 +1393,7 @@ shiftcosts (RTX)
return 1; return 1;
} }
int int
andcosts (RTX) andcosts (RTX)
rtx RTX; rtx RTX;
{ {
...@@ -1410,28 +1410,33 @@ andcosts (RTX) ...@@ -1410,28 +1410,33 @@ andcosts (RTX)
return 5; return 5;
} }
int howshift (i) int
int i; howshift (i)
int i;
{ {
int total = 0; int total = 0;
while (i > 0) while (i > 0)
{ {
if (i >= 16) { if (i >= 16)
total++; {
i -= 16; total++;
} i -= 16;
else if (i >= 8) { }
total++; else if (i >= 8)
i -= 8; {
} total++;
else if (i >= 2) { i -= 8;
total++; }
i -= 2; else if (i >= 2)
} {
else if (i>=1) { total++;
total++; i -= 2;
i--; }
} else if (i >= 1)
{
total++;
i--;
}
} }
return total; return total;
} }
...@@ -1442,14 +1447,14 @@ multcosts (RTX) ...@@ -1442,14 +1447,14 @@ multcosts (RTX)
rtx RTX; rtx RTX;
{ {
/* If mult by a power of 2 then work out how we'd shift to make it */ /* If mult by a power of 2 then work out how we'd shift to make it */
int insn_cost; int insn_cost = 0;
if (GET_CODE (XEXP (RTX, 1)) == CONST_INT) if (GET_CODE (XEXP (RTX, 1)) == CONST_INT)
{ {
int i = exact_log2 (INTVAL (XEXP (RTX, 1))); int i = exact_log2 (INTVAL (XEXP (RTX, 1)));
if (i >= 0) if (i >= 0)
insn_cost = howshift (i); insn_cost = howshift (i);
else else
insn_cost = 100000; insn_cost = 100000;
} }
if (TARGET_SH2) if (TARGET_SH2)
...@@ -1458,7 +1463,7 @@ multcosts (RTX) ...@@ -1458,7 +1463,7 @@ multcosts (RTX)
read of the mac reg, but count more because of the latency and extra reg read of the mac reg, but count more because of the latency and extra reg
usage */ usage */
if (TARGET_SMALLCODE) if (TARGET_SMALLCODE)
return 2; return 2;
if (insn_cost > 5) if (insn_cost > 5)
return 5; return 5;
return insn_cost; return insn_cost;
...@@ -1467,7 +1472,7 @@ multcosts (RTX) ...@@ -1467,7 +1472,7 @@ multcosts (RTX)
/* If we we're aiming at small code, then just count the number of /* If we we're aiming at small code, then just count the number of
insns in a multiply call sequence */ insns in a multiply call sequence */
if (TARGET_SMALLCODE) if (TARGET_SMALLCODE)
{ {
if (insn_cost > 6) if (insn_cost > 6)
return 6; return 6;
...@@ -1627,7 +1632,6 @@ dump_table (scan) ...@@ -1627,7 +1632,6 @@ dump_table (scan)
rtx scan; rtx scan;
{ {
int i; int i;
int pass;
int need_align = 1; int need_align = 1;
...@@ -1706,6 +1710,10 @@ fixit (src, mode) ...@@ -1706,6 +1710,10 @@ fixit (src, mode)
{ {
return 1; return 1;
} }
if (GET_CODE (src) == LABEL_REF)
{
return 1;
}
if (GET_CODE (src) == CONST_INT) if (GET_CODE (src) == CONST_INT)
{ {
/* All QI insns are ok */ /* All QI insns are ok */
...@@ -1740,17 +1748,18 @@ hi_const (src) ...@@ -1740,17 +1748,18 @@ hi_const (src)
/* Find the last barrier less than MAX_COUNT bytes from FROM, or create one. /* Find the last barrier less than MAX_COUNT bytes from FROM, or create one.
If an HI move is found, then make sure that MAX_COUNT_HI isn't broken from that one. */ If an HI move is found, then make sure that MAX_COUNT_HI isn't broken from that one. */
static rtx from;
static static
rtx rtx
find_barrier (from) find_barrier (from_)
rtx from; rtx from_;
{ {
int count_si = 0; int count_si = 0;
int count_hi = 0; int count_hi = 0;
int found_hi = 0; int found_hi = 0;
int found_si = 0; int found_si = 0;
rtx found_barrier = 0; rtx found_barrier = 0;
from = from_;
while (from while (from
&& count_si < max_count_si && count_si < max_count_si
&& count_hi < max_count_hi) && count_hi < max_count_hi)
...@@ -1786,11 +1795,14 @@ find_barrier (from) ...@@ -1786,11 +1795,14 @@ find_barrier (from)
if (!found_barrier) if (!found_barrier)
{ {
/* Insert a jump around the barrier here */ /* We didn't find a barrier in time to
dump our stuff, so we'll make one */
rtx label = gen_label_rtx (); rtx label = gen_label_rtx ();
/* Walk back to be just before any jump */ /* Walk back to be just before any jump */
from = PREV_INSN (from);
while (GET_CODE (from) == JUMP_INSN while (GET_CODE (from) == JUMP_INSN
|| GET_CODE (from) == NOTE) || GET_CODE (from) == NOTE
|| GET_CODE (from) == CODE_LABEL)
{ {
from = PREV_INSN (from); from = PREV_INSN (from);
} }
...@@ -1836,7 +1848,6 @@ machine_dependent_reorg (first) ...@@ -1836,7 +1848,6 @@ machine_dependent_reorg (first)
rtx first; rtx first;
{ {
rtx insn; rtx insn;
int limit;
for (insn = first; insn; insn = NEXT_INSN (insn)) for (insn = first; insn; insn = NEXT_INSN (insn))
{ {
if (broken_move (insn)) if (broken_move (insn))
...@@ -1895,7 +1906,7 @@ machine_dependent_reorg (first) ...@@ -1895,7 +1906,7 @@ machine_dependent_reorg (first)
/* Called from the md file, set up the operands of a compare instruction */ /* Called from the md file, set up the operands of a compare instruction */
int void
from_compare (operands, code) from_compare (operands, code)
rtx *operands; rtx *operands;
int code; int code;
...@@ -1905,7 +1916,7 @@ from_compare (operands, code) ...@@ -1905,7 +1916,7 @@ from_compare (operands, code)
/* Force args into regs, since we can't use constants here */ /* Force args into regs, since we can't use constants here */
sh_compare_op0 = force_reg (SImode, sh_compare_op0); sh_compare_op0 = force_reg (SImode, sh_compare_op0);
if (sh_compare_op1 != const0_rtx) if (sh_compare_op1 != const0_rtx)
sh_compare_op1 = force_reg (SImode, sh_compare_op1); sh_compare_op1 = force_reg (SImode, sh_compare_op1);
} }
operands[1] = sh_compare_op0; operands[1] = sh_compare_op0;
operands[2] = sh_compare_op1; operands[2] = sh_compare_op1;
...@@ -1923,33 +1934,67 @@ equality_operator (x, mode) ...@@ -1923,33 +1934,67 @@ equality_operator (x, mode)
} }
/* Framefull frame looks like: /* Add this function to the list of ones seen - temporary
gross hack to try out bsrs. */
arg-5 struct flist
arg-4 {
[ if current_function_anonymous_args char *name;
arg-3 struct flist *next;
arg-2 };
arg-1 struct flist *head;
arg-0 ]
saved-fp
saved-r10
saved-r11
saved-r12
saved-pr
local-n
..
local-1
local-0 <- fp points here
static void
add_function (name)
char *name;
{
struct flist *n = (struct flist *) xmalloc (sizeof (struct flist));
int l = strlen (name) + 1;
n->name = xmalloc (l);
memcpy (n->name, name, l);
n->next = head;
head = n;
}
If TARGET_SMALLCALL, then the preserved registers are pushed by a static int
wrapper before the routine is entered, so the regs are always pushed seen_function (name)
and there are two pr's on the stack - the caller and the wrapper. char *name;
*/ {
struct flist *p = head;
for (p = head; p; p = p->next)
{
if (strcmp (p->name, name) == 0)
return 1;
}
return 0;
}
/* Framefull frame looks like:
arg-5
arg-4
[ if current_function_anonymous_args
arg-3
arg-2
arg-1
arg-0 ]
saved-fp
saved-r10
saved-r11
saved-r12
saved-pr
local-n
..
local-1
local-0 <- fp points here
/* Code to generate prologue and epilogue sequences */ If TARGET_SMALLCALL, then the preserved registers are pushed by a
wrapper before the routine is entered, so the regs are always pushed
and there are two pr's on the stack - the caller and the wrapper.
*/
/* Code to generate prologue and epilogue sequences */
void void
...@@ -1957,7 +2002,7 @@ sh_expand_prologue () ...@@ -1957,7 +2002,7 @@ sh_expand_prologue ()
{ {
int live_regs_mask; int live_regs_mask;
int d; int d;
extern tree current_function_decl;
live_regs_mask = calc_live_regs (&d); live_regs_mask = calc_live_regs (&d);
/* We have pretend args if we had an object sent partially in registers /* We have pretend args if we had an object sent partially in registers
...@@ -1984,6 +2029,12 @@ sh_expand_prologue () ...@@ -1984,6 +2029,12 @@ sh_expand_prologue ()
{ {
emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx)); emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
} }
if (TARGET_BSR)
{
add_function (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
}
} }
void void
...@@ -2027,11 +2078,14 @@ sh_expand_epilogue () ...@@ -2027,11 +2078,14 @@ sh_expand_epilogue ()
int int
initial_elimination_offset (from, to) initial_elimination_offset (from, to)
int from;
int to;
{ {
int regs_saved; int regs_saved;
int regs_saved_mask = calc_live_regs (&regs_saved);
int total_saved_regs_space; int total_saved_regs_space;
int total_auto_space = get_frame_size (); int total_auto_space = get_frame_size ();
calc_live_regs (&regs_saved);
total_saved_regs_space = (regs_saved) * 4; total_saved_regs_space = (regs_saved) * 4;
if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM) if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
...@@ -2074,12 +2128,12 @@ handle_pragma (file) ...@@ -2074,12 +2128,12 @@ handle_pragma (file)
if (psize == 9 && strncmp (pbuf, "interrupt", 9) == 0) if (psize == 9 && strncmp (pbuf, "interrupt", 9) == 0)
{ {
pragma_interrupt = 1; pragma_interrupt = 1;
return; return c;
} }
if (psize == 5 && strncmp (pbuf, "trapa", 5) == 0) if (psize == 5 && strncmp (pbuf, "trapa", 5) == 0)
{ {
pragma_interrupt = pragma_trapa = 1; pragma_interrupt = pragma_trapa = 1;
return; return c;
} }
c = getc (file); c = getc (file);
} }
...@@ -2088,7 +2142,7 @@ handle_pragma (file) ...@@ -2088,7 +2142,7 @@ handle_pragma (file)
/* insn expand helpers */ /* insn expand helpers */
/* Emit insns to perform a call. /* Emit insns to perform a call.
If TARGET_SHORTADDR then use a bsr. If TARGET_SMALLCALL, then load the If TARGET_SHORTADDR then use a bsr. If TARGET_SMALLCALL, then load the
target address into r1 and call __saveargs, otherwise target address into r1 and call __saveargs, otherwise
perform the standard call sequence */ perform the standard call sequence */
...@@ -2103,29 +2157,29 @@ expand_acall (isa_retval, operands) ...@@ -2103,29 +2157,29 @@ expand_acall (isa_retval, operands)
rtx call_target = operands[isa_retval + 0]; rtx call_target = operands[isa_retval + 0];
rtx numargs = operands[isa_retval + 1]; rtx numargs = operands[isa_retval + 1];
if (TARGET_BSR) if (TARGET_BSR && bsr_operand (call_target, VOIDmode))
{ {
call = gen_rtx (CALL, VOIDmode, call_target, numargs); call = gen_rtx (CALL, VOIDmode, call_target, numargs);
} }
else { else
{
if (GET_CODE (call_target) == MEM) if (GET_CODE (call_target) == MEM)
{ {
call_target = force_reg (Pmode, call_target = force_reg (Pmode,
XEXP (call_target, 0)); XEXP (call_target, 0));
} }
if (TARGET_SMALLCALL) if (TARGET_SMALLCALL)
{ {
rtx tmp = gen_reg_rtx (SImode); rtx tmp = gen_reg_rtx (SImode);
rtx r1 = gen_rtx (REG, SImode, 1); rtx r1 = gen_rtx (REG, SImode, 1);
emit_move_insn (tmp, gen_rtx (SYMBOL_REF, SImode, "__saveargs")); emit_move_insn (tmp, gen_rtx (SYMBOL_REF, SImode, "__saveargs"));
emit_move_insn (r1, call_target); emit_move_insn (r1, call_target);
emit_insn (gen_rtx (USE, VOIDmode, r1)); emit_insn (gen_rtx (USE, VOIDmode, r1));
call_target = tmp; call_target = tmp;
} }
call = gen_rtx (CALL, VOIDmode, gen_rtx (MEM, SImode, call_target), numargs); call = gen_rtx (CALL, VOIDmode, gen_rtx (MEM, SImode, call_target), numargs);
} }
if (isa_retval) if (isa_retval)
{ {
call = gen_rtx (SET, VOIDmode, ret, call); call = gen_rtx (SET, VOIDmode, ret, call);
...@@ -2134,7 +2188,7 @@ expand_acall (isa_retval, operands) ...@@ -2134,7 +2188,7 @@ expand_acall (isa_retval, operands)
emit_call_insn (gen_rtx (PARALLEL, VOIDmode, emit_call_insn (gen_rtx (PARALLEL, VOIDmode,
gen_rtvec (2, gen_rtvec (2,
call, call,
gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 17))))); gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 17)))));
} }
...@@ -2156,10 +2210,18 @@ general_movsrc_operand (op, mode) ...@@ -2156,10 +2210,18 @@ general_movsrc_operand (op, mode)
GET_CODE (XEXP (op, 0)) == LABEL_REF) GET_CODE (XEXP (op, 0)) == LABEL_REF)
return 1; return 1;
/* No predec allowed */ /* No post inc allowed */
if (GET_CODE (op) == MEM if (GET_CODE (op) == MEM
&& GET_CODE (XEXP (op, 0)) == PRE_DEC) && (GET_CODE (XEXP (op, 0)) == POST_DEC
|| GET_CODE (XEXP (op, 0)) == PRE_INC
|| GET_CODE (XEXP (op, 0)) == PRE_DEC))
return 0;
/* Can't do that with large modes */
if (GET_CODE (op) == MEM
&& GET_CODE (XEXP (op, 0)) == POST_INC
&& GET_MODE_SIZE (mode) > 4)
return 0; return 0;
if ((mode == QImode || mode == HImode) if ((mode == QImode || mode == HImode)
...@@ -2185,12 +2247,18 @@ general_movdst_operand (op, mode) ...@@ -2185,12 +2247,18 @@ general_movdst_operand (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
/* No pre dec allowed */
if (GET_CODE (op) == MEM 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_INC
|| GET_CODE (XEXP (op, 0)) == POST_DEC)) || GET_CODE (XEXP (op, 0)) == POST_DEC))
return 0; return 0;
if (GET_CODE (op) == MEM
&& GET_CODE (XEXP (op, 0)) == PRE_DEC
&& GET_MODE_SIZE (mode) > 4)
return 0;
return general_operand (op, mode); return general_operand (op, mode);
} }
...@@ -2200,11 +2268,19 @@ general_movdst_operand (op, mode) ...@@ -2200,11 +2268,19 @@ general_movdst_operand (op, mode)
int int
bsr_operand (op, mode) bsr_operand (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
if (GET_CODE (op) == SYMBOL_REF) if (TARGET_BSR)
return 1; {
if (GET_CODE (op) == SYMBOL_REF)
{
if (!strcmp (XSTR (op, 0),
IDENTIFIER_POINTER (DECL_NAME (current_function_decl))))
return 1;
return (seen_function (XSTR (op, 0)));
}
}
return 0; return 0;
} }
...@@ -2329,7 +2405,7 @@ mac_operand (op, mode) ...@@ -2329,7 +2405,7 @@ mac_operand (op, mode)
if (arith_reg_operand (op, mode)) if (arith_reg_operand (op, mode))
return 1; return 1;
#if 0 #if 0
Turned off till mac is understood Turned off till mac is understood
if (GET_CODE (op) == MEM) if (GET_CODE (op) == MEM)
return 1; return 1;
#endif #endif
...@@ -2349,27 +2425,27 @@ mac_operand (op, mode) ...@@ -2349,27 +2425,27 @@ mac_operand (op, mode)
NAMED is nonzero if this argument is a named parameter NAMED is nonzero if this argument is a named parameter
(otherwise it is an extra parameter matching an ellipsis). */ (otherwise it is an extra parameter matching an ellipsis). */
rtx rtx
sh_function_arg (cum, mode, type, named) sh_function_arg (cum, mode, type, named)
CUMULATIVE_ARGS cum; CUMULATIVE_ARGS cum;
enum machine_mode mode; enum machine_mode mode;
tree type; tree type;
int named; int named;
{ {
if (named) if (named)
{ {
int rr = (ROUND_REG ((cum), (mode))); int rr = (ROUND_REG ((cum), (mode)));
if (rr < NPARM_REGS) if (rr < NPARM_REGS)
{ {
return ((((mode) != BLKmode return ((((mode) != BLKmode
&& ((type)==0 || ! TREE_ADDRESSABLE ((tree)(type))) && ((type) == 0 || !TREE_ADDRESSABLE ((tree) (type)))
&& ((type)==0 || (mode) != BLKmode && ((type) == 0 || (mode) != BLKmode
|| (TYPE_ALIGN ((type)) % PARM_BOUNDARY == 0)) || (TYPE_ALIGN ((type)) % PARM_BOUNDARY == 0))
? gen_rtx (REG, (mode), ? gen_rtx (REG, (mode),
(FIRST_PARM_REG + rr)): 0))); (FIRST_PARM_REG + rr)) : 0)));
} }
} }
return 0; return 0;
} }
...@@ -2387,18 +2463,17 @@ sh_function_arg_partial_nregs (CUM, MODE, TYPE, NAMED) ...@@ -2387,18 +2463,17 @@ sh_function_arg_partial_nregs (CUM, MODE, TYPE, NAMED)
tree TYPE; tree TYPE;
int NAMED; int NAMED;
{ {
if ((CUM) < NPARM_REGS) if ((CUM) < NPARM_REGS)
{ {
if (((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE))) if (((TYPE) == 0 || !TREE_ADDRESSABLE ((tree) (TYPE)))
&& ((TYPE)==0 || (MODE) != BLKmode && ((TYPE) == 0 || (MODE) != BLKmode
|| (TYPE_ALIGN ((TYPE)) % PARM_BOUNDARY == 0)) || (TYPE_ALIGN ((TYPE)) % PARM_BOUNDARY == 0))
&& ((CUM) + ((MODE) == BLKmode && ((CUM) + ((MODE) == BLKmode
? ROUND_ADVANCE (int_size_in_bytes (TYPE)) ? ROUND_ADVANCE (int_size_in_bytes (TYPE))
: ROUND_ADVANCE (GET_MODE_SIZE (MODE))) - NPARM_REGS > 0)) : ROUND_ADVANCE (GET_MODE_SIZE (MODE))) - NPARM_REGS > 0))
{ {
return NPARM_REGS - CUM; return NPARM_REGS - CUM;
} }
} }
return 0; return 0;
} }
/* Definitions of target machine for GNU compiler, for Hitachi Super-H. /* Definitions of target machine for GNU compiler,
for Hitachi Super-H.
Copyright (C) 1993, 1994 Free Software Foundation, Inc. Copyright (C) 1993, 1994 Free Software Foundation, Inc.
Contributed by Steve Chamberlain (sac@cygnus.com) Contributed by Steve Chamberlain (sac@cygnus.com)
...@@ -83,6 +84,7 @@ extern int target_flags; ...@@ -83,6 +84,7 @@ extern int target_flags;
#define CONSTLEN_0_BIT (1<<25) #define CONSTLEN_0_BIT (1<<25)
#define BSR_BIT (1<<26) #define BSR_BIT (1<<26)
#define SHORTADDR_BIT (1<<27) #define SHORTADDR_BIT (1<<27)
#define PACKSTRUCT_BIT (1<<28)
/* Nonzero if we should generate code using type 0 insns */ /* Nonzero if we should generate code using type 0 insns */
#define TARGET_SH0 (target_flags & SH0_BIT) #define TARGET_SH0 (target_flags & SH0_BIT)
...@@ -141,11 +143,14 @@ extern int target_flags; ...@@ -141,11 +143,14 @@ extern int target_flags;
/* Nonzero if using Hitachi's calling convention */ /* 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_PARANOID (target_flags & PARANOID_BIT)
#define TARGET_RETR2 (target_flags & RETR2_BIT) #define TARGET_RETR2 (target_flags & RETR2_BIT)
#define TARGET_SHORTADDR (target_flags & SHORTADDR_BIT) #define TARGET_SHORTADDR (target_flags & SHORTADDR_BIT)
#define TARGET_BSR (target_flags & BSR_BIT) #define TARGET_BSR (target_flags & BSR_BIT)
/* Nonzero if packing structures as small as they'll go (incompatible with Hitachi's compiler) */
#define TARGET_PACKSTRUCT (target_flags & PACKSTRUCT_BIT)
#define TARGET_SWITCHES \ #define TARGET_SWITCHES \
{ {"isize", ( ISIZE_BIT) }, \ { {"isize", ( ISIZE_BIT) }, \
...@@ -170,10 +175,11 @@ extern int target_flags; ...@@ -170,10 +175,11 @@ extern int target_flags;
{"r2", ( RETR2_BIT) }, \ {"r2", ( RETR2_BIT) }, \
{"shortaddr", ( SHORTADDR_BIT) }, \ {"shortaddr", ( SHORTADDR_BIT) }, \
{"bsr", ( BSR_BIT) }, \ {"bsr", ( BSR_BIT) }, \
{"packstruct",( PACKSTRUCT_BIT) }, \
{"", TARGET_DEFAULT} \ {"", TARGET_DEFAULT} \
} }
#define TARGET_DEFAULT (FAST_BIT) #define TARGET_DEFAULT (FAST_BIT | BIGTABLE_BIT)
/* Macro to define table for command options with values. */ /* Macro to define table for command options with values. */
#define TARGET_OPTIONS \ #define TARGET_OPTIONS \
...@@ -206,7 +212,7 @@ do { \ ...@@ -206,7 +212,7 @@ do { \
if (max_hi) \ if (max_hi) \
max_count_hi = atoi (max_hi); \ max_count_hi = atoi (max_hi); \
else \ else \
max_count_hi = 505; \ max_count_hi = 500; \
if (TARGET_BSR) \ if (TARGET_BSR) \
flag_no_function_cse = 1; \ flag_no_function_cse = 1; \
} while (0) } while (0)
...@@ -264,9 +270,6 @@ do { \ ...@@ -264,9 +270,6 @@ do { \
/* The best alignment to use in cases where we have a choice. */ /* The best alignment to use in cases where we have a choice. */
#define FASTEST_ALIGNMENT 32 #define FASTEST_ALIGNMENT 32
/* Every structures size must be a multiple of 32 bits. */
#define STRUCTURE_SIZE_BOUNDARY 32
/* Make strings word-aligned so strcpy from constants will be faster. */ /* Make strings word-aligned so strcpy from constants will be faster. */
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \ #define CONSTANT_ALIGNMENT(EXP, ALIGN) \
((TREE_CODE (EXP) == STRING_CST \ ((TREE_CODE (EXP) == STRING_CST \
...@@ -279,6 +282,11 @@ do { \ ...@@ -279,6 +282,11 @@ do { \
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
&& (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN)) && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
/* Number of bits which any structure or union's size must be a
multiple of. Each structure or union's size is rounded up to a
multiple of this. */
#define STRUCTURE_SIZE_BOUNDARY (TARGET_PACKSTRUCT ? 8 : 32)
/* Set this nonzero if move instructions will actually fail to work /* Set this nonzero if move instructions will actually fail to work
when given unaligned data. */ when given unaligned data. */
#define STRICT_ALIGNMENT 1 #define STRICT_ALIGNMENT 1
...@@ -305,9 +313,7 @@ do { \ ...@@ -305,9 +313,7 @@ do { \
The hardware registers are assigned numbers for the compiler The hardware registers are assigned numbers for the compiler
from 0 to just below FIRST_PSEUDO_REGISTER. from 0 to just below FIRST_PSEUDO_REGISTER.
All registers that the compiler knows about must be given numbers, All registers that the compiler knows about must be given numbers,
even those that are not normally considered general registers. even those that are not normally considered general registers. */
*/
#define AP_REG 16 #define AP_REG 16
#define PR_REG 17 #define PR_REG 17
...@@ -867,7 +873,7 @@ extern int current_function_anonymous_args; ...@@ -867,7 +873,7 @@ extern int current_function_anonymous_args;
/* Nonzero if the constant value X is a legitimate general operand. */ /* Nonzero if the constant value X is a legitimate general operand. */
#define LEGITIMATE_CONSTANT_P(X) \ #define LEGITIMATE_CONSTANT_P(X) \
(GET_CODE(X) != CONST_DOUBLE && GET_CODE(X) != LABEL_REF) (GET_CODE(X) != CONST_DOUBLE /*&& GET_CODE(X) != LABEL_REF*/)
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
...@@ -877,9 +883,9 @@ extern int current_function_anonymous_args; ...@@ -877,9 +883,9 @@ extern int current_function_anonymous_args;
them unless they have been allocated suitable hard regs. them unless they have been allocated suitable hard regs.
The symbol REG_OK_STRICT causes the latter definition to be used. */ 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_4(X,MODE) ((GET_MODE_SIZE(MODE)==4) && ((unsigned)INTVAL(X)<64) && (!(INTVAL(X) &3)))
#define MODE_DISP_OK_8(X,MODE) ((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60)) #define MODE_DISP_OK_8(X,MODE) ((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60) && (!(INTVAL(X) &3)))
#define MODE_DISP_OK_2(X,MODE) ((GET_MODE_SIZE(MODE)==2) && ((unsigned)INTVAL(X)<32) && TARGET_TRYR0) #define MODE_DISP_OK_2(X,MODE) ((GET_MODE_SIZE(MODE)==2) && ((unsigned)INTVAL(X)<32) && TARGET_TRYR0 && (!INTVAL(X) &1))
#define MODE_DISP_OK_1(X,MODE) ((GET_MODE_SIZE(MODE)==1) && ((unsigned)INTVAL(X)<16) && TARGET_TRYR0) #define MODE_DISP_OK_1(X,MODE) ((GET_MODE_SIZE(MODE)==1) && ((unsigned)INTVAL(X)<16) && TARGET_TRYR0)
#ifndef REG_OK_STRICT #ifndef REG_OK_STRICT
...@@ -896,7 +902,7 @@ extern int current_function_anonymous_args; ...@@ -896,7 +902,7 @@ extern int current_function_anonymous_args;
(REGNO (X) == 0 || REGNO(X) >= FIRST_PSEUDO_REGISTER) (REGNO (X) == 0 || REGNO(X) >= FIRST_PSEUDO_REGISTER)
#define REG_OK_FOR_PRE_POST_P(X) \ #define REG_OK_FOR_PRE_POST_P(X) \
(REG_OK_FOR_INDEX_P (X)) (REG_OK_FOR_BASE_P (X))
#else #else
/* Nonzero if X is a hard reg that can be used as a base reg. */ /* Nonzero if X is a hard reg that can be used as a base reg. */
...@@ -908,7 +914,7 @@ extern int current_function_anonymous_args; ...@@ -908,7 +914,7 @@ extern int current_function_anonymous_args;
REGNO_OK_FOR_INDEX_P (REGNO (X)) REGNO_OK_FOR_INDEX_P (REGNO (X))
#define REG_OK_FOR_PRE_POST_P(X) \ #define REG_OK_FOR_PRE_POST_P(X) \
(REGNO_OK_FOR_INDEX_P (REGNO (X))) (REGNO_OK_FOR_BASE_P (REGNO (X)))
#endif #endif
/* The Q is a pc relative load operand */ /* The Q is a pc relative load operand */
...@@ -1039,7 +1045,7 @@ extern int current_function_anonymous_args; ...@@ -1039,7 +1045,7 @@ extern int current_function_anonymous_args;
/* Define this if the tablejump instruction expects the table /* Define this if the tablejump instruction expects the table
to contain offsets from the address of the table. to contain offsets from the address of the table.
Do not define this if the table should contain absolute addresses. */ Do not define this if the table should contain absolute addresses. */
#define CASE_VECTOR_PC_RELATIVE /*#define CASE_VECTOR_PC_RELATIVE */
/* Specify the tree operation to be used to convert reals to integers. */ /* Specify the tree operation to be used to convert reals to integers. */
#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR #define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
...@@ -1053,6 +1059,9 @@ extern int current_function_anonymous_args; ...@@ -1053,6 +1059,9 @@ extern int current_function_anonymous_args;
/* The type of size_t unsigned int. */ /* The type of size_t unsigned int. */
#define SIZE_TYPE "unsigned int" #define SIZE_TYPE "unsigned int"
#define WCHAR_TYPE "short unsigned int"
#define WCHAR_TYPE_SIZE 16
/* Don't cse the address of the function being compiled. */ /* Don't cse the address of the function being compiled. */
/*#define NO_RECURSIVE_FUNCTION_CSE 1*/ /*#define NO_RECURSIVE_FUNCTION_CSE 1*/
...@@ -1195,13 +1204,14 @@ extern int current_function_anonymous_args; ...@@ -1195,13 +1204,14 @@ extern int current_function_anonymous_args;
/* How to change between sections. */ /* How to change between sections. */
#define TEXT_SECTION_ASM_OP "\t.text" #define TEXT_SECTION_ASM_OP "\t.text"
#define DATA_SECTION_ASM_OP "\t.data" #define DATA_SECTION_ASM_OP "\t.data"
#define CTORS_SECTION_ASM_OP "\t.section\t.ctors\n" #define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rdata\n"
#define DTORS_SECTION_ASM_OP "\t.section\t.dtors\n" #define CTORS_SECTION_ASM_OP "\t.section\t.ctors\n"
#define INIT_SECTION_ASM_OP "\t.section\t.init\n" #define DTORS_SECTION_ASM_OP "\t.section\t.dtors\n"
#define EXTRA_SECTIONS in_ctors, in_dtors #define INIT_SECTION_ASM_OP "\t.section\t.init\n"
#define EXTRA_SECTIONS in_ctors, in_dtors, in_rdata
#define READONLY_DATA_SECTION rdata_section
#define EXTRA_SECTION_FUNCTIONS \ #define EXTRA_SECTION_FUNCTIONS \
void \ void \
ctors_section() \ ctors_section() \
...@@ -1220,6 +1230,15 @@ dtors_section() \ ...@@ -1220,6 +1230,15 @@ dtors_section() \
fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \ fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \
in_section = in_dtors; \ in_section = in_dtors; \
} \ } \
} \
void \
rdata_section() \
{ \
if (in_section != in_rdata) \
{ \
fprintf (asm_out_file, "%s\n", READONLY_DATA_SECTION_ASM_OP); \
in_section = in_rdata; \
} \
} }
/* Assemble generic sections. /* Assemble generic sections.
...@@ -1462,7 +1481,7 @@ extern char *output_far_jump(); ...@@ -1462,7 +1481,7 @@ extern char *output_far_jump();
#define TARGET_MEM_FUNCTIONS #define TARGET_MEM_FUNCTIONS
#define HANDLE_PRAGMA(finput) handle_pragma (finput) #define HANDLE_PRAGMA(finput) return handle_pragma (finput)
/* Set when processing a function with pragma interrupt turned on. */ /* Set when processing a function with pragma interrupt turned on. */
......
...@@ -158,11 +158,14 @@ ...@@ -158,11 +158,14 @@
(cond [(eq_attr "type" "cbranch") (const_string "no") (cond [(eq_attr "type" "cbranch") (const_string "no")
(eq_attr "type" "jump") (const_string "no") (eq_attr "type" "jump") (const_string "no")
(eq_attr "type" "pload") (const_string "no") (eq_attr "type" "pload") (const_string "no")
(eq_attr "type" "pcloadsi") (const_string "no")
(eq_attr "type" "pcloadhi") (const_string "no")
(eq_attr "type" "return") (const_string "no") (eq_attr "type" "return") (const_string "no")
(eq_attr "length" "2") (const_string "yes") (eq_attr "length" "2") (const_string "yes")
(eq_attr "length" "4,6,8,10,12") (const_string "no") (eq_attr "length" "4,6,8,10,12") (const_string "no")
] (const_string "yes"))) ] (const_string "yes")))
;; ------------------------------------------------------------------------- ;; -------------------------------------------------------------------------
;; SImode signed integer comparisons ;; SImode signed integer comparisons
...@@ -259,18 +262,21 @@ ...@@ -259,18 +262,21 @@
;; Addition instructions ;; Addition instructions
;; ------------------------------------------------------------------------- ;; -------------------------------------------------------------------------
(define_insn "addc"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
(plus:SI (reg:SI 18)
(plus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
(match_operand:SI 2 "arith_reg_operand" "r"))))
(set (reg:SI 18) (gt:SI (match_dup 1) (match_dup 0)))]
""
"addc %2,%0")
;; this should be a define split. ;; this should be a define split.
(define_insn "addc"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
(plus:SI (match_dup 0)
(plus:SI (match_operand:SI 1 "arith_reg_operand" "r")
(reg:SI 18))))
(clobber (reg:SI 18))]
""
"addc %1,%0")
(define_expand "adddi3" (define_expand "adddi3"
[(set (match_operand:DI 0 "register_operand" "") [(set (match_operand:DI 0 "register_operand" "")
(plus:DI (match_operand:DI 1 "register_operand" "") (plus:DI (match_operand:DI 1 "register_operand" "")
...@@ -278,17 +284,20 @@ ...@@ -278,17 +284,20 @@
"" ""
" "
{ {
rtx low_a = gen_rtx (SUBREG, SImode, operands[1], 1); rtx low_a = operand_subword (operands[1], 1, 1, DImode);
rtx low_b = gen_rtx (SUBREG, SImode, operands[2], 1); rtx low_b = operand_subword (operands[2], 1, 1, DImode);
rtx low_s = gen_rtx (SUBREG, SImode, operands[0], 1); rtx low_s = operand_subword (operands[0], 1, 1, DImode);
rtx high_a = gen_rtx (SUBREG, SImode, operands[1], 0); rtx high_a = operand_subword (operands[1], 0, 1, DImode);
rtx high_b = gen_rtx (SUBREG, SImode, operands[2], 0); rtx high_b = operand_subword (operands[2], 0, 1, DImode);
rtx high_s = gen_rtx (SUBREG, SImode, operands[0], 0); rtx high_s = operand_subword (operands[0], 0, 1, DImode);
emit_insn (gen_clrt ()); emit_insn (gen_clrt ());
emit_insn (gen_addc (low_s, low_a, low_b));
emit_insn (gen_addc (high_s, high_a, high_b)); emit_move_insn (low_s, low_a);
emit_insn (gen_addc (low_s, low_b));
emit_move_insn (high_s, high_a);
emit_insn (gen_addc (high_s, high_b));
DONE; DONE;
}") }")
...@@ -314,16 +323,37 @@ ...@@ -314,16 +323,37 @@
;; Subtraction instructions ;; Subtraction instructions
;; ------------------------------------------------------------------------- ;; -------------------------------------------------------------------------
(define_insn "subdi3"
[(set (match_operand:DI 0 "arith_reg_operand" "=r") (define_insn "subc"
(minus:DI (match_operand:DI 1 "arith_reg_operand" "0") [(set (match_operand:SI 0 "arith_reg_operand" "=r")
(match_operand:DI 2 "arith_reg_operand" "r"))) (minus:SI (match_operand:SI 1 "arith_reg_operand" "%0")
(plus:SI (match_operand:SI 2 "arith_reg_operand" "r")
(reg:SI 18))))
(clobber (reg:SI 18))] (clobber (reg:SI 18))]
"" ""
"clrt\;subc %R2,%R0\;subc %2,%0" "subc %2,%0")
[(set_attr "length" "6")
(set_attr "in_delay_slot" "no") (define_expand "subdi3"
(set_attr "type" "arith")]) [(set (match_operand:DI 0 "register_operand" "")
(plus:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "register_operand" "")))]
""
"
{
rtx low_a = operand_subword (operands[1], 1, 1, DImode);
rtx low_b = operand_subword (operands[2], 1, 1, DImode);
rtx low_s = operand_subword (operands[0], 1, 1, DImode);
rtx high_a = operand_subword (operands[1], 0, 1, DImode);
rtx high_b = operand_subword (operands[2], 0, 1, DImode);
rtx high_s = operand_subword (operands[0], 0, 1, DImode);
emit_insn (gen_clrt ());
emit_insn (gen_subc (low_s, low_a, low_b));
emit_insn (gen_subc (high_s, high_a, high_b));
DONE;
}")
(define_insn "subsi3" (define_insn "subsi3"
[(set (match_operand:SI 0 "arith_reg_operand" "=r") [(set (match_operand:SI 0 "arith_reg_operand" "=r")
...@@ -504,14 +534,7 @@ ...@@ -504,14 +534,7 @@
(set (match_operand:SI 0 "arith_reg_operand" "=r") (set (match_operand:SI 0 "arith_reg_operand" "=r")
(reg:SI 21))] (reg:SI 21))]
"TARGET_SH2" "TARGET_SH2"
" "")
{
if (!TARGET_SH2)
{
emit_insn (gen_mulsi3_call (operands[0], operands[1], operands[2]));
DONE;
}
}")
(define_insn "" (define_insn ""
[(set (reg:DI 20) [(set (reg:DI 20)
...@@ -769,7 +792,7 @@ ...@@ -769,7 +792,7 @@
(define_insn "ashldi3_k" (define_insn "ashldi3_k"
[(set (match_operand:DI 0 "arith_reg_operand" "=r") [(set (match_operand:DI 0 "arith_reg_operand" "=r")
(ashift:DI (match_operand:DI 1 "arith_reg_operand" "0") (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
(match_operand:DI 2 "immediate_operand" "I"))) (const_int 1)))
(clobber (reg:SI 18))] (clobber (reg:SI 18))]
"" ""
"shll %R0\;rotcl %0" "shll %R0\;rotcl %0"
...@@ -788,7 +811,7 @@ ...@@ -788,7 +811,7 @@
(define_insn "lshrdi3_k" (define_insn "lshrdi3_k"
[(set (match_operand:DI 0 "arith_reg_operand" "=r") [(set (match_operand:DI 0 "arith_reg_operand" "=r")
(lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0") (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
(match_operand:DI 2 "immediate_operand" "I"))) (const_int 1)))
(clobber (reg:SI 18))] (clobber (reg:SI 18))]
"" ""
"shlr %0\;rotcr %R0" "shlr %0\;rotcr %R0"
...@@ -806,7 +829,7 @@ ...@@ -806,7 +829,7 @@
(define_insn "ashrdi3_k" (define_insn "ashrdi3_k"
[(set (match_operand:DI 0 "arith_reg_operand" "=r") [(set (match_operand:DI 0 "arith_reg_operand" "=r")
(ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0") (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
(match_operand:DI 2 "immediate_operand" ""))) (const_int 1)))
(clobber (reg:SI 18))] (clobber (reg:SI 18))]
"" ""
"shar %0\;rotcr %R0" "shar %0\;rotcr %R0"
...@@ -826,15 +849,35 @@ ...@@ -826,15 +849,35 @@
;; Unary arithmetic ;; Unary arithmetic
;; ------------------------------------------------------------------------- ;; -------------------------------------------------------------------------
(define_insn "negdi2"
[(set (match_operand:DI 0 "arith_reg_operand" "=&r") (define_insn "negc"
(neg:DI (match_operand:DI 1 "arith_reg_operand" "0"))) [(set (match_operand:SI 0 "arith_reg_operand" "=r")
(clobber (reg:SI 18))] (neg:SI (plus:SI (reg:SI 18) (match_operand:SI 1 "arith_reg_operand" "r"))))]
"" ""
"clrt\;negc %R1,%R0\;negc %1,%0" "negc %1,%0"
[(set_attr "length" "6") [(set_attr "length" "2")
(set_attr "type" "arith")]) (set_attr "type" "arith")])
(define_expand "negdi2"
[(set (match_operand:DI 0 "arith_reg_operand" "=r")
(neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))
(clobber (reg:SI 18))]
""
"{
rtx low_src = operand_subword (operands[1], 1, 0, DImode);
rtx high_src = operand_subword (operands[1], 0, 0, DImode);
rtx low_dst = operand_subword (operands[0], 1, 1, DImode);
rtx high_dst = operand_subword (operands[0], 0, 1, DImode);
emit_insn (gen_clrt ());
emit_insn (gen_negc (low_dst, low_src));
emit_insn (gen_negc (high_dst, high_src));
DONE;
}
")
(define_insn "negsi2" (define_insn "negsi2"
[(set (match_operand:SI 0 "arith_reg_operand" "=r") [(set (match_operand:SI 0 "arith_reg_operand" "=r")
(neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))] (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
...@@ -982,32 +1025,19 @@ ...@@ -982,32 +1025,19 @@
[(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,r,<m,<,xl,xl,t,r") [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,r,<m,<,xl,xl,t,r")
(match_operand:SI 1 "general_movsrc_operand" "Q,rI,>m,xl,t,r,xl,r,>,r,i"))] (match_operand:SI 1 "general_movsrc_operand" "Q,rI,>m,xl,t,r,xl,r,>,r,i"))]
"" ""
"* "@
{ mov.l %1,%0
switch (which_alternative) mov %1,%0
{ mov.l %1,%0
case 0: sts %1,%0
switch (get_attr_length(insn)) movt %0
{ mov.l %1,%0
case 2: sts.l %1,%0
return \"mov.l %1,%0\"; lds %1,%0
case 12: lds.l %1,%0
return \"mov.l TA%*,%0\;bra TB%*\;mov.l @%0,%0\;.align 2\;TA%*: .long %1\;TB%*:%^\"; tst %1,%1\;bt T%*\;bra F%*\;sett\;T%*:clrt\;F%*:%^
} fake %1,%0"
case 1: return \"mov %1,%0\"; [(set_attr "type" "pcloadsi,move,load,move,store,store,move,load,move,move,move")])
case 2: return \"mov.l %1,%0\";
case 3: return \"sts %1,%0\";
case 4: return \"movt %0\";
case 5: return \"mov.l %1,%0\";
case 6: return \"sts.l %1,%0\";
case 7: return \"lds %1,%0\";
case 8: return \"lds.l %1,%0\";
case 9: return \"tst %1,%1\;bt T%*\;bra F%*\;sett\;T%*:clrt\;F%*:%^\";
case 10: return \"fake %1,%0\";
}
}"
[(set_attr "length" "*,2,2,2,2,2,2,2,2,6,2")
(set_attr "type" "pcloadsi,move,load,move,store,store,move,load,move,move,move")])
(define_expand "movsi" (define_expand "movsi"
[(set (match_operand:SI 0 "general_movdst_operand" "") [(set (match_operand:SI 0 "general_movdst_operand" "")
...@@ -1042,27 +1072,15 @@ ...@@ -1042,27 +1072,15 @@
[(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,<m,r,r,l") [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,<m,r,r,l")
(match_operand:HI 1 "general_movsrc_operand" "Q,rI,>m,t,r,i,l,r"))] (match_operand:HI 1 "general_movsrc_operand" "Q,rI,>m,t,r,i,l,r"))]
"" ""
"* "@
{ mov.w %1,%0
switch (which_alternative) mov %1,%0
{ mov.w %1,%0
case 0: movt %0
switch (get_attr_length(insn)) mov.w %1,%0
{ fake %1,%0
case 2: sts %1,%0
return \"mov.w %1,%0\"; lds %1,%0"
case 12:
return \"mov.l TA%*,%0\;bra TB%*\;mov.w @%0,%0\;.align 2\;TA%*: .long %1\;TB%*:%^\";
}
case 1: return \"mov %1,%0\";
case 2: return \"mov.w %1,%0\";
case 3: return \"movt %0\";
case 4: return \"mov.w %1,%0\";
case 5: return \"fake %1,%0\";
case 6: return \"sts %1,%0\";
case 7: return \"lds %1,%0\";
}
}"
[(set_attr "length" "*,2,2,2,2,2,2,2") [(set_attr "length" "*,2,2,2,2,2,2,2")
(set_attr "type" "pcloadhi,move,load,move,store,move,move,move")]) (set_attr "type" "pcloadhi,move,load,move,store,move,move,move")])
...@@ -1089,6 +1107,43 @@ ...@@ -1089,6 +1107,43 @@
[(set_attr "length" "*,4,4,4,4") [(set_attr "length" "*,4,4,4,4")
(set_attr "type" "pcloadsi,move,load,store,move")]) (set_attr "type" "pcloadsi,move,load,store,move")])
;; If the output is a register and the input is memory, we have to be careful
;; and see which word needs to be loaded first.
;;
(define_split
[(set (match_operand:DI 0 "general_movdst_operand" "")
(match_operand:DI 1 "general_movsrc_operand" ""))]
"! (GET_CODE (operands[0]) == REG
&& REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
&& ! (GET_CODE (operands[1]) == REG
&& REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
&& ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
&& ! reload_completed
&& reg_overlap_mentioned_p (operands[0], operands[1]))"
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 5))]
"
{ 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, DImode);
operands[3] = operand_subword (operands[1], 0, 0, DImode);
operands[4] = operand_subword (operands[0], 1, 0, DImode);
operands[5] = operand_subword (operands[1], 1, 0, DImode);
}
else
{
operands[2] = operand_subword (operands[0], 1, 0, DImode);
operands[3] = operand_subword (operands[1], 1, 0, DImode);
operands[4] = operand_subword (operands[0], 0, 0, DImode);
operands[5] = operand_subword (operands[1], 0, 0, DImode);
}
if (operands[2] == 0 || operands[3] == 0
|| operands[4] == 0 || operands[5] == 0)
FAIL;
}")
(define_expand "movdi" (define_expand "movdi"
...@@ -1114,6 +1169,45 @@ ...@@ -1114,6 +1169,45 @@
[(set_attr "length" "4") [(set_attr "length" "4")
(set_attr "type" "move,load,store")]) (set_attr "type" "move,load,store")])
;; If the output is a register and the input is memory, we have to be careful
;; and see which word needs to be loaded first.
;;
(define_split
[(set (match_operand:DF 0 "general_movdst_operand" "")
(match_operand:DF 1 "general_movsrc_operand" ""))]
"! (GET_CODE (operands[0]) == REG
&& REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
&& ! (GET_CODE (operands[1]) == REG
&& REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
&& ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
&& ! reload_completed
&& reg_overlap_mentioned_p (operands[0], operands[1]))"
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 5))]
"
{ 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, DFmode);
operands[3] = operand_subword (operands[1], 0, 0, DFmode);
operands[4] = operand_subword (operands[0], 1, 0, DFmode);
operands[5] = operand_subword (operands[1], 1, 0, DFmode);
}
else
{
operands[2] = operand_subword (operands[0], 1, 0, DFmode);
operands[3] = operand_subword (operands[1], 1, 0, DFmode);
operands[4] = operand_subword (operands[0], 0, 0, DFmode);
operands[5] = operand_subword (operands[1], 0, 0, DFmode);
}
if (operands[2] == 0 || operands[3] == 0
|| operands[4] == 0 || operands[5] == 0)
FAIL;
}")
(define_expand "movdf" (define_expand "movdf"
[(set (match_operand:DF 0 "general_movdst_operand" "") [(set (match_operand:DF 0 "general_movdst_operand" "")
(match_operand:DF 1 "general_movsrc_operand" ""))] (match_operand:DF 1 "general_movsrc_operand" ""))]
...@@ -1443,12 +1537,15 @@ ...@@ -1443,12 +1537,15 @@
(const_int 1)) (const_int 1))
(label_ref (match_operand 4 "" "")) (label_ref (match_operand 4 "" ""))
(pc))) (pc)))
(set (match_dup 6) (plus:SI (match_dup 5) (match_dup 5))) (parallel[(set (match_dup 5) (ashift:SI (match_dup 5) (const_int 2)))
(clobber (reg:SI 18))])
(set (reg:SI 0) (label_ref (match_operand 3 "" ""))) (set (reg:SI 0) (label_ref (match_operand 3 "" "")))
(parallel[(set (reg:SI 0) (plus:SI (reg:SI 0) (set (reg:SI 0) (mem:SI (plus:SI (reg:SI 0) (match_dup 5))))
(mem:HI (plus:SI (reg:SI 0)
(match_dup 6))))) ;; (parallel[(set (reg:SI 0) (plus:SI (reg:SI 0)
(set (match_dup 6) (mem:HI (plus:SI (reg:SI 0) (match_dup 6))))]) ;; (mem:HI (plus:SI (reg:SI 0)
;; (match_dup 5)))))
;; (set (match_dup 6) (mem:HI (plus:SI (reg:SI 0) (match_dup 6))))])
(set (pc) (reg:SI 0))] (set (pc) (reg:SI 0))]
"" ""
" "
...@@ -1456,7 +1553,7 @@ ...@@ -1456,7 +1553,7 @@
operands[1] = copy_to_mode_reg (SImode, operands[1]); operands[1] = copy_to_mode_reg (SImode, operands[1]);
operands[2] = copy_to_mode_reg (SImode, operands[2]); operands[2] = copy_to_mode_reg (SImode, operands[2]);
operands[5] = gen_reg_rtx (SImode); operands[5] = gen_reg_rtx (SImode);
operands[6] = gen_reg_rtx (SImode);
}") }")
(define_insn "casesi_worker" (define_insn "casesi_worker"
...@@ -1470,7 +1567,7 @@ ...@@ -1470,7 +1567,7 @@
"mov.w @(r0,%0),%0\;add %0,r0" "mov.w @(r0,%0),%0\;add %0,r0"
[(set_attr "needs_delay_slot" "no") [(set_attr "needs_delay_slot" "no")
(set_attr "in_delay_slot" "no") (set_attr "in_delay_slot" "no")
(set_attr "length" "6")]) (set_attr "length" "4")])
(define_insn "return" (define_insn "return"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment