def FMOV_S : FP_MOV<0b0000000100010100100101, "fmov.s", FPR32, FPR32>;
def MOVGR2FR_W : FP_MOV<0b0000000100010100101001, "movgr2fr.w", FPR32, GPR>;
def MOVFR2GR_S : FP_MOV<0b0000000100010100101101, "movfr2gr.s", GPR, FPR32>;
-def MOVGR2FCSR : FPFmtMOV<0b0000000100010100110000, (outs), (ins FCSR:$dst, GPR:$src),
- "movgr2fcsr", "$dst, $src">;
+def MOVGR2FCSR : FP_MOV<0b0000000100010100110000, "movgr2fcsr", FCSR, GPR>;
def MOVFCSR2GR : FP_MOV<0b0000000100010100110010, "movfcsr2gr", GPR, FCSR>;
def MOVFR2CF_S : FP_MOV<0b0000000100010100110100, "movfr2cf", CFR, FPR32>;
def MOVCF2FR_S : FP_MOV<0b0000000100010100110101, "movcf2fr", FPR32, CFR>;
}
return DAG.getMergeValues(
{DAG.getNode(LoongArchISD::MOVFCSR2GR, DL, Op.getValueType(),
- DAG.getRegister(LoongArch::FCSR0 + Imm, MVT::i32)),
+ DAG.getConstant(Imm, DL, GRLenVT)),
Op.getOperand(0)},
DL);
}
return DAG.getNode(
LoongArchISD::MOVGR2FCSR, DL, MVT::Other, Op0,
- DAG.getRegister(LoongArch::FCSR0 + Imm, MVT::i32),
+ DAG.getConstant(Imm, DL, GRLenVT),
DAG.getNode(ISD::ANY_EXTEND, DL, GRLenVT, Op.getOperand(3)));
}
case Intrinsic::loongarch_syscall: {
SDValue Op0 = N->getOperand(0);
EVT VT = N->getValueType(0);
uint64_t Op1 = N->getConstantOperandVal(1);
+ MVT GRLenVT = Subtarget.getGRLenVT();
if (Op1 == Intrinsic::loongarch_movfcsr2gr) {
if (!Subtarget.hasBasicF()) {
DAG.getContext()->emitError(
Results.push_back(N->getOperand(0));
return;
}
- Results.push_back(DAG.getNode(
- ISD::TRUNCATE, DL, VT,
- DAG.getNode(LoongArchISD::MOVFCSR2GR, SDLoc(N), MVT::i64,
- DAG.getRegister(LoongArch::FCSR0 + Imm, MVT::i32))));
+ Results.push_back(
+ DAG.getNode(ISD::TRUNCATE, DL, VT,
+ DAG.getNode(LoongArchISD::MOVFCSR2GR, SDLoc(N), MVT::i64,
+ DAG.getConstant(Imm, DL, GRLenVT))));
Results.push_back(N->getOperand(0));
return;
}
SDValue Op2 = N->getOperand(2);
- MVT GRLenVT = Subtarget.getGRLenVT();
std::string Name = N->getOperationName(0);
switch (Op1) {
MachineBasicBlock *LoongArchTargetLowering::EmitInstrWithCustomInserter(
MachineInstr &MI, MachineBasicBlock *BB) const {
+ const TargetInstrInfo *TII = Subtarget.getInstrInfo();
+ DebugLoc DL = MI.getDebugLoc();
switch (MI.getOpcode()) {
default:
case LoongArch::MOD_DU:
return insertDivByZeroTrap(MI, BB);
break;
+ case LoongArch::WRFCSR: {
+ BuildMI(*BB, MI, DL, TII->get(LoongArch::MOVGR2FCSR),
+ LoongArch::FCSR0 + MI.getOperand(0).getImm())
+ .addReg(MI.getOperand(1).getReg());
+ MI.eraseFromParent();
+ return BB;
+ }
+ case LoongArch::RDFCSR: {
+ MachineInstr *ReadFCSR =
+ BuildMI(*BB, MI, DL, TII->get(LoongArch::MOVFCSR2GR),
+ MI.getOperand(0).getReg())
+ .addReg(LoongArch::FCSR0 + MI.getOperand(1).getImm());
+ ReadFCSR->getOperand(1).setIsUndef();
+ MI.eraseFromParent();
+ return BB;
+ }
}
}
SDTCisVT<3, GRLenVT>]>;
def SDT_LoongArchIocsrwr : SDTypeProfile<0, 2, [SDTCisInt<0>,
SDTCisSameAs<0, 1>]>;
-def SDT_LoongArchMovgr2fcsr : SDTypeProfile<0, 2, [SDTCisVT<0, i32>,
- SDTCisVT<1, GRLenVT>]>;
+def SDT_LoongArchMovgr2fcsr : SDTypeProfile<0, 2, [SDTCisVT<0, GRLenVT>,
+ SDTCisSameAs<0, 1>]>;
def SDT_LoongArchMovfcsr2gr : SDTypeProfile<1, 1, [SDTCisVT<0, GRLenVT>,
- SDTCisVT<1, i32>]>;
+ SDTCisSameAs<0, 1>]>;
// TODO: Add LoongArch specific DAG Nodes
// Target-independent nodes, but with target-specific formats.
let ParserMatchClass = ImmAsmOperand<"", 32, "">;
}
-def uimm2 : Operand<GRLenVT> {
+def uimm2 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<2>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<2>;
}
include "LoongArchFloat32InstrInfo.td"
include "LoongArchFloat64InstrInfo.td"
-let Predicates = [HasBasicF] in {
-def : Pat<(loongarch_movfcsr2gr i32:$fcsr),
- (MOVFCSR2GR FCSR:$fcsr)>;
-def : Pat<(loongarch_movgr2fcsr i32:$fcsr, GRLenVT:$rj),
- (MOVGR2FCSR FCSR:$fcsr, GPR:$rj)>;
+let Predicates = [HasBasicF], usesCustomInserter = 1 in {
+ def WRFCSR : Pseudo<(outs), (ins uimm2:$fcsr, GPR:$src),
+ [(loongarch_movgr2fcsr uimm2:$fcsr, GRLenVT:$src)]>;
+ def RDFCSR : Pseudo<(outs GPR:$rd), (ins uimm2:$fcsr),
+ [(set GPR:$rd, (loongarch_movfcsr2gr uimm2:$fcsr))]>;
}
//===----------------------------------------------------------------------===//
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc --mtriple=loongarch32 --mattr=+f < %s | FileCheck %s
-; RUN: llc --mtriple=loongarch64 --mattr=+f < %s | FileCheck %s
+; RUN: llc --mtriple=loongarch32 --mattr=+f --verify-machineinstrs < %s | FileCheck %s
+; RUN: llc --mtriple=loongarch64 --mattr=+f --verify-machineinstrs < %s | FileCheck %s
declare void @llvm.loongarch.dbar(i32)
declare void @llvm.loongarch.ibar(i32)