aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/SparcV9/SparcV9CodeEmitter.cpp
blob: e34ace67a372f4e14fa71b9481341607d48737e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//===-- 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"