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