LLVM  9.0.0svn
PPCMCCodeEmitter.cpp
Go to the documentation of this file.
1 //===-- PPCMCCodeEmitter.cpp - Convert PPC code to machine code -----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the PPCMCCodeEmitter class.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "PPCInstrInfo.h"
15 #include "PPCMCCodeEmitter.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/MC/MCFixup.h"
20 #include "llvm/MC/MCInstrDesc.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/Support/Endian.h"
27 #include <cassert>
28 #include <cstdint>
29 
30 using namespace llvm;
31 
32 #define DEBUG_TYPE "mccodeemitter"
33 
34 STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
35 
37  const MCRegisterInfo &MRI,
38  MCContext &Ctx) {
39  return new PPCMCCodeEmitter(MCII, Ctx);
40 }
41 
42 unsigned PPCMCCodeEmitter::
43 getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
45  const MCSubtargetInfo &STI) const {
46  const MCOperand &MO = MI.getOperand(OpNo);
47  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
48 
49  // Add a fixup for the branch target.
50  Fixups.push_back(MCFixup::create(0, MO.getExpr(),
52  return 0;
53 }
54 
55 unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst &MI, unsigned OpNo,
57  const MCSubtargetInfo &STI) const {
58  const MCOperand &MO = MI.getOperand(OpNo);
59  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
60 
61  // Add a fixup for the branch target.
62  Fixups.push_back(MCFixup::create(0, MO.getExpr(),
64  return 0;
65 }
66 
67 unsigned PPCMCCodeEmitter::
68 getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo,
70  const MCSubtargetInfo &STI) const {
71  const MCOperand &MO = MI.getOperand(OpNo);
72  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
73 
74  // Add a fixup for the branch target.
75  Fixups.push_back(MCFixup::create(0, MO.getExpr(),
77  return 0;
78 }
79 
80 unsigned PPCMCCodeEmitter::
81 getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo,
83  const MCSubtargetInfo &STI) const {
84  const MCOperand &MO = MI.getOperand(OpNo);
85  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
86 
87  // Add a fixup for the branch target.
88  Fixups.push_back(MCFixup::create(0, MO.getExpr(),
90  return 0;
91 }
92 
93 unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst &MI, unsigned OpNo,
95  const MCSubtargetInfo &STI) const {
96  const MCOperand &MO = MI.getOperand(OpNo);
97  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
98 
99  // Add a fixup for the immediate field.
100  Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(),
102  return 0;
103 }
104 
105 unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo,
107  const MCSubtargetInfo &STI) const {
108  // Encode (imm, reg) as a memri, which has the low 16-bits as the
109  // displacement and the next 5 bits as the register #.
110  assert(MI.getOperand(OpNo+1).isReg());
111  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 16;
112 
113  const MCOperand &MO = MI.getOperand(OpNo);
114  if (MO.isImm())
115  return (getMachineOpValue(MI, MO, Fixups, STI) & 0xFFFF) | RegBits;
116 
117  // Add a fixup for the displacement field.
118  Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(),
120  return RegBits;
121 }
122 
123 unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
125  const MCSubtargetInfo &STI) const {
126  // Encode (imm, reg) as a memrix, which has the low 14-bits as the
127  // displacement and the next 5 bits as the register #.
128  assert(MI.getOperand(OpNo+1).isReg());
129  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 14;
130 
131  const MCOperand &MO = MI.getOperand(OpNo);
132  if (MO.isImm())
133  return ((getMachineOpValue(MI, MO, Fixups, STI) >> 2) & 0x3FFF) | RegBits;
134 
135  // Add a fixup for the displacement field.
136  Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(),
138  return RegBits;
139 }
140 
141 unsigned PPCMCCodeEmitter::getMemRIX16Encoding(const MCInst &MI, unsigned OpNo,
143  const MCSubtargetInfo &STI) const {
144  // Encode (imm, reg) as a memrix16, which has the low 12-bits as the
145  // displacement and the next 5 bits as the register #.
146  assert(MI.getOperand(OpNo+1).isReg());
147  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 12;
148 
149  const MCOperand &MO = MI.getOperand(OpNo);
150  if (MO.isImm()) {
151  assert(!(MO.getImm() % 16) &&
152  "Expecting an immediate that is a multiple of 16");
153  return ((getMachineOpValue(MI, MO, Fixups, STI) >> 4) & 0xFFF) | RegBits;
154  }
155 
156  // Otherwise add a fixup for the displacement field.
157  Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(),
159  return RegBits;
160 }
161 
162 unsigned PPCMCCodeEmitter::getSPE8DisEncoding(const MCInst &MI, unsigned OpNo,
164  const MCSubtargetInfo &STI)
165  const {
166  // Encode (imm, reg) as a spe8dis, which has the low 5-bits of (imm / 8)
167  // as the displacement and the next 5 bits as the register #.
168  assert(MI.getOperand(OpNo+1).isReg());
169  uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5;
170 
171  const MCOperand &MO = MI.getOperand(OpNo);
172  assert(MO.isImm());
173  uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 3;
174  return reverseBits(Imm | RegBits) >> 22;
175 }
176 
177 unsigned PPCMCCodeEmitter::getSPE4DisEncoding(const MCInst &MI, unsigned OpNo,
179  const MCSubtargetInfo &STI)
180  const {
181  // Encode (imm, reg) as a spe4dis, which has the low 5-bits of (imm / 4)
182  // as the displacement and the next 5 bits as the register #.
183  assert(MI.getOperand(OpNo+1).isReg());
184  uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5;
185 
186  const MCOperand &MO = MI.getOperand(OpNo);
187  assert(MO.isImm());
188  uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 2;
189  return reverseBits(Imm | RegBits) >> 22;
190 }
191 
192 unsigned PPCMCCodeEmitter::getSPE2DisEncoding(const MCInst &MI, unsigned OpNo,
194  const MCSubtargetInfo &STI)
195  const {
196  // Encode (imm, reg) as a spe2dis, which has the low 5-bits of (imm / 2)
197  // as the displacement and the next 5 bits as the register #.
198  assert(MI.getOperand(OpNo+1).isReg());
199  uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5;
200 
201  const MCOperand &MO = MI.getOperand(OpNo);
202  assert(MO.isImm());
203  uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 1;
204  return reverseBits(Imm | RegBits) >> 22;
205 }
206 
207 unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
209  const MCSubtargetInfo &STI) const {
210  const MCOperand &MO = MI.getOperand(OpNo);
211  if (MO.isReg()) return getMachineOpValue(MI, MO, Fixups, STI);
212 
213  // Add a fixup for the TLS register, which simply provides a relocation
214  // hint to the linker that this statement is part of a relocation sequence.
215  // Return the thread-pointer register's encoding.
216  Fixups.push_back(MCFixup::create(0, MO.getExpr(),
218  const Triple &TT = STI.getTargetTriple();
219  bool isPPC64 = TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le;
220  return CTX.getRegisterInfo()->getEncodingValue(isPPC64 ? PPC::X13 : PPC::R2);
221 }
222 
223 unsigned PPCMCCodeEmitter::getTLSCallEncoding(const MCInst &MI, unsigned OpNo,
225  const MCSubtargetInfo &STI) const {
226  // For special TLS calls, we need two fixups; one for the branch target
227  // (__tls_get_addr), which we create via getDirectBrEncoding as usual,
228  // and one for the TLSGD or TLSLD symbol, which is emitted here.
229  const MCOperand &MO = MI.getOperand(OpNo+1);
230  Fixups.push_back(MCFixup::create(0, MO.getExpr(),
232  return getDirectBrEncoding(MI, OpNo, Fixups, STI);
233 }
234 
235 unsigned PPCMCCodeEmitter::
236 get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
238  const MCSubtargetInfo &STI) const {
239  const MCOperand &MO = MI.getOperand(OpNo);
240  assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 ||
241  MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) &&
242  (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7));
243  return 0x80 >> CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
244 }
245 
246 // Get the index for this operand in this instruction. This is needed for
247 // computing the register number in PPCInstrInfo::getRegNumForOperand() for
248 // any instructions that use a different numbering scheme for registers in
249 // different operands.
250 static unsigned getOpIdxForMO(const MCInst &MI, const MCOperand &MO) {
251  for (unsigned i = 0; i < MI.getNumOperands(); i++) {
252  const MCOperand &Op = MI.getOperand(i);
253  if (&Op == &MO)
254  return i;
255  }
256  llvm_unreachable("This operand is not part of this instruction");
257  return ~0U; // Silence any warnings about no return.
258 }
259 
260 unsigned PPCMCCodeEmitter::
263  const MCSubtargetInfo &STI) const {
264  if (MO.isReg()) {
265  // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
266  // The GPR operand should come through here though.
267  assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 &&
268  MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) ||
269  MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7);
270  unsigned OpNo = getOpIdxForMO(MI, MO);
271  unsigned Reg =
273  MO.getReg(), OpNo);
274  return CTX.getRegisterInfo()->getEncodingValue(Reg);
275  }
276 
277  assert(MO.isImm() &&
278  "Relocation required in an instruction that we cannot encode!");
279  return MO.getImm();
280 }
281 
284  const MCSubtargetInfo &STI) const {
285  verifyInstructionPredicates(MI,
286  computeAvailableFeatures(STI.getFeatureBits()));
287 
288  uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
289 
290  // Output the constant in big/little endian byte order.
291  unsigned Size = getInstSizeInBytes(MI);
292  support::endianness E = IsLittleEndian ? support::little : support::big;
293  switch (Size) {
294  case 0:
295  break;
296  case 4:
297  support::endian::write<uint32_t>(OS, Bits, E);
298  break;
299  case 8:
300  // If we emit a pair of instructions, the first one is
301  // always in the top 32 bits, even on little-endian.
302  support::endian::write<uint32_t>(OS, Bits >> 32, E);
303  support::endian::write<uint32_t>(OS, Bits, E);
304  break;
305  default:
306  llvm_unreachable("Invalid instruction size");
307  }
308 
309  ++MCNumEmitted; // Keep track of the # of mi's emitted.
310 }
311 
312 // Get the number of bytes used to encode the given MCInst.
314  unsigned Opcode = MI.getOpcode();
315  const MCInstrDesc &Desc = MCII.get(Opcode);
316  return Desc.getSize();
317 }
318 
319 #define ENABLE_INSTR_PREDICATE_VERIFIER
320 #include "PPCGenMCCodeEmitter.inc"
unsigned getMemRIEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getTLSRegEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
bool isImm() const
Definition: MCInst.h:58
This class represents lattice values for constants.
Definition: AllocatorList.h:23
void encodeInstruction(const MCInst &MI, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const override
EncodeInstruction - Encode the given Inst to bytes on the output stream OS.
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:163
unsigned Reg
bool isReg() const
Definition: MCInst.h:57
STATISTIC(NumFunctions, "Total number of functions")
14-bit absolute relocation for conditional branches.
Definition: PPCFixupKinds.h:29
#define R2(n)
unsigned getImm16Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
const Triple & getTargetTriple() const
A 16-bit fixup corresponding to lo16(_foo) or ha16(_foo) for instrs like &#39;li&#39; or &#39;addis&#39;.
Definition: PPCFixupKinds.h:33
24-bit absolute relocation for direct branches like &#39;ba&#39; and &#39;bla&#39;.
Definition: PPCFixupKinds.h:26
const FeatureBitset & getFeatureBits() const
unsigned getMemRIX16Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getCondBrEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:41
Not a true fixup, but ties a symbol to a call to __tls_get_addr for the TLS general and local dynamic...
Definition: PPCFixupKinds.h:42
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:64
Context object for machine code objects.
Definition: MCContext.h:62
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
Definition: Triple.h:290
unsigned getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getSPE4DisEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
const MCExpr * getExpr() const
Definition: MCInst.h:95
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
int64_t getImm() const
Definition: MCInst.h:75
unsigned const MachineRegisterInfo * MRI
unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
getMachineOpValue - Return binary encoding of operand.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:21
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:23
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:22
unsigned getInstSizeInBytes(const MCInst &MI) const
unsigned getNumOperands() const
Definition: MCInst.h:181
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:89
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getSPE2DisEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:43
unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
uint64_t getBinaryCodeForInstr(const MCInst &MI, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
static unsigned getRegNumForOperand(const MCInstrDesc &Desc, unsigned Reg, unsigned OpNo)
getRegNumForOperand - some operands use different numbering schemes for the same registers.
Definition: PPCInstrInfo.h:441
static unsigned getOpIdxForMO(const MCInst &MI, const MCOperand &MO)
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:179
unsigned getDirectBrEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getTLSCallEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
A 14-bit fixup corresponding to lo16(_foo) with implied 2 zero bits for instrs like &#39;std&#39;...
Definition: PPCFixupKinds.h:37
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:44
Generic base class for all target subtargets.
unsigned getSPE8DisEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
uint32_t Size
Definition: Profile.cpp:46
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:294
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
IRTranslator LLVM IR MI
14-bit PC relative relocation for conditional branches.
Definition: PPCFixupKinds.h:23
unsigned getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getOpcode() const
Definition: MCInst.h:171
T reverseBits(T Val)
Reverse the bits in Val.
Definition: MathExtras.h:268
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:34
MCCodeEmitter * createPPCMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx)
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
Definition: MCInstrDesc.h:580