|| 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. */
{
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;
}
{
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. */
(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"
"*
/* 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