LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PPCMCCodeEmitter.cpp
Go to the documentation of this file.
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"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/MC/MCCodeEmitter.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstrInfo.h"
27 using namespace llvm;
28 
29 STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
30 
31 namespace {
32 class PPCMCCodeEmitter : public MCCodeEmitter {
33  PPCMCCodeEmitter(const PPCMCCodeEmitter &) LLVM_DELETED_FUNCTION;
34  void operator=(const PPCMCCodeEmitter &) LLVM_DELETED_FUNCTION;
35 
36  const MCSubtargetInfo &STI;
37  const MCContext &CTX;
38  Triple TT;
39 
40 public:
41  PPCMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,
42  MCContext &ctx)
43  : STI(sti), CTX(ctx), TT(STI.getTargetTriple()) {
44  }
45 
46  ~PPCMCCodeEmitter() {}
47 
48  unsigned getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
50  unsigned getCondBrEncoding(const MCInst &MI, unsigned OpNo,
52  unsigned getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo,
54  unsigned getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo,
56  unsigned getImm16Encoding(const MCInst &MI, unsigned OpNo,
58  unsigned getMemRIEncoding(const MCInst &MI, unsigned OpNo,
60  unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
62  unsigned getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
64  unsigned getTLSCallEncoding(const MCInst &MI, unsigned OpNo,
66  unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
68 
69  /// getMachineOpValue - Return binary encoding of operand. If the machine
70  /// operand requires relocation, record the relocation and return zero.
71  unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
73 
74  // getBinaryCodeForInstr - TableGen'erated function for getting the
75  // binary encoding for an instruction.
76  uint64_t getBinaryCodeForInstr(const MCInst &MI,
78  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
80  // For fast-isel, a float COPY_TO_REGCLASS can survive this long.
81  // It's just a nop to keep the register classes happy, so don't
82  // generate anything.
83  unsigned Opcode = MI.getOpcode();
84  if (Opcode == TargetOpcode::COPY_TO_REGCLASS)
85  return;
86 
87  uint64_t Bits = getBinaryCodeForInstr(MI, Fixups);
88 
89  // BL8_NOP etc. all have a size of 8 because of the following 'nop'.
90  unsigned Size = 4; // FIXME: Have Desc.getSize() return the correct value!
91  if (Opcode == PPC::BL8_NOP || Opcode == PPC::BLA8_NOP ||
92  Opcode == PPC::BL8_NOP_TLS)
93  Size = 8;
94 
95  // Output the constant in big endian byte order.
96  int ShiftValue = (Size * 8) - 8;
97  for (unsigned i = 0; i != Size; ++i) {
98  OS << (char)(Bits >> ShiftValue);
99  Bits <<= 8;
100  }
101 
102  ++MCNumEmitted; // Keep track of the # of mi's emitted.
103  }
104 
105 };
106 
107 } // end anonymous namespace
108 
110  const MCRegisterInfo &MRI,
111  const MCSubtargetInfo &STI,
112  MCContext &Ctx) {
113  return new PPCMCCodeEmitter(MCII, STI, Ctx);
114 }
115 
116 unsigned PPCMCCodeEmitter::
117 getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
118  SmallVectorImpl<MCFixup> &Fixups) const {
119  const MCOperand &MO = MI.getOperand(OpNo);
120  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
121 
122  // Add a fixup for the branch target.
123  Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
125  return 0;
126 }
127 
128 unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst &MI, unsigned OpNo,
129  SmallVectorImpl<MCFixup> &Fixups) const {
130  const MCOperand &MO = MI.getOperand(OpNo);
131  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
132 
133  // Add a fixup for the branch target.
134  Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
136  return 0;
137 }
138 
139 unsigned PPCMCCodeEmitter::
140 getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo,
141  SmallVectorImpl<MCFixup> &Fixups) const {
142  const MCOperand &MO = MI.getOperand(OpNo);
143  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
144 
145  // Add a fixup for the branch target.
146  Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
148  return 0;
149 }
150 
151 unsigned PPCMCCodeEmitter::
152 getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo,
153  SmallVectorImpl<MCFixup> &Fixups) const {
154  const MCOperand &MO = MI.getOperand(OpNo);
155  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
156 
157  // Add a fixup for the branch target.
158  Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
160  return 0;
161 }
162 
163 unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst &MI, unsigned OpNo,
164  SmallVectorImpl<MCFixup> &Fixups) const {
165  const MCOperand &MO = MI.getOperand(OpNo);
166  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
167 
168  // Add a fixup for the immediate field.
169  Fixups.push_back(MCFixup::Create(2, MO.getExpr(),
171  return 0;
172 }
173 
174 unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo,
175  SmallVectorImpl<MCFixup> &Fixups) const {
176  // Encode (imm, reg) as a memri, which has the low 16-bits as the
177  // displacement and the next 5 bits as the register #.
178  assert(MI.getOperand(OpNo+1).isReg());
179  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups) << 16;
180 
181  const MCOperand &MO = MI.getOperand(OpNo);
182  if (MO.isImm())
183  return (getMachineOpValue(MI, MO, Fixups) & 0xFFFF) | RegBits;
184 
185  // Add a fixup for the displacement field.
186  Fixups.push_back(MCFixup::Create(2, MO.getExpr(),
188  return RegBits;
189 }
190 
191 
192 unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
193  SmallVectorImpl<MCFixup> &Fixups) const {
194  // Encode (imm, reg) as a memrix, which has the low 14-bits as the
195  // displacement and the next 5 bits as the register #.
196  assert(MI.getOperand(OpNo+1).isReg());
197  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups) << 14;
198 
199  const MCOperand &MO = MI.getOperand(OpNo);
200  if (MO.isImm())
201  return ((getMachineOpValue(MI, MO, Fixups) >> 2) & 0x3FFF) | RegBits;
202 
203  // Add a fixup for the displacement field.
204  Fixups.push_back(MCFixup::Create(2, MO.getExpr(),
206  return RegBits;
207 }
208 
209 
210 unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
211  SmallVectorImpl<MCFixup> &Fixups) const {
212  const MCOperand &MO = MI.getOperand(OpNo);
213  if (MO.isReg()) return getMachineOpValue(MI, MO, Fixups);
214 
215  // Add a fixup for the TLS register, which simply provides a relocation
216  // hint to the linker that this statement is part of a relocation sequence.
217  // Return the thread-pointer register's encoding.
218  Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
220  return CTX.getRegisterInfo()->getEncodingValue(PPC::X13);
221 }
222 
223 unsigned PPCMCCodeEmitter::getTLSCallEncoding(const MCInst &MI, unsigned OpNo,
224  SmallVectorImpl<MCFixup> &Fixups) const {
225  // For special TLS calls, we need two fixups; one for the branch target
226  // (__tls_get_addr), which we create via getDirectBrEncoding as usual,
227  // and one for the TLSGD or TLSLD symbol, which is emitted here.
228  const MCOperand &MO = MI.getOperand(OpNo+1);
229  Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
231  return getDirectBrEncoding(MI, OpNo, Fixups);
232 }
233 
234 unsigned PPCMCCodeEmitter::
235 get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
236  SmallVectorImpl<MCFixup> &Fixups) const {
237  const MCOperand &MO = MI.getOperand(OpNo);
238  assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 ||
239  MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) &&
240  (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7));
241  return 0x80 >> CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
242 }
243 
244 
245 unsigned PPCMCCodeEmitter::
246 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
247  SmallVectorImpl<MCFixup> &Fixups) const {
248  if (MO.isReg()) {
249  // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
250  // The GPR operand should come through here though.
251  assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 &&
252  MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) ||
253  MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7);
254  return CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
255  }
256 
257  assert(MO.isImm() &&
258  "Relocation required in an instruction that we cannot encode!");
259  return MO.getImm();
260 }
261 
262 
263 #include "PPCGenMCCodeEmitter.inc"
bool isReg() const
Definition: MCInst.h:56
STATISTIC(MCNumEmitted,"Number of MC instructions emitted")
MCCodeEmitter * createPPCMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI, MCContext &Ctx)
unsigned getReg() const
getReg - Returns the register number.
Definition: MCInst.h:63
bool isImm() const
Definition: MCInst.h:57
const MCExpr * getExpr() const
Definition: MCInst.h:93
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:22
MCFixupKind
MCFixupKind - Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:22
#define LLVM_DELETED_FUNCTION
Definition: Compiler.h:137
unsigned getOpcode() const
Definition: MCInst.h:158
int64_t getImm() const
Definition: MCInst.h:74
static MCFixup Create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:77
const MCRegisterInfo & MRI
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:163