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