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 
13 #include "PPCMCCodeEmitter.h"
14 #include "MCTargetDesc/PPCFixupKinds.h"
15 #include "PPCMCTargetDesc.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCFixup.h"
20 #include "llvm/MC/MCInstrDesc.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/Support/Casting.h"
23 #include "llvm/Support/Endian.h"
24 #include "llvm/Support/EndianStream.h"
25 #include "llvm/Support/ErrorHandling.h"
26 #include "llvm/Support/MathExtras.h"
27 #include "llvm/Support/raw_ostream.h"
28 #include "llvm/TargetParser/Triple.h"
29 #include <cassert>
30 #include <cstdint>
31 
32 using namespace llvm;
33 
34 #define DEBUG_TYPE "mccodeemitter"
35 
36 STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
37 
38 MCCodeEmitter *llvm::createPPCMCCodeEmitter(const MCInstrInfo &MCII,
39                                             MCContext &Ctx) {
40   return new PPCMCCodeEmitter(MCII, Ctx);
41 }
42 
43 unsigned PPCMCCodeEmitter::
44 getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
45                     SmallVectorImpl<MCFixup> &Fixups,
46                     const MCSubtargetInfo &STI) const {
47   const MCOperand &MO = MI.getOperand(OpNo);
48 
49   if (MO.isReg() || MO.isImm())
50     return getMachineOpValue(MI, MO, Fixups, STI);
51 
52   // Add a fixup for the branch target.
53   Fixups.push_back(MCFixup::create(0, MO.getExpr(),
54                                    (isNoTOCCallInstr(MI)
55                                         ? (MCFixupKind)PPC::fixup_ppc_br24_notoc
56                                         : (MCFixupKind)PPC::fixup_ppc_br24)));
57   return 0;
58 }
59 
60 /// Check if Opcode corresponds to a call instruction that should be marked
61 /// with the NOTOC relocation.
62 bool PPCMCCodeEmitter::isNoTOCCallInstr(const MCInst &MI) const {
63   unsigned Opcode = MI.getOpcode();
64   if (!MCII.get(Opcode).isCall())
65     return false;
66 
67   switch (Opcode) {
68   default:
69 #ifndef NDEBUG
70     llvm_unreachable("Unknown call opcode");
71 #endif
72     return false;
73   case PPC::BL8_NOTOC:
74   case PPC::BL8_NOTOC_TLS:
75   case PPC::BL8_NOTOC_RM:
76     return true;
77 #ifndef NDEBUG
78   case PPC::BL8:
79   case PPC::BL:
80   case PPC::BL8_TLS:
81   case PPC::BL_TLS:
82   case PPC::BLA8:
83   case PPC::BLA:
84   case PPC::BCCL:
85   case PPC::BCCLA:
86   case PPC::BCL:
87   case PPC::BCLn:
88   case PPC::BL8_NOP:
89   case PPC::BL_NOP:
90   case PPC::BL8_NOP_TLS:
91   case PPC::BLA8_NOP:
92   case PPC::BCTRL8:
93   case PPC::BCTRL:
94   case PPC::BCCCTRL8:
95   case PPC::BCCCTRL:
96   case PPC::BCCTRL8:
97   case PPC::BCCTRL:
98   case PPC::BCCTRL8n:
99   case PPC::BCCTRLn:
100   case PPC::BL8_RM:
101   case PPC::BLA8_RM:
102   case PPC::BL8_NOP_RM:
103   case PPC::BLA8_NOP_RM:
104   case PPC::BCTRL8_RM:
105   case PPC::BCTRL8_LDinto_toc:
106   case PPC::BCTRL8_LDinto_toc_RM:
107   case PPC::BL8_TLS_:
108   case PPC::TCRETURNdi8:
109   case PPC::TCRETURNai8:
110   case PPC::TCRETURNri8:
111   case PPC::TAILBCTR8:
112   case PPC::TAILB8:
113   case PPC::TAILBA8:
114   case PPC::BCLalways:
115   case PPC::BLRL:
116   case PPC::BCCLRL:
117   case PPC::BCLRL:
118   case PPC::BCLRLn:
119   case PPC::BDZL:
120   case PPC::BDNZL:
121   case PPC::BDZLA:
122   case PPC::BDNZLA:
123   case PPC::BDZLp:
124   case PPC::BDNZLp:
125   case PPC::BDZLAp:
126   case PPC::BDNZLAp:
127   case PPC::BDZLm:
128   case PPC::BDNZLm:
129   case PPC::BDZLAm:
130   case PPC::BDNZLAm:
131   case PPC::BDZLRL:
132   case PPC::BDNZLRL:
133   case PPC::BDZLRLp:
134   case PPC::BDNZLRLp:
135   case PPC::BDZLRLm:
136   case PPC::BDNZLRLm:
137   case PPC::BL_RM:
138   case PPC::BLA_RM:
139   case PPC::BL_NOP_RM:
140   case PPC::BCTRL_RM:
141   case PPC::TCRETURNdi:
142   case PPC::TCRETURNai:
143   case PPC::TCRETURNri:
144   case PPC::BCTRL_LWZinto_toc:
145   case PPC::BCTRL_LWZinto_toc_RM:
146   case PPC::TAILBCTR:
147   case PPC::TAILB:
148   case PPC::TAILBA:
149     return false;
150 #endif
151   }
152 }
153 
154 unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst &MI, unsigned OpNo,
155                                      SmallVectorImpl<MCFixup> &Fixups,
156                                      const MCSubtargetInfo &STI) const {
157   const MCOperand &MO = MI.getOperand(OpNo);
158   if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
159 
160   // Add a fixup for the branch target.
161   Fixups.push_back(MCFixup::create(0, MO.getExpr(),
162                                    (MCFixupKind)PPC::fixup_ppc_brcond14));
163   return 0;
164 }
165 
166 unsigned PPCMCCodeEmitter::
167 getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo,
168                        SmallVectorImpl<MCFixup> &Fixups,
169                        const MCSubtargetInfo &STI) const {
170   const MCOperand &MO = MI.getOperand(OpNo);
171   if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
172 
173   // Add a fixup for the branch target.
174   Fixups.push_back(MCFixup::create(0, MO.getExpr(),
175                                    (MCFixupKind)PPC::fixup_ppc_br24abs));
176   return 0;
177 }
178 
179 unsigned PPCMCCodeEmitter::
180 getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo,
181                      SmallVectorImpl<MCFixup> &Fixups,
182                      const MCSubtargetInfo &STI) const {
183   const MCOperand &MO = MI.getOperand(OpNo);
184   if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
185 
186   // Add a fixup for the branch target.
187   Fixups.push_back(MCFixup::create(0, MO.getExpr(),
188                                    (MCFixupKind)PPC::fixup_ppc_brcond14abs));
189   return 0;
190 }
191 
192 unsigned
193 PPCMCCodeEmitter::getVSRpEvenEncoding(const MCInst &MI, unsigned OpNo,
194                                       SmallVectorImpl<MCFixup> &Fixups,
195                                       const MCSubtargetInfo &STI) const {
196   assert(MI.getOperand(OpNo).isReg() && "Operand should be a register");
197   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI)
198                      << 1;
199   return RegBits;
200 }
201 
202 unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst &MI, unsigned OpNo,
203                                        SmallVectorImpl<MCFixup> &Fixups,
204                                        const MCSubtargetInfo &STI) const {
205   const MCOperand &MO = MI.getOperand(OpNo);
206   if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
207 
208   // Add a fixup for the immediate field.
209   Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(),
210                                    (MCFixupKind)PPC::fixup_ppc_half16));
211   return 0;
212 }
213 
214 uint64_t PPCMCCodeEmitter::getImm34Encoding(const MCInst &MI, unsigned OpNo,
215                                             SmallVectorImpl<MCFixup> &Fixups,
216                                             const MCSubtargetInfo &STI,
217                                             MCFixupKind Fixup) const {
218   const MCOperand &MO = MI.getOperand(OpNo);
219   assert(!MO.isReg() && "Not expecting a register for this operand.");
220   if (MO.isImm())
221     return getMachineOpValue(MI, MO, Fixups, STI);
222 
223   // Add a fixup for the immediate field.
224   Fixups.push_back(MCFixup::create(0, MO.getExpr(), Fixup));
225   return 0;
226 }
227 
228 uint64_t
229 PPCMCCodeEmitter::getImm34EncodingNoPCRel(const MCInst &MI, unsigned OpNo,
230                                           SmallVectorImpl<MCFixup> &Fixups,
231                                           const MCSubtargetInfo &STI) const {
232   return getImm34Encoding(MI, OpNo, Fixups, STI,
233                           (MCFixupKind)PPC::fixup_ppc_imm34);
234 }
235 
236 uint64_t
237 PPCMCCodeEmitter::getImm34EncodingPCRel(const MCInst &MI, unsigned OpNo,
238                                         SmallVectorImpl<MCFixup> &Fixups,
239                                         const MCSubtargetInfo &STI) const {
240   return getImm34Encoding(MI, OpNo, Fixups, STI,
241                           (MCFixupKind)PPC::fixup_ppc_pcrel34);
242 }
243 
244 unsigned PPCMCCodeEmitter::getDispRIEncoding(const MCInst &MI, unsigned OpNo,
245                                              SmallVectorImpl<MCFixup> &Fixups,
246                                              const MCSubtargetInfo &STI) const {
247   const MCOperand &MO = MI.getOperand(OpNo);
248   if (MO.isImm())
249     return getMachineOpValue(MI, MO, Fixups, STI) & 0xFFFF;
250 
251   // Add a fixup for the displacement field.
252   Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(),
253                                    (MCFixupKind)PPC::fixup_ppc_half16));
254   return 0;
255 }
256 
257 unsigned
258 PPCMCCodeEmitter::getDispRIXEncoding(const MCInst &MI, unsigned OpNo,
259                                      SmallVectorImpl<MCFixup> &Fixups,
260                                      const MCSubtargetInfo &STI) const {
261   const MCOperand &MO = MI.getOperand(OpNo);
262   if (MO.isImm())
263     return ((getMachineOpValue(MI, MO, Fixups, STI) >> 2) & 0x3FFF);
264 
265   // Add a fixup for the displacement field.
266   Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(),
267                                    (MCFixupKind)PPC::fixup_ppc_half16ds));
268   return 0;
269 }
270 
271 unsigned
272 PPCMCCodeEmitter::getDispRIX16Encoding(const MCInst &MI, unsigned OpNo,
273                                        SmallVectorImpl<MCFixup> &Fixups,
274                                        const MCSubtargetInfo &STI) const {
275   const MCOperand &MO = MI.getOperand(OpNo);
276   if (MO.isImm()) {
277     assert(!(MO.getImm() % 16) &&
278            "Expecting an immediate that is a multiple of 16");
279     return ((getMachineOpValue(MI, MO, Fixups, STI) >> 4) & 0xFFF);
280   }
281 
282   // Otherwise add a fixup for the displacement field.
283   Fixups.push_back(MCFixup::create(IsLittleEndian ? 0 : 2, MO.getExpr(),
284                                    (MCFixupKind)PPC::fixup_ppc_half16dq));
285   return 0;
286 }
287 
288 unsigned
289 PPCMCCodeEmitter::getDispRIHashEncoding(const MCInst &MI, unsigned OpNo,
290                                         SmallVectorImpl<MCFixup> &Fixups,
291                                         const MCSubtargetInfo &STI) const {
292   // Encode imm for the hash load/store to stack for the ROP Protection
293   // instructions.
294   const MCOperand &MO = MI.getOperand(OpNo);
295 
296   assert(MO.isImm() && "Expecting an immediate operand.");
297   assert(!(MO.getImm() % 8) && "Expecting offset to be 8 byte aligned.");
298 
299   unsigned DX = (MO.getImm() >> 3) & 0x3F;
300   return DX;
301 }
302 
303 uint64_t
304 PPCMCCodeEmitter::getDispRI34PCRelEncoding(const MCInst &MI, unsigned OpNo,
305                                            SmallVectorImpl<MCFixup> &Fixups,
306                                            const MCSubtargetInfo &STI) const {
307   // Encode the displacement part of pc-relative memri34, which is an imm34.
308   // The 34 bit immediate can fall into one of three cases:
309   // 1) It is a relocation to be filled in by the linker represented as:
310   //    (MCExpr::SymbolRef)
311   // 2) It is a relocation + SignedOffset represented as:
312   //    (MCExpr::Binary(MCExpr::SymbolRef + MCExpr::Constant))
313   // 3) It is a known value at compile time.
314 
315   // If this is not a MCExpr then we are in case 3) and we are dealing with
316   // a value known at compile time, not a relocation.
317   const MCOperand &MO = MI.getOperand(OpNo);
318   if (!MO.isExpr())
319     return (getMachineOpValue(MI, MO, Fixups, STI)) & 0x3FFFFFFFFUL;
320 
321   // At this point in the function it is known that MO is of type MCExpr.
322   // Therefore we are dealing with either case 1) a symbol ref or
323   // case 2) a symbol ref plus a constant.
324   const MCExpr *Expr = MO.getExpr();
325   switch (Expr->getKind()) {
326   default:
327     llvm_unreachable("Unsupported MCExpr for getMemRI34PCRelEncoding.");
328   case MCExpr::SymbolRef: {
329     // Relocation alone.
330     const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Expr);
331     (void)SRE;
332     // Currently these are the only valid PCRelative Relocations.
333     assert((SRE->getKind() == MCSymbolRefExpr::VK_PCREL ||
334             SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_PCREL ||
335             SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL ||
336             SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL ||
337             SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL) &&
338            "VariantKind must be VK_PCREL or VK_PPC_GOT_PCREL or "
339            "VK_PPC_GOT_TLSGD_PCREL or VK_PPC_GOT_TLSLD_PCREL or "
340            "VK_PPC_GOT_TPREL_PCREL.");
341     // Generate the fixup for the relocation.
342     Fixups.push_back(
343         MCFixup::create(0, Expr,
344                         static_cast<MCFixupKind>(PPC::fixup_ppc_pcrel34)));
345     // Put zero in the location of the immediate. The linker will fill in the
346     // correct value based on the relocation.
347     return 0;
348   }
349   case MCExpr::Binary: {
350     // Relocation plus some offset.
351     const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
352     assert(BE->getOpcode() == MCBinaryExpr::Add &&
353            "Binary expression opcode must be an add.");
354 
355     const MCExpr *LHS = BE->getLHS();
356     const MCExpr *RHS = BE->getRHS();
357 
358     // Need to check in both directions. Reloc+Offset and Offset+Reloc.
359     if (LHS->getKind() != MCExpr::SymbolRef)
360       std::swap(LHS, RHS);
361 
362     if (LHS->getKind() != MCExpr::SymbolRef ||
363         RHS->getKind() != MCExpr::Constant)
364       llvm_unreachable("Expecting to have one constant and one relocation.");
365 
366     const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(LHS);
367     (void)SRE;
368     assert(isInt<34>(cast<MCConstantExpr>(RHS)->getValue()) &&
369            "Value must fit in 34 bits.");
370 
371     // Currently these are the only valid PCRelative Relocations.
372     assert((SRE->getKind() == MCSymbolRefExpr::VK_PCREL ||
373             SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_PCREL) &&
374            "VariantKind must be VK_PCREL or VK_PPC_GOT_PCREL");
375     // Generate the fixup for the relocation.
376     Fixups.push_back(
377         MCFixup::create(0, Expr,
378                         static_cast<MCFixupKind>(PPC::fixup_ppc_pcrel34)));
379     // Put zero in the location of the immediate. The linker will fill in the
380     // correct value based on the relocation.
381     return 0;
382     }
383   }
384 }
385 
386 uint64_t
387 PPCMCCodeEmitter::getDispRI34Encoding(const MCInst &MI, unsigned OpNo,
388                                       SmallVectorImpl<MCFixup> &Fixups,
389                                       const MCSubtargetInfo &STI) const {
390   // Encode the displacement part of a memri34.
391   const MCOperand &MO = MI.getOperand(OpNo);
392   return (getMachineOpValue(MI, MO, Fixups, STI)) & 0x3FFFFFFFFUL;
393 }
394 
395 unsigned
396 PPCMCCodeEmitter::getDispSPE8Encoding(const MCInst &MI, unsigned OpNo,
397                                       SmallVectorImpl<MCFixup> &Fixups,
398                                       const MCSubtargetInfo &STI) const {
399   // Encode imm as a dispSPE8, which has the low 5-bits of (imm / 8).
400   const MCOperand &MO = MI.getOperand(OpNo);
401   assert(MO.isImm());
402   return getMachineOpValue(MI, MO, Fixups, STI) >> 3;
403 }
404 
405 unsigned
406 PPCMCCodeEmitter::getDispSPE4Encoding(const MCInst &MI, unsigned OpNo,
407                                       SmallVectorImpl<MCFixup> &Fixups,
408                                       const MCSubtargetInfo &STI) const {
409   // Encode imm as a dispSPE8, which has the low 5-bits of (imm / 4).
410   const MCOperand &MO = MI.getOperand(OpNo);
411   assert(MO.isImm());
412   return getMachineOpValue(MI, MO, Fixups, STI) >> 2;
413 }
414 
415 unsigned
416 PPCMCCodeEmitter::getDispSPE2Encoding(const MCInst &MI, unsigned OpNo,
417                                       SmallVectorImpl<MCFixup> &Fixups,
418                                       const MCSubtargetInfo &STI) const {
419   // Encode imm as a dispSPE8, which has the low 5-bits of (imm / 2).
420   const MCOperand &MO = MI.getOperand(OpNo);
421   assert(MO.isImm());
422   return getMachineOpValue(MI, MO, Fixups, STI) >> 1;
423 }
424 
425 unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
426                                        SmallVectorImpl<MCFixup> &Fixups,
427                                        const MCSubtargetInfo &STI) const {
428   const MCOperand &MO = MI.getOperand(OpNo);
429   if (MO.isReg()) return getMachineOpValue(MI, MO, Fixups, STI);
430 
431   // Add a fixup for the TLS register, which simply provides a relocation
432   // hint to the linker that this statement is part of a relocation sequence.
433   // Return the thread-pointer register's encoding. Add a one byte displacement
434   // if using PC relative memops.
435   const MCExpr *Expr = MO.getExpr();
436   const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Expr);
437   bool IsPCRel = SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL;
438   Fixups.push_back(MCFixup::create(IsPCRel ? 1 : 0, Expr,
439                                    (MCFixupKind)PPC::fixup_ppc_nofixup));
440   const Triple &TT = STI.getTargetTriple();
441   bool isPPC64 = TT.isPPC64();
442   return CTX.getRegisterInfo()->getEncodingValue(isPPC64 ? PPC::X13 : PPC::R2);
443 }
444 
445 unsigned PPCMCCodeEmitter::getTLSCallEncoding(const MCInst &MI, unsigned OpNo,
446                                        SmallVectorImpl<MCFixup> &Fixups,
447                                        const MCSubtargetInfo &STI) const {
448   // For special TLS calls, we need two fixups; one for the branch target
449   // (__tls_get_addr), which we create via getDirectBrEncoding as usual,
450   // and one for the TLSGD or TLSLD symbol, which is emitted here.
451   const MCOperand &MO = MI.getOperand(OpNo+1);
452   Fixups.push_back(MCFixup::create(0, MO.getExpr(),
453                                    (MCFixupKind)PPC::fixup_ppc_nofixup));
454   return getDirectBrEncoding(MI, OpNo, Fixups, STI);
455 }
456 
457 unsigned PPCMCCodeEmitter::
458 get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
459                     SmallVectorImpl<MCFixup> &Fixups,
460                     const MCSubtargetInfo &STI) const {
461   const MCOperand &MO = MI.getOperand(OpNo);
462   assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 ||
463           MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) &&
464          (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7));
465   return 0x80 >> CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
466 }
467 
468 // Get the index for this operand in this instruction. This is needed for
469 // computing the register number in PPC::getRegNumForOperand() for
470 // any instructions that use a different numbering scheme for registers in
471 // different operands.
472 static unsigned getOpIdxForMO(const MCInst &MI, const MCOperand &MO) {
473   for (unsigned i = 0; i < MI.getNumOperands(); i++) {
474     const MCOperand &Op = MI.getOperand(i);
475     if (&Op == &MO)
476       return i;
477   }
478   llvm_unreachable("This operand is not part of this instruction");
479   return ~0U; // Silence any warnings about no return.
480 }
481 
482 uint64_t PPCMCCodeEmitter::
483 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
484                   SmallVectorImpl<MCFixup> &Fixups,
485                   const MCSubtargetInfo &STI) const {
486   if (MO.isReg()) {
487     // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
488     // The GPR operand should come through here though.
489     assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 &&
490             MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) ||
491            MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7);
492     unsigned OpNo = getOpIdxForMO(MI, MO);
493     unsigned Reg =
494         PPC::getRegNumForOperand(MCII.get(MI.getOpcode()), MO.getReg(), OpNo);
495     return CTX.getRegisterInfo()->getEncodingValue(Reg);
496   }
497 
498   assert(MO.isImm() &&
499          "Relocation required in an instruction that we cannot encode!");
500   return MO.getImm();
501 }
502 
503 void PPCMCCodeEmitter::encodeInstruction(const MCInst &MI,
504                                          SmallVectorImpl<char> &CB,
505                                          SmallVectorImpl<MCFixup> &Fixups,
506                                          const MCSubtargetInfo &STI) const {
507   uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
508 
509   // Output the constant in big/little endian byte order.
510   unsigned Size = getInstSizeInBytes(MI);
511   llvm::endianness E =
512       IsLittleEndian ? llvm::endianness::little : llvm::endianness::big;
513   switch (Size) {
514   case 0:
515     break;
516   case 4:
517     support::endian::write<uint32_t>(CB, Bits, E);
518     break;
519   case 8:
520     // If we emit a pair of instructions, the first one is
521     // always in the top 32 bits, even on little-endian.
522     support::endian::write<uint32_t>(CB, Bits >> 32, E);
523     support::endian::write<uint32_t>(CB, Bits, E);
524     break;
525   default:
526     llvm_unreachable("Invalid instruction size");
527   }
528 
529   ++MCNumEmitted; // Keep track of the # of mi's emitted.
530 }
531 
532 // Get the number of bytes used to encode the given MCInst.
533 unsigned PPCMCCodeEmitter::getInstSizeInBytes(const MCInst &MI) const {
534   unsigned Opcode = MI.getOpcode();
535   const MCInstrDesc &Desc = MCII.get(Opcode);
536   return Desc.getSize();
537 }
538 
539 bool PPCMCCodeEmitter::isPrefixedInstruction(const MCInst &MI) const {
540   return MCII.get(MI.getOpcode()).TSFlags & PPCII::Prefixed;
541 }
542 
543 #include "PPCGenMCCodeEmitter.inc"
544