1 //===- PPCInstructionSelector.cpp --------------------------------*- C++ -*-==//
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
7 //===----------------------------------------------------------------------===//
9 /// This file implements the targeting of the InstructionSelector class for
11 //===----------------------------------------------------------------------===//
14 #include "PPCInstrInfo.h"
15 #include "PPCMachineFunctionInfo.h"
16 #include "PPCRegisterBankInfo.h"
17 #include "PPCSubtarget.h"
18 #include "PPCTargetMachine.h"
19 #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
20 #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
21 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
22 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
23 #include "llvm/CodeGen/MachineConstantPool.h"
24 #include "llvm/CodeGen/MachineFunction.h"
25 #include "llvm/IR/IntrinsicsPowerPC.h"
26 #include "llvm/Support/Debug.h"
28 #define DEBUG_TYPE "ppc-gisel"
34 #define GET_GLOBALISEL_PREDICATE_BITSET
35 #include "PPCGenGlobalISel.inc"
36 #undef GET_GLOBALISEL_PREDICATE_BITSET
38 class PPCInstructionSelector
: public InstructionSelector
{
40 PPCInstructionSelector(const PPCTargetMachine
&TM
, const PPCSubtarget
&STI
,
41 const PPCRegisterBankInfo
&RBI
);
43 bool select(MachineInstr
&I
) override
;
44 static const char *getName() { return DEBUG_TYPE
; }
47 /// tblgen generated 'select' implementation that is used as the initial
48 /// selector for the patterns that do not require complex C++.
49 bool selectImpl(MachineInstr
&I
, CodeGenCoverage
&CoverageInfo
) const;
51 bool selectFPToInt(MachineInstr
&I
, MachineBasicBlock
&MBB
,
52 MachineRegisterInfo
&MRI
) const;
53 bool selectIntToFP(MachineInstr
&I
, MachineBasicBlock
&MBB
,
54 MachineRegisterInfo
&MRI
) const;
56 bool selectZExt(MachineInstr
&I
, MachineBasicBlock
&MBB
,
57 MachineRegisterInfo
&MRI
) const;
58 bool selectConstantPool(MachineInstr
&I
, MachineBasicBlock
&MBB
,
59 MachineRegisterInfo
&MRI
) const;
61 std::optional
<bool> selectI64ImmDirect(MachineInstr
&I
,
62 MachineBasicBlock
&MBB
,
63 MachineRegisterInfo
&MRI
, Register Reg
,
65 bool selectI64Imm(MachineInstr
&I
, MachineBasicBlock
&MBB
,
66 MachineRegisterInfo
&MRI
) const;
68 const PPCTargetMachine
&TM
;
69 const PPCSubtarget
&STI
;
70 const PPCInstrInfo
&TII
;
71 const PPCRegisterInfo
&TRI
;
72 const PPCRegisterBankInfo
&RBI
;
74 #define GET_GLOBALISEL_PREDICATES_DECL
75 #include "PPCGenGlobalISel.inc"
76 #undef GET_GLOBALISEL_PREDICATES_DECL
78 #define GET_GLOBALISEL_TEMPORARIES_DECL
79 #include "PPCGenGlobalISel.inc"
80 #undef GET_GLOBALISEL_TEMPORARIES_DECL
83 } // end anonymous namespace
85 #define GET_GLOBALISEL_IMPL
86 #include "PPCGenGlobalISel.inc"
87 #undef GET_GLOBALISEL_IMPL
89 PPCInstructionSelector::PPCInstructionSelector(const PPCTargetMachine
&TM
,
90 const PPCSubtarget
&STI
,
91 const PPCRegisterBankInfo
&RBI
)
92 : TM(TM
), STI(STI
), TII(*STI
.getInstrInfo()), TRI(*STI
.getRegisterInfo()),
94 #define GET_GLOBALISEL_PREDICATES_INIT
95 #include "PPCGenGlobalISel.inc"
96 #undef GET_GLOBALISEL_PREDICATES_INIT
97 #define GET_GLOBALISEL_TEMPORARIES_INIT
98 #include "PPCGenGlobalISel.inc"
99 #undef GET_GLOBALISEL_TEMPORARIES_INIT
103 static const TargetRegisterClass
*getRegClass(LLT Ty
, const RegisterBank
*RB
) {
104 if (RB
->getID() == PPC::GPRRegBankID
) {
105 if (Ty
.getSizeInBits() == 64)
106 return &PPC::G8RCRegClass
;
107 if (Ty
.getSizeInBits() <= 32)
108 return &PPC::GPRCRegClass
;
110 if (RB
->getID() == PPC::FPRRegBankID
) {
111 if (Ty
.getSizeInBits() == 32)
112 return &PPC::F4RCRegClass
;
113 if (Ty
.getSizeInBits() == 64)
114 return &PPC::F8RCRegClass
;
116 if (RB
->getID() == PPC::VECRegBankID
) {
117 if (Ty
.getSizeInBits() == 128)
118 return &PPC::VSRCRegClass
;
120 if (RB
->getID() == PPC::CRRegBankID
) {
121 if (Ty
.getSizeInBits() == 1)
122 return &PPC::CRBITRCRegClass
;
123 if (Ty
.getSizeInBits() == 4)
124 return &PPC::CRRCRegClass
;
127 llvm_unreachable("Unknown RegBank!");
130 static bool selectCopy(MachineInstr
&I
, const TargetInstrInfo
&TII
,
131 MachineRegisterInfo
&MRI
, const TargetRegisterInfo
&TRI
,
132 const RegisterBankInfo
&RBI
) {
133 Register DstReg
= I
.getOperand(0).getReg();
135 if (DstReg
.isPhysical())
138 const RegisterBank
*DstRegBank
= RBI
.getRegBank(DstReg
, MRI
, TRI
);
139 const TargetRegisterClass
*DstRC
=
140 getRegClass(MRI
.getType(DstReg
), DstRegBank
);
142 // No need to constrain SrcReg. It will get constrained when we hit another of
143 // its use or its defs.
144 // Copies do not have constraints.
145 if (!RBI
.constrainGenericRegister(DstReg
, *DstRC
, MRI
)) {
146 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII
.getName(I
.getOpcode())
154 static unsigned selectLoadStoreOp(unsigned GenericOpc
, unsigned RegBankID
,
156 const bool IsStore
= GenericOpc
== TargetOpcode::G_STORE
;
158 case PPC::GPRRegBankID
:
161 return IsStore
? PPC::STW
: PPC::LWZ
;
163 return IsStore
? PPC::STD
: PPC::LD
;
165 llvm_unreachable("Unexpected size!");
168 case PPC::FPRRegBankID
:
171 return IsStore
? PPC::STFS
: PPC::LFS
;
173 return IsStore
? PPC::STFD
: PPC::LFD
;
175 llvm_unreachable("Unexpected size!");
179 llvm_unreachable("Unexpected register bank!");
184 bool PPCInstructionSelector::selectIntToFP(MachineInstr
&I
,
185 MachineBasicBlock
&MBB
,
186 MachineRegisterInfo
&MRI
) const {
187 if (!STI
.hasDirectMove() || !STI
.isPPC64() || !STI
.hasFPCVT())
190 const DebugLoc
&DbgLoc
= I
.getDebugLoc();
191 const Register DstReg
= I
.getOperand(0).getReg();
192 const Register SrcReg
= I
.getOperand(1).getReg();
194 Register MoveReg
= MRI
.createVirtualRegister(&PPC::VSFRCRegClass
);
196 // For now, only handle the case for 64 bit integer.
197 BuildMI(MBB
, I
, DbgLoc
, TII
.get(PPC::MTVSRD
), MoveReg
).addReg(SrcReg
);
199 bool IsSingle
= MRI
.getType(DstReg
).getSizeInBits() == 32;
200 bool IsSigned
= I
.getOpcode() == TargetOpcode::G_SITOFP
;
201 unsigned ConvOp
= IsSingle
? (IsSigned
? PPC::XSCVSXDSP
: PPC::XSCVUXDSP
)
202 : (IsSigned
? PPC::XSCVSXDDP
: PPC::XSCVUXDDP
);
205 BuildMI(MBB
, I
, DbgLoc
, TII
.get(ConvOp
), DstReg
).addReg(MoveReg
);
208 return constrainSelectedInstRegOperands(*MI
, TII
, TRI
, RBI
);
211 bool PPCInstructionSelector::selectFPToInt(MachineInstr
&I
,
212 MachineBasicBlock
&MBB
,
213 MachineRegisterInfo
&MRI
) const {
214 if (!STI
.hasDirectMove() || !STI
.isPPC64() || !STI
.hasFPCVT())
217 const DebugLoc
&DbgLoc
= I
.getDebugLoc();
218 const Register DstReg
= I
.getOperand(0).getReg();
219 const Register SrcReg
= I
.getOperand(1).getReg();
221 Register CopyReg
= MRI
.createVirtualRegister(&PPC::VSFRCRegClass
);
222 BuildMI(MBB
, I
, DbgLoc
, TII
.get(TargetOpcode::COPY
), CopyReg
).addReg(SrcReg
);
224 Register ConvReg
= MRI
.createVirtualRegister(&PPC::VSFRCRegClass
);
226 bool IsSigned
= I
.getOpcode() == TargetOpcode::G_FPTOSI
;
228 // single-precision is stored as double-precision on PPC in registers, so
229 // always use double-precision convertions.
230 unsigned ConvOp
= IsSigned
? PPC::XSCVDPSXDS
: PPC::XSCVDPUXDS
;
232 BuildMI(MBB
, I
, DbgLoc
, TII
.get(ConvOp
), ConvReg
).addReg(CopyReg
);
235 BuildMI(MBB
, I
, DbgLoc
, TII
.get(PPC::MFVSRD
), DstReg
).addReg(ConvReg
);
238 return constrainSelectedInstRegOperands(*MI
, TII
, TRI
, RBI
);
241 bool PPCInstructionSelector::selectZExt(MachineInstr
&I
, MachineBasicBlock
&MBB
,
242 MachineRegisterInfo
&MRI
) const {
243 const Register DstReg
= I
.getOperand(0).getReg();
244 const LLT DstTy
= MRI
.getType(DstReg
);
245 const RegisterBank
*DstRegBank
= RBI
.getRegBank(DstReg
, MRI
, TRI
);
247 const Register SrcReg
= I
.getOperand(1).getReg();
249 assert(DstTy
.getSizeInBits() == 64 && "Unexpected dest size!");
250 assert(MRI
.getType(SrcReg
).getSizeInBits() == 32 && "Unexpected src size!");
253 MRI
.createVirtualRegister(getRegClass(DstTy
, DstRegBank
));
254 BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(TargetOpcode::IMPLICIT_DEF
),
258 MRI
.createVirtualRegister(getRegClass(DstTy
, DstRegBank
));
259 BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(TargetOpcode::INSERT_SUBREG
),
263 .addImm(PPC::sub_32
);
266 BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::RLDICL
), DstReg
)
272 return constrainSelectedInstRegOperands(*MI
, TII
, TRI
, RBI
);
275 // For any 32 < Num < 64, check if the Imm contains at least Num consecutive
276 // zeros and return the number of bits by the left of these consecutive zeros.
277 static uint32_t findContiguousZerosAtLeast(uint64_t Imm
, unsigned Num
) {
278 uint32_t HiTZ
= llvm::countr_zero
<uint32_t>(Hi_32(Imm
));
279 uint32_t LoLZ
= llvm::countl_zero
<uint32_t>(Lo_32(Imm
));
280 if ((HiTZ
+ LoLZ
) >= Num
)
285 // Direct materialization of 64-bit constants by enumerated patterns.
286 // Similar to PPCISelDAGToDAG::selectI64ImmDirect().
287 std::optional
<bool> PPCInstructionSelector::selectI64ImmDirect(MachineInstr
&I
,
288 MachineBasicBlock
&MBB
,
289 MachineRegisterInfo
&MRI
,
291 uint64_t Imm
) const {
292 unsigned TZ
= llvm::countr_zero
<uint64_t>(Imm
);
293 unsigned LZ
= llvm::countl_zero
<uint64_t>(Imm
);
294 unsigned TO
= llvm::countr_one
<uint64_t>(Imm
);
295 unsigned LO
= llvm::countl_one
<uint64_t>(Imm
);
296 uint32_t Hi32
= Hi_32(Imm
);
297 uint32_t Lo32
= Lo_32(Imm
);
300 // Following patterns use 1 instructions to materialize the Imm.
302 // 1-1) Patterns : {zeros}{15-bit valve}
303 // {ones}{15-bit valve}
305 return BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::LI8
), Reg
)
307 .constrainAllUses(TII
, TRI
, RBI
);
308 // 1-2) Patterns : {zeros}{15-bit valve}{16 zeros}
309 // {ones}{15-bit valve}{16 zeros}
310 if (TZ
> 15 && (LZ
> 32 || LO
> 32))
311 return BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::LIS8
), Reg
)
312 .addImm((Imm
>> 16) & 0xffff)
313 .constrainAllUses(TII
, TRI
, RBI
);
315 // Following patterns use 2 instructions to materialize the Imm.
317 assert(LZ
< 64 && "Unexpected leading zeros here.");
318 // Count of ones follwing the leading zeros.
319 unsigned FO
= llvm::countl_one
<uint64_t>(Imm
<< LZ
);
320 // 2-1) Patterns : {zeros}{31-bit value}
321 // {ones}{31-bit value}
322 if (isInt
<32>(Imm
)) {
323 uint64_t ImmHi16
= (Imm
>> 16) & 0xffff;
324 unsigned Opcode
= ImmHi16
? PPC::LIS8
: PPC::LI8
;
325 Register TmpReg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
326 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(Opcode
), TmpReg
)
327 .addImm((Imm
>> 16) & 0xffff)
328 .constrainAllUses(TII
, TRI
, RBI
))
330 return BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::ORI8
), Reg
)
331 .addReg(TmpReg
, RegState::Kill
)
332 .addImm(Imm
& 0xffff)
333 .constrainAllUses(TII
, TRI
, RBI
);
335 // 2-2) Patterns : {zeros}{ones}{15-bit value}{zeros}
336 // {zeros}{15-bit value}{zeros}
337 // {zeros}{ones}{15-bit value}
338 // {ones}{15-bit value}{zeros}
339 // We can take advantage of LI's sign-extension semantics to generate leading
340 // ones, and then use RLDIC to mask off the ones in both sides after rotation.
341 if ((LZ
+ FO
+ TZ
) > 48) {
342 Register TmpReg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
343 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::LI8
), TmpReg
)
344 .addImm((Imm
>> TZ
) & 0xffff)
345 .constrainAllUses(TII
, TRI
, RBI
))
347 return BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::RLDIC
), Reg
)
348 .addReg(TmpReg
, RegState::Kill
)
351 .constrainAllUses(TII
, TRI
, RBI
);
353 // 2-3) Pattern : {zeros}{15-bit value}{ones}
354 // Shift right the Imm by (48 - LZ) bits to construct a negtive 16 bits value,
355 // therefore we can take advantage of LI's sign-extension semantics, and then
356 // mask them off after rotation.
358 // +--LZ--||-15-bit-||--TO--+ +-------------|--16-bit--+
359 // |00000001bbbbbbbbb1111111| -> |00000000000001bbbbbbbbb1|
360 // +------------------------+ +------------------------+
362 // Imm (Imm >> (48 - LZ) & 0xffff)
363 // +----sext-----|--16-bit--+ +clear-|-----------------+
364 // |11111111111111bbbbbbbbb1| -> |00000001bbbbbbbbb1111111|
365 // +------------------------+ +------------------------+
367 // LI8: sext many leading zeros RLDICL: rotate left (48 - LZ), clear left LZ
368 if ((LZ
+ TO
) > 48) {
369 // Since the immediates with (LZ > 32) have been handled by previous
370 // patterns, here we have (LZ <= 32) to make sure we will not shift right
371 // the Imm by a negative value.
372 assert(LZ
<= 32 && "Unexpected shift value.");
373 Register TmpReg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
374 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::LI8
), TmpReg
)
375 .addImm(Imm
>> (48 - LZ
) & 0xffff)
376 .constrainAllUses(TII
, TRI
, RBI
))
378 return BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::RLDICL
), Reg
)
379 .addReg(TmpReg
, RegState::Kill
)
382 .constrainAllUses(TII
, TRI
, RBI
);
384 // 2-4) Patterns : {zeros}{ones}{15-bit value}{ones}
385 // {ones}{15-bit value}{ones}
386 // We can take advantage of LI's sign-extension semantics to generate leading
387 // ones, and then use RLDICL to mask off the ones in left sides (if required)
390 // +-LZ-FO||-15-bit-||--TO--+ +-------------|--16-bit--+
391 // |00011110bbbbbbbbb1111111| -> |000000000011110bbbbbbbbb|
392 // +------------------------+ +------------------------+
394 // Imm (Imm >> TO) & 0xffff
395 // +----sext-----|--16-bit--+ +LZ|---------------------+
396 // |111111111111110bbbbbbbbb| -> |00011110bbbbbbbbb1111111|
397 // +------------------------+ +------------------------+
399 // LI8: sext many leading zeros RLDICL: rotate left TO, clear left LZ
400 if ((LZ
+ FO
+ TO
) > 48) {
401 Register TmpReg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
402 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::LI8
), TmpReg
)
403 .addImm((Imm
>> TO
) & 0xffff)
404 .constrainAllUses(TII
, TRI
, RBI
))
406 return BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::RLDICL
), Reg
)
407 .addReg(TmpReg
, RegState::Kill
)
410 .constrainAllUses(TII
, TRI
, RBI
);
412 // 2-5) Pattern : {32 zeros}{****}{0}{15-bit value}
413 // If Hi32 is zero and the Lo16(in Lo32) can be presented as a positive 16 bit
414 // value, we can use LI for Lo16 without generating leading ones then add the
416 if (LZ
== 32 && ((Lo32
& 0x8000) == 0)) {
417 Register TmpReg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
418 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::LI8
), TmpReg
)
419 .addImm(Lo32
& 0xffff)
420 .constrainAllUses(TII
, TRI
, RBI
))
422 return BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::ORIS8
), Reg
)
423 .addReg(TmpReg
, RegState::Kill
)
425 .constrainAllUses(TII
, TRI
, RBI
);
427 // 2-6) Patterns : {******}{49 zeros}{******}
428 // {******}{49 ones}{******}
429 // If the Imm contains 49 consecutive zeros/ones, it means that a total of 15
430 // bits remain on both sides. Rotate right the Imm to construct an int<16>
431 // value, use LI for int<16> value and then use RLDICL without mask to rotate
434 // 1) findContiguousZerosAtLeast(Imm, 49)
435 // +------|--zeros-|------+ +---ones--||---15 bit--+
436 // |bbbbbb0000000000aaaaaa| -> |0000000000aaaaaabbbbbb|
437 // +----------------------+ +----------------------+
440 // 2) findContiguousZerosAtLeast(~Imm, 49)
441 // +------|--ones--|------+ +---ones--||---15 bit--+
442 // |bbbbbb1111111111aaaaaa| -> |1111111111aaaaaabbbbbb|
443 // +----------------------+ +----------------------+
445 if ((Shift
= findContiguousZerosAtLeast(Imm
, 49)) ||
446 (Shift
= findContiguousZerosAtLeast(~Imm
, 49))) {
447 uint64_t RotImm
= APInt(64, Imm
).rotr(Shift
).getZExtValue();
448 Register TmpReg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
449 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::LI8
), TmpReg
)
450 .addImm(RotImm
& 0xffff)
451 .constrainAllUses(TII
, TRI
, RBI
))
453 return BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::RLDICL
), Reg
)
454 .addReg(TmpReg
, RegState::Kill
)
457 .constrainAllUses(TII
, TRI
, RBI
);
460 // Following patterns use 3 instructions to materialize the Imm.
462 // 3-1) Patterns : {zeros}{ones}{31-bit value}{zeros}
463 // {zeros}{31-bit value}{zeros}
464 // {zeros}{ones}{31-bit value}
465 // {ones}{31-bit value}{zeros}
466 // We can take advantage of LIS's sign-extension semantics to generate leading
467 // ones, add the remaining bits with ORI, and then use RLDIC to mask off the
468 // ones in both sides after rotation.
469 if ((LZ
+ FO
+ TZ
) > 32) {
470 uint64_t ImmHi16
= (Imm
>> (TZ
+ 16)) & 0xffff;
471 unsigned Opcode
= ImmHi16
? PPC::LIS8
: PPC::LI8
;
472 Register TmpReg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
473 Register Tmp2Reg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
474 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(Opcode
), TmpReg
)
476 .constrainAllUses(TII
, TRI
, RBI
))
478 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::ORI8
), Tmp2Reg
)
479 .addReg(TmpReg
, RegState::Kill
)
480 .addImm((Imm
>> TZ
) & 0xffff)
481 .constrainAllUses(TII
, TRI
, RBI
))
483 return BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::RLDIC
), Reg
)
484 .addReg(Tmp2Reg
, RegState::Kill
)
487 .constrainAllUses(TII
, TRI
, RBI
);
489 // 3-2) Pattern : {zeros}{31-bit value}{ones}
490 // Shift right the Imm by (32 - LZ) bits to construct a negative 32 bits
491 // value, therefore we can take advantage of LIS's sign-extension semantics,
492 // add the remaining bits with ORI, and then mask them off after rotation.
493 // This is similar to Pattern 2-3, please refer to the diagram there.
494 if ((LZ
+ TO
) > 32) {
495 // Since the immediates with (LZ > 32) have been handled by previous
496 // patterns, here we have (LZ <= 32) to make sure we will not shift right
497 // the Imm by a negative value.
498 assert(LZ
<= 32 && "Unexpected shift value.");
499 Register TmpReg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
500 Register Tmp2Reg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
501 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::LIS8
), TmpReg
)
502 .addImm((Imm
>> (48 - LZ
)) & 0xffff)
503 .constrainAllUses(TII
, TRI
, RBI
))
505 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::ORI8
), Tmp2Reg
)
506 .addReg(TmpReg
, RegState::Kill
)
507 .addImm((Imm
>> (32 - LZ
)) & 0xffff)
508 .constrainAllUses(TII
, TRI
, RBI
))
510 return BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::RLDICL
), Reg
)
511 .addReg(Tmp2Reg
, RegState::Kill
)
514 .constrainAllUses(TII
, TRI
, RBI
);
516 // 3-3) Patterns : {zeros}{ones}{31-bit value}{ones}
517 // {ones}{31-bit value}{ones}
518 // We can take advantage of LIS's sign-extension semantics to generate leading
519 // ones, add the remaining bits with ORI, and then use RLDICL to mask off the
520 // ones in left sides (if required) after rotation.
521 // This is similar to Pattern 2-4, please refer to the diagram there.
522 if ((LZ
+ FO
+ TO
) > 32) {
523 Register TmpReg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
524 Register Tmp2Reg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
525 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::LIS8
), TmpReg
)
526 .addImm((Imm
>> (TO
+ 16)) & 0xffff)
527 .constrainAllUses(TII
, TRI
, RBI
))
529 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::ORI8
), Tmp2Reg
)
530 .addReg(TmpReg
, RegState::Kill
)
531 .addImm((Imm
>> TO
) & 0xffff)
532 .constrainAllUses(TII
, TRI
, RBI
))
534 return BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::RLDICL
), Reg
)
535 .addReg(Tmp2Reg
, RegState::Kill
)
538 .constrainAllUses(TII
, TRI
, RBI
);
540 // 3-4) Patterns : High word == Low word
542 // Handle the first 32 bits.
543 uint64_t ImmHi16
= (Lo32
>> 16) & 0xffff;
544 unsigned Opcode
= ImmHi16
? PPC::LIS8
: PPC::LI8
;
545 Register TmpReg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
546 Register Tmp2Reg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
547 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(Opcode
), TmpReg
)
549 .constrainAllUses(TII
, TRI
, RBI
))
551 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::ORI8
), Tmp2Reg
)
552 .addReg(TmpReg
, RegState::Kill
)
553 .addImm(Lo32
& 0xffff)
554 .constrainAllUses(TII
, TRI
, RBI
))
556 return BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::RLDIMI
), Reg
)
558 .addReg(Tmp2Reg
, RegState::Kill
)
561 .constrainAllUses(TII
, TRI
, RBI
);
563 // 3-5) Patterns : {******}{33 zeros}{******}
564 // {******}{33 ones}{******}
565 // If the Imm contains 33 consecutive zeros/ones, it means that a total of 31
566 // bits remain on both sides. Rotate right the Imm to construct an int<32>
567 // value, use LIS + ORI for int<32> value and then use RLDICL without mask to
569 // This is similar to Pattern 2-6, please refer to the diagram there.
570 if ((Shift
= findContiguousZerosAtLeast(Imm
, 33)) ||
571 (Shift
= findContiguousZerosAtLeast(~Imm
, 33))) {
572 uint64_t RotImm
= APInt(64, Imm
).rotr(Shift
).getZExtValue();
573 uint64_t ImmHi16
= (RotImm
>> 16) & 0xffff;
574 unsigned Opcode
= ImmHi16
? PPC::LIS8
: PPC::LI8
;
575 Register TmpReg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
576 Register Tmp2Reg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
577 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(Opcode
), TmpReg
)
579 .constrainAllUses(TII
, TRI
, RBI
))
581 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::ORI8
), Tmp2Reg
)
582 .addReg(TmpReg
, RegState::Kill
)
583 .addImm(RotImm
& 0xffff)
584 .constrainAllUses(TII
, TRI
, RBI
))
586 return BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::RLDICL
), Reg
)
587 .addReg(Tmp2Reg
, RegState::Kill
)
590 .constrainAllUses(TII
, TRI
, RBI
);
593 // If we end up here then no instructions were inserted.
597 // Derived from PPCISelDAGToDAG::selectI64Imm().
598 // TODO: Add support for prefixed instructions.
599 bool PPCInstructionSelector::selectI64Imm(MachineInstr
&I
,
600 MachineBasicBlock
&MBB
,
601 MachineRegisterInfo
&MRI
) const {
602 assert(I
.getOpcode() == TargetOpcode::G_CONSTANT
&& "Unexpected G code");
604 Register DstReg
= I
.getOperand(0).getReg();
605 int64_t Imm
= I
.getOperand(1).getCImm()->getValue().getZExtValue();
606 // No more than 3 instructions are used if we can select the i64 immediate
608 if (std::optional
<bool> Res
= selectI64ImmDirect(I
, MBB
, MRI
, DstReg
, Imm
)) {
613 // Calculate the last bits as required.
614 uint32_t Hi16
= (Lo_32(Imm
) >> 16) & 0xffff;
615 uint32_t Lo16
= Lo_32(Imm
) & 0xffff;
618 (Hi16
|| Lo16
) ? MRI
.createVirtualRegister(&PPC::G8RCRegClass
) : DstReg
;
620 // Handle the upper 32 bit value.
621 std::optional
<bool> Res
=
622 selectI64ImmDirect(I
, MBB
, MRI
, Reg
, Imm
& 0xffffffff00000000);
626 // Add in the last bits as required.
629 Lo16
? MRI
.createVirtualRegister(&PPC::G8RCRegClass
) : DstReg
;
630 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::ORIS8
), TmpReg
)
631 .addReg(Reg
, RegState::Kill
)
633 .constrainAllUses(TII
, TRI
, RBI
))
638 if (!BuildMI(MBB
, I
, I
.getDebugLoc(), TII
.get(PPC::ORI8
), DstReg
)
639 .addReg(Reg
, RegState::Kill
)
641 .constrainAllUses(TII
, TRI
, RBI
))
648 bool PPCInstructionSelector::selectConstantPool(
649 MachineInstr
&I
, MachineBasicBlock
&MBB
, MachineRegisterInfo
&MRI
) const {
650 const DebugLoc
&DbgLoc
= I
.getDebugLoc();
651 MachineFunction
*MF
= MBB
.getParent();
653 // TODO: handle 32-bit.
654 // TODO: Enabling floating point constant pool selection on AIX requires
655 // global isel on big endian target enabled first.
656 // See CallLowering::enableBigEndian().
657 if (!STI
.isPPC64() || !STI
.isLittleEndian())
660 MF
->getInfo
<PPCFunctionInfo
>()->setUsesTOCBasePtr();
662 const Register DstReg
= I
.getOperand(0).getReg();
663 unsigned CPI
= I
.getOperand(1).getIndex();
665 // Address stored in the TOC entry. This is related to code model and the ABI
666 // we are currently using. For now we only handle 64-bit Linux LE. PowerPC
667 // only supports small, medium and large code model.
668 const CodeModel::Model CModel
= TM
.getCodeModel();
669 assert(!(CModel
== CodeModel::Tiny
|| CModel
== CodeModel::Kernel
) &&
670 "PowerPC doesn't support tiny or kernel code models.");
672 const MCRegister TOCReg
= STI
.getTOCPointerRegister();
673 MachineMemOperand
*MMO
= MF
->getMachineMemOperand(
674 MachinePointerInfo::getGOT(*MF
), MachineMemOperand::MOLoad
,
675 MRI
.getType(DstReg
), MF
->getDataLayout().getPointerABIAlignment(0));
677 MachineInstr
*MI
= nullptr;
678 // For now we only handle 64-bit Linux.
679 if (CModel
== CodeModel::Small
) {
680 // For small code model, generate LDtocCPT(CPI, X2).
681 MI
= BuildMI(MBB
, I
, DbgLoc
, TII
.get(PPC::LDtocCPT
), DstReg
)
682 .addConstantPoolIndex(CPI
)
686 Register HaAddrReg
= MRI
.createVirtualRegister(&PPC::G8RCRegClass
);
687 BuildMI(MBB
, I
, DbgLoc
, TII
.get(PPC::ADDIStocHA8
), HaAddrReg
)
689 .addConstantPoolIndex(CPI
);
691 if (CModel
== CodeModel::Large
)
692 // For large code model, generate LDtocL(CPI, ADDIStocHA8(X2, CPI))
693 MI
= BuildMI(MBB
, I
, DbgLoc
, TII
.get(PPC::LDtocL
), DstReg
)
694 .addConstantPoolIndex(CPI
)
698 // For medium code model, generate ADDItocL8(CPI, ADDIStocHA8(X2, CPI))
699 MI
= BuildMI(MBB
, I
, DbgLoc
, TII
.get(PPC::ADDItocL8
), DstReg
)
701 .addConstantPoolIndex(CPI
);
705 return constrainSelectedInstRegOperands(*MI
, TII
, TRI
, RBI
);
708 bool PPCInstructionSelector::select(MachineInstr
&I
) {
709 auto &MBB
= *I
.getParent();
710 auto &MF
= *MBB
.getParent();
711 auto &MRI
= MF
.getRegInfo();
713 if (!isPreISelGenericOpcode(I
.getOpcode())) {
715 return selectCopy(I
, TII
, MRI
, TRI
, RBI
);
720 if (selectImpl(I
, *CoverageInfo
))
723 unsigned Opcode
= I
.getOpcode();
728 case TargetOpcode::G_LOAD
:
729 case TargetOpcode::G_STORE
: {
730 GLoadStore
&LdSt
= cast
<GLoadStore
>(I
);
731 LLT PtrTy
= MRI
.getType(LdSt
.getPointerReg());
733 if (PtrTy
!= LLT::pointer(0, 64)) {
734 LLVM_DEBUG(dbgs() << "Load/Store pointer has type: " << PtrTy
735 << ", expected: " << LLT::pointer(0, 64) << '\n');
739 auto SelectLoadStoreAddressingMode
= [&]() -> MachineInstr
* {
740 const unsigned NewOpc
= selectLoadStoreOp(
741 I
.getOpcode(), RBI
.getRegBank(LdSt
.getReg(0), MRI
, TRI
)->getID(),
742 LdSt
.getMemSizeInBits().getValue());
744 if (NewOpc
== I
.getOpcode())
747 // For now, simply use DForm with load/store addr as base and 0 as imm.
748 // FIXME: optimize load/store with some specific address patterns.
749 I
.setDesc(TII
.get(NewOpc
));
750 Register AddrReg
= I
.getOperand(1).getReg();
751 bool IsKill
= I
.getOperand(1).isKill();
752 I
.getOperand(1).ChangeToImmediate(0);
753 I
.addOperand(*I
.getParent()->getParent(),
754 MachineOperand::CreateReg(AddrReg
, /* isDef */ false,
755 /* isImp */ false, IsKill
));
759 MachineInstr
*LoadStore
= SelectLoadStoreAddressingMode();
763 return constrainSelectedInstRegOperands(*LoadStore
, TII
, TRI
, RBI
);
765 case TargetOpcode::G_SITOFP
:
766 case TargetOpcode::G_UITOFP
:
767 return selectIntToFP(I
, MBB
, MRI
);
768 case TargetOpcode::G_FPTOSI
:
769 case TargetOpcode::G_FPTOUI
:
770 return selectFPToInt(I
, MBB
, MRI
);
771 // G_SEXT will be selected in tb-gen pattern.
772 case TargetOpcode::G_ZEXT
:
773 return selectZExt(I
, MBB
, MRI
);
774 case TargetOpcode::G_CONSTANT
:
775 return selectI64Imm(I
, MBB
, MRI
);
776 case TargetOpcode::G_CONSTANT_POOL
:
777 return selectConstantPool(I
, MBB
, MRI
);
783 InstructionSelector
*
784 createPPCInstructionSelector(const PPCTargetMachine
&TM
,
785 const PPCSubtarget
&Subtarget
,
786 const PPCRegisterBankInfo
&RBI
) {
787 return new PPCInstructionSelector(TM
, Subtarget
, RBI
);
789 } // end namespace llvm