PPCInstructionSelector.cpp 28 KB

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