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