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/JITCodeEmitter.h"
21 #include "llvm/CodeGen/MachineFunctionPass.h"
22 #include "llvm/CodeGen/MachineInstr.h"
23 #include "llvm/CodeGen/Passes.h"
24 #include "llvm/Function.h"
25 #include "llvm/Support/Debug.h"
26 #include "llvm/Support/ErrorHandling.h"
27 #include "llvm/Support/raw_ostream.h"
31 class AlphaCodeEmitter
: public MachineFunctionPass
{
33 const AlphaInstrInfo
*II
;
37 AlphaCodeEmitter(JITCodeEmitter
&mce
) : MachineFunctionPass(ID
),
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
) const;
46 /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
48 unsigned getMachineOpValue(const MachineInstr
&MI
,
49 const MachineOperand
&MO
) const;
51 bool runOnMachineFunction(MachineFunction
&MF
);
53 virtual const char *getPassName() const {
54 return "Alpha Machine Code Emitter";
58 void emitBasicBlock(MachineBasicBlock
&MBB
);
62 char AlphaCodeEmitter::ID
= 0;
65 /// createAlphaCodeEmitterPass - Return a pass that emits the collected Alpha
66 /// code to the specified MCE object.
68 FunctionPass
*llvm::createAlphaJITCodeEmitterPass(AlphaTargetMachine
&TM
,
69 JITCodeEmitter
&JCE
) {
70 return new AlphaCodeEmitter(JCE
);
73 bool AlphaCodeEmitter::runOnMachineFunction(MachineFunction
&MF
) {
74 II
= ((AlphaTargetMachine
&)MF
.getTarget()).getInstrInfo();
77 MCE
.startFunction(MF
);
78 for (MachineFunction::iterator I
= MF
.begin(), E
= MF
.end(); I
!= E
; ++I
)
80 } while (MCE
.finishFunction(MF
));
85 void AlphaCodeEmitter::emitBasicBlock(MachineBasicBlock
&MBB
) {
86 MCE
.StartMachineBasicBlock(&MBB
);
87 for (MachineBasicBlock::iterator I
= MBB
.begin(), E
= MBB
.end();
89 const MachineInstr
&MI
= *I
;
90 MCE
.processDebugLoc(MI
.getDebugLoc(), true);
91 switch(MI
.getOpcode()) {
93 MCE
.emitWordLE(getBinaryCodeForInstr(*I
));
98 case TargetOpcode::IMPLICIT_DEF
:
99 case TargetOpcode::KILL
:
102 MCE
.processDebugLoc(MI
.getDebugLoc(), false);
106 static unsigned getAlphaRegNumber(unsigned Reg
) {
108 case Alpha::R0
: case Alpha::F0
: return 0;
109 case Alpha::R1
: case Alpha::F1
: return 1;
110 case Alpha::R2
: case Alpha::F2
: return 2;
111 case Alpha::R3
: case Alpha::F3
: return 3;
112 case Alpha::R4
: case Alpha::F4
: return 4;
113 case Alpha::R5
: case Alpha::F5
: return 5;
114 case Alpha::R6
: case Alpha::F6
: return 6;
115 case Alpha::R7
: case Alpha::F7
: return 7;
116 case Alpha::R8
: case Alpha::F8
: return 8;
117 case Alpha::R9
: case Alpha::F9
: return 9;
118 case Alpha::R10
: case Alpha::F10
: return 10;
119 case Alpha::R11
: case Alpha::F11
: return 11;
120 case Alpha::R12
: case Alpha::F12
: return 12;
121 case Alpha::R13
: case Alpha::F13
: return 13;
122 case Alpha::R14
: case Alpha::F14
: return 14;
123 case Alpha::R15
: case Alpha::F15
: return 15;
124 case Alpha::R16
: case Alpha::F16
: return 16;
125 case Alpha::R17
: case Alpha::F17
: return 17;
126 case Alpha::R18
: case Alpha::F18
: return 18;
127 case Alpha::R19
: case Alpha::F19
: return 19;
128 case Alpha::R20
: case Alpha::F20
: return 20;
129 case Alpha::R21
: case Alpha::F21
: return 21;
130 case Alpha::R22
: case Alpha::F22
: return 22;
131 case Alpha::R23
: case Alpha::F23
: return 23;
132 case Alpha::R24
: case Alpha::F24
: return 24;
133 case Alpha::R25
: case Alpha::F25
: return 25;
134 case Alpha::R26
: case Alpha::F26
: return 26;
135 case Alpha::R27
: case Alpha::F27
: return 27;
136 case Alpha::R28
: case Alpha::F28
: return 28;
137 case Alpha::R29
: case Alpha::F29
: return 29;
138 case Alpha::R30
: case Alpha::F30
: return 30;
139 case Alpha::R31
: case Alpha::F31
: return 31;
141 llvm_unreachable("Unhandled reg");
145 unsigned AlphaCodeEmitter::getMachineOpValue(const MachineInstr
&MI
,
146 const MachineOperand
&MO
) const {
148 unsigned rv
= 0; // Return value; defaults to 0 for unhandled cases
149 // or things that get fixed up later by the JIT.
152 rv
= getAlphaRegNumber(MO
.getReg());
153 } else if (MO
.isImm()) {
155 } else if (MO
.isGlobal() || MO
.isSymbol() || MO
.isCPI()) {
156 DEBUG(errs() << MO
<< " is a relocated op for " << MI
<< "\n");
160 switch (MI
.getOpcode()) {
162 Reloc
= Alpha::reloc_bsr
;
177 Reloc
= Alpha::reloc_gprellow
;
180 Reloc
= Alpha::reloc_gprelhigh
;
183 Reloc
= Alpha::reloc_literal
;
188 Reloc
= Alpha::reloc_gpdist
;
189 Offset
= MI
.getOperand(3).getImm();
192 llvm_unreachable("unknown relocatable instruction");
195 MCE
.addRelocation(MachineRelocation::getGV(
196 MCE
.getCurrentPCOffset(),
198 const_cast<GlobalValue
*>(MO
.getGlobal()),
200 isa
<Function
>(MO
.getGlobal()),
202 else if (MO
.isSymbol())
203 MCE
.addRelocation(MachineRelocation::getExtSym(MCE
.getCurrentPCOffset(),
204 Reloc
, MO
.getSymbolName(),
207 MCE
.addRelocation(MachineRelocation::getConstPool(MCE
.getCurrentPCOffset(),
208 Reloc
, MO
.getIndex(), Offset
));
209 } else if (MO
.isMBB()) {
210 MCE
.addRelocation(MachineRelocation::getBB(MCE
.getCurrentPCOffset(),
211 Alpha::reloc_bsr
, MO
.getMBB()));
214 errs() << "ERROR: Unknown type of MachineOperand: " << MO
<< "\n";
222 #include "AlphaGenCodeEmitter.inc"