ARMCodeEmitter.cpp revision cd40d8954058f9dbfd9192fd0d5f8e0f8d00fa10
1//===-- ARM/ARMCodeEmitter.cpp - Convert ARM code to machine code ---------===// 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 file contains the pass that transforms the ARM machine instructions into 11// relocatable machine code. 12// 13//===----------------------------------------------------------------------===// 14 15#define DEBUG_TYPE "arm-emitter" 16#include "ARM.h" 17#include "ARMAddressingModes.h" 18#include "ARMInstrInfo.h" 19#include "ARMRelocations.h" 20#include "ARMSubtarget.h" 21#include "ARMTargetMachine.h" 22#include "llvm/Constants.h" 23#include "llvm/DerivedTypes.h" 24#include "llvm/Function.h" 25#include "llvm/PassManager.h" 26#include "llvm/CodeGen/MachineCodeEmitter.h" 27#include "llvm/CodeGen/MachineConstantPool.h" 28#include "llvm/CodeGen/MachineFunctionPass.h" 29#include "llvm/CodeGen/MachineInstr.h" 30#include "llvm/CodeGen/Passes.h" 31#include "llvm/ADT/Statistic.h" 32#include "llvm/Support/Compiler.h" 33#include "llvm/Support/Debug.h" 34using namespace llvm; 35 36STATISTIC(NumEmitted, "Number of machine instructions emitted"); 37 38namespace { 39 class VISIBILITY_HIDDEN ARMCodeEmitter : public MachineFunctionPass { 40 ARMJITInfo *JTI; 41 const ARMInstrInfo *II; 42 const TargetData *TD; 43 TargetMachine &TM; 44 MachineCodeEmitter &MCE; 45 const MachineConstantPool *MCP; 46 public: 47 static char ID; 48 explicit ARMCodeEmitter(TargetMachine &tm, MachineCodeEmitter &mce) 49 : MachineFunctionPass(&ID), JTI(0), II(0), TD(0), TM(tm), 50 MCE(mce), MCP(0) {} 51 ARMCodeEmitter(TargetMachine &tm, MachineCodeEmitter &mce, 52 const ARMInstrInfo &ii, const TargetData &td) 53 : MachineFunctionPass(&ID), JTI(0), II(&ii), TD(&td), TM(tm), 54 MCE(mce), MCP(0) {} 55 56 bool runOnMachineFunction(MachineFunction &MF); 57 58 virtual const char *getPassName() const { 59 return "ARM Machine Code Emitter"; 60 } 61 62 void emitInstruction(const MachineInstr &MI); 63 64 private: 65 66 void emitConstPoolInstruction(const MachineInstr &MI); 67 68 void emitPseudoInstruction(const MachineInstr &MI); 69 70 unsigned getAddrModeNoneInstrBinary(const MachineInstr &MI, 71 const TargetInstrDesc &TID, 72 unsigned Binary); 73 74 unsigned getMachineSoRegOpValue(const MachineInstr &MI, 75 const TargetInstrDesc &TID, 76 unsigned OpIdx); 77 78 unsigned getAddrMode1SBit(const MachineInstr &MI, 79 const TargetInstrDesc &TID) const; 80 81 unsigned getAddrMode1InstrBinary(const MachineInstr &MI, 82 const TargetInstrDesc &TID, 83 unsigned Binary); 84 unsigned getAddrMode2InstrBinary(const MachineInstr &MI, 85 const TargetInstrDesc &TID, 86 unsigned Binary); 87 unsigned getAddrMode3InstrBinary(const MachineInstr &MI, 88 const TargetInstrDesc &TID, 89 unsigned Binary); 90 unsigned getAddrMode4InstrBinary(const MachineInstr &MI, 91 const TargetInstrDesc &TID, 92 unsigned Binary); 93 94 /// getInstrBinary - Return binary encoding for the specified 95 /// machine instruction. 96 unsigned getInstrBinary(const MachineInstr &MI); 97 98 /// getBinaryCodeForInstr - This function, generated by the 99 /// CodeEmitterGenerator using TableGen, produces the binary encoding for 100 /// machine instructions. 101 /// 102 unsigned getBinaryCodeForInstr(const MachineInstr &MI); 103 104 /// getMachineOpValue - Return binary encoding of operand. If the machine 105 /// operand requires relocation, record the relocation and return zero. 106 unsigned getMachineOpValue(const MachineInstr &MI, unsigned OpIdx) { 107 return getMachineOpValue(MI, MI.getOperand(OpIdx)); 108 } 109 unsigned getMachineOpValue(const MachineInstr &MI, 110 const MachineOperand &MO); 111 112 /// getBaseOpcodeFor - Return the opcode value. 113 /// 114 unsigned getBaseOpcodeFor(const TargetInstrDesc &TID) const { 115 return (TID.TSFlags & ARMII::OpcodeMask) >> ARMII::OpcodeShift; 116 } 117 118 /// getShiftOp - Return the shift opcode (bit[6:5]) of the machine operand. 119 /// 120 unsigned getShiftOp(const MachineOperand &MO) const ; 121 122 /// Routines that handle operands which add machine relocations which are 123 /// fixed up by the JIT fixup stage. 124 void emitGlobalAddress(GlobalValue *GV, unsigned Reloc, 125 bool NeedStub); 126 void emitExternalSymbolAddress(const char *ES, unsigned Reloc); 127 void emitConstPoolAddress(unsigned CPI, unsigned Reloc, 128 int Disp = 0, unsigned PCAdj = 0 ); 129 void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc, 130 unsigned PCAdj = 0); 131 void emitGlobalConstant(const Constant *CV); 132 void emitMachineBasicBlock(MachineBasicBlock *BB); 133 }; 134 char ARMCodeEmitter::ID = 0; 135} 136 137/// createARMCodeEmitterPass - Return a pass that emits the collected ARM code 138/// to the specified MCE object. 139FunctionPass *llvm::createARMCodeEmitterPass(ARMTargetMachine &TM, 140 MachineCodeEmitter &MCE) { 141 return new ARMCodeEmitter(TM, MCE); 142} 143 144bool ARMCodeEmitter::runOnMachineFunction(MachineFunction &MF) { 145 assert((MF.getTarget().getRelocationModel() != Reloc::Default || 146 MF.getTarget().getRelocationModel() != Reloc::Static) && 147 "JIT relocation model must be set to static or default!"); 148 II = ((ARMTargetMachine&)MF.getTarget()).getInstrInfo(); 149 TD = ((ARMTargetMachine&)MF.getTarget()).getTargetData(); 150 JTI = ((ARMTargetMachine&)MF.getTarget()).getJITInfo(); 151 MCP = MF.getConstantPool(); 152 153 do { 154 DOUT << "JITTing function '" << MF.getFunction()->getName() << "'\n"; 155 MCE.startFunction(MF); 156 for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); 157 MBB != E; ++MBB) { 158 MCE.StartMachineBasicBlock(MBB); 159 for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end(); 160 I != E; ++I) 161 emitInstruction(*I); 162 } 163 } while (MCE.finishFunction(MF)); 164 165 return false; 166} 167 168/// getShiftOp - Return the shift opcode (bit[6:5]) of the machine operand. 169/// 170unsigned ARMCodeEmitter::getShiftOp(const MachineOperand &MO) const { 171 switch (ARM_AM::getAM2ShiftOpc(MO.getImm())) { 172 default: assert(0 && "Unknown shift opc!"); 173 case ARM_AM::asr: return 2; 174 case ARM_AM::lsl: return 0; 175 case ARM_AM::lsr: return 1; 176 case ARM_AM::ror: 177 case ARM_AM::rrx: return 3; 178 } 179 return 0; 180} 181 182/// getMachineOpValue - Return binary encoding of operand. If the machine 183/// operand requires relocation, record the relocation and return zero. 184unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI, 185 const MachineOperand &MO) { 186 if (MO.isReg()) 187 return ARMRegisterInfo::getRegisterNumbering(MO.getReg()); 188 else if (MO.isImm()) 189 return static_cast<unsigned>(MO.getImm()); 190 else if (MO.isGlobal()) 191 emitGlobalAddress(MO.getGlobal(), ARM::reloc_arm_branch, true); 192 else if (MO.isSymbol()) 193 emitExternalSymbolAddress(MO.getSymbolName(), ARM::reloc_arm_relative); 194 else if (MO.isCPI()) 195 emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_relative); 196 else if (MO.isJTI()) 197 emitJumpTableAddress(MO.getIndex(), ARM::reloc_arm_relative); 198 else if (MO.isMBB()) 199 emitMachineBasicBlock(MO.getMBB()); 200 else { 201 cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; 202 abort(); 203 } 204 return 0; 205} 206 207/// emitGlobalAddress - Emit the specified address to the code stream. 208/// 209void ARMCodeEmitter::emitGlobalAddress(GlobalValue *GV, 210 unsigned Reloc, bool NeedStub) { 211 MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), 212 Reloc, GV, 0, NeedStub)); 213} 214 215/// emitExternalSymbolAddress - Arrange for the address of an external symbol to 216/// be emitted to the current location in the function, and allow it to be PC 217/// relative. 218void ARMCodeEmitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) { 219 MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), 220 Reloc, ES)); 221} 222 223/// emitConstPoolAddress - Arrange for the address of an constant pool 224/// to be emitted to the current location in the function, and allow it to be PC 225/// relative. 226void ARMCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc, 227 int Disp /* = 0 */, 228 unsigned PCAdj /* = 0 */) { 229 MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), 230 Reloc, CPI, PCAdj)); 231} 232 233/// emitJumpTableAddress - Arrange for the address of a jump table to 234/// be emitted to the current location in the function, and allow it to be PC 235/// relative. 236void ARMCodeEmitter::emitJumpTableAddress(unsigned JTIndex, unsigned Reloc, 237 unsigned PCAdj /* = 0 */) { 238 MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), 239 Reloc, JTIndex, PCAdj)); 240} 241 242/// emitMachineBasicBlock - Emit the specified address basic block. 243void ARMCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB) { 244 MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), 245 ARM::reloc_arm_branch, BB)); 246} 247 248void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) { 249 DOUT << MI; 250 251 NumEmitted++; // Keep track of the # of mi's emitted 252 if ((MI.getDesc().TSFlags & ARMII::FormMask) == ARMII::Pseudo) 253 emitPseudoInstruction(MI); 254 else 255 MCE.emitWordLE(getInstrBinary(MI)); 256} 257 258unsigned ARMCodeEmitter::getAddrModeNoneInstrBinary(const MachineInstr &MI, 259 const TargetInstrDesc &TID, 260 unsigned Binary) { 261 // Set the conditional execution predicate 262 Binary |= II->getPredicate(&MI) << 28; 263 264 switch (TID.TSFlags & ARMII::FormMask) { 265 default: 266 assert(0 && "Unknown instruction subtype!"); 267 break; 268 case ARMII::Branch: { 269 // Set signed_immed_24 field 270 Binary |= getMachineOpValue(MI, 0); 271 272 // if it is a conditional branch, set cond field 273 if (TID.Opcode == ARM::Bcc) { 274 Binary &= 0x0FFFFFFF; // clear conditional field 275 Binary |= getMachineOpValue(MI, 1) << 28; // set conditional field 276 } 277 break; 278 } 279 case ARMII::BranchMisc: { 280 if (TID.Opcode == ARM::BX) 281 abort(); // FIXME 282 if (TID.Opcode == ARM::BX_RET) 283 Binary |= 0xe; // the return register is LR 284 else 285 // otherwise, set the return register 286 Binary |= getMachineOpValue(MI, 0); 287 break; 288 } 289 } 290 291 return Binary; 292} 293 294unsigned ARMCodeEmitter::getMachineSoRegOpValue(const MachineInstr &MI, 295 const TargetInstrDesc &TID, 296 unsigned OpIdx) { 297 // Set last operand (register Rm) 298 unsigned Binary = getMachineOpValue(MI, OpIdx); 299 300 const MachineOperand &MO1 = MI.getOperand(OpIdx + 1); 301 const MachineOperand &MO2 = MI.getOperand(OpIdx + 2); 302 ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm()); 303 304 // Encode the shift opcode. 305 unsigned SBits = 0; 306 unsigned Rs = MO1.getReg(); 307 if (Rs) { 308 // Set shift operand (bit[7:4]). 309 // LSL - 0001 310 // LSR - 0011 311 // ASR - 0101 312 // ROR - 0111 313 // RRX - 0110 and bit[11:8] clear. 314 switch (SOpc) { 315 default: assert(0 && "Unknown shift opc!"); 316 case ARM_AM::lsl: SBits = 0x1; break; 317 case ARM_AM::lsr: SBits = 0x3; break; 318 case ARM_AM::asr: SBits = 0x5; break; 319 case ARM_AM::ror: SBits = 0x7; break; 320 case ARM_AM::rrx: SBits = 0x6; break; 321 } 322 } else { 323 // Set shift operand (bit[6:4]). 324 // LSL - 000 325 // LSR - 010 326 // ASR - 100 327 // ROR - 110 328 switch (SOpc) { 329 default: assert(0 && "Unknown shift opc!"); 330 case ARM_AM::lsl: SBits = 0x0; break; 331 case ARM_AM::lsr: SBits = 0x2; break; 332 case ARM_AM::asr: SBits = 0x4; break; 333 case ARM_AM::ror: SBits = 0x6; break; 334 } 335 } 336 Binary |= SBits << 4; 337 if (SOpc == ARM_AM::rrx) 338 return Binary; 339 340 // Encode the shift operation Rs or shift_imm (except rrx). 341 if (Rs) { 342 // Encode Rs bit[11:8]. 343 assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0); 344 return Binary | 345 (ARMRegisterInfo::getRegisterNumbering(Rs) << ARMII::RegRsShift); 346 } 347 348 // Encode shift_imm bit[11:7]. 349 return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7; 350} 351 352unsigned ARMCodeEmitter::getAddrMode1SBit(const MachineInstr &MI, 353 const TargetInstrDesc &TID) const { 354 for (unsigned i = MI.getNumOperands(), e = TID.getNumOperands(); i != e; --i){ 355 const MachineOperand &MO = MI.getOperand(i-1); 356 if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR) 357 return 1 << ARMII::S_BitShift; 358 } 359 return 0; 360} 361 362void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) { 363 unsigned CPID = MI.getOperand(0).getImm(); 364 unsigned CPIndex = MI.getOperand(1).getIndex(); 365 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIndex]; 366 367 //FIXME: Can we get these here? 368 assert (!MCPE.isMachineConstantPoolEntry()); 369 370 const Constant *CV = MCPE.Val.ConstVal; 371 // FIXME: We can get other types here. Need to handle them. 372 // According to the constant island pass, everything is multiples, 373 // of 4-bytes in size, though, so that helps. 374 assert (CV->getType()->isInteger()); 375 assert (cast<IntegerType>(CV->getType())->getBitWidth() == 32); 376 377 const ConstantInt *CI = dyn_cast<ConstantInt>(CV); 378 uint32_t Val = *(uint32_t*)CI->getValue().getRawData(); 379 380 DOUT << "Constant pool #" << CPID << ", value '" << Val << "' @ " << 381 (void*)MCE.getCurrentPCValue() << "\n"; 382 383 if (JTI) 384 JTI->mapCPIDtoAddress(CPID, MCE.getCurrentPCValue()); 385 MCE.emitWordLE(Val); 386} 387 388void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) { 389 unsigned Opcode = MI.getDesc().Opcode; 390 switch (Opcode) { 391 default: 392 abort(); // FIXME: 393 case ARM::CONSTPOOL_ENTRY: { 394 emitConstPoolInstruction(MI); 395 break; 396 } 397 } 398} 399 400unsigned ARMCodeEmitter::getAddrMode1InstrBinary(const MachineInstr &MI, 401 const TargetInstrDesc &TID, 402 unsigned Binary) { 403 // Set the conditional execution predicate 404 Binary |= II->getPredicate(&MI) << 28; 405 406 // Encode S bit if MI modifies CPSR. 407 Binary |= getAddrMode1SBit(MI, TID); 408 409 // Encode register def if there is one. 410 unsigned NumDefs = TID.getNumDefs(); 411 unsigned OpIdx = 0; 412 if (NumDefs) { 413 Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRdShift; 414 ++OpIdx; 415 } 416 417 // Encode first non-shifter register operand if there is one. 418 unsigned Format = TID.TSFlags & ARMII::FormMask; 419 bool hasRnOperand= !(Format == ARMII::DPRdMisc || 420 Format == ARMII::DPRdIm || 421 Format == ARMII::DPRdReg || 422 Format == ARMII::DPRdSoReg); 423 if (hasRnOperand) { 424 Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRnShift; 425 ++OpIdx; 426 } 427 428 // Encode shifter operand. 429 bool HasSoReg = (Format == ARMII::DPRdSoReg || 430 Format == ARMII::DPRnSoReg || 431 Format == ARMII::DPRSoReg || 432 Format == ARMII::DPRSoRegS); 433 if (HasSoReg) 434 // Encode SoReg. 435 return Binary | getMachineSoRegOpValue(MI, TID, OpIdx); 436 437 const MachineOperand &MO = MI.getOperand(OpIdx); 438 if (MO.isReg()) 439 // Encode register Rm. 440 return Binary | getMachineOpValue(MI, NumDefs); 441 442 // Encode so_imm. 443 // Set bit I(25) to identify this is the immediate form of <shifter_op> 444 Binary |= 1 << ARMII::I_BitShift; 445 unsigned SoImm = MO.getImm(); 446 // Encode rotate_imm. 447 Binary |= ARM_AM::getSOImmValRot(SoImm) << ARMII::RotImmShift; 448 // Encode immed_8. 449 Binary |= ARM_AM::getSOImmVal(SoImm); 450 return Binary; 451} 452 453unsigned ARMCodeEmitter::getAddrMode2InstrBinary(const MachineInstr &MI, 454 const TargetInstrDesc &TID, 455 unsigned Binary) { 456 // Set the conditional execution predicate 457 Binary |= II->getPredicate(&MI) << 28; 458 459 // Set first operand 460 Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift; 461 462 // Set second operand 463 Binary |= getMachineOpValue(MI, 1) << ARMII::RegRnShift; 464 465 const MachineOperand &MO2 = MI.getOperand(2); 466 const MachineOperand &MO3 = MI.getOperand(3); 467 468 // Set bit U(23) according to sign of immed value (positive or negative). 469 Binary |= ((ARM_AM::getAM2Op(MO3.getImm()) == ARM_AM::add ? 1 : 0) << 470 ARMII::U_BitShift); 471 if (!MO2.getReg()) { // is immediate 472 if (ARM_AM::getAM2Offset(MO3.getImm())) 473 // Set the value of offset_12 field 474 Binary |= ARM_AM::getAM2Offset(MO3.getImm()); 475 return Binary; 476 } 477 478 // Set bit I(25), because this is not in immediate enconding. 479 Binary |= 1 << ARMII::I_BitShift; 480 assert(TargetRegisterInfo::isPhysicalRegister(MO2.getReg())); 481 // Set bit[3:0] to the corresponding Rm register 482 Binary |= ARMRegisterInfo::getRegisterNumbering(MO2.getReg()); 483 484 // if this instr is in scaled register offset/index instruction, set 485 // shift_immed(bit[11:7]) and shift(bit[6:5]) fields. 486 if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) { 487 Binary |= getShiftOp(MO3) << 5; // shift 488 Binary |= ShImm << 7; // shift_immed 489 } 490 491 return Binary; 492} 493 494unsigned ARMCodeEmitter::getAddrMode3InstrBinary(const MachineInstr &MI, 495 const TargetInstrDesc &TID, 496 unsigned Binary) { 497 // Set the conditional execution predicate 498 Binary |= II->getPredicate(&MI) << 28; 499 500 // Set first operand 501 Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift; 502 503 // Set second operand 504 Binary |= getMachineOpValue(MI, 1) << ARMII::RegRnShift; 505 506 const MachineOperand &MO2 = MI.getOperand(2); 507 const MachineOperand &MO3 = MI.getOperand(3); 508 509 // Set bit U(23) according to sign of immed value (positive or negative) 510 Binary |= ((ARM_AM::getAM2Op(MO3.getImm()) == ARM_AM::add ? 1 : 0) << 511 ARMII::U_BitShift); 512 513 // If this instr is in register offset/index encoding, set bit[3:0] 514 // to the corresponding Rm register. 515 if (MO2.getReg()) { 516 Binary |= ARMRegisterInfo::getRegisterNumbering(MO2.getReg()); 517 return Binary; 518 } 519 520 // if this instr is in immediate offset/index encoding, set bit 22 to 1 521 if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm())) { 522 Binary |= 1 << 22; 523 // Set operands 524 Binary |= (ImmOffs >> 4) << 8; // immedH 525 Binary |= (ImmOffs & ~0xF); // immedL 526 } 527 528 return Binary; 529} 530 531unsigned ARMCodeEmitter::getAddrMode4InstrBinary(const MachineInstr &MI, 532 const TargetInstrDesc &TID, 533 unsigned Binary) { 534 // Set the conditional execution predicate 535 Binary |= II->getPredicate(&MI) << 28; 536 537 // Set first operand 538 Binary |= getMachineOpValue(MI, 0) << ARMII::RegRnShift; 539 540 // Set addressing mode by modifying bits U(23) and P(24) 541 // IA - Increment after - bit U = 1 and bit P = 0 542 // IB - Increment before - bit U = 1 and bit P = 1 543 // DA - Decrement after - bit U = 0 and bit P = 0 544 // DB - Decrement before - bit U = 0 and bit P = 1 545 const MachineOperand &MO = MI.getOperand(1); 546 ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO.getImm()); 547 switch (Mode) { 548 default: assert(0 && "Unknown addressing sub-mode!"); 549 case ARM_AM::da: break; 550 case ARM_AM::db: Binary |= 0x1 << 24; break; 551 case ARM_AM::ia: Binary |= 0x1 << 23; break; 552 case ARM_AM::ib: Binary |= 0x3 << 23; break; 553 } 554 555 // Set bit W(21) 556 if (ARM_AM::getAM4WBFlag(MO.getImm())) 557 Binary |= 0x1 << 21; 558 559 // Set registers 560 for (unsigned i = 4, e = MI.getNumOperands(); i != e; ++i) { 561 const MachineOperand &MO = MI.getOperand(i); 562 if (MO.isReg() && MO.isImplicit()) 563 continue; 564 unsigned RegNum = ARMRegisterInfo::getRegisterNumbering(MO.getReg()); 565 assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && 566 RegNum < 16); 567 Binary |= 0x1 << RegNum; 568 } 569 570 return Binary; 571} 572 573/// getInstrBinary - Return binary encoding for the specified 574/// machine instruction. 575unsigned ARMCodeEmitter::getInstrBinary(const MachineInstr &MI) { 576 // Part of binary is determined by TableGn. 577 unsigned Binary = getBinaryCodeForInstr(MI); 578 579 const TargetInstrDesc &TID = MI.getDesc(); 580 switch (TID.TSFlags & ARMII::AddrModeMask) { 581 case ARMII::AddrModeNone: 582 return getAddrModeNoneInstrBinary(MI, TID, Binary); 583 case ARMII::AddrMode1: 584 return getAddrMode1InstrBinary(MI, TID, Binary); 585 case ARMII::AddrMode2: 586 return getAddrMode2InstrBinary(MI, TID, Binary); 587 case ARMII::AddrMode3: 588 return getAddrMode3InstrBinary(MI, TID, Binary); 589 case ARMII::AddrMode4: 590 return getAddrMode4InstrBinary(MI, TID, Binary); 591 } 592 593 abort(); 594 return 0; 595} 596 597#include "ARMGenCodeEmitter.inc" 598