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 #include "MCTargetDesc/PPCMCTargetDesc.h"
15 #include "MCTargetDesc/PPCFixupKinds.h"
16 #include "llvm/ADT/Statistic.h"
17 #include "llvm/MC/MCAsmInfo.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"
23 #include "llvm/MC/MCRegisterInfo.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/Support/ErrorHandling.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include "llvm/Target/TargetOpcodes.h"
28 using namespace llvm;
29 
30 #define DEBUG_TYPE "mccodeemitter"
31 
32 STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
33 
34 namespace {
35 class PPCMCCodeEmitter : public MCCodeEmitter {
36   PPCMCCodeEmitter(const PPCMCCodeEmitter &) = delete;
37   void operator=(const PPCMCCodeEmitter &) = delete;
38 
39   const MCInstrInfo &MCII;
40   const MCContext &CTX;
41   bool IsLittleEndian;
42 
43 public:
44   PPCMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
45       : MCII(mcii), CTX(ctx),
46         IsLittleEndian(ctx.getAsmInfo()->isLittleEndian()) {}
47 
48   ~PPCMCCodeEmitter() override {}
49 
50   unsigned getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
51                                SmallVectorImpl<MCFixup> &Fixups,
52                                const MCSubtargetInfo &STI) const;
53   unsigned getCondBrEncoding(const MCInst &MI, unsigned OpNo,
54                              SmallVectorImpl<MCFixup> &Fixups,
55                              const MCSubtargetInfo &STI) const;
56   unsigned getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo,
57                                   SmallVectorImpl<MCFixup> &Fixups,
58                                   const MCSubtargetInfo &STI) const;
59   unsigned getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo,
60                                 SmallVectorImpl<MCFixup> &Fixups,
61                                 const MCSubtargetInfo &STI) const;
62   unsigned getImm16Encoding(const MCInst &MI, unsigned OpNo,
63                              SmallVectorImpl<MCFixup> &Fixups,
64                              const MCSubtargetInfo &STI) const;
65   unsigned getMemRIEncoding(const MCInst &MI, unsigned OpNo,
66                             SmallVectorImpl<MCFixup> &Fixups,
67                             const MCSubtargetInfo &STI) const;
68   unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
69                              SmallVectorImpl<MCFixup> &Fixups,
70                              const MCSubtargetInfo &STI) const;
71   unsigned getSPE8DisEncoding(const MCInst &MI, unsigned OpNo,
72                               SmallVectorImpl<MCFixup> &Fixups,
73                               const MCSubtargetInfo &STI) const;
74   unsigned getSPE4DisEncoding(const MCInst &MI, unsigned OpNo,
75                               SmallVectorImpl<MCFixup> &Fixups,
76                               const MCSubtargetInfo &STI) const;
77   unsigned getSPE2DisEncoding(const MCInst &MI, unsigned OpNo,
78                               SmallVectorImpl<MCFixup> &Fixups,
79                               const MCSubtargetInfo &STI) const;
80   unsigned getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
81                              SmallVectorImpl<MCFixup> &Fixups,
82                              const MCSubtargetInfo &STI) const;
83   unsigned getTLSCallEncoding(const MCInst &MI, unsigned OpNo,
84                               SmallVectorImpl<MCFixup> &Fixups,
85                               const MCSubtargetInfo &STI) const;
86   unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
87                                SmallVectorImpl<MCFixup> &Fixups,
88                                const MCSubtargetInfo &STI) const;
89 
90   /// getMachineOpValue - Return binary encoding of operand. If the machine
91   /// operand requires relocation, record the relocation and return zero.
92   unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
93                              SmallVectorImpl<MCFixup> &Fixups,
94                              const MCSubtargetInfo &STI) const;
95 
96   // getBinaryCodeForInstr - TableGen'erated function for getting the
97   // binary encoding for an instruction.
98   uint64_t getBinaryCodeForInstr(const MCInst &MI,
99                                  SmallVectorImpl<MCFixup> &Fixups,
100                                  const MCSubtargetInfo &STI) const;
101   void encodeInstruction(const MCInst &MI, raw_ostream &OS,
102                          SmallVectorImpl<MCFixup> &Fixups,
103                          const MCSubtargetInfo &STI) const override {
104     // For fast-isel, a float COPY_TO_REGCLASS can survive this long.
105     // It's just a nop to keep the register classes happy, so don't
106     // generate anything.
107     unsigned Opcode = MI.getOpcode();
108     const MCInstrDesc &Desc = MCII.get(Opcode);
109     if (Opcode == TargetOpcode::COPY_TO_REGCLASS)
110       return;
111 
112     uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
113 
114     // Output the constant in big/little endian byte order.
115     unsigned Size = Desc.getSize();
116     switch (Size) {
117     case 4:
118       if (IsLittleEndian) {
119         OS << (char)(Bits);
120         OS << (char)(Bits >> 8);
121         OS << (char)(Bits >> 16);
122         OS << (char)(Bits >> 24);
123       } else {
124         OS << (char)(Bits >> 24);
125         OS << (char)(Bits >> 16);
126         OS << (char)(Bits >> 8);
127         OS << (char)(Bits);
128       }
129       break;
130     case 8:
131       // If we emit a pair of instructions, the first one is
132       // always in the top 32 bits, even on little-endian.
133       if (IsLittleEndian) {
134         OS << (char)(Bits >> 32);
135         OS << (char)(Bits >> 40);
136         OS << (char)(Bits >> 48);
137         OS << (char)(Bits >> 56);
138         OS << (char)(Bits);
139         OS << (char)(Bits >> 8);
140         OS << (char)(Bits >> 16);
141         OS << (char)(Bits >> 24);
142       } else {
143         OS << (char)(Bits >> 56);
144         OS << (char)(Bits >> 48);
145         OS << (char)(Bits >> 40);
146         OS << (char)(Bits >> 32);
147         OS << (char)(Bits >> 24);
148         OS << (char)(Bits >> 16);
149         OS << (char)(Bits >> 8);
150         OS << (char)(Bits);
151       }
152       break;
153     default:
154       llvm_unreachable ("Invalid instruction size");
155     }
156 
157     ++MCNumEmitted;  // Keep track of the # of mi's emitted.
158   }
159 
160 };
161 
162 } // end anonymous namespace
163 
164 MCCodeEmitter *llvm::createPPCMCCodeEmitter(const MCInstrInfo &MCII,
165                                             const MCRegisterInfo &MRI,
166                                             MCContext &Ctx) {
167   return new PPCMCCodeEmitter(MCII, Ctx);
168 }
169 
170 unsigned PPCMCCodeEmitter::
171 getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
172                     SmallVectorImpl<MCFixup> &Fixups,
173                     const MCSubtargetInfo &STI) const {
174   const MCOperand &MO = MI.getOperand(OpNo);
175   if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
176 
177   // Add a fixup for the branch target.
178   Fixups.push_back(MCFixup::create(0, MO.getExpr(),
179                                    (MCFixupKind)PPC::fixup_ppc_br24));
180   return 0;
181 }
182 
183 unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst &MI, unsigned OpNo,
184                                      SmallVectorImpl<MCFixup> &Fixups,
185                                      const MCSubtargetInfo &STI) const {
186   const MCOperand &MO = MI.getOperand(OpNo);
187   if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
188 
189   // Add a fixup for the branch target.
190   Fixups.push_back(MCFixup::create(0, MO.getExpr(),
191                                    (MCFixupKind)PPC::fixup_ppc_brcond14));
192   return 0;
193 }
194 
195 unsigned PPCMCCodeEmitter::
196 getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo,
197                        SmallVectorImpl<MCFixup> &Fixups,
198                        const MCSubtargetInfo &STI) const {
199   const MCOperand &MO = MI.getOperand(OpNo);
200   if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
201 
202   // Add a fixup for the branch target.
203   Fixups.push_back(MCFixup::create(0, MO.getExpr(),
204                                    (MCFixupKind)PPC::fixup_ppc_br24abs));
205   return 0;
206 }
207 
208 unsigned PPCMCCodeEmitter::
209 getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo,
210                      SmallVectorImpl<MCFixup> &Fixups,
211                      const MCSubtargetInfo &STI) const {
212   const MCOperand &MO = MI.getOperand(OpNo);
213   if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
214 
215   // Add a fixup for the branch target.
216   Fixups.push_back(MCFixup::create(0, MO.getExpr(),
217                                    (MCFixupKind)PPC::fixup_ppc_brcond14abs));
218   return 0;
219 }
220 
221 unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst &MI, unsigned OpNo,
222                                        SmallVectorImpl<MCFixup> &Fixups,
223                                        const MCSubtargetInfo &STI) const {
224   const MCOperand &MO = MI.getOperand(OpNo);
225   if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
226 
227   // Add a fixup for the immediate field.
228   Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(),
229                                    (MCFixupKind)PPC::fixup_ppc_half16));
230   return 0;
231 }
232 
233 unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo,
234                                             SmallVectorImpl<MCFixup> &Fixups,
235                                             const MCSubtargetInfo &STI) const {
236   // Encode (imm, reg) as a memri, which has the low 16-bits as the
237   // displacement and the next 5 bits as the register #.
238   assert(MI.getOperand(OpNo+1).isReg());
239   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 16;
240 
241   const MCOperand &MO = MI.getOperand(OpNo);
242   if (MO.isImm())
243     return (getMachineOpValue(MI, MO, Fixups, STI) & 0xFFFF) | RegBits;
244 
245   // Add a fixup for the displacement field.
246   Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(),
247                                    (MCFixupKind)PPC::fixup_ppc_half16));
248   return RegBits;
249 }
250 
251 
252 unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
253                                        SmallVectorImpl<MCFixup> &Fixups,
254                                        const MCSubtargetInfo &STI) const {
255   // Encode (imm, reg) as a memrix, which has the low 14-bits as the
256   // displacement and the next 5 bits as the register #.
257   assert(MI.getOperand(OpNo+1).isReg());
258   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 14;
259 
260   const MCOperand &MO = MI.getOperand(OpNo);
261   if (MO.isImm())
262     return ((getMachineOpValue(MI, MO, Fixups, STI) >> 2) & 0x3FFF) | RegBits;
263 
264   // Add a fixup for the displacement field.
265   Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(),
266                                    (MCFixupKind)PPC::fixup_ppc_half16ds));
267   return RegBits;
268 }
269 
270 
271 unsigned PPCMCCodeEmitter::getSPE8DisEncoding(const MCInst &MI, unsigned OpNo,
272                                               SmallVectorImpl<MCFixup> &Fixups,
273                                               const MCSubtargetInfo &STI)
274                                               const {
275   // Encode (imm, reg) as a spe8dis, which has the low 5-bits of (imm / 8)
276   // as the displacement and the next 5 bits as the register #.
277   assert(MI.getOperand(OpNo+1).isReg());
278   uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5;
279 
280   const MCOperand &MO = MI.getOperand(OpNo);
281   assert(MO.isImm());
282   uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 3;
283   return reverseBits(Imm | RegBits) >> 22;
284 }
285 
286 
287 unsigned PPCMCCodeEmitter::getSPE4DisEncoding(const MCInst &MI, unsigned OpNo,
288                                               SmallVectorImpl<MCFixup> &Fixups,
289                                               const MCSubtargetInfo &STI)
290                                               const {
291   // Encode (imm, reg) as a spe4dis, which has the low 5-bits of (imm / 4)
292   // as the displacement and the next 5 bits as the register #.
293   assert(MI.getOperand(OpNo+1).isReg());
294   uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5;
295 
296   const MCOperand &MO = MI.getOperand(OpNo);
297   assert(MO.isImm());
298   uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 2;
299   return reverseBits(Imm | RegBits) >> 22;
300 }
301 
302 
303 unsigned PPCMCCodeEmitter::getSPE2DisEncoding(const MCInst &MI, unsigned OpNo,
304                                               SmallVectorImpl<MCFixup> &Fixups,
305                                               const MCSubtargetInfo &STI)
306                                               const {
307   // Encode (imm, reg) as a spe2dis, which has the low 5-bits of (imm / 2)
308   // as the displacement and the next 5 bits as the register #.
309   assert(MI.getOperand(OpNo+1).isReg());
310   uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5;
311 
312   const MCOperand &MO = MI.getOperand(OpNo);
313   assert(MO.isImm());
314   uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 1;
315   return reverseBits(Imm | RegBits) >> 22;
316 }
317 
318 
319 unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
320                                        SmallVectorImpl<MCFixup> &Fixups,
321                                        const MCSubtargetInfo &STI) const {
322   const MCOperand &MO = MI.getOperand(OpNo);
323   if (MO.isReg()) return getMachineOpValue(MI, MO, Fixups, STI);
324 
325   // Add a fixup for the TLS register, which simply provides a relocation
326   // hint to the linker that this statement is part of a relocation sequence.
327   // Return the thread-pointer register's encoding.
328   Fixups.push_back(MCFixup::create(0, MO.getExpr(),
329                                    (MCFixupKind)PPC::fixup_ppc_nofixup));
330   Triple TT(STI.getTargetTriple());
331   bool isPPC64 = TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le;
332   return CTX.getRegisterInfo()->getEncodingValue(isPPC64 ? PPC::X13 : PPC::R2);
333 }
334 
335 unsigned PPCMCCodeEmitter::getTLSCallEncoding(const MCInst &MI, unsigned OpNo,
336                                        SmallVectorImpl<MCFixup> &Fixups,
337                                        const MCSubtargetInfo &STI) const {
338   // For special TLS calls, we need two fixups; one for the branch target
339   // (__tls_get_addr), which we create via getDirectBrEncoding as usual,
340   // and one for the TLSGD or TLSLD symbol, which is emitted here.
341   const MCOperand &MO = MI.getOperand(OpNo+1);
342   Fixups.push_back(MCFixup::create(0, MO.getExpr(),
343                                    (MCFixupKind)PPC::fixup_ppc_nofixup));
344   return getDirectBrEncoding(MI, OpNo, Fixups, STI);
345 }
346 
347 unsigned PPCMCCodeEmitter::
348 get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
349                     SmallVectorImpl<MCFixup> &Fixups,
350                     const MCSubtargetInfo &STI) const {
351   const MCOperand &MO = MI.getOperand(OpNo);
352   assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 ||
353           MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) &&
354          (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7));
355   return 0x80 >> CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
356 }
357 
358 
359 unsigned PPCMCCodeEmitter::
360 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
361                   SmallVectorImpl<MCFixup> &Fixups,
362                   const MCSubtargetInfo &STI) const {
363   if (MO.isReg()) {
364     // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
365     // The GPR operand should come through here though.
366     assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 &&
367             MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) ||
368            MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7);
369     return CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
370   }
371 
372   assert(MO.isImm() &&
373          "Relocation required in an instruction that we cannot encode!");
374   return MO.getImm();
375 }
376 
377 
378 #include "PPCGenMCCodeEmitter.inc"
379