EDEmitter.cpp revision 519c893c2682a597049f958b2842e34c456b0434
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 326 return 1; 327} 328 329#undef REG 330#undef MEM 331#undef LEA 332#undef IMM 333#undef PCR 334 335#undef SET 336 337/// X86PopulateOperands - Handles all the operands in an X86 instruction, adding 338/// the appropriate flags to their descriptors 339/// 340/// @operandFlags - A reference the array of operand flag objects 341/// @inst - The instruction to use as a source of information 342static void X86PopulateOperands( 343 LiteralConstantEmitter *(&operandTypes)[EDIS_MAX_OPERANDS], 344 const CodeGenInstruction &inst) { 345 if (!inst.TheDef->isSubClassOf("X86Inst")) 346 return; 347 348 unsigned int index; 349 unsigned int numOperands = inst.OperandList.size(); 350 351 for (index = 0; index < numOperands; ++index) { 352 const CodeGenInstruction::OperandInfo &operandInfo = 353 inst.OperandList[index]; 354 Record &rec = *operandInfo.Rec; 355 356 if (X86TypeFromOpName(operandTypes[index], rec.getName())) { 357 errs() << "Operand type: " << rec.getName().c_str() << "\n"; 358 errs() << "Operand name: " << operandInfo.Name.c_str() << "\n"; 359 errs() << "Instruction name: " << inst.TheDef->getName().c_str() << "\n"; 360 llvm_unreachable("Unhandled type"); 361 } 362 } 363} 364 365/// decorate1 - Decorates a named operand with a new flag 366/// 367/// @operandFlags - The array of operand flag objects, which don't have names 368/// @inst - The CodeGenInstruction, which provides a way to translate 369/// between names and operand indices 370/// @opName - The name of the operand 371/// @flag - The name of the flag to add 372static inline void decorate1( 373 FlagsConstantEmitter *(&operandFlags)[EDIS_MAX_OPERANDS], 374 const CodeGenInstruction &inst, 375 const char *opName, 376 const char *opFlag) { 377 unsigned opIndex; 378 379 opIndex = inst.getOperandNamed(std::string(opName)); 380 381 operandFlags[opIndex]->addEntry(opFlag); 382} 383 384#define DECORATE1(opName, opFlag) decorate1(operandFlags, inst, opName, opFlag) 385 386#define MOV(source, target) { \ 387 instType.set("kInstructionTypeMove"); \ 388 DECORATE1(source, "kOperandFlagSource"); \ 389 DECORATE1(target, "kOperandFlagTarget"); \ 390} 391 392#define BRANCH(target) { \ 393 instType.set("kInstructionTypeBranch"); \ 394 DECORATE1(target, "kOperandFlagTarget"); \ 395} 396 397#define PUSH(source) { \ 398 instType.set("kInstructionTypePush"); \ 399 DECORATE1(source, "kOperandFlagSource"); \ 400} 401 402#define POP(target) { \ 403 instType.set("kInstructionTypePop"); \ 404 DECORATE1(target, "kOperandFlagTarget"); \ 405} 406 407#define CALL(target) { \ 408 instType.set("kInstructionTypeCall"); \ 409 DECORATE1(target, "kOperandFlagTarget"); \ 410} 411 412#define RETURN() { \ 413 instType.set("kInstructionTypeReturn"); \ 414} 415 416/// X86ExtractSemantics - Performs various checks on the name of an X86 417/// instruction to determine what sort of an instruction it is and then adds 418/// the appropriate flags to the instruction and its operands 419/// 420/// @arg instType - A reference to the type for the instruction as a whole 421/// @arg operandFlags - A reference to the array of operand flag object pointers 422/// @arg inst - A reference to the original instruction 423static void X86ExtractSemantics( 424 LiteralConstantEmitter &instType, 425 FlagsConstantEmitter *(&operandFlags)[EDIS_MAX_OPERANDS], 426 const CodeGenInstruction &inst) { 427 const std::string &name = inst.TheDef->getName(); 428 429 if (name.find("MOV") != name.npos) { 430 if (name.find("MOV_V") != name.npos) { 431 // ignore (this is a pseudoinstruction) 432 } else if (name.find("MASK") != name.npos) { 433 // ignore (this is a masking move) 434 } else if (name.find("r0") != name.npos) { 435 // ignore (this is a pseudoinstruction) 436 } else if (name.find("PS") != name.npos || 437 name.find("PD") != name.npos) { 438 // ignore (this is a shuffling move) 439 } else if (name.find("MOVS") != name.npos) { 440 // ignore (this is a string move) 441 } else if (name.find("_F") != name.npos) { 442 // TODO handle _F moves to ST(0) 443 } else if (name.find("a") != name.npos) { 444 // TODO handle moves to/from %ax 445 } else if (name.find("CMOV") != name.npos) { 446 MOV("src2", "dst"); 447 } else if (name.find("PC") != name.npos) { 448 MOV("label", "reg") 449 } else { 450 MOV("src", "dst"); 451 } 452 } 453 454 if (name.find("JMP") != name.npos || 455 name.find("J") == 0) { 456 if (name.find("FAR") != name.npos && name.find("i") != name.npos) { 457 BRANCH("off"); 458 } else { 459 BRANCH("dst"); 460 } 461 } 462 463 if (name.find("PUSH") != name.npos) { 464 if (name.find("CS") != name.npos || 465 name.find("DS") != name.npos || 466 name.find("ES") != name.npos || 467 name.find("FS") != name.npos || 468 name.find("GS") != name.npos || 469 name.find("SS") != name.npos) { 470 instType.set("kInstructionTypePush"); 471 // TODO add support for fixed operands 472 } else if (name.find("F") != name.npos) { 473 // ignore (this pushes onto the FP stack) 474 } else if (name.find("A") != name.npos) { 475 // ignore (pushes all GP registoers onto the stack) 476 } else if (name[name.length() - 1] == 'm') { 477 PUSH("src"); 478 } else if (name.find("i") != name.npos) { 479 PUSH("imm"); 480 } else { 481 PUSH("reg"); 482 } 483 } 484 485 if (name.find("POP") != name.npos) { 486 if (name.find("POPCNT") != name.npos) { 487 // ignore (not a real pop) 488 } else if (name.find("CS") != name.npos || 489 name.find("DS") != name.npos || 490 name.find("ES") != name.npos || 491 name.find("FS") != name.npos || 492 name.find("GS") != name.npos || 493 name.find("SS") != name.npos) { 494 instType.set("kInstructionTypePop"); 495 // TODO add support for fixed operands 496 } else if (name.find("F") != name.npos) { 497 // ignore (this pops from the FP stack) 498 } else if (name.find("A") != name.npos) { 499 // ignore (pushes all GP registoers onto the stack) 500 } else if (name[name.length() - 1] == 'm') { 501 POP("dst"); 502 } else { 503 POP("reg"); 504 } 505 } 506 507 if (name.find("CALL") != name.npos) { 508 if (name.find("ADJ") != name.npos) { 509 // ignore (not a call) 510 } else if (name.find("SYSCALL") != name.npos) { 511 // ignore (doesn't go anywhere we know about) 512 } else if (name.find("VMCALL") != name.npos) { 513 // ignore (rather different semantics than a regular call) 514 } else if (name.find("FAR") != name.npos && name.find("i") != name.npos) { 515 CALL("off"); 516 } else { 517 CALL("dst"); 518 } 519 } 520 521 if (name.find("RET") != name.npos) { 522 RETURN(); 523 } 524} 525 526#undef MOV 527#undef BRANCH 528#undef PUSH 529#undef POP 530#undef CALL 531#undef RETURN 532 533///////////////////////////////////////////////////// 534// Support functions for handling ARM instructions // 535///////////////////////////////////////////////////// 536 537#define SET(flag) { type->set(flag); return 0; } 538 539#define REG(str) if (name == str) SET("kOperandTypeRegister"); 540#define IMM(str) if (name == str) SET("kOperandTypeImmediate"); 541 542#define MISC(str, type) if (name == str) SET(type); 543 544/// ARMFlagFromOpName - Processes the name of a single ARM operand (which is 545/// actually its type) and translates it into an operand type 546/// 547/// @arg type - The type object to set 548/// @arg name - The name of the operand 549static int ARMFlagFromOpName(LiteralConstantEmitter *type, 550 const std::string &name) { 551 REG("GPR"); 552 REG("rGPR"); 553 REG("tcGPR"); 554 REG("cc_out"); 555 REG("s_cc_out"); 556 REG("tGPR"); 557 REG("DPR"); 558 REG("DPR_VFP2"); 559 REG("DPR_8"); 560 REG("SPR"); 561 REG("QPR"); 562 REG("QQPR"); 563 REG("QQQQPR"); 564 565 IMM("i32imm"); 566 IMM("bf_inv_mask_imm"); 567 IMM("jtblock_operand"); 568 IMM("nohash_imm"); 569 IMM("cpinst_operand"); 570 IMM("cps_opt"); 571 IMM("vfp_f64imm"); 572 IMM("vfp_f32imm"); 573 IMM("memb_opt"); 574 IMM("msr_mask"); 575 IMM("neg_zero"); 576 IMM("imm0_31"); 577 IMM("nModImm"); 578 IMM("imm0_4095"); 579 IMM("jt2block_operand"); 580 IMM("t_imm_s4"); 581 IMM("pclabel"); 582 IMM("shift_imm"); 583 584 MISC("brtarget", "kOperandTypeARMBranchTarget"); // ? 585 MISC("so_reg", "kOperandTypeARMSoReg"); // R, R, I 586 MISC("t2_so_reg", "kOperandTypeThumb2SoReg"); // R, I 587 MISC("so_imm", "kOperandTypeARMSoImm"); // I 588 MISC("t2_so_imm", "kOperandTypeThumb2SoImm"); // I 589 MISC("so_imm2part", "kOperandTypeARMSoImm2Part"); // I 590 MISC("pred", "kOperandTypeARMPredicate"); // I, R 591 MISC("it_pred", "kOperandTypeARMPredicate"); // I 592 MISC("addrmode2", "kOperandTypeARMAddrMode2"); // R, R, I 593 MISC("am2offset", "kOperandTypeARMAddrMode2Offset"); // R, I 594 MISC("addrmode3", "kOperandTypeARMAddrMode3"); // R, R, I 595 MISC("am3offset", "kOperandTypeARMAddrMode3Offset"); // R, I 596 MISC("addrmode4", "kOperandTypeARMAddrMode4"); // R, I 597 MISC("addrmode5", "kOperandTypeARMAddrMode5"); // R, I 598 MISC("addrmode6", "kOperandTypeARMAddrMode6"); // R, R, I, I 599 MISC("am6offset", "kOperandTypeARMAddrMode6Offset"); // R, I, I 600 MISC("addrmodepc", "kOperandTypeARMAddrModePC"); // R, I 601 MISC("reglist", "kOperandTypeARMRegisterList"); // I, R, ... 602 MISC("it_mask", "kOperandTypeThumbITMask"); // I 603 MISC("t2addrmode_imm8", "kOperandTypeThumb2AddrModeImm8"); // R, I 604 MISC("t2am_imm8_offset", "kOperandTypeThumb2AddrModeImm8Offset");//I 605 MISC("t2addrmode_imm12", "kOperandTypeThumb2AddrModeImm12"); // R, I 606 MISC("t2addrmode_so_reg", "kOperandTypeThumb2AddrModeSoReg"); // R, R, I 607 MISC("t2addrmode_imm8s4", "kOperandTypeThumb2AddrModeImm8s4"); // R, I 608 MISC("t2am_imm8s4_offset", "kOperandTypeThumb2AddrModeImm8s4Offset"); 609 // R, I 610 MISC("tb_addrmode", "kOperandTypeARMTBAddrMode"); // I 611 MISC("t_addrmode_s1", "kOperandTypeThumbAddrModeS1"); // R, I, R 612 MISC("t_addrmode_s2", "kOperandTypeThumbAddrModeS2"); // R, I, R 613 MISC("t_addrmode_s4", "kOperandTypeThumbAddrModeS4"); // R, I, R 614 MISC("t_addrmode_rr", "kOperandTypeThumbAddrModeRR"); // R, R 615 MISC("t_addrmode_sp", "kOperandTypeThumbAddrModeSP"); // R, I 616 617 return 1; 618} 619 620#undef SOREG 621#undef SOIMM 622#undef PRED 623#undef REG 624#undef MEM 625#undef LEA 626#undef IMM 627#undef PCR 628 629#undef SET 630 631/// ARMPopulateOperands - Handles all the operands in an ARM instruction, adding 632/// the appropriate flags to their descriptors 633/// 634/// @operandFlags - A reference the array of operand flag objects 635/// @inst - The instruction to use as a source of information 636static void ARMPopulateOperands( 637 LiteralConstantEmitter *(&operandTypes)[EDIS_MAX_OPERANDS], 638 const CodeGenInstruction &inst) { 639 if (!inst.TheDef->isSubClassOf("InstARM") && 640 !inst.TheDef->isSubClassOf("InstThumb")) 641 return; 642 643 unsigned int index; 644 unsigned int numOperands = inst.OperandList.size(); 645 646 if (numOperands > EDIS_MAX_OPERANDS) { 647 errs() << "numOperands == " << numOperands << " > " << 648 EDIS_MAX_OPERANDS << '\n'; 649 llvm_unreachable("Too many operands"); 650 } 651 652 for (index = 0; index < numOperands; ++index) { 653 const CodeGenInstruction::OperandInfo &operandInfo = 654 inst.OperandList[index]; 655 Record &rec = *operandInfo.Rec; 656 657 if (ARMFlagFromOpName(operandTypes[index], rec.getName())) { 658 errs() << "Operand type: " << rec.getName() << '\n'; 659 errs() << "Operand name: " << operandInfo.Name << '\n'; 660 errs() << "Instruction name: " << inst.TheDef->getName() << '\n'; 661 llvm_unreachable("Unhandled type"); 662 } 663 } 664} 665 666#define BRANCH(target) { \ 667 instType.set("kInstructionTypeBranch"); \ 668 DECORATE1(target, "kOperandFlagTarget"); \ 669} 670 671/// ARMExtractSemantics - Performs various checks on the name of an ARM 672/// instruction to determine what sort of an instruction it is and then adds 673/// the appropriate flags to the instruction and its operands 674/// 675/// @arg instType - A reference to the type for the instruction as a whole 676/// @arg operandTypes - A reference to the array of operand type object pointers 677/// @arg operandFlags - A reference to the array of operand flag object pointers 678/// @arg inst - A reference to the original instruction 679static void ARMExtractSemantics( 680 LiteralConstantEmitter &instType, 681 LiteralConstantEmitter *(&operandTypes)[EDIS_MAX_OPERANDS], 682 FlagsConstantEmitter *(&operandFlags)[EDIS_MAX_OPERANDS], 683 const CodeGenInstruction &inst) { 684 const std::string &name = inst.TheDef->getName(); 685 686 if (name == "tBcc" || 687 name == "tB" || 688 name == "t2Bcc" || 689 name == "Bcc" || 690 name == "tCBZ" || 691 name == "tCBNZ") { 692 BRANCH("target"); 693 } 694 695 if (name == "tBLr9" || 696 name == "BLr9_pred" || 697 name == "tBLXi_r9" || 698 name == "tBLXr_r9" || 699 name == "BLXr9" || 700 name == "t2BXJ" || 701 name == "BXJ") { 702 BRANCH("func"); 703 704 unsigned opIndex; 705 opIndex = inst.getOperandNamed("func"); 706 if (operandTypes[opIndex]->is("kOperandTypeImmediate")) 707 operandTypes[opIndex]->set("kOperandTypeARMBranchTarget"); 708 } 709} 710 711#undef BRANCH 712 713/// populateInstInfo - Fills an array of InstInfos with information about each 714/// instruction in a target 715/// 716/// @arg infoArray - The array of InstInfo objects to populate 717/// @arg target - The CodeGenTarget to use as a source of instructions 718static void populateInstInfo(CompoundConstantEmitter &infoArray, 719 CodeGenTarget &target) { 720 const std::vector<const CodeGenInstruction*> &numberedInstructions = 721 target.getInstructionsByEnumValue(); 722 723 unsigned int index; 724 unsigned int numInstructions = numberedInstructions.size(); 725 726 for (index = 0; index < numInstructions; ++index) { 727 const CodeGenInstruction& inst = *numberedInstructions[index]; 728 729 CompoundConstantEmitter *infoStruct = new CompoundConstantEmitter; 730 infoArray.addEntry(infoStruct); 731 732 LiteralConstantEmitter *instType = new LiteralConstantEmitter; 733 infoStruct->addEntry(instType); 734 735 LiteralConstantEmitter *numOperandsEmitter = 736 new LiteralConstantEmitter(inst.OperandList.size()); 737 infoStruct->addEntry(numOperandsEmitter); 738 739 CompoundConstantEmitter *operandTypeArray = new CompoundConstantEmitter; 740 infoStruct->addEntry(operandTypeArray); 741 742 LiteralConstantEmitter *operandTypes[EDIS_MAX_OPERANDS]; 743 744 CompoundConstantEmitter *operandFlagArray = new CompoundConstantEmitter; 745 infoStruct->addEntry(operandFlagArray); 746 747 FlagsConstantEmitter *operandFlags[EDIS_MAX_OPERANDS]; 748 749 for (unsigned operandIndex = 0; 750 operandIndex < EDIS_MAX_OPERANDS; 751 ++operandIndex) { 752 operandTypes[operandIndex] = new LiteralConstantEmitter; 753 operandTypeArray->addEntry(operandTypes[operandIndex]); 754 755 operandFlags[operandIndex] = new FlagsConstantEmitter; 756 operandFlagArray->addEntry(operandFlags[operandIndex]); 757 } 758 759 unsigned numSyntaxes = 0; 760 761 if (target.getName() == "X86") { 762 X86PopulateOperands(operandTypes, inst); 763 X86ExtractSemantics(*instType, operandFlags, inst); 764 numSyntaxes = 2; 765 } 766 else if (target.getName() == "ARM") { 767 ARMPopulateOperands(operandTypes, inst); 768 ARMExtractSemantics(*instType, operandTypes, operandFlags, inst); 769 numSyntaxes = 1; 770 } 771 772 CompoundConstantEmitter *operandOrderArray = new CompoundConstantEmitter; 773 774 infoStruct->addEntry(operandOrderArray); 775 776 for (unsigned syntaxIndex = 0; 777 syntaxIndex < EDIS_MAX_SYNTAXES; 778 ++syntaxIndex) { 779 CompoundConstantEmitter *operandOrder = 780 new CompoundConstantEmitter(EDIS_MAX_OPERANDS); 781 782 operandOrderArray->addEntry(operandOrder); 783 784 if (syntaxIndex < numSyntaxes) { 785 populateOperandOrder(operandOrder, inst, syntaxIndex); 786 } 787 } 788 789 infoStruct = NULL; 790 } 791} 792 793static void emitCommonEnums(raw_ostream &o, unsigned int &i) { 794 EnumEmitter operandTypes("OperandTypes"); 795 operandTypes.addEntry("kOperandTypeNone"); 796 operandTypes.addEntry("kOperandTypeImmediate"); 797 operandTypes.addEntry("kOperandTypeRegister"); 798 operandTypes.addEntry("kOperandTypeX86Memory"); 799 operandTypes.addEntry("kOperandTypeX86EffectiveAddress"); 800 operandTypes.addEntry("kOperandTypeX86PCRelative"); 801 operandTypes.addEntry("kOperandTypeARMBranchTarget"); 802 operandTypes.addEntry("kOperandTypeARMSoReg"); 803 operandTypes.addEntry("kOperandTypeARMSoImm"); 804 operandTypes.addEntry("kOperandTypeARMSoImm2Part"); 805 operandTypes.addEntry("kOperandTypeARMPredicate"); 806 operandTypes.addEntry("kOperandTypeARMAddrMode2"); 807 operandTypes.addEntry("kOperandTypeARMAddrMode2Offset"); 808 operandTypes.addEntry("kOperandTypeARMAddrMode3"); 809 operandTypes.addEntry("kOperandTypeARMAddrMode3Offset"); 810 operandTypes.addEntry("kOperandTypeARMAddrMode4"); 811 operandTypes.addEntry("kOperandTypeARMAddrMode5"); 812 operandTypes.addEntry("kOperandTypeARMAddrMode6"); 813 operandTypes.addEntry("kOperandTypeARMAddrMode6Offset"); 814 operandTypes.addEntry("kOperandTypeARMAddrModePC"); 815 operandTypes.addEntry("kOperandTypeARMRegisterList"); 816 operandTypes.addEntry("kOperandTypeARMTBAddrMode"); 817 operandTypes.addEntry("kOperandTypeThumbITMask"); 818 operandTypes.addEntry("kOperandTypeThumbAddrModeS1"); 819 operandTypes.addEntry("kOperandTypeThumbAddrModeS2"); 820 operandTypes.addEntry("kOperandTypeThumbAddrModeS4"); 821 operandTypes.addEntry("kOperandTypeThumbAddrModeRR"); 822 operandTypes.addEntry("kOperandTypeThumbAddrModeSP"); 823 operandTypes.addEntry("kOperandTypeThumb2SoReg"); 824 operandTypes.addEntry("kOperandTypeThumb2SoImm"); 825 operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8"); 826 operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8Offset"); 827 operandTypes.addEntry("kOperandTypeThumb2AddrModeImm12"); 828 operandTypes.addEntry("kOperandTypeThumb2AddrModeSoReg"); 829 operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8s4"); 830 operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8s4Offset"); 831 operandTypes.emit(o, i); 832 833 o << "\n"; 834 835 EnumEmitter operandFlags("OperandFlags"); 836 operandFlags.addEntry("kOperandFlagSource"); 837 operandFlags.addEntry("kOperandFlagTarget"); 838 operandFlags.emitAsFlags(o, i); 839 840 o << "\n"; 841 842 EnumEmitter instructionTypes("InstructionTypes"); 843 instructionTypes.addEntry("kInstructionTypeNone"); 844 instructionTypes.addEntry("kInstructionTypeMove"); 845 instructionTypes.addEntry("kInstructionTypeBranch"); 846 instructionTypes.addEntry("kInstructionTypePush"); 847 instructionTypes.addEntry("kInstructionTypePop"); 848 instructionTypes.addEntry("kInstructionTypeCall"); 849 instructionTypes.addEntry("kInstructionTypeReturn"); 850 instructionTypes.emit(o, i); 851 852 o << "\n"; 853} 854 855void EDEmitter::run(raw_ostream &o) { 856 unsigned int i = 0; 857 858 CompoundConstantEmitter infoArray; 859 CodeGenTarget target; 860 861 populateInstInfo(infoArray, target); 862 863 emitCommonEnums(o, i); 864 865 o << "namespace {\n"; 866 867 o << "llvm::EDInstInfo instInfo" << target.getName().c_str() << "[] = "; 868 infoArray.emit(o, i); 869 o << ";" << "\n"; 870 871 o << "}\n"; 872} 873