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