xref: /llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp (revision f7d8336a2fb4fad4a6efe5af9b0a10ddd970f6d3)
1 //=- LoongArchInstrInfo.cpp - LoongArch Instruction Information -*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the LoongArch implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "LoongArchInstrInfo.h"
14 #include "LoongArch.h"
15 #include "LoongArchMachineFunctionInfo.h"
16 #include "LoongArchRegisterInfo.h"
17 #include "MCTargetDesc/LoongArchMCTargetDesc.h"
18 #include "MCTargetDesc/LoongArchMatInt.h"
19 #include "llvm/CodeGen/RegisterScavenging.h"
20 #include "llvm/CodeGen/StackMaps.h"
21 #include "llvm/MC/MCInstBuilder.h"
22 
23 using namespace llvm;
24 
25 #define GET_INSTRINFO_CTOR_DTOR
26 #include "LoongArchGenInstrInfo.inc"
27 
28 LoongArchInstrInfo::LoongArchInstrInfo(LoongArchSubtarget &STI)
29     : LoongArchGenInstrInfo(LoongArch::ADJCALLSTACKDOWN,
30                             LoongArch::ADJCALLSTACKUP),
31       STI(STI) {}
32 
33 MCInst LoongArchInstrInfo::getNop() const {
34   return MCInstBuilder(LoongArch::ANDI)
35       .addReg(LoongArch::R0)
36       .addReg(LoongArch::R0)
37       .addImm(0);
38 }
39 
40 void LoongArchInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
41                                      MachineBasicBlock::iterator MBBI,
42                                      const DebugLoc &DL, MCRegister DstReg,
43                                      MCRegister SrcReg, bool KillSrc,
44                                      bool RenamableDest,
45                                      bool RenamableSrc) const {
46   if (LoongArch::GPRRegClass.contains(DstReg, SrcReg)) {
47     BuildMI(MBB, MBBI, DL, get(LoongArch::OR), DstReg)
48         .addReg(SrcReg, getKillRegState(KillSrc))
49         .addReg(LoongArch::R0);
50     return;
51   }
52 
53   // VR->VR copies.
54   if (LoongArch::LSX128RegClass.contains(DstReg, SrcReg)) {
55     BuildMI(MBB, MBBI, DL, get(LoongArch::VORI_B), DstReg)
56         .addReg(SrcReg, getKillRegState(KillSrc))
57         .addImm(0);
58     return;
59   }
60 
61   // XR->XR copies.
62   if (LoongArch::LASX256RegClass.contains(DstReg, SrcReg)) {
63     BuildMI(MBB, MBBI, DL, get(LoongArch::XVORI_B), DstReg)
64         .addReg(SrcReg, getKillRegState(KillSrc))
65         .addImm(0);
66     return;
67   }
68 
69   // GPR->CFR copy.
70   if (LoongArch::CFRRegClass.contains(DstReg) &&
71       LoongArch::GPRRegClass.contains(SrcReg)) {
72     BuildMI(MBB, MBBI, DL, get(LoongArch::MOVGR2CF), DstReg)
73         .addReg(SrcReg, getKillRegState(KillSrc));
74     return;
75   }
76   // CFR->GPR copy.
77   if (LoongArch::GPRRegClass.contains(DstReg) &&
78       LoongArch::CFRRegClass.contains(SrcReg)) {
79     BuildMI(MBB, MBBI, DL, get(LoongArch::MOVCF2GR), DstReg)
80         .addReg(SrcReg, getKillRegState(KillSrc));
81     return;
82   }
83   // CFR->CFR copy.
84   if (LoongArch::CFRRegClass.contains(DstReg, SrcReg)) {
85     BuildMI(MBB, MBBI, DL, get(LoongArch::PseudoCopyCFR), DstReg)
86         .addReg(SrcReg, getKillRegState(KillSrc));
87     return;
88   }
89 
90   // FPR->FPR copies.
91   unsigned Opc;
92   if (LoongArch::FPR32RegClass.contains(DstReg, SrcReg)) {
93     Opc = LoongArch::FMOV_S;
94   } else if (LoongArch::FPR64RegClass.contains(DstReg, SrcReg)) {
95     Opc = LoongArch::FMOV_D;
96   } else if (LoongArch::GPRRegClass.contains(DstReg) &&
97              LoongArch::FPR32RegClass.contains(SrcReg)) {
98     // FPR32 -> GPR copies
99     Opc = LoongArch::MOVFR2GR_S;
100   } else if (LoongArch::GPRRegClass.contains(DstReg) &&
101              LoongArch::FPR64RegClass.contains(SrcReg)) {
102     // FPR64 -> GPR copies
103     Opc = LoongArch::MOVFR2GR_D;
104   } else {
105     // TODO: support other copies.
106     llvm_unreachable("Impossible reg-to-reg copy");
107   }
108 
109   BuildMI(MBB, MBBI, DL, get(Opc), DstReg)
110       .addReg(SrcReg, getKillRegState(KillSrc));
111 }
112 
113 void LoongArchInstrInfo::storeRegToStackSlot(
114     MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Register SrcReg,
115     bool IsKill, int FI, const TargetRegisterClass *RC,
116     const TargetRegisterInfo *TRI, Register VReg,
117     MachineInstr::MIFlag Flags) const {
118   MachineFunction *MF = MBB.getParent();
119   MachineFrameInfo &MFI = MF->getFrameInfo();
120 
121   unsigned Opcode;
122   if (LoongArch::GPRRegClass.hasSubClassEq(RC))
123     Opcode = TRI->getRegSizeInBits(LoongArch::GPRRegClass) == 32
124                  ? LoongArch::ST_W
125                  : LoongArch::ST_D;
126   else if (LoongArch::FPR32RegClass.hasSubClassEq(RC))
127     Opcode = LoongArch::FST_S;
128   else if (LoongArch::FPR64RegClass.hasSubClassEq(RC))
129     Opcode = LoongArch::FST_D;
130   else if (LoongArch::LSX128RegClass.hasSubClassEq(RC))
131     Opcode = LoongArch::VST;
132   else if (LoongArch::LASX256RegClass.hasSubClassEq(RC))
133     Opcode = LoongArch::XVST;
134   else if (LoongArch::CFRRegClass.hasSubClassEq(RC))
135     Opcode = LoongArch::PseudoST_CFR;
136   else
137     llvm_unreachable("Can't store this register to stack slot");
138 
139   MachineMemOperand *MMO = MF->getMachineMemOperand(
140       MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore,
141       MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
142 
143   BuildMI(MBB, I, DebugLoc(), get(Opcode))
144       .addReg(SrcReg, getKillRegState(IsKill))
145       .addFrameIndex(FI)
146       .addImm(0)
147       .addMemOperand(MMO);
148 }
149 
150 void LoongArchInstrInfo::loadRegFromStackSlot(
151     MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Register DstReg,
152     int FI, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI,
153     Register VReg, MachineInstr::MIFlag Flags) const {
154   MachineFunction *MF = MBB.getParent();
155   MachineFrameInfo &MFI = MF->getFrameInfo();
156   DebugLoc DL;
157   if (I != MBB.end())
158     DL = I->getDebugLoc();
159 
160   unsigned Opcode;
161   if (LoongArch::GPRRegClass.hasSubClassEq(RC))
162     Opcode = TRI->getRegSizeInBits(LoongArch::GPRRegClass) == 32
163                  ? LoongArch::LD_W
164                  : LoongArch::LD_D;
165   else if (LoongArch::FPR32RegClass.hasSubClassEq(RC))
166     Opcode = LoongArch::FLD_S;
167   else if (LoongArch::FPR64RegClass.hasSubClassEq(RC))
168     Opcode = LoongArch::FLD_D;
169   else if (LoongArch::LSX128RegClass.hasSubClassEq(RC))
170     Opcode = LoongArch::VLD;
171   else if (LoongArch::LASX256RegClass.hasSubClassEq(RC))
172     Opcode = LoongArch::XVLD;
173   else if (LoongArch::CFRRegClass.hasSubClassEq(RC))
174     Opcode = LoongArch::PseudoLD_CFR;
175   else
176     llvm_unreachable("Can't load this register from stack slot");
177 
178   MachineMemOperand *MMO = MF->getMachineMemOperand(
179       MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad,
180       MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
181 
182   BuildMI(MBB, I, DL, get(Opcode), DstReg)
183       .addFrameIndex(FI)
184       .addImm(0)
185       .addMemOperand(MMO);
186 }
187 
188 void LoongArchInstrInfo::movImm(MachineBasicBlock &MBB,
189                                 MachineBasicBlock::iterator MBBI,
190                                 const DebugLoc &DL, Register DstReg,
191                                 uint64_t Val, MachineInstr::MIFlag Flag) const {
192   Register SrcReg = LoongArch::R0;
193 
194   if (!STI.is64Bit() && !isInt<32>(Val))
195     report_fatal_error("Should only materialize 32-bit constants for LA32");
196 
197   auto Seq = LoongArchMatInt::generateInstSeq(Val);
198   assert(!Seq.empty());
199 
200   for (auto &Inst : Seq) {
201     switch (Inst.Opc) {
202     case LoongArch::LU12I_W:
203       BuildMI(MBB, MBBI, DL, get(Inst.Opc), DstReg)
204           .addImm(Inst.Imm)
205           .setMIFlag(Flag);
206       break;
207     case LoongArch::ADDI_W:
208     case LoongArch::ORI:
209     case LoongArch::LU32I_D: // "rj" is needed due to InstrInfo pattern
210     case LoongArch::LU52I_D:
211       BuildMI(MBB, MBBI, DL, get(Inst.Opc), DstReg)
212           .addReg(SrcReg, RegState::Kill)
213           .addImm(Inst.Imm)
214           .setMIFlag(Flag);
215       break;
216     case LoongArch::BSTRINS_D:
217       BuildMI(MBB, MBBI, DL, get(Inst.Opc), DstReg)
218           .addReg(SrcReg, RegState::Kill)
219           .addReg(SrcReg, RegState::Kill)
220           .addImm(Inst.Imm >> 32)
221           .addImm(Inst.Imm & 0xFF)
222           .setMIFlag(Flag);
223       break;
224     default:
225       assert(false && "Unknown insn emitted by LoongArchMatInt");
226     }
227 
228     // Only the first instruction has $zero as its source.
229     SrcReg = DstReg;
230   }
231 }
232 
233 unsigned LoongArchInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
234   unsigned Opcode = MI.getOpcode();
235 
236   if (Opcode == TargetOpcode::INLINEASM ||
237       Opcode == TargetOpcode::INLINEASM_BR) {
238     const MachineFunction *MF = MI.getParent()->getParent();
239     const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo();
240     return getInlineAsmLength(MI.getOperand(0).getSymbolName(), *MAI);
241   }
242 
243   unsigned NumBytes = 0;
244   const MCInstrDesc &Desc = MI.getDesc();
245 
246   // Size should be preferably set in
247   // llvm/lib/Target/LoongArch/LoongArch*InstrInfo.td (default case).
248   // Specific cases handle instructions of variable sizes.
249   switch (Desc.getOpcode()) {
250   default:
251     return Desc.getSize();
252   case TargetOpcode::STATEPOINT:
253     NumBytes = StatepointOpers(&MI).getNumPatchBytes();
254     assert(NumBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
255     // No patch bytes means a normal call inst (i.e. `bl`) is emitted.
256     if (NumBytes == 0)
257       NumBytes = 4;
258     break;
259   }
260   return NumBytes;
261 }
262 
263 bool LoongArchInstrInfo::isAsCheapAsAMove(const MachineInstr &MI) const {
264   const unsigned Opcode = MI.getOpcode();
265   switch (Opcode) {
266   default:
267     break;
268   case LoongArch::ADDI_D:
269   case LoongArch::ORI:
270   case LoongArch::XORI:
271     return (MI.getOperand(1).isReg() &&
272             MI.getOperand(1).getReg() == LoongArch::R0) ||
273            (MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0);
274   }
275   return MI.isAsCheapAsAMove();
276 }
277 
278 MachineBasicBlock *
279 LoongArchInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
280   assert(MI.getDesc().isBranch() && "Unexpected opcode!");
281   // The branch target is always the last operand.
282   return MI.getOperand(MI.getNumExplicitOperands() - 1).getMBB();
283 }
284 
285 static void parseCondBranch(MachineInstr &LastInst, MachineBasicBlock *&Target,
286                             SmallVectorImpl<MachineOperand> &Cond) {
287   // Block ends with fall-through condbranch.
288   assert(LastInst.getDesc().isConditionalBranch() &&
289          "Unknown conditional branch");
290   int NumOp = LastInst.getNumExplicitOperands();
291   Target = LastInst.getOperand(NumOp - 1).getMBB();
292 
293   Cond.push_back(MachineOperand::CreateImm(LastInst.getOpcode()));
294   for (int i = 0; i < NumOp - 1; i++)
295     Cond.push_back(LastInst.getOperand(i));
296 }
297 
298 bool LoongArchInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
299                                        MachineBasicBlock *&TBB,
300                                        MachineBasicBlock *&FBB,
301                                        SmallVectorImpl<MachineOperand> &Cond,
302                                        bool AllowModify) const {
303   TBB = FBB = nullptr;
304   Cond.clear();
305 
306   // If the block has no terminators, it just falls into the block after it.
307   MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
308   if (I == MBB.end() || !isUnpredicatedTerminator(*I))
309     return false;
310 
311   // Count the number of terminators and find the first unconditional or
312   // indirect branch.
313   MachineBasicBlock::iterator FirstUncondOrIndirectBr = MBB.end();
314   int NumTerminators = 0;
315   for (auto J = I.getReverse(); J != MBB.rend() && isUnpredicatedTerminator(*J);
316        J++) {
317     NumTerminators++;
318     if (J->getDesc().isUnconditionalBranch() ||
319         J->getDesc().isIndirectBranch()) {
320       FirstUncondOrIndirectBr = J.getReverse();
321     }
322   }
323 
324   // If AllowModify is true, we can erase any terminators after
325   // FirstUncondOrIndirectBR.
326   if (AllowModify && FirstUncondOrIndirectBr != MBB.end()) {
327     while (std::next(FirstUncondOrIndirectBr) != MBB.end()) {
328       std::next(FirstUncondOrIndirectBr)->eraseFromParent();
329       NumTerminators--;
330     }
331     I = FirstUncondOrIndirectBr;
332   }
333 
334   // Handle a single unconditional branch.
335   if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) {
336     TBB = getBranchDestBlock(*I);
337     return false;
338   }
339 
340   // Handle a single conditional branch.
341   if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) {
342     parseCondBranch(*I, TBB, Cond);
343     return false;
344   }
345 
346   // Handle a conditional branch followed by an unconditional branch.
347   if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() &&
348       I->getDesc().isUnconditionalBranch()) {
349     parseCondBranch(*std::prev(I), TBB, Cond);
350     FBB = getBranchDestBlock(*I);
351     return false;
352   }
353 
354   // Otherwise, we can't handle this.
355   return true;
356 }
357 
358 bool LoongArchInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
359                                                int64_t BrOffset) const {
360   switch (BranchOp) {
361   default:
362     llvm_unreachable("Unknown branch instruction!");
363   case LoongArch::BEQ:
364   case LoongArch::BNE:
365   case LoongArch::BLT:
366   case LoongArch::BGE:
367   case LoongArch::BLTU:
368   case LoongArch::BGEU:
369     return isInt<18>(BrOffset);
370   case LoongArch::BEQZ:
371   case LoongArch::BNEZ:
372   case LoongArch::BCEQZ:
373   case LoongArch::BCNEZ:
374     return isInt<23>(BrOffset);
375   case LoongArch::B:
376   case LoongArch::PseudoBR:
377     return isInt<28>(BrOffset);
378   }
379 }
380 
381 bool LoongArchInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
382                                               const MachineBasicBlock *MBB,
383                                               const MachineFunction &MF) const {
384   if (TargetInstrInfo::isSchedulingBoundary(MI, MBB, MF))
385     return true;
386 
387   auto MII = MI.getIterator();
388   auto MIE = MBB->end();
389 
390   // According to psABI v2.30:
391   //
392   // https://github.com/loongson/la-abi-specs/releases/tag/v2.30
393   //
394   // The following instruction patterns are prohibited from being reordered:
395   //
396   // * pcalau12i $a0, %pc_hi20(s)
397   //   addi.d $a1, $zero, %pc_lo12(s)
398   //   lu32i.d $a1, %pc64_lo20(s)
399   //   lu52i.d $a1, $a1, %pc64_hi12(s)
400   //
401   // * pcalau12i $a0, %got_pc_hi20(s) | %ld_pc_hi20(s) | %gd_pc_hi20(s)
402   //   addi.d $a1, $zero, %got_pc_lo12(s)
403   //   lu32i.d $a1, %got64_pc_lo20(s)
404   //   lu52i.d $a1, $a1, %got64_pc_hi12(s)
405   //
406   // * pcalau12i $a0, %ie_pc_hi20(s)
407   //   addi.d $a1, $zero, %ie_pc_lo12(s)
408   //   lu32i.d $a1, %ie64_pc_lo20(s)
409   //   lu52i.d $a1, $a1, %ie64_pc_hi12(s)
410   //
411   // * pcalau12i $a0, %desc_pc_hi20(s)
412   //   addi.d $a1, $zero, %desc_pc_lo12(s)
413   //   lu32i.d $a1, %desc64_pc_lo20(s)
414   //   lu52i.d $a1, $a1, %desc64_pc_hi12(s)
415   //
416   // For simplicity, only pcalau12i and lu52i.d are marked as scheduling
417   // boundaries, and the instructions between them are guaranteed to be
418   // ordered according to data dependencies.
419   switch (MI.getOpcode()) {
420   case LoongArch::PCALAU12I: {
421     auto AddI = std::next(MII);
422     if (AddI == MIE || AddI->getOpcode() != LoongArch::ADDI_D)
423       break;
424     auto Lu32I = std::next(AddI);
425     if (Lu32I == MIE || Lu32I->getOpcode() != LoongArch::LU32I_D)
426       break;
427     auto MO0 = MI.getOperand(1).getTargetFlags();
428     auto MO1 = AddI->getOperand(2).getTargetFlags();
429     auto MO2 = Lu32I->getOperand(2).getTargetFlags();
430     if (MO0 == LoongArchII::MO_PCREL_HI && MO1 == LoongArchII::MO_PCREL_LO &&
431         MO2 == LoongArchII::MO_PCREL64_LO)
432       return true;
433     if ((MO0 == LoongArchII::MO_GOT_PC_HI || MO0 == LoongArchII::MO_LD_PC_HI ||
434          MO0 == LoongArchII::MO_GD_PC_HI) &&
435         MO1 == LoongArchII::MO_GOT_PC_LO && MO2 == LoongArchII::MO_GOT_PC64_LO)
436       return true;
437     if (MO0 == LoongArchII::MO_IE_PC_HI && MO1 == LoongArchII::MO_IE_PC_LO &&
438         MO2 == LoongArchII::MO_IE_PC64_LO)
439       return true;
440     if (MO0 == LoongArchII::MO_DESC_PC_HI &&
441         MO1 == LoongArchII::MO_DESC_PC_LO &&
442         MO2 == LoongArchII::MO_DESC64_PC_LO)
443       return true;
444     break;
445   }
446   case LoongArch::LU52I_D: {
447     auto MO = MI.getOperand(2).getTargetFlags();
448     if (MO == LoongArchII::MO_PCREL64_HI || MO == LoongArchII::MO_GOT_PC64_HI ||
449         MO == LoongArchII::MO_IE_PC64_HI || MO == LoongArchII::MO_DESC64_PC_HI)
450       return true;
451     break;
452   }
453   default:
454     break;
455   }
456 
457   const auto &STI = MF.getSubtarget<LoongArchSubtarget>();
458   if (STI.hasFeature(LoongArch::FeatureRelax)) {
459     // When linker relaxation enabled, the following instruction patterns are
460     // prohibited from being reordered:
461     //
462     // * pcalau12i $a0, %pc_hi20(s)
463     //   addi.w/d $a0, $a0, %pc_lo12(s)
464     //
465     // * pcalau12i $a0, %got_pc_hi20(s)
466     //   ld.w/d $a0, $a0, %got_pc_lo12(s)
467     //
468     // * pcalau12i $a0, %ld_pc_hi20(s) | %gd_pc_hi20(s)
469     //   addi.w/d $a0, $a0, %got_pc_lo12(s)
470     //
471     // * pcalau12i $a0, %desc_pc_hi20(s)
472     //   addi.w/d  $a0, $a0, %desc_pc_lo12(s)
473     //   ld.w/d    $ra, $a0, %desc_ld(s)
474     //   jirl      $ra, $ra, %desc_call(s)
475     unsigned AddiOp = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
476     unsigned LdOp = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
477     switch (MI.getOpcode()) {
478     case LoongArch::PCALAU12I: {
479       auto MO0 = LoongArchII::getDirectFlags(MI.getOperand(1));
480       auto SecondOp = std::next(MII);
481       if (MO0 == LoongArchII::MO_DESC_PC_HI) {
482         if (SecondOp == MIE || SecondOp->getOpcode() != AddiOp)
483           break;
484         auto Ld = std::next(SecondOp);
485         if (Ld == MIE || Ld->getOpcode() != LdOp)
486           break;
487         auto MO1 = LoongArchII::getDirectFlags(SecondOp->getOperand(2));
488         auto MO2 = LoongArchII::getDirectFlags(Ld->getOperand(2));
489         if (MO1 == LoongArchII::MO_DESC_PC_LO && MO2 == LoongArchII::MO_DESC_LD)
490           return true;
491         break;
492       }
493       if (SecondOp == MIE ||
494           (SecondOp->getOpcode() != AddiOp && SecondOp->getOpcode() != LdOp))
495         break;
496       auto MO1 = LoongArchII::getDirectFlags(SecondOp->getOperand(2));
497       if (MO0 == LoongArchII::MO_PCREL_HI && SecondOp->getOpcode() == AddiOp &&
498           MO1 == LoongArchII::MO_PCREL_LO)
499         return true;
500       if (MO0 == LoongArchII::MO_GOT_PC_HI && SecondOp->getOpcode() == LdOp &&
501           MO1 == LoongArchII::MO_GOT_PC_LO)
502         return true;
503       if ((MO0 == LoongArchII::MO_LD_PC_HI ||
504            MO0 == LoongArchII::MO_GD_PC_HI) &&
505           SecondOp->getOpcode() == AddiOp && MO1 == LoongArchII::MO_GOT_PC_LO)
506         return true;
507       break;
508     }
509     case LoongArch::ADDI_W:
510     case LoongArch::ADDI_D: {
511       auto MO = LoongArchII::getDirectFlags(MI.getOperand(2));
512       if (MO == LoongArchII::MO_PCREL_LO || MO == LoongArchII::MO_GOT_PC_LO)
513         return true;
514       break;
515     }
516     case LoongArch::LD_W:
517     case LoongArch::LD_D: {
518       auto MO = LoongArchII::getDirectFlags(MI.getOperand(2));
519       if (MO == LoongArchII::MO_GOT_PC_LO)
520         return true;
521       break;
522     }
523     case LoongArch::PseudoDESC_CALL: {
524       auto MO = LoongArchII::getDirectFlags(MI.getOperand(2));
525       if (MO == LoongArchII::MO_DESC_CALL)
526         return true;
527       break;
528     }
529     default:
530       break;
531     }
532   }
533 
534   return false;
535 }
536 
537 unsigned LoongArchInstrInfo::removeBranch(MachineBasicBlock &MBB,
538                                           int *BytesRemoved) const {
539   if (BytesRemoved)
540     *BytesRemoved = 0;
541   MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
542   if (I == MBB.end())
543     return 0;
544 
545   if (!I->getDesc().isBranch())
546     return 0;
547 
548   // Remove the branch.
549   if (BytesRemoved)
550     *BytesRemoved += getInstSizeInBytes(*I);
551   I->eraseFromParent();
552 
553   I = MBB.end();
554 
555   if (I == MBB.begin())
556     return 1;
557   --I;
558   if (!I->getDesc().isConditionalBranch())
559     return 1;
560 
561   // Remove the branch.
562   if (BytesRemoved)
563     *BytesRemoved += getInstSizeInBytes(*I);
564   I->eraseFromParent();
565   return 2;
566 }
567 
568 // Inserts a branch into the end of the specific MachineBasicBlock, returning
569 // the number of instructions inserted.
570 unsigned LoongArchInstrInfo::insertBranch(
571     MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
572     ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
573   if (BytesAdded)
574     *BytesAdded = 0;
575 
576   // Shouldn't be a fall through.
577   assert(TBB && "insertBranch must not be told to insert a fallthrough");
578   assert(Cond.size() <= 3 && Cond.size() != 1 &&
579          "LoongArch branch conditions have at most two components!");
580 
581   // Unconditional branch.
582   if (Cond.empty()) {
583     MachineInstr &MI = *BuildMI(&MBB, DL, get(LoongArch::PseudoBR)).addMBB(TBB);
584     if (BytesAdded)
585       *BytesAdded += getInstSizeInBytes(MI);
586     return 1;
587   }
588 
589   // Either a one or two-way conditional branch.
590   MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(Cond[0].getImm()));
591   for (unsigned i = 1; i < Cond.size(); ++i)
592     MIB.add(Cond[i]);
593   MIB.addMBB(TBB);
594   if (BytesAdded)
595     *BytesAdded += getInstSizeInBytes(*MIB);
596 
597   // One-way conditional branch.
598   if (!FBB)
599     return 1;
600 
601   // Two-way conditional branch.
602   MachineInstr &MI = *BuildMI(&MBB, DL, get(LoongArch::PseudoBR)).addMBB(FBB);
603   if (BytesAdded)
604     *BytesAdded += getInstSizeInBytes(MI);
605   return 2;
606 }
607 
608 void LoongArchInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
609                                               MachineBasicBlock &DestBB,
610                                               MachineBasicBlock &RestoreBB,
611                                               const DebugLoc &DL,
612                                               int64_t BrOffset,
613                                               RegScavenger *RS) const {
614   assert(RS && "RegScavenger required for long branching");
615   assert(MBB.empty() &&
616          "new block should be inserted for expanding unconditional branch");
617   assert(MBB.pred_size() == 1);
618 
619   MachineFunction *MF = MBB.getParent();
620   MachineRegisterInfo &MRI = MF->getRegInfo();
621   const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
622   LoongArchMachineFunctionInfo *LAFI =
623       MF->getInfo<LoongArchMachineFunctionInfo>();
624 
625   if (!isInt<32>(BrOffset))
626     report_fatal_error(
627         "Branch offsets outside of the signed 32-bit range not supported");
628 
629   Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass);
630   auto II = MBB.end();
631 
632   MachineInstr &PCALAU12I =
633       *BuildMI(MBB, II, DL, get(LoongArch::PCALAU12I), ScratchReg)
634            .addMBB(&DestBB, LoongArchII::MO_PCREL_HI);
635   MachineInstr &ADDI =
636       *BuildMI(MBB, II, DL,
637                get(STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W),
638                ScratchReg)
639            .addReg(ScratchReg)
640            .addMBB(&DestBB, LoongArchII::MO_PCREL_LO);
641   BuildMI(MBB, II, DL, get(LoongArch::PseudoBRIND))
642       .addReg(ScratchReg, RegState::Kill)
643       .addImm(0);
644 
645   RS->enterBasicBlockEnd(MBB);
646   Register Scav = RS->scavengeRegisterBackwards(
647       LoongArch::GPRRegClass, PCALAU12I.getIterator(), /*RestoreAfter=*/false,
648       /*SPAdj=*/0, /*AllowSpill=*/false);
649   if (Scav != LoongArch::NoRegister)
650     RS->setRegUsed(Scav);
651   else {
652     // When there is no scavenged register, it needs to specify a register.
653     // Specify t8 register because it won't be used too often.
654     Scav = LoongArch::R20;
655     int FrameIndex = LAFI->getBranchRelaxationSpillFrameIndex();
656     if (FrameIndex == -1)
657       report_fatal_error("The function size is incorrectly estimated.");
658     storeRegToStackSlot(MBB, PCALAU12I, Scav, /*IsKill=*/true, FrameIndex,
659                         &LoongArch::GPRRegClass, TRI, Register());
660     TRI->eliminateFrameIndex(std::prev(PCALAU12I.getIterator()),
661                              /*SpAdj=*/0, /*FIOperandNum=*/1);
662     PCALAU12I.getOperand(1).setMBB(&RestoreBB);
663     ADDI.getOperand(2).setMBB(&RestoreBB);
664     loadRegFromStackSlot(RestoreBB, RestoreBB.end(), Scav, FrameIndex,
665                          &LoongArch::GPRRegClass, TRI, Register());
666     TRI->eliminateFrameIndex(RestoreBB.back(),
667                              /*SpAdj=*/0, /*FIOperandNum=*/1);
668   }
669   MRI.replaceRegWith(ScratchReg, Scav);
670   MRI.clearVirtRegs();
671 }
672 
673 static unsigned getOppositeBranchOpc(unsigned Opc) {
674   switch (Opc) {
675   default:
676     llvm_unreachable("Unrecognized conditional branch");
677   case LoongArch::BEQ:
678     return LoongArch::BNE;
679   case LoongArch::BNE:
680     return LoongArch::BEQ;
681   case LoongArch::BEQZ:
682     return LoongArch::BNEZ;
683   case LoongArch::BNEZ:
684     return LoongArch::BEQZ;
685   case LoongArch::BCEQZ:
686     return LoongArch::BCNEZ;
687   case LoongArch::BCNEZ:
688     return LoongArch::BCEQZ;
689   case LoongArch::BLT:
690     return LoongArch::BGE;
691   case LoongArch::BGE:
692     return LoongArch::BLT;
693   case LoongArch::BLTU:
694     return LoongArch::BGEU;
695   case LoongArch::BGEU:
696     return LoongArch::BLTU;
697   }
698 }
699 
700 bool LoongArchInstrInfo::reverseBranchCondition(
701     SmallVectorImpl<MachineOperand> &Cond) const {
702   assert((Cond.size() && Cond.size() <= 3) && "Invalid branch condition!");
703   Cond[0].setImm(getOppositeBranchOpc(Cond[0].getImm()));
704   return false;
705 }
706 
707 std::pair<unsigned, unsigned>
708 LoongArchInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
709   const unsigned Mask = LoongArchII::MO_DIRECT_FLAG_MASK;
710   return std::make_pair(TF & Mask, TF & ~Mask);
711 }
712 
713 ArrayRef<std::pair<unsigned, const char *>>
714 LoongArchInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
715   using namespace LoongArchII;
716   // TODO: Add more target flags.
717   static const std::pair<unsigned, const char *> TargetFlags[] = {
718       {MO_CALL, "loongarch-call"},
719       {MO_CALL_PLT, "loongarch-call-plt"},
720       {MO_PCREL_HI, "loongarch-pcrel-hi"},
721       {MO_PCREL_LO, "loongarch-pcrel-lo"},
722       {MO_PCREL64_LO, "loongarch-pcrel64-lo"},
723       {MO_PCREL64_HI, "loongarch-pcrel64-hi"},
724       {MO_GOT_PC_HI, "loongarch-got-pc-hi"},
725       {MO_GOT_PC_LO, "loongarch-got-pc-lo"},
726       {MO_GOT_PC64_LO, "loongarch-got-pc64-lo"},
727       {MO_GOT_PC64_HI, "loongarch-got-pc64-hi"},
728       {MO_LE_HI, "loongarch-le-hi"},
729       {MO_LE_LO, "loongarch-le-lo"},
730       {MO_LE64_LO, "loongarch-le64-lo"},
731       {MO_LE64_HI, "loongarch-le64-hi"},
732       {MO_IE_PC_HI, "loongarch-ie-pc-hi"},
733       {MO_IE_PC_LO, "loongarch-ie-pc-lo"},
734       {MO_IE_PC64_LO, "loongarch-ie-pc64-lo"},
735       {MO_IE_PC64_HI, "loongarch-ie-pc64-hi"},
736       {MO_LD_PC_HI, "loongarch-ld-pc-hi"},
737       {MO_GD_PC_HI, "loongarch-gd-pc-hi"},
738       {MO_CALL36, "loongarch-call36"},
739       {MO_DESC_PC_HI, "loongarch-desc-pc-hi"},
740       {MO_DESC_PC_LO, "loongarch-desc-pc-lo"},
741       {MO_DESC64_PC_LO, "loongarch-desc64-pc-lo"},
742       {MO_DESC64_PC_HI, "loongarch-desc64-pc-hi"},
743       {MO_DESC_LD, "loongarch-desc-ld"},
744       {MO_DESC_CALL, "loongarch-desc-call"},
745       {MO_LE_HI_R, "loongarch-le-hi-r"},
746       {MO_LE_ADD_R, "loongarch-le-add-r"},
747       {MO_LE_LO_R, "loongarch-le-lo-r"}};
748   return ArrayRef(TargetFlags);
749 }
750 
751 ArrayRef<std::pair<unsigned, const char *>>
752 LoongArchInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
753   using namespace LoongArchII;
754   static const std::pair<unsigned, const char *> TargetFlags[] = {
755       {MO_RELAX, "loongarch-relax"}};
756   return ArrayRef(TargetFlags);
757 }
758 
759 // Returns true if this is the sext.w pattern, addi.w rd, rs, 0.
760 bool LoongArch::isSEXT_W(const MachineInstr &MI) {
761   return MI.getOpcode() == LoongArch::ADDI_W && MI.getOperand(1).isReg() &&
762          MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0;
763 }
764