1 //===-- Alpha/AlphaCodeEmitter.cpp - Convert Alpha code to machine code ---===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the pass that transforms the Alpha machine instructions
11 // into relocatable machine code.
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "alpha-emitter"
16 #include "AlphaTargetMachine.h"
17 #include "AlphaRelocations.h"
19 #include "llvm/PassManager.h"
20 #include "llvm/CodeGen/MachineCodeEmitter.h"
21 #include "llvm/CodeGen/JITCodeEmitter.h"
22 #include "llvm/CodeGen/ObjectCodeEmitter.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/CodeGen/MachineInstr.h"
25 #include "llvm/CodeGen/Passes.h"
26 #include "llvm/Function.h"
27 #include "llvm/Support/Compiler.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/ErrorHandling.h"
30 #include "llvm/Support/raw_ostream.h"
35 class AlphaCodeEmitter
{
36 MachineCodeEmitter
&MCE
;
38 AlphaCodeEmitter(MachineCodeEmitter
&mce
) : MCE(mce
) {}
40 /// getBinaryCodeForInstr - This function, generated by the
41 /// CodeEmitterGenerator using TableGen, produces the binary encoding for
42 /// machine instructions.
44 unsigned getBinaryCodeForInstr(const MachineInstr
&MI
);
46 /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
48 unsigned getMachineOpValue(const MachineInstr
&MI
,
49 const MachineOperand
&MO
);
52 template <class CodeEmitter
>
53 class VISIBILITY_HIDDEN Emitter
: public MachineFunctionPass
,
54 public AlphaCodeEmitter
56 const AlphaInstrInfo
*II
;
62 explicit Emitter(TargetMachine
&tm
, CodeEmitter
&mce
)
63 : MachineFunctionPass(&ID
), AlphaCodeEmitter(mce
),
64 II(0), TM(tm
), MCE(mce
) {}
65 Emitter(TargetMachine
&tm
, CodeEmitter
&mce
, const AlphaInstrInfo
& ii
)
66 : MachineFunctionPass(&ID
), AlphaCodeEmitter(mce
),
67 II(&ii
), TM(tm
), MCE(mce
) {}
69 bool runOnMachineFunction(MachineFunction
&MF
);
71 virtual const char *getPassName() const {
72 return "Alpha Machine Code Emitter";
76 void emitBasicBlock(MachineBasicBlock
&MBB
);
79 template <class CodeEmitter
>
80 char Emitter
<CodeEmitter
>::ID
= 0;
83 /// createAlphaCodeEmitterPass - Return a pass that emits the collected Alpha
84 /// code to the specified MCE object.
86 FunctionPass
*llvm::createAlphaCodeEmitterPass(AlphaTargetMachine
&TM
,
87 MachineCodeEmitter
&MCE
) {
88 return new Emitter
<MachineCodeEmitter
>(TM
, MCE
);
91 FunctionPass
*llvm::createAlphaJITCodeEmitterPass(AlphaTargetMachine
&TM
,
92 JITCodeEmitter
&JCE
) {
93 return new Emitter
<JITCodeEmitter
>(TM
, JCE
);
95 FunctionPass
*llvm::createAlphaObjectCodeEmitterPass(AlphaTargetMachine
&TM
,
96 ObjectCodeEmitter
&OCE
) {
97 return new Emitter
<ObjectCodeEmitter
>(TM
, OCE
);
100 template <class CodeEmitter
>
101 bool Emitter
<CodeEmitter
>::runOnMachineFunction(MachineFunction
&MF
) {
102 II
= ((AlphaTargetMachine
&)MF
.getTarget()).getInstrInfo();
105 MCE
.startFunction(MF
);
106 for (MachineFunction::iterator I
= MF
.begin(), E
= MF
.end(); I
!= E
; ++I
)
108 } while (MCE
.finishFunction(MF
));
113 template <class CodeEmitter
>
114 void Emitter
<CodeEmitter
>::emitBasicBlock(MachineBasicBlock
&MBB
) {
115 MCE
.StartMachineBasicBlock(&MBB
);
116 for (MachineBasicBlock::iterator I
= MBB
.begin(), E
= MBB
.end();
118 const MachineInstr
&MI
= *I
;
119 MCE
.processDebugLoc(MI
.getDebugLoc());
120 switch(MI
.getOpcode()) {
122 MCE
.emitWordLE(getBinaryCodeForInstr(*I
));
126 case Alpha::MEMLABEL
:
127 case TargetInstrInfo::IMPLICIT_DEF
:
133 static unsigned getAlphaRegNumber(unsigned Reg
) {
135 case Alpha::R0
: case Alpha::F0
: return 0;
136 case Alpha::R1
: case Alpha::F1
: return 1;
137 case Alpha::R2
: case Alpha::F2
: return 2;
138 case Alpha::R3
: case Alpha::F3
: return 3;
139 case Alpha::R4
: case Alpha::F4
: return 4;
140 case Alpha::R5
: case Alpha::F5
: return 5;
141 case Alpha::R6
: case Alpha::F6
: return 6;
142 case Alpha::R7
: case Alpha::F7
: return 7;
143 case Alpha::R8
: case Alpha::F8
: return 8;
144 case Alpha::R9
: case Alpha::F9
: return 9;
145 case Alpha::R10
: case Alpha::F10
: return 10;
146 case Alpha::R11
: case Alpha::F11
: return 11;
147 case Alpha::R12
: case Alpha::F12
: return 12;
148 case Alpha::R13
: case Alpha::F13
: return 13;
149 case Alpha::R14
: case Alpha::F14
: return 14;
150 case Alpha::R15
: case Alpha::F15
: return 15;
151 case Alpha::R16
: case Alpha::F16
: return 16;
152 case Alpha::R17
: case Alpha::F17
: return 17;
153 case Alpha::R18
: case Alpha::F18
: return 18;
154 case Alpha::R19
: case Alpha::F19
: return 19;
155 case Alpha::R20
: case Alpha::F20
: return 20;
156 case Alpha::R21
: case Alpha::F21
: return 21;
157 case Alpha::R22
: case Alpha::F22
: return 22;
158 case Alpha::R23
: case Alpha::F23
: return 23;
159 case Alpha::R24
: case Alpha::F24
: return 24;
160 case Alpha::R25
: case Alpha::F25
: return 25;
161 case Alpha::R26
: case Alpha::F26
: return 26;
162 case Alpha::R27
: case Alpha::F27
: return 27;
163 case Alpha::R28
: case Alpha::F28
: return 28;
164 case Alpha::R29
: case Alpha::F29
: return 29;
165 case Alpha::R30
: case Alpha::F30
: return 30;
166 case Alpha::R31
: case Alpha::F31
: return 31;
168 llvm_unreachable("Unhandled reg");
172 unsigned AlphaCodeEmitter::getMachineOpValue(const MachineInstr
&MI
,
173 const MachineOperand
&MO
) {
175 unsigned rv
= 0; // Return value; defaults to 0 for unhandled cases
176 // or things that get fixed up later by the JIT.
179 rv
= getAlphaRegNumber(MO
.getReg());
180 } else if (MO
.isImm()) {
182 } else if (MO
.isGlobal() || MO
.isSymbol() || MO
.isCPI()) {
183 DOUT
<< MO
<< " is a relocated op for " << MI
<< "\n";
187 switch (MI
.getOpcode()) {
189 Reloc
= Alpha::reloc_bsr
;
204 Reloc
= Alpha::reloc_gprellow
;
207 Reloc
= Alpha::reloc_gprelhigh
;
210 Reloc
= Alpha::reloc_literal
;
215 Reloc
= Alpha::reloc_gpdist
;
216 Offset
= MI
.getOperand(3).getImm();
219 llvm_unreachable("unknown relocatable instruction");
222 MCE
.addRelocation(MachineRelocation::getGV(MCE
.getCurrentPCOffset(),
223 Reloc
, MO
.getGlobal(), Offset
,
224 isa
<Function
>(MO
.getGlobal()),
226 else if (MO
.isSymbol())
227 MCE
.addRelocation(MachineRelocation::getExtSym(MCE
.getCurrentPCOffset(),
228 Reloc
, MO
.getSymbolName(),
231 MCE
.addRelocation(MachineRelocation::getConstPool(MCE
.getCurrentPCOffset(),
232 Reloc
, MO
.getIndex(), Offset
));
233 } else if (MO
.isMBB()) {
234 MCE
.addRelocation(MachineRelocation::getBB(MCE
.getCurrentPCOffset(),
235 Alpha::reloc_bsr
, MO
.getMBB()));
238 cerr
<< "ERROR: Unknown type of MachineOperand: " << MO
<< "\n";
246 #include "AlphaGenCodeEmitter.inc"