Commit a271e61c by Hans-Peter Nilsson Committed by Hans-Peter Nilsson

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
parent 8df77722
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"))))
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