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:
Jim Wilson 1999-06-14 15:47:30 +00:00 committed by Jim Wilson
parent 13f1623bc0
commit bf4f78eef9
3 changed files with 81 additions and 5 deletions

View File

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

View File

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

View File

@ -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;
}
}")