ARMCodeEmitter.cpp revision 6232760ee0d566bcf09b2f20bae65c1d6e73946c
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 "ARMInstrInfo.h" 17#include "ARMSubtarget.h" 18#include "ARMTargetMachine.h" 19#include "ARMRelocations.h" 20#include "ARMAddressingModes.h" 21#include "ARM.h" 22#include "llvm/PassManager.h" 23#include "llvm/CodeGen/MachineCodeEmitter.h" 24#include "llvm/CodeGen/MachineFunctionPass.h" 25#include "llvm/CodeGen/MachineInstr.h" 26#include "llvm/CodeGen/Passes.h" 27#include "llvm/Function.h" 28#include "llvm/ADT/Statistic.h" 29#include "llvm/Support/Compiler.h" 30using namespace llvm; 31 32STATISTIC(NumEmitted, "Number of machine instructions emitted"); 33 34namespace { 35 class VISIBILITY_HIDDEN Emitter : public MachineFunctionPass { 36 const ARMInstrInfo *II; 37 const TargetData *TD; 38 TargetMachine &TM; 39 MachineCodeEmitter &MCE; 40 public: 41 static char ID; 42 explicit Emitter(TargetMachine &tm, MachineCodeEmitter &mce) 43 : MachineFunctionPass((intptr_t)&ID), II(0), TD(0), TM(tm), 44 MCE(mce) {} 45 Emitter(TargetMachine &tm, MachineCodeEmitter &mce, 46 const ARMInstrInfo &ii, const TargetData &td) 47 : MachineFunctionPass((intptr_t)&ID), II(&ii), TD(&td), TM(tm), 48 MCE(mce) {} 49 50 bool runOnMachineFunction(MachineFunction &MF); 51 52 virtual const char *getPassName() const { 53 return "ARM Machine Code Emitter"; 54 } 55 56 void emitInstruction(const MachineInstr &MI); 57 int getMachineOpValue(const MachineInstr &MI, unsigned OpIndex); 58 unsigned getBaseOpcodeFor(const TargetInstrDescriptor *TID); 59 unsigned getBinaryCodeForInstr(const MachineInstr &MI); 60 61 void emitGlobalAddressForCall(GlobalValue *GV, bool DoesntNeedStub); 62 void emitExternalSymbolAddress(const char *ES, unsigned Reloc); 63 void emitConstPoolAddress(unsigned CPI, unsigned Reloc, 64 int Disp = 0, unsigned PCAdj = 0 ); 65 void emitJumpTableAddress(unsigned JTI, unsigned Reloc, 66 unsigned PCAdj = 0); 67 void emitGlobalConstant(const Constant *CV); 68 void emitMachineBasicBlock(MachineBasicBlock *BB); 69 70 private: 71 int getShiftOp(const MachineOperand &MO); 72 73 }; 74 char Emitter::ID = 0; 75} 76 77/// createARMCodeEmitterPass - Return a pass that emits the collected ARM code 78/// to the specified MCE object. 79FunctionPass *llvm::createARMCodeEmitterPass(ARMTargetMachine &TM, 80 MachineCodeEmitter &MCE) { 81 return new Emitter(TM, MCE); 82} 83 84bool Emitter::runOnMachineFunction(MachineFunction &MF) { 85 assert((MF.getTarget().getRelocationModel() != Reloc::Default || 86 MF.getTarget().getRelocationModel() != Reloc::Static) && 87 "JIT relocation model must be set to static or default!"); 88 II = ((ARMTargetMachine&)MF.getTarget()).getInstrInfo(); 89 TD = ((ARMTargetMachine&)MF.getTarget()).getTargetData(); 90 91 do { 92 MCE.startFunction(MF); 93 for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); 94 MBB != E; ++MBB) { 95 MCE.StartMachineBasicBlock(MBB); 96 for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end(); 97 I != E; ++I) 98 emitInstruction(*I); 99 } 100 } while (MCE.finishFunction(MF)); 101 102 return false; 103} 104 105/// getBaseOpcodeFor - Return the opcode value 106unsigned Emitter::getBaseOpcodeFor(const TargetInstrDescriptor *TID) { 107 return (TID->TSFlags & ARMII::OpcodeMask) >> ARMII::OpcodeShift; 108} 109 110/// getShiftOp - Verify which is the shift opcode (bit[6:5]) of the 111/// machine operand. 112int Emitter::getShiftOp(const MachineOperand &MO) { 113 unsigned ShiftOp = 0x0; 114 switch(ARM_AM::getAM2ShiftOpc(MO.getImm())) { 115 default: assert(0 && "Unknown shift opc!"); 116 case ARM_AM::asr: 117 ShiftOp = 0X2; 118 break; 119 case ARM_AM::lsl: 120 ShiftOp = 0X0; 121 break; 122 case ARM_AM::lsr: 123 ShiftOp = 0X1; 124 break; 125 case ARM_AM::ror: 126 case ARM_AM::rrx: 127 ShiftOp = 0X3; 128 break; 129 } 130 return ShiftOp; 131} 132 133int Emitter::getMachineOpValue(const MachineInstr &MI, unsigned OpIndex) { 134 intptr_t rv = 0; 135 const MachineOperand &MO = MI.getOperand(OpIndex); 136 if (MO.isRegister()) { 137 assert(MRegisterInfo::isPhysicalRegister(MO.getReg())); 138 rv = ARMRegisterInfo::getRegisterNumbering(MO.getReg()); 139 } else if (MO.isImmediate()) { 140 rv = MO.getImm(); 141 } else if (MO.isGlobalAddress()) { 142 emitGlobalAddressForCall(MO.getGlobal(), false); 143 } else if (MO.isExternalSymbol()) { 144 emitExternalSymbolAddress(MO.getSymbolName(), ARM::reloc_arm_relative); 145 } else if (MO.isConstantPoolIndex()) { 146 emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_relative); 147 } else if (MO.isJumpTableIndex()) { 148 emitJumpTableAddress(MO.getIndex(), ARM::reloc_arm_relative); 149 } else if (MO.isMachineBasicBlock()) { 150 emitMachineBasicBlock(MO.getMBB()); 151 } 152 153 return rv; 154} 155 156/// emitGlobalAddressForCall - Emit the specified address to the code stream 157/// assuming this is part of a function call, which is PC relative. 158/// 159void Emitter::emitGlobalAddressForCall(GlobalValue *GV, bool DoesntNeedStub) { 160 MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), 161 ARM::reloc_arm_branch, GV, 0, 162 DoesntNeedStub)); 163} 164 165/// emitExternalSymbolAddress - Arrange for the address of an external symbol to 166/// be emitted to the current location in the function, and allow it to be PC 167/// relative. 168void Emitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) { 169 MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), 170 Reloc, ES)); 171} 172 173/// emitConstPoolAddress - Arrange for the address of an constant pool 174/// to be emitted to the current location in the function, and allow it to be PC 175/// relative. 176void Emitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc, 177 int Disp /* = 0 */, 178 unsigned PCAdj /* = 0 */) { 179 MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), 180 Reloc, CPI, PCAdj)); 181} 182 183/// emitJumpTableAddress - Arrange for the address of a jump table to 184/// be emitted to the current location in the function, and allow it to be PC 185/// relative. 186void Emitter::emitJumpTableAddress(unsigned JTI, unsigned Reloc, 187 unsigned PCAdj /* = 0 */) { 188 MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), 189 Reloc, JTI, PCAdj)); 190} 191 192/// emitMachineBasicBlock - Emit the specified address basic block. 193void Emitter::emitMachineBasicBlock(MachineBasicBlock *BB) { 194 MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), 195 ARM::reloc_arm_branch, BB)); 196} 197 198void Emitter::emitInstruction(const MachineInstr &MI) { 199 NumEmitted++; // Keep track of the # of mi's emitted 200 MCE.emitWordLE(getBinaryCodeForInstr(MI)); 201} 202 203unsigned Emitter::getBinaryCodeForInstr(const MachineInstr &MI) { 204 const TargetInstrDescriptor *Desc = MI.getDesc(); 205 unsigned opcode = Desc->Opcode; 206 // initial instruction mask 207 unsigned Value = 0xE0000000; 208 unsigned op; 209 210 switch (Desc->TSFlags & ARMII::AddrModeMask) { 211 case ARMII::AddrModeNone: { 212 switch(Desc->TSFlags & ARMII::FormMask) { 213 default: { 214 assert(0 && "Unknown instruction subtype!"); 215 // treat special instruction CLZ 216 if(opcode == ARM::CLZ) { 217 // set first operand 218 op = getMachineOpValue(MI,0); 219 Value |= op << ARMII::RegRdShift; 220 221 // set second operand 222 op = getMachineOpValue(MI,1); 223 Value |= op; 224 } 225 break; 226 } 227 case ARMII::MulSMLAW: 228 case ARMII::MulSMULW: 229 // set bit W(21) 230 Value |= 1 << 21; 231 case ARMII::MulSMLA: 232 case ARMII::MulSMUL: { 233 // set bit W(21) 234 Value |= 1 << 24; 235 236 // set opcode (bit[7:4]). For more information, see ARM-ARM page A3-31 237 // SMLA<x><y> - 1yx0 238 // SMLAW<y> - 1y00 239 // SMULW<y> - 1y10 240 // SMUL<x><y> - 1yx0 241 unsigned char BaseOpcode = getBaseOpcodeFor(Desc); 242 Value |= BaseOpcode << 4; 243 244 unsigned Format = (Desc->TSFlags & ARMII::FormMask); 245 if (Format == ARMII::MulSMUL) 246 Value |= 1 << 22; 247 248 // set first operand 249 op = getMachineOpValue(MI,0); 250 Value |= op << ARMII::RegRnShift; 251 252 // set second operand 253 op = getMachineOpValue(MI,1); 254 Value |= op; 255 256 // set third operand 257 op = getMachineOpValue(MI,2); 258 Value |= op << ARMII::RegRsShift; 259 260 // instructions SMLA and SMLAW have a fourth operand 261 if (Format != ARMII::MulSMULW && Format != ARMII::MulSMUL) { 262 op = getMachineOpValue(MI,3); 263 Value |= op << ARMII::RegRdShift; 264 } 265 266 break; 267 } 268 case ARMII::MulFrm: { 269 // bit[7:4] is always 9 270 Value |= 9 << 4; 271 // set opcode (bit[23:20]) 272 unsigned char BaseOpcode = getBaseOpcodeFor(Desc); 273 Value |= BaseOpcode << 20; 274 275 bool isMUL = opcode == ARM::MUL; 276 bool isMLA = opcode == ARM::MLA; 277 278 // set first operand 279 op = getMachineOpValue(MI,0); 280 Value |= op << (isMUL || isMLA ? ARMII::RegRnShift : ARMII::RegRdShift); 281 282 // set second operand 283 op = getMachineOpValue(MI,1); 284 Value |= op << (isMUL || isMLA ? 0 : ARMII::RegRnShift); 285 286 // set third operand 287 op = getMachineOpValue(MI,2); 288 Value |= op << (isMUL || isMLA ? ARMII::RegRsShift : 0); 289 290 // multiply instructions (except MUL), have a fourth operand 291 if (!isMUL) { 292 op = getMachineOpValue(MI,3); 293 Value |= op << (isMLA ? ARMII::RegRdShift : ARMII::RegRsShift); 294 } 295 296 break; 297 } 298 case ARMII::Branch: { 299 // set opcode (bit[27:24]) 300 unsigned BaseOpcode = getBaseOpcodeFor(Desc); 301 Value |= BaseOpcode << 24; 302 303 // set signed_immed_24 field 304 op = getMachineOpValue(MI,0); 305 Value |= op; 306 307 // if it is a conditional branch, set cond field 308 if (opcode == ARM::Bcc) { 309 op = getMachineOpValue(MI,1); 310 Value &= 0x0FFFFFFF; // clear conditional field 311 Value |= op << 28; // set conditional field 312 } 313 314 break; 315 } 316 case ARMII::BranchMisc: { 317 // set opcode (bit[7:4]) 318 unsigned char BaseOpcode = getBaseOpcodeFor(Desc); 319 Value |= BaseOpcode << 4; 320 // set bit[27:24] to 1, set bit[23:20] to 2 and set bit[19:8] to 0xFFF 321 Value |= 0x12fff << 8; 322 323 if (opcode == ARM::BX_RET) 324 op = 0xe; // the return register is LR 325 else 326 // otherwise, set the return register 327 op = getMachineOpValue(MI,0); 328 Value |= op; 329 330 break; 331 } 332 case ARMII::Pseudo: 333 break; 334 } 335 336 break; 337 } 338 case ARMII::AddrMode1: { 339 // set opcode (bit[24:21]) of data-processing instructions 340 unsigned char BaseOpcode = getBaseOpcodeFor(Desc); 341 Value |= BaseOpcode << 21; 342 343 // treat 3 special instructions: MOVsra_flag, MOVsrl_flag and 344 // MOVrx. 345 unsigned Format = (Desc->TSFlags & ARMII::FormMask); 346 if (Format == ARMII::DPRdMisc) { 347 Value |= getMachineOpValue(MI,0) << ARMII::RegRdShift; 348 Value |= getMachineOpValue(MI,1); 349 switch(opcode) { 350 case ARM::MOVsra_flag: { 351 Value |= 0x1 << 6; 352 Value |= 0x1 << 7; 353 break; 354 } 355 case ARM::MOVsrl_flag: { 356 Value |= 0x1 << 5; 357 Value |= 0x1 << 7; 358 break; 359 } 360 case ARM::MOVrx: { 361 Value |= 0x3 << 5; 362 break; 363 } 364 } 365 break; 366 } 367 368 // Data processing operand instructions has 3 possible encodings (for more 369 // information, see ARM-ARM page A3-10): 370 // 1. <instr> <Rd>,<shifter_operand> 371 // 2. <instr> <Rn>,<shifter_operand> 372 // 3. <instr> <Rd>,<Rn>,<shifter_operand> 373 bool IsDataProcessing1 = Format == ARMII::DPRdIm || 374 Format == ARMII::DPRdReg || 375 Format == ARMII::DPRdSoReg; 376 bool IsDataProcessing2 = Format == ARMII::DPRnIm || 377 Format == ARMII::DPRnReg || 378 Format == ARMII::DPRnSoReg; 379 bool IsDataProcessing3 = false; 380 381 // set bit S(20) 382 if (Format == ARMII::DPRImS || Format == ARMII::DPRRegS || 383 Format == ARMII::DPRSoRegS || IsDataProcessing2) { 384 Value |= 1 << ARMII::S_BitShift; 385 IsDataProcessing3 = !IsDataProcessing2; 386 } 387 388 IsDataProcessing3 = Format == ARMII::DPRIm || 389 Format == ARMII::DPRReg || 390 Format == ARMII::DPRSoReg || 391 IsDataProcessing3; 392 393 // set first operand 394 op = getMachineOpValue(MI,0); 395 if (IsDataProcessing1 || IsDataProcessing3) { 396 Value |= op << ARMII::RegRdShift; 397 } else if (IsDataProcessing2) { 398 Value |= op << ARMII::RegRnShift; 399 } 400 401 // set second operand of data processing #3 instructions 402 if (IsDataProcessing3) { 403 op = getMachineOpValue(MI,1); 404 Value |= op << ARMII::RegRnShift; 405 } 406 407 unsigned OperandIndex = IsDataProcessing3 ? 2 : 1; 408 switch (Format) { 409 case ARMII::DPRdIm: case ARMII::DPRnIm: 410 case ARMII::DPRIm: case ARMII::DPRImS: { 411 // set bit I(25) to identify this is the immediate form of <shifter_op> 412 Value |= 1 << ARMII::I_BitShift; 413 // set immed_8 field 414 const MachineOperand &MO = MI.getOperand(OperandIndex); 415 op = ARM_AM::getSOImmVal(MO.getImm()); 416 Value |= op; 417 418 break; 419 } 420 case ARMII::DPRdReg: case ARMII::DPRnReg: 421 case ARMII::DPRReg: case ARMII::DPRRegS: { 422 // set last operand (register Rm) 423 op = getMachineOpValue(MI,OperandIndex); 424 Value |= op; 425 426 break; 427 } 428 case ARMII::DPRdSoReg: case ARMII::DPRnSoReg: 429 case ARMII::DPRSoReg: case ARMII::DPRSoRegS: { 430 // set last operand (register Rm) 431 op = getMachineOpValue(MI,OperandIndex); 432 Value |= op; 433 434 const MachineOperand &MO1 = MI.getOperand(OperandIndex + 1); 435 const MachineOperand &MO2 = MI.getOperand(OperandIndex + 2); 436 // identify it the instr is in immed or register shifts encoding 437 bool IsShiftByRegister = MO1.getReg() > 0; 438 // set shift operand (bit[6:4]). 439 // ASR - 101 if it is in register shifts encoding; 100, otherwise. 440 // LSL - 001 if it is in register shifts encoding; 000, otherwise. 441 // LSR - 011 if it is in register shifts encoding; 010, otherwise. 442 // ROR - 111 if it is in register shifts encoding; 110, otherwise. 443 // RRX - 110 and bit[11:7] clear. 444 switch(ARM_AM::getSORegShOp(MO2.getImm())) { 445 default: assert(0 && "Unknown shift opc!"); 446 case ARM_AM::asr: { 447 if(IsShiftByRegister) 448 Value |= 0x5 << 4; 449 else 450 Value |= 0x1 << 6; 451 break; 452 } 453 case ARM_AM::lsl: { 454 if(IsShiftByRegister) 455 Value |= 0x1 << 4; 456 break; 457 } 458 case ARM_AM::lsr: { 459 if(IsShiftByRegister) 460 Value |= 0x3 << 4; 461 else 462 Value |= 0x1 << 5; 463 break; 464 } 465 case ARM_AM::ror: { 466 if(IsShiftByRegister) 467 Value |= 0x7 << 4; 468 else 469 Value |= 0x3 << 5; 470 break; 471 } 472 case ARM_AM::rrx: { 473 Value |= 0x3 << 5; 474 break; 475 } 476 } 477 // set the field related to shift operations (except rrx). 478 if(ARM_AM::getSORegShOp(MO2.getImm()) != ARM_AM::rrx) 479 if(IsShiftByRegister) { 480 // set the value of bit[11:8] (register Rs). 481 assert(MRegisterInfo::isPhysicalRegister(MO1.getReg())); 482 op = ARMRegisterInfo::getRegisterNumbering(MO1.getReg()); 483 assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0); 484 Value |= op << ARMII::RegRsShift; 485 } else { 486 // set the value of bit [11:7] (shift_immed field). 487 op = ARM_AM::getSORegOffset(MO2.getImm()); 488 Value |= op << 7; 489 } 490 break; 491 } 492 default: assert(false && "Unknown operand type!"); 493 break; 494 } 495 496 break; 497 } 498 case ARMII::AddrMode2: { 499 // bit 26 is always 1 500 Value |= 1 << 26; 501 502 unsigned Index = (Desc->TSFlags & ARMII::IndexModeMask); 503 // if the instruction uses offset addressing or pre-indexed addressing, 504 // set bit P(24) to 1 505 if (Index == ARMII::IndexModePre || Index == 0) 506 Value |= 1 << ARMII::IndexShift; 507 // if the instruction uses post-indexed addressing, set bit W(21) to 1 508 if (Index == ARMII::IndexModePre) 509 Value |= 1 << 21; 510 511 unsigned Format = (Desc->TSFlags & ARMII::FormMask); 512 // If it is a load instruction (except LDRD), set bit L(20) to 1 513 if (Format == ARMII::LdFrm) 514 Value |= 1 << ARMII::L_BitShift; 515 516 // set bit B(22) 517 unsigned BitByte = getBaseOpcodeFor(Desc); 518 Value |= BitByte << 22; 519 520 // set first operand 521 op = getMachineOpValue(MI,0); 522 Value |= op << ARMII::RegRdShift; 523 524 // set second operand 525 op = getMachineOpValue(MI,1); 526 Value |= op << ARMII::RegRnShift; 527 528 const MachineOperand &MO2 = MI.getOperand(2); 529 const MachineOperand &MO3 = MI.getOperand(3); 530 531 // set bit U(23) according to signal of immed value (positive or negative) 532 Value |= (ARM_AM::getAM2Op(MO3.getImm()) == ARM_AM::add ? 1 : 0) << 533 ARMII::U_BitShift; 534 if (!MO2.getReg()) { // is immediate 535 if (ARM_AM::getAM2Offset(MO3.getImm())) 536 // set the value of offset_12 field 537 Value |= ARM_AM::getAM2Offset(MO3.getImm()); 538 break; 539 } 540 541 // set bit I(25), because this is not in immediate enconding. 542 Value |= 1 << ARMII::I_BitShift; 543 assert(MRegisterInfo::isPhysicalRegister(MO2.getReg())); 544 // set bit[3:0] to the corresponding Rm register 545 Value |= ARMRegisterInfo::getRegisterNumbering(MO2.getReg()); 546 547 // if this instr is in scaled register offset/index instruction, set 548 // shift_immed(bit[11:7]) and shift(bit[6:5]) fields. 549 if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) { 550 unsigned ShiftOp = getShiftOp(MO3); 551 Value |= ShiftOp << 5; // shift 552 Value |= ShImm << 7; // shift_immed 553 } 554 555 break; 556 } 557 case ARMII::AddrMode3: { 558 559 unsigned Index = (Desc->TSFlags & ARMII::IndexModeMask); 560 // if the instruction uses offset addressing or pre-indexed addressing, 561 // set bit P(24) to 1 562 if (Index == ARMII::IndexModePre || Index == 0) 563 Value |= 1 << ARMII::IndexShift; 564 565 unsigned Format = (Desc->TSFlags & ARMII::FormMask); 566 // If it is a load instruction (except LDRD), set bit L(20) to 1 567 if (Format == ARMII::LdFrm && opcode != ARM::LDRD) 568 Value |= 1 << ARMII::L_BitShift; 569 570 // bit[7:4] is the opcode of this instruction class (bits S and H). 571 unsigned char BaseOpcode = getBaseOpcodeFor(Desc); 572 Value |= BaseOpcode << 4; 573 574 // set first operand 575 op = getMachineOpValue(MI,0); 576 Value |= op << ARMII::RegRdShift; 577 578 // set second operand 579 op = getMachineOpValue(MI,1); 580 Value |= op << ARMII::RegRnShift; 581 582 const MachineOperand &MO2 = MI.getOperand(2); 583 const MachineOperand &MO3 = MI.getOperand(3); 584 585 // set bit U(23) according to signal of immed value (positive or negative) 586 Value |= (ARM_AM::getAM2Op(MO3.getImm()) == ARM_AM::add ? 1 : 0) << 587 ARMII::U_BitShift; 588 589 // if this instr is in register offset/index encoding, set bit[3:0] 590 // to the corresponding Rm register. 591 if (MO2.getReg()) { 592 Value |= ARMRegisterInfo::getRegisterNumbering(MO2.getReg()); 593 break; 594 } 595 596 // if this instr is in immediate offset/index encoding, set bit 22 to 1 597 if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm())) { 598 Value |= 1 << 22; 599 // set operands 600 Value |= (ImmOffs >> 4) << 8; // immedH 601 Value |= (ImmOffs & ~0xF); // immedL 602 } 603 604 break; 605 } 606 case ARMII::AddrMode4: { 607 // bit 27 is always 1 608 Value |= 1 << 27; 609 610 unsigned Format = (Desc->TSFlags & ARMII::FormMask); 611 // if it is a load instr, set bit L(20) to 1 612 if (Format == ARMII::LdFrm) 613 Value |= 1 << ARMII::L_BitShift; 614 615 unsigned OpIndex = 0; 616 617 // set first operand 618 op = getMachineOpValue(MI,OpIndex); 619 Value |= op << ARMII::RegRnShift; 620 621 // set addressing mode by modifying bits U(23) and P(24) 622 // IA - Increment after - bit U = 1 and bit P = 0 623 // IB - Increment before - bit U = 1 and bit P = 1 624 // DA - Decrement after - bit U = 0 and bit P = 0 625 // DB - Decrement before - bit U = 0 and bit P = 1 626 const MachineOperand &MO = MI.getOperand(OpIndex + 1); 627 ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO.getImm()); 628 switch(Mode) { 629 default: assert(0 && "Unknown addressing sub-mode!"); 630 case ARM_AM::ia: Value |= 0x1 << 23; break; 631 case ARM_AM::ib: Value |= 0x3 << 23; break; 632 case ARM_AM::da: break; 633 case ARM_AM::db: Value |= 0x1 << 24; break; 634 } 635 636 // set bit W(21) 637 if (ARM_AM::getAM4WBFlag(MO.getImm())) 638 Value |= 0x1 << 21; 639 640 // set registers 641 for (unsigned i = OpIndex + 4, e = MI.getNumOperands(); i != e; ++i) { 642 const MachineOperand &MOR = MI.getOperand(i); 643 unsigned RegNumber = ARMRegisterInfo::getRegisterNumbering(MOR.getReg()); 644 assert(MRegisterInfo::isPhysicalRegister(MOR.getReg()) && RegNumber < 16); 645 Value |= 0x1 << RegNumber; 646 } 647 648 break; 649 } 650 } 651 652 return Value; 653} 654