setOperationAction(ISD::CTLZ, MVT::i32, Custom);
setOperationAction(ISD::INTRINSIC_VOID, MVT::i32, Custom);
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i32, Custom);
+ setOperationAction(ISD::READ_REGISTER, MVT::i32, Custom);
+ setOperationAction(ISD::WRITE_REGISTER, MVT::i32, Custom);
if (Subtarget.hasBasicF() && !Subtarget.hasBasicD())
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
if (Subtarget.hasBasicF())
} else {
setOperationAction(ISD::BITREVERSE, MVT::i32, Legal);
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom);
+ setOperationAction(ISD::READ_REGISTER, MVT::i64, Custom);
+ setOperationAction(ISD::WRITE_REGISTER, MVT::i64, Custom);
}
static const ISD::CondCode FPCCToExpand[] = {
return lowerFRAMEADDR(Op, DAG);
case ISD::RETURNADDR:
return lowerRETURNADDR(Op, DAG);
+ case ISD::WRITE_REGISTER:
+ return lowerWRITE_REGISTER(Op, DAG);
}
return SDValue();
}
+SDValue LoongArchTargetLowering::lowerWRITE_REGISTER(SDValue Op,
+ SelectionDAG &DAG) const {
+
+ if (Subtarget.is64Bit() && Op.getOperand(2).getValueType() == MVT::i32) {
+ DAG.getContext()->emitError(
+ "On LA64, only 64-bit registers can be written.");
+ return Op.getOperand(0);
+ }
+
+ if (!Subtarget.is64Bit() && Op.getOperand(2).getValueType() == MVT::i64) {
+ DAG.getContext()->emitError(
+ "On LA32, only 32-bit registers can be written.");
+ return Op.getOperand(0);
+ }
+
+ return Op;
+}
+
SDValue LoongArchTargetLowering::lowerFRAMEADDR(SDValue Op,
SelectionDAG &DAG) const {
if (!isa<ConstantSDNode>(Op.getOperand(0))) {
}
break;
}
+ case ISD::READ_REGISTER: {
+ if (Subtarget.is64Bit())
+ DAG.getContext()->emitError(
+ "On LA64, only 64-bit registers can be read.");
+ else
+ DAG.getContext()->emitError(
+ "On LA32, only 32-bit registers can be read.");
+ Results.push_back(DAG.getUNDEF(N->getValueType(0)));
+ Results.push_back(N->getOperand(0));
+ break;
+ }
}
}
--- /dev/null
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: not llc < %s --mtriple=loongarch32 2>&1 | FileCheck %s
+
+define i64 @read_sp() nounwind {
+entry:
+; CHECK: On LA32, only 32-bit registers can be read.
+ %a1 = call i64 @llvm.read_register.i64(metadata !0)
+ ret i64 %a1
+}
+
+define void @write_sp(i64 %val) nounwind {
+entry:
+; CHECK: On LA32, only 32-bit registers can be written.
+ call void @llvm.write_register.i64(metadata !0, i64 %val)
+ ret void
+}
+
+declare i64 @llvm.read_register.i64(metadata) nounwind
+declare void @llvm.write_register.i64(metadata, i64) nounwind
+
+!0 = !{!"$sp\00"}
--- /dev/null
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: not llc < %s --mtriple=loongarch64 2>&1 | FileCheck %s
+
+define i32 @read_sp() nounwind {
+entry:
+; CHECK: On LA64, only 64-bit registers can be read.
+ %a1 = call i32 @llvm.read_register.i32(metadata !0)
+ ret i32 %a1
+}
+
+define void @write_sp(i32 %val) nounwind {
+entry:
+; CHECK: On LA64, only 64-bit registers can be written.
+ call void @llvm.write_register.i32(metadata !0, i32 %val)
+ ret void
+}
+
+declare i32 @llvm.read_register.i32(metadata) nounwind
+declare void @llvm.write_register.i32(metadata, i32) nounwind
+
+!0 = !{!"$sp\00"}