In this context, a reglist is a reg.
[oota-llvm.git] / lib / Target / ARM / ARMMCCodeEmitter.cpp
1 //===-- ARM/ARMMCCodeEmitter.cpp - Convert ARM 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 ARMMCCodeEmitter class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #define DEBUG_TYPE "arm-emitter"
15 #include "ARM.h"
16 #include "ARMAddressingModes.h"
17 #include "ARMFixupKinds.h"
18 #include "ARMInstrInfo.h"
19 #include "llvm/MC/MCCodeEmitter.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/ADT/Statistic.h"
23 #include "llvm/Support/raw_ostream.h"
24 using namespace llvm;
25
26 STATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
27 STATISTIC(MCNumCPRelocations, "Number of constant pool relocations created.");
28
29 namespace {
30 class ARMMCCodeEmitter : public MCCodeEmitter {
31   ARMMCCodeEmitter(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT
32   void operator=(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT
33   const TargetMachine &TM;
34   const TargetInstrInfo &TII;
35   MCContext &Ctx;
36
37 public:
38   ARMMCCodeEmitter(TargetMachine &tm, MCContext &ctx)
39     : TM(tm), TII(*TM.getInstrInfo()), Ctx(ctx) {
40   }
41
42   ~ARMMCCodeEmitter() {}
43
44   unsigned getNumFixupKinds() const { return 2; }
45
46   const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
47     const static MCFixupKindInfo Infos[] = {
48       { "fixup_arm_pcrel_12", 2, 12, MCFixupKindInfo::FKF_IsPCRel },
49       { "fixup_arm_vfp_pcrel_12", 3, 8, MCFixupKindInfo::FKF_IsPCRel },
50     };
51
52     if (Kind < FirstTargetFixupKind)
53       return MCCodeEmitter::getFixupKindInfo(Kind);
54
55     assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
56            "Invalid kind!");
57     return Infos[Kind - FirstTargetFixupKind];
58   }
59   unsigned getMachineSoImmOpValue(unsigned SoImm) const;
60
61   // getBinaryCodeForInstr - TableGen'erated function for getting the
62   // binary encoding for an instruction.
63   unsigned getBinaryCodeForInstr(const MCInst &MI,
64                                  SmallVectorImpl<MCFixup> &Fixups) const;
65
66   /// getMachineOpValue - Return binary encoding of operand. If the machine
67   /// operand requires relocation, record the relocation and return zero.
68   unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
69                              SmallVectorImpl<MCFixup> &Fixups) const;
70
71   bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx,
72                               unsigned &Reg, unsigned &Imm,
73                               SmallVectorImpl<MCFixup> &Fixups) const;
74
75   /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
76   /// operand.
77   uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
78                                    SmallVectorImpl<MCFixup> &Fixups) const;
79
80   /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand.
81   uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
82                                SmallVectorImpl<MCFixup> &Fixups) const;
83
84   /// getCCOutOpValue - Return encoding of the 's' bit.
85   unsigned getCCOutOpValue(const MCInst &MI, unsigned Op,
86                            SmallVectorImpl<MCFixup> &Fixups) const {
87     // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or
88     // '1' respectively.
89     return MI.getOperand(Op).getReg() == ARM::CPSR;
90   }
91
92   /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value.
93   unsigned getSOImmOpValue(const MCInst &MI, unsigned Op,
94                            SmallVectorImpl<MCFixup> &Fixups) const {
95     unsigned SoImm = MI.getOperand(Op).getImm();
96     int SoImmVal = ARM_AM::getSOImmVal(SoImm);
97     assert(SoImmVal != -1 && "Not a valid so_imm value!");
98
99     // Encode rotate_imm.
100     unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1)
101       << ARMII::SoRotImmShift;
102
103     // Encode immed_8.
104     Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
105     return Binary;
106   }
107
108   /// getSORegOpValue - Return an encoded so_reg shifted register value.
109   unsigned getSORegOpValue(const MCInst &MI, unsigned Op,
110                            SmallVectorImpl<MCFixup> &Fixups) const;
111
112   unsigned getRotImmOpValue(const MCInst &MI, unsigned Op,
113                             SmallVectorImpl<MCFixup> &Fixups) const {
114     switch (MI.getOperand(Op).getImm()) {
115     default: assert (0 && "Not a valid rot_imm value!");
116     case 0:  return 0;
117     case 8:  return 1;
118     case 16: return 2;
119     case 24: return 3;
120     }
121   }
122
123   unsigned getImmMinusOneOpValue(const MCInst &MI, unsigned Op,
124                                  SmallVectorImpl<MCFixup> &Fixups) const {
125     return MI.getOperand(Op).getImm() - 1;
126   }
127
128   unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op,
129                                    SmallVectorImpl<MCFixup> &Fixups) const {
130     return 64 - MI.getOperand(Op).getImm();
131   }
132
133   unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
134                                       SmallVectorImpl<MCFixup> &Fixups) const;
135
136   unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op,
137                                   SmallVectorImpl<MCFixup> &Fixups) const;
138   unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
139                                       SmallVectorImpl<MCFixup> &Fixups) const;
140   unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
141                                      SmallVectorImpl<MCFixup> &Fixups) const;
142
143   void EmitByte(unsigned char C, raw_ostream &OS) const {
144     OS << (char)C;
145   }
146
147   void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const {
148     // Output the constant in little endian byte order.
149     for (unsigned i = 0; i != Size; ++i) {
150       EmitByte(Val & 255, OS);
151       Val >>= 8;
152     }
153   }
154
155   void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
156                          SmallVectorImpl<MCFixup> &Fixups) const;
157 };
158
159 } // end anonymous namespace
160
161 MCCodeEmitter *llvm::createARMMCCodeEmitter(const Target &, TargetMachine &TM,
162                                             MCContext &Ctx) {
163   return new ARMMCCodeEmitter(TM, Ctx);
164 }
165
166 /// getMachineOpValue - Return binary encoding of operand. If the machine
167 /// operand requires relocation, record the relocation and return zero.
168 unsigned ARMMCCodeEmitter::
169 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
170                   SmallVectorImpl<MCFixup> &Fixups) const {
171   if (MO.isReg()) {
172     unsigned Reg = MO.getReg();
173     unsigned RegNo = getARMRegisterNumbering(Reg);
174
175     // Q registers are encodes as 2x their register number.
176     switch (Reg) {
177     default:
178       return RegNo;
179     case ARM::Q0:  case ARM::Q1:  case ARM::Q2:  case ARM::Q3:
180     case ARM::Q4:  case ARM::Q5:  case ARM::Q6:  case ARM::Q7:
181     case ARM::Q8:  case ARM::Q9:  case ARM::Q10: case ARM::Q11:
182     case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15:
183       return 2 * RegNo;
184     }
185   } else if (MO.isImm()) {
186     return static_cast<unsigned>(MO.getImm());
187   } else if (MO.isFPImm()) {
188     return static_cast<unsigned>(APFloat(MO.getFPImm())
189                      .bitcastToAPInt().getHiBits(32).getLimitedValue());
190   }
191
192 #ifndef NDEBUG
193   errs() << MO;
194 #endif
195   llvm_unreachable(0);
196   return 0;
197 }
198
199 /// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand.
200 bool ARMMCCodeEmitter::
201 EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg,
202                        unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups) const {
203   const MCOperand &MO  = MI.getOperand(OpIdx);
204   const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
205
206   Reg = getARMRegisterNumbering(MO.getReg());
207
208   int32_t SImm = MO1.getImm();
209   bool isAdd = true;
210
211   // Special value for #-0
212   if (SImm == INT32_MIN)
213     SImm = 0;
214
215   // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
216   if (SImm < 0) {
217     SImm = -SImm;
218     isAdd = false;
219   }
220
221   Imm = SImm;
222   return isAdd;
223 }
224
225 /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand.
226 uint32_t ARMMCCodeEmitter::
227 getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
228                         SmallVectorImpl<MCFixup> &Fixups) const {
229   // {17-13} = reg
230   // {12}    = (U)nsigned (add == '1', sub == '0')
231   // {11-0}  = imm12
232   unsigned Reg, Imm12;
233   bool isAdd = true;
234   // If The first operand isn't a register, we have a label reference.
235   const MCOperand &MO = MI.getOperand(OpIdx);
236   if (!MO.isReg()) {
237     Reg = ARM::PC;              // Rn is PC.
238     Imm12 = 0;
239
240     assert(MO.isExpr() && "Unexpected machine operand type!");
241     const MCExpr *Expr = MO.getExpr();
242     MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_12);
243     Fixups.push_back(MCFixup::Create(0, Expr, Kind));
244
245     ++MCNumCPRelocations;
246   } else
247     isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups);
248
249   if (Reg == ARM::PC)
250     return ARM::PC << 13;       // Rn is PC;
251
252   uint32_t Binary = Imm12 & 0xfff;
253   // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
254   if (isAdd)
255     Binary |= (1 << 12);
256   Binary |= (Reg << 13);
257   return Binary;
258 }
259
260 /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm12' operand.
261 uint32_t ARMMCCodeEmitter::
262 getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
263                     SmallVectorImpl<MCFixup> &Fixups) const {
264   // {12-9} = reg
265   // {8}    = (U)nsigned (add == '1', sub == '0')
266   // {7-0}  = imm8
267   unsigned Reg, Imm8;
268   // If The first operand isn't a register, we have a label reference.
269   const MCOperand &MO = MI.getOperand(OpIdx);
270   if (!MO.isReg()) {
271     Reg = ARM::PC;              // Rn is PC.
272     Imm8 = 0;
273
274     assert(MO.isExpr() && "Unexpected machine operand type!");
275     const MCExpr *Expr = MO.getExpr();
276     MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_vfp_pcrel_12);
277     Fixups.push_back(MCFixup::Create(0, Expr, Kind));
278
279     ++MCNumCPRelocations;
280   } else
281     EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
282
283   if (Reg == ARM::PC)
284     return ARM::PC << 9;        // Rn is PC;
285
286   uint32_t Binary = ARM_AM::getAM5Offset(Imm8);
287   // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
288   if (ARM_AM::getAM5Op(Imm8) == ARM_AM::add)
289     Binary |= (1 << 8);
290   Binary |= (Reg << 9);
291   return Binary;
292 }
293
294 unsigned ARMMCCodeEmitter::
295 getSORegOpValue(const MCInst &MI, unsigned OpIdx,
296                 SmallVectorImpl<MCFixup> &Fixups) const {
297   // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be
298   // shifted. The second is either Rs, the amount to shift by, or reg0 in which
299   // case the imm contains the amount to shift by.
300   //
301   // {3-0} = Rm.
302   // {4}   = 1 if reg shift, 0 if imm shift
303   // {6-5} = type
304   //    If reg shift:
305   //      {11-8} = Rs
306   //      {7}    = 0
307   //    else (imm shift)
308   //      {11-7} = imm
309
310   const MCOperand &MO  = MI.getOperand(OpIdx);
311   const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
312   const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
313   ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());
314
315   // Encode Rm.
316   unsigned Binary = getARMRegisterNumbering(MO.getReg());
317
318   // Encode the shift opcode.
319   unsigned SBits = 0;
320   unsigned Rs = MO1.getReg();
321   if (Rs) {
322     // Set shift operand (bit[7:4]).
323     // LSL - 0001
324     // LSR - 0011
325     // ASR - 0101
326     // ROR - 0111
327     // RRX - 0110 and bit[11:8] clear.
328     switch (SOpc) {
329     default: llvm_unreachable("Unknown shift opc!");
330     case ARM_AM::lsl: SBits = 0x1; break;
331     case ARM_AM::lsr: SBits = 0x3; break;
332     case ARM_AM::asr: SBits = 0x5; break;
333     case ARM_AM::ror: SBits = 0x7; break;
334     case ARM_AM::rrx: SBits = 0x6; break;
335     }
336   } else {
337     // Set shift operand (bit[6:4]).
338     // LSL - 000
339     // LSR - 010
340     // ASR - 100
341     // ROR - 110
342     switch (SOpc) {
343     default: llvm_unreachable("Unknown shift opc!");
344     case ARM_AM::lsl: SBits = 0x0; break;
345     case ARM_AM::lsr: SBits = 0x2; break;
346     case ARM_AM::asr: SBits = 0x4; break;
347     case ARM_AM::ror: SBits = 0x6; break;
348     }
349   }
350
351   Binary |= SBits << 4;
352   if (SOpc == ARM_AM::rrx)
353     return Binary;
354
355   // Encode the shift operation Rs or shift_imm (except rrx).
356   if (Rs) {
357     // Encode Rs bit[11:8].
358     assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
359     return Binary | (getARMRegisterNumbering(Rs) << ARMII::RegRsShift);
360   }
361
362   // Encode shift_imm bit[11:7].
363   return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7;
364 }
365
366 unsigned ARMMCCodeEmitter::
367 getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
368                                SmallVectorImpl<MCFixup> &Fixups) const {
369   // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the
370   // msb of the mask.
371   const MCOperand &MO = MI.getOperand(Op);
372   uint32_t v = ~MO.getImm();
373   uint32_t lsb = CountTrailingZeros_32(v);
374   uint32_t msb = (32 - CountLeadingZeros_32 (v)) - 1;
375   assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!");
376   return lsb | (msb << 5);
377 }
378
379 unsigned ARMMCCodeEmitter::
380 getRegisterListOpValue(const MCInst &MI, unsigned Op,
381                        SmallVectorImpl<MCFixup> &Fixups) const {
382   // Convert a list of GPRs into a bitfield (R0 -> bit 0). For each
383   // register in the list, set the corresponding bit.
384   unsigned Binary = 0;
385   for (unsigned i = Op, e = MI.getNumOperands(); i < e; ++i) {
386     unsigned regno = getARMRegisterNumbering(MI.getOperand(i).getReg());
387     Binary |= 1 << regno;
388   }
389   return Binary;
390 }
391
392 unsigned ARMMCCodeEmitter::
393 getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
394                            SmallVectorImpl<MCFixup> &Fixups) const {
395   const MCOperand &Reg = MI.getOperand(Op);
396   const MCOperand &Imm = MI.getOperand(Op + 1);
397
398   unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
399   unsigned Align = 0;
400
401   switch (Imm.getImm()) {
402   default: break;
403   case 2:
404   case 4:
405   case 8:  Align = 0x01; break;
406   case 16: Align = 0x02; break;
407   case 32: Align = 0x03; break;
408   }
409
410   return RegNo | (Align << 4);
411 }
412
413 unsigned ARMMCCodeEmitter::
414 getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
415                           SmallVectorImpl<MCFixup> &Fixups) const {
416   const MCOperand &MO = MI.getOperand(Op);
417   if (MO.getReg() == 0) return 0x0D;
418   return MO.getReg();
419 }
420
421 void ARMMCCodeEmitter::
422 EncodeInstruction(const MCInst &MI, raw_ostream &OS,
423                   SmallVectorImpl<MCFixup> &Fixups) const {
424   // Pseudo instructions don't get encoded.
425   const TargetInstrDesc &Desc = TII.get(MI.getOpcode());
426   if ((Desc.TSFlags & ARMII::FormMask) == ARMII::Pseudo)
427     return;
428
429   EmitConstant(getBinaryCodeForInstr(MI, Fixups), 4, OS);
430   ++MCNumEmitted;  // Keep track of the # of mi's emitted.
431 }
432
433 #include "ARMGenMCCodeEmitter.inc"