~ubuntu-branches/ubuntu/feisty/clamav/feisty

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2007-02-20 10:33:44 UTC
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: james.westby@ubuntu.com-20070220103344-zgcu2psnx9d98fpa
Tags: upstream-0.90
ImportĀ upstreamĀ versionĀ 0.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//===-- PPCCodeEmitter.cpp - JIT Code Emitter for PowerPC32 -------*- C++ -*-=//
2
 
//
3
 
//                     The LLVM Compiler Infrastructure
4
 
//
5
 
// This file is distributed under the University of Illinois Open Source
6
 
// License. See LICENSE.TXT for details.
7
 
//
8
 
//===----------------------------------------------------------------------===//
9
 
//
10
 
// This file defines the PowerPC 32-bit CodeEmitter and associated machinery to
11
 
// JIT-compile bitcode to native PowerPC.
12
 
//
13
 
//===----------------------------------------------------------------------===//
14
 
 
15
 
#include "PPCTargetMachine.h"
16
 
#include "PPCRelocations.h"
17
 
#include "PPC.h"
18
 
#include "llvm/Module.h"
19
 
#include "llvm/PassManager.h"
20
 
#include "llvm/CodeGen/JITCodeEmitter.h"
21
 
#include "llvm/CodeGen/MachineFunctionPass.h"
22
 
#include "llvm/CodeGen/MachineInstrBuilder.h"
23
 
#include "llvm/CodeGen/MachineModuleInfo.h"
24
 
#include "llvm/Support/ErrorHandling.h"
25
 
#include "llvm/Support/raw_ostream.h"
26
 
#include "llvm/Target/TargetOptions.h"
27
 
using namespace llvm;
28
 
 
29
 
namespace {
30
 
  class PPCCodeEmitter : public MachineFunctionPass {
31
 
    TargetMachine &TM;
32
 
    JITCodeEmitter &MCE;
33
 
    MachineModuleInfo *MMI;
34
 
    
35
 
    void getAnalysisUsage(AnalysisUsage &AU) const {
36
 
      AU.addRequired<MachineModuleInfo>();
37
 
      MachineFunctionPass::getAnalysisUsage(AU);
38
 
    }
39
 
    
40
 
    static char ID;
41
 
    
42
 
    /// MovePCtoLROffset - When/if we see a MovePCtoLR instruction, we record
43
 
    /// its address in the function into this pointer.
44
 
    void *MovePCtoLROffset;
45
 
  public:
46
 
    
47
 
    PPCCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce)
48
 
      : MachineFunctionPass(ID), TM(tm), MCE(mce) {}
49
 
 
50
 
    /// getBinaryCodeForInstr - This function, generated by the
51
 
    /// CodeEmitterGenerator using TableGen, produces the binary encoding for
52
 
    /// machine instructions.
53
 
 
54
 
    unsigned getBinaryCodeForInstr(const MachineInstr &MI);
55
 
 
56
 
    /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
57
 
 
58
 
    unsigned getMachineOpValue(const MachineInstr &MI,
59
 
                               const MachineOperand &MO);
60
 
 
61
 
    const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
62
 
 
63
 
    /// runOnMachineFunction - emits the given MachineFunction to memory
64
 
    ///
65
 
    bool runOnMachineFunction(MachineFunction &MF);
66
 
 
67
 
    /// emitBasicBlock - emits the given MachineBasicBlock to memory
68
 
    ///
69
 
    void emitBasicBlock(MachineBasicBlock &MBB);
70
 
 
71
 
    /// getValueBit - return the particular bit of Val
72
 
    ///
73
 
    unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; }
74
 
  };
75
 
}
76
 
 
77
 
char PPCCodeEmitter::ID = 0;
78
 
 
79
 
/// createPPCCodeEmitterPass - Return a pass that emits the collected PPC code
80
 
/// to the specified MCE object.
81
 
FunctionPass *llvm::createPPCJITCodeEmitterPass(PPCTargetMachine &TM,
82
 
                                                JITCodeEmitter &JCE) {
83
 
  return new PPCCodeEmitter(TM, JCE);
84
 
}
85
 
 
86
 
bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
87
 
  assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
88
 
          MF.getTarget().getRelocationModel() != Reloc::Static) &&
89
 
         "JIT relocation model must be set to static or default!");
90
 
 
91
 
  MMI = &getAnalysis<MachineModuleInfo>();
92
 
  MCE.setModuleInfo(MMI);
93
 
  do {
94
 
    MovePCtoLROffset = 0;
95
 
    MCE.startFunction(MF);
96
 
    for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
97
 
      emitBasicBlock(*BB);
98
 
  } while (MCE.finishFunction(MF));
99
 
 
100
 
  return false;
101
 
}
102
 
 
103
 
void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
104
 
  MCE.StartMachineBasicBlock(&MBB);
105
 
 
106
 
  for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){
107
 
    const MachineInstr &MI = *I;
108
 
    MCE.processDebugLoc(MI.getDebugLoc(), true);
109
 
    switch (MI.getOpcode()) {
110
 
    default:
111
 
      MCE.emitWordBE(getBinaryCodeForInstr(MI));
112
 
      break;
113
 
    case TargetOpcode::PROLOG_LABEL:
114
 
    case TargetOpcode::EH_LABEL:
115
 
      MCE.emitLabel(MI.getOperand(0).getMCSymbol());
116
 
      break;
117
 
    case TargetOpcode::IMPLICIT_DEF:
118
 
    case TargetOpcode::KILL:
119
 
      break; // pseudo opcode, no side effects
120
 
    case PPC::MovePCtoLR:
121
 
    case PPC::MovePCtoLR8:
122
 
      assert(TM.getRelocationModel() == Reloc::PIC_);
123
 
      MovePCtoLROffset = (void*)MCE.getCurrentPCValue();
124
 
      MCE.emitWordBE(0x48000005);   // bl 1
125
 
      break;
126
 
    }
127
 
    MCE.processDebugLoc(MI.getDebugLoc(), false);
128
 
  }
129
 
}
130
 
 
131
 
unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI,
132
 
                                           const MachineOperand &MO) {
133
 
 
134
 
  unsigned rv = 0; // Return value; defaults to 0 for unhandled cases
135
 
                   // or things that get fixed up later by the JIT.
136
 
  if (MO.isReg()) {
137
 
    rv = PPCRegisterInfo::getRegisterNumbering(MO.getReg());
138
 
 
139
 
    // Special encoding for MTCRF and MFOCRF, which uses a bit mask for the
140
 
    // register, not the register number directly.
141
 
    if ((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MFOCRF) &&
142
 
        (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)) {
143
 
      rv = 0x80 >> rv;
144
 
    }
145
 
  } else if (MO.isImm()) {
146
 
    rv = MO.getImm();
147
 
  } else if (MO.isGlobal() || MO.isSymbol() ||
148
 
             MO.isCPI() || MO.isJTI()) {
149
 
    unsigned Reloc = 0;
150
 
    if (MI.getOpcode() == PPC::BL_Darwin || MI.getOpcode() == PPC::BL8_Darwin ||
151
 
        MI.getOpcode() == PPC::BL_SVR4 || MI.getOpcode() == PPC::BL8_ELF ||
152
 
        MI.getOpcode() == PPC::TAILB || MI.getOpcode() == PPC::TAILB8)
153
 
      Reloc = PPC::reloc_pcrel_bx;
154
 
    else {
155
 
      if (TM.getRelocationModel() == Reloc::PIC_) {
156
 
        assert(MovePCtoLROffset && "MovePCtoLR not seen yet?");
157
 
      }
158
 
      switch (MI.getOpcode()) {
159
 
      default: MI.dump(); llvm_unreachable("Unknown instruction for relocation!");
160
 
      case PPC::LIS:
161
 
      case PPC::LIS8:
162
 
      case PPC::ADDIS:
163
 
      case PPC::ADDIS8:
164
 
        Reloc = PPC::reloc_absolute_high;       // Pointer to symbol
165
 
        break;
166
 
      case PPC::LI:
167
 
      case PPC::LI8:
168
 
      case PPC::LA:
169
 
      // Loads.
170
 
      case PPC::LBZ:
171
 
      case PPC::LBZ8:
172
 
      case PPC::LHA:
173
 
      case PPC::LHA8:
174
 
      case PPC::LHZ:
175
 
      case PPC::LHZ8:
176
 
      case PPC::LWZ:
177
 
      case PPC::LWZ8:
178
 
      case PPC::LFS:
179
 
      case PPC::LFD:
180
 
 
181
 
      // Stores.
182
 
      case PPC::STB:
183
 
      case PPC::STB8:
184
 
      case PPC::STH:
185
 
      case PPC::STH8:
186
 
      case PPC::STW:
187
 
      case PPC::STW8:
188
 
      case PPC::STFS:
189
 
      case PPC::STFD:
190
 
        Reloc = PPC::reloc_absolute_low;
191
 
        break;
192
 
 
193
 
      case PPC::LWA:
194
 
      case PPC::LD:
195
 
      case PPC::STD:
196
 
      case PPC::STD_32:
197
 
        Reloc = PPC::reloc_absolute_low_ix;
198
 
        break;
199
 
      }
200
 
    }
201
 
 
202
 
    MachineRelocation R;
203
 
    if (MO.isGlobal()) {
204
 
      R = MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
205
 
                                   const_cast<GlobalValue *>(MO.getGlobal()), 0,
206
 
                                   isa<Function>(MO.getGlobal()));
207
 
    } else if (MO.isSymbol()) {
208
 
      R = MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
209
 
                                       Reloc, MO.getSymbolName(), 0);
210
 
    } else if (MO.isCPI()) {
211
 
      R = MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
212
 
                                          Reloc, MO.getIndex(), 0);
213
 
    } else {
214
 
      assert(MO.isJTI());
215
 
      R = MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
216
 
                                          Reloc, MO.getIndex(), 0);
217
 
    }
218
 
 
219
 
    // If in PIC mode, we need to encode the negated address of the
220
 
    // 'movepctolr' into the unrelocated field.  After relocation, we'll have
221
 
    // &gv-&movepctolr-4 in the imm field.  Once &movepctolr is added to the imm
222
 
    // field, we get &gv.  This doesn't happen for branch relocations, which are
223
 
    // always implicitly pc relative.
224
 
    if (TM.getRelocationModel() == Reloc::PIC_ && Reloc != PPC::reloc_pcrel_bx){
225
 
      assert(MovePCtoLROffset && "MovePCtoLR not seen yet?");
226
 
      R.setConstantVal(-(intptr_t)MovePCtoLROffset - 4);
227
 
    }
228
 
    MCE.addRelocation(R);
229
 
 
230
 
  } else if (MO.isMBB()) {
231
 
    unsigned Reloc = 0;
232
 
    unsigned Opcode = MI.getOpcode();
233
 
    if (Opcode == PPC::B || Opcode == PPC::BL_Darwin ||
234
 
        Opcode == PPC::BLA_Darwin|| Opcode == PPC::BL_SVR4 ||
235
 
        Opcode == PPC::BLA_SVR4)
236
 
      Reloc = PPC::reloc_pcrel_bx;
237
 
    else // BCC instruction
238
 
      Reloc = PPC::reloc_pcrel_bcx;
239
 
 
240
 
    MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
241
 
                                               Reloc, MO.getMBB()));
242
 
  } else {
243
 
#ifndef NDEBUG
244
 
    errs() << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
245
 
#endif
246
 
    llvm_unreachable(0);
247
 
  }
248
 
 
249
 
  return rv;
250
 
}
251
 
 
252
 
#include "PPCGenCodeEmitter.inc"