diff options
author | hp <hp@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-22 09:25:02 +0000 |
---|---|---|
committer | hp <hp@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-22 09:25:02 +0000 |
commit | 4d66cf0196b97053a3291f954879871578c45429 (patch) | |
tree | 9dd3ba4f5ea1d10b1b85ceea37b5854a8590184f | |
parent | 9c2ac5939f2f4115d7052af9aba886bd3773d28a (diff) | |
download | gcc-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/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/mmix/constraints.md | 4 | ||||
-rw-r--r-- | gcc/config/mmix/mmix.c | 4 | ||||
-rw-r--r-- | gcc/config/mmix/mmix.md | 44 | ||||
-rw-r--r-- | gcc/config/mmix/predicates.md | 11 |
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")))) |