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;
getName()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
PPCInstructionSelector(const PPCTargetMachine & TM,const PPCSubtarget & STI,const PPCRegisterBankInfo & RBI)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
getRegClass(LLT Ty,const RegisterBank * RB)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
selectCopy(MachineInstr & I,const TargetInstrInfo & TII,MachineRegisterInfo & MRI,const TargetRegisterInfo & TRI,const RegisterBankInfo & RBI)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
selectLoadStoreOp(unsigned GenericOpc,unsigned RegBankID,unsigned OpSize)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
selectIntToFP(MachineInstr & I,MachineBasicBlock & MBB,MachineRegisterInfo & MRI) const175 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
selectFPToInt(MachineInstr & I,MachineBasicBlock & MBB,MachineRegisterInfo & MRI) const202 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
selectZExt(MachineInstr & I,MachineBasicBlock & MBB,MachineRegisterInfo & MRI) const232 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.
findContiguousZerosAtLeast(uint64_t Imm,unsigned Num)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().
selectI64ImmDirect(MachineInstr & I,MachineBasicBlock & MBB,MachineRegisterInfo & MRI,Register Reg,uint64_t Imm) const278 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.
selectI64Imm(MachineInstr & I,MachineBasicBlock & MBB,MachineRegisterInfo & MRI) const590 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
select(MachineInstr & I)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 *
createPPCInstructionSelector(const PPCTargetMachine & TM,const PPCSubtarget & Subtarget,const PPCRegisterBankInfo & RBI)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