bbadcb07918d355bd8270d1ffa42ebf95b4e10de
[oota-llvm.git] / lib / Target / PowerPC / PPCMCCodeEmitter.cpp
1 //===-- PPCMCCodeEmitter.cpp - Convert PPC code to machine code -----------===//
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 implements the PPCMCCodeEmitter class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #define DEBUG_TYPE "mccodeemitter"
15 #include "PPC.h"
16 #include "PPCRegisterInfo.h"
17 #include "llvm/MC/MCCodeEmitter.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/ADT/Statistic.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include "llvm/Support/ErrorHandling.h"
22 using namespace llvm;
23
24 STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
25
26 namespace {
27 class PPCMCCodeEmitter : public MCCodeEmitter {
28   PPCMCCodeEmitter(const PPCMCCodeEmitter &); // DO NOT IMPLEMENT
29   void operator=(const PPCMCCodeEmitter &);   // DO NOT IMPLEMENT
30   const TargetMachine &TM;
31   MCContext &Ctx;
32   
33 public:
34   PPCMCCodeEmitter(TargetMachine &tm, MCContext &ctx)
35     : TM(tm), Ctx(ctx) {
36   }
37   
38   ~PPCMCCodeEmitter() {}
39   
40   unsigned getNumFixupKinds() const { return 0 /*PPC::NumTargetFixupKinds*/; }
41   
42   const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
43     const static MCFixupKindInfo Infos[] = {
44       // name                     offset  bits  flags
45       { "fixup_arm_pcrel_12",     2,      12,   MCFixupKindInfo::FKF_IsPCRel }
46 #if 0
47       { "fixup_arm_vfp_pcrel_12", 3,      8,    MCFixupKindInfo::FKF_IsPCRel },
48       { "fixup_arm_branch",       1,      24,   MCFixupKindInfo::FKF_IsPCRel },
49 #endif
50     };
51     
52     if (Kind < FirstTargetFixupKind)
53       return MCCodeEmitter::getFixupKindInfo(Kind);
54     
55     assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
56            "Invalid kind!");
57     return Infos[Kind - FirstTargetFixupKind];
58   }
59
60   unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
61                                SmallVectorImpl<MCFixup> &Fixups) const;
62
63   /// getMachineOpValue - Return binary encoding of operand. If the machine
64   /// operand requires relocation, record the relocation and return zero.
65   unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
66                              SmallVectorImpl<MCFixup> &Fixups) const;
67   
68   // getBinaryCodeForInstr - TableGen'erated function for getting the
69   // binary encoding for an instruction.
70   unsigned getBinaryCodeForInstr(const MCInst &MI,
71                                  SmallVectorImpl<MCFixup> &Fixups) const;
72   void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
73                          SmallVectorImpl<MCFixup> &Fixups) const {
74     unsigned Bits = getBinaryCodeForInstr(MI, Fixups);
75     
76     // Output the constant in big endian byte order.
77     for (unsigned i = 0; i != 4; ++i) {
78       OS << (char)(Bits >> 24);
79       Bits <<= 8;
80     }
81     
82     ++MCNumEmitted;  // Keep track of the # of mi's emitted.
83   }
84   
85 };
86   
87 } // end anonymous namespace
88   
89 MCCodeEmitter *llvm::createPPCMCCodeEmitter(const Target &, TargetMachine &TM,
90                                             MCContext &Ctx) {
91   return new PPCMCCodeEmitter(TM, Ctx);
92 }
93
94 unsigned PPCMCCodeEmitter::
95 get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
96                     SmallVectorImpl<MCFixup> &Fixups) const {
97   const MCOperand &MO = MI.getOperand(OpNo);
98   assert((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MFOCRF) &&
99          (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7));
100   return 0x80 >> PPCRegisterInfo::getRegisterNumbering(MO.getReg());
101 }
102
103
104 unsigned PPCMCCodeEmitter::
105 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
106                   SmallVectorImpl<MCFixup> &Fixups) const {
107   if (MO.isReg()) {
108     assert(MI.getOpcode() != PPC::MTCRF && MI.getOpcode() != PPC::MFOCRF);
109     return PPCRegisterInfo::getRegisterNumbering(MO.getReg());
110   }
111   
112   if (MO.isImm())
113     return MO.getImm();
114   
115   // FIXME.
116   return 0;
117 }
118
119
120 #include "PPCGenMCCodeEmitter.inc"