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