mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-22 10:33:23 +00:00
dcbe712841
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6462 91177308-0d34-0410-b5e6-96231b3b80d8
148 lines
4.7 KiB
C++
148 lines
4.7 KiB
C++
//===-- SparcV9CodeEmitter.cpp - --------===//
|
|
//
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/PassManager.h"
|
|
#include "llvm/CodeGen/MachineCodeEmitter.h"
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
|
#include "llvm/CodeGen/MachineInstr.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
#include "SparcInternals.h"
|
|
#include "SparcV9CodeEmitter.h"
|
|
|
|
MachineCodeEmitter * SparcV9CodeEmitter::MCE = 0;
|
|
TargetMachine * SparcV9CodeEmitter::TM = 0;
|
|
|
|
bool UltraSparc::addPassesToEmitMachineCode(PassManager &PM,
|
|
MachineCodeEmitter &MCE) {
|
|
//PM.add(new SparcV9CodeEmitter(MCE));
|
|
//MachineCodeEmitter *M = MachineCodeEmitter::createDebugMachineCodeEmitter();
|
|
MachineCodeEmitter *M =
|
|
MachineCodeEmitter::createFilePrinterMachineCodeEmitter(MCE);
|
|
PM.add(new SparcV9CodeEmitter(this, *M));
|
|
PM.add(createMachineCodeDestructionPass()); // Free stuff no longer needed
|
|
return false;
|
|
}
|
|
|
|
void SparcV9CodeEmitter::emitConstant(unsigned Val, unsigned Size) {
|
|
// Output the constant in big endian byte order...
|
|
unsigned byteVal;
|
|
for (int i = Size-1; i >= 0; --i) {
|
|
byteVal = Val >> 8*i;
|
|
MCE->emitByte(byteVal & 255);
|
|
}
|
|
}
|
|
|
|
unsigned getRealRegNum(unsigned fakeReg, unsigned regClass) {
|
|
switch (regClass) {
|
|
case UltraSparcRegInfo::IntRegType: {
|
|
// Sparc manual, p31
|
|
static const unsigned IntRegMap[] = {
|
|
// "o0", "o1", "o2", "o3", "o4", "o5", "o7",
|
|
8, 9, 10, 11, 12, 13, 15,
|
|
// "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
|
|
16, 17, 18, 19, 20, 21, 22, 23,
|
|
// "i0", "i1", "i2", "i3", "i4", "i5",
|
|
24, 25, 26, 27, 28, 29,
|
|
// "i6", "i7",
|
|
30, 31,
|
|
// "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
|
|
0, 1, 2, 3, 4, 5, 6, 7,
|
|
// "o6"
|
|
14
|
|
};
|
|
|
|
return IntRegMap[fakeReg];
|
|
break;
|
|
}
|
|
case UltraSparcRegInfo::FPSingleRegType: {
|
|
return fakeReg;
|
|
}
|
|
case UltraSparcRegInfo::FPDoubleRegType: {
|
|
return fakeReg;
|
|
}
|
|
case UltraSparcRegInfo::FloatCCRegType: {
|
|
return fakeReg;
|
|
|
|
}
|
|
case UltraSparcRegInfo::IntCCRegType: {
|
|
return fakeReg;
|
|
}
|
|
default:
|
|
assert(0 && "Invalid unified register number in getRegType");
|
|
return fakeReg;
|
|
}
|
|
}
|
|
|
|
int64_t SparcV9CodeEmitter::getMachineOpValue(MachineInstr &MI,
|
|
MachineOperand &MO) {
|
|
if (MO.isPhysicalRegister()) {
|
|
// This is necessary because the Sparc doesn't actually lay out registers
|
|
// in the real fashion -- it skips those that it chooses not to allocate,
|
|
// i.e. those that are the SP, etc.
|
|
unsigned fakeReg = MO.getReg(), realReg, regClass, regType;
|
|
regType = TM->getRegInfo().getRegType(fakeReg);
|
|
// At least map fakeReg into its class
|
|
fakeReg = TM->getRegInfo().getClassRegNum(fakeReg, regClass);
|
|
// Find the real register number for use in an instruction
|
|
realReg = getRealRegNum(fakeReg, regClass);
|
|
std::cerr << "Reg[" << fakeReg << "] = " << realReg << "\n";
|
|
return realReg;
|
|
} else if (MO.isImmediate()) {
|
|
return MO.getImmedValue();
|
|
} else if (MO.isPCRelativeDisp()) {
|
|
std::cerr << "Saving reference to BB (PCRelDisp)\n";
|
|
MCE->saveBBreference((BasicBlock*)MO.getVRegValue(), MI);
|
|
return 0;
|
|
} else if (MO.isMachineBasicBlock()) {
|
|
std::cerr << "Saving reference to BB (MBB)\n";
|
|
MCE->saveBBreference(MO.getMachineBasicBlock()->getBasicBlock(), MI);
|
|
return 0;
|
|
} else if (MO.isFrameIndex()) {
|
|
std::cerr << "ERROR: Frame index unhandled.\n";
|
|
return 0;
|
|
} else if (MO.isConstantPoolIndex()) {
|
|
std::cerr << "ERROR: Constant Pool index unhandled.\n";
|
|
return 0;
|
|
} else if (MO.isGlobalAddress()) {
|
|
std::cerr << "ERROR: Global addr unhandled.\n";
|
|
return 0;
|
|
} else if (MO.isExternalSymbol()) {
|
|
std::cerr << "ERROR: External symbol unhandled.\n";
|
|
return 0;
|
|
} else {
|
|
std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
|
|
//abort();
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
unsigned SparcV9CodeEmitter::getValueBit(int64_t Val, unsigned bit) {
|
|
Val >>= bit;
|
|
return (Val & 1);
|
|
}
|
|
|
|
|
|
bool SparcV9CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
|
|
MCE->startFunction(MF);
|
|
MCE->emitConstantPool(MF.getConstantPool());
|
|
for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
|
|
emitBasicBlock(*I);
|
|
MCE->finishFunction(MF);
|
|
return false;
|
|
}
|
|
|
|
void SparcV9CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
|
|
currBB = MBB.getBasicBlock();
|
|
MCE->startBasicBlock(MBB);
|
|
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I)
|
|
emitInstruction(**I);
|
|
}
|
|
|
|
void SparcV9CodeEmitter::emitInstruction(MachineInstr &MI) {
|
|
emitConstant(getBinaryCodeForInstr(MI), 4);
|
|
}
|
|
|
|
#include "SparcV9CodeEmitter.inc"
|