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