Line data Source code
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 : #include "MCTargetDesc/ARMAddressingModes.h"
15 : #include "MCTargetDesc/ARMBaseInfo.h"
16 : #include "MCTargetDesc/ARMFixupKinds.h"
17 : #include "MCTargetDesc/ARMMCExpr.h"
18 : #include "llvm/ADT/APFloat.h"
19 : #include "llvm/ADT/APInt.h"
20 : #include "llvm/ADT/SmallVector.h"
21 : #include "llvm/ADT/Statistic.h"
22 : #include "llvm/ADT/Triple.h"
23 : #include "llvm/MC/MCCodeEmitter.h"
24 : #include "llvm/MC/MCContext.h"
25 : #include "llvm/MC/MCExpr.h"
26 : #include "llvm/MC/MCFixup.h"
27 : #include "llvm/MC/MCInst.h"
28 : #include "llvm/MC/MCInstrDesc.h"
29 : #include "llvm/MC/MCInstrInfo.h"
30 : #include "llvm/MC/MCRegisterInfo.h"
31 : #include "llvm/MC/MCSubtargetInfo.h"
32 : #include "llvm/Support/Casting.h"
33 : #include "llvm/Support/Compiler.h"
34 : #include "llvm/Support/ErrorHandling.h"
35 : #include "llvm/Support/MathExtras.h"
36 : #include "llvm/Support/raw_ostream.h"
37 : #include <algorithm>
38 : #include <cassert>
39 : #include <cstdint>
40 : #include <cstdlib>
41 :
42 : using namespace llvm;
43 :
44 : #define DEBUG_TYPE "mccodeemitter"
45 :
46 : STATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
47 : STATISTIC(MCNumCPRelocations, "Number of constant pool relocations created.");
48 :
49 : namespace {
50 :
51 : class ARMMCCodeEmitter : public MCCodeEmitter {
52 : const MCInstrInfo &MCII;
53 : const MCContext &CTX;
54 : bool IsLittleEndian;
55 :
56 : public:
57 : ARMMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx, bool IsLittle)
58 951 : : MCII(mcii), CTX(ctx), IsLittleEndian(IsLittle) {
59 : }
60 : ARMMCCodeEmitter(const ARMMCCodeEmitter &) = delete;
61 : ARMMCCodeEmitter &operator=(const ARMMCCodeEmitter &) = delete;
62 944 : ~ARMMCCodeEmitter() override = default;
63 :
64 0 : bool isThumb(const MCSubtargetInfo &STI) const {
65 0 : return STI.getFeatureBits()[ARM::ModeThumb];
66 : }
67 :
68 0 : bool isThumb2(const MCSubtargetInfo &STI) const {
69 6191 : return isThumb(STI) && STI.getFeatureBits()[ARM::FeatureThumb2];
70 : }
71 :
72 : bool isTargetMachO(const MCSubtargetInfo &STI) const {
73 : const Triple &TT = STI.getTargetTriple();
74 : return TT.isOSBinFormatMachO();
75 : }
76 :
77 : unsigned getMachineSoImmOpValue(unsigned SoImm) const;
78 :
79 : // getBinaryCodeForInstr - TableGen'erated function for getting the
80 : // binary encoding for an instruction.
81 : uint64_t getBinaryCodeForInstr(const MCInst &MI,
82 : SmallVectorImpl<MCFixup> &Fixups,
83 : const MCSubtargetInfo &STI) const;
84 :
85 : /// getMachineOpValue - Return binary encoding of operand. If the machine
86 : /// operand requires relocation, record the relocation and return zero.
87 : unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
88 : SmallVectorImpl<MCFixup> &Fixups,
89 : const MCSubtargetInfo &STI) const;
90 :
91 : /// getHiLo16ImmOpValue - Return the encoding for the hi / low 16-bit of
92 : /// the specified operand. This is used for operands with :lower16: and
93 : /// :upper16: prefixes.
94 : uint32_t getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
95 : SmallVectorImpl<MCFixup> &Fixups,
96 : const MCSubtargetInfo &STI) const;
97 :
98 : bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx,
99 : unsigned &Reg, unsigned &Imm,
100 : SmallVectorImpl<MCFixup> &Fixups,
101 : const MCSubtargetInfo &STI) const;
102 :
103 : /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate
104 : /// BL branch target.
105 : uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
106 : SmallVectorImpl<MCFixup> &Fixups,
107 : const MCSubtargetInfo &STI) const;
108 :
109 : /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
110 : /// BLX branch target.
111 : uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
112 : SmallVectorImpl<MCFixup> &Fixups,
113 : const MCSubtargetInfo &STI) const;
114 :
115 : /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
116 : uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
117 : SmallVectorImpl<MCFixup> &Fixups,
118 : const MCSubtargetInfo &STI) const;
119 :
120 : /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
121 : uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
122 : SmallVectorImpl<MCFixup> &Fixups,
123 : const MCSubtargetInfo &STI) const;
124 :
125 : /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
126 : uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
127 : SmallVectorImpl<MCFixup> &Fixups,
128 : const MCSubtargetInfo &STI) const;
129 :
130 : /// getBranchTargetOpValue - Return encoding info for 24-bit immediate
131 : /// branch target.
132 : uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
133 : SmallVectorImpl<MCFixup> &Fixups,
134 : const MCSubtargetInfo &STI) const;
135 :
136 : /// getThumbBranchTargetOpValue - Return encoding info for 24-bit
137 : /// immediate Thumb2 direct branch target.
138 : uint32_t getThumbBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
139 : SmallVectorImpl<MCFixup> &Fixups,
140 : const MCSubtargetInfo &STI) const;
141 :
142 : /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate
143 : /// branch target.
144 : uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
145 : SmallVectorImpl<MCFixup> &Fixups,
146 : const MCSubtargetInfo &STI) const;
147 : uint32_t getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
148 : SmallVectorImpl<MCFixup> &Fixups,
149 : const MCSubtargetInfo &STI) const;
150 : uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
151 : SmallVectorImpl<MCFixup> &Fixups,
152 : const MCSubtargetInfo &STI) const;
153 :
154 : /// getAdrLabelOpValue - Return encoding info for 12-bit immediate
155 : /// ADR label target.
156 : uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
157 : SmallVectorImpl<MCFixup> &Fixups,
158 : const MCSubtargetInfo &STI) const;
159 : uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
160 : SmallVectorImpl<MCFixup> &Fixups,
161 : const MCSubtargetInfo &STI) const;
162 : uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
163 : SmallVectorImpl<MCFixup> &Fixups,
164 : const MCSubtargetInfo &STI) const;
165 :
166 :
167 : /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
168 : /// operand.
169 : uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
170 : SmallVectorImpl<MCFixup> &Fixups,
171 : const MCSubtargetInfo &STI) const;
172 :
173 : /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand.
174 : uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
175 : SmallVectorImpl<MCFixup> &Fixups,
176 : const MCSubtargetInfo &STI) const;
177 :
178 : /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2'
179 : /// operand.
180 : uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
181 : SmallVectorImpl<MCFixup> &Fixups,
182 : const MCSubtargetInfo &STI) const;
183 :
184 : /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 'reg + imm8<<2'
185 : /// operand.
186 : uint32_t getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,
187 : SmallVectorImpl<MCFixup> &Fixups,
188 : const MCSubtargetInfo &STI) const;
189 :
190 : /// getT2Imm8s4OpValue - Return encoding info for '+/- imm8<<2'
191 : /// operand.
192 : uint32_t getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx,
193 : SmallVectorImpl<MCFixup> &Fixups,
194 : const MCSubtargetInfo &STI) const;
195 :
196 :
197 : /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm'
198 : /// operand as needed by load/store instructions.
199 : uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
200 : SmallVectorImpl<MCFixup> &Fixups,
201 : const MCSubtargetInfo &STI) const;
202 :
203 : /// getLdStmModeOpValue - Return encoding for load/store multiple mode.
204 : uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx,
205 : SmallVectorImpl<MCFixup> &Fixups,
206 : const MCSubtargetInfo &STI) const {
207 : ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm();
208 : switch (Mode) {
209 : default: llvm_unreachable("Unknown addressing sub-mode!");
210 : case ARM_AM::da: return 0;
211 : case ARM_AM::ia: return 1;
212 : case ARM_AM::db: return 2;
213 : case ARM_AM::ib: return 3;
214 : }
215 : }
216 :
217 : /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
218 : ///
219 0 : unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const {
220 0 : switch (ShOpc) {
221 : case ARM_AM::no_shift:
222 : case ARM_AM::lsl: return 0;
223 0 : case ARM_AM::lsr: return 1;
224 0 : case ARM_AM::asr: return 2;
225 0 : case ARM_AM::ror:
226 0 : case ARM_AM::rrx: return 3;
227 : }
228 0 : llvm_unreachable("Invalid ShiftOpc!");
229 : }
230 :
231 : /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands.
232 : uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
233 : SmallVectorImpl<MCFixup> &Fixups,
234 : const MCSubtargetInfo &STI) const;
235 :
236 : /// getPostIdxRegOpValue - Return encoding for postidx_reg operands.
237 : uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
238 : SmallVectorImpl<MCFixup> &Fixups,
239 : const MCSubtargetInfo &STI) const;
240 :
241 : /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands.
242 : uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
243 : SmallVectorImpl<MCFixup> &Fixups,
244 : const MCSubtargetInfo &STI) const;
245 :
246 : /// getAddrMode3OpValue - Return encoding for addrmode3 operands.
247 : uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
248 : SmallVectorImpl<MCFixup> &Fixups,
249 : const MCSubtargetInfo &STI) const;
250 :
251 : /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12'
252 : /// operand.
253 : uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
254 : SmallVectorImpl<MCFixup> &Fixups,
255 : const MCSubtargetInfo &STI) const;
256 :
257 : /// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
258 : uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
259 : SmallVectorImpl<MCFixup> &Fixups,
260 : const MCSubtargetInfo &STI) const;
261 :
262 : /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
263 : uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
264 : SmallVectorImpl<MCFixup> &Fixups,
265 : const MCSubtargetInfo &STI) const;
266 :
267 : /// getAddrMode5OpValue - Return encoding info for 'reg +/- (imm8 << 2)' operand.
268 : uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
269 : SmallVectorImpl<MCFixup> &Fixups,
270 : const MCSubtargetInfo &STI) const;
271 :
272 : /// getAddrMode5FP16OpValue - Return encoding info for 'reg +/- (imm8 << 1)' operand.
273 : uint32_t getAddrMode5FP16OpValue(const MCInst &MI, unsigned OpIdx,
274 : SmallVectorImpl<MCFixup> &Fixups,
275 : const MCSubtargetInfo &STI) const;
276 :
277 : /// getCCOutOpValue - Return encoding of the 's' bit.
278 0 : unsigned getCCOutOpValue(const MCInst &MI, unsigned Op,
279 : SmallVectorImpl<MCFixup> &Fixups,
280 : const MCSubtargetInfo &STI) const {
281 : // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or
282 : // '1' respectively.
283 6641 : return MI.getOperand(Op).getReg() == ARM::CPSR;
284 : }
285 :
286 : /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value.
287 : unsigned getSOImmOpValue(const MCInst &MI, unsigned Op,
288 : SmallVectorImpl<MCFixup> &Fixups,
289 : const MCSubtargetInfo &STI) const {
290 : const MCOperand &MO = MI.getOperand(Op);
291 :
292 : // We expect MO to be an immediate or an expression,
293 : // if it is an immediate - that's fine, just encode the value.
294 : // Otherwise - create a Fixup.
295 : if (MO.isExpr()) {
296 : const MCExpr *Expr = MO.getExpr();
297 : // In instruction code this value always encoded as lowest 12 bits,
298 : // so we don't have to perform any specific adjustments.
299 : // Due to requirements of relocatable records we have to use FK_Data_4.
300 : // See ARMELFObjectWriter::ExplicitRelSym and
301 : // ARMELFObjectWriter::GetRelocTypeInner for more details.
302 : MCFixupKind Kind = MCFixupKind(FK_Data_4);
303 : Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
304 : return 0;
305 : }
306 :
307 : unsigned SoImm = MO.getImm();
308 : int SoImmVal = ARM_AM::getSOImmVal(SoImm);
309 : assert(SoImmVal != -1 && "Not a valid so_imm value!");
310 :
311 : // Encode rotate_imm.
312 : unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1)
313 : << ARMII::SoRotImmShift;
314 :
315 : // Encode immed_8.
316 : Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
317 : return Binary;
318 : }
319 :
320 0 : unsigned getModImmOpValue(const MCInst &MI, unsigned Op,
321 : SmallVectorImpl<MCFixup> &Fixups,
322 : const MCSubtargetInfo &ST) const {
323 : const MCOperand &MO = MI.getOperand(Op);
324 :
325 : // Support for fixups (MCFixup)
326 0 : if (MO.isExpr()) {
327 0 : const MCExpr *Expr = MO.getExpr();
328 : // Fixups resolve to plain values that need to be encoded.
329 : MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_mod_imm);
330 0 : Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
331 0 : return 0;
332 : }
333 :
334 : // Immediate is already in its encoded format
335 0 : return MO.getImm();
336 : }
337 :
338 : /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value.
339 0 : unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op,
340 : SmallVectorImpl<MCFixup> &Fixups,
341 : const MCSubtargetInfo &STI) const {
342 : const MCOperand &MO = MI.getOperand(Op);
343 :
344 : // Support for fixups (MCFixup)
345 0 : if (MO.isExpr()) {
346 0 : const MCExpr *Expr = MO.getExpr();
347 : // Fixups resolve to plain values that need to be encoded.
348 : MCFixupKind Kind = MCFixupKind(ARM::fixup_t2_so_imm);
349 0 : Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
350 0 : return 0;
351 : }
352 0 : unsigned SoImm = MO.getImm();
353 0 : unsigned Encoded = ARM_AM::getT2SOImmVal(SoImm);
354 : assert(Encoded != ~0U && "Not a Thumb2 so_imm value?");
355 0 : return Encoded;
356 : }
357 :
358 : unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
359 : SmallVectorImpl<MCFixup> &Fixups,
360 : const MCSubtargetInfo &STI) const;
361 : unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
362 : SmallVectorImpl<MCFixup> &Fixups,
363 : const MCSubtargetInfo &STI) const;
364 : unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
365 : SmallVectorImpl<MCFixup> &Fixups,
366 : const MCSubtargetInfo &STI) const;
367 :
368 : /// getSORegOpValue - Return an encoded so_reg shifted register value.
369 : unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op,
370 : SmallVectorImpl<MCFixup> &Fixups,
371 : const MCSubtargetInfo &STI) const;
372 : unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op,
373 : SmallVectorImpl<MCFixup> &Fixups,
374 : const MCSubtargetInfo &STI) const;
375 : unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,
376 : SmallVectorImpl<MCFixup> &Fixups,
377 : const MCSubtargetInfo &STI) const;
378 :
379 0 : unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op,
380 : SmallVectorImpl<MCFixup> &Fixups,
381 : const MCSubtargetInfo &STI) const {
382 56 : return 64 - MI.getOperand(Op).getImm();
383 : }
384 :
385 : unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
386 : SmallVectorImpl<MCFixup> &Fixups,
387 : const MCSubtargetInfo &STI) const;
388 :
389 : unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op,
390 : SmallVectorImpl<MCFixup> &Fixups,
391 : const MCSubtargetInfo &STI) const;
392 : unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
393 : SmallVectorImpl<MCFixup> &Fixups,
394 : const MCSubtargetInfo &STI) const;
395 : unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
396 : SmallVectorImpl<MCFixup> &Fixups,
397 : const MCSubtargetInfo &STI) const;
398 : unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
399 : SmallVectorImpl<MCFixup> &Fixups,
400 : const MCSubtargetInfo &STI) const;
401 : unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
402 : SmallVectorImpl<MCFixup> &Fixups,
403 : const MCSubtargetInfo &STI) const;
404 :
405 : unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op,
406 : SmallVectorImpl<MCFixup> &Fixups,
407 : const MCSubtargetInfo &STI) const;
408 : unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op,
409 : SmallVectorImpl<MCFixup> &Fixups,
410 : const MCSubtargetInfo &STI) const;
411 : unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op,
412 : SmallVectorImpl<MCFixup> &Fixups,
413 : const MCSubtargetInfo &STI) const;
414 : unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op,
415 : SmallVectorImpl<MCFixup> &Fixups,
416 : const MCSubtargetInfo &STI) const;
417 :
418 : unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op,
419 : SmallVectorImpl<MCFixup> &Fixups,
420 : const MCSubtargetInfo &STI) const;
421 :
422 : unsigned NEONThumb2DataIPostEncoder(const MCInst &MI,
423 : unsigned EncodedValue,
424 : const MCSubtargetInfo &STI) const;
425 : unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI,
426 : unsigned EncodedValue,
427 : const MCSubtargetInfo &STI) const;
428 : unsigned NEONThumb2DupPostEncoder(const MCInst &MI,
429 : unsigned EncodedValue,
430 : const MCSubtargetInfo &STI) const;
431 : unsigned NEONThumb2V8PostEncoder(const MCInst &MI,
432 : unsigned EncodedValue,
433 : const MCSubtargetInfo &STI) const;
434 :
435 : unsigned VFPThumb2PostEncoder(const MCInst &MI,
436 : unsigned EncodedValue,
437 : const MCSubtargetInfo &STI) const;
438 :
439 : void EmitByte(unsigned char C, raw_ostream &OS) const {
440 0 : OS << (char)C;
441 : }
442 :
443 0 : void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const {
444 : // Output the constant in little endian byte order.
445 0 : for (unsigned i = 0; i != Size; ++i) {
446 0 : unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
447 0 : EmitByte((Val >> Shift) & 0xff, OS);
448 : }
449 0 : }
450 :
451 : void encodeInstruction(const MCInst &MI, raw_ostream &OS,
452 : SmallVectorImpl<MCFixup> &Fixups,
453 : const MCSubtargetInfo &STI) const override;
454 : };
455 :
456 : } // end anonymous namespace
457 :
458 : /// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing
459 : /// instructions, and rewrite them to their Thumb2 form if we are currently in
460 : /// Thumb2 mode.
461 0 : unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,
462 : unsigned EncodedValue,
463 : const MCSubtargetInfo &STI) const {
464 : if (isThumb2(STI)) {
465 : // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved
466 : // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are
467 : // set to 1111.
468 : unsigned Bit24 = EncodedValue & 0x01000000;
469 1004 : unsigned Bit28 = Bit24 << 4;
470 1004 : EncodedValue &= 0xEFFFFFFF;
471 1004 : EncodedValue |= Bit28;
472 1004 : EncodedValue |= 0x0F000000;
473 : }
474 :
475 0 : return EncodedValue;
476 : }
477 :
478 : /// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store
479 : /// instructions, and rewrite them to their Thumb2 form if we are currently in
480 : /// Thumb2 mode.
481 0 : unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,
482 : unsigned EncodedValue,
483 : const MCSubtargetInfo &STI) const {
484 : if (isThumb2(STI)) {
485 1196 : EncodedValue &= 0xF0FFFFFF;
486 1196 : EncodedValue |= 0x09000000;
487 : }
488 :
489 0 : return EncodedValue;
490 : }
491 :
492 : /// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup
493 : /// instructions, and rewrite them to their Thumb2 form if we are currently in
494 : /// Thumb2 mode.
495 0 : unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
496 : unsigned EncodedValue,
497 : const MCSubtargetInfo &STI) const {
498 : if (isThumb2(STI)) {
499 29 : EncodedValue &= 0x00FFFFFF;
500 29 : EncodedValue |= 0xEE000000;
501 : }
502 :
503 0 : return EncodedValue;
504 : }
505 :
506 : /// Post-process encoded NEON v8 instructions, and rewrite them to Thumb2 form
507 : /// if we are in Thumb2.
508 0 : unsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI,
509 : unsigned EncodedValue,
510 : const MCSubtargetInfo &STI) const {
511 : if (isThumb2(STI)) {
512 101 : EncodedValue |= 0xC000000; // Set bits 27-26
513 : }
514 :
515 0 : return EncodedValue;
516 : }
517 :
518 : /// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite
519 : /// them to their Thumb2 form if we are currently in Thumb2 mode.
520 0 : unsigned ARMMCCodeEmitter::
521 : VFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue,
522 : const MCSubtargetInfo &STI) const {
523 : if (isThumb2(STI)) {
524 686 : EncodedValue &= 0x0FFFFFFF;
525 686 : EncodedValue |= 0xE0000000;
526 : }
527 0 : return EncodedValue;
528 : }
529 :
530 : /// getMachineOpValue - Return binary encoding of operand. If the machine
531 : /// operand requires relocation, record the relocation and return zero.
532 0 : unsigned ARMMCCodeEmitter::
533 : getMachineOpValue(const MCInst &MI, const MCOperand &MO,
534 : SmallVectorImpl<MCFixup> &Fixups,
535 : const MCSubtargetInfo &STI) const {
536 0 : if (MO.isReg()) {
537 0 : unsigned Reg = MO.getReg();
538 0 : unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg);
539 :
540 : // Q registers are encoded as 2x their register number.
541 0 : switch (Reg) {
542 0 : default:
543 0 : return RegNo;
544 0 : case ARM::Q0: case ARM::Q1: case ARM::Q2: case ARM::Q3:
545 : case ARM::Q4: case ARM::Q5: case ARM::Q6: case ARM::Q7:
546 : case ARM::Q8: case ARM::Q9: case ARM::Q10: case ARM::Q11:
547 : case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15:
548 0 : return 2 * RegNo;
549 : }
550 0 : } else if (MO.isImm()) {
551 0 : return static_cast<unsigned>(MO.getImm());
552 0 : } else if (MO.isFPImm()) {
553 0 : return static_cast<unsigned>(APFloat(MO.getFPImm())
554 0 : .bitcastToAPInt().getHiBits(32).getLimitedValue());
555 : }
556 :
557 0 : llvm_unreachable("Unable to encode MCOperand!");
558 : }
559 :
560 : /// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand.
561 0 : bool ARMMCCodeEmitter::
562 : EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg,
563 : unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups,
564 : const MCSubtargetInfo &STI) const {
565 : const MCOperand &MO = MI.getOperand(OpIdx);
566 0 : const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
567 :
568 3804 : Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
569 :
570 3804 : int32_t SImm = MO1.getImm();
571 : bool isAdd = true;
572 :
573 : // Special value for #-0
574 3804 : if (SImm == INT32_MIN) {
575 : SImm = 0;
576 : isAdd = false;
577 : }
578 :
579 : // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
580 3802 : if (SImm < 0) {
581 9 : SImm = -SImm;
582 : isAdd = false;
583 : }
584 :
585 3804 : Imm = SImm;
586 0 : return isAdd;
587 : }
588 :
589 : /// getBranchTargetOpValue - Helper function to get the branch target operand,
590 : /// which is either an immediate or requires a fixup.
591 0 : static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
592 : unsigned FixupKind,
593 : SmallVectorImpl<MCFixup> &Fixups,
594 : const MCSubtargetInfo &STI) {
595 : const MCOperand &MO = MI.getOperand(OpIdx);
596 :
597 : // If the destination is an immediate, we have nothing to do.
598 0 : if (MO.isImm()) return MO.getImm();
599 : assert(MO.isExpr() && "Unexpected branch target type!");
600 0 : const MCExpr *Expr = MO.getExpr();
601 : MCFixupKind Kind = MCFixupKind(FixupKind);
602 0 : Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
603 :
604 : // All of the information is in the fixup.
605 0 : return 0;
606 : }
607 :
608 : // Thumb BL and BLX use a strange offset encoding where bits 22 and 21 are
609 : // determined by negating them and XOR'ing them with bit 23.
610 : static int32_t encodeThumbBLOffset(int32_t offset) {
611 0 : offset >>= 1;
612 0 : uint32_t S = (offset & 0x800000) >> 23;
613 0 : uint32_t J1 = (offset & 0x400000) >> 22;
614 0 : uint32_t J2 = (offset & 0x200000) >> 21;
615 0 : J1 = (~J1 & 0x1);
616 0 : J2 = (~J2 & 0x1);
617 0 : J1 ^= S;
618 0 : J2 ^= S;
619 :
620 0 : offset &= ~0x600000;
621 0 : offset |= J1 << 22;
622 0 : offset |= J2 << 21;
623 :
624 : return offset;
625 : }
626 :
627 : /// getThumbBLTargetOpValue - Return encoding info for immediate branch target.
628 0 : uint32_t ARMMCCodeEmitter::
629 : getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
630 : SmallVectorImpl<MCFixup> &Fixups,
631 : const MCSubtargetInfo &STI) const {
632 0 : const MCOperand MO = MI.getOperand(OpIdx);
633 0 : if (MO.isExpr())
634 0 : return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl,
635 0 : Fixups, STI);
636 0 : return encodeThumbBLOffset(MO.getImm());
637 : }
638 :
639 : /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
640 : /// BLX branch target.
641 0 : uint32_t ARMMCCodeEmitter::
642 : getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
643 : SmallVectorImpl<MCFixup> &Fixups,
644 : const MCSubtargetInfo &STI) const {
645 0 : const MCOperand MO = MI.getOperand(OpIdx);
646 0 : if (MO.isExpr())
647 0 : return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx,
648 0 : Fixups, STI);
649 0 : return encodeThumbBLOffset(MO.getImm());
650 : }
651 :
652 : /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
653 0 : uint32_t ARMMCCodeEmitter::
654 : getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
655 : SmallVectorImpl<MCFixup> &Fixups,
656 : const MCSubtargetInfo &STI) const {
657 0 : const MCOperand MO = MI.getOperand(OpIdx);
658 0 : if (MO.isExpr())
659 0 : return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br,
660 0 : Fixups, STI);
661 0 : return (MO.getImm() >> 1);
662 : }
663 :
664 : /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
665 0 : uint32_t ARMMCCodeEmitter::
666 : getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
667 : SmallVectorImpl<MCFixup> &Fixups,
668 : const MCSubtargetInfo &STI) const {
669 0 : const MCOperand MO = MI.getOperand(OpIdx);
670 0 : if (MO.isExpr())
671 0 : return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc,
672 0 : Fixups, STI);
673 0 : return (MO.getImm() >> 1);
674 : }
675 :
676 : /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
677 0 : uint32_t ARMMCCodeEmitter::
678 : getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
679 : SmallVectorImpl<MCFixup> &Fixups,
680 : const MCSubtargetInfo &STI) const {
681 0 : const MCOperand MO = MI.getOperand(OpIdx);
682 0 : if (MO.isExpr())
683 0 : return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups, STI);
684 0 : return (MO.getImm() >> 1);
685 : }
686 :
687 : /// Return true if this branch has a non-always predication
688 1021 : static bool HasConditionalBranch(const MCInst &MI) {
689 1021 : int NumOp = MI.getNumOperands();
690 1021 : if (NumOp >= 2) {
691 833 : for (int i = 0; i < NumOp-1; ++i) {
692 625 : const MCOperand &MCOp1 = MI.getOperand(i);
693 625 : const MCOperand &MCOp2 = MI.getOperand(i + 1);
694 625 : if (MCOp1.isImm() && MCOp2.isReg() &&
695 312 : (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) {
696 312 : if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL)
697 : return true;
698 : }
699 : }
700 : }
701 : return false;
702 : }
703 :
704 : /// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
705 : /// target.
706 0 : uint32_t ARMMCCodeEmitter::
707 : getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
708 : SmallVectorImpl<MCFixup> &Fixups,
709 : const MCSubtargetInfo &STI) const {
710 : // FIXME: This really, really shouldn't use TargetMachine. We don't want
711 : // coupling between MC and TM anywhere we can help it.
712 : if (isThumb2(STI))
713 : return
714 0 : ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups, STI);
715 0 : return getARMBranchTargetOpValue(MI, OpIdx, Fixups, STI);
716 : }
717 :
718 : /// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
719 : /// target.
720 0 : uint32_t ARMMCCodeEmitter::
721 : getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
722 : SmallVectorImpl<MCFixup> &Fixups,
723 : const MCSubtargetInfo &STI) const {
724 0 : const MCOperand MO = MI.getOperand(OpIdx);
725 0 : if (MO.isExpr()) {
726 0 : if (HasConditionalBranch(MI))
727 0 : return ::getBranchTargetOpValue(MI, OpIdx,
728 0 : ARM::fixup_arm_condbranch, Fixups, STI);
729 0 : return ::getBranchTargetOpValue(MI, OpIdx,
730 0 : ARM::fixup_arm_uncondbranch, Fixups, STI);
731 : }
732 :
733 0 : return MO.getImm() >> 2;
734 : }
735 :
736 0 : uint32_t ARMMCCodeEmitter::
737 : getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
738 : SmallVectorImpl<MCFixup> &Fixups,
739 : const MCSubtargetInfo &STI) const {
740 0 : const MCOperand MO = MI.getOperand(OpIdx);
741 0 : if (MO.isExpr()) {
742 0 : if (HasConditionalBranch(MI))
743 0 : return ::getBranchTargetOpValue(MI, OpIdx,
744 0 : ARM::fixup_arm_condbl, Fixups, STI);
745 0 : return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbl, Fixups, STI);
746 : }
747 :
748 0 : return MO.getImm() >> 2;
749 : }
750 :
751 0 : uint32_t ARMMCCodeEmitter::
752 : getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
753 : SmallVectorImpl<MCFixup> &Fixups,
754 : const MCSubtargetInfo &STI) const {
755 0 : const MCOperand MO = MI.getOperand(OpIdx);
756 0 : if (MO.isExpr())
757 0 : return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_blx, Fixups, STI);
758 :
759 0 : return MO.getImm() >> 1;
760 : }
761 :
762 : /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
763 : /// immediate branch target.
764 0 : uint32_t ARMMCCodeEmitter::getThumbBranchTargetOpValue(
765 : const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
766 : const MCSubtargetInfo &STI) const {
767 : unsigned Val = 0;
768 0 : const MCOperand MO = MI.getOperand(OpIdx);
769 :
770 0 : if(MO.isExpr())
771 0 : return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups, STI);
772 : else
773 0 : Val = MO.getImm() >> 1;
774 :
775 0 : bool I = (Val & 0x800000);
776 0 : bool J1 = (Val & 0x400000);
777 0 : bool J2 = (Val & 0x200000);
778 0 : if (I ^ J1)
779 0 : Val &= ~0x400000;
780 : else
781 0 : Val |= 0x400000;
782 :
783 0 : if (I ^ J2)
784 0 : Val &= ~0x200000;
785 : else
786 0 : Val |= 0x200000;
787 :
788 : return Val;
789 : }
790 :
791 : /// getAdrLabelOpValue - Return encoding info for 12-bit shifted-immediate
792 : /// ADR label target.
793 0 : uint32_t ARMMCCodeEmitter::
794 : getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
795 : SmallVectorImpl<MCFixup> &Fixups,
796 : const MCSubtargetInfo &STI) const {
797 0 : const MCOperand MO = MI.getOperand(OpIdx);
798 0 : if (MO.isExpr())
799 0 : return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12,
800 0 : Fixups, STI);
801 : int64_t offset = MO.getImm();
802 : uint32_t Val = 0x2000;
803 :
804 : int SoImmVal;
805 0 : if (offset == INT32_MIN) {
806 : Val = 0x1000;
807 : SoImmVal = 0;
808 0 : } else if (offset < 0) {
809 : Val = 0x1000;
810 0 : offset *= -1;
811 0 : SoImmVal = ARM_AM::getSOImmVal(offset);
812 0 : if(SoImmVal == -1) {
813 : Val = 0x2000;
814 : offset *= -1;
815 0 : SoImmVal = ARM_AM::getSOImmVal(offset);
816 : }
817 : } else {
818 0 : SoImmVal = ARM_AM::getSOImmVal(offset);
819 0 : if(SoImmVal == -1) {
820 : Val = 0x1000;
821 0 : offset *= -1;
822 0 : SoImmVal = ARM_AM::getSOImmVal(offset);
823 : }
824 : }
825 :
826 : assert(SoImmVal != -1 && "Not a valid so_imm value!");
827 :
828 0 : Val |= SoImmVal;
829 0 : return Val;
830 : }
831 :
832 : /// getT2AdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
833 : /// target.
834 0 : uint32_t ARMMCCodeEmitter::
835 : getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
836 : SmallVectorImpl<MCFixup> &Fixups,
837 : const MCSubtargetInfo &STI) const {
838 0 : const MCOperand MO = MI.getOperand(OpIdx);
839 0 : if (MO.isExpr())
840 0 : return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12,
841 0 : Fixups, STI);
842 0 : int32_t Val = MO.getImm();
843 0 : if (Val == INT32_MIN)
844 : Val = 0x1000;
845 0 : else if (Val < 0) {
846 0 : Val *= -1;
847 0 : Val |= 0x1000;
848 : }
849 0 : return Val;
850 : }
851 :
852 : /// getThumbAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label
853 : /// target.
854 0 : uint32_t ARMMCCodeEmitter::
855 : getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
856 : SmallVectorImpl<MCFixup> &Fixups,
857 : const MCSubtargetInfo &STI) const {
858 26 : const MCOperand MO = MI.getOperand(OpIdx);
859 26 : if (MO.isExpr())
860 13 : return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10,
861 0 : Fixups, STI);
862 13 : return MO.getImm();
863 : }
864 :
865 : /// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg'
866 : /// operand.
867 0 : uint32_t ARMMCCodeEmitter::
868 : getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
869 : SmallVectorImpl<MCFixup> &,
870 : const MCSubtargetInfo &STI) const {
871 : // [Rn, Rm]
872 : // {5-3} = Rm
873 : // {2-0} = Rn
874 : const MCOperand &MO1 = MI.getOperand(OpIdx);
875 0 : const MCOperand &MO2 = MI.getOperand(OpIdx + 1);
876 44 : unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
877 44 : unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO2.getReg());
878 44 : return (Rm << 3) | Rn;
879 : }
880 :
881 : /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand.
882 3298 : uint32_t ARMMCCodeEmitter::
883 : getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
884 : SmallVectorImpl<MCFixup> &Fixups,
885 : const MCSubtargetInfo &STI) const {
886 : // {17-13} = reg
887 : // {12} = (U)nsigned (add == '1', sub == '0')
888 : // {11-0} = imm12
889 : unsigned Reg, Imm12;
890 : bool isAdd = true;
891 : // If The first operand isn't a register, we have a label reference.
892 : const MCOperand &MO = MI.getOperand(OpIdx);
893 3298 : if (!MO.isReg()) {
894 106 : Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC.
895 : Imm12 = 0;
896 :
897 106 : if (MO.isExpr()) {
898 58 : const MCExpr *Expr = MO.getExpr();
899 : isAdd = false ; // 'U' bit is set as part of the fixup.
900 :
901 : MCFixupKind Kind;
902 : if (isThumb2(STI))
903 : Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12);
904 : else
905 : Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12);
906 116 : Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
907 :
908 : ++MCNumCPRelocations;
909 : } else {
910 : Reg = ARM::PC;
911 48 : int32_t Offset = MO.getImm();
912 48 : if (Offset == INT32_MIN) {
913 : Offset = 0;
914 : isAdd = false;
915 32 : } else if (Offset < 0) {
916 32 : Offset *= -1;
917 : isAdd = false;
918 : }
919 48 : Imm12 = Offset;
920 : }
921 : } else
922 3192 : isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups, STI);
923 :
924 3298 : uint32_t Binary = Imm12 & 0xfff;
925 : // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
926 3298 : if (isAdd)
927 3181 : Binary |= (1 << 12);
928 3298 : Binary |= (Reg << 13);
929 3298 : return Binary;
930 : }
931 :
932 : /// getT2Imm8s4OpValue - Return encoding info for
933 : /// '+/- imm8<<2' operand.
934 0 : uint32_t ARMMCCodeEmitter::
935 : getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx,
936 : SmallVectorImpl<MCFixup> &Fixups,
937 : const MCSubtargetInfo &STI) const {
938 : // FIXME: The immediate operand should have already been encoded like this
939 : // before ever getting here. The encoder method should just need to combine
940 : // the MI operands for the register and the offset into a single
941 : // representation for the complex operand in the .td file. This isn't just
942 : // style, unfortunately. As-is, we can't represent the distinct encoding
943 : // for #-0.
944 :
945 : // {8} = (U)nsigned (add == '1', sub == '0')
946 : // {7-0} = imm8
947 48 : int32_t Imm8 = MI.getOperand(OpIdx).getImm();
948 : bool isAdd = Imm8 >= 0;
949 :
950 : // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
951 48 : if (Imm8 < 0)
952 23 : Imm8 = -(uint32_t)Imm8;
953 :
954 : // Scaled by 4.
955 48 : Imm8 /= 4;
956 :
957 48 : uint32_t Binary = Imm8 & 0xff;
958 : // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
959 48 : if (isAdd)
960 25 : Binary |= (1 << 8);
961 0 : return Binary;
962 : }
963 :
964 : /// getT2AddrModeImm8s4OpValue - Return encoding info for
965 : /// 'reg +/- imm8<<2' operand.
966 0 : uint32_t ARMMCCodeEmitter::
967 : getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
968 : SmallVectorImpl<MCFixup> &Fixups,
969 : const MCSubtargetInfo &STI) const {
970 : // {12-9} = reg
971 : // {8} = (U)nsigned (add == '1', sub == '0')
972 : // {7-0} = imm8
973 : unsigned Reg, Imm8;
974 : bool isAdd = true;
975 : // If The first operand isn't a register, we have a label reference.
976 : const MCOperand &MO = MI.getOperand(OpIdx);
977 0 : if (!MO.isReg()) {
978 0 : Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC.
979 : Imm8 = 0;
980 : isAdd = false ; // 'U' bit is set as part of the fixup.
981 :
982 : assert(MO.isExpr() && "Unexpected machine operand type!");
983 0 : const MCExpr *Expr = MO.getExpr();
984 : MCFixupKind Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
985 0 : Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
986 :
987 : ++MCNumCPRelocations;
988 : } else
989 0 : isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI);
990 :
991 : // FIXME: The immediate operand should have already been encoded like this
992 : // before ever getting here. The encoder method should just need to combine
993 : // the MI operands for the register and the offset into a single
994 : // representation for the complex operand in the .td file. This isn't just
995 : // style, unfortunately. As-is, we can't represent the distinct encoding
996 : // for #-0.
997 0 : uint32_t Binary = (Imm8 >> 2) & 0xff;
998 : // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
999 0 : if (isAdd)
1000 0 : Binary |= (1 << 8);
1001 0 : Binary |= (Reg << 9);
1002 0 : return Binary;
1003 : }
1004 :
1005 : /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for
1006 : /// 'reg + imm8<<2' operand.
1007 0 : uint32_t ARMMCCodeEmitter::
1008 : getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,
1009 : SmallVectorImpl<MCFixup> &Fixups,
1010 : const MCSubtargetInfo &STI) const {
1011 : // {11-8} = reg
1012 : // {7-0} = imm8
1013 : const MCOperand &MO = MI.getOperand(OpIdx);
1014 0 : const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1015 34 : unsigned Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1016 34 : unsigned Imm8 = MO1.getImm();
1017 34 : return (Reg << 8) | Imm8;
1018 : }
1019 :
1020 : uint32_t
1021 0 : ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
1022 : SmallVectorImpl<MCFixup> &Fixups,
1023 : const MCSubtargetInfo &STI) const {
1024 : // {20-16} = imm{15-12}
1025 : // {11-0} = imm{11-0}
1026 : const MCOperand &MO = MI.getOperand(OpIdx);
1027 0 : if (MO.isImm())
1028 : // Hi / lo 16 bits already extracted during earlier passes.
1029 0 : return static_cast<unsigned>(MO.getImm());
1030 :
1031 : // Handle :upper16: and :lower16: assembly prefixes.
1032 0 : const MCExpr *E = MO.getExpr();
1033 : MCFixupKind Kind;
1034 0 : if (E->getKind() == MCExpr::Target) {
1035 : const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E);
1036 0 : E = ARM16Expr->getSubExpr();
1037 :
1038 : if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(E)) {
1039 0 : const int64_t Value = MCE->getValue();
1040 0 : if (Value > UINT32_MAX)
1041 0 : report_fatal_error("constant value truncated (limited to 32-bit)");
1042 :
1043 0 : switch (ARM16Expr->getKind()) {
1044 0 : case ARMMCExpr::VK_ARM_HI16:
1045 0 : return (int32_t(Value) & 0xffff0000) >> 16;
1046 0 : case ARMMCExpr::VK_ARM_LO16:
1047 0 : return (int32_t(Value) & 0x0000ffff);
1048 0 : default: llvm_unreachable("Unsupported ARMFixup");
1049 : }
1050 : }
1051 :
1052 0 : switch (ARM16Expr->getKind()) {
1053 0 : default: llvm_unreachable("Unsupported ARMFixup");
1054 : case ARMMCExpr::VK_ARM_HI16:
1055 0 : Kind = MCFixupKind(isThumb(STI) ? ARM::fixup_t2_movt_hi16
1056 : : ARM::fixup_arm_movt_hi16);
1057 : break;
1058 : case ARMMCExpr::VK_ARM_LO16:
1059 0 : Kind = MCFixupKind(isThumb(STI) ? ARM::fixup_t2_movw_lo16
1060 : : ARM::fixup_arm_movw_lo16);
1061 : break;
1062 : }
1063 :
1064 0 : Fixups.push_back(MCFixup::create(0, E, Kind, MI.getLoc()));
1065 0 : return 0;
1066 : }
1067 : // If the expression doesn't have :upper16: or :lower16: on it,
1068 : // it's just a plain immediate expression, previously those evaluated to
1069 : // the lower 16 bits of the expression regardless of whether
1070 : // we have a movt or a movw, but that led to misleadingly results.
1071 : // This is disallowed in the AsmParser in validateInstruction()
1072 : // so this should never happen.
1073 0 : llvm_unreachable("expression without :upper16: or :lower16:");
1074 : }
1075 :
1076 0 : uint32_t ARMMCCodeEmitter::
1077 : getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
1078 : SmallVectorImpl<MCFixup> &Fixups,
1079 : const MCSubtargetInfo &STI) const {
1080 : const MCOperand &MO = MI.getOperand(OpIdx);
1081 0 : const MCOperand &MO1 = MI.getOperand(OpIdx+1);
1082 0 : const MCOperand &MO2 = MI.getOperand(OpIdx+2);
1083 0 : unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1084 0 : unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
1085 0 : unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm());
1086 : bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add;
1087 : ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
1088 : unsigned SBits = getShiftOp(ShOp);
1089 :
1090 : // While "lsr #32" and "asr #32" exist, they are encoded with a 0 in the shift
1091 : // amount. However, it would be an easy mistake to make so check here.
1092 : assert((ShImm & ~0x1f) == 0 && "Out of range shift amount");
1093 :
1094 : // {16-13} = Rn
1095 : // {12} = isAdd
1096 : // {11-0} = shifter
1097 : // {3-0} = Rm
1098 : // {4} = 0
1099 : // {6-5} = type
1100 : // {11-7} = imm
1101 : uint32_t Binary = Rm;
1102 0 : Binary |= Rn << 13;
1103 0 : Binary |= SBits << 5;
1104 0 : Binary |= ShImm << 7;
1105 0 : if (isAdd)
1106 0 : Binary |= 1 << 12;
1107 0 : return Binary;
1108 : }
1109 :
1110 0 : uint32_t ARMMCCodeEmitter::
1111 : getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
1112 : SmallVectorImpl<MCFixup> &Fixups,
1113 : const MCSubtargetInfo &STI) const {
1114 : // {13} 1 == imm12, 0 == Rm
1115 : // {12} isAdd
1116 : // {11-0} imm12/Rm
1117 : const MCOperand &MO = MI.getOperand(OpIdx);
1118 0 : const MCOperand &MO1 = MI.getOperand(OpIdx+1);
1119 0 : unsigned Imm = MO1.getImm();
1120 0 : bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add;
1121 0 : bool isReg = MO.getReg() != 0;
1122 : uint32_t Binary = ARM_AM::getAM2Offset(Imm);
1123 : // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12
1124 0 : if (isReg) {
1125 : ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm);
1126 0 : Binary <<= 7; // Shift amount is bits [11:7]
1127 0 : Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5]
1128 0 : Binary |= CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); // Rm is bits [3:0]
1129 : }
1130 0 : return Binary | (isAdd << 12) | (isReg << 13);
1131 : }
1132 :
1133 0 : uint32_t ARMMCCodeEmitter::
1134 : getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
1135 : SmallVectorImpl<MCFixup> &Fixups,
1136 : const MCSubtargetInfo &STI) const {
1137 : // {4} isAdd
1138 : // {3-0} Rm
1139 : const MCOperand &MO = MI.getOperand(OpIdx);
1140 0 : const MCOperand &MO1 = MI.getOperand(OpIdx+1);
1141 12 : bool isAdd = MO1.getImm() != 0;
1142 24 : return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()) | (isAdd << 4);
1143 : }
1144 :
1145 0 : uint32_t ARMMCCodeEmitter::
1146 : getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
1147 : SmallVectorImpl<MCFixup> &Fixups,
1148 : const MCSubtargetInfo &STI) const {
1149 : // {9} 1 == imm8, 0 == Rm
1150 : // {8} isAdd
1151 : // {7-4} imm7_4/zero
1152 : // {3-0} imm3_0/Rm
1153 : const MCOperand &MO = MI.getOperand(OpIdx);
1154 0 : const MCOperand &MO1 = MI.getOperand(OpIdx+1);
1155 0 : unsigned Imm = MO1.getImm();
1156 0 : bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
1157 0 : bool isImm = MO.getReg() == 0;
1158 0 : uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
1159 : // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
1160 0 : if (!isImm)
1161 0 : Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1162 0 : return Imm8 | (isAdd << 8) | (isImm << 9);
1163 : }
1164 :
1165 0 : uint32_t ARMMCCodeEmitter::
1166 : getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
1167 : SmallVectorImpl<MCFixup> &Fixups,
1168 : const MCSubtargetInfo &STI) const {
1169 : // {13} 1 == imm8, 0 == Rm
1170 : // {12-9} Rn
1171 : // {8} isAdd
1172 : // {7-4} imm7_4/zero
1173 : // {3-0} imm3_0/Rm
1174 : const MCOperand &MO = MI.getOperand(OpIdx);
1175 0 : const MCOperand &MO1 = MI.getOperand(OpIdx+1);
1176 0 : const MCOperand &MO2 = MI.getOperand(OpIdx+2);
1177 :
1178 : // If The first operand isn't a register, we have a label reference.
1179 0 : if (!MO.isReg()) {
1180 0 : unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC.
1181 :
1182 : assert(MO.isExpr() && "Unexpected machine operand type!");
1183 0 : const MCExpr *Expr = MO.getExpr();
1184 : MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10_unscaled);
1185 0 : Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
1186 :
1187 : ++MCNumCPRelocations;
1188 0 : return (Rn << 9) | (1 << 13);
1189 : }
1190 0 : unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1191 0 : unsigned Imm = MO2.getImm();
1192 0 : bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
1193 0 : bool isImm = MO1.getReg() == 0;
1194 0 : uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
1195 : // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
1196 0 : if (!isImm)
1197 0 : Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
1198 0 : return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13);
1199 : }
1200 :
1201 : /// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands.
1202 0 : uint32_t ARMMCCodeEmitter::
1203 : getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
1204 : SmallVectorImpl<MCFixup> &Fixups,
1205 : const MCSubtargetInfo &STI) const {
1206 : // [SP, #imm]
1207 : // {7-0} = imm8
1208 0 : const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1209 : assert(MI.getOperand(OpIdx).getReg() == ARM::SP &&
1210 : "Unexpected base register!");
1211 :
1212 : // The immediate is already shifted for the implicit zeroes, so no change
1213 : // here.
1214 924 : return MO1.getImm() & 0xff;
1215 : }
1216 :
1217 : /// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
1218 0 : uint32_t ARMMCCodeEmitter::
1219 : getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
1220 : SmallVectorImpl<MCFixup> &Fixups,
1221 : const MCSubtargetInfo &STI) const {
1222 : // [Rn, #imm]
1223 : // {7-3} = imm5
1224 : // {2-0} = Rn
1225 : const MCOperand &MO = MI.getOperand(OpIdx);
1226 0 : const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1227 2203 : unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1228 2203 : unsigned Imm5 = MO1.getImm();
1229 2203 : return ((Imm5 & 0x1f) << 3) | Rn;
1230 : }
1231 :
1232 : /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
1233 0 : uint32_t ARMMCCodeEmitter::
1234 : getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
1235 : SmallVectorImpl<MCFixup> &Fixups,
1236 : const MCSubtargetInfo &STI) const {
1237 0 : const MCOperand MO = MI.getOperand(OpIdx);
1238 0 : if (MO.isExpr())
1239 0 : return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups, STI);
1240 0 : return (MO.getImm() >> 2);
1241 : }
1242 :
1243 : /// getAddrMode5OpValue - Return encoding info for 'reg +/- (imm8 << 2)' operand.
1244 728 : uint32_t ARMMCCodeEmitter::
1245 : getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
1246 : SmallVectorImpl<MCFixup> &Fixups,
1247 : const MCSubtargetInfo &STI) const {
1248 : // {12-9} = reg
1249 : // {8} = (U)nsigned (add == '1', sub == '0')
1250 : // {7-0} = imm8
1251 : unsigned Reg, Imm8;
1252 : bool isAdd;
1253 : // If The first operand isn't a register, we have a label reference.
1254 : const MCOperand &MO = MI.getOperand(OpIdx);
1255 728 : if (!MO.isReg()) {
1256 148 : Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC.
1257 : Imm8 = 0;
1258 : isAdd = false; // 'U' bit is handled as part of the fixup.
1259 :
1260 : assert(MO.isExpr() && "Unexpected machine operand type!");
1261 148 : const MCExpr *Expr = MO.getExpr();
1262 : MCFixupKind Kind;
1263 : if (isThumb2(STI))
1264 : Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
1265 : else
1266 : Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
1267 296 : Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
1268 :
1269 : ++MCNumCPRelocations;
1270 : } else {
1271 580 : EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI);
1272 580 : isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add;
1273 : }
1274 :
1275 : uint32_t Binary = ARM_AM::getAM5Offset(Imm8);
1276 : // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
1277 728 : if (isAdd)
1278 362 : Binary |= (1 << 8);
1279 728 : Binary |= (Reg << 9);
1280 728 : return Binary;
1281 : }
1282 :
1283 : /// getAddrMode5FP16OpValue - Return encoding info for 'reg +/- (imm8 << 1)' operand.
1284 32 : uint32_t ARMMCCodeEmitter::
1285 : getAddrMode5FP16OpValue(const MCInst &MI, unsigned OpIdx,
1286 : SmallVectorImpl<MCFixup> &Fixups,
1287 : const MCSubtargetInfo &STI) const {
1288 : // {12-9} = reg
1289 : // {8} = (U)nsigned (add == '1', sub == '0')
1290 : // {7-0} = imm8
1291 : unsigned Reg, Imm8;
1292 : bool isAdd;
1293 : // If The first operand isn't a register, we have a label reference.
1294 : const MCOperand &MO = MI.getOperand(OpIdx);
1295 32 : if (!MO.isReg()) {
1296 0 : Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC.
1297 : Imm8 = 0;
1298 : isAdd = false; // 'U' bit is handled as part of the fixup.
1299 :
1300 : assert(MO.isExpr() && "Unexpected machine operand type!");
1301 0 : const MCExpr *Expr = MO.getExpr();
1302 : MCFixupKind Kind;
1303 : if (isThumb2(STI))
1304 : Kind = MCFixupKind(ARM::fixup_t2_pcrel_9);
1305 : else
1306 : Kind = MCFixupKind(ARM::fixup_arm_pcrel_9);
1307 0 : Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
1308 :
1309 : ++MCNumCPRelocations;
1310 : } else {
1311 32 : EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI);
1312 32 : isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add;
1313 : }
1314 :
1315 : uint32_t Binary = ARM_AM::getAM5Offset(Imm8);
1316 : // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
1317 32 : if (isAdd)
1318 16 : Binary |= (1 << 8);
1319 32 : Binary |= (Reg << 9);
1320 32 : return Binary;
1321 : }
1322 :
1323 0 : unsigned ARMMCCodeEmitter::
1324 : getSORegRegOpValue(const MCInst &MI, unsigned OpIdx,
1325 : SmallVectorImpl<MCFixup> &Fixups,
1326 : const MCSubtargetInfo &STI) const {
1327 : // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be
1328 : // shifted. The second is Rs, the amount to shift by, and the third specifies
1329 : // the type of the shift.
1330 : //
1331 : // {3-0} = Rm.
1332 : // {4} = 1
1333 : // {6-5} = type
1334 : // {11-8} = Rs
1335 : // {7} = 0
1336 :
1337 : const MCOperand &MO = MI.getOperand(OpIdx);
1338 0 : const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1339 0 : const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
1340 0 : ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());
1341 :
1342 : // Encode Rm.
1343 0 : unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1344 :
1345 : // Encode the shift opcode.
1346 : unsigned SBits = 0;
1347 0 : unsigned Rs = MO1.getReg();
1348 0 : if (Rs) {
1349 : // Set shift operand (bit[7:4]).
1350 : // LSL - 0001
1351 : // LSR - 0011
1352 : // ASR - 0101
1353 : // ROR - 0111
1354 0 : switch (SOpc) {
1355 0 : default: llvm_unreachable("Unknown shift opc!");
1356 : case ARM_AM::lsl: SBits = 0x1; break;
1357 0 : case ARM_AM::lsr: SBits = 0x3; break;
1358 0 : case ARM_AM::asr: SBits = 0x5; break;
1359 0 : case ARM_AM::ror: SBits = 0x7; break;
1360 : }
1361 : }
1362 :
1363 0 : Binary |= SBits << 4;
1364 :
1365 : // Encode the shift operation Rs.
1366 : // Encode Rs bit[11:8].
1367 : assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
1368 0 : return Binary | (CTX.getRegisterInfo()->getEncodingValue(Rs) << ARMII::RegRsShift);
1369 : }
1370 :
1371 0 : unsigned ARMMCCodeEmitter::
1372 : getSORegImmOpValue(const MCInst &MI, unsigned OpIdx,
1373 : SmallVectorImpl<MCFixup> &Fixups,
1374 : const MCSubtargetInfo &STI) const {
1375 : // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
1376 : // shifted. The second is the amount to shift by.
1377 : //
1378 : // {3-0} = Rm.
1379 : // {4} = 0
1380 : // {6-5} = type
1381 : // {11-7} = imm
1382 :
1383 : const MCOperand &MO = MI.getOperand(OpIdx);
1384 0 : const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1385 0 : ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
1386 :
1387 : // Encode Rm.
1388 0 : unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1389 :
1390 : // Encode the shift opcode.
1391 : unsigned SBits = 0;
1392 :
1393 : // Set shift operand (bit[6:4]).
1394 : // LSL - 000
1395 : // LSR - 010
1396 : // ASR - 100
1397 : // ROR - 110
1398 : // RRX - 110 and bit[11:8] clear.
1399 0 : switch (SOpc) {
1400 0 : default: llvm_unreachable("Unknown shift opc!");
1401 : case ARM_AM::lsl: SBits = 0x0; break;
1402 0 : case ARM_AM::lsr: SBits = 0x2; break;
1403 0 : case ARM_AM::asr: SBits = 0x4; break;
1404 0 : case ARM_AM::ror: SBits = 0x6; break;
1405 0 : case ARM_AM::rrx:
1406 0 : Binary |= 0x60;
1407 0 : return Binary;
1408 : }
1409 :
1410 : // Encode shift_imm bit[11:7].
1411 0 : Binary |= SBits << 4;
1412 : unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm());
1413 : assert(Offset < 32 && "Offset must be in range 0-31!");
1414 0 : return Binary | (Offset << 7);
1415 : }
1416 :
1417 :
1418 0 : unsigned ARMMCCodeEmitter::
1419 : getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
1420 : SmallVectorImpl<MCFixup> &Fixups,
1421 : const MCSubtargetInfo &STI) const {
1422 : const MCOperand &MO1 = MI.getOperand(OpNum);
1423 0 : const MCOperand &MO2 = MI.getOperand(OpNum+1);
1424 0 : const MCOperand &MO3 = MI.getOperand(OpNum+2);
1425 :
1426 : // Encoded as [Rn, Rm, imm].
1427 : // FIXME: Needs fixup support.
1428 252 : unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
1429 252 : Value <<= 4;
1430 252 : Value |= CTX.getRegisterInfo()->getEncodingValue(MO2.getReg());
1431 252 : Value <<= 2;
1432 252 : Value |= MO3.getImm();
1433 :
1434 0 : return Value;
1435 : }
1436 :
1437 0 : unsigned ARMMCCodeEmitter::
1438 : getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
1439 : SmallVectorImpl<MCFixup> &Fixups,
1440 : const MCSubtargetInfo &STI) const {
1441 : const MCOperand &MO1 = MI.getOperand(OpNum);
1442 0 : const MCOperand &MO2 = MI.getOperand(OpNum+1);
1443 :
1444 : // FIXME: Needs fixup support.
1445 151 : unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
1446 :
1447 : // Even though the immediate is 8 bits long, we need 9 bits in order
1448 : // to represent the (inverse of the) sign bit.
1449 151 : Value <<= 9;
1450 151 : int32_t tmp = (int32_t)MO2.getImm();
1451 151 : if (tmp < 0)
1452 55 : tmp = abs(tmp);
1453 : else
1454 96 : Value |= 256; // Set the ADD bit
1455 151 : Value |= tmp & 255;
1456 0 : return Value;
1457 : }
1458 :
1459 0 : unsigned ARMMCCodeEmitter::
1460 : getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
1461 : SmallVectorImpl<MCFixup> &Fixups,
1462 : const MCSubtargetInfo &STI) const {
1463 : const MCOperand &MO1 = MI.getOperand(OpNum);
1464 :
1465 : // FIXME: Needs fixup support.
1466 : unsigned Value = 0;
1467 954 : int32_t tmp = (int32_t)MO1.getImm();
1468 954 : if (tmp < 0)
1469 18 : tmp = abs(tmp);
1470 : else
1471 : Value |= 256; // Set the ADD bit
1472 954 : Value |= tmp & 255;
1473 0 : return Value;
1474 : }
1475 :
1476 0 : unsigned ARMMCCodeEmitter::
1477 : getT2SORegOpValue(const MCInst &MI, unsigned OpIdx,
1478 : SmallVectorImpl<MCFixup> &Fixups,
1479 : const MCSubtargetInfo &STI) const {
1480 : // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
1481 : // shifted. The second is the amount to shift by.
1482 : //
1483 : // {3-0} = Rm.
1484 : // {4} = 0
1485 : // {6-5} = type
1486 : // {11-7} = imm
1487 :
1488 : const MCOperand &MO = MI.getOperand(OpIdx);
1489 0 : const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1490 0 : ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
1491 :
1492 : // Encode Rm.
1493 0 : unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1494 :
1495 : // Encode the shift opcode.
1496 : unsigned SBits = 0;
1497 : // Set shift operand (bit[6:4]).
1498 : // LSL - 000
1499 : // LSR - 010
1500 : // ASR - 100
1501 : // ROR - 110
1502 0 : switch (SOpc) {
1503 0 : default: llvm_unreachable("Unknown shift opc!");
1504 : case ARM_AM::lsl: SBits = 0x0; break;
1505 0 : case ARM_AM::lsr: SBits = 0x2; break;
1506 0 : case ARM_AM::asr: SBits = 0x4; break;
1507 0 : case ARM_AM::rrx: LLVM_FALLTHROUGH;
1508 0 : case ARM_AM::ror: SBits = 0x6; break;
1509 : }
1510 :
1511 0 : Binary |= SBits << 4;
1512 0 : if (SOpc == ARM_AM::rrx)
1513 0 : return Binary;
1514 :
1515 : // Encode shift_imm bit[11:7].
1516 0 : return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7;
1517 : }
1518 :
1519 0 : unsigned ARMMCCodeEmitter::
1520 : getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
1521 : SmallVectorImpl<MCFixup> &Fixups,
1522 : const MCSubtargetInfo &STI) const {
1523 : // 10 bits. lower 5 bits are the lsb of the mask, high five bits are the
1524 : // msb of the mask.
1525 : const MCOperand &MO = MI.getOperand(Op);
1526 75 : uint32_t v = ~MO.getImm();
1527 75 : uint32_t lsb = countTrailingZeros(v);
1528 75 : uint32_t msb = (32 - countLeadingZeros (v)) - 1;
1529 : assert(v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!");
1530 75 : return lsb | (msb << 5);
1531 : }
1532 :
1533 0 : unsigned ARMMCCodeEmitter::
1534 : getRegisterListOpValue(const MCInst &MI, unsigned Op,
1535 : SmallVectorImpl<MCFixup> &Fixups,
1536 : const MCSubtargetInfo &STI) const {
1537 : // VLDM/VSTM:
1538 : // {12-8} = Vd
1539 : // {7-0} = Number of registers
1540 : //
1541 : // LDM/STM:
1542 : // {15-0} = Bitfield of GPRs.
1543 0 : unsigned Reg = MI.getOperand(Op).getReg();
1544 0 : bool SPRRegs = ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg);
1545 0 : bool DPRRegs = ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg);
1546 :
1547 : unsigned Binary = 0;
1548 :
1549 0 : if (SPRRegs || DPRRegs) {
1550 : // VLDM/VSTM
1551 0 : unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg);
1552 0 : unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff;
1553 0 : Binary |= (RegNo & 0x1f) << 8;
1554 0 : if (SPRRegs)
1555 0 : Binary |= NumRegs;
1556 : else
1557 0 : Binary |= NumRegs * 2;
1558 : } else {
1559 0 : const MCRegisterInfo &MRI = *CTX.getRegisterInfo();
1560 : assert(std::is_sorted(MI.begin() + Op, MI.end(),
1561 : [&](const MCOperand &LHS, const MCOperand &RHS) {
1562 : return MRI.getEncodingValue(LHS.getReg()) <
1563 : MRI.getEncodingValue(RHS.getReg());
1564 : }));
1565 :
1566 0 : for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) {
1567 0 : unsigned RegNo = MRI.getEncodingValue(MI.getOperand(I).getReg());
1568 0 : Binary |= 1 << RegNo;
1569 : }
1570 : }
1571 :
1572 0 : return Binary;
1573 : }
1574 :
1575 : /// getAddrMode6AddressOpValue - Encode an addrmode6 register number along
1576 : /// with the alignment operand.
1577 0 : unsigned ARMMCCodeEmitter::
1578 : getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
1579 : SmallVectorImpl<MCFixup> &Fixups,
1580 : const MCSubtargetInfo &STI) const {
1581 : const MCOperand &Reg = MI.getOperand(Op);
1582 0 : const MCOperand &Imm = MI.getOperand(Op + 1);
1583 :
1584 1415 : unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg());
1585 : unsigned Align = 0;
1586 :
1587 1415 : switch (Imm.getImm()) {
1588 : default: break;
1589 0 : case 2:
1590 : case 4:
1591 0 : case 8: Align = 0x01; break;
1592 0 : case 16: Align = 0x02; break;
1593 0 : case 32: Align = 0x03; break;
1594 : }
1595 :
1596 1415 : return RegNo | (Align << 4);
1597 : }
1598 :
1599 : /// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number
1600 : /// along with the alignment operand for use in VST1 and VLD1 with size 32.
1601 0 : unsigned ARMMCCodeEmitter::
1602 : getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
1603 : SmallVectorImpl<MCFixup> &Fixups,
1604 : const MCSubtargetInfo &STI) const {
1605 : const MCOperand &Reg = MI.getOperand(Op);
1606 0 : const MCOperand &Imm = MI.getOperand(Op + 1);
1607 :
1608 19 : unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg());
1609 : unsigned Align = 0;
1610 :
1611 19 : switch (Imm.getImm()) {
1612 : default: break;
1613 : case 8:
1614 : case 16:
1615 : case 32: // Default '0' value for invalid alignments of 8, 16, 32 bytes.
1616 : case 2: Align = 0x00; break;
1617 12 : case 4: Align = 0x03; break;
1618 : }
1619 :
1620 19 : return RegNo | (Align << 4);
1621 : }
1622 :
1623 :
1624 : /// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and
1625 : /// alignment operand for use in VLD-dup instructions. This is the same as
1626 : /// getAddrMode6AddressOpValue except for the alignment encoding, which is
1627 : /// different for VLD4-dup.
1628 0 : unsigned ARMMCCodeEmitter::
1629 : getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
1630 : SmallVectorImpl<MCFixup> &Fixups,
1631 : const MCSubtargetInfo &STI) const {
1632 : const MCOperand &Reg = MI.getOperand(Op);
1633 0 : const MCOperand &Imm = MI.getOperand(Op + 1);
1634 :
1635 0 : unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg());
1636 : unsigned Align = 0;
1637 :
1638 0 : switch (Imm.getImm()) {
1639 : default: break;
1640 0 : case 2:
1641 : case 4:
1642 0 : case 8: Align = 0x01; break;
1643 0 : case 16: Align = 0x03; break;
1644 : }
1645 :
1646 0 : return RegNo | (Align << 4);
1647 : }
1648 :
1649 0 : unsigned ARMMCCodeEmitter::
1650 : getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
1651 : SmallVectorImpl<MCFixup> &Fixups,
1652 : const MCSubtargetInfo &STI) const {
1653 : const MCOperand &MO = MI.getOperand(Op);
1654 529 : if (MO.getReg() == 0) return 0x0D;
1655 309 : return CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1656 : }
1657 :
1658 0 : unsigned ARMMCCodeEmitter::
1659 : getShiftRight8Imm(const MCInst &MI, unsigned Op,
1660 : SmallVectorImpl<MCFixup> &Fixups,
1661 : const MCSubtargetInfo &STI) const {
1662 98 : return 8 - MI.getOperand(Op).getImm();
1663 : }
1664 :
1665 0 : unsigned ARMMCCodeEmitter::
1666 : getShiftRight16Imm(const MCInst &MI, unsigned Op,
1667 : SmallVectorImpl<MCFixup> &Fixups,
1668 : const MCSubtargetInfo &STI) const {
1669 98 : return 16 - MI.getOperand(Op).getImm();
1670 : }
1671 :
1672 0 : unsigned ARMMCCodeEmitter::
1673 : getShiftRight32Imm(const MCInst &MI, unsigned Op,
1674 : SmallVectorImpl<MCFixup> &Fixups,
1675 : const MCSubtargetInfo &STI) const {
1676 98 : return 32 - MI.getOperand(Op).getImm();
1677 : }
1678 :
1679 0 : unsigned ARMMCCodeEmitter::
1680 : getShiftRight64Imm(const MCInst &MI, unsigned Op,
1681 : SmallVectorImpl<MCFixup> &Fixups,
1682 : const MCSubtargetInfo &STI) const {
1683 80 : return 64 - MI.getOperand(Op).getImm();
1684 : }
1685 :
1686 41932 : void ARMMCCodeEmitter::
1687 : encodeInstruction(const MCInst &MI, raw_ostream &OS,
1688 : SmallVectorImpl<MCFixup> &Fixups,
1689 : const MCSubtargetInfo &STI) const {
1690 : // Pseudo instructions don't get encoded.
1691 41932 : const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
1692 41932 : uint64_t TSFlags = Desc.TSFlags;
1693 41932 : if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo)
1694 : return;
1695 :
1696 : int Size;
1697 83862 : if (Desc.getSize() == 2 || Desc.getSize() == 4)
1698 : Size = Desc.getSize();
1699 : else
1700 0 : llvm_unreachable("Unexpected instruction size!");
1701 :
1702 41931 : uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
1703 : // Thumb 32-bit wide instructions need to emit the high order halfword
1704 : // first.
1705 41931 : if (isThumb(STI) && Size == 4) {
1706 13067 : EmitConstant(Binary >> 16, 2, OS);
1707 13067 : EmitConstant(Binary & 0xffff, 2, OS);
1708 : } else
1709 28864 : EmitConstant(Binary, Size, OS);
1710 : ++MCNumEmitted; // Keep track of the # of mi's emitted.
1711 : }
1712 :
1713 : #include "ARMGenMCCodeEmitter.inc"
1714 :
1715 932 : MCCodeEmitter *llvm::createARMLEMCCodeEmitter(const MCInstrInfo &MCII,
1716 : const MCRegisterInfo &MRI,
1717 : MCContext &Ctx) {
1718 932 : return new ARMMCCodeEmitter(MCII, Ctx, true);
1719 : }
1720 :
1721 19 : MCCodeEmitter *llvm::createARMBEMCCodeEmitter(const MCInstrInfo &MCII,
1722 : const MCRegisterInfo &MRI,
1723 : MCContext &Ctx) {
1724 19 : return new ARMMCCodeEmitter(MCII, Ctx, false);
1725 : }
|