EDEmitter.cpp revision 36c3bc431b92f1573b3f3bd75b644774681998ee
1//===- EDEmitter.cpp - Generate instruction descriptions for ED -*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This tablegen backend is responsible for emitting a description of each 11// instruction in a format that the enhanced disassembler can use to tokenize 12// and parse instructions. 13// 14//===----------------------------------------------------------------------===// 15 16#include "EDEmitter.h" 17 18#include "AsmWriterInst.h" 19#include "CodeGenTarget.h" 20#include "Record.h" 21 22#include "llvm/MC/EDInstInfo.h" 23#include "llvm/Support/ErrorHandling.h" 24#include "llvm/Support/Format.h" 25#include "llvm/Support/raw_ostream.h" 26 27#include <map> 28#include <string> 29#include <vector> 30 31using namespace llvm; 32 33/////////////////////////////////////////////////////////// 34// Support classes for emitting nested C data structures // 35/////////////////////////////////////////////////////////// 36 37namespace { 38 39 class EnumEmitter { 40 private: 41 std::string Name; 42 std::vector<std::string> Entries; 43 public: 44 EnumEmitter(const char *N) : Name(N) { 45 } 46 int addEntry(const char *e) { 47 Entries.push_back(std::string(e)); 48 return Entries.size() - 1; 49 } 50 void emit(raw_ostream &o, unsigned int &i) { 51 o.indent(i) << "enum " << Name.c_str() << " {" << "\n"; 52 i += 2; 53 54 unsigned int index = 0; 55 unsigned int numEntries = Entries.size(); 56 for (index = 0; index < numEntries; ++index) { 57 o.indent(i) << Entries[index]; 58 if (index < (numEntries - 1)) 59 o << ","; 60 o << "\n"; 61 } 62 63 i -= 2; 64 o.indent(i) << "};" << "\n"; 65 } 66 67 void emitAsFlags(raw_ostream &o, unsigned int &i) { 68 o.indent(i) << "enum " << Name.c_str() << " {" << "\n"; 69 i += 2; 70 71 unsigned int index = 0; 72 unsigned int numEntries = Entries.size(); 73 unsigned int flag = 1; 74 for (index = 0; index < numEntries; ++index) { 75 o.indent(i) << Entries[index] << " = " << format("0x%x", flag); 76 if (index < (numEntries - 1)) 77 o << ","; 78 o << "\n"; 79 flag <<= 1; 80 } 81 82 i -= 2; 83 o.indent(i) << "};" << "\n"; 84 } 85 }; 86 87 class ConstantEmitter { 88 public: 89 virtual ~ConstantEmitter() { } 90 virtual void emit(raw_ostream &o, unsigned int &i) = 0; 91 }; 92 93 class LiteralConstantEmitter : public ConstantEmitter { 94 private: 95 bool IsNumber; 96 union { 97 int Number; 98 const char* String; 99 }; 100 public: 101 LiteralConstantEmitter(int number = 0) : 102 IsNumber(true), 103 Number(number) { 104 } 105 void set(const char *string) { 106 IsNumber = false; 107 Number = 0; 108 String = string; 109 } 110 bool is(const char *string) { 111 return !strcmp(String, string); 112 } 113 void emit(raw_ostream &o, unsigned int &i) { 114 if (IsNumber) 115 o << Number; 116 else 117 o << String; 118 } 119 }; 120 121 class CompoundConstantEmitter : public ConstantEmitter { 122 private: 123 unsigned int Padding; 124 std::vector<ConstantEmitter *> Entries; 125 public: 126 CompoundConstantEmitter(unsigned int padding = 0) : Padding(padding) { 127 } 128 CompoundConstantEmitter &addEntry(ConstantEmitter *e) { 129 Entries.push_back(e); 130 131 return *this; 132 } 133 ~CompoundConstantEmitter() { 134 while (Entries.size()) { 135 ConstantEmitter *entry = Entries.back(); 136 Entries.pop_back(); 137 delete entry; 138 } 139 } 140 void emit(raw_ostream &o, unsigned int &i) { 141 o << "{" << "\n"; 142 i += 2; 143 144 unsigned int index; 145 unsigned int numEntries = Entries.size(); 146 147 unsigned int numToPrint; 148 149 if (Padding) { 150 if (numEntries > Padding) { 151 fprintf(stderr, "%u entries but %u padding\n", numEntries, Padding); 152 llvm_unreachable("More entries than padding"); 153 } 154 numToPrint = Padding; 155 } else { 156 numToPrint = numEntries; 157 } 158 159 for (index = 0; index < numToPrint; ++index) { 160 o.indent(i); 161 if (index < numEntries) 162 Entries[index]->emit(o, i); 163 else 164 o << "-1"; 165 166 if (index < (numToPrint - 1)) 167 o << ","; 168 o << "\n"; 169 } 170 171 i -= 2; 172 o.indent(i) << "}"; 173 } 174 }; 175 176 class FlagsConstantEmitter : public ConstantEmitter { 177 private: 178 std::vector<std::string> Flags; 179 public: 180 FlagsConstantEmitter() { 181 } 182 FlagsConstantEmitter &addEntry(const char *f) { 183 Flags.push_back(std::string(f)); 184 return *this; 185 } 186 void emit(raw_ostream &o, unsigned int &i) { 187 unsigned int index; 188 unsigned int numFlags = Flags.size(); 189 if (numFlags == 0) 190 o << "0"; 191 192 for (index = 0; index < numFlags; ++index) { 193 o << Flags[index].c_str(); 194 if (index < (numFlags - 1)) 195 o << " | "; 196 } 197 } 198 }; 199} 200 201EDEmitter::EDEmitter(RecordKeeper &R) : Records(R) { 202} 203 204/// populateOperandOrder - Accepts a CodeGenInstruction and generates its 205/// AsmWriterInst for the desired assembly syntax, giving an ordered list of 206/// operands in the order they appear in the printed instruction. Then, for 207/// each entry in that list, determines the index of the same operand in the 208/// CodeGenInstruction, and emits the resulting mapping into an array, filling 209/// in unused slots with -1. 210/// 211/// @arg operandOrder - The array that will be populated with the operand 212/// mapping. Each entry will contain -1 (invalid index 213/// into the operands present in the AsmString) or a number 214/// representing an index in the operand descriptor array. 215/// @arg inst - The instruction to use when looking up the operands 216/// @arg syntax - The syntax to use, according to LLVM's enumeration 217void populateOperandOrder(CompoundConstantEmitter *operandOrder, 218 const CodeGenInstruction &inst, 219 unsigned syntax) { 220 unsigned int numArgs = 0; 221 222 AsmWriterInst awInst(inst, syntax, -1, -1); 223 224 std::vector<AsmWriterOperand>::iterator operandIterator; 225 226 for (operandIterator = awInst.Operands.begin(); 227 operandIterator != awInst.Operands.end(); 228 ++operandIterator) { 229 if (operandIterator->OperandType == 230 AsmWriterOperand::isMachineInstrOperand) { 231 operandOrder->addEntry( 232 new LiteralConstantEmitter(operandIterator->CGIOpNo)); 233 numArgs++; 234 } 235 } 236} 237 238///////////////////////////////////////////////////// 239// Support functions for handling X86 instructions // 240///////////////////////////////////////////////////// 241 242#define SET(flag) { type->set(flag); return 0; } 243 244#define REG(str) if (name == str) SET("kOperandTypeRegister"); 245#define MEM(str) if (name == str) SET("kOperandTypeX86Memory"); 246#define LEA(str) if (name == str) SET("kOperandTypeX86EffectiveAddress"); 247#define IMM(str) if (name == str) SET("kOperandTypeImmediate"); 248#define PCR(str) if (name == str) SET("kOperandTypeX86PCRelative"); 249 250/// X86TypeFromOpName - Processes the name of a single X86 operand (which is 251/// actually its type) and translates it into an operand type 252/// 253/// @arg flags - The type object to set 254/// @arg name - The name of the operand 255static int X86TypeFromOpName(LiteralConstantEmitter *type, 256 const std::string &name) { 257 REG("GR8"); 258 REG("GR8_NOREX"); 259 REG("GR16"); 260 REG("GR32"); 261 REG("GR32_NOREX"); 262 REG("GR32_TC"); 263 REG("FR32"); 264 REG("RFP32"); 265 REG("GR64"); 266 REG("GR64_TC"); 267 REG("FR64"); 268 REG("VR64"); 269 REG("RFP64"); 270 REG("RFP80"); 271 REG("VR128"); 272 REG("VR256"); 273 REG("RST"); 274 REG("SEGMENT_REG"); 275 REG("DEBUG_REG"); 276 REG("CONTROL_REG"); 277 278 IMM("i8imm"); 279 IMM("i16imm"); 280 IMM("i16i8imm"); 281 IMM("i32imm"); 282 IMM("i32i8imm"); 283 IMM("i64imm"); 284 IMM("i64i8imm"); 285 IMM("i64i32imm"); 286 IMM("SSECC"); 287 288 // all R, I, R, I, R 289 MEM("i8mem"); 290 MEM("i8mem_NOREX"); 291 MEM("i16mem"); 292 MEM("i32mem"); 293 MEM("i32mem_TC"); 294 MEM("f32mem"); 295 MEM("ssmem"); 296 MEM("opaque32mem"); 297 MEM("opaque48mem"); 298 MEM("i64mem"); 299 MEM("i64mem_TC"); 300 MEM("f64mem"); 301 MEM("sdmem"); 302 MEM("f80mem"); 303 MEM("opaque80mem"); 304 MEM("i128mem"); 305 MEM("i256mem"); 306 MEM("f128mem"); 307 MEM("f256mem"); 308 MEM("opaque512mem"); 309 310 // all R, I, R, I 311 LEA("lea32mem"); 312 LEA("lea64_32mem"); 313 LEA("lea64mem"); 314 315 // all I 316 PCR("i16imm_pcrel"); 317 PCR("i32imm_pcrel"); 318 PCR("i64i32imm_pcrel"); 319 PCR("brtarget8"); 320 PCR("offset8"); 321 PCR("offset16"); 322 PCR("offset32"); 323 PCR("offset64"); 324 PCR("brtarget"); 325 PCR("uncondbrtarget"); 326 PCR("bltarget"); 327 328 return 1; 329} 330 331#undef REG 332#undef MEM 333#undef LEA 334#undef IMM 335#undef PCR 336 337#undef SET 338 339/// X86PopulateOperands - Handles all the operands in an X86 instruction, adding 340/// the appropriate flags to their descriptors 341/// 342/// @operandFlags - A reference the array of operand flag objects 343/// @inst - The instruction to use as a source of information 344static void X86PopulateOperands( 345 LiteralConstantEmitter *(&operandTypes)[EDIS_MAX_OPERANDS], 346 const CodeGenInstruction &inst) { 347 if (!inst.TheDef->isSubClassOf("X86Inst")) 348 return; 349 350 unsigned int index; 351 unsigned int numOperands = inst.Operands.size(); 352 353 for (index = 0; index < numOperands; ++index) { 354 const CGIOperandList::OperandInfo &operandInfo = inst.Operands[index]; 355 Record &rec = *operandInfo.Rec; 356 357 if (X86TypeFromOpName(operandTypes[index], rec.getName()) && 358 !rec.isSubClassOf("PointerLikeRegClass")) { 359 errs() << "Operand type: " << rec.getName().c_str() << "\n"; 360 errs() << "Operand name: " << operandInfo.Name.c_str() << "\n"; 361 errs() << "Instruction name: " << inst.TheDef->getName().c_str() << "\n"; 362 llvm_unreachable("Unhandled type"); 363 } 364 } 365} 366 367/// decorate1 - Decorates a named operand with a new flag 368/// 369/// @operandFlags - The array of operand flag objects, which don't have names 370/// @inst - The CodeGenInstruction, which provides a way to translate 371/// between names and operand indices 372/// @opName - The name of the operand 373/// @flag - The name of the flag to add 374static inline void decorate1( 375 FlagsConstantEmitter *(&operandFlags)[EDIS_MAX_OPERANDS], 376 const CodeGenInstruction &inst, 377 const char *opName, 378 const char *opFlag) { 379 unsigned opIndex; 380 381 opIndex = inst.Operands.getOperandNamed(std::string(opName)); 382 383 operandFlags[opIndex]->addEntry(opFlag); 384} 385 386#define DECORATE1(opName, opFlag) decorate1(operandFlags, inst, opName, opFlag) 387 388#define MOV(source, target) { \ 389 instType.set("kInstructionTypeMove"); \ 390 DECORATE1(source, "kOperandFlagSource"); \ 391 DECORATE1(target, "kOperandFlagTarget"); \ 392} 393 394#define BRANCH(target) { \ 395 instType.set("kInstructionTypeBranch"); \ 396 DECORATE1(target, "kOperandFlagTarget"); \ 397} 398 399#define PUSH(source) { \ 400 instType.set("kInstructionTypePush"); \ 401 DECORATE1(source, "kOperandFlagSource"); \ 402} 403 404#define POP(target) { \ 405 instType.set("kInstructionTypePop"); \ 406 DECORATE1(target, "kOperandFlagTarget"); \ 407} 408 409#define CALL(target) { \ 410 instType.set("kInstructionTypeCall"); \ 411 DECORATE1(target, "kOperandFlagTarget"); \ 412} 413 414#define RETURN() { \ 415 instType.set("kInstructionTypeReturn"); \ 416} 417 418/// X86ExtractSemantics - Performs various checks on the name of an X86 419/// instruction to determine what sort of an instruction it is and then adds 420/// the appropriate flags to the instruction and its operands 421/// 422/// @arg instType - A reference to the type for the instruction as a whole 423/// @arg operandFlags - A reference to the array of operand flag object pointers 424/// @arg inst - A reference to the original instruction 425static void X86ExtractSemantics( 426 LiteralConstantEmitter &instType, 427 FlagsConstantEmitter *(&operandFlags)[EDIS_MAX_OPERANDS], 428 const CodeGenInstruction &inst) { 429 const std::string &name = inst.TheDef->getName(); 430 431 if (name.find("MOV") != name.npos) { 432 if (name.find("MOV_V") != name.npos) { 433 // ignore (this is a pseudoinstruction) 434 } else if (name.find("MASK") != name.npos) { 435 // ignore (this is a masking move) 436 } else if (name.find("r0") != name.npos) { 437 // ignore (this is a pseudoinstruction) 438 } else if (name.find("PS") != name.npos || 439 name.find("PD") != name.npos) { 440 // ignore (this is a shuffling move) 441 } else if (name.find("MOVS") != name.npos) { 442 // ignore (this is a string move) 443 } else if (name.find("_F") != name.npos) { 444 // TODO handle _F moves to ST(0) 445 } else if (name.find("a") != name.npos) { 446 // TODO handle moves to/from %ax 447 } else if (name.find("CMOV") != name.npos) { 448 MOV("src2", "dst"); 449 } else if (name.find("PC") != name.npos) { 450 MOV("label", "reg") 451 } else { 452 MOV("src", "dst"); 453 } 454 } 455 456 if (name.find("JMP") != name.npos || 457 name.find("J") == 0) { 458 if (name.find("FAR") != name.npos && name.find("i") != name.npos) { 459 BRANCH("off"); 460 } else { 461 BRANCH("dst"); 462 } 463 } 464 465 if (name.find("PUSH") != name.npos) { 466 if (name.find("CS") != name.npos || 467 name.find("DS") != name.npos || 468 name.find("ES") != name.npos || 469 name.find("FS") != name.npos || 470 name.find("GS") != name.npos || 471 name.find("SS") != name.npos) { 472 instType.set("kInstructionTypePush"); 473 // TODO add support for fixed operands 474 } else if (name.find("F") != name.npos) { 475 // ignore (this pushes onto the FP stack) 476 } else if (name.find("A") != name.npos) { 477 // ignore (pushes all GP registoers onto the stack) 478 } else if (name[name.length() - 1] == 'm') { 479 PUSH("src"); 480 } else if (name.find("i") != name.npos) { 481 PUSH("imm"); 482 } else { 483 PUSH("reg"); 484 } 485 } 486 487 if (name.find("POP") != name.npos) { 488 if (name.find("POPCNT") != name.npos) { 489 // ignore (not a real pop) 490 } else if (name.find("CS") != name.npos || 491 name.find("DS") != name.npos || 492 name.find("ES") != name.npos || 493 name.find("FS") != name.npos || 494 name.find("GS") != name.npos || 495 name.find("SS") != name.npos) { 496 instType.set("kInstructionTypePop"); 497 // TODO add support for fixed operands 498 } else if (name.find("F") != name.npos) { 499 // ignore (this pops from the FP stack) 500 } else if (name.find("A") != name.npos) { 501 // ignore (pushes all GP registoers onto the stack) 502 } else if (name[name.length() - 1] == 'm') { 503 POP("dst"); 504 } else { 505 POP("reg"); 506 } 507 } 508 509 if (name.find("CALL") != name.npos) { 510 if (name.find("ADJ") != name.npos) { 511 // ignore (not a call) 512 } else if (name.find("SYSCALL") != name.npos) { 513 // ignore (doesn't go anywhere we know about) 514 } else if (name.find("VMCALL") != name.npos) { 515 // ignore (rather different semantics than a regular call) 516 } else if (name.find("FAR") != name.npos && name.find("i") != name.npos) { 517 CALL("off"); 518 } else { 519 CALL("dst"); 520 } 521 } 522 523 if (name.find("RET") != name.npos) { 524 RETURN(); 525 } 526} 527 528#undef MOV 529#undef BRANCH 530#undef PUSH 531#undef POP 532#undef CALL 533#undef RETURN 534 535///////////////////////////////////////////////////// 536// Support functions for handling ARM instructions // 537///////////////////////////////////////////////////// 538 539#define SET(flag) { type->set(flag); return 0; } 540 541#define REG(str) if (name == str) SET("kOperandTypeRegister"); 542#define IMM(str) if (name == str) SET("kOperandTypeImmediate"); 543 544#define MISC(str, type) if (name == str) SET(type); 545 546/// ARMFlagFromOpName - Processes the name of a single ARM operand (which is 547/// actually its type) and translates it into an operand type 548/// 549/// @arg type - The type object to set 550/// @arg name - The name of the operand 551static int ARMFlagFromOpName(LiteralConstantEmitter *type, 552 const std::string &name) { 553 REG("GPR"); 554 REG("rGPR"); 555 REG("tcGPR"); 556 REG("cc_out"); 557 REG("s_cc_out"); 558 REG("tGPR"); 559 REG("DPR"); 560 REG("DPR_VFP2"); 561 REG("DPR_8"); 562 REG("SPR"); 563 REG("QPR"); 564 REG("QQPR"); 565 REG("QQQQPR"); 566 567 IMM("i32imm"); 568 IMM("i32imm_hilo16"); 569 IMM("bf_inv_mask_imm"); 570 IMM("lsb_pos_imm"); 571 IMM("width_imm"); 572 IMM("jtblock_operand"); 573 IMM("nohash_imm"); 574 IMM("p_imm"); 575 IMM("c_imm"); 576 IMM("cpinst_operand"); 577 IMM("setend_op"); 578 IMM("cps_opt"); 579 IMM("vfp_f64imm"); 580 IMM("vfp_f32imm"); 581 IMM("memb_opt"); 582 IMM("msr_mask"); 583 IMM("neg_zero"); 584 IMM("imm0_31"); 585 IMM("imm0_31_m1"); 586 IMM("nModImm"); 587 IMM("imm0_4095"); 588 IMM("jt2block_operand"); 589 IMM("t_imm_s4"); 590 IMM("pclabel"); 591 IMM("adrlabel"); 592 IMM("t_adrlabel"); 593 IMM("t2adrlabel"); 594 IMM("shift_imm"); 595 IMM("neon_vcvt_imm32"); 596 597 MISC("brtarget", "kOperandTypeARMBranchTarget"); // ? 598 MISC("uncondbrtarget", "kOperandTypeARMBranchTarget"); // ? 599 MISC("t_brtarget", "kOperandTypeARMBranchTarget"); // ? 600 MISC("t_bcctarget", "kOperandTypeARMBranchTarget"); // ? 601 MISC("t_cbtarget", "kOperandTypeARMBranchTarget"); // ? 602 MISC("bltarget", "kOperandTypeARMBranchTarget"); // ? 603 MISC("t_bltarget", "kOperandTypeARMBranchTarget"); // ? 604 MISC("t_blxtarget", "kOperandTypeARMBranchTarget"); // ? 605 MISC("so_reg", "kOperandTypeARMSoReg"); // R, R, I 606 MISC("shift_so_reg", "kOperandTypeARMSoReg"); // R, R, I 607 MISC("t2_so_reg", "kOperandTypeThumb2SoReg"); // R, I 608 MISC("so_imm", "kOperandTypeARMSoImm"); // I 609 MISC("rot_imm", "kOperandTypeARMRotImm"); // I 610 MISC("t2_so_imm", "kOperandTypeThumb2SoImm"); // I 611 MISC("so_imm2part", "kOperandTypeARMSoImm2Part"); // I 612 MISC("pred", "kOperandTypeARMPredicate"); // I, R 613 MISC("it_pred", "kOperandTypeARMPredicate"); // I 614 MISC("addrmode_imm12", "kOperandTypeAddrModeImm12"); // R, I 615 MISC("ldst_so_reg", "kOperandTypeLdStSOReg"); // R, R, I 616 MISC("addrmode2", "kOperandTypeARMAddrMode2"); // R, R, I 617 MISC("am2offset", "kOperandTypeARMAddrMode2Offset"); // R, I 618 MISC("addrmode3", "kOperandTypeARMAddrMode3"); // R, R, I 619 MISC("am3offset", "kOperandTypeARMAddrMode3Offset"); // R, I 620 MISC("ldstm_mode", "kOperandTypeARMLdStmMode"); // I 621 MISC("addrmode5", "kOperandTypeARMAddrMode5"); // R, I 622 MISC("addrmode6", "kOperandTypeARMAddrMode6"); // R, R, I, I 623 MISC("am6offset", "kOperandTypeARMAddrMode6Offset"); // R, I, I 624 MISC("addrmode6dup", "kOperandTypeARMAddrMode6"); // R, R, I, I 625 MISC("addrmodepc", "kOperandTypeARMAddrModePC"); // R, I 626 MISC("reglist", "kOperandTypeARMRegisterList"); // I, R, ... 627 MISC("dpr_reglist", "kOperandTypeARMDPRRegisterList"); // I, R, ... 628 MISC("spr_reglist", "kOperandTypeARMSPRRegisterList"); // I, R, ... 629 MISC("it_mask", "kOperandTypeThumbITMask"); // I 630 MISC("t2addrmode_imm8", "kOperandTypeThumb2AddrModeImm8"); // R, I 631 MISC("t2am_imm8_offset", "kOperandTypeThumb2AddrModeImm8Offset");//I 632 MISC("t2addrmode_imm12", "kOperandTypeThumb2AddrModeImm12"); // R, I 633 MISC("t2addrmode_so_reg", "kOperandTypeThumb2AddrModeSoReg"); // R, R, I 634 MISC("t2addrmode_imm8s4", "kOperandTypeThumb2AddrModeImm8s4"); // R, I 635 MISC("t2am_imm8s4_offset", "kOperandTypeThumb2AddrModeImm8s4Offset"); 636 // R, I 637 MISC("tb_addrmode", "kOperandTypeARMTBAddrMode"); // I 638 MISC("t_addrmode_rrs1", "kOperandTypeThumbAddrModeRegS"); // R, R 639 MISC("t_addrmode_rrs2", "kOperandTypeThumbAddrModeRegS"); // R, R 640 MISC("t_addrmode_rrs4", "kOperandTypeThumbAddrModeRegS"); // R, R 641 MISC("t_addrmode_is1", "kOperandTypeThumbAddrModeImmS"); // R, I 642 MISC("t_addrmode_is2", "kOperandTypeThumbAddrModeImmS"); // R, I 643 MISC("t_addrmode_is4", "kOperandTypeThumbAddrModeImmS"); // R, I 644 MISC("t_addrmode_rr", "kOperandTypeThumbAddrModeRR"); // R, R 645 MISC("t_addrmode_sp", "kOperandTypeThumbAddrModeSP"); // R, I 646 MISC("t_addrmode_pc", "kOperandTypeThumbAddrModePC"); // R, I 647 648 return 1; 649} 650 651#undef SOREG 652#undef SOIMM 653#undef PRED 654#undef REG 655#undef MEM 656#undef LEA 657#undef IMM 658#undef PCR 659 660#undef SET 661 662/// ARMPopulateOperands - Handles all the operands in an ARM instruction, adding 663/// the appropriate flags to their descriptors 664/// 665/// @operandFlags - A reference the array of operand flag objects 666/// @inst - The instruction to use as a source of information 667static void ARMPopulateOperands( 668 LiteralConstantEmitter *(&operandTypes)[EDIS_MAX_OPERANDS], 669 const CodeGenInstruction &inst) { 670 if (!inst.TheDef->isSubClassOf("InstARM") && 671 !inst.TheDef->isSubClassOf("InstThumb")) 672 return; 673 674 unsigned int index; 675 unsigned int numOperands = inst.Operands.size(); 676 677 if (numOperands > EDIS_MAX_OPERANDS) { 678 errs() << "numOperands == " << numOperands << " > " << 679 EDIS_MAX_OPERANDS << '\n'; 680 llvm_unreachable("Too many operands"); 681 } 682 683 for (index = 0; index < numOperands; ++index) { 684 const CGIOperandList::OperandInfo &operandInfo = inst.Operands[index]; 685 Record &rec = *operandInfo.Rec; 686 687 if (ARMFlagFromOpName(operandTypes[index], rec.getName())) { 688 errs() << "Operand type: " << rec.getName() << '\n'; 689 errs() << "Operand name: " << operandInfo.Name << '\n'; 690 errs() << "Instruction name: " << inst.TheDef->getName() << '\n'; 691 llvm_unreachable("Unhandled type"); 692 } 693 } 694} 695 696#define BRANCH(target) { \ 697 instType.set("kInstructionTypeBranch"); \ 698 DECORATE1(target, "kOperandFlagTarget"); \ 699} 700 701/// ARMExtractSemantics - Performs various checks on the name of an ARM 702/// instruction to determine what sort of an instruction it is and then adds 703/// the appropriate flags to the instruction and its operands 704/// 705/// @arg instType - A reference to the type for the instruction as a whole 706/// @arg operandTypes - A reference to the array of operand type object pointers 707/// @arg operandFlags - A reference to the array of operand flag object pointers 708/// @arg inst - A reference to the original instruction 709static void ARMExtractSemantics( 710 LiteralConstantEmitter &instType, 711 LiteralConstantEmitter *(&operandTypes)[EDIS_MAX_OPERANDS], 712 FlagsConstantEmitter *(&operandFlags)[EDIS_MAX_OPERANDS], 713 const CodeGenInstruction &inst) { 714 const std::string &name = inst.TheDef->getName(); 715 716 if (name == "tBcc" || 717 name == "tB" || 718 name == "t2Bcc" || 719 name == "Bcc" || 720 name == "tCBZ" || 721 name == "tCBNZ") { 722 BRANCH("target"); 723 } 724 725 if (name == "tBLr9" || 726 name == "BLr9_pred" || 727 name == "tBLXi_r9" || 728 name == "tBLXr_r9" || 729 name == "BLXr9" || 730 name == "t2BXJ" || 731 name == "BXJ") { 732 BRANCH("func"); 733 734 unsigned opIndex; 735 opIndex = inst.Operands.getOperandNamed("func"); 736 if (operandTypes[opIndex]->is("kOperandTypeImmediate")) 737 operandTypes[opIndex]->set("kOperandTypeARMBranchTarget"); 738 } 739} 740 741#undef BRANCH 742 743/// populateInstInfo - Fills an array of InstInfos with information about each 744/// instruction in a target 745/// 746/// @arg infoArray - The array of InstInfo objects to populate 747/// @arg target - The CodeGenTarget to use as a source of instructions 748static void populateInstInfo(CompoundConstantEmitter &infoArray, 749 CodeGenTarget &target) { 750 const std::vector<const CodeGenInstruction*> &numberedInstructions = 751 target.getInstructionsByEnumValue(); 752 753 unsigned int index; 754 unsigned int numInstructions = numberedInstructions.size(); 755 756 for (index = 0; index < numInstructions; ++index) { 757 const CodeGenInstruction& inst = *numberedInstructions[index]; 758 759 CompoundConstantEmitter *infoStruct = new CompoundConstantEmitter; 760 infoArray.addEntry(infoStruct); 761 762 LiteralConstantEmitter *instType = new LiteralConstantEmitter; 763 infoStruct->addEntry(instType); 764 765 LiteralConstantEmitter *numOperandsEmitter = 766 new LiteralConstantEmitter(inst.Operands.size()); 767 infoStruct->addEntry(numOperandsEmitter); 768 769 CompoundConstantEmitter *operandTypeArray = new CompoundConstantEmitter; 770 infoStruct->addEntry(operandTypeArray); 771 772 LiteralConstantEmitter *operandTypes[EDIS_MAX_OPERANDS]; 773 774 CompoundConstantEmitter *operandFlagArray = new CompoundConstantEmitter; 775 infoStruct->addEntry(operandFlagArray); 776 777 FlagsConstantEmitter *operandFlags[EDIS_MAX_OPERANDS]; 778 779 for (unsigned operandIndex = 0; 780 operandIndex < EDIS_MAX_OPERANDS; 781 ++operandIndex) { 782 operandTypes[operandIndex] = new LiteralConstantEmitter; 783 operandTypeArray->addEntry(operandTypes[operandIndex]); 784 785 operandFlags[operandIndex] = new FlagsConstantEmitter; 786 operandFlagArray->addEntry(operandFlags[operandIndex]); 787 } 788 789 unsigned numSyntaxes = 0; 790 791 if (target.getName() == "X86") { 792 X86PopulateOperands(operandTypes, inst); 793 X86ExtractSemantics(*instType, operandFlags, inst); 794 numSyntaxes = 2; 795 } 796 else if (target.getName() == "ARM") { 797 ARMPopulateOperands(operandTypes, inst); 798 ARMExtractSemantics(*instType, operandTypes, operandFlags, inst); 799 numSyntaxes = 1; 800 } 801 802 CompoundConstantEmitter *operandOrderArray = new CompoundConstantEmitter; 803 804 infoStruct->addEntry(operandOrderArray); 805 806 for (unsigned syntaxIndex = 0; 807 syntaxIndex < EDIS_MAX_SYNTAXES; 808 ++syntaxIndex) { 809 CompoundConstantEmitter *operandOrder = 810 new CompoundConstantEmitter(EDIS_MAX_OPERANDS); 811 812 operandOrderArray->addEntry(operandOrder); 813 814 if (syntaxIndex < numSyntaxes) { 815 populateOperandOrder(operandOrder, inst, syntaxIndex); 816 } 817 } 818 819 infoStruct = NULL; 820 } 821} 822 823static void emitCommonEnums(raw_ostream &o, unsigned int &i) { 824 EnumEmitter operandTypes("OperandTypes"); 825 operandTypes.addEntry("kOperandTypeNone"); 826 operandTypes.addEntry("kOperandTypeImmediate"); 827 operandTypes.addEntry("kOperandTypeRegister"); 828 operandTypes.addEntry("kOperandTypeX86Memory"); 829 operandTypes.addEntry("kOperandTypeX86EffectiveAddress"); 830 operandTypes.addEntry("kOperandTypeX86PCRelative"); 831 operandTypes.addEntry("kOperandTypeARMBranchTarget"); 832 operandTypes.addEntry("kOperandTypeARMSoReg"); 833 operandTypes.addEntry("kOperandTypeARMSoImm"); 834 operandTypes.addEntry("kOperandTypeARMRotImm"); 835 operandTypes.addEntry("kOperandTypeARMSoImm2Part"); 836 operandTypes.addEntry("kOperandTypeARMPredicate"); 837 operandTypes.addEntry("kOperandTypeAddrModeImm12"); 838 operandTypes.addEntry("kOperandTypeLdStSOReg"); 839 operandTypes.addEntry("kOperandTypeARMAddrMode2"); 840 operandTypes.addEntry("kOperandTypeARMAddrMode2Offset"); 841 operandTypes.addEntry("kOperandTypeARMAddrMode3"); 842 operandTypes.addEntry("kOperandTypeARMAddrMode3Offset"); 843 operandTypes.addEntry("kOperandTypeARMLdStmMode"); 844 operandTypes.addEntry("kOperandTypeARMAddrMode5"); 845 operandTypes.addEntry("kOperandTypeARMAddrMode6"); 846 operandTypes.addEntry("kOperandTypeARMAddrMode6Offset"); 847 operandTypes.addEntry("kOperandTypeARMAddrModePC"); 848 operandTypes.addEntry("kOperandTypeARMRegisterList"); 849 operandTypes.addEntry("kOperandTypeARMDPRRegisterList"); 850 operandTypes.addEntry("kOperandTypeARMSPRRegisterList"); 851 operandTypes.addEntry("kOperandTypeARMTBAddrMode"); 852 operandTypes.addEntry("kOperandTypeThumbITMask"); 853 operandTypes.addEntry("kOperandTypeThumbAddrModeRegS"); 854 operandTypes.addEntry("kOperandTypeThumbAddrModeImmS"); 855 operandTypes.addEntry("kOperandTypeThumbAddrModeRR"); 856 operandTypes.addEntry("kOperandTypeThumbAddrModeSP"); 857 operandTypes.addEntry("kOperandTypeThumbAddrModePC"); 858 operandTypes.addEntry("kOperandTypeThumb2SoReg"); 859 operandTypes.addEntry("kOperandTypeThumb2SoImm"); 860 operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8"); 861 operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8Offset"); 862 operandTypes.addEntry("kOperandTypeThumb2AddrModeImm12"); 863 operandTypes.addEntry("kOperandTypeThumb2AddrModeSoReg"); 864 operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8s4"); 865 operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8s4Offset"); 866 operandTypes.emit(o, i); 867 868 o << "\n"; 869 870 EnumEmitter operandFlags("OperandFlags"); 871 operandFlags.addEntry("kOperandFlagSource"); 872 operandFlags.addEntry("kOperandFlagTarget"); 873 operandFlags.emitAsFlags(o, i); 874 875 o << "\n"; 876 877 EnumEmitter instructionTypes("InstructionTypes"); 878 instructionTypes.addEntry("kInstructionTypeNone"); 879 instructionTypes.addEntry("kInstructionTypeMove"); 880 instructionTypes.addEntry("kInstructionTypeBranch"); 881 instructionTypes.addEntry("kInstructionTypePush"); 882 instructionTypes.addEntry("kInstructionTypePop"); 883 instructionTypes.addEntry("kInstructionTypeCall"); 884 instructionTypes.addEntry("kInstructionTypeReturn"); 885 instructionTypes.emit(o, i); 886 887 o << "\n"; 888} 889 890void EDEmitter::run(raw_ostream &o) { 891 unsigned int i = 0; 892 893 CompoundConstantEmitter infoArray; 894 CodeGenTarget target(Records); 895 896 populateInstInfo(infoArray, target); 897 898 emitCommonEnums(o, i); 899 900 o << "namespace {\n"; 901 902 o << "llvm::EDInstInfo instInfo" << target.getName().c_str() << "[] = "; 903 infoArray.emit(o, i); 904 o << ";" << "\n"; 905 906 o << "}\n"; 907} 908