aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/PowerPC/PPCCodeEmitter.cpp
blob: e33c8c133e3715356c1097b5939631d854c979c7 (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
//===-- PPC32CodeEmitter.cpp - JIT Code Emitter for PowerPC32 -----*- C++ -*-=//
// 
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
// 
//===----------------------------------------------------------------------===//
// 
// This file defines the PowerPC 32-bit CodeEmitter and associated machinery to
// JIT-compile bytecode to native PowerPC.
//
//===----------------------------------------------------------------------===//

#include "PPC32JITInfo.h"
#include "PPC32TargetMachine.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/Debug.h"

namespace llvm {

namespace {
  class PPC32CodeEmitter : public MachineFunctionPass {
    TargetMachine &TM;
    MachineCodeEmitter &MCE;

    int64_t getMachineOpValue(MachineInstr &MI, MachineOperand &MO);

  public:
    PPC32CodeEmitter(TargetMachine &T, MachineCodeEmitter &M) 
      : TM(T), MCE(M) {}

    const char *getPassName() const { return "PowerPC Machine Code Emitter"; }

    /// runOnMachineFunction - emits the given MachineFunction to memory
    ///
    bool runOnMachineFunction(MachineFunction &MF);

    /// emitBasicBlock - emits the given MachineBasicBlock to memory
    ///
    void emitBasicBlock(MachineBasicBlock &MBB);

    /// emitWord - write a 32-bit word to memory at the current PC
    ///
    void emitWord(unsigned w) { MCE.emitWord(w); }
    
    /// getValueBit - return the particular bit of Val
    ///
    unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; }

    /// getBinaryCodeForInstr - returns the assembled code for an instruction
    ///
    unsigned getBinaryCodeForInstr(MachineInstr &MI);
  };
}

/// addPassesToEmitMachineCode - Add passes to the specified pass manager to get
/// machine code emitted.  This uses a MachineCodeEmitter object to handle
/// actually outputting the machine code and resolving things like the address
/// of functions.  This method should returns true if machine code emission is
/// not supported.
///
bool PPC32TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
                                                    MachineCodeEmitter &MCE) {
  // Machine code emitter pass for PowerPC
  PM.add(new PPC32CodeEmitter(*this, MCE)); 
  // Delete machine code for this function after emitting it
  PM.add(createMachineCodeDeleter());
  return false;
}

bool PPC32CodeEmitter::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 PPC32CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
  for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I)
    emitWord(getBinaryCodeForInstr(*I));
}

int64_t PPC32CodeEmitter::getMachineOpValue(MachineInstr &MI, 
                                            MachineOperand &MO) {
  int64_t rv = 0; // Return value; defaults to 0 for unhandled cases
                  // or things that get fixed up later by the JIT.
  if (MO.isPCRelativeDisp()) {
    std::cerr << "PPC32CodeEmitter: PC-relative disp unhandled\n";
    abort();
  } else if (MO.isRegister()) {
    rv = MO.getReg();
  } else if (MO.isImmediate()) {
    rv = MO.getImmedValue();
#if 0
  } else if (MO.isGlobalAddress()) {
  } else if (MO.isMachineBasicBlock()) {
    MachineBasicBlock *MBB = MO.getMachineBasicBlock();
  } else if (MO.isExternalSymbol()) {
  } else if (MO.isFrameIndex()) {
    unsigned index = MO.getFrameIndex();
  } else if (MO.isConstantPoolIndex()) {
    unsigned index = MO.getCosntantPoolIndex();
#endif
  } else {
    std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
    abort();
  }

  return rv;
}


void *PPC32JITInfo::getJITStubForFunction(Function *F,
                                          MachineCodeEmitter &MCE) {
  std::cerr << "PPC32JITInfo::getJITStubForFunction not implemented\n";
  abort();
  return 0;
}

void PPC32JITInfo::replaceMachineCodeForFunction (void *Old, void *New) {
  std::cerr << "PPC32JITInfo::replaceMachineCodeForFunction not implemented\n";
  abort();
}

#include "PPC32GenCodeEmitter.inc"

} // end llvm namespace