1 //===-- ARM/ARMCodeEmitter.cpp - Convert ARM code to machine code ---------===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the Raul Herbster and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the pass that transforms the ARM machine instructions into
11 // relocatable machine code.
13 //===----------------------------------------------------------------------===//
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"
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"
32 STATISTIC(NumEmitted, "Number of machine instructions emitted");
35 class VISIBILITY_HIDDEN Emitter : public MachineFunctionPass {
36 const ARMInstrInfo *II;
39 MachineCodeEmitter &MCE;
42 explicit Emitter(TargetMachine &tm, MachineCodeEmitter &mce)
43 : MachineFunctionPass((intptr_t)&ID), II(0), TD(0), TM(tm),
45 Emitter(TargetMachine &tm, MachineCodeEmitter &mce,
46 const ARMInstrInfo &ii, const TargetData &td)
47 : MachineFunctionPass((intptr_t)&ID), II(&ii), TD(&td), TM(tm),
50 bool runOnMachineFunction(MachineFunction &MF);
52 virtual const char *getPassName() const {
53 return "ARM Machine Code Emitter";
56 void emitInstruction(const MachineInstr &MI);
57 unsigned getBinaryCodeForInstr(const MachineInstr &MI);
58 int getMachineOpValue(const MachineInstr &MI, unsigned OpIndex);
59 unsigned getBaseOpcodeFor(const TargetInstrDescriptor *TID);
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,
69 int getShiftOp(const MachineOperand &MO);
75 /// createARMCodeEmitterPass - Return a pass that emits the collected ARM code
76 /// to the specified MCE object.
77 FunctionPass *llvm::createARMCodeEmitterPass(ARMTargetMachine &TM,
78 MachineCodeEmitter &MCE) {
79 return new Emitter(TM, MCE);
82 bool Emitter::runOnMachineFunction(MachineFunction &MF) {
83 assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
84 MF.getTarget().getRelocationModel() != Reloc::Static) &&
85 "JIT relocation model must be set to static or default!");
86 II = ((ARMTargetMachine&)MF.getTarget()).getInstrInfo();
87 TD = ((ARMTargetMachine&)MF.getTarget()).getTargetData();
90 MCE.startFunction(MF);
91 for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
93 MCE.StartMachineBasicBlock(MBB);
94 for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end();
98 } while (MCE.finishFunction(MF));
103 unsigned Emitter::getBaseOpcodeFor(const TargetInstrDescriptor *TID) {
104 return (TID->TSFlags & ARMII::OpcodeMask) >> ARMII::OpcodeShift;
107 int Emitter::getShiftOp(const MachineOperand &MO) {
108 unsigned ShiftOp = 0x0;
109 switch(ARM_AM::getAM2ShiftOpc(MO.getImmedValue())) {
110 default: assert(0 && "Unknown shift opc!");
128 int Emitter::getMachineOpValue(const MachineInstr &MI, unsigned OpIndex) {
130 const MachineOperand &MO = MI.getOperand(OpIndex);
131 if (MO.isRegister()) {
132 assert(MRegisterInfo::isPhysicalRegister(MO.getReg()));
133 rv = ARMRegisterInfo::getRegisterNumbering(MO.getReg());
134 } else if (MO.isImmediate()) {
135 rv = MO.getImmedValue();
136 } else if (MO.isGlobalAddress() || MO.isExternalSymbol() ||
137 MO.isConstantPoolIndex() || MO.isJumpTableIndex()) {
139 if (MO.isGlobalAddress()) {
140 emitGlobalAddressForCall(MO.getGlobal(), true);
141 } else if (MO.isExternalSymbol()) {
142 emitExternalSymbolAddress(MO.getSymbolName(), ARM::reloc_arm_relative);
143 } else if (MO.isConstantPoolIndex()) {
144 emitConstPoolAddress(MO.getConstantPoolIndex(), ARM::reloc_arm_relative);
145 } else if (MO.isJumpTableIndex()) {
146 emitJumpTableAddress(MO.getJumpTableIndex(), ARM::reloc_arm_relative);
153 /// emitGlobalAddressForCall - Emit the specified address to the code stream
154 /// assuming this is part of a function call, which is PC relative.
156 void Emitter::emitGlobalAddressForCall(GlobalValue *GV, bool DoesntNeedStub) {
157 MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(),
158 ARM::reloc_arm_branch, GV, 0,
162 /// emitExternalSymbolAddress - Arrange for the address of an external symbol to
163 /// be emitted to the current location in the function, and allow it to be PC
165 void Emitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) {
166 MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
170 /// emitConstPoolAddress - Arrange for the address of an constant pool
171 /// to be emitted to the current location in the function, and allow it to be PC
173 void Emitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc,
175 unsigned PCAdj /* = 0 */) {
176 MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
180 /// emitJumpTableAddress - Arrange for the address of a jump table to
181 /// be emitted to the current location in the function, and allow it to be PC
183 void Emitter::emitJumpTableAddress(unsigned JTI, unsigned Reloc,
184 unsigned PCAdj /* = 0 */) {
185 MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
191 void Emitter::emitInstruction(const MachineInstr &MI) {
192 NumEmitted++; // Keep track of the # of mi's emitted
193 MCE.emitWordLE(getBinaryCodeForInstr(MI));
196 unsigned Emitter::getBinaryCodeForInstr(const MachineInstr &MI) {
197 const TargetInstrDescriptor *Desc = MI.getInstrDescriptor();
198 const unsigned opcode = MI.getOpcode();
199 unsigned Value = 0xE0000000;
202 switch (Desc->TSFlags & ARMII::AddrModeMask) {
203 case ARMII::AddrModeNone: {
204 switch(Desc->TSFlags & ARMII::FormMask) {
206 assert(0 && "Unknown instruction subtype!");
207 if(opcode == ARM::CLZ) {
209 op = getMachineOpValue(MI,0);
212 // set second operand
213 op = getMachineOpValue(MI,1);
218 case ARMII::MulFrm: {
221 unsigned char BaseOpcode = getBaseOpcodeFor(Desc);
222 Value |= BaseOpcode << 20;
224 bool isMUL = opcode == ARM::MUL;
225 bool isMLA = opcode == ARM::MLA;
228 op = getMachineOpValue(MI,0);
229 Value |= op << (isMUL || isMLA ? 16 : 12);
231 // set second operand
232 op = getMachineOpValue(MI,1);
233 Value |= op << (isMUL || isMLA ? 0 : 16);
236 op = getMachineOpValue(MI,2);
237 Value |= op << (isMUL || isMLA ? 8 : 0);
240 op = getMachineOpValue(MI,3);
241 Value |= op << (isMLA ? 12 : 8);
246 case ARMII::Branch: {
247 unsigned BaseOpcode = getBaseOpcodeFor(Desc);
248 Value |= BaseOpcode << 24;
250 op = getMachineOpValue(MI,0);
255 case ARMII::BranchMisc: {
256 unsigned char BaseOpcode = getBaseOpcodeFor(Desc);
257 Value |= BaseOpcode << 4;
258 Value |= 0x12fff << 8;
260 if (opcode == ARM::BX_RET)
263 op = getMachineOpValue(MI,0);
274 case ARMII::AddrMode1: {
275 unsigned char BaseOpcode = getBaseOpcodeFor(Desc);
276 Value |= BaseOpcode << 21;
278 unsigned Format = (Desc->TSFlags & ARMII::FormMask);
279 if (Format == ARMII::DPRdMisc) {
280 Value |= getMachineOpValue(MI,0) << 12;
281 Value |= getMachineOpValue(MI,1);
283 case ARM::MOVsra_flag: {
288 case ARM::MOVsrl_flag: {
301 bool IsDataProcessing3 = false;
303 if (Format == ARMII::DPRImS || Format == ARMII::DPRRegS ||
304 Format == ARMII::DPRSoRegS) {
306 IsDataProcessing3 = true;
309 bool IsDataProcessing1 = Format == ARMII::DPRdIm ||
310 Format == ARMII::DPRdReg ||
311 Format == ARMII::DPRdSoReg;
312 bool IsDataProcessing2 = Format == ARMII::DPRnIm ||
313 Format == ARMII::DPRnReg ||
314 Format == ARMII::DPRnSoReg;
315 IsDataProcessing3 = Format == ARMII::DPRIm ||
316 Format == ARMII::DPRReg ||
317 Format == ARMII::DPRSoReg ||
321 op = getMachineOpValue(MI,0);
322 if (IsDataProcessing1 || IsDataProcessing3) {
324 } else if (IsDataProcessing2) {
328 if (IsDataProcessing3) {
329 op = getMachineOpValue(MI,1);
333 unsigned OperandIndex = IsDataProcessing3 ? 2 : 1;
336 case ARMII::DPRdIm: case ARMII::DPRnIm:
337 case ARMII::DPRIm: case ARMII::DPRImS: {
339 const MachineOperand &MO = MI.getOperand(OperandIndex);
340 op = ARM_AM::getSOImmVal(MO.getImmedValue());
345 case ARMII::DPRdReg: case ARMII::DPRnReg:
346 case ARMII::DPRReg: case ARMII::DPRRegS: {
347 op = getMachineOpValue(MI,OperandIndex);
352 case ARMII::DPRdSoReg: case ARMII::DPRnSoReg:
353 case ARMII::DPRSoReg: case ARMII::DPRSoRegS: {
354 op = getMachineOpValue(MI,OperandIndex);
357 const MachineOperand &MO1 = MI.getOperand(OperandIndex + 1);
358 const MachineOperand &MO2 = MI.getOperand(OperandIndex + 2);
359 bool IsShiftByRegister = MO1.getReg() > 0;
360 switch(ARM_AM::getSORegShOp(MO2.getImmedValue())) {
361 default: assert(0 && "Unknown shift opc!");
363 if(IsShiftByRegister)
370 if(IsShiftByRegister)
375 if(IsShiftByRegister)
382 if(IsShiftByRegister)
393 if(ARM_AM::getSORegShOp(MO2.getImmedValue()) != ARM_AM::rrx)
394 if(IsShiftByRegister) {
395 assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
396 op = ARMRegisterInfo::getRegisterNumbering(MO1.getReg());
397 assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
400 op = ARM_AM::getSORegOffset(MO2.getImm());
405 default: assert(false && "Unknown operand type!");
411 case ARMII::AddrMode2: {
414 unsigned Index = (Desc->TSFlags & ARMII::IndexModeMask);
415 if (Index == ARMII::IndexModePre || Index == 0)
417 if (Index == ARMII::IndexModePre)
420 unsigned Format = (Desc->TSFlags & ARMII::FormMask);
421 if (Format == ARMII::LdFrm)
424 unsigned BitByte = getBaseOpcodeFor(Desc);
425 Value |= BitByte << 22;
428 op = getMachineOpValue(MI,0);
432 op = getMachineOpValue(MI,1);
435 const MachineOperand &MO2 = MI.getOperand(2);
436 const MachineOperand &MO3 = MI.getOperand(3);
438 Value |= (ARM_AM::getAM2Op(MO3.getImm()) == ARM_AM::add ? 1 : 0) << 23;
439 if (!MO2.getReg()) { // is immediate
440 if (ARM_AM::getAM2Offset(MO3.getImm()))
441 Value |= ARM_AM::getAM2Offset(MO3.getImm());
446 assert(MRegisterInfo::isPhysicalRegister(MO2.getReg()));
447 Value |= ARMRegisterInfo::getRegisterNumbering(MO2.getReg());
449 if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) {
450 unsigned ShiftOp = getShiftOp(MO3);
451 Value |= ShiftOp << 5;
457 case ARMII::AddrMode3: {
458 unsigned Index = (Desc->TSFlags & ARMII::IndexModeMask);
459 if (Index == ARMII::IndexModePre || Index == 0)
462 unsigned Format = (Desc->TSFlags & ARMII::FormMask);
463 if (Format == ARMII::LdFrm)
466 unsigned char BaseOpcode = getBaseOpcodeFor(Desc);
467 Value |= BaseOpcode << 4;
470 op = getMachineOpValue(MI,0);
474 op = getMachineOpValue(MI,1);
477 const MachineOperand &MO2 = MI.getOperand(2);
478 const MachineOperand &MO3 = MI.getOperand(3);
480 Value |= (ARM_AM::getAM2Op(MO3.getImm()) == ARM_AM::add ? 1 : 0) << 23;
483 Value |= ARMRegisterInfo::getRegisterNumbering(MO2.getReg());
487 if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm())) {
489 Value |= (ImmOffs >> 4) << 8; // immedH
490 Value |= (ImmOffs & ~0xF); // immedL
495 case ARMII::AddrMode4: {
498 unsigned Format = (Desc->TSFlags & ARMII::FormMask);
499 if (Format == ARMII::LdFrm)
502 unsigned OpIndex = 0;
505 op = getMachineOpValue(MI,OpIndex);
508 // set addressing mode
509 const MachineOperand &MO = MI.getOperand(OpIndex + 1);
510 ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO.getImm());
512 default: assert(0 && "Unknown addressing sub-mode!");
513 case ARM_AM::ia: Value |= 0x1 << 23; break;
514 case ARM_AM::ib: Value |= 0x2 << 23; break;
515 case ARM_AM::da: break;
516 case ARM_AM::db: Value |= 0x1 << 24; break;
520 if (ARM_AM::getAM4WBFlag(MO.getImm()))
524 for (unsigned i = OpIndex + 4, e = MI.getNumOperands(); i != e; ++i) {
525 const MachineOperand &MOR = MI.getOperand(i);
526 unsigned RegNumber = ARMRegisterInfo::getRegisterNumbering(MOR.getReg());
527 assert(MRegisterInfo::isPhysicalRegister(MOR.getReg()) && RegNumber < 16);
528 Value |= 0x1 << RegNumber;