diff --git a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td index f6981a0b2d9ac..40e7665fb1f7e 100644 --- a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td @@ -98,8 +98,7 @@ def FSEL_S : FP_SEL<0b00001101000000, "fsel", FPR32>; 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>; diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index afdc6d1bd43b0..61fda67433227 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -722,7 +722,7 @@ LoongArchTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op, } 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); } @@ -812,7 +812,7 @@ SDValue LoongArchTargetLowering::lowerINTRINSIC_VOID(SDValue Op, 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: { @@ -1145,6 +1145,7 @@ void LoongArchTargetLowering::ReplaceNodeResults( 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( @@ -1163,15 +1164,14 @@ void LoongArchTargetLowering::ReplaceNodeResults( 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) { @@ -1729,6 +1729,8 @@ static MachineBasicBlock *insertDivByZeroTrap(MachineInstr &MI, MachineBasicBlock *LoongArchTargetLowering::EmitInstrWithCustomInserter( MachineInstr &MI, MachineBasicBlock *BB) const { + const TargetInstrInfo *TII = Subtarget.getInstrInfo(); + DebugLoc DL = MI.getDebugLoc(); switch (MI.getOpcode()) { default: @@ -1743,6 +1745,22 @@ MachineBasicBlock *LoongArchTargetLowering::EmitInstrWithCustomInserter( 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; + } } } diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td index 8e552b23b65d7..75b2adc729d0e 100644 --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -48,10 +48,10 @@ def SDT_LoongArchCsrxchg : SDTypeProfile<1, 3, [SDTCisInt<0>, 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. @@ -180,7 +180,7 @@ def imm32 : Operand { let ParserMatchClass = ImmAsmOperand<"", 32, "">; } -def uimm2 : Operand { +def uimm2 : Operand, ImmLeaf(Imm);}]> { let ParserMatchClass = UImmAsmOperand<2>; } @@ -1647,11 +1647,11 @@ def PseudoLI_D : Pseudo<(outs GPR:$rd), (ins grlenimm:$imm), [], 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))]>; } //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/LoongArch/intrinsic.ll b/llvm/test/CodeGen/LoongArch/intrinsic.ll index 401e07fdefdf5..cfd54e17d1d4c 100644 --- a/llvm/test/CodeGen/LoongArch/intrinsic.ll +++ b/llvm/test/CodeGen/LoongArch/intrinsic.ll @@ -1,6 +1,6 @@ ; 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)