sparc.c (label_ref_operand): New function.
authorDoug Evans <dje@gnu.org>
Thu, 15 Aug 1996 19:05:21 +0000 (19:05 +0000)
committerDoug Evans <dje@gnu.org>
Thu, 15 Aug 1996 19:05:21 +0000 (19:05 +0000)
* sparc/sparc.c (label_ref_operand): New function.
(emit_move_sequence): Pass label_ref to gen_move_label_di to not
lose flags.
* sparc/sparc.md (move_label_di): Operand one is label_ref now.
* genattrtab.c (write_test_expr): Allow label_ref in match_dup.

From-SVN: r12643

gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md
gcc/genattrtab.c

index 1708b3717533891f578da1b7328e5ff403bd6abd..5b80dcb43c26952417290711e9b82cd3aba89e19 100644 (file)
@@ -441,6 +441,20 @@ symbolic_memory_operand (op, mode)
          || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
 }
 
+/* Return truth value of statement that OP is a LABEL_REF of mode MODE.  */
+
+int
+label_ref_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_CODE (op) != LABEL_REF)
+    return 0;
+  if (GET_MODE (op) != mode)
+    return 0;
+  return 1;
+}
+
 /* Return 1 if the operand is an argument used in generating pic references
    in either the medium/low or medium/anywhere code models of sparc64.  */
 
@@ -1502,6 +1516,8 @@ emit_move_sequence (operands, mode)
     {
       if (TARGET_ARCH64)
        abort ();
+      /* ??? This might suffer from the same problem the DImode case did:
+        flags in operand1 not being propagated.  */
       emit_insn (gen_move_pic_label_si (operand0, XEXP (operand1, 0)));
       return 1;
     }
@@ -1512,7 +1528,7 @@ emit_move_sequence (operands, mode)
     {
       if (! TARGET_ARCH64)
        abort ();
-      emit_insn (gen_move_label_di (operands[0], XEXP (operands[1], 0)));
+      emit_insn (gen_move_label_di (operand0, operand1));
       return 1;
     }
   /* DImode HIGH values in sparc64 need a clobber added.  */
index 1fc88de223adf7f007552d0317000d8d82fb2c39..f565dc631f7f5d8488091a539767ee59f7c61ed8 100644 (file)
 
 (define_insn "move_label_di"
   [(set (match_operand:DI 0 "register_operand" "=r")
-       (label_ref:DI (match_operand 1 "" "")))
+       ; This was previously (label_ref:DI (match_operand 1 "" "")) but that
+       ; loses the volatil and other flags of the original label_ref.
+       (match_operand:DI 1 "label_ref_operand" ""))
    (set (reg:DI 15) (pc))]
   "TARGET_ARCH64"
   "*
index 38285f1c33b2d0142421d89e5409d5f1528f64dd..f1a94d08d64138547e6072066d2f1f5cabb9ae10 100644 (file)
@@ -4488,7 +4488,8 @@ write_test_expr (exp, in_comparison)
 
     /* The address of the branch target.  */
     case MATCH_DUP:
-      printf ("insn_addresses[INSN_UID (operands[%d])]", XINT (exp, 0));
+      printf ("insn_addresses[INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])]",
+             XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
       break;
 
     /* The address of the current insn.  It would be more consistent with