blob: 6066671ff37f3e318fef53f004daad9c865f9d78 [file] [log] [blame]
Evan Cheng148b6a42007-07-05 21:15:40 +00001//===-- ARM/ARMCodeEmitter.cpp - Convert ARM code to machine code ---------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattnerc3dbe702007-07-17 05:56:43 +00005// 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.
Evan Cheng148b6a42007-07-05 21:15:40 +00007//
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"
Evan Cheng0ff94f72007-08-07 01:37:15 +000019#include "ARMRelocations.h"
20#include "ARMAddressingModes.h"
Evan Cheng148b6a42007-07-05 21:15:40 +000021#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);
Evan Cheng0ff94f72007-08-07 01:37:15 +000057 unsigned getBinaryCodeForInstr(const MachineInstr &MI);
58 int getMachineOpValue(const MachineInstr &MI, unsigned OpIndex);
59 unsigned getBaseOpcodeFor(const TargetInstrDescriptor *TID);
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);
Evan Cheng148b6a42007-07-05 21:15:40 +000067
68 private:
Evan Cheng0ff94f72007-08-07 01:37:15 +000069 int getShiftOp(const MachineOperand &MO);
Evan Cheng148b6a42007-07-05 21:15:40 +000070
71 };
72 char Emitter::ID = 0;
73}
74
75/// createARMCodeEmitterPass - Return a pass that emits the collected ARM code
76/// to the specified MCE object.
77FunctionPass *llvm::createARMCodeEmitterPass(ARMTargetMachine &TM,
78 MachineCodeEmitter &MCE) {
79 return new Emitter(TM, MCE);
80}
81
82bool 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();
88
89 do {
90 MCE.startFunction(MF);
91 for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
92 MBB != E; ++MBB) {
93 MCE.StartMachineBasicBlock(MBB);
94 for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end();
95 I != E; ++I)
96 emitInstruction(*I);
97 }
98 } while (MCE.finishFunction(MF));
99
100 return false;
101}
102
Evan Cheng0ff94f72007-08-07 01:37:15 +0000103unsigned Emitter::getBaseOpcodeFor(const TargetInstrDescriptor *TID) {
104 return (TID->TSFlags & ARMII::OpcodeMask) >> ARMII::OpcodeShift;
105}
106
107int Emitter::getShiftOp(const MachineOperand &MO) {
108 unsigned ShiftOp = 0x0;
109 switch(ARM_AM::getAM2ShiftOpc(MO.getImmedValue())) {
110 default: assert(0 && "Unknown shift opc!");
111 case ARM_AM::asr:
112 ShiftOp = 0X2;
113 break;
114 case ARM_AM::lsl:
115 ShiftOp = 0X0;
116 break;
117 case ARM_AM::lsr:
118 ShiftOp = 0X1;
119 break;
120 case ARM_AM::ror:
121 case ARM_AM::rrx:
122 ShiftOp = 0X3;
123 break;
124 }
125 return ShiftOp;
126}
127
128int Emitter::getMachineOpValue(const MachineInstr &MI, unsigned OpIndex) {
129 intptr_t rv = 0;
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()) {
138
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);
147 }
148
149 }
150 return rv;
151}
152
153/// emitGlobalAddressForCall - Emit the specified address to the code stream
154/// assuming this is part of a function call, which is PC relative.
155///
156void Emitter::emitGlobalAddressForCall(GlobalValue *GV, bool DoesntNeedStub) {
157 MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(),
158 ARM::reloc_arm_branch, GV, 0,
159 DoesntNeedStub));
160}
161
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
164/// relative.
165void Emitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) {
166 MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
167 Reloc, ES));
168}
169
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
172/// relative.
173void Emitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc,
174 int Disp /* = 0 */,
175 unsigned PCAdj /* = 0 */) {
176 MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
177 Reloc, CPI, PCAdj));
178}
179
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
182/// relative.
183void Emitter::emitJumpTableAddress(unsigned JTI, unsigned Reloc,
184 unsigned PCAdj /* = 0 */) {
185 MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
186 Reloc, JTI, PCAdj));
187}
188
189
190
Evan Cheng148b6a42007-07-05 21:15:40 +0000191void Emitter::emitInstruction(const MachineInstr &MI) {
192 NumEmitted++; // Keep track of the # of mi's emitted
Evan Cheng0ff94f72007-08-07 01:37:15 +0000193 MCE.emitWordLE(getBinaryCodeForInstr(MI));
194}
195
196unsigned Emitter::getBinaryCodeForInstr(const MachineInstr &MI) {
197 const TargetInstrDescriptor *Desc = MI.getInstrDescriptor();
198 const unsigned opcode = MI.getOpcode();
199 unsigned Value = 0xE0000000;
200 unsigned op;
201
202 switch (Desc->TSFlags & ARMII::AddrModeMask) {
203 case ARMII::AddrModeNone: {
204 switch(Desc->TSFlags & ARMII::FormMask) {
205 default: {
206 assert(0 && "Unknown instruction subtype!");
207 if(opcode == ARM::CLZ) {
208 // set first operand
209 op = getMachineOpValue(MI,0);
210 Value |= op << 12;
211
212 // set second operand
213 op = getMachineOpValue(MI,1);
214 Value |= op;
215 }
216 break;
217 }
218 case ARMII::MulFrm: {
219 Value |= 9 << 4;
220
221 unsigned char BaseOpcode = getBaseOpcodeFor(Desc);
222 Value |= BaseOpcode << 20;
223
224 bool isMUL = opcode == ARM::MUL;
225 bool isMLA = opcode == ARM::MLA;
226
227 // set first operand
228 op = getMachineOpValue(MI,0);
229 Value |= op << (isMUL || isMLA ? 16 : 12);
230
231 // set second operand
232 op = getMachineOpValue(MI,1);
233 Value |= op << (isMUL || isMLA ? 0 : 16);
234
235 // set third operand
236 op = getMachineOpValue(MI,2);
237 Value |= op << (isMUL || isMLA ? 8 : 0);
238
239 if (!isMUL) {
240 op = getMachineOpValue(MI,3);
241 Value |= op << (isMLA ? 12 : 8);
242 }
243
244 break;
245 }
246 case ARMII::Branch: {
247 unsigned BaseOpcode = getBaseOpcodeFor(Desc);
248 Value |= BaseOpcode << 24;
249
250 op = getMachineOpValue(MI,0);
251 Value |= op;
252
253 break;
254 }
255 case ARMII::BranchMisc: {
256 unsigned char BaseOpcode = getBaseOpcodeFor(Desc);
257 Value |= BaseOpcode << 4;
258 Value |= 0x12fff << 8;
259
260 if (opcode == ARM::BX_RET)
261 op = 0xe;
262 else
263 op = getMachineOpValue(MI,0);
264 Value |= op;
265
266 break;
267 }
268 case ARMII::Pseudo:
269 break;
270 }
271
272 break;
273 }
274 case ARMII::AddrMode1: {
275 unsigned char BaseOpcode = getBaseOpcodeFor(Desc);
276 Value |= BaseOpcode << 21;
277
278 unsigned Format = (Desc->TSFlags & ARMII::FormMask);
279 if (Format == ARMII::DPRdMisc) {
280 Value |= getMachineOpValue(MI,0) << 12;
281 Value |= getMachineOpValue(MI,1);
282 switch(opcode) {
283 case ARM::MOVsra_flag: {
284 Value |= 0x1 << 6;
285 Value |= 0x1 << 7;
286 break;
287 }
288 case ARM::MOVsrl_flag: {
289 Value |= 0x1 << 5;
290 Value |= 0x1 << 7;
291 break;
292 }
293 case ARM::MOVrx: {
294 Value |= 0x3 << 5;
295 break;
296 }
297 }
298 break;
299 }
300
301 bool IsDataProcessing3 = false;
302
303 if (Format == ARMII::DPRImS || Format == ARMII::DPRRegS ||
304 Format == ARMII::DPRSoRegS) {
305 Value |= 1 << 20;
306 IsDataProcessing3 = true;
307 }
308
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 ||
318 IsDataProcessing3;
319
320 // set first operand
321 op = getMachineOpValue(MI,0);
322 if (IsDataProcessing1 || IsDataProcessing3) {
323 Value |= op << 12;
324 } else if (IsDataProcessing2) {
325 Value |= op << 16;
326 }
327
328 if (IsDataProcessing3) {
329 op = getMachineOpValue(MI,1);
330 Value |= op << 16;
331 }
332
333 unsigned OperandIndex = IsDataProcessing3 ? 2 : 1;
334 // set shift operand
335 switch (Format) {
336 case ARMII::DPRdIm: case ARMII::DPRnIm:
337 case ARMII::DPRIm: case ARMII::DPRImS: {
338 Value |= 1 << 25;
339 const MachineOperand &MO = MI.getOperand(OperandIndex);
340 op = ARM_AM::getSOImmVal(MO.getImmedValue());
341 Value |= op;
342
343 break;
344 }
345 case ARMII::DPRdReg: case ARMII::DPRnReg:
346 case ARMII::DPRReg: case ARMII::DPRRegS: {
347 op = getMachineOpValue(MI,OperandIndex);
348 Value |= op;
349
350 break;
351 }
352 case ARMII::DPRdSoReg: case ARMII::DPRnSoReg:
353 case ARMII::DPRSoReg: case ARMII::DPRSoRegS: {
354 op = getMachineOpValue(MI,OperandIndex);
355 Value |= op;
356
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!");
362 case ARM_AM::asr: {
363 if(IsShiftByRegister)
364 Value |= 0x5 << 4;
365 else
366 Value |= 0x1 << 6;
367 break;
368 }
369 case ARM_AM::lsl: {
370 if(IsShiftByRegister)
371 Value |= 0x1 << 4;
372 break;
373 }
374 case ARM_AM::lsr: {
375 if(IsShiftByRegister)
376 Value |= 0x3 << 4;
377 else
378 Value |= 0x1 << 5;
379 break;
380 }
381 case ARM_AM::ror: {
382 if(IsShiftByRegister)
383 Value |= 0x7 << 4;
384 else
385 Value |= 0x3 << 5;
386 break;
387 }
388 case ARM_AM::rrx: {
389 Value |= 0x3 << 5;
390 break;
391 }
392 }
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);
398 Value |= op << 8;
399 } else {
400 op = ARM_AM::getSORegOffset(MO2.getImm());
401 Value |= op << 7;
402 }
403 break;
404 }
405 default: assert(false && "Unknown operand type!");
406 break;
407 }
408
409 break;
410 }
411 case ARMII::AddrMode2: {
412 Value |= 1 << 26;
413
414 unsigned Index = (Desc->TSFlags & ARMII::IndexModeMask);
415 if (Index == ARMII::IndexModePre || Index == 0)
416 Value |= 1 << 24;
417 if (Index == ARMII::IndexModePre)
418 Value |= 1 << 21;
419
420 unsigned Format = (Desc->TSFlags & ARMII::FormMask);
421 if (Format == ARMII::LdFrm)
422 Value |= 1 << 20;
423
424 unsigned BitByte = getBaseOpcodeFor(Desc);
425 Value |= BitByte << 22;
426
427 // set first operand
428 op = getMachineOpValue(MI,0);
429 Value |= op << 12;
430
431 // addressing mode
432 op = getMachineOpValue(MI,1);
433 Value |= op << 16;
434
435 const MachineOperand &MO2 = MI.getOperand(2);
436 const MachineOperand &MO3 = MI.getOperand(3);
437
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());
442 break;
443 }
444
445 Value |= 1 << 25;
446 assert(MRegisterInfo::isPhysicalRegister(MO2.getReg()));
447 Value |= ARMRegisterInfo::getRegisterNumbering(MO2.getReg());
448
449 if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) {
450 unsigned ShiftOp = getShiftOp(MO3);
451 Value |= ShiftOp << 5;
452 Value |= ShImm << 7;
453 }
454
455 break;
456 }
457 case ARMII::AddrMode3: {
458 unsigned Index = (Desc->TSFlags & ARMII::IndexModeMask);
459 if (Index == ARMII::IndexModePre || Index == 0)
460 Value |= 1 << 24;
461
462 unsigned Format = (Desc->TSFlags & ARMII::FormMask);
463 if (Format == ARMII::LdFrm)
464 Value |= 1 << 20;
465
466 unsigned char BaseOpcode = getBaseOpcodeFor(Desc);
467 Value |= BaseOpcode << 4;
468
469 // set first operand
470 op = getMachineOpValue(MI,0);
471 Value |= op << 12;
472
473 // addressing mode
474 op = getMachineOpValue(MI,1);
475 Value |= op << 16;
476
477 const MachineOperand &MO2 = MI.getOperand(2);
478 const MachineOperand &MO3 = MI.getOperand(3);
479
480 Value |= (ARM_AM::getAM2Op(MO3.getImm()) == ARM_AM::add ? 1 : 0) << 23;
481
482 if (MO2.getReg()) {
483 Value |= ARMRegisterInfo::getRegisterNumbering(MO2.getReg());
484 break;
485 }
486
487 if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm())) {
488 Value |= 1 << 22;
489 Value |= (ImmOffs >> 4) << 8; // immedH
490 Value |= (ImmOffs & ~0xF); // immedL
491 }
492
493 break;
494 }
495 case ARMII::AddrMode4: {
496 Value |= 1 << 27;
497
498 unsigned Format = (Desc->TSFlags & ARMII::FormMask);
499 if (Format == ARMII::LdFrm)
500 Value |= 1 << 20;
501
502 unsigned OpIndex = 0;
503
504 // set first operand
505 op = getMachineOpValue(MI,OpIndex);
506 Value |= op << 16;
507
508 // set addressing mode
509 const MachineOperand &MO = MI.getOperand(OpIndex + 1);
510 ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO.getImm());
511 switch(Mode) {
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;
517 }
518
519 // set flag W
520 if (ARM_AM::getAM4WBFlag(MO.getImm()))
521 Value |= 0x1 << 21;
522
523 // set registers
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;
529 }
530
531 break;
532 }
533 }
534
535 return Value;
Evan Cheng148b6a42007-07-05 21:15:40 +0000536}