e34ace67a372f4e14fa71b9481341607d48737e1
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9CodeEmitter.cpp
1 //===-- SparcV9CodeEmitter.cpp -  --------===//
2 //
3 //
4 //===----------------------------------------------------------------------===//
5
6 #include "llvm/PassManager.h"
7 #include "llvm/CodeGen/MachineCodeEmitter.h"
8 #include "llvm/CodeGen/MachineFunctionPass.h"
9 #include "llvm/CodeGen/MachineInstr.h"
10 #include "llvm/Target/TargetMachine.h"
11 #include "SparcInternals.h"
12 #include "SparcV9CodeEmitter.h"
13
14 MachineCodeEmitter * SparcV9CodeEmitter::MCE = 0;
15 TargetMachine * SparcV9CodeEmitter::TM = 0;
16
17 bool UltraSparc::addPassesToEmitMachineCode(PassManager &PM,
18                                             MachineCodeEmitter &MCE) {
19   //PM.add(new SparcV9CodeEmitter(MCE));
20   //MachineCodeEmitter *M = MachineCodeEmitter::createDebugMachineCodeEmitter();
21   MachineCodeEmitter *M = 
22     MachineCodeEmitter::createFilePrinterMachineCodeEmitter(MCE);
23   PM.add(new SparcV9CodeEmitter(this, *M));
24   PM.add(createMachineCodeDestructionPass()); // Free stuff no longer needed
25   return false;
26 }
27
28 void SparcV9CodeEmitter::emitConstant(unsigned Val, unsigned Size) {
29   // Output the constant in big endian byte order...
30   unsigned byteVal;
31   for (int i = Size-1; i >= 0; --i) {
32     byteVal = Val >> 8*i;
33     MCE->emitByte(byteVal & 255);
34   }
35 }
36
37 unsigned getRealRegNum(unsigned fakeReg, unsigned regClass) {
38   switch (regClass) {
39   case UltraSparcRegInfo::IntRegType: {
40     // Sparc manual, p31
41     static const unsigned IntRegMap[] = {
42       // "o0", "o1", "o2", "o3", "o4", "o5",       "o7",
43       8, 9, 10, 11, 12, 13, 15,
44       // "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
45       16, 17, 18, 19, 20, 21, 22, 23,
46       // "i0", "i1", "i2", "i3", "i4", "i5",  
47       24, 25, 26, 27, 28, 29,
48       // "i6", "i7",
49       30, 31,
50       // "g0", "g1", "g2", "g3", "g4", "g5",  "g6", "g7", 
51       0, 1, 2, 3, 4, 5, 6, 7,
52       // "o6"
53       14
54     }; 
55  
56     return IntRegMap[fakeReg];
57     break;
58   }
59   case UltraSparcRegInfo::FPSingleRegType: {
60     return fakeReg;
61   }
62   case UltraSparcRegInfo::FPDoubleRegType: {
63     return fakeReg;
64   }
65   case UltraSparcRegInfo::FloatCCRegType: {
66     return fakeReg;
67
68   }
69   case UltraSparcRegInfo::IntCCRegType: {
70     return fakeReg;
71   }
72   default:
73     assert(0 && "Invalid unified register number in getRegType");
74     return fakeReg;
75   }
76 }
77
78 int64_t SparcV9CodeEmitter::getMachineOpValue(MachineInstr &MI,
79                                               MachineOperand &MO) {
80   if (MO.isPhysicalRegister()) {
81     // This is necessary because the Sparc doesn't actually lay out registers
82     // in the real fashion -- it skips those that it chooses not to allocate,
83     // i.e. those that are the SP, etc.
84     unsigned fakeReg = MO.getReg(), realReg, regClass, regType;
85     regType = TM->getRegInfo().getRegType(fakeReg);
86     // At least map fakeReg into its class
87     fakeReg = TM->getRegInfo().getClassRegNum(fakeReg, regClass);
88     // Find the real register number for use in an instruction
89     realReg = getRealRegNum(fakeReg, regClass);
90     std::cerr << "Reg[" << fakeReg << "] = " << realReg << "\n";
91     return realReg;
92   } else if (MO.isImmediate()) {
93     return MO.getImmedValue();
94   } else if (MO.isPCRelativeDisp()) {
95     std::cerr << "Saving reference to BB (PCRelDisp)\n";
96     MCE->saveBBreference((BasicBlock*)MO.getVRegValue(), MI);
97     return 0;
98   } else if (MO.isMachineBasicBlock()) {
99     std::cerr << "Saving reference to BB (MBB)\n";
100     MCE->saveBBreference(MO.getMachineBasicBlock()->getBasicBlock(), MI);
101     return 0;
102   } else if (MO.isFrameIndex()) {
103     std::cerr << "ERROR: Frame index unhandled.\n";
104     return 0;
105   } else if (MO.isConstantPoolIndex()) {
106     std::cerr << "ERROR: Constant Pool index unhandled.\n";
107     return 0;
108   } else if (MO.isGlobalAddress()) {
109     std::cerr << "ERROR: Global addr unhandled.\n";
110     return 0;
111   } else if (MO.isExternalSymbol()) {
112     std::cerr << "ERROR: External symbol unhandled.\n";
113     return 0;
114   } else {
115     std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
116     //abort();
117     return 0;
118   }
119 }
120
121 unsigned SparcV9CodeEmitter::getValueBit(int64_t Val, unsigned bit) {
122   Val >>= bit;
123   return (Val & 1);
124 }
125
126
127 bool SparcV9CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
128   MCE->startFunction(MF);
129   MCE->emitConstantPool(MF.getConstantPool());
130   for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
131     emitBasicBlock(*I);
132   MCE->finishFunction(MF);
133   return false;
134 }
135
136 void SparcV9CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
137   currBB = MBB.getBasicBlock();
138   MCE->startBasicBlock(MBB);
139   for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I)
140     emitInstruction(**I);
141 }
142
143 void SparcV9CodeEmitter::emitInstruction(MachineInstr &MI) {
144   emitConstant(getBinaryCodeForInstr(MI), 4);
145 }
146
147 #include "SparcV9CodeEmitter.inc"