blob: 19ac1f9cf0f24244346a726887ed3401368a2be1 [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 Brukmandcbe7122003-05-31 06:26:06 +000024 PM.add(createMachineCodeDestructionPass()); // Free stuff no longer needed
Misha Brukman3de36f52003-05-27 20:07:58 +000025 return false;
26}
27
28void 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;
Misha Brukmana9f7f6e2003-05-30 20:17:33 +000033 MCE->emitByte(byteVal & 255);
34 }
Misha Brukmana9f7f6e2003-05-30 20:17:33 +000035}
36
37unsigned 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;
Misha Brukman3de36f52003-05-27 20:07:58 +000075 }
76}
77
Misha Brukmana9f7f6e2003-05-30 20:17:33 +000078int64_t SparcV9CodeEmitter::getMachineOpValue(MachineInstr &MI,
79 MachineOperand &MO) {
Brian Gaekec3eaa892003-06-02 02:13:26 +000080 int64_t rv = 0; // Return value; defaults to 0 for unhandled cases
81 // or things that get fixed up later by the JIT.
82
Misha Brukman3de36f52003-05-27 20:07:58 +000083 if (MO.isPhysicalRegister()) {
Misha Brukmana9f7f6e2003-05-30 20:17:33 +000084 // This is necessary because the Sparc doesn't actually lay out registers
85 // in the real fashion -- it skips those that it chooses not to allocate,
86 // i.e. those that are the SP, etc.
87 unsigned fakeReg = MO.getReg(), realReg, regClass, regType;
88 regType = TM->getRegInfo().getRegType(fakeReg);
89 // At least map fakeReg into its class
90 fakeReg = TM->getRegInfo().getClassRegNum(fakeReg, regClass);
91 // Find the real register number for use in an instruction
92 realReg = getRealRegNum(fakeReg, regClass);
93 std::cerr << "Reg[" << fakeReg << "] = " << realReg << "\n";
Brian Gaekec3eaa892003-06-02 02:13:26 +000094 rv = realReg;
Misha Brukman3de36f52003-05-27 20:07:58 +000095 } else if (MO.isImmediate()) {
Brian Gaekec3eaa892003-06-02 02:13:26 +000096 rv = MO.getImmedValue();
Misha Brukman3de36f52003-05-27 20:07:58 +000097 } else if (MO.isPCRelativeDisp()) {
Misha Brukmana9f7f6e2003-05-30 20:17:33 +000098 std::cerr << "Saving reference to BB (PCRelDisp)\n";
99 MCE->saveBBreference((BasicBlock*)MO.getVRegValue(), MI);
Misha Brukmana9f7f6e2003-05-30 20:17:33 +0000100 } else if (MO.isMachineBasicBlock()) {
101 std::cerr << "Saving reference to BB (MBB)\n";
102 MCE->saveBBreference(MO.getMachineBasicBlock()->getBasicBlock(), MI);
Misha Brukmana9f7f6e2003-05-30 20:17:33 +0000103 } else if (MO.isFrameIndex()) {
104 std::cerr << "ERROR: Frame index unhandled.\n";
Misha Brukmana9f7f6e2003-05-30 20:17:33 +0000105 } else if (MO.isConstantPoolIndex()) {
106 std::cerr << "ERROR: Constant Pool index unhandled.\n";
Misha Brukmana9f7f6e2003-05-30 20:17:33 +0000107 } else if (MO.isGlobalAddress()) {
108 std::cerr << "ERROR: Global addr unhandled.\n";
Misha Brukmana9f7f6e2003-05-30 20:17:33 +0000109 } else if (MO.isExternalSymbol()) {
110 std::cerr << "ERROR: External symbol unhandled.\n";
Misha Brukman3de36f52003-05-27 20:07:58 +0000111 } else {
Misha Brukmana9f7f6e2003-05-30 20:17:33 +0000112 std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
Brian Gaekec3eaa892003-06-02 02:13:26 +0000113 }
114
115 // Finally, deal with the various bitfield-extracting functions that
116 // are used in SPARC assembly. (Some of these make no sense in combination
117 // with some of the above; we'll trust that the instruction selector
118 // will not produce nonsense, and not check for valid combinations here.)
119 if (MO.opLoBits32()) { // %lo(val)
120 return rv & 0x03ff;
121 } else if (MO.opHiBits32()) { // %lm(val)
122 return (rv >> 10) & 0x03fffff;
123 } else if (MO.opLoBits64()) { // %hm(val)
124 return (rv >> 32) & 0x03ff;
125 } else if (MO.opHiBits64()) { // %hh(val)
126 return rv >> 42;
127 } else { // (unadorned) val
128 return rv;
Misha Brukman3de36f52003-05-27 20:07:58 +0000129 }
130}
131
132unsigned SparcV9CodeEmitter::getValueBit(int64_t Val, unsigned bit) {
133 Val >>= bit;
134 return (Val & 1);
135}
136
137
138bool SparcV9CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
Misha Brukmana9f7f6e2003-05-30 20:17:33 +0000139 MCE->startFunction(MF);
140 MCE->emitConstantPool(MF.getConstantPool());
Misha Brukman3de36f52003-05-27 20:07:58 +0000141 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
142 emitBasicBlock(*I);
Misha Brukmana9f7f6e2003-05-30 20:17:33 +0000143 MCE->finishFunction(MF);
Misha Brukman3de36f52003-05-27 20:07:58 +0000144 return false;
145}
146
147void SparcV9CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
Misha Brukman0d603452003-05-27 22:41:44 +0000148 currBB = MBB.getBasicBlock();
Misha Brukmana9f7f6e2003-05-30 20:17:33 +0000149 MCE->startBasicBlock(MBB);
Misha Brukman3de36f52003-05-27 20:07:58 +0000150 for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I)
151 emitInstruction(**I);
152}
153
154void SparcV9CodeEmitter::emitInstruction(MachineInstr &MI) {
155 emitConstant(getBinaryCodeForInstr(MI), 4);
156}
157
158#include "SparcV9CodeEmitter.inc"