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