1 //===-- SparcV9CodeEmitter.cpp - --------===//
4 //===----------------------------------------------------------------------===//
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"
14 MachineCodeEmitter * SparcV9CodeEmitter::MCE = 0;
15 TargetMachine * SparcV9CodeEmitter::TM = 0;
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
28 void SparcV9CodeEmitter::emitConstant(unsigned Val, unsigned Size) {
29 // Output the constant in big endian byte order...
31 for (int i = Size-1; i >= 0; --i) {
33 MCE->emitByte(byteVal & 255);
37 unsigned getRealRegNum(unsigned fakeReg, unsigned regClass) {
39 case UltraSparcRegInfo::IntRegType: {
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,
50 // "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
51 0, 1, 2, 3, 4, 5, 6, 7,
56 return IntRegMap[fakeReg];
59 case UltraSparcRegInfo::FPSingleRegType: {
62 case UltraSparcRegInfo::FPDoubleRegType: {
65 case UltraSparcRegInfo::FloatCCRegType: {
69 case UltraSparcRegInfo::IntCCRegType: {
73 assert(0 && "Invalid unified register number in getRegType");
78 int64_t SparcV9CodeEmitter::getMachineOpValue(MachineInstr &MI,
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";
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);
98 } else if (MO.isMachineBasicBlock()) {
99 std::cerr << "Saving reference to BB (MBB)\n";
100 MCE->saveBBreference(MO.getMachineBasicBlock()->getBasicBlock(), MI);
102 } else if (MO.isFrameIndex()) {
103 std::cerr << "ERROR: Frame index unhandled.\n";
105 } else if (MO.isConstantPoolIndex()) {
106 std::cerr << "ERROR: Constant Pool index unhandled.\n";
108 } else if (MO.isGlobalAddress()) {
109 std::cerr << "ERROR: Global addr unhandled.\n";
111 } else if (MO.isExternalSymbol()) {
112 std::cerr << "ERROR: External symbol unhandled.\n";
115 std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
121 unsigned SparcV9CodeEmitter::getValueBit(int64_t Val, unsigned bit) {
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)
132 MCE->finishFunction(MF);
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);
143 void SparcV9CodeEmitter::emitInstruction(MachineInstr &MI) {
144 emitConstant(getBinaryCodeForInstr(MI), 4);
147 #include "SparcV9CodeEmitter.inc"