Fix switch table and reload problems for mips16.
* config/mips/mips.c (mips_secondary_reload_class): Check for (PLUS (SP) (REG)) and return appropriate register class. * config/mips/mips.md (reload_insi): Delete predicate for operand 1. Handle (PLUS (SP) (REG)). (tablejump): In mips16 code, use emit_insn instead of emit_jump_insn. (tablejump_mips161, tablejump_mips162): Use emit_jump_insn instead of emit_insn for tablejump. From-SVN: r27519
This commit is contained in:
parent
13f1623bc0
commit
bf4f78eef9
|
@ -1,3 +1,13 @@
|
|||
Mon Jun 14 15:38:43 1999 Jim Wilson <wilson@cygnus.com>
|
||||
|
||||
* config/mips/mips.c (mips_secondary_reload_class): Check for
|
||||
(PLUS (SP) (REG)) and return appropriate register class.
|
||||
* config/mips/mips.md (reload_insi): Delete predicate for operand 1.
|
||||
Handle (PLUS (SP) (REG)).
|
||||
(tablejump): In mips16 code, use emit_insn instead of emit_jump_insn.
|
||||
(tablejump_mips161, tablejump_mips162): Use emit_jump_insn instead
|
||||
of emit_insn for tablejump.
|
||||
|
||||
Mon Jun 14 17:26:40 1999 David Edelsohn <edelsohn@gnu.org>
|
||||
|
||||
* rs6000.c (output_prolog): RS6000_CALL_GLUE must be
|
||||
|
|
|
@ -7234,6 +7234,19 @@ mips_secondary_reload_class (class, mode, x, in_p)
|
|||
}
|
||||
if (! gp_reg_p)
|
||||
{
|
||||
/* The stack pointer isn't a valid operand to an add instruction,
|
||||
so we need to load it into M16_REGS first. This can happen as
|
||||
a result of register elimination and form_sum converting
|
||||
(plus reg (plus SP CONST)) to (plus (plus reg SP) CONST). We
|
||||
need an extra register if the dest is the same as the other
|
||||
register. In that case, we can't fix the problem by loading SP
|
||||
into the dest first. */
|
||||
if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == REG
|
||||
&& GET_CODE (XEXP (x, 1)) == REG
|
||||
&& (XEXP (x, 0) == stack_pointer_rtx
|
||||
|| XEXP (x, 1) == stack_pointer_rtx))
|
||||
return (class == M16_REGS ? M16_NA_REGS : M16_REGS);
|
||||
|
||||
if (class == M16_REGS || class == M16_NA_REGS)
|
||||
return NO_REGS;
|
||||
return M16_REGS;
|
||||
|
|
|
@ -5473,9 +5473,12 @@ move\\t%0,%z4\\n\\
|
|||
;; so we use a mult. ??? This is hideous, and we ought to figure out
|
||||
;; something better.
|
||||
|
||||
;; We use no predicate for operand1, because it may be a PLUS, and there
|
||||
;; is no convenient predicate for that.
|
||||
|
||||
(define_expand "reload_insi"
|
||||
[(set (match_operand:SI 0 "register_operand" "=b")
|
||||
(match_operand:SI 1 "register_operand" "b"))
|
||||
(match_operand:SI 1 "" "b"))
|
||||
(clobber (match_operand:SI 2 "register_operand" "=&d"))]
|
||||
"TARGET_MIPS16"
|
||||
"
|
||||
|
@ -5499,6 +5502,56 @@ move\\t%0,%z4\\n\\
|
|||
gen_rtx (REG, SImode, 66)))));
|
||||
DONE;
|
||||
}
|
||||
|
||||
/* If this is a plus, then this must be an add of the stack pointer against
|
||||
either a hard register or a pseudo. */
|
||||
if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
|
||||
{
|
||||
rtx plus_op;
|
||||
|
||||
if (XEXP (operands[1], 0) == stack_pointer_rtx)
|
||||
plus_op = XEXP (operands[1], 1);
|
||||
else if (XEXP (operands[1], 1) == stack_pointer_rtx)
|
||||
plus_op = XEXP (operands[1], 0);
|
||||
else
|
||||
abort ();
|
||||
|
||||
/* We should have a register now. */
|
||||
if (GET_CODE (plus_op) != REG)
|
||||
abort ();
|
||||
|
||||
if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
/* We have to have at least one temporary register which is not
|
||||
overlapping plus_op. */
|
||||
if (! rtx_equal_p (plus_op, operands[0]))
|
||||
{
|
||||
emit_move_insn (operands[0], stack_pointer_rtx);
|
||||
emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
|
||||
}
|
||||
else if (! rtx_equal_p (plus_op, operands[2]))
|
||||
{
|
||||
emit_move_insn (operands[2], stack_pointer_rtx);
|
||||
emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
|
||||
}
|
||||
else
|
||||
abort ();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We need two registers in this case. */
|
||||
if (! rtx_equal_p (operands[0], operands[2]))
|
||||
{
|
||||
emit_move_insn (operands[0], stack_pointer_rtx);
|
||||
emit_move_insn (operands[2], plus_op);
|
||||
emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
|
||||
}
|
||||
else
|
||||
abort ();
|
||||
}
|
||||
DONE;
|
||||
}
|
||||
|
||||
/* FIXME: I don't know how to get a value into the HI register. */
|
||||
emit_move_insn (operands[0], operands[1]);
|
||||
DONE;
|
||||
|
@ -9039,9 +9092,9 @@ move\\t%0,%z4\\n\\
|
|||
if (GET_MODE (operands[0]) != HImode)
|
||||
abort ();
|
||||
if (!(Pmode == DImode))
|
||||
emit_jump_insn (gen_tablejump_mips161 (operands[0], operands[1]));
|
||||
emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
|
||||
else
|
||||
emit_jump_insn (gen_tablejump_mips162 (operands[0], operands[1]));
|
||||
emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
|
||||
DONE;
|
||||
}
|
||||
|
||||
|
@ -9110,7 +9163,7 @@ move\\t%0,%z4\\n\\
|
|||
emit_insn (gen_extendhisi2 (t1, operands[0]));
|
||||
emit_move_insn (t2, gen_rtx (LABEL_REF, SImode, operands[1]));
|
||||
emit_insn (gen_addsi3 (t3, t1, t2));
|
||||
emit_insn (gen_tablejump_internal1 (t3, operands[1]));
|
||||
emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
|
||||
DONE;
|
||||
}
|
||||
}")
|
||||
|
@ -9132,7 +9185,7 @@ move\\t%0,%z4\\n\\
|
|||
emit_insn (gen_extendhidi2 (t1, operands[0]));
|
||||
emit_move_insn (t2, gen_rtx (LABEL_REF, DImode, operands[1]));
|
||||
emit_insn (gen_adddi3 (t3, t1, t2));
|
||||
emit_insn (gen_tablejump_internal2 (t3, operands[1]));
|
||||
emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
|
||||
DONE;
|
||||
}
|
||||
}")
|
||||
|
|
Loading…
Reference in New Issue