Re-sort all of the includes with ./utils/sort_includes.py so that
[oota-llvm.git] / lib / Target / Sparc / MCTargetDesc / SparcMCCodeEmitter.cpp
1 //===-- SparcMCCodeEmitter.cpp - Convert Sparc 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 SparcMCCodeEmitter class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #define DEBUG_TYPE "mccodeemitter"
15 #include "SparcMCExpr.h"
16 #include "MCTargetDesc/SparcFixupKinds.h"
17 #include "SparcMCTargetDesc.h"
18 #include "llvm/ADT/Statistic.h"
19 #include "llvm/MC/MCCodeEmitter.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCRegisterInfo.h"
24 #include "llvm/Support/raw_ostream.h"
25
26 using namespace llvm;
27
28 STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
29
30 namespace {
31 class SparcMCCodeEmitter : public MCCodeEmitter {
32   SparcMCCodeEmitter(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION;
33   void operator=(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION;
34   MCContext &Ctx;
35
36 public:
37   SparcMCCodeEmitter(MCContext &ctx): Ctx(ctx) {}
38
39   ~SparcMCCodeEmitter() {}
40
41   void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
42                          SmallVectorImpl<MCFixup> &Fixups) const;
43
44   // getBinaryCodeForInstr - TableGen'erated function for getting the
45   // binary encoding for an instruction.
46   uint64_t getBinaryCodeForInstr(const MCInst &MI,
47                                  SmallVectorImpl<MCFixup> &Fixups) const;
48
49   /// getMachineOpValue - Return binary encoding of operand. If the machine
50   /// operand requires relocation, record the relocation and return zero.
51   unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
52                              SmallVectorImpl<MCFixup> &Fixups) const;
53
54   unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
55                              SmallVectorImpl<MCFixup> &Fixups) const;
56   unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
57                              SmallVectorImpl<MCFixup> &Fixups) const;
58
59 };
60 } // end anonymous namespace
61
62 MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,
63                                               const MCRegisterInfo &MRI,
64                                               const MCSubtargetInfo &STI,
65                                               MCContext &Ctx) {
66   return new SparcMCCodeEmitter(Ctx);
67 }
68
69 void SparcMCCodeEmitter::
70 EncodeInstruction(const MCInst &MI, raw_ostream &OS,
71                   SmallVectorImpl<MCFixup> &Fixups) const {
72   unsigned Bits = getBinaryCodeForInstr(MI, Fixups);
73
74   // Output the constant in big endian byte order.
75   for (unsigned i = 0; i != 4; ++i) {
76     OS << (char)(Bits >> 24);
77     Bits <<= 8;
78   }
79
80   ++MCNumEmitted;  // Keep track of the # of mi's emitted.
81 }
82
83
84 unsigned SparcMCCodeEmitter::
85 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
86                   SmallVectorImpl<MCFixup> &Fixups) const {
87
88   if (MO.isReg())
89     return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
90
91   if (MO.isImm())
92     return MO.getImm();
93
94   assert(MO.isExpr());
95   const MCExpr *Expr = MO.getExpr();
96   if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) {
97     switch(SExpr->getKind()) {
98     default: assert(0 && "Unhandled sparc expression!"); break;
99     case SparcMCExpr::VK_Sparc_LO:
100       Fixups.push_back(MCFixup::Create(0, Expr,
101                                        (MCFixupKind)Sparc::fixup_sparc_lo10));
102       break;
103     case SparcMCExpr::VK_Sparc_HI:
104       Fixups.push_back(MCFixup::Create(0, Expr,
105                                        (MCFixupKind)Sparc::fixup_sparc_hi22));
106       break;
107     case SparcMCExpr::VK_Sparc_H44:
108       Fixups.push_back(MCFixup::Create(0, Expr,
109                                        (MCFixupKind)Sparc::fixup_sparc_h44));
110       break;
111     case SparcMCExpr::VK_Sparc_M44:
112       Fixups.push_back(MCFixup::Create(0, Expr,
113                                        (MCFixupKind)Sparc::fixup_sparc_m44));
114       break;
115     case SparcMCExpr::VK_Sparc_L44:
116       Fixups.push_back(MCFixup::Create(0, Expr,
117                                        (MCFixupKind)Sparc::fixup_sparc_l44));
118       break;
119     case SparcMCExpr::VK_Sparc_HH:
120       Fixups.push_back(MCFixup::Create(0, Expr,
121                                        (MCFixupKind)Sparc::fixup_sparc_hh));
122       break;
123     case SparcMCExpr::VK_Sparc_HM:
124       Fixups.push_back(MCFixup::Create(0, Expr,
125                                        (MCFixupKind)Sparc::fixup_sparc_hm));
126       break;
127     }
128     return 0;
129   }
130
131   int64_t Res;
132   if (Expr->EvaluateAsAbsolute(Res))
133     return Res;
134
135   assert(0 && "Unhandled expression!");
136   return 0;
137 }
138
139 unsigned SparcMCCodeEmitter::
140 getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
141                      SmallVectorImpl<MCFixup> &Fixups) const {
142   const MCOperand &MO = MI.getOperand(OpNo);
143   if (MO.isReg() || MO.isImm())
144     return getMachineOpValue(MI, MO, Fixups);
145
146   Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
147                                    (MCFixupKind)Sparc::fixup_sparc_call30));
148   return 0;
149 }
150
151 unsigned SparcMCCodeEmitter::
152 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
153                   SmallVectorImpl<MCFixup> &Fixups) const {
154   const MCOperand &MO = MI.getOperand(OpNo);
155   if (MO.isReg() || MO.isImm())
156     return getMachineOpValue(MI, MO, Fixups);
157
158   Sparc::Fixups fixup = Sparc::fixup_sparc_br22;
159   if (MI.getOpcode() == SP::BPXCC)
160     fixup = Sparc::fixup_sparc_br19;
161
162   Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
163                                    (MCFixupKind)fixup));
164   return 0;
165 }
166
167 #include "SparcGenMCCodeEmitter.inc"