mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 18:20:51 +08:00
mmix.md ("nonlocal_goto_receiver"): Refer to the frame-pointer as an operand.
* config/mmix/mmix.md ("nonlocal_goto_receiver"): Refer to the frame-pointer as an operand. ("*nonlocal_goto_receiver_expanded"): Ditto. Use mmix_output_register_setting instead of naked output_asm_insn for the offset from the frame-pointer to the saved rO. * config/mmix/mmix.c (mmix_output_register_setting): Emit NEGU for values -255..0. * config/mmix/predicates.md ("frame_pointer_operand"): New. * config/mmix/constraints.md ("Yf"): New. From-SVN: r192677
This commit is contained in:
parent
8df7772284
commit
a271e61c6b
@ -1,5 +1,15 @@
|
||||
2012-10-22 Hans-Peter Nilsson <hp@bitrange.com>
|
||||
|
||||
* config/mmix/mmix.md ("nonlocal_goto_receiver"): Refer to the
|
||||
frame-pointer as an operand.
|
||||
("*nonlocal_goto_receiver_expanded"): Ditto. Use
|
||||
mmix_output_register_setting instead of naked output_asm_insn for
|
||||
the offset from the frame-pointer to the saved rO.
|
||||
* config/mmix/mmix.c (mmix_output_register_setting): Emit NEGU for
|
||||
values -255..0.
|
||||
* config/mmix/predicates.md ("frame_pointer_operand"): New.
|
||||
* config/mmix/constraints.md ("Yf"): New.
|
||||
|
||||
* stmt.c (expand_nl_goto_receiver): Remove almost-copy of
|
||||
expand_builtin_setjmp_receiver.
|
||||
(expand_label): Adjust, call expand_builtin_setjmp_receiver
|
||||
|
@ -110,3 +110,7 @@
|
||||
(define_address_constraint "U"
|
||||
"@internal"
|
||||
(match_operand 0 "mmix_address_operand"))
|
||||
|
||||
(define_constraint "Yf"
|
||||
"@internal"
|
||||
(match_operand 0 "frame_pointer_operand"))
|
||||
|
@ -2299,7 +2299,9 @@ mmix_output_register_setting (FILE *stream,
|
||||
if (do_begin_end)
|
||||
fprintf (stream, "\t");
|
||||
|
||||
if (mmix_shiftable_wyde_value ((unsigned HOST_WIDEST_INT) value))
|
||||
if (insn_const_int_ok_for_constraint (value, CONSTRAINT_K))
|
||||
fprintf (stream, "NEGU %s,0," HOST_WIDEST_INT_PRINT_DEC, reg_names[regno], -value);
|
||||
else if (mmix_shiftable_wyde_value ((unsigned HOST_WIDEST_INT) value))
|
||||
{
|
||||
/* First, the one-insn cases. */
|
||||
mmix_output_shiftvalue_op_from_str (stream, "SET",
|
||||
|
@ -1120,7 +1120,7 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
|
||||
;; of "pop 0,0" until rO equals the saved value. (If it goes lower, we
|
||||
;; should die with a trap.)
|
||||
(define_expand "nonlocal_goto_receiver"
|
||||
[(parallel [(unspec_volatile [(const_int 0)] 1)
|
||||
[(parallel [(unspec_volatile [(match_dup 1)] 1)
|
||||
(clobber (scratch:DI))
|
||||
(clobber (reg:DI MMIX_rJ_REGNUM))])
|
||||
(set (reg:DI MMIX_rJ_REGNUM) (match_dup 0))]
|
||||
@ -1131,6 +1131,13 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
|
||||
= mmix_get_hard_reg_initial_val (Pmode,
|
||||
MMIX_INCOMING_RETURN_ADDRESS_REGNUM);
|
||||
|
||||
/* We need the frame-pointer to be live or the equivalent
|
||||
expression, so refer to in in the pattern. We can't use a MEM
|
||||
(that may contain out-of-range offsets in the final expression)
|
||||
for fear that middle-end will legitimize it or replace the address
|
||||
using temporary registers (which are not revived at this point). */
|
||||
operands[1] = frame_pointer_rtx;
|
||||
|
||||
/* Mark this function as containing a landing-pad. */
|
||||
cfun->machine->has_landing_pad = 1;
|
||||
}")
|
||||
@ -1140,45 +1147,40 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
|
||||
;; address and re-use them after the register stack unwind, so it's best
|
||||
;; to form the address ourselves.
|
||||
(define_insn "*nonlocal_goto_receiver_expanded"
|
||||
[(unspec_volatile [(const_int 0)] 1)
|
||||
[(unspec_volatile [(match_operand:DI 1 "frame_pointer_operand" "Yf")] 1)
|
||||
(clobber (match_scratch:DI 0 "=&r"))
|
||||
(clobber (reg:DI MMIX_rJ_REGNUM))]
|
||||
""
|
||||
{
|
||||
rtx temp_reg = operands[0];
|
||||
rtx my_operands[2];
|
||||
HOST_WIDEST_INT offs;
|
||||
rtx my_operands[3];
|
||||
const char *my_template
|
||||
= "GETA $255,0f\;PUT rJ,$255\;LDOU $255,%a0\n\
|
||||
0:\;GET %1,rO\;CMPU %1,%1,$255\;BNP %1,1f\;POP 0,0\n1:";
|
||||
|
||||
my_operands[1] = temp_reg;
|
||||
my_operands[1] = operands[0];
|
||||
my_operands[2] = GEN_INT (-MMIX_fp_rO_OFFSET);
|
||||
|
||||
/* If we have a frame-pointer (hence unknown stack-pointer offset),
|
||||
just use the frame-pointer and the known offset. */
|
||||
if (frame_pointer_needed)
|
||||
if (operands[1] == hard_frame_pointer_rtx)
|
||||
{
|
||||
my_operands[0] = GEN_INT (-MMIX_fp_rO_OFFSET);
|
||||
|
||||
output_asm_insn ("NEGU %1,0,%0", my_operands);
|
||||
my_operands[0] = gen_rtx_PLUS (Pmode, frame_pointer_rtx, temp_reg);
|
||||
mmix_output_register_setting (asm_out_file, REGNO (operands[0]),
|
||||
MMIX_fp_rO_OFFSET, 1);
|
||||
my_operands[0]
|
||||
= gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, operands[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We know the fp-based offset, so "eliminate" it to be sp-based. */
|
||||
offs
|
||||
= (mmix_initial_elimination_offset (MMIX_FRAME_POINTER_REGNUM,
|
||||
MMIX_STACK_POINTER_REGNUM)
|
||||
+ MMIX_fp_rO_OFFSET);
|
||||
HOST_WIDEST_INT offs = INTVAL (XEXP (operands[1], 1));
|
||||
offs += MMIX_fp_rO_OFFSET;
|
||||
|
||||
if (offs >= 0 && offs <= 255)
|
||||
if (insn_const_int_ok_for_constraint (offs, CONSTRAINT_I))
|
||||
my_operands[0]
|
||||
= gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offs));
|
||||
else
|
||||
{
|
||||
mmix_output_register_setting (asm_out_file, REGNO (temp_reg),
|
||||
mmix_output_register_setting (asm_out_file, REGNO (operands[0]),
|
||||
offs, 1);
|
||||
my_operands[0] = gen_rtx_PLUS (Pmode, stack_pointer_rtx, temp_reg);
|
||||
my_operands[0]
|
||||
= gen_rtx_PLUS (Pmode, stack_pointer_rtx, operands[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,3 +161,14 @@
|
||||
(if_then_else (match_test "reload_in_progress || reload_completed")
|
||||
(match_test "strict_memory_address_p (Pmode, op)")
|
||||
(match_test "memory_address_p (Pmode, op)")))
|
||||
|
||||
(define_predicate "frame_pointer_operand"
|
||||
(ior
|
||||
(and
|
||||
(match_code "reg")
|
||||
(match_test "op == hard_frame_pointer_rtx || op == frame_pointer_rtx"))
|
||||
(and
|
||||
(match_code "plus")
|
||||
(match_code "reg" "0")
|
||||
(match_code "const_int" "1")
|
||||
(match_test "XEXP (op, 0) == stack_pointer_rtx"))))
|
||||
|
Loading…
x
Reference in New Issue
Block a user