summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhp <hp@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-22 09:25:02 +0000
committerhp <hp@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-22 09:25:02 +0000
commit4d66cf0196b97053a3291f954879871578c45429 (patch)
tree9dd3ba4f5ea1d10b1b85ceea37b5854a8590184f
parent9c2ac5939f2f4115d7052af9aba886bd3773d28a (diff)
downloadgcc-4d66cf0196b97053a3291f954879871578c45429.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@192677 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/mmix/constraints.md4
-rw-r--r--gcc/config/mmix/mmix.c4
-rw-r--r--gcc/config/mmix/mmix.md44
-rw-r--r--gcc/config/mmix/predicates.md11
5 files changed, 51 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 128837f8e4c..c5dd80d4e37 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/mmix/constraints.md b/gcc/config/mmix/constraints.md
index 954cddaa5af..c1d28e858c8 100644
--- a/gcc/config/mmix/constraints.md
+++ b/gcc/config/mmix/constraints.md
@@ -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"))
diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c
index 1ce88001277..7199c5edc2c 100644
--- a/gcc/config/mmix/mmix.c
+++ b/gcc/config/mmix/mmix.c
@@ -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",
diff --git a/gcc/config/mmix/mmix.md b/gcc/config/mmix/mmix.md
index 24d6292f787..587b8f1f492 100644
--- a/gcc/config/mmix/mmix.md
+++ b/gcc/config/mmix/mmix.md
@@ -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]);
}
}
diff --git a/gcc/config/mmix/predicates.md b/gcc/config/mmix/predicates.md
index f9ba32c8832..bf92c86ff0b 100644
--- a/gcc/config/mmix/predicates.md
+++ b/gcc/config/mmix/predicates.md
@@ -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"))))