mmix.md ("nonlocal_goto_receiver"): Refer to the frame-pointer as an operand.
authorHans-Peter Nilsson <hp@bitrange.com>
Mon, 22 Oct 2012 09:25:02 +0000 (09:25 +0000)
committerHans-Peter Nilsson <hp@gcc.gnu.org>
Mon, 22 Oct 2012 09:25:02 +0000 (09:25 +0000)
* 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

gcc/ChangeLog
gcc/config/mmix/constraints.md
gcc/config/mmix/mmix.c
gcc/config/mmix/mmix.md
gcc/config/mmix/predicates.md

index 128837f8e4c0bfe68158c8694f4217fb5126f60b..c5dd80d4e376869f510ebeda0cb9a7789e861595 100644 (file)
@@ -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
index 954cddaa5af7775c7cb34953ad0010f28b8eb7fc..c1d28e858c80f4f48de6bf30de81748200bd7259 100644 (file)
 (define_address_constraint "U"
   "@internal"
   (match_operand 0 "mmix_address_operand"))
+
+(define_constraint "Yf"
+  "@internal"
+  (match_operand 0 "frame_pointer_operand"))
index 1ce880012778b5164d3dc12582ee7c06ad21ebc2..7199c5edc2ca6f5fc6c8cdc3ccc633d65c2f99ac 100644 (file)
@@ -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",
index 24d6292f78704c5993625a1ab14c46fb82937728..587b8f1f492df9285b1ea858d5c63ac9a6e0d898 100644 (file)
@@ -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]);
        }
     }
 
index f9ba32c88326e7ae422bee939fbb4e08a2076c7b..bf92c86ff0bf8f359cd4cfbaac5f7a848b88a28f 100644 (file)
   (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"))))