xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/GISel/PPCInstructionSelector.cpp (revision 7ef62cebc2f965b0f640263e179276928885e33d)
1 //===- PPCInstructionSelector.cpp --------------------------------*- 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 /// \file
9 /// This file implements the targeting of the InstructionSelector class for
10 /// PowerPC.
11 //===----------------------------------------------------------------------===//
12 
13 #include "PPC.h"
14 #include "PPCInstrInfo.h"
15 #include "PPCRegisterBankInfo.h"
16 #include "PPCSubtarget.h"
17 #include "PPCTargetMachine.h"
18 #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
19 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
20 #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
21 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
22 #include "llvm/CodeGen/MachineConstantPool.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/IR/IntrinsicsPowerPC.h"
25 #include "llvm/Support/Debug.h"
26 
27 #define DEBUG_TYPE "ppc-gisel"
28 
29 using namespace llvm;
30 
31 namespace {
32 
33 #define GET_GLOBALISEL_PREDICATE_BITSET
34 #include "PPCGenGlobalISel.inc"
35 #undef GET_GLOBALISEL_PREDICATE_BITSET
36 
37 class PPCInstructionSelector : public InstructionSelector {
38 public:
39   PPCInstructionSelector(const PPCTargetMachine &TM, const PPCSubtarget &STI,
40                          const PPCRegisterBankInfo &RBI);
41 
42   bool select(MachineInstr &I) override;
43   static const char *getName() { return DEBUG_TYPE; }
44 
45 private:
46   /// tblgen generated 'select' implementation that is used as the initial
47   /// selector for the patterns that do not require complex C++.
48   bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
49 
50   bool selectFPToInt(MachineInstr &I, MachineBasicBlock &MBB,
51                   MachineRegisterInfo &MRI) const;
52   bool selectIntToFP(MachineInstr &I, MachineBasicBlock &MBB,
53                   MachineRegisterInfo &MRI) const;
54 
55   bool selectZExt(MachineInstr &I, MachineBasicBlock &MBB,
56                   MachineRegisterInfo &MRI) const;
57 
58   std::optional<bool> selectI64ImmDirect(MachineInstr &I,
59                                          MachineBasicBlock &MBB,
60                                          MachineRegisterInfo &MRI, Register Reg,
61                                          uint64_t Imm) const;
62   bool selectI64Imm(MachineInstr &I, MachineBasicBlock &MBB,
63                     MachineRegisterInfo &MRI) const;
64 
65   const PPCSubtarget &STI;
66   const PPCInstrInfo &TII;
67   const PPCRegisterInfo &TRI;
68   const PPCRegisterBankInfo &RBI;
69 
70 #define GET_GLOBALISEL_PREDICATES_DECL
71 #include "PPCGenGlobalISel.inc"
72 #undef GET_GLOBALISEL_PREDICATES_DECL
73 
74 #define GET_GLOBALISEL_TEMPORARIES_DECL
75 #include "PPCGenGlobalISel.inc"
76 #undef GET_GLOBALISEL_TEMPORARIES_DECL
77 };
78 
79 } // end anonymous namespace
80 
81 #define GET_GLOBALISEL_IMPL
82 #include "PPCGenGlobalISel.inc"
83 #undef GET_GLOBALISEL_IMPL
84 
85 PPCInstructionSelector::PPCInstructionSelector(const PPCTargetMachine &TM,
86                                                const PPCSubtarget &STI,
87                                                const PPCRegisterBankInfo &RBI)
88     : STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI),
89 #define GET_GLOBALISEL_PREDICATES_INIT
90 #include "PPCGenGlobalISel.inc"
91 #undef GET_GLOBALISEL_PREDICATES_INIT
92 #define GET_GLOBALISEL_TEMPORARIES_INIT
93 #include "PPCGenGlobalISel.inc"
94 #undef GET_GLOBALISEL_TEMPORARIES_INIT
95 {
96 }
97 
98 static const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank *RB) {
99   if (RB->getID() == PPC::GPRRegBankID) {
100     if (Ty.getSizeInBits() == 64)
101       return &PPC::G8RCRegClass;
102     if (Ty.getSizeInBits() <= 32)
103       return &PPC::GPRCRegClass;
104   }
105   if (RB->getID() == PPC::FPRRegBankID) {
106     if (Ty.getSizeInBits() == 32)
107       return &PPC::F4RCRegClass;
108     if (Ty.getSizeInBits() == 64)
109       return &PPC::F8RCRegClass;
110   }
111   if (RB->getID() == PPC::CRRegBankID) {
112     if (Ty.getSizeInBits() == 1)
113       return &PPC::CRBITRCRegClass;
114     if (Ty.getSizeInBits() == 4)
115       return &PPC::CRRCRegClass;
116   }
117 
118   llvm_unreachable("Unknown RegBank!");
119 }
120 
121 static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
122                        MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
123                        const RegisterBankInfo &RBI) {
124   Register DstReg = I.getOperand(0).getReg();
125 
126   if (DstReg.isPhysical())
127     return true;
128 
129   const RegisterBank *DstRegBank = RBI.getRegBank(DstReg, MRI, TRI);
130   const TargetRegisterClass *DstRC =
131       getRegClass(MRI.getType(DstReg), DstRegBank);
132 
133   // No need to constrain SrcReg. It will get constrained when we hit another of
134   // its use or its defs.
135   // Copies do not have constraints.
136   if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
137     LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
138                       << " operand\n");
139     return false;
140   }
141 
142   return true;
143 }
144 
145 static unsigned selectLoadStoreOp(unsigned GenericOpc, unsigned RegBankID,
146                                   unsigned OpSize) {
147   const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
148   switch (RegBankID) {
149   case PPC::GPRRegBankID:
150     switch (OpSize) {
151     case 32:
152       return IsStore ? PPC::STW : PPC::LWZ;
153     case 64:
154       return IsStore ? PPC::STD : PPC::LD;
155     default:
156       llvm_unreachable("Unexpected size!");
157     }
158     break;
159   case PPC::FPRRegBankID:
160     switch (OpSize) {
161     case 32:
162       return IsStore ? PPC::STFS : PPC::LFS;
163     case 64:
164       return IsStore ? PPC::STFD : PPC::LFD;
165     default:
166       llvm_unreachable("Unexpected size!");
167     }
168     break;
169   default:
170     llvm_unreachable("Unexpected register bank!");
171   }
172   return GenericOpc;
173 }
174 
175 bool PPCInstructionSelector::selectIntToFP(MachineInstr &I,
176                                            MachineBasicBlock &MBB,
177                                            MachineRegisterInfo &MRI) const {
178   if (!STI.hasDirectMove() || !STI.isPPC64() || !STI.hasFPCVT())
179     return false;
180 
181   const DebugLoc &DbgLoc = I.getDebugLoc();
182   const Register DstReg = I.getOperand(0).getReg();
183   const Register SrcReg = I.getOperand(1).getReg();
184 
185   Register MoveReg = MRI.createVirtualRegister(&PPC::VSFRCRegClass);
186 
187   // For now, only handle the case for 64 bit integer.
188   BuildMI(MBB, I, DbgLoc, TII.get(PPC::MTVSRD), MoveReg).addReg(SrcReg);
189 
190   bool IsSingle = MRI.getType(DstReg).getSizeInBits() == 32;
191   bool IsSigned = I.getOpcode() == TargetOpcode::G_SITOFP;
192   unsigned ConvOp = IsSingle ? (IsSigned ? PPC::XSCVSXDSP : PPC::XSCVUXDSP)
193                              : (IsSigned ? PPC::XSCVSXDDP : PPC::XSCVUXDDP);
194 
195   MachineInstr *MI =
196       BuildMI(MBB, I, DbgLoc, TII.get(ConvOp), DstReg).addReg(MoveReg);
197 
198   I.eraseFromParent();
199   return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
200 }
201 
202 bool PPCInstructionSelector::selectFPToInt(MachineInstr &I,
203                                            MachineBasicBlock &MBB,
204                                            MachineRegisterInfo &MRI) const {
205   if (!STI.hasDirectMove() || !STI.isPPC64() || !STI.hasFPCVT())
206     return false;
207 
208   const DebugLoc &DbgLoc = I.getDebugLoc();
209   const Register DstReg = I.getOperand(0).getReg();
210   const Register SrcReg = I.getOperand(1).getReg();
211 
212   Register CopyReg = MRI.createVirtualRegister(&PPC::VSFRCRegClass);
213   BuildMI(MBB, I, DbgLoc, TII.get(TargetOpcode::COPY), CopyReg).addReg(SrcReg);
214 
215   Register ConvReg = MRI.createVirtualRegister(&PPC::VSFRCRegClass);
216 
217   bool IsSigned = I.getOpcode() == TargetOpcode::G_FPTOSI;
218 
219   // single-precision is stored as double-precision on PPC in registers, so
220   // always use double-precision convertions.
221   unsigned ConvOp = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
222 
223   BuildMI(MBB, I, DbgLoc, TII.get(ConvOp), ConvReg).addReg(CopyReg);
224 
225   MachineInstr *MI =
226       BuildMI(MBB, I, DbgLoc, TII.get(PPC::MFVSRD), DstReg).addReg(ConvReg);
227 
228   I.eraseFromParent();
229   return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
230 }
231 
232 bool PPCInstructionSelector::selectZExt(MachineInstr &I, MachineBasicBlock &MBB,
233                                         MachineRegisterInfo &MRI) const {
234   const Register DstReg = I.getOperand(0).getReg();
235   const LLT DstTy = MRI.getType(DstReg);
236   const RegisterBank *DstRegBank = RBI.getRegBank(DstReg, MRI, TRI);
237 
238   const Register SrcReg = I.getOperand(1).getReg();
239 
240   assert(DstTy.getSizeInBits() == 64 && "Unexpected dest size!");
241   assert(MRI.getType(SrcReg).getSizeInBits() == 32 && "Unexpected src size!");
242 
243   Register ImpDefReg =
244       MRI.createVirtualRegister(getRegClass(DstTy, DstRegBank));
245   BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::IMPLICIT_DEF),
246           ImpDefReg);
247 
248   Register NewDefReg =
249       MRI.createVirtualRegister(getRegClass(DstTy, DstRegBank));
250   BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::INSERT_SUBREG),
251           NewDefReg)
252       .addReg(ImpDefReg)
253       .addReg(SrcReg)
254       .addImm(PPC::sub_32);
255 
256   MachineInstr *MI =
257       BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), DstReg)
258           .addReg(NewDefReg)
259           .addImm(0)
260           .addImm(32);
261 
262   I.eraseFromParent();
263   return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
264 }
265 
266 // For any 32 < Num < 64, check if the Imm contains at least Num consecutive
267 // zeros and return the number of bits by the left of these consecutive zeros.
268 static uint32_t findContiguousZerosAtLeast(uint64_t Imm, unsigned Num) {
269   uint32_t HiTZ = countTrailingZeros<uint32_t>(Hi_32(Imm));
270   uint32_t LoLZ = countLeadingZeros<uint32_t>(Lo_32(Imm));
271   if ((HiTZ + LoLZ) >= Num)
272     return (32 + HiTZ);
273   return 0;
274 }
275 
276 // Direct materialization of 64-bit constants by enumerated patterns.
277 // Similar to PPCISelDAGToDAG::selectI64ImmDirect().
278 std::optional<bool> PPCInstructionSelector::selectI64ImmDirect(MachineInstr &I,
279                                                 MachineBasicBlock &MBB,
280                                                 MachineRegisterInfo &MRI,
281                                                 Register Reg,
282                                                 uint64_t Imm) const {
283   unsigned TZ = countTrailingZeros<uint64_t>(Imm);
284   unsigned LZ = countLeadingZeros<uint64_t>(Imm);
285   unsigned TO = countTrailingOnes<uint64_t>(Imm);
286   unsigned LO = countLeadingOnes<uint64_t>(Imm);
287   uint32_t Hi32 = Hi_32(Imm);
288   uint32_t Lo32 = Lo_32(Imm);
289   uint32_t Shift = 0;
290 
291   // Following patterns use 1 instructions to materialize the Imm.
292 
293   // 1-1) Patterns : {zeros}{15-bit valve}
294   //                 {ones}{15-bit valve}
295   if (isInt<16>(Imm))
296     return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), Reg)
297         .addImm(Imm)
298         .constrainAllUses(TII, TRI, RBI);
299   // 1-2) Patterns : {zeros}{15-bit valve}{16 zeros}
300   //                 {ones}{15-bit valve}{16 zeros}
301   if (TZ > 15 && (LZ > 32 || LO > 32))
302     return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LIS8), Reg)
303         .addImm((Imm >> 16) & 0xffff)
304         .constrainAllUses(TII, TRI, RBI);
305 
306   // Following patterns use 2 instructions to materialize the Imm.
307 
308   assert(LZ < 64 && "Unexpected leading zeros here.");
309   // Count of ones follwing the leading zeros.
310   unsigned FO = countLeadingOnes<uint64_t>(Imm << LZ);
311   // 2-1) Patterns : {zeros}{31-bit value}
312   //                 {ones}{31-bit value}
313   if (isInt<32>(Imm)) {
314     uint64_t ImmHi16 = (Imm >> 16) & 0xffff;
315     unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
316     Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
317     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode), TmpReg)
318              .addImm((Imm >> 16) & 0xffff)
319              .constrainAllUses(TII, TRI, RBI))
320       return false;
321     return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Reg)
322         .addReg(TmpReg, RegState::Kill)
323         .addImm(Imm & 0xffff)
324         .constrainAllUses(TII, TRI, RBI);
325   }
326   // 2-2) Patterns : {zeros}{ones}{15-bit value}{zeros}
327   //                 {zeros}{15-bit value}{zeros}
328   //                 {zeros}{ones}{15-bit value}
329   //                 {ones}{15-bit value}{zeros}
330   // We can take advantage of LI's sign-extension semantics to generate leading
331   // ones, and then use RLDIC to mask off the ones in both sides after rotation.
332   if ((LZ + FO + TZ) > 48) {
333     Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
334     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
335              .addImm((Imm >> TZ) & 0xffff)
336              .constrainAllUses(TII, TRI, RBI))
337       return false;
338     return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDIC), Reg)
339         .addReg(TmpReg, RegState::Kill)
340         .addImm(TZ)
341         .addImm(LZ)
342         .constrainAllUses(TII, TRI, RBI);
343   }
344   // 2-3) Pattern : {zeros}{15-bit value}{ones}
345   // Shift right the Imm by (48 - LZ) bits to construct a negtive 16 bits value,
346   // therefore we can take advantage of LI's sign-extension semantics, and then
347   // mask them off after rotation.
348   //
349   // +--LZ--||-15-bit-||--TO--+     +-------------|--16-bit--+
350   // |00000001bbbbbbbbb1111111| ->  |00000000000001bbbbbbbbb1|
351   // +------------------------+     +------------------------+
352   // 63                      0      63                      0
353   //          Imm                   (Imm >> (48 - LZ) & 0xffff)
354   // +----sext-----|--16-bit--+     +clear-|-----------------+
355   // |11111111111111bbbbbbbbb1| ->  |00000001bbbbbbbbb1111111|
356   // +------------------------+     +------------------------+
357   // 63                      0      63                      0
358   // LI8: sext many leading zeros   RLDICL: rotate left (48 - LZ), clear left LZ
359   if ((LZ + TO) > 48) {
360     // Since the immediates with (LZ > 32) have been handled by previous
361     // patterns, here we have (LZ <= 32) to make sure we will not shift right
362     // the Imm by a negative value.
363     assert(LZ <= 32 && "Unexpected shift value.");
364     Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
365     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
366              .addImm(Imm >> (48 - LZ) & 0xffff)
367              .constrainAllUses(TII, TRI, RBI))
368       return false;
369     return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
370         .addReg(TmpReg, RegState::Kill)
371         .addImm(48 - LZ)
372         .addImm(LZ)
373         .constrainAllUses(TII, TRI, RBI);
374   }
375   // 2-4) Patterns : {zeros}{ones}{15-bit value}{ones}
376   //                 {ones}{15-bit value}{ones}
377   // We can take advantage of LI's sign-extension semantics to generate leading
378   // ones, and then use RLDICL to mask off the ones in left sides (if required)
379   // after rotation.
380   //
381   // +-LZ-FO||-15-bit-||--TO--+     +-------------|--16-bit--+
382   // |00011110bbbbbbbbb1111111| ->  |000000000011110bbbbbbbbb|
383   // +------------------------+     +------------------------+
384   // 63                      0      63                      0
385   //            Imm                    (Imm >> TO) & 0xffff
386   // +----sext-----|--16-bit--+     +LZ|---------------------+
387   // |111111111111110bbbbbbbbb| ->  |00011110bbbbbbbbb1111111|
388   // +------------------------+     +------------------------+
389   // 63                      0      63                      0
390   // LI8: sext many leading zeros   RLDICL: rotate left TO, clear left LZ
391   if ((LZ + FO + TO) > 48) {
392     Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
393     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
394              .addImm((Imm >> TO) & 0xffff)
395              .constrainAllUses(TII, TRI, RBI))
396       return false;
397     return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
398         .addReg(TmpReg, RegState::Kill)
399         .addImm(TO)
400         .addImm(LZ)
401         .constrainAllUses(TII, TRI, RBI);
402   }
403   // 2-5) Pattern : {32 zeros}{****}{0}{15-bit value}
404   // If Hi32 is zero and the Lo16(in Lo32) can be presented as a positive 16 bit
405   // value, we can use LI for Lo16 without generating leading ones then add the
406   // Hi16(in Lo32).
407   if (LZ == 32 && ((Lo32 & 0x8000) == 0)) {
408     Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
409     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
410              .addImm(Lo32 & 0xffff)
411              .constrainAllUses(TII, TRI, RBI))
412       return false;
413     return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORIS8), Reg)
414         .addReg(TmpReg, RegState::Kill)
415         .addImm(Lo32 >> 16)
416         .constrainAllUses(TII, TRI, RBI);
417   }
418   // 2-6) Patterns : {******}{49 zeros}{******}
419   //                 {******}{49 ones}{******}
420   // If the Imm contains 49 consecutive zeros/ones, it means that a total of 15
421   // bits remain on both sides. Rotate right the Imm to construct an int<16>
422   // value, use LI for int<16> value and then use RLDICL without mask to rotate
423   // it back.
424   //
425   // 1) findContiguousZerosAtLeast(Imm, 49)
426   // +------|--zeros-|------+     +---ones--||---15 bit--+
427   // |bbbbbb0000000000aaaaaa| ->  |0000000000aaaaaabbbbbb|
428   // +----------------------+     +----------------------+
429   // 63                    0      63                    0
430   //
431   // 2) findContiguousZerosAtLeast(~Imm, 49)
432   // +------|--ones--|------+     +---ones--||---15 bit--+
433   // |bbbbbb1111111111aaaaaa| ->  |1111111111aaaaaabbbbbb|
434   // +----------------------+     +----------------------+
435   // 63                    0      63                    0
436   if ((Shift = findContiguousZerosAtLeast(Imm, 49)) ||
437       (Shift = findContiguousZerosAtLeast(~Imm, 49))) {
438     uint64_t RotImm = APInt(64, Imm).rotr(Shift).getZExtValue();
439     Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
440     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
441              .addImm(RotImm & 0xffff)
442              .constrainAllUses(TII, TRI, RBI))
443       return false;
444     return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
445         .addReg(TmpReg, RegState::Kill)
446         .addImm(Shift)
447         .addImm(0)
448         .constrainAllUses(TII, TRI, RBI);
449   }
450 
451   // Following patterns use 3 instructions to materialize the Imm.
452 
453   // 3-1) Patterns : {zeros}{ones}{31-bit value}{zeros}
454   //                 {zeros}{31-bit value}{zeros}
455   //                 {zeros}{ones}{31-bit value}
456   //                 {ones}{31-bit value}{zeros}
457   // We can take advantage of LIS's sign-extension semantics to generate leading
458   // ones, add the remaining bits with ORI, and then use RLDIC to mask off the
459   // ones in both sides after rotation.
460   if ((LZ + FO + TZ) > 32) {
461     uint64_t ImmHi16 = (Imm >> (TZ + 16)) & 0xffff;
462     unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
463     Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
464     Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
465     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode), TmpReg)
466              .addImm(ImmHi16)
467              .constrainAllUses(TII, TRI, RBI))
468       return false;
469     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Tmp2Reg)
470              .addReg(TmpReg, RegState::Kill)
471              .addImm((Imm >> TZ) & 0xffff)
472              .constrainAllUses(TII, TRI, RBI))
473       return false;
474     return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDIC), Reg)
475         .addReg(Tmp2Reg, RegState::Kill)
476         .addImm(TZ)
477         .addImm(LZ)
478         .constrainAllUses(TII, TRI, RBI);
479   }
480   // 3-2) Pattern : {zeros}{31-bit value}{ones}
481   // Shift right the Imm by (32 - LZ) bits to construct a negative 32 bits
482   // value, therefore we can take advantage of LIS's sign-extension semantics,
483   // add the remaining bits with ORI, and then mask them off after rotation.
484   // This is similar to Pattern 2-3, please refer to the diagram there.
485   if ((LZ + TO) > 32) {
486     // Since the immediates with (LZ > 32) have been handled by previous
487     // patterns, here we have (LZ <= 32) to make sure we will not shift right
488     // the Imm by a negative value.
489     assert(LZ <= 32 && "Unexpected shift value.");
490     Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
491     Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
492     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LIS8), TmpReg)
493             .addImm((Imm >> (48 - LZ)) & 0xffff)
494             .constrainAllUses(TII, TRI, RBI))
495       return false;
496     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Tmp2Reg)
497              .addReg(TmpReg, RegState::Kill)
498              .addImm((Imm >> (32 - LZ)) & 0xffff)
499              .constrainAllUses(TII, TRI, RBI))
500       return false;
501     return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
502         .addReg(Tmp2Reg, RegState::Kill)
503         .addImm(32 - LZ)
504         .addImm(LZ)
505         .constrainAllUses(TII, TRI, RBI);
506   }
507   // 3-3) Patterns : {zeros}{ones}{31-bit value}{ones}
508   //                 {ones}{31-bit value}{ones}
509   // We can take advantage of LIS's sign-extension semantics to generate leading
510   // ones, add the remaining bits with ORI, and then use RLDICL to mask off the
511   // ones in left sides (if required) after rotation.
512   // This is similar to Pattern 2-4, please refer to the diagram there.
513   if ((LZ + FO + TO) > 32) {
514     Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
515     Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
516     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LIS8), TmpReg)
517              .addImm((Imm >> (TO + 16)) & 0xffff)
518              .constrainAllUses(TII, TRI, RBI))
519       return false;
520     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Tmp2Reg)
521              .addReg(TmpReg, RegState::Kill)
522              .addImm((Imm >> TO) & 0xffff)
523              .constrainAllUses(TII, TRI, RBI))
524       return false;
525     return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
526         .addReg(Tmp2Reg, RegState::Kill)
527         .addImm(TO)
528         .addImm(LZ)
529         .constrainAllUses(TII, TRI, RBI);
530   }
531   // 3-4) Patterns : High word == Low word
532   if (Hi32 == Lo32) {
533     // Handle the first 32 bits.
534     uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
535     unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
536     Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
537     Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
538     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode), TmpReg)
539              .addImm(ImmHi16)
540              .constrainAllUses(TII, TRI, RBI))
541       return false;
542     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Tmp2Reg)
543              .addReg(TmpReg, RegState::Kill)
544              .addImm(Lo32 & 0xffff)
545              .constrainAllUses(TII, TRI, RBI))
546       return false;
547     return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDIMI), Reg)
548         .addReg(Tmp2Reg)
549         .addReg(Tmp2Reg, RegState::Kill)
550         .addImm(32)
551         .addImm(0)
552         .constrainAllUses(TII, TRI, RBI);
553   }
554   // 3-5) Patterns : {******}{33 zeros}{******}
555   //                 {******}{33 ones}{******}
556   // If the Imm contains 33 consecutive zeros/ones, it means that a total of 31
557   // bits remain on both sides. Rotate right the Imm to construct an int<32>
558   // value, use LIS + ORI for int<32> value and then use RLDICL without mask to
559   // rotate it back.
560   // This is similar to Pattern 2-6, please refer to the diagram there.
561   if ((Shift = findContiguousZerosAtLeast(Imm, 33)) ||
562       (Shift = findContiguousZerosAtLeast(~Imm, 33))) {
563     uint64_t RotImm = APInt(64, Imm).rotr(Shift).getZExtValue();
564     uint64_t ImmHi16 = (RotImm >> 16) & 0xffff;
565     unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
566     Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
567     Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
568     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode), TmpReg)
569              .addImm(ImmHi16)
570              .constrainAllUses(TII, TRI, RBI))
571       return false;
572     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Tmp2Reg)
573              .addReg(TmpReg, RegState::Kill)
574              .addImm(RotImm & 0xffff)
575              .constrainAllUses(TII, TRI, RBI))
576       return false;
577     return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
578         .addReg(Tmp2Reg, RegState::Kill)
579         .addImm(Shift)
580         .addImm(0)
581         .constrainAllUses(TII, TRI, RBI);
582   }
583 
584   // If we end up here then no instructions were inserted.
585   return std::nullopt;
586 }
587 
588 // Derived from PPCISelDAGToDAG::selectI64Imm().
589 // TODO: Add support for prefixed instructions.
590 bool PPCInstructionSelector::selectI64Imm(MachineInstr &I,
591                                           MachineBasicBlock &MBB,
592                                           MachineRegisterInfo &MRI) const {
593   assert(I.getOpcode() == TargetOpcode::G_CONSTANT && "Unexpected G code");
594 
595   Register DstReg = I.getOperand(0).getReg();
596   int64_t Imm = I.getOperand(1).getCImm()->getValue().getZExtValue();
597   // No more than 3 instructions are used if we can select the i64 immediate
598   // directly.
599   if (std::optional<bool> Res = selectI64ImmDirect(I, MBB, MRI, DstReg, Imm)) {
600     I.eraseFromParent();
601     return *Res;
602   }
603 
604   // Calculate the last bits as required.
605   uint32_t Hi16 = (Lo_32(Imm) >> 16) & 0xffff;
606   uint32_t Lo16 = Lo_32(Imm) & 0xffff;
607 
608   Register Reg =
609       (Hi16 || Lo16) ? MRI.createVirtualRegister(&PPC::G8RCRegClass) : DstReg;
610 
611   // Handle the upper 32 bit value.
612   std::optional<bool> Res =
613       selectI64ImmDirect(I, MBB, MRI, Reg, Imm & 0xffffffff00000000);
614   if (!Res || !*Res)
615     return false;
616 
617   // Add in the last bits as required.
618   if (Hi16) {
619     Register TmpReg =
620         Lo16 ? MRI.createVirtualRegister(&PPC::G8RCRegClass) : DstReg;
621     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORIS8), TmpReg)
622              .addReg(Reg, RegState::Kill)
623              .addImm(Hi16)
624              .constrainAllUses(TII, TRI, RBI))
625       return false;
626     Reg = TmpReg;
627   }
628   if (Lo16) {
629     if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), DstReg)
630              .addReg(Reg, RegState::Kill)
631              .addImm(Lo16)
632              .constrainAllUses(TII, TRI, RBI))
633       return false;
634   }
635   I.eraseFromParent();
636   return true;
637 }
638 
639 bool PPCInstructionSelector::select(MachineInstr &I) {
640   auto &MBB = *I.getParent();
641   auto &MF = *MBB.getParent();
642   auto &MRI = MF.getRegInfo();
643 
644   if (!isPreISelGenericOpcode(I.getOpcode())) {
645     if (I.isCopy())
646       return selectCopy(I, TII, MRI, TRI, RBI);
647 
648     return true;
649   }
650 
651   if (selectImpl(I, *CoverageInfo))
652     return true;
653 
654   unsigned Opcode = I.getOpcode();
655 
656   switch (Opcode) {
657   default:
658     return false;
659   case TargetOpcode::G_LOAD:
660   case TargetOpcode::G_STORE: {
661     GLoadStore &LdSt = cast<GLoadStore>(I);
662     LLT PtrTy = MRI.getType(LdSt.getPointerReg());
663 
664     if (PtrTy != LLT::pointer(0, 64)) {
665       LLVM_DEBUG(dbgs() << "Load/Store pointer has type: " << PtrTy
666                         << ", expected: " << LLT::pointer(0, 64) << '\n');
667       return false;
668     }
669 
670     auto SelectLoadStoreAddressingMode = [&]() -> MachineInstr * {
671       const unsigned NewOpc = selectLoadStoreOp(
672           I.getOpcode(), RBI.getRegBank(LdSt.getReg(0), MRI, TRI)->getID(),
673           LdSt.getMemSizeInBits());
674 
675       if (NewOpc == I.getOpcode())
676         return nullptr;
677 
678       // For now, simply use DForm with load/store addr as base and 0 as imm.
679       // FIXME: optimize load/store with some specific address patterns.
680       I.setDesc(TII.get(NewOpc));
681       Register AddrReg = I.getOperand(1).getReg();
682       bool IsKill = I.getOperand(1).isKill();
683       I.getOperand(1).ChangeToImmediate(0);
684       I.addOperand(*I.getParent()->getParent(),
685                    MachineOperand::CreateReg(AddrReg, /* isDef */ false,
686                                              /* isImp */ false, IsKill));
687       return &I;
688     };
689 
690     MachineInstr *LoadStore = SelectLoadStoreAddressingMode();
691     if (!LoadStore)
692       return false;
693 
694     return constrainSelectedInstRegOperands(*LoadStore, TII, TRI, RBI);
695   }
696   case TargetOpcode::G_SITOFP:
697   case TargetOpcode::G_UITOFP:
698     return selectIntToFP(I, MBB, MRI);
699   case TargetOpcode::G_FPTOSI:
700   case TargetOpcode::G_FPTOUI:
701     return selectFPToInt(I, MBB, MRI);
702   // G_SEXT will be selected in tb-gen pattern.
703   case TargetOpcode::G_ZEXT:
704     return selectZExt(I, MBB, MRI);
705   case TargetOpcode::G_CONSTANT:
706     return selectI64Imm(I, MBB, MRI);
707   }
708   return false;
709 }
710 
711 namespace llvm {
712 InstructionSelector *
713 createPPCInstructionSelector(const PPCTargetMachine &TM,
714                              const PPCSubtarget &Subtarget,
715                              const PPCRegisterBankInfo &RBI) {
716   return new PPCInstructionSelector(TM, Subtarget, RBI);
717 }
718 } // end namespace llvm
719