Add support for a few simple fixups to the ARM Darwin asm backend. This allows
[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 = getARMRegisterNumbering(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   uint32_t Binary = Imm12 & 0xfff;
250   // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
251   if (isAdd)
252     Binary |= (1 << 12);
253   Binary |= (Reg << 13);
254   return Binary;
255 }
256
257 /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm12' operand.
258 uint32_t ARMMCCodeEmitter::
259 getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
260                     SmallVectorImpl<MCFixup> &Fixups) const {
261   // {12-9} = reg
262   // {8}    = (U)nsigned (add == '1', sub == '0')
263   // {7-0}  = imm8
264   unsigned Reg, Imm8;
265   // If The first operand isn't a register, we have a label reference.
266   const MCOperand &MO = MI.getOperand(OpIdx);
267   if (!MO.isReg()) {
268     Reg = getARMRegisterNumbering(ARM::PC);   // Rn is PC.
269     Imm8 = 0;
270
271     assert(MO.isExpr() && "Unexpected machine operand type!");
272     const MCExpr *Expr = MO.getExpr();
273     MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_vfp_pcrel_12);
274     Fixups.push_back(MCFixup::Create(0, Expr, Kind));
275
276     ++MCNumCPRelocations;
277   } else
278     EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
279
280   uint32_t Binary = ARM_AM::getAM5Offset(Imm8);
281   // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
282   if (ARM_AM::getAM5Op(Imm8) == ARM_AM::add)
283     Binary |= (1 << 8);
284   Binary |= (Reg << 9);
285   return Binary;
286 }
287
288 unsigned ARMMCCodeEmitter::
289 getSORegOpValue(const MCInst &MI, unsigned OpIdx,
290                 SmallVectorImpl<MCFixup> &Fixups) const {
291   // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be
292   // shifted. The second is either Rs, the amount to shift by, or reg0 in which
293   // case the imm contains the amount to shift by.
294   //
295   // {3-0} = Rm.
296   // {4}   = 1 if reg shift, 0 if imm shift
297   // {6-5} = type
298   //    If reg shift:
299   //      {11-8} = Rs
300   //      {7}    = 0
301   //    else (imm shift)
302   //      {11-7} = imm
303
304   const MCOperand &MO  = MI.getOperand(OpIdx);
305   const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
306   const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
307   ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());
308
309   // Encode Rm.
310   unsigned Binary = getARMRegisterNumbering(MO.getReg());
311
312   // Encode the shift opcode.
313   unsigned SBits = 0;
314   unsigned Rs = MO1.getReg();
315   if (Rs) {
316     // Set shift operand (bit[7:4]).
317     // LSL - 0001
318     // LSR - 0011
319     // ASR - 0101
320     // ROR - 0111
321     // RRX - 0110 and bit[11:8] clear.
322     switch (SOpc) {
323     default: llvm_unreachable("Unknown shift opc!");
324     case ARM_AM::lsl: SBits = 0x1; break;
325     case ARM_AM::lsr: SBits = 0x3; break;
326     case ARM_AM::asr: SBits = 0x5; break;
327     case ARM_AM::ror: SBits = 0x7; break;
328     case ARM_AM::rrx: SBits = 0x6; break;
329     }
330   } else {
331     // Set shift operand (bit[6:4]).
332     // LSL - 000
333     // LSR - 010
334     // ASR - 100
335     // ROR - 110
336     switch (SOpc) {
337     default: llvm_unreachable("Unknown shift opc!");
338     case ARM_AM::lsl: SBits = 0x0; break;
339     case ARM_AM::lsr: SBits = 0x2; break;
340     case ARM_AM::asr: SBits = 0x4; break;
341     case ARM_AM::ror: SBits = 0x6; break;
342     }
343   }
344
345   Binary |= SBits << 4;
346   if (SOpc == ARM_AM::rrx)
347     return Binary;
348
349   // Encode the shift operation Rs or shift_imm (except rrx).
350   if (Rs) {
351     // Encode Rs bit[11:8].
352     assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
353     return Binary | (getARMRegisterNumbering(Rs) << ARMII::RegRsShift);
354   }
355
356   // Encode shift_imm bit[11:7].
357   return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7;
358 }
359
360 unsigned ARMMCCodeEmitter::
361 getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
362                                SmallVectorImpl<MCFixup> &Fixups) const {
363   // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the
364   // msb of the mask.
365   const MCOperand &MO = MI.getOperand(Op);
366   uint32_t v = ~MO.getImm();
367   uint32_t lsb = CountTrailingZeros_32(v);
368   uint32_t msb = (32 - CountLeadingZeros_32 (v)) - 1;
369   assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!");
370   return lsb | (msb << 5);
371 }
372
373 unsigned ARMMCCodeEmitter::
374 getRegisterListOpValue(const MCInst &MI, unsigned Op,
375                        SmallVectorImpl<MCFixup> &Fixups) const {
376   // Convert a list of GPRs into a bitfield (R0 -> bit 0). For each
377   // register in the list, set the corresponding bit.
378   unsigned Binary = 0;
379   for (unsigned i = Op, e = MI.getNumOperands(); i < e; ++i) {
380     unsigned regno = getARMRegisterNumbering(MI.getOperand(i).getReg());
381     Binary |= 1 << regno;
382   }
383   return Binary;
384 }
385
386 unsigned ARMMCCodeEmitter::
387 getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
388                            SmallVectorImpl<MCFixup> &Fixups) const {
389   const MCOperand &Reg = MI.getOperand(Op);
390   const MCOperand &Imm = MI.getOperand(Op + 1);
391
392   unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
393   unsigned Align = 0;
394
395   switch (Imm.getImm()) {
396   default: break;
397   case 2:
398   case 4:
399   case 8:  Align = 0x01; break;
400   case 16: Align = 0x02; break;
401   case 32: Align = 0x03; break;
402   }
403
404   return RegNo | (Align << 4);
405 }
406
407 unsigned ARMMCCodeEmitter::
408 getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
409                           SmallVectorImpl<MCFixup> &Fixups) const {
410   const MCOperand &MO = MI.getOperand(Op);
411   if (MO.getReg() == 0) return 0x0D;
412   return MO.getReg();
413 }
414
415 void ARMMCCodeEmitter::
416 EncodeInstruction(const MCInst &MI, raw_ostream &OS,
417                   SmallVectorImpl<MCFixup> &Fixups) const {
418   // Pseudo instructions don't get encoded.
419   const TargetInstrDesc &Desc = TII.get(MI.getOpcode());
420   if ((Desc.TSFlags & ARMII::FormMask) == ARMII::Pseudo)
421     return;
422
423   EmitConstant(getBinaryCodeForInstr(MI, Fixups), 4, OS);
424   ++MCNumEmitted;  // Keep track of the # of mi's emitted.
425 }
426
427 #include "ARMGenMCCodeEmitter.inc"