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/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"
29 class AlphaCodeEmitter
: public MachineFunctionPass
{
30 const AlphaInstrInfo
*II
;
32 MachineCodeEmitter
&MCE
;
34 /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
36 unsigned getMachineOpValue(const MachineInstr
&MI
,
37 const MachineOperand
&MO
);
41 explicit AlphaCodeEmitter(TargetMachine
&tm
, MachineCodeEmitter
&mce
)
42 : MachineFunctionPass(&ID
), II(0), TM(tm
), MCE(mce
) {}
43 AlphaCodeEmitter(TargetMachine
&tm
, MachineCodeEmitter
&mce
,
44 const AlphaInstrInfo
& ii
)
45 : MachineFunctionPass(&ID
), II(&ii
), TM(tm
), MCE(mce
) {}
47 bool runOnMachineFunction(MachineFunction
&MF
);
49 virtual const char *getPassName() const {
50 return "Alpha Machine Code Emitter";
53 void emitInstruction(const MachineInstr
&MI
);
55 /// getBinaryCodeForInstr - This function, generated by the
56 /// CodeEmitterGenerator using TableGen, produces the binary encoding for
57 /// machine instructions.
59 unsigned getBinaryCodeForInstr(const MachineInstr
&MI
);
62 void emitBasicBlock(MachineBasicBlock
&MBB
);
65 char AlphaCodeEmitter::ID
= 0;
68 /// createAlphaCodeEmitterPass - Return a pass that emits the collected Alpha code
69 /// to the specified MCE object.
70 FunctionPass
*llvm::createAlphaCodeEmitterPass(AlphaTargetMachine
&TM
,
71 MachineCodeEmitter
&MCE
) {
72 return new AlphaCodeEmitter(TM
, MCE
);
75 bool AlphaCodeEmitter::runOnMachineFunction(MachineFunction
&MF
) {
76 II
= ((AlphaTargetMachine
&)MF
.getTarget()).getInstrInfo();
79 MCE
.startFunction(MF
);
80 for (MachineFunction::iterator I
= MF
.begin(), E
= MF
.end(); I
!= E
; ++I
)
82 } while (MCE
.finishFunction(MF
));
87 void AlphaCodeEmitter::emitBasicBlock(MachineBasicBlock
&MBB
) {
88 MCE
.StartMachineBasicBlock(&MBB
);
89 for (MachineBasicBlock::iterator I
= MBB
.begin(), E
= MBB
.end();
91 const MachineInstr
&MI
= *I
;
92 switch(MI
.getOpcode()) {
94 MCE
.emitWordLE(getBinaryCodeForInstr(*I
));
99 case TargetInstrInfo::IMPLICIT_DEF
:
105 static unsigned getAlphaRegNumber(unsigned Reg
) {
107 case Alpha::R0
: case Alpha::F0
: return 0;
108 case Alpha::R1
: case Alpha::F1
: return 1;
109 case Alpha::R2
: case Alpha::F2
: return 2;
110 case Alpha::R3
: case Alpha::F3
: return 3;
111 case Alpha::R4
: case Alpha::F4
: return 4;
112 case Alpha::R5
: case Alpha::F5
: return 5;
113 case Alpha::R6
: case Alpha::F6
: return 6;
114 case Alpha::R7
: case Alpha::F7
: return 7;
115 case Alpha::R8
: case Alpha::F8
: return 8;
116 case Alpha::R9
: case Alpha::F9
: return 9;
117 case Alpha::R10
: case Alpha::F10
: return 10;
118 case Alpha::R11
: case Alpha::F11
: return 11;
119 case Alpha::R12
: case Alpha::F12
: return 12;
120 case Alpha::R13
: case Alpha::F13
: return 13;
121 case Alpha::R14
: case Alpha::F14
: return 14;
122 case Alpha::R15
: case Alpha::F15
: return 15;
123 case Alpha::R16
: case Alpha::F16
: return 16;
124 case Alpha::R17
: case Alpha::F17
: return 17;
125 case Alpha::R18
: case Alpha::F18
: return 18;
126 case Alpha::R19
: case Alpha::F19
: return 19;
127 case Alpha::R20
: case Alpha::F20
: return 20;
128 case Alpha::R21
: case Alpha::F21
: return 21;
129 case Alpha::R22
: case Alpha::F22
: return 22;
130 case Alpha::R23
: case Alpha::F23
: return 23;
131 case Alpha::R24
: case Alpha::F24
: return 24;
132 case Alpha::R25
: case Alpha::F25
: return 25;
133 case Alpha::R26
: case Alpha::F26
: return 26;
134 case Alpha::R27
: case Alpha::F27
: return 27;
135 case Alpha::R28
: case Alpha::F28
: return 28;
136 case Alpha::R29
: case Alpha::F29
: return 29;
137 case Alpha::R30
: case Alpha::F30
: return 30;
138 case Alpha::R31
: case Alpha::F31
: return 31;
140 assert(0 && "Unhandled reg");
145 unsigned AlphaCodeEmitter::getMachineOpValue(const MachineInstr
&MI
,
146 const MachineOperand
&MO
) {
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 DOUT
<< 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 assert(0 && "unknown relocatable instruction");
196 MCE
.addRelocation(MachineRelocation::getGV(MCE
.getCurrentPCOffset(),
197 Reloc
, MO
.getGlobal(), Offset
,
198 isa
<Function
>(MO
.getGlobal()),
200 else if (MO
.isSymbol())
201 MCE
.addRelocation(MachineRelocation::getExtSym(MCE
.getCurrentPCOffset(),
202 Reloc
, MO
.getSymbolName(),
205 MCE
.addRelocation(MachineRelocation::getConstPool(MCE
.getCurrentPCOffset(),
206 Reloc
, MO
.getIndex(), Offset
));
207 } else if (MO
.isMBB()) {
208 MCE
.addRelocation(MachineRelocation::getBB(MCE
.getCurrentPCOffset(),
209 Alpha::reloc_bsr
, MO
.getMBB()));
211 cerr
<< "ERROR: Unknown type of MachineOperand: " << MO
<< "\n";
219 #include "AlphaGenCodeEmitter.inc"