Lines Matching full:loongarch

1 //=- LoongArchISelLowering.cpp - LoongArch DAG Lowering Implementation  ---===//
9 // This file defines the interfaces that LoongArch uses to lower LLVM code into
15 #include "LoongArch.h"
37 #define DEBUG_TYPE "loongarch-isel-lowering"
41 static cl::opt<bool> ZeroDivCheck("loongarch-check-zero-division", cl::Hidden,
53 addRegisterClass(GRLenVT, &LoongArch::GPRRegClass); in LoongArchTargetLowering()
55 addRegisterClass(MVT::f32, &LoongArch::FPR32RegClass); in LoongArchTargetLowering()
57 addRegisterClass(MVT::f64, &LoongArch::FPR64RegClass); in LoongArchTargetLowering()
66 addRegisterClass(VT, &LoongArch::LSX128RegClass); in LoongArchTargetLowering()
70 addRegisterClass(VT, &LoongArch::LASX256RegClass); in LoongArchTargetLowering()
349 setStackPointerRegisterToSaveRestore(LoongArch::R3); in LoongArchTargetLowering()
826 /// Dispatching routine to lower various 128-bit LoongArch vector shuffles.
1148 /// The first case is the closest to LoongArch instructions and the other
1187 // is low lane type, which is closest to the LoongArch instructions. in canonicalizeShuffleVectorByLane()
1189 // Note: In the LoongArch architecture, the high lane of mask corresponds in canonicalizeShuffleVectorByLane()
1251 /// Dispatching routine to lower various 256-bit LoongArch vector shuffles.
1714 Load = SDValue(DAG.getMachineNode(LoongArch::PseudoLA_PCREL_LARGE, DL, Ty, in getAddr()
1721 DAG.getMachineNode(LoongArch::PseudoLA_GOT_LARGE, DL, Ty, Tmp, Addr), in getAddr()
1733 DAG.getMachineNode(LoongArch::PseudoLA_PCREL, DL, Ty, Addr), 0); in getAddr()
1738 SDValue(DAG.getMachineNode(LoongArch::PseudoLA_GOT, DL, Ty, Addr), 0); in getAddr()
1817 DAG.getRegister(LoongArch::R2, GRLenVT)); in getStaticTLSAddr()
1899 Large ? LoongArch::PseudoLA_TLS_GD_LARGE in lowerGlobalTLSAddress()
1900 : LoongArch::PseudoLA_TLS_GD, in lowerGlobalTLSAddress()
1908 Large ? LoongArch::PseudoLA_TLS_LD_LARGE in lowerGlobalTLSAddress()
1909 : LoongArch::PseudoLA_TLS_LD, in lowerGlobalTLSAddress()
1915 Large ? LoongArch::PseudoLA_TLS_IE_LARGE in lowerGlobalTLSAddress()
1916 : LoongArch::PseudoLA_TLS_IE, in lowerGlobalTLSAddress()
1923 return getStaticTLSAddr(N, DAG, LoongArch::PseudoLA_TLS_LE, in lowerGlobalTLSAddress()
1928 Large ? LoongArch::PseudoLA_TLS_DESC_PC_LARGE in lowerGlobalTLSAddress()
1929 : LoongArch::PseudoLA_TLS_DESC_PC, in lowerGlobalTLSAddress()
1956 return DAG.getRegister(LoongArch::R2, PtrVT); in lowerINTRINSIC_WO_CHAIN()
2380 // call void @llvm.loongarch.cacop.[d/w](uimm5, rj, simm12) in lowerINTRINSIC_VOID()
4283 BuildMI(MBB, DL, TII.get(LoongArch::BNEZ)) in insertDivByZeroTrap()
4290 // See linux header file arch/loongarch/include/uapi/asm/break.h for the in insertDivByZeroTrap()
4292 BuildMI(BreakMBB, DL, TII.get(LoongArch::BREAK)).addImm(7 /*BRK_DIVZERO*/); in insertDivByZeroTrap()
4308 case LoongArch::PseudoVBZ: in emitVecCondBranchPseudo()
4309 CondOpc = LoongArch::VSETEQZ_V; in emitVecCondBranchPseudo()
4311 case LoongArch::PseudoVBZ_B: in emitVecCondBranchPseudo()
4312 CondOpc = LoongArch::VSETANYEQZ_B; in emitVecCondBranchPseudo()
4314 case LoongArch::PseudoVBZ_H: in emitVecCondBranchPseudo()
4315 CondOpc = LoongArch::VSETANYEQZ_H; in emitVecCondBranchPseudo()
4317 case LoongArch::PseudoVBZ_W: in emitVecCondBranchPseudo()
4318 CondOpc = LoongArch::VSETANYEQZ_W; in emitVecCondBranchPseudo()
4320 case LoongArch::PseudoVBZ_D: in emitVecCondBranchPseudo()
4321 CondOpc = LoongArch::VSETANYEQZ_D; in emitVecCondBranchPseudo()
4323 case LoongArch::PseudoVBNZ: in emitVecCondBranchPseudo()
4324 CondOpc = LoongArch::VSETNEZ_V; in emitVecCondBranchPseudo()
4326 case LoongArch::PseudoVBNZ_B: in emitVecCondBranchPseudo()
4327 CondOpc = LoongArch::VSETALLNEZ_B; in emitVecCondBranchPseudo()
4329 case LoongArch::PseudoVBNZ_H: in emitVecCondBranchPseudo()
4330 CondOpc = LoongArch::VSETALLNEZ_H; in emitVecCondBranchPseudo()
4332 case LoongArch::PseudoVBNZ_W: in emitVecCondBranchPseudo()
4333 CondOpc = LoongArch::VSETALLNEZ_W; in emitVecCondBranchPseudo()
4335 case LoongArch::PseudoVBNZ_D: in emitVecCondBranchPseudo()
4336 CondOpc = LoongArch::VSETALLNEZ_D; in emitVecCondBranchPseudo()
4338 case LoongArch::PseudoXVBZ: in emitVecCondBranchPseudo()
4339 CondOpc = LoongArch::XVSETEQZ_V; in emitVecCondBranchPseudo()
4341 case LoongArch::PseudoXVBZ_B: in emitVecCondBranchPseudo()
4342 CondOpc = LoongArch::XVSETANYEQZ_B; in emitVecCondBranchPseudo()
4344 case LoongArch::PseudoXVBZ_H: in emitVecCondBranchPseudo()
4345 CondOpc = LoongArch::XVSETANYEQZ_H; in emitVecCondBranchPseudo()
4347 case LoongArch::PseudoXVBZ_W: in emitVecCondBranchPseudo()
4348 CondOpc = LoongArch::XVSETANYEQZ_W; in emitVecCondBranchPseudo()
4350 case LoongArch::PseudoXVBZ_D: in emitVecCondBranchPseudo()
4351 CondOpc = LoongArch::XVSETANYEQZ_D; in emitVecCondBranchPseudo()
4353 case LoongArch::PseudoXVBNZ: in emitVecCondBranchPseudo()
4354 CondOpc = LoongArch::XVSETNEZ_V; in emitVecCondBranchPseudo()
4356 case LoongArch::PseudoXVBNZ_B: in emitVecCondBranchPseudo()
4357 CondOpc = LoongArch::XVSETALLNEZ_B; in emitVecCondBranchPseudo()
4359 case LoongArch::PseudoXVBNZ_H: in emitVecCondBranchPseudo()
4360 CondOpc = LoongArch::XVSETALLNEZ_H; in emitVecCondBranchPseudo()
4362 case LoongArch::PseudoXVBNZ_W: in emitVecCondBranchPseudo()
4363 CondOpc = LoongArch::XVSETALLNEZ_W; in emitVecCondBranchPseudo()
4365 case LoongArch::PseudoXVBNZ_D: in emitVecCondBranchPseudo()
4366 CondOpc = LoongArch::XVSETALLNEZ_D; in emitVecCondBranchPseudo()
4390 Register FCC = MRI.createVirtualRegister(&LoongArch::CFRRegClass); in emitVecCondBranchPseudo()
4394 BuildMI(BB, DL, TII->get(LoongArch::BCNEZ)).addReg(FCC).addMBB(TrueBB); in emitVecCondBranchPseudo()
4399 Register RD1 = MRI.createVirtualRegister(&LoongArch::GPRRegClass); in emitVecCondBranchPseudo()
4400 BuildMI(FalseBB, DL, TII->get(LoongArch::ADDI_W), RD1) in emitVecCondBranchPseudo()
4401 .addReg(LoongArch::R0) in emitVecCondBranchPseudo()
4403 BuildMI(FalseBB, DL, TII->get(LoongArch::PseudoBR)).addMBB(SinkBB); in emitVecCondBranchPseudo()
4407 Register RD2 = MRI.createVirtualRegister(&LoongArch::GPRRegClass); in emitVecCondBranchPseudo()
4408 BuildMI(TrueBB, DL, TII->get(LoongArch::ADDI_W), RD2) in emitVecCondBranchPseudo()
4409 .addReg(LoongArch::R0) in emitVecCondBranchPseudo()
4414 BuildMI(*SinkBB, SinkBB->begin(), DL, TII->get(LoongArch::PHI), in emitVecCondBranchPseudo()
4434 case LoongArch::PseudoXVINSGR2VR_B: in emitPseudoXVINSGR2VR()
4436 InsOp = LoongArch::VINSGR2VR_B; in emitPseudoXVINSGR2VR()
4438 case LoongArch::PseudoXVINSGR2VR_H: in emitPseudoXVINSGR2VR()
4440 InsOp = LoongArch::VINSGR2VR_H; in emitPseudoXVINSGR2VR()
4444 const TargetRegisterClass *RC = &LoongArch::LASX256RegClass; in emitPseudoXVINSGR2VR()
4445 const TargetRegisterClass *SubRC = &LoongArch::LSX128RegClass; in emitPseudoXVINSGR2VR()
4457 BuildMI(*BB, MI, DL, TII->get(LoongArch::XVPERMI_Q), ScratchReg1) in emitPseudoXVINSGR2VR()
4465 BuildMI(*BB, MI, DL, TII->get(LoongArch::COPY), ScratchSubReg1) in emitPseudoXVINSGR2VR()
4466 .addReg(ScratchReg1, 0, LoongArch::sub_128); in emitPseudoXVINSGR2VR()
4476 BuildMI(*BB, MI, DL, TII->get(LoongArch::SUBREG_TO_REG), ScratchReg2) in emitPseudoXVINSGR2VR()
4479 .addImm(LoongArch::sub_128); in emitPseudoXVINSGR2VR()
4482 BuildMI(*BB, MI, DL, TII->get(LoongArch::XVPERMI_Q), XDst) in emitPseudoXVINSGR2VR()
4499 case LoongArch::DIV_W: in EmitInstrWithCustomInserter()
4500 case LoongArch::DIV_WU: in EmitInstrWithCustomInserter()
4501 case LoongArch::MOD_W: in EmitInstrWithCustomInserter()
4502 case LoongArch::MOD_WU: in EmitInstrWithCustomInserter()
4503 case LoongArch::DIV_D: in EmitInstrWithCustomInserter()
4504 case LoongArch::DIV_DU: in EmitInstrWithCustomInserter()
4505 case LoongArch::MOD_D: in EmitInstrWithCustomInserter()
4506 case LoongArch::MOD_DU: in EmitInstrWithCustomInserter()
4509 case LoongArch::WRFCSR: { in EmitInstrWithCustomInserter()
4510 BuildMI(*BB, MI, DL, TII->get(LoongArch::MOVGR2FCSR), in EmitInstrWithCustomInserter()
4511 LoongArch::FCSR0 + MI.getOperand(0).getImm()) in EmitInstrWithCustomInserter()
4516 case LoongArch::RDFCSR: { in EmitInstrWithCustomInserter()
4518 BuildMI(*BB, MI, DL, TII->get(LoongArch::MOVFCSR2GR), in EmitInstrWithCustomInserter()
4520 .addReg(LoongArch::FCSR0 + MI.getOperand(1).getImm()); in EmitInstrWithCustomInserter()
4525 case LoongArch::PseudoVBZ: in EmitInstrWithCustomInserter()
4526 case LoongArch::PseudoVBZ_B: in EmitInstrWithCustomInserter()
4527 case LoongArch::PseudoVBZ_H: in EmitInstrWithCustomInserter()
4528 case LoongArch::PseudoVBZ_W: in EmitInstrWithCustomInserter()
4529 case LoongArch::PseudoVBZ_D: in EmitInstrWithCustomInserter()
4530 case LoongArch::PseudoVBNZ: in EmitInstrWithCustomInserter()
4531 case LoongArch::PseudoVBNZ_B: in EmitInstrWithCustomInserter()
4532 case LoongArch::PseudoVBNZ_H: in EmitInstrWithCustomInserter()
4533 case LoongArch::PseudoVBNZ_W: in EmitInstrWithCustomInserter()
4534 case LoongArch::PseudoVBNZ_D: in EmitInstrWithCustomInserter()
4535 case LoongArch::PseudoXVBZ: in EmitInstrWithCustomInserter()
4536 case LoongArch::PseudoXVBZ_B: in EmitInstrWithCustomInserter()
4537 case LoongArch::PseudoXVBZ_H: in EmitInstrWithCustomInserter()
4538 case LoongArch::PseudoXVBZ_W: in EmitInstrWithCustomInserter()
4539 case LoongArch::PseudoXVBZ_D: in EmitInstrWithCustomInserter()
4540 case LoongArch::PseudoXVBNZ: in EmitInstrWithCustomInserter()
4541 case LoongArch::PseudoXVBNZ_B: in EmitInstrWithCustomInserter()
4542 case LoongArch::PseudoXVBNZ_H: in EmitInstrWithCustomInserter()
4543 case LoongArch::PseudoXVBNZ_W: in EmitInstrWithCustomInserter()
4544 case LoongArch::PseudoXVBNZ_D: in EmitInstrWithCustomInserter()
4546 case LoongArch::PseudoXVINSGR2VR_B: in EmitInstrWithCustomInserter()
4547 case LoongArch::PseudoXVINSGR2VR_H: in EmitInstrWithCustomInserter()
4657 const MCPhysReg ArgGPRs[] = {LoongArch::R4, LoongArch::R5, LoongArch::R6,
4658 LoongArch::R7, LoongArch::R8, LoongArch::R9,
4659 LoongArch::R10, LoongArch::R11};
4662 const MCPhysReg ArgFPR32s[] = {LoongArch::F0, LoongArch::F1, LoongArch::F2,
4663 LoongArch::F3, LoongArch::F4, LoongArch::F5,
4664 LoongArch::F6, LoongArch::F7};
4667 LoongArch::F0_64, LoongArch::F1_64, LoongArch::F2_64, LoongArch::F3_64,
4668 LoongArch::F4_64, LoongArch::F5_64, LoongArch::F6_64, LoongArch::F7_64};
4670 const MCPhysReg ArgVRs[] = {LoongArch::VR0, LoongArch::VR1, LoongArch::VR2,
4671 LoongArch::VR3, LoongArch::VR4, LoongArch::VR5,
4672 LoongArch::VR6, LoongArch::VR7};
4674 const MCPhysReg ArgXRs[] = {LoongArch::XR0, LoongArch::XR1, LoongArch::XR2,
4675 LoongArch::XR3, LoongArch::XR4, LoongArch::XR5,
4676 LoongArch::XR6, LoongArch::XR7};
4715 // Implements the LoongArch calling convention. Returns true upon failure.
4764 // If this is a variadic argument, the LoongArch calling convention requires in CC_LoongArch()
5012 LoongArch::R23, LoongArch::R24, LoongArch::R25, in CC_LoongArch_GHC()
5013 LoongArch::R26, LoongArch::R27, LoongArch::R28, in CC_LoongArch_GHC()
5014 LoongArch::R29, LoongArch::R30, LoongArch::R31}; in CC_LoongArch_GHC()
5024 static const MCPhysReg FPR32List[] = {LoongArch::F24, LoongArch::F25, in CC_LoongArch_GHC()
5025 LoongArch::F26, LoongArch::F27}; in CC_LoongArch_GHC()
5035 static const MCPhysReg FPR64List[] = {LoongArch::F28_64, LoongArch::F29_64, in CC_LoongArch_GHC()
5036 LoongArch::F30_64, LoongArch::F31_64}; in CC_LoongArch_GHC()
5062 if (!MF.getSubtarget().hasFeature(LoongArch::FeatureBasicF) || in LowerFormalArguments()
5063 !MF.getSubtarget().hasFeature(LoongArch::FeatureBasicD)) in LowerFormalArguments()
5115 const TargetRegisterClass *RC = &LoongArch::GPRRegClass; in LowerFormalArguments()
5400 StackPtr = DAG.getCopyFromReg(Chain, DL, LoongArch::R3, PtrVT); in LowerCall()
5821 return LoongArch::R4; in getExceptionPointerRegister()
5826 return LoongArch::R5; in getExceptionSelectorRegister()
5830 // LoongArch Inline Assembly Support
5835 // LoongArch specific constraints in GCC: config/loongarch/constraints.md in getConstraintType()
5887 // First, see if this is a constraint that directly corresponds to a LoongArch in getRegForInlineAsmConstraint()
5895 return std::make_pair(0U, &LoongArch::GPRRegClass); in getRegForInlineAsmConstraint()
5898 return std::make_pair(0U, &LoongArch::FPR32RegClass); in getRegForInlineAsmConstraint()
5900 return std::make_pair(0U, &LoongArch::FPR64RegClass); in getRegForInlineAsmConstraint()
5902 TRI->isTypeLegalForClass(LoongArch::LSX128RegClass, VT)) in getRegForInlineAsmConstraint()
5903 return std::make_pair(0U, &LoongArch::LSX128RegClass); in getRegForInlineAsmConstraint()
5905 TRI->isTypeLegalForClass(LoongArch::LASX256RegClass, VT)) in getRegForInlineAsmConstraint()
5906 return std::make_pair(0U, &LoongArch::LASX256RegClass); in getRegForInlineAsmConstraint()
5922 // AFAIK, the not yet upstreamed `rustc` for LoongArch will always use in getRegForInlineAsmConstraint()
5934 if (LoongArch::F0 <= RegNo && RegNo <= LoongArch::F31) { in getRegForInlineAsmConstraint()
5936 unsigned DReg = RegNo - LoongArch::F0 + LoongArch::F0_64; in getRegForInlineAsmConstraint()
5937 return std::make_pair(DReg, &LoongArch::FPR64RegClass); in getRegForInlineAsmConstraint()
6003 if (Reg == LoongArch::NoRegister) in getRegisterByName()
6005 if (Reg == LoongArch::NoRegister) in getRegisterByName()
6066 // LoongArch has four basic addressing modes: in isLegalAddressingMode()