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
29using namespace llvm;
30
31namespace {
32
33#define GET_GLOBALISEL_PREDICATE_BITSET
34#include "PPCGenGlobalISel.inc"
35#undef GET_GLOBALISEL_PREDICATE_BITSET
36
37class PPCInstructionSelector : public InstructionSelector {
38public:
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
45private:
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
85PPCInstructionSelector::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
98static 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
121static 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
145static 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
175bool 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
202bool 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
232bool 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.
268static 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().
278std::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.
590bool 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
639bool 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
711namespace llvm {
712InstructionSelector *
713createPPCInstructionSelector(const PPCTargetMachine &TM,
714                             const PPCSubtarget &Subtarget,
715                             const PPCRegisterBankInfo &RBI) {
716  return new PPCInstructionSelector(TM, Subtarget, RBI);
717}
718} // end namespace llvm
719