X86FoldTablesEmitter.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. //===- utils/TableGen/X86FoldTablesEmitter.cpp - X86 backend-*- 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. //
  9. // This tablegen backend is responsible for emitting the memory fold tables of
  10. // the X86 backend instructions.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "CodeGenTarget.h"
  14. #include "X86RecognizableInstr.h"
  15. #include "llvm/Support/FormattedStream.h"
  16. #include "llvm/TableGen/Error.h"
  17. #include "llvm/TableGen/TableGenBackend.h"
  18. using namespace llvm;
  19. namespace {
  20. // 3 possible strategies for the unfolding flag (TB_NO_REVERSE) of the
  21. // manual added entries.
  22. enum UnfoldStrategy {
  23. UNFOLD, // Allow unfolding
  24. NO_UNFOLD, // Prevent unfolding
  25. NO_STRATEGY // Make decision according to operands' sizes
  26. };
  27. // Represents an entry in the manual mapped instructions set.
  28. struct ManualMapEntry {
  29. const char *RegInstStr;
  30. const char *MemInstStr;
  31. UnfoldStrategy Strategy;
  32. ManualMapEntry(const char *RegInstStr, const char *MemInstStr,
  33. UnfoldStrategy Strategy = NO_STRATEGY)
  34. : RegInstStr(RegInstStr), MemInstStr(MemInstStr), Strategy(Strategy) {}
  35. };
  36. // List of instructions requiring explicitly aligned memory.
  37. const char *ExplicitAlign[] = {"MOVDQA", "MOVAPS", "MOVAPD", "MOVNTPS",
  38. "MOVNTPD", "MOVNTDQ", "MOVNTDQA"};
  39. // List of instructions NOT requiring explicit memory alignment.
  40. const char *ExplicitUnalign[] = {"MOVDQU", "MOVUPS", "MOVUPD",
  41. "PCMPESTRM", "PCMPESTRI",
  42. "PCMPISTRM", "PCMPISTRI" };
  43. // For manually mapping instructions that do not match by their encoding.
  44. const ManualMapEntry ManualMapSet[] = {
  45. { "ADD16ri_DB", "ADD16mi", NO_UNFOLD },
  46. { "ADD16ri8_DB", "ADD16mi8", NO_UNFOLD },
  47. { "ADD16rr_DB", "ADD16mr", NO_UNFOLD },
  48. { "ADD32ri_DB", "ADD32mi", NO_UNFOLD },
  49. { "ADD32ri8_DB", "ADD32mi8", NO_UNFOLD },
  50. { "ADD32rr_DB", "ADD32mr", NO_UNFOLD },
  51. { "ADD64ri32_DB", "ADD64mi32", NO_UNFOLD },
  52. { "ADD64ri8_DB", "ADD64mi8", NO_UNFOLD },
  53. { "ADD64rr_DB", "ADD64mr", NO_UNFOLD },
  54. { "ADD8ri_DB", "ADD8mi", NO_UNFOLD },
  55. { "ADD8rr_DB", "ADD8mr", NO_UNFOLD },
  56. { "ADD16rr_DB", "ADD16rm", NO_UNFOLD },
  57. { "ADD32rr_DB", "ADD32rm", NO_UNFOLD },
  58. { "ADD64rr_DB", "ADD64rm", NO_UNFOLD },
  59. { "ADD8rr_DB", "ADD8rm", NO_UNFOLD },
  60. { "PUSH16r", "PUSH16rmm", UNFOLD },
  61. { "PUSH32r", "PUSH32rmm", UNFOLD },
  62. { "PUSH64r", "PUSH64rmm", UNFOLD },
  63. { "TAILJMPr", "TAILJMPm", UNFOLD },
  64. { "TAILJMPr64", "TAILJMPm64", UNFOLD },
  65. { "TAILJMPr64_REX", "TAILJMPm64_REX", UNFOLD },
  66. };
  67. static bool isExplicitAlign(const CodeGenInstruction *Inst) {
  68. return any_of(ExplicitAlign, [Inst](const char *InstStr) {
  69. return Inst->TheDef->getName().contains(InstStr);
  70. });
  71. }
  72. static bool isExplicitUnalign(const CodeGenInstruction *Inst) {
  73. return any_of(ExplicitUnalign, [Inst](const char *InstStr) {
  74. return Inst->TheDef->getName().contains(InstStr);
  75. });
  76. }
  77. class X86FoldTablesEmitter {
  78. RecordKeeper &Records;
  79. CodeGenTarget Target;
  80. // Represents an entry in the folding table
  81. class X86FoldTableEntry {
  82. const CodeGenInstruction *RegInst;
  83. const CodeGenInstruction *MemInst;
  84. public:
  85. bool CannotUnfold = false;
  86. bool IsLoad = false;
  87. bool IsStore = false;
  88. bool IsAligned = false;
  89. unsigned int Alignment = 0;
  90. X86FoldTableEntry(const CodeGenInstruction *RegInst,
  91. const CodeGenInstruction *MemInst)
  92. : RegInst(RegInst), MemInst(MemInst) {}
  93. void print(formatted_raw_ostream &OS) const {
  94. OS.indent(2);
  95. OS << "{ X86::" << RegInst->TheDef->getName() << ",";
  96. OS.PadToColumn(40);
  97. OS << "X86::" << MemInst->TheDef->getName() << ",";
  98. OS.PadToColumn(75);
  99. if (IsLoad)
  100. OS << "TB_FOLDED_LOAD | ";
  101. if (IsStore)
  102. OS << "TB_FOLDED_STORE | ";
  103. if (CannotUnfold)
  104. OS << "TB_NO_REVERSE | ";
  105. if (IsAligned)
  106. OS << "TB_ALIGN_" << Alignment << " | ";
  107. OS << "0 },\n";
  108. }
  109. bool operator<(const X86FoldTableEntry &RHS) const {
  110. bool LHSpseudo = RegInst->TheDef->getValueAsBit("isPseudo");
  111. bool RHSpseudo = RHS.RegInst->TheDef->getValueAsBit("isPseudo");
  112. if (LHSpseudo != RHSpseudo)
  113. return LHSpseudo;
  114. return RegInst->TheDef->getName() < RHS.RegInst->TheDef->getName();
  115. }
  116. };
  117. typedef std::vector<X86FoldTableEntry> FoldTable;
  118. // std::vector for each folding table.
  119. // Table2Addr - Holds instructions which their memory form performs load+store
  120. // Table#i - Holds instructions which the their memory form perform a load OR
  121. // a store, and their #i'th operand is folded.
  122. FoldTable Table2Addr;
  123. FoldTable Table0;
  124. FoldTable Table1;
  125. FoldTable Table2;
  126. FoldTable Table3;
  127. FoldTable Table4;
  128. public:
  129. X86FoldTablesEmitter(RecordKeeper &R) : Records(R), Target(R) {}
  130. // run - Generate the 6 X86 memory fold tables.
  131. void run(formatted_raw_ostream &OS);
  132. private:
  133. // Decides to which table to add the entry with the given instructions.
  134. // S sets the strategy of adding the TB_NO_REVERSE flag.
  135. void updateTables(const CodeGenInstruction *RegInstr,
  136. const CodeGenInstruction *MemInstr,
  137. const UnfoldStrategy S = NO_STRATEGY);
  138. // Generates X86FoldTableEntry with the given instructions and fill it with
  139. // the appropriate flags - then adds it to Table.
  140. void addEntryWithFlags(FoldTable &Table, const CodeGenInstruction *RegInstr,
  141. const CodeGenInstruction *MemInstr,
  142. const UnfoldStrategy S, const unsigned int FoldedInd);
  143. // Print the given table as a static const C++ array of type
  144. // X86MemoryFoldTableEntry.
  145. void printTable(const FoldTable &Table, StringRef TableName,
  146. formatted_raw_ostream &OS) {
  147. OS << "static const X86MemoryFoldTableEntry MemoryFold" << TableName
  148. << "[] = {\n";
  149. for (const X86FoldTableEntry &E : Table)
  150. E.print(OS);
  151. OS << "};\n\n";
  152. }
  153. };
  154. // Return true if one of the instruction's operands is a RST register class
  155. static bool hasRSTRegClass(const CodeGenInstruction *Inst) {
  156. return any_of(Inst->Operands, [](const CGIOperandList::OperandInfo &OpIn) {
  157. return OpIn.Rec->getName() == "RST" || OpIn.Rec->getName() == "RSTi";
  158. });
  159. }
  160. // Return true if one of the instruction's operands is a ptr_rc_tailcall
  161. static bool hasPtrTailcallRegClass(const CodeGenInstruction *Inst) {
  162. return any_of(Inst->Operands, [](const CGIOperandList::OperandInfo &OpIn) {
  163. return OpIn.Rec->getName() == "ptr_rc_tailcall";
  164. });
  165. }
  166. // Calculates the integer value representing the BitsInit object
  167. static inline uint64_t getValueFromBitsInit(const BitsInit *B) {
  168. assert(B->getNumBits() <= sizeof(uint64_t) * 8 && "BitInits' too long!");
  169. uint64_t Value = 0;
  170. for (unsigned i = 0, e = B->getNumBits(); i != e; ++i) {
  171. BitInit *Bit = cast<BitInit>(B->getBit(i));
  172. Value |= uint64_t(Bit->getValue()) << i;
  173. }
  174. return Value;
  175. }
  176. // Returns true if the two given BitsInits represent the same integer value
  177. static inline bool equalBitsInits(const BitsInit *B1, const BitsInit *B2) {
  178. if (B1->getNumBits() != B2->getNumBits())
  179. PrintFatalError("Comparing two BitsInits with different sizes!");
  180. for (unsigned i = 0, e = B1->getNumBits(); i != e; ++i) {
  181. BitInit *Bit1 = cast<BitInit>(B1->getBit(i));
  182. BitInit *Bit2 = cast<BitInit>(B2->getBit(i));
  183. if (Bit1->getValue() != Bit2->getValue())
  184. return false;
  185. }
  186. return true;
  187. }
  188. // Return the size of the register operand
  189. static inline unsigned int getRegOperandSize(const Record *RegRec) {
  190. if (RegRec->isSubClassOf("RegisterOperand"))
  191. RegRec = RegRec->getValueAsDef("RegClass");
  192. if (RegRec->isSubClassOf("RegisterClass"))
  193. return RegRec->getValueAsListOfDefs("RegTypes")[0]->getValueAsInt("Size");
  194. llvm_unreachable("Register operand's size not known!");
  195. }
  196. // Return the size of the memory operand
  197. static inline unsigned getMemOperandSize(const Record *MemRec) {
  198. if (MemRec->isSubClassOf("Operand")) {
  199. StringRef Name =
  200. MemRec->getValueAsDef("ParserMatchClass")->getValueAsString("Name");
  201. if (Name == "Mem8")
  202. return 8;
  203. if (Name == "Mem16")
  204. return 16;
  205. if (Name == "Mem32")
  206. return 32;
  207. if (Name == "Mem64")
  208. return 64;
  209. if (Name == "Mem80")
  210. return 80;
  211. if (Name == "Mem128")
  212. return 128;
  213. if (Name == "Mem256")
  214. return 256;
  215. if (Name == "Mem512")
  216. return 512;
  217. }
  218. llvm_unreachable("Memory operand's size not known!");
  219. }
  220. // Return true if the instruction defined as a register flavor.
  221. static inline bool hasRegisterFormat(const Record *Inst) {
  222. const BitsInit *FormBits = Inst->getValueAsBitsInit("FormBits");
  223. uint64_t FormBitsNum = getValueFromBitsInit(FormBits);
  224. // Values from X86Local namespace defined in X86RecognizableInstr.cpp
  225. return FormBitsNum >= X86Local::MRMDestReg && FormBitsNum <= X86Local::MRM7r;
  226. }
  227. // Return true if the instruction defined as a memory flavor.
  228. static inline bool hasMemoryFormat(const Record *Inst) {
  229. const BitsInit *FormBits = Inst->getValueAsBitsInit("FormBits");
  230. uint64_t FormBitsNum = getValueFromBitsInit(FormBits);
  231. // Values from X86Local namespace defined in X86RecognizableInstr.cpp
  232. return FormBitsNum >= X86Local::MRMDestMem && FormBitsNum <= X86Local::MRM7m;
  233. }
  234. static inline bool isNOREXRegClass(const Record *Op) {
  235. return Op->getName().contains("_NOREX");
  236. }
  237. static inline bool isRegisterOperand(const Record *Rec) {
  238. return Rec->isSubClassOf("RegisterClass") ||
  239. Rec->isSubClassOf("RegisterOperand") ||
  240. Rec->isSubClassOf("PointerLikeRegClass");
  241. }
  242. static inline bool isMemoryOperand(const Record *Rec) {
  243. return Rec->isSubClassOf("Operand") &&
  244. Rec->getValueAsString("OperandType") == "OPERAND_MEMORY";
  245. }
  246. static inline bool isImmediateOperand(const Record *Rec) {
  247. return Rec->isSubClassOf("Operand") &&
  248. Rec->getValueAsString("OperandType") == "OPERAND_IMMEDIATE";
  249. }
  250. // Get the alternative instruction pointed by "FoldGenRegForm" field.
  251. static inline const CodeGenInstruction *
  252. getAltRegInst(const CodeGenInstruction *I, const RecordKeeper &Records,
  253. const CodeGenTarget &Target) {
  254. StringRef AltRegInstStr = I->TheDef->getValueAsString("FoldGenRegForm");
  255. Record *AltRegInstRec = Records.getDef(AltRegInstStr);
  256. assert(AltRegInstRec &&
  257. "Alternative register form instruction def not found");
  258. CodeGenInstruction &AltRegInst = Target.getInstruction(AltRegInstRec);
  259. return &AltRegInst;
  260. }
  261. // Function object - Operator() returns true if the given VEX instruction
  262. // matches the EVEX instruction of this object.
  263. class IsMatch {
  264. const CodeGenInstruction *MemInst;
  265. public:
  266. IsMatch(const CodeGenInstruction *Inst, const RecordKeeper &Records)
  267. : MemInst(Inst) {}
  268. bool operator()(const CodeGenInstruction *RegInst) {
  269. Record *MemRec = MemInst->TheDef;
  270. Record *RegRec = RegInst->TheDef;
  271. // Return false if one (at least) of the encoding fields of both
  272. // instructions do not match.
  273. if (RegRec->getValueAsDef("OpEnc") != MemRec->getValueAsDef("OpEnc") ||
  274. !equalBitsInits(RegRec->getValueAsBitsInit("Opcode"),
  275. MemRec->getValueAsBitsInit("Opcode")) ||
  276. // VEX/EVEX fields
  277. RegRec->getValueAsDef("OpPrefix") !=
  278. MemRec->getValueAsDef("OpPrefix") ||
  279. RegRec->getValueAsDef("OpMap") != MemRec->getValueAsDef("OpMap") ||
  280. RegRec->getValueAsDef("OpSize") != MemRec->getValueAsDef("OpSize") ||
  281. RegRec->getValueAsDef("AdSize") != MemRec->getValueAsDef("AdSize") ||
  282. RegRec->getValueAsBit("hasVEX_4V") !=
  283. MemRec->getValueAsBit("hasVEX_4V") ||
  284. RegRec->getValueAsBit("hasEVEX_K") !=
  285. MemRec->getValueAsBit("hasEVEX_K") ||
  286. RegRec->getValueAsBit("hasEVEX_Z") !=
  287. MemRec->getValueAsBit("hasEVEX_Z") ||
  288. // EVEX_B means different things for memory and register forms.
  289. RegRec->getValueAsBit("hasEVEX_B") != 0 ||
  290. MemRec->getValueAsBit("hasEVEX_B") != 0 ||
  291. RegRec->getValueAsBit("hasEVEX_RC") !=
  292. MemRec->getValueAsBit("hasEVEX_RC") ||
  293. RegRec->getValueAsBit("hasREX_WPrefix") !=
  294. MemRec->getValueAsBit("hasREX_WPrefix") ||
  295. RegRec->getValueAsBit("hasLockPrefix") !=
  296. MemRec->getValueAsBit("hasLockPrefix") ||
  297. RegRec->getValueAsBit("hasNoTrackPrefix") !=
  298. MemRec->getValueAsBit("hasNoTrackPrefix") ||
  299. RegRec->getValueAsBit("hasVEX_L") !=
  300. MemRec->getValueAsBit("hasVEX_L") ||
  301. RegRec->getValueAsBit("hasEVEX_L2") !=
  302. MemRec->getValueAsBit("hasEVEX_L2") ||
  303. RegRec->getValueAsBit("ignoresVEX_L") !=
  304. MemRec->getValueAsBit("ignoresVEX_L") ||
  305. RegRec->getValueAsBit("HasVEX_W") !=
  306. MemRec->getValueAsBit("HasVEX_W") ||
  307. RegRec->getValueAsBit("IgnoresVEX_W") !=
  308. MemRec->getValueAsBit("IgnoresVEX_W") ||
  309. RegRec->getValueAsBit("EVEX_W1_VEX_W0") !=
  310. MemRec->getValueAsBit("EVEX_W1_VEX_W0") ||
  311. // Instruction's format - The register form's "Form" field should be
  312. // the opposite of the memory form's "Form" field.
  313. !areOppositeForms(RegRec->getValueAsBitsInit("FormBits"),
  314. MemRec->getValueAsBitsInit("FormBits")) ||
  315. RegRec->getValueAsBit("isAsmParserOnly") !=
  316. MemRec->getValueAsBit("isAsmParserOnly"))
  317. return false;
  318. // Make sure the sizes of the operands of both instructions suit each other.
  319. // This is needed for instructions with intrinsic version (_Int).
  320. // Where the only difference is the size of the operands.
  321. // For example: VUCOMISDZrm and Int_VUCOMISDrm
  322. // Also for instructions that their EVEX version was upgraded to work with
  323. // k-registers. For example VPCMPEQBrm (xmm output register) and
  324. // VPCMPEQBZ128rm (k register output register).
  325. bool ArgFolded = false;
  326. unsigned MemOutSize = MemRec->getValueAsDag("OutOperandList")->getNumArgs();
  327. unsigned RegOutSize = RegRec->getValueAsDag("OutOperandList")->getNumArgs();
  328. unsigned MemInSize = MemRec->getValueAsDag("InOperandList")->getNumArgs();
  329. unsigned RegInSize = RegRec->getValueAsDag("InOperandList")->getNumArgs();
  330. // Instructions with one output in their memory form use the memory folded
  331. // operand as source and destination (Read-Modify-Write).
  332. unsigned RegStartIdx =
  333. (MemOutSize + 1 == RegOutSize) && (MemInSize == RegInSize) ? 1 : 0;
  334. for (unsigned i = 0, e = MemInst->Operands.size(); i < e; i++) {
  335. Record *MemOpRec = MemInst->Operands[i].Rec;
  336. Record *RegOpRec = RegInst->Operands[i + RegStartIdx].Rec;
  337. if (MemOpRec == RegOpRec)
  338. continue;
  339. if (isRegisterOperand(MemOpRec) && isRegisterOperand(RegOpRec)) {
  340. if (getRegOperandSize(MemOpRec) != getRegOperandSize(RegOpRec) ||
  341. isNOREXRegClass(MemOpRec) != isNOREXRegClass(RegOpRec))
  342. return false;
  343. } else if (isMemoryOperand(MemOpRec) && isMemoryOperand(RegOpRec)) {
  344. if (getMemOperandSize(MemOpRec) != getMemOperandSize(RegOpRec))
  345. return false;
  346. } else if (isImmediateOperand(MemOpRec) && isImmediateOperand(RegOpRec)) {
  347. if (MemOpRec->getValueAsDef("Type") != RegOpRec->getValueAsDef("Type"))
  348. return false;
  349. } else {
  350. // Only one operand can be folded.
  351. if (ArgFolded)
  352. return false;
  353. assert(isRegisterOperand(RegOpRec) && isMemoryOperand(MemOpRec));
  354. ArgFolded = true;
  355. }
  356. }
  357. return true;
  358. }
  359. private:
  360. // Return true of the 2 given forms are the opposite of each other.
  361. bool areOppositeForms(const BitsInit *RegFormBits,
  362. const BitsInit *MemFormBits) {
  363. uint64_t MemFormNum = getValueFromBitsInit(MemFormBits);
  364. uint64_t RegFormNum = getValueFromBitsInit(RegFormBits);
  365. if ((MemFormNum == X86Local::MRM0m && RegFormNum == X86Local::MRM0r) ||
  366. (MemFormNum == X86Local::MRM1m && RegFormNum == X86Local::MRM1r) ||
  367. (MemFormNum == X86Local::MRM2m && RegFormNum == X86Local::MRM2r) ||
  368. (MemFormNum == X86Local::MRM3m && RegFormNum == X86Local::MRM3r) ||
  369. (MemFormNum == X86Local::MRM4m && RegFormNum == X86Local::MRM4r) ||
  370. (MemFormNum == X86Local::MRM5m && RegFormNum == X86Local::MRM5r) ||
  371. (MemFormNum == X86Local::MRM6m && RegFormNum == X86Local::MRM6r) ||
  372. (MemFormNum == X86Local::MRM7m && RegFormNum == X86Local::MRM7r) ||
  373. (MemFormNum == X86Local::MRMXm && RegFormNum == X86Local::MRMXr) ||
  374. (MemFormNum == X86Local::MRMXmCC && RegFormNum == X86Local::MRMXrCC) ||
  375. (MemFormNum == X86Local::MRMDestMem &&
  376. RegFormNum == X86Local::MRMDestReg) ||
  377. (MemFormNum == X86Local::MRMSrcMem &&
  378. RegFormNum == X86Local::MRMSrcReg) ||
  379. (MemFormNum == X86Local::MRMSrcMem4VOp3 &&
  380. RegFormNum == X86Local::MRMSrcReg4VOp3) ||
  381. (MemFormNum == X86Local::MRMSrcMemOp4 &&
  382. RegFormNum == X86Local::MRMSrcRegOp4) ||
  383. (MemFormNum == X86Local::MRMSrcMemCC &&
  384. RegFormNum == X86Local::MRMSrcRegCC))
  385. return true;
  386. return false;
  387. }
  388. };
  389. } // end anonymous namespace
  390. void X86FoldTablesEmitter::addEntryWithFlags(FoldTable &Table,
  391. const CodeGenInstruction *RegInstr,
  392. const CodeGenInstruction *MemInstr,
  393. const UnfoldStrategy S,
  394. const unsigned int FoldedInd) {
  395. X86FoldTableEntry Result = X86FoldTableEntry(RegInstr, MemInstr);
  396. Record *RegRec = RegInstr->TheDef;
  397. Record *MemRec = MemInstr->TheDef;
  398. // Only table0 entries should explicitly specify a load or store flag.
  399. if (&Table == &Table0) {
  400. unsigned MemInOpsNum = MemRec->getValueAsDag("InOperandList")->getNumArgs();
  401. unsigned RegInOpsNum = RegRec->getValueAsDag("InOperandList")->getNumArgs();
  402. // If the instruction writes to the folded operand, it will appear as an
  403. // output in the register form instruction and as an input in the memory
  404. // form instruction.
  405. // If the instruction reads from the folded operand, it well appear as in
  406. // input in both forms.
  407. if (MemInOpsNum == RegInOpsNum)
  408. Result.IsLoad = true;
  409. else
  410. Result.IsStore = true;
  411. }
  412. Record *RegOpRec = RegInstr->Operands[FoldedInd].Rec;
  413. Record *MemOpRec = MemInstr->Operands[FoldedInd].Rec;
  414. // Unfolding code generates a load/store instruction according to the size of
  415. // the register in the register form instruction.
  416. // If the register's size is greater than the memory's operand size, do not
  417. // allow unfolding.
  418. if (S == UNFOLD)
  419. Result.CannotUnfold = false;
  420. else if (S == NO_UNFOLD)
  421. Result.CannotUnfold = true;
  422. else if (getRegOperandSize(RegOpRec) > getMemOperandSize(MemOpRec))
  423. Result.CannotUnfold = true; // S == NO_STRATEGY
  424. uint64_t Enc = getValueFromBitsInit(RegRec->getValueAsBitsInit("OpEncBits"));
  425. if (isExplicitAlign(RegInstr)) {
  426. // The instruction require explicitly aligned memory.
  427. BitsInit *VectSize = RegRec->getValueAsBitsInit("VectSize");
  428. uint64_t Value = getValueFromBitsInit(VectSize);
  429. Result.IsAligned = true;
  430. Result.Alignment = Value;
  431. } else if (Enc != X86Local::XOP && Enc != X86Local::VEX &&
  432. Enc != X86Local::EVEX) {
  433. // Instructions with VEX encoding do not require alignment.
  434. if (!isExplicitUnalign(RegInstr) && getMemOperandSize(MemOpRec) > 64) {
  435. // SSE packed vector instructions require a 16 byte alignment.
  436. Result.IsAligned = true;
  437. Result.Alignment = 16;
  438. }
  439. }
  440. Table.push_back(Result);
  441. }
  442. void X86FoldTablesEmitter::updateTables(const CodeGenInstruction *RegInstr,
  443. const CodeGenInstruction *MemInstr,
  444. const UnfoldStrategy S) {
  445. Record *RegRec = RegInstr->TheDef;
  446. Record *MemRec = MemInstr->TheDef;
  447. unsigned MemOutSize = MemRec->getValueAsDag("OutOperandList")->getNumArgs();
  448. unsigned RegOutSize = RegRec->getValueAsDag("OutOperandList")->getNumArgs();
  449. unsigned MemInSize = MemRec->getValueAsDag("InOperandList")->getNumArgs();
  450. unsigned RegInSize = RegRec->getValueAsDag("InOperandList")->getNumArgs();
  451. // Instructions which Read-Modify-Write should be added to Table2Addr.
  452. if (MemOutSize != RegOutSize && MemInSize == RegInSize) {
  453. addEntryWithFlags(Table2Addr, RegInstr, MemInstr, S, 0);
  454. return;
  455. }
  456. if (MemInSize == RegInSize && MemOutSize == RegOutSize) {
  457. // Load-Folding cases.
  458. // If the i'th register form operand is a register and the i'th memory form
  459. // operand is a memory operand, add instructions to Table#i.
  460. for (unsigned i = RegOutSize, e = RegInstr->Operands.size(); i < e; i++) {
  461. Record *RegOpRec = RegInstr->Operands[i].Rec;
  462. Record *MemOpRec = MemInstr->Operands[i].Rec;
  463. if (isRegisterOperand(RegOpRec) && isMemoryOperand(MemOpRec)) {
  464. switch (i) {
  465. case 0:
  466. addEntryWithFlags(Table0, RegInstr, MemInstr, S, 0);
  467. return;
  468. case 1:
  469. addEntryWithFlags(Table1, RegInstr, MemInstr, S, 1);
  470. return;
  471. case 2:
  472. addEntryWithFlags(Table2, RegInstr, MemInstr, S, 2);
  473. return;
  474. case 3:
  475. addEntryWithFlags(Table3, RegInstr, MemInstr, S, 3);
  476. return;
  477. case 4:
  478. addEntryWithFlags(Table4, RegInstr, MemInstr, S, 4);
  479. return;
  480. }
  481. }
  482. }
  483. } else if (MemInSize == RegInSize + 1 && MemOutSize + 1 == RegOutSize) {
  484. // Store-Folding cases.
  485. // If the memory form instruction performs a store, the *output*
  486. // register of the register form instructions disappear and instead a
  487. // memory *input* operand appears in the memory form instruction.
  488. // For example:
  489. // MOVAPSrr => (outs VR128:$dst), (ins VR128:$src)
  490. // MOVAPSmr => (outs), (ins f128mem:$dst, VR128:$src)
  491. Record *RegOpRec = RegInstr->Operands[RegOutSize - 1].Rec;
  492. Record *MemOpRec = MemInstr->Operands[RegOutSize - 1].Rec;
  493. if (isRegisterOperand(RegOpRec) && isMemoryOperand(MemOpRec) &&
  494. getRegOperandSize(RegOpRec) == getMemOperandSize(MemOpRec))
  495. addEntryWithFlags(Table0, RegInstr, MemInstr, S, 0);
  496. }
  497. }
  498. void X86FoldTablesEmitter::run(formatted_raw_ostream &OS) {
  499. emitSourceFileHeader("X86 fold tables", OS);
  500. // Holds all memory instructions
  501. std::vector<const CodeGenInstruction *> MemInsts;
  502. // Holds all register instructions - divided according to opcode.
  503. std::map<uint8_t, std::vector<const CodeGenInstruction *>> RegInsts;
  504. ArrayRef<const CodeGenInstruction *> NumberedInstructions =
  505. Target.getInstructionsByEnumValue();
  506. for (const CodeGenInstruction *Inst : NumberedInstructions) {
  507. if (!Inst->TheDef->getNameInit() || !Inst->TheDef->isSubClassOf("X86Inst"))
  508. continue;
  509. const Record *Rec = Inst->TheDef;
  510. // - Do not proceed if the instruction is marked as notMemoryFoldable.
  511. // - Instructions including RST register class operands are not relevant
  512. // for memory folding (for further details check the explanation in
  513. // lib/Target/X86/X86InstrFPStack.td file).
  514. // - Some instructions (listed in the manual map above) use the register
  515. // class ptr_rc_tailcall, which can be of a size 32 or 64, to ensure
  516. // safe mapping of these instruction we manually map them and exclude
  517. // them from the automation.
  518. if (Rec->getValueAsBit("isMemoryFoldable") == false ||
  519. hasRSTRegClass(Inst) || hasPtrTailcallRegClass(Inst))
  520. continue;
  521. // Add all the memory form instructions to MemInsts, and all the register
  522. // form instructions to RegInsts[Opc], where Opc in the opcode of each
  523. // instructions. this helps reducing the runtime of the backend.
  524. if (hasMemoryFormat(Rec))
  525. MemInsts.push_back(Inst);
  526. else if (hasRegisterFormat(Rec)) {
  527. uint8_t Opc = getValueFromBitsInit(Rec->getValueAsBitsInit("Opcode"));
  528. RegInsts[Opc].push_back(Inst);
  529. }
  530. }
  531. // For each memory form instruction, try to find its register form
  532. // instruction.
  533. for (const CodeGenInstruction *MemInst : MemInsts) {
  534. uint8_t Opc =
  535. getValueFromBitsInit(MemInst->TheDef->getValueAsBitsInit("Opcode"));
  536. auto RegInstsIt = RegInsts.find(Opc);
  537. if (RegInstsIt == RegInsts.end())
  538. continue;
  539. // Two forms (memory & register) of the same instruction must have the same
  540. // opcode. try matching only with register form instructions with the same
  541. // opcode.
  542. std::vector<const CodeGenInstruction *> &OpcRegInsts = RegInstsIt->second;
  543. auto Match = find_if(OpcRegInsts, IsMatch(MemInst, Records));
  544. if (Match != OpcRegInsts.end()) {
  545. const CodeGenInstruction *RegInst = *Match;
  546. // If the matched instruction has it's "FoldGenRegForm" set, map the
  547. // memory form instruction to the register form instruction pointed by
  548. // this field
  549. if (RegInst->TheDef->isValueUnset("FoldGenRegForm")) {
  550. updateTables(RegInst, MemInst);
  551. } else {
  552. const CodeGenInstruction *AltRegInst =
  553. getAltRegInst(RegInst, Records, Target);
  554. updateTables(AltRegInst, MemInst);
  555. }
  556. OpcRegInsts.erase(Match);
  557. }
  558. }
  559. // Add the manually mapped instructions listed above.
  560. for (const ManualMapEntry &Entry : ManualMapSet) {
  561. Record *RegInstIter = Records.getDef(Entry.RegInstStr);
  562. Record *MemInstIter = Records.getDef(Entry.MemInstStr);
  563. updateTables(&(Target.getInstruction(RegInstIter)),
  564. &(Target.getInstruction(MemInstIter)), Entry.Strategy);
  565. }
  566. // Sort the tables before printing.
  567. llvm::sort(Table2Addr);
  568. llvm::sort(Table0);
  569. llvm::sort(Table1);
  570. llvm::sort(Table2);
  571. llvm::sort(Table3);
  572. llvm::sort(Table4);
  573. // Print all tables.
  574. printTable(Table2Addr, "Table2Addr", OS);
  575. printTable(Table0, "Table0", OS);
  576. printTable(Table1, "Table1", OS);
  577. printTable(Table2, "Table2", OS);
  578. printTable(Table3, "Table3", OS);
  579. printTable(Table4, "Table4", OS);
  580. }
  581. namespace llvm {
  582. void EmitX86FoldTables(RecordKeeper &RK, raw_ostream &o) {
  583. formatted_raw_ostream OS(o);
  584. X86FoldTablesEmitter(RK).run(OS);
  585. }
  586. } // namespace llvm