1 | //===-- ARM/ARMMCCodeEmitter.cpp - Convert ARM code to machine code -------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file implements the ARMMCCodeEmitter class. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "MCTargetDesc/ARMAddressingModes.h" |
14 | #include "MCTargetDesc/ARMBaseInfo.h" |
15 | #include "MCTargetDesc/ARMFixupKinds.h" |
16 | #include "MCTargetDesc/ARMMCExpr.h" |
17 | #include "llvm/ADT/APFloat.h" |
18 | #include "llvm/ADT/APInt.h" |
19 | #include "llvm/ADT/SmallVector.h" |
20 | #include "llvm/ADT/Statistic.h" |
21 | #include "llvm/MC/MCCodeEmitter.h" |
22 | #include "llvm/MC/MCContext.h" |
23 | #include "llvm/MC/MCExpr.h" |
24 | #include "llvm/MC/MCFixup.h" |
25 | #include "llvm/MC/MCInst.h" |
26 | #include "llvm/MC/MCInstrDesc.h" |
27 | #include "llvm/MC/MCInstrInfo.h" |
28 | #include "llvm/MC/MCRegisterInfo.h" |
29 | #include "llvm/MC/MCSubtargetInfo.h" |
30 | #include "llvm/Support/Casting.h" |
31 | #include "llvm/Support/Compiler.h" |
32 | #include "llvm/Support/EndianStream.h" |
33 | #include "llvm/Support/ErrorHandling.h" |
34 | #include "llvm/Support/MathExtras.h" |
35 | #include "llvm/Support/raw_ostream.h" |
36 | #include "llvm/TargetParser/Triple.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 | MCContext &CTX; |
54 | bool IsLittleEndian; |
55 | |
56 | public: |
57 | ARMMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx, bool IsLittle) |
58 | : MCII(mcii), CTX(ctx), IsLittleEndian(IsLittle) { |
59 | } |
60 | ARMMCCodeEmitter(const ARMMCCodeEmitter &) = delete; |
61 | ARMMCCodeEmitter &operator=(const ARMMCCodeEmitter &) = delete; |
62 | ~ARMMCCodeEmitter() override = default; |
63 | |
64 | bool isThumb(const MCSubtargetInfo &STI) const { |
65 | return STI.hasFeature(Feature: ARM::ModeThumb); |
66 | } |
67 | |
68 | bool isThumb2(const MCSubtargetInfo &STI) const { |
69 | return isThumb(STI) && STI.hasFeature(Feature: 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 | /// getHiLoImmOpValue - Return the encoding for either the hi / low 16-bit, or |
92 | /// high/middle-high/middle-low/low 8 bits of the specified operand. This is |
93 | /// used for operands with :lower16:, :upper16: :lower0_7:, :lower8_15:, |
94 | /// :higher0_7:, and :higher8_15: prefixes. |
95 | uint32_t getHiLoImmOpValue(const MCInst &MI, unsigned OpIdx, |
96 | SmallVectorImpl<MCFixup> &Fixups, |
97 | const MCSubtargetInfo &STI) const; |
98 | |
99 | bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, |
100 | unsigned &Reg, unsigned &Imm, |
101 | SmallVectorImpl<MCFixup> &Fixups, |
102 | const MCSubtargetInfo &STI) const; |
103 | |
104 | /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate |
105 | /// BL branch target. |
106 | uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, |
107 | SmallVectorImpl<MCFixup> &Fixups, |
108 | const MCSubtargetInfo &STI) const; |
109 | |
110 | /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate |
111 | /// BLX branch target. |
112 | uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, |
113 | SmallVectorImpl<MCFixup> &Fixups, |
114 | const MCSubtargetInfo &STI) const; |
115 | |
116 | /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. |
117 | uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, |
118 | SmallVectorImpl<MCFixup> &Fixups, |
119 | const MCSubtargetInfo &STI) const; |
120 | |
121 | /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. |
122 | uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, |
123 | SmallVectorImpl<MCFixup> &Fixups, |
124 | const MCSubtargetInfo &STI) const; |
125 | |
126 | /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. |
127 | uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, |
128 | SmallVectorImpl<MCFixup> &Fixups, |
129 | const MCSubtargetInfo &STI) const; |
130 | |
131 | /// getBranchTargetOpValue - Return encoding info for 24-bit immediate |
132 | /// branch target. |
133 | uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, |
134 | SmallVectorImpl<MCFixup> &Fixups, |
135 | const MCSubtargetInfo &STI) const; |
136 | |
137 | /// getThumbBranchTargetOpValue - Return encoding info for 24-bit |
138 | /// immediate Thumb2 direct branch target. |
139 | uint32_t getThumbBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, |
140 | SmallVectorImpl<MCFixup> &Fixups, |
141 | const MCSubtargetInfo &STI) const; |
142 | |
143 | /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate |
144 | /// branch target. |
145 | uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, |
146 | SmallVectorImpl<MCFixup> &Fixups, |
147 | const MCSubtargetInfo &STI) const; |
148 | uint32_t getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx, |
149 | SmallVectorImpl<MCFixup> &Fixups, |
150 | const MCSubtargetInfo &STI) const; |
151 | uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, |
152 | SmallVectorImpl<MCFixup> &Fixups, |
153 | const MCSubtargetInfo &STI) const; |
154 | |
155 | /// getAdrLabelOpValue - Return encoding info for 12-bit immediate |
156 | /// ADR label target. |
157 | uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, |
158 | SmallVectorImpl<MCFixup> &Fixups, |
159 | const MCSubtargetInfo &STI) const; |
160 | uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, |
161 | SmallVectorImpl<MCFixup> &Fixups, |
162 | const MCSubtargetInfo &STI) const; |
163 | uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, |
164 | SmallVectorImpl<MCFixup> &Fixups, |
165 | const MCSubtargetInfo &STI) const; |
166 | |
167 | uint32_t getITMaskOpValue(const MCInst &MI, unsigned OpIdx, |
168 | SmallVectorImpl<MCFixup> &Fixups, |
169 | const MCSubtargetInfo &STI) const; |
170 | |
171 | /// getMVEShiftImmOpValue - Return encoding info for the 'sz:imm5' |
172 | /// operand. |
173 | uint32_t getMVEShiftImmOpValue(const MCInst &MI, unsigned OpIdx, |
174 | SmallVectorImpl<MCFixup> &Fixups, |
175 | const MCSubtargetInfo &STI) const; |
176 | |
177 | /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' |
178 | /// operand. |
179 | uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, |
180 | SmallVectorImpl<MCFixup> &Fixups, |
181 | const MCSubtargetInfo &STI) const; |
182 | |
183 | /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand. |
184 | uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, |
185 | SmallVectorImpl<MCFixup> &Fixups, |
186 | const MCSubtargetInfo &STI) const; |
187 | |
188 | /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2' |
189 | /// operand. |
190 | uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, |
191 | SmallVectorImpl<MCFixup> &Fixups, |
192 | const MCSubtargetInfo &STI) const; |
193 | |
194 | /// getT2AddrModeImm7s4OpValue - Return encoding info for 'reg +/- imm7<<2' |
195 | /// operand. |
196 | uint32_t getT2AddrModeImm7s4OpValue(const MCInst &MI, unsigned OpIdx, |
197 | SmallVectorImpl<MCFixup> &Fixups, |
198 | const MCSubtargetInfo &STI) const; |
199 | |
200 | /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 'reg + imm8<<2' |
201 | /// operand. |
202 | uint32_t getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx, |
203 | SmallVectorImpl<MCFixup> &Fixups, |
204 | const MCSubtargetInfo &STI) const; |
205 | |
206 | /// getT2ScaledImmOpValue - Return encoding info for '+/- immX<<Y' |
207 | /// operand. |
208 | template<unsigned Bits, unsigned Shift> |
209 | uint32_t getT2ScaledImmOpValue(const MCInst &MI, unsigned OpIdx, |
210 | SmallVectorImpl<MCFixup> &Fixups, |
211 | const MCSubtargetInfo &STI) const; |
212 | |
213 | /// getMveAddrModeRQOpValue - Return encoding info for 'reg, vreg' |
214 | /// operand. |
215 | uint32_t getMveAddrModeRQOpValue(const MCInst &MI, unsigned OpIdx, |
216 | SmallVectorImpl<MCFixup> &Fixups, |
217 | const MCSubtargetInfo &STI) const; |
218 | |
219 | /// getMveAddrModeQOpValue - Return encoding info for 'reg +/- imm7<<{shift}' |
220 | /// operand. |
221 | template<int shift> |
222 | uint32_t getMveAddrModeQOpValue(const MCInst &MI, unsigned OpIdx, |
223 | SmallVectorImpl<MCFixup> &Fixups, |
224 | const MCSubtargetInfo &STI) const; |
225 | |
226 | /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm' |
227 | /// operand as needed by load/store instructions. |
228 | uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, |
229 | SmallVectorImpl<MCFixup> &Fixups, |
230 | const MCSubtargetInfo &STI) const; |
231 | |
232 | /// getLdStmModeOpValue - Return encoding for load/store multiple mode. |
233 | uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx, |
234 | SmallVectorImpl<MCFixup> &Fixups, |
235 | const MCSubtargetInfo &STI) const { |
236 | ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(i: OpIdx).getImm(); |
237 | switch (Mode) { |
238 | default: llvm_unreachable("Unknown addressing sub-mode!" ); |
239 | case ARM_AM::da: return 0; |
240 | case ARM_AM::ia: return 1; |
241 | case ARM_AM::db: return 2; |
242 | case ARM_AM::ib: return 3; |
243 | } |
244 | } |
245 | |
246 | /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value. |
247 | /// |
248 | unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const { |
249 | switch (ShOpc) { |
250 | case ARM_AM::no_shift: |
251 | case ARM_AM::lsl: return 0; |
252 | case ARM_AM::lsr: return 1; |
253 | case ARM_AM::asr: return 2; |
254 | case ARM_AM::ror: |
255 | case ARM_AM::rrx: return 3; |
256 | default: |
257 | llvm_unreachable("Invalid ShiftOpc!" ); |
258 | } |
259 | } |
260 | |
261 | /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands. |
262 | uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, |
263 | SmallVectorImpl<MCFixup> &Fixups, |
264 | const MCSubtargetInfo &STI) const; |
265 | |
266 | /// getPostIdxRegOpValue - Return encoding for postidx_reg operands. |
267 | uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, |
268 | SmallVectorImpl<MCFixup> &Fixups, |
269 | const MCSubtargetInfo &STI) const; |
270 | |
271 | /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands. |
272 | uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, |
273 | SmallVectorImpl<MCFixup> &Fixups, |
274 | const MCSubtargetInfo &STI) const; |
275 | |
276 | /// getAddrMode3OpValue - Return encoding for addrmode3 operands. |
277 | uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, |
278 | SmallVectorImpl<MCFixup> &Fixups, |
279 | const MCSubtargetInfo &STI) const; |
280 | |
281 | /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12' |
282 | /// operand. |
283 | uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, |
284 | SmallVectorImpl<MCFixup> &Fixups, |
285 | const MCSubtargetInfo &STI) const; |
286 | |
287 | /// getAddrModeISOpValue - Encode the t_addrmode_is# operands. |
288 | uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, |
289 | SmallVectorImpl<MCFixup> &Fixups, |
290 | const MCSubtargetInfo &STI) const; |
291 | |
292 | /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. |
293 | uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, |
294 | SmallVectorImpl<MCFixup> &Fixups, |
295 | const MCSubtargetInfo &STI) const; |
296 | |
297 | /// getAddrMode5OpValue - Return encoding info for 'reg +/- (imm8 << 2)' operand. |
298 | uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, |
299 | SmallVectorImpl<MCFixup> &Fixups, |
300 | const MCSubtargetInfo &STI) const; |
301 | |
302 | /// getAddrMode5FP16OpValue - Return encoding info for 'reg +/- (imm8 << 1)' operand. |
303 | uint32_t getAddrMode5FP16OpValue(const MCInst &MI, unsigned OpIdx, |
304 | SmallVectorImpl<MCFixup> &Fixups, |
305 | const MCSubtargetInfo &STI) const; |
306 | |
307 | /// getCCOutOpValue - Return encoding of the 's' bit. |
308 | unsigned getCCOutOpValue(const MCInst &MI, unsigned Op, |
309 | SmallVectorImpl<MCFixup> &Fixups, |
310 | const MCSubtargetInfo &STI) const { |
311 | // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or |
312 | // '1' respectively. |
313 | return MI.getOperand(i: Op).getReg() == ARM::CPSR; |
314 | } |
315 | |
316 | unsigned getModImmOpValue(const MCInst &MI, unsigned Op, |
317 | SmallVectorImpl<MCFixup> &Fixups, |
318 | const MCSubtargetInfo &ST) const { |
319 | const MCOperand &MO = MI.getOperand(i: Op); |
320 | |
321 | // Support for fixups (MCFixup) |
322 | if (MO.isExpr()) { |
323 | const MCExpr *Expr = MO.getExpr(); |
324 | // Fixups resolve to plain values that need to be encoded. |
325 | MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_mod_imm); |
326 | Fixups.push_back(Elt: MCFixup::create(Offset: 0, Value: Expr, Kind, Loc: MI.getLoc())); |
327 | return 0; |
328 | } |
329 | |
330 | // Immediate is already in its encoded format |
331 | return MO.getImm(); |
332 | } |
333 | |
334 | /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value. |
335 | unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op, |
336 | SmallVectorImpl<MCFixup> &Fixups, |
337 | const MCSubtargetInfo &STI) const { |
338 | const MCOperand &MO = MI.getOperand(i: Op); |
339 | |
340 | // Support for fixups (MCFixup) |
341 | if (MO.isExpr()) { |
342 | const MCExpr *Expr = MO.getExpr(); |
343 | // Fixups resolve to plain values that need to be encoded. |
344 | MCFixupKind Kind = MCFixupKind(ARM::fixup_t2_so_imm); |
345 | Fixups.push_back(Elt: MCFixup::create(Offset: 0, Value: Expr, Kind, Loc: MI.getLoc())); |
346 | return 0; |
347 | } |
348 | unsigned SoImm = MO.getImm(); |
349 | unsigned Encoded = ARM_AM::getT2SOImmVal(Arg: SoImm); |
350 | assert(Encoded != ~0U && "Not a Thumb2 so_imm value?" ); |
351 | return Encoded; |
352 | } |
353 | |
354 | unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, |
355 | SmallVectorImpl<MCFixup> &Fixups, |
356 | const MCSubtargetInfo &STI) const; |
357 | template<unsigned Bits, unsigned Shift> |
358 | unsigned getT2AddrModeImmOpValue(const MCInst &MI, unsigned OpNum, |
359 | SmallVectorImpl<MCFixup> &Fixups, |
360 | const MCSubtargetInfo &STI) const; |
361 | unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, |
362 | SmallVectorImpl<MCFixup> &Fixups, |
363 | const MCSubtargetInfo &STI) const; |
364 | |
365 | /// getSORegOpValue - Return an encoded so_reg shifted register value. |
366 | unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op, |
367 | SmallVectorImpl<MCFixup> &Fixups, |
368 | const MCSubtargetInfo &STI) const; |
369 | unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op, |
370 | SmallVectorImpl<MCFixup> &Fixups, |
371 | const MCSubtargetInfo &STI) const; |
372 | unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op, |
373 | SmallVectorImpl<MCFixup> &Fixups, |
374 | const MCSubtargetInfo &STI) const; |
375 | |
376 | unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op, |
377 | SmallVectorImpl<MCFixup> &Fixups, |
378 | const MCSubtargetInfo &STI) const { |
379 | return 64 - MI.getOperand(i: Op).getImm(); |
380 | } |
381 | |
382 | unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, |
383 | SmallVectorImpl<MCFixup> &Fixups, |
384 | const MCSubtargetInfo &STI) const; |
385 | |
386 | unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op, |
387 | SmallVectorImpl<MCFixup> &Fixups, |
388 | const MCSubtargetInfo &STI) const; |
389 | unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, |
390 | SmallVectorImpl<MCFixup> &Fixups, |
391 | const MCSubtargetInfo &STI) const; |
392 | unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, |
393 | SmallVectorImpl<MCFixup> &Fixups, |
394 | const MCSubtargetInfo &STI) const; |
395 | unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, |
396 | SmallVectorImpl<MCFixup> &Fixups, |
397 | const MCSubtargetInfo &STI) const; |
398 | unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, |
399 | SmallVectorImpl<MCFixup> &Fixups, |
400 | const MCSubtargetInfo &STI) const; |
401 | |
402 | unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op, |
403 | SmallVectorImpl<MCFixup> &Fixups, |
404 | const MCSubtargetInfo &STI) const; |
405 | unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op, |
406 | SmallVectorImpl<MCFixup> &Fixups, |
407 | const MCSubtargetInfo &STI) const; |
408 | unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op, |
409 | SmallVectorImpl<MCFixup> &Fixups, |
410 | const MCSubtargetInfo &STI) const; |
411 | unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op, |
412 | SmallVectorImpl<MCFixup> &Fixups, |
413 | const MCSubtargetInfo &STI) const; |
414 | |
415 | unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op, |
416 | SmallVectorImpl<MCFixup> &Fixups, |
417 | const MCSubtargetInfo &STI) const; |
418 | |
419 | unsigned NEONThumb2DataIPostEncoder(const MCInst &MI, |
420 | unsigned EncodedValue, |
421 | const MCSubtargetInfo &STI) const; |
422 | unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI, |
423 | unsigned EncodedValue, |
424 | const MCSubtargetInfo &STI) const; |
425 | unsigned NEONThumb2DupPostEncoder(const MCInst &MI, |
426 | unsigned EncodedValue, |
427 | const MCSubtargetInfo &STI) const; |
428 | unsigned NEONThumb2V8PostEncoder(const MCInst &MI, |
429 | unsigned EncodedValue, |
430 | const MCSubtargetInfo &STI) const; |
431 | |
432 | unsigned VFPThumb2PostEncoder(const MCInst &MI, |
433 | unsigned EncodedValue, |
434 | const MCSubtargetInfo &STI) const; |
435 | |
436 | uint32_t getPowerTwoOpValue(const MCInst &MI, unsigned OpIdx, |
437 | SmallVectorImpl<MCFixup> &Fixups, |
438 | const MCSubtargetInfo &STI) const; |
439 | |
440 | void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB, |
441 | SmallVectorImpl<MCFixup> &Fixups, |
442 | const MCSubtargetInfo &STI) const override; |
443 | |
444 | template <bool isNeg, ARM::Fixups fixup> |
445 | uint32_t getBFTargetOpValue(const MCInst &MI, unsigned OpIdx, |
446 | SmallVectorImpl<MCFixup> &Fixups, |
447 | const MCSubtargetInfo &STI) const; |
448 | |
449 | uint32_t getBFAfterTargetOpValue(const MCInst &MI, unsigned OpIdx, |
450 | SmallVectorImpl<MCFixup> &Fixups, |
451 | const MCSubtargetInfo &STI) const; |
452 | |
453 | uint32_t getVPTMaskOpValue(const MCInst &MI, unsigned OpIdx, |
454 | SmallVectorImpl<MCFixup> &Fixups, |
455 | const MCSubtargetInfo &STI) const; |
456 | uint32_t getRestrictedCondCodeOpValue(const MCInst &MI, unsigned OpIdx, |
457 | SmallVectorImpl<MCFixup> &Fixups, |
458 | const MCSubtargetInfo &STI) const; |
459 | template <unsigned size> |
460 | uint32_t getMVEPairVectorIndexOpValue(const MCInst &MI, unsigned OpIdx, |
461 | SmallVectorImpl<MCFixup> &Fixups, |
462 | const MCSubtargetInfo &STI) const; |
463 | }; |
464 | |
465 | } // end anonymous namespace |
466 | |
467 | /// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing |
468 | /// instructions, and rewrite them to their Thumb2 form if we are currently in |
469 | /// Thumb2 mode. |
470 | unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI, |
471 | unsigned EncodedValue, |
472 | const MCSubtargetInfo &STI) const { |
473 | if (isThumb2(STI)) { |
474 | // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved |
475 | // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are |
476 | // set to 1111. |
477 | unsigned Bit24 = EncodedValue & 0x01000000; |
478 | unsigned Bit28 = Bit24 << 4; |
479 | EncodedValue &= 0xEFFFFFFF; |
480 | EncodedValue |= Bit28; |
481 | EncodedValue |= 0x0F000000; |
482 | } |
483 | |
484 | return EncodedValue; |
485 | } |
486 | |
487 | /// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store |
488 | /// instructions, and rewrite them to their Thumb2 form if we are currently in |
489 | /// Thumb2 mode. |
490 | unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI, |
491 | unsigned EncodedValue, |
492 | const MCSubtargetInfo &STI) const { |
493 | if (isThumb2(STI)) { |
494 | EncodedValue &= 0xF0FFFFFF; |
495 | EncodedValue |= 0x09000000; |
496 | } |
497 | |
498 | return EncodedValue; |
499 | } |
500 | |
501 | /// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup |
502 | /// instructions, and rewrite them to their Thumb2 form if we are currently in |
503 | /// Thumb2 mode. |
504 | unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI, |
505 | unsigned EncodedValue, |
506 | const MCSubtargetInfo &STI) const { |
507 | if (isThumb2(STI)) { |
508 | EncodedValue &= 0x00FFFFFF; |
509 | EncodedValue |= 0xEE000000; |
510 | } |
511 | |
512 | return EncodedValue; |
513 | } |
514 | |
515 | /// Post-process encoded NEON v8 instructions, and rewrite them to Thumb2 form |
516 | /// if we are in Thumb2. |
517 | unsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI, |
518 | unsigned EncodedValue, |
519 | const MCSubtargetInfo &STI) const { |
520 | if (isThumb2(STI)) { |
521 | EncodedValue |= 0xC000000; // Set bits 27-26 |
522 | } |
523 | |
524 | return EncodedValue; |
525 | } |
526 | |
527 | /// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite |
528 | /// them to their Thumb2 form if we are currently in Thumb2 mode. |
529 | unsigned ARMMCCodeEmitter:: |
530 | VFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue, |
531 | const MCSubtargetInfo &STI) const { |
532 | if (isThumb2(STI)) { |
533 | EncodedValue &= 0x0FFFFFFF; |
534 | EncodedValue |= 0xE0000000; |
535 | } |
536 | return EncodedValue; |
537 | } |
538 | |
539 | /// getMachineOpValue - Return binary encoding of operand. If the machine |
540 | /// operand requires relocation, record the relocation and return zero. |
541 | unsigned ARMMCCodeEmitter:: |
542 | getMachineOpValue(const MCInst &MI, const MCOperand &MO, |
543 | SmallVectorImpl<MCFixup> &Fixups, |
544 | const MCSubtargetInfo &STI) const { |
545 | if (MO.isReg()) { |
546 | unsigned Reg = MO.getReg(); |
547 | unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(RegNo: Reg); |
548 | |
549 | // In NEON, Q registers are encoded as 2x their register number, |
550 | // because they're using the same indices as the D registers they |
551 | // overlap. In MVE, there are no 64-bit vector instructions, so |
552 | // the encodings all refer to Q-registers by their literal |
553 | // register number. |
554 | |
555 | if (STI.hasFeature(Feature: ARM::HasMVEIntegerOps)) |
556 | return RegNo; |
557 | |
558 | switch (Reg) { |
559 | default: |
560 | return RegNo; |
561 | case ARM::Q0: case ARM::Q1: case ARM::Q2: case ARM::Q3: |
562 | case ARM::Q4: case ARM::Q5: case ARM::Q6: case ARM::Q7: |
563 | case ARM::Q8: case ARM::Q9: case ARM::Q10: case ARM::Q11: |
564 | case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15: |
565 | return 2 * RegNo; |
566 | } |
567 | } else if (MO.isImm()) { |
568 | return static_cast<unsigned>(MO.getImm()); |
569 | } else if (MO.isDFPImm()) { |
570 | return static_cast<unsigned>(APFloat(bit_cast<double>(from: MO.getDFPImm())) |
571 | .bitcastToAPInt() |
572 | .getHiBits(numBits: 32) |
573 | .getLimitedValue()); |
574 | } |
575 | |
576 | llvm_unreachable("Unable to encode MCOperand!" ); |
577 | } |
578 | |
579 | /// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand. |
580 | bool ARMMCCodeEmitter:: |
581 | EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg, |
582 | unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups, |
583 | const MCSubtargetInfo &STI) const { |
584 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
585 | const MCOperand &MO1 = MI.getOperand(i: OpIdx + 1); |
586 | |
587 | Reg = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO.getReg()); |
588 | |
589 | int32_t SImm = MO1.getImm(); |
590 | bool isAdd = true; |
591 | |
592 | // Special value for #-0 |
593 | if (SImm == INT32_MIN) { |
594 | SImm = 0; |
595 | isAdd = false; |
596 | } |
597 | |
598 | // Immediate is always encoded as positive. The 'U' bit controls add vs sub. |
599 | if (SImm < 0) { |
600 | SImm = -SImm; |
601 | isAdd = false; |
602 | } |
603 | |
604 | Imm = SImm; |
605 | return isAdd; |
606 | } |
607 | |
608 | /// getBranchTargetOpValue - Helper function to get the branch target operand, |
609 | /// which is either an immediate or requires a fixup. |
610 | static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, |
611 | unsigned FixupKind, |
612 | SmallVectorImpl<MCFixup> &Fixups, |
613 | const MCSubtargetInfo &STI) { |
614 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
615 | |
616 | // If the destination is an immediate, we have nothing to do. |
617 | if (MO.isImm()) return MO.getImm(); |
618 | assert(MO.isExpr() && "Unexpected branch target type!" ); |
619 | const MCExpr *Expr = MO.getExpr(); |
620 | MCFixupKind Kind = MCFixupKind(FixupKind); |
621 | Fixups.push_back(Elt: MCFixup::create(Offset: 0, Value: Expr, Kind, Loc: MI.getLoc())); |
622 | |
623 | // All of the information is in the fixup. |
624 | return 0; |
625 | } |
626 | |
627 | // Thumb BL and BLX use a strange offset encoding where bits 22 and 21 are |
628 | // determined by negating them and XOR'ing them with bit 23. |
629 | static int32_t encodeThumbBLOffset(int32_t offset) { |
630 | offset >>= 1; |
631 | uint32_t S = (offset & 0x800000) >> 23; |
632 | uint32_t J1 = (offset & 0x400000) >> 22; |
633 | uint32_t J2 = (offset & 0x200000) >> 21; |
634 | J1 = (~J1 & 0x1); |
635 | J2 = (~J2 & 0x1); |
636 | J1 ^= S; |
637 | J2 ^= S; |
638 | |
639 | offset &= ~0x600000; |
640 | offset |= J1 << 22; |
641 | offset |= J2 << 21; |
642 | |
643 | return offset; |
644 | } |
645 | |
646 | /// getThumbBLTargetOpValue - Return encoding info for immediate branch target. |
647 | uint32_t ARMMCCodeEmitter:: |
648 | getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx, |
649 | SmallVectorImpl<MCFixup> &Fixups, |
650 | const MCSubtargetInfo &STI) const { |
651 | const MCOperand MO = MI.getOperand(i: OpIdx); |
652 | if (MO.isExpr()) |
653 | return ::getBranchTargetOpValue(MI, OpIdx, FixupKind: ARM::fixup_arm_thumb_bl, |
654 | Fixups, STI); |
655 | return encodeThumbBLOffset(offset: MO.getImm()); |
656 | } |
657 | |
658 | /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate |
659 | /// BLX branch target. |
660 | uint32_t ARMMCCodeEmitter:: |
661 | getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, |
662 | SmallVectorImpl<MCFixup> &Fixups, |
663 | const MCSubtargetInfo &STI) const { |
664 | const MCOperand MO = MI.getOperand(i: OpIdx); |
665 | if (MO.isExpr()) |
666 | return ::getBranchTargetOpValue(MI, OpIdx, FixupKind: ARM::fixup_arm_thumb_blx, |
667 | Fixups, STI); |
668 | return encodeThumbBLOffset(offset: MO.getImm()); |
669 | } |
670 | |
671 | /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target. |
672 | uint32_t ARMMCCodeEmitter:: |
673 | getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, |
674 | SmallVectorImpl<MCFixup> &Fixups, |
675 | const MCSubtargetInfo &STI) const { |
676 | const MCOperand MO = MI.getOperand(i: OpIdx); |
677 | if (MO.isExpr()) |
678 | return ::getBranchTargetOpValue(MI, OpIdx, FixupKind: ARM::fixup_arm_thumb_br, |
679 | Fixups, STI); |
680 | return (MO.getImm() >> 1); |
681 | } |
682 | |
683 | /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target. |
684 | uint32_t ARMMCCodeEmitter:: |
685 | getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx, |
686 | SmallVectorImpl<MCFixup> &Fixups, |
687 | const MCSubtargetInfo &STI) const { |
688 | const MCOperand MO = MI.getOperand(i: OpIdx); |
689 | if (MO.isExpr()) |
690 | return ::getBranchTargetOpValue(MI, OpIdx, FixupKind: ARM::fixup_arm_thumb_bcc, |
691 | Fixups, STI); |
692 | return (MO.getImm() >> 1); |
693 | } |
694 | |
695 | /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target. |
696 | uint32_t ARMMCCodeEmitter:: |
697 | getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, |
698 | SmallVectorImpl<MCFixup> &Fixups, |
699 | const MCSubtargetInfo &STI) const { |
700 | const MCOperand MO = MI.getOperand(i: OpIdx); |
701 | if (MO.isExpr()) |
702 | return ::getBranchTargetOpValue(MI, OpIdx, FixupKind: ARM::fixup_arm_thumb_cb, Fixups, STI); |
703 | return (MO.getImm() >> 1); |
704 | } |
705 | |
706 | /// Return true if this branch has a non-always predication |
707 | static bool HasConditionalBranch(const MCInst &MI) { |
708 | int NumOp = MI.getNumOperands(); |
709 | if (NumOp >= 2) { |
710 | for (int i = 0; i < NumOp-1; ++i) { |
711 | const MCOperand &MCOp1 = MI.getOperand(i); |
712 | const MCOperand &MCOp2 = MI.getOperand(i: i + 1); |
713 | if (MCOp1.isImm() && MCOp2.isReg() && |
714 | (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) { |
715 | if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL) |
716 | return true; |
717 | } |
718 | } |
719 | } |
720 | return false; |
721 | } |
722 | |
723 | /// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch |
724 | /// target. |
725 | uint32_t ARMMCCodeEmitter:: |
726 | getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, |
727 | SmallVectorImpl<MCFixup> &Fixups, |
728 | const MCSubtargetInfo &STI) const { |
729 | // FIXME: This really, really shouldn't use TargetMachine. We don't want |
730 | // coupling between MC and TM anywhere we can help it. |
731 | if (isThumb2(STI)) |
732 | return |
733 | ::getBranchTargetOpValue(MI, OpIdx, FixupKind: ARM::fixup_t2_condbranch, Fixups, STI); |
734 | return getARMBranchTargetOpValue(MI, OpIdx, Fixups, STI); |
735 | } |
736 | |
737 | /// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch |
738 | /// target. |
739 | uint32_t ARMMCCodeEmitter:: |
740 | getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, |
741 | SmallVectorImpl<MCFixup> &Fixups, |
742 | const MCSubtargetInfo &STI) const { |
743 | const MCOperand MO = MI.getOperand(i: OpIdx); |
744 | if (MO.isExpr()) { |
745 | if (HasConditionalBranch(MI)) |
746 | return ::getBranchTargetOpValue(MI, OpIdx, |
747 | FixupKind: ARM::fixup_arm_condbranch, Fixups, STI); |
748 | return ::getBranchTargetOpValue(MI, OpIdx, |
749 | FixupKind: ARM::fixup_arm_uncondbranch, Fixups, STI); |
750 | } |
751 | |
752 | return MO.getImm() >> 2; |
753 | } |
754 | |
755 | uint32_t ARMMCCodeEmitter:: |
756 | getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx, |
757 | SmallVectorImpl<MCFixup> &Fixups, |
758 | const MCSubtargetInfo &STI) const { |
759 | const MCOperand MO = MI.getOperand(i: OpIdx); |
760 | if (MO.isExpr()) { |
761 | if (HasConditionalBranch(MI)) |
762 | return ::getBranchTargetOpValue(MI, OpIdx, |
763 | FixupKind: ARM::fixup_arm_condbl, Fixups, STI); |
764 | return ::getBranchTargetOpValue(MI, OpIdx, FixupKind: ARM::fixup_arm_uncondbl, Fixups, STI); |
765 | } |
766 | |
767 | return MO.getImm() >> 2; |
768 | } |
769 | |
770 | uint32_t ARMMCCodeEmitter:: |
771 | getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx, |
772 | SmallVectorImpl<MCFixup> &Fixups, |
773 | const MCSubtargetInfo &STI) const { |
774 | const MCOperand MO = MI.getOperand(i: OpIdx); |
775 | if (MO.isExpr()) |
776 | return ::getBranchTargetOpValue(MI, OpIdx, FixupKind: ARM::fixup_arm_blx, Fixups, STI); |
777 | |
778 | return MO.getImm() >> 1; |
779 | } |
780 | |
781 | /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit |
782 | /// immediate branch target. |
783 | uint32_t ARMMCCodeEmitter::getThumbBranchTargetOpValue( |
784 | const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups, |
785 | const MCSubtargetInfo &STI) const { |
786 | unsigned Val = 0; |
787 | const MCOperand MO = MI.getOperand(i: OpIdx); |
788 | |
789 | if(MO.isExpr()) |
790 | return ::getBranchTargetOpValue(MI, OpIdx, FixupKind: ARM::fixup_t2_uncondbranch, Fixups, STI); |
791 | else |
792 | Val = MO.getImm() >> 1; |
793 | |
794 | bool I = (Val & 0x800000); |
795 | bool J1 = (Val & 0x400000); |
796 | bool J2 = (Val & 0x200000); |
797 | if (I ^ J1) |
798 | Val &= ~0x400000; |
799 | else |
800 | Val |= 0x400000; |
801 | |
802 | if (I ^ J2) |
803 | Val &= ~0x200000; |
804 | else |
805 | Val |= 0x200000; |
806 | |
807 | return Val; |
808 | } |
809 | |
810 | /// getAdrLabelOpValue - Return encoding info for 12-bit shifted-immediate |
811 | /// ADR label target. |
812 | uint32_t ARMMCCodeEmitter:: |
813 | getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, |
814 | SmallVectorImpl<MCFixup> &Fixups, |
815 | const MCSubtargetInfo &STI) const { |
816 | const MCOperand MO = MI.getOperand(i: OpIdx); |
817 | if (MO.isExpr()) |
818 | return ::getBranchTargetOpValue(MI, OpIdx, FixupKind: ARM::fixup_arm_adr_pcrel_12, |
819 | Fixups, STI); |
820 | int64_t offset = MO.getImm(); |
821 | uint32_t Val = 0x2000; |
822 | |
823 | int SoImmVal; |
824 | if (offset == INT32_MIN) { |
825 | Val = 0x1000; |
826 | SoImmVal = 0; |
827 | } else if (offset < 0) { |
828 | Val = 0x1000; |
829 | offset *= -1; |
830 | SoImmVal = ARM_AM::getSOImmVal(Arg: offset); |
831 | if(SoImmVal == -1) { |
832 | Val = 0x2000; |
833 | offset *= -1; |
834 | SoImmVal = ARM_AM::getSOImmVal(Arg: offset); |
835 | } |
836 | } else { |
837 | SoImmVal = ARM_AM::getSOImmVal(Arg: offset); |
838 | if(SoImmVal == -1) { |
839 | Val = 0x1000; |
840 | offset *= -1; |
841 | SoImmVal = ARM_AM::getSOImmVal(Arg: offset); |
842 | } |
843 | } |
844 | |
845 | assert(SoImmVal != -1 && "Not a valid so_imm value!" ); |
846 | |
847 | Val |= SoImmVal; |
848 | return Val; |
849 | } |
850 | |
851 | /// getT2AdrLabelOpValue - Return encoding info for 12-bit immediate ADR label |
852 | /// target. |
853 | uint32_t ARMMCCodeEmitter:: |
854 | getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, |
855 | SmallVectorImpl<MCFixup> &Fixups, |
856 | const MCSubtargetInfo &STI) const { |
857 | const MCOperand MO = MI.getOperand(i: OpIdx); |
858 | if (MO.isExpr()) |
859 | return ::getBranchTargetOpValue(MI, OpIdx, FixupKind: ARM::fixup_t2_adr_pcrel_12, |
860 | Fixups, STI); |
861 | int32_t Val = MO.getImm(); |
862 | if (Val == INT32_MIN) |
863 | Val = 0x1000; |
864 | else if (Val < 0) { |
865 | Val *= -1; |
866 | Val |= 0x1000; |
867 | } |
868 | return Val; |
869 | } |
870 | |
871 | /// getITMaskOpValue - Return the architectural encoding of an IT |
872 | /// predication mask, given the MCOperand format. |
873 | uint32_t ARMMCCodeEmitter:: |
874 | getITMaskOpValue(const MCInst &MI, unsigned OpIdx, |
875 | SmallVectorImpl<MCFixup> &Fixups, |
876 | const MCSubtargetInfo &STI) const { |
877 | const MCOperand MaskMO = MI.getOperand(i: OpIdx); |
878 | assert(MaskMO.isImm() && "Unexpected operand type!" ); |
879 | |
880 | unsigned Mask = MaskMO.getImm(); |
881 | |
882 | // IT masks are encoded as a sequence of replacement low-order bits |
883 | // for the condition code. So if the low bit of the starting |
884 | // condition code is 1, then we have to flip all the bits above the |
885 | // terminating bit (which is the lowest 1 bit). |
886 | assert(OpIdx > 0 && "IT mask appears first!" ); |
887 | const MCOperand CondMO = MI.getOperand(i: OpIdx-1); |
888 | assert(CondMO.isImm() && "Unexpected operand type!" ); |
889 | if (CondMO.getImm() & 1) { |
890 | unsigned LowBit = Mask & -Mask; |
891 | unsigned BitsAboveLowBit = 0xF & (-LowBit << 1); |
892 | Mask ^= BitsAboveLowBit; |
893 | } |
894 | |
895 | return Mask; |
896 | } |
897 | |
898 | /// getThumbAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label |
899 | /// target. |
900 | uint32_t ARMMCCodeEmitter:: |
901 | getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, |
902 | SmallVectorImpl<MCFixup> &Fixups, |
903 | const MCSubtargetInfo &STI) const { |
904 | const MCOperand MO = MI.getOperand(i: OpIdx); |
905 | if (MO.isExpr()) |
906 | return ::getBranchTargetOpValue(MI, OpIdx, FixupKind: ARM::fixup_thumb_adr_pcrel_10, |
907 | Fixups, STI); |
908 | return MO.getImm(); |
909 | } |
910 | |
911 | /// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg' |
912 | /// operand. |
913 | uint32_t ARMMCCodeEmitter:: |
914 | getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, |
915 | SmallVectorImpl<MCFixup> &, |
916 | const MCSubtargetInfo &STI) const { |
917 | // [Rn, Rm] |
918 | // {5-3} = Rm |
919 | // {2-0} = Rn |
920 | const MCOperand &MO1 = MI.getOperand(i: OpIdx); |
921 | const MCOperand &MO2 = MI.getOperand(i: OpIdx + 1); |
922 | unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO1.getReg()); |
923 | unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO2.getReg()); |
924 | return (Rm << 3) | Rn; |
925 | } |
926 | |
927 | /// getMVEShiftImmOpValue - Return encoding info for the 'sz:imm5' |
928 | /// operand. |
929 | uint32_t |
930 | ARMMCCodeEmitter::getMVEShiftImmOpValue(const MCInst &MI, unsigned OpIdx, |
931 | SmallVectorImpl<MCFixup> &Fixups, |
932 | const MCSubtargetInfo &STI) const { |
933 | // {4-0} = szimm5 |
934 | // The value we are trying to encode is an immediate between either the |
935 | // range of [1-7] or [1-15] depending on whether we are dealing with the |
936 | // u8/s8 or the u16/s16 variants respectively. |
937 | // This value is encoded as follows, if ShiftImm is the value within those |
938 | // ranges then the encoding szimm5 = ShiftImm + size, where size is either 8 |
939 | // or 16. |
940 | |
941 | unsigned Size, ShiftImm; |
942 | switch(MI.getOpcode()) { |
943 | case ARM::MVE_VSHLL_imms16bh: |
944 | case ARM::MVE_VSHLL_imms16th: |
945 | case ARM::MVE_VSHLL_immu16bh: |
946 | case ARM::MVE_VSHLL_immu16th: |
947 | Size = 16; |
948 | break; |
949 | case ARM::MVE_VSHLL_imms8bh: |
950 | case ARM::MVE_VSHLL_imms8th: |
951 | case ARM::MVE_VSHLL_immu8bh: |
952 | case ARM::MVE_VSHLL_immu8th: |
953 | Size = 8; |
954 | break; |
955 | default: |
956 | llvm_unreachable("Use of operand not supported by this instruction" ); |
957 | } |
958 | ShiftImm = MI.getOperand(i: OpIdx).getImm(); |
959 | return Size + ShiftImm; |
960 | } |
961 | |
962 | /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand. |
963 | uint32_t ARMMCCodeEmitter:: |
964 | getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, |
965 | SmallVectorImpl<MCFixup> &Fixups, |
966 | const MCSubtargetInfo &STI) const { |
967 | // {17-13} = reg |
968 | // {12} = (U)nsigned (add == '1', sub == '0') |
969 | // {11-0} = imm12 |
970 | unsigned Reg = 0, Imm12 = 0; |
971 | bool isAdd = true; |
972 | // If The first operand isn't a register, we have a label reference. |
973 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
974 | if (MO.isReg()) { |
975 | const MCOperand &MO1 = MI.getOperand(i: OpIdx + 1); |
976 | if (MO1.isImm()) { |
977 | isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm&: Imm12, Fixups, STI); |
978 | } else if (MO1.isExpr()) { |
979 | assert(!isThumb(STI) && !isThumb2(STI) && |
980 | "Thumb mode requires different encoding" ); |
981 | Reg = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO.getReg()); |
982 | isAdd = false; // 'U' bit is set as part of the fixup. |
983 | MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_ldst_abs_12); |
984 | Fixups.push_back(Elt: MCFixup::create(Offset: 0, Value: MO1.getExpr(), Kind, Loc: MI.getLoc())); |
985 | } |
986 | } else if (MO.isExpr()) { |
987 | Reg = CTX.getRegisterInfo()->getEncodingValue(RegNo: ARM::PC); // Rn is PC. |
988 | isAdd = false; // 'U' bit is set as part of the fixup. |
989 | MCFixupKind Kind; |
990 | if (isThumb2(STI)) |
991 | Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12); |
992 | else |
993 | Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12); |
994 | Fixups.push_back(Elt: MCFixup::create(Offset: 0, Value: MO.getExpr(), Kind, Loc: MI.getLoc())); |
995 | |
996 | ++MCNumCPRelocations; |
997 | } else { |
998 | Reg = ARM::PC; |
999 | int32_t Offset = MO.getImm(); |
1000 | if (Offset == INT32_MIN) { |
1001 | Offset = 0; |
1002 | isAdd = false; |
1003 | } else if (Offset < 0) { |
1004 | Offset *= -1; |
1005 | isAdd = false; |
1006 | } |
1007 | Imm12 = Offset; |
1008 | } |
1009 | uint32_t Binary = Imm12 & 0xfff; |
1010 | // Immediate is always encoded as positive. The 'U' bit controls add vs sub. |
1011 | if (isAdd) |
1012 | Binary |= (1 << 12); |
1013 | Binary |= (Reg << 13); |
1014 | return Binary; |
1015 | } |
1016 | |
1017 | template<unsigned Bits, unsigned Shift> |
1018 | uint32_t ARMMCCodeEmitter:: |
1019 | getT2ScaledImmOpValue(const MCInst &MI, unsigned OpIdx, |
1020 | SmallVectorImpl<MCFixup> &Fixups, |
1021 | const MCSubtargetInfo &STI) const { |
1022 | // FIXME: The immediate operand should have already been encoded like this |
1023 | // before ever getting here. The encoder method should just need to combine |
1024 | // the MI operands for the register and the offset into a single |
1025 | // representation for the complex operand in the .td file. This isn't just |
1026 | // style, unfortunately. As-is, we can't represent the distinct encoding |
1027 | // for #-0. |
1028 | |
1029 | // {Bits} = (U)nsigned (add == '1', sub == '0') |
1030 | // {(Bits-1)-0} = immediate |
1031 | int32_t Imm = MI.getOperand(i: OpIdx).getImm(); |
1032 | bool isAdd = Imm >= 0; |
1033 | |
1034 | // Immediate is always encoded as positive. The 'U' bit controls add vs sub. |
1035 | if (Imm < 0) |
1036 | Imm = -(uint32_t)Imm; |
1037 | |
1038 | Imm >>= Shift; |
1039 | |
1040 | uint32_t Binary = Imm & ((1U << Bits) - 1); |
1041 | // Immediate is always encoded as positive. The 'U' bit controls add vs sub. |
1042 | if (isAdd) |
1043 | Binary |= (1U << Bits); |
1044 | return Binary; |
1045 | } |
1046 | |
1047 | /// getMveAddrModeRQOpValue - Return encoding info for 'reg, vreg' |
1048 | /// operand. |
1049 | uint32_t ARMMCCodeEmitter:: |
1050 | getMveAddrModeRQOpValue(const MCInst &MI, unsigned OpIdx, |
1051 | SmallVectorImpl<MCFixup> &Fixups, |
1052 | const MCSubtargetInfo &STI) const { |
1053 | // {6-3} Rn |
1054 | // {2-0} Qm |
1055 | const MCOperand &M0 = MI.getOperand(i: OpIdx); |
1056 | const MCOperand &M1 = MI.getOperand(i: OpIdx + 1); |
1057 | |
1058 | unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(RegNo: M0.getReg()); |
1059 | unsigned Qm = CTX.getRegisterInfo()->getEncodingValue(RegNo: M1.getReg()); |
1060 | |
1061 | assert(Qm < 8 && "Qm is supposed to be encodable in 3 bits" ); |
1062 | |
1063 | return (Rn << 3) | Qm; |
1064 | } |
1065 | |
1066 | /// getMveAddrModeRQOpValue - Return encoding info for 'reg, vreg' |
1067 | /// operand. |
1068 | template<int shift> |
1069 | uint32_t ARMMCCodeEmitter:: |
1070 | getMveAddrModeQOpValue(const MCInst &MI, unsigned OpIdx, |
1071 | SmallVectorImpl<MCFixup> &Fixups, |
1072 | const MCSubtargetInfo &STI) const { |
1073 | // {10-8} Qm |
1074 | // {7-0} Imm |
1075 | const MCOperand &M0 = MI.getOperand(i: OpIdx); |
1076 | const MCOperand &M1 = MI.getOperand(i: OpIdx + 1); |
1077 | |
1078 | unsigned Qm = CTX.getRegisterInfo()->getEncodingValue(RegNo: M0.getReg()); |
1079 | int32_t Imm = M1.getImm(); |
1080 | |
1081 | bool isAdd = Imm >= 0; |
1082 | |
1083 | Imm >>= shift; |
1084 | |
1085 | if (!isAdd) |
1086 | Imm = -(uint32_t)Imm; |
1087 | |
1088 | Imm &= 0x7f; |
1089 | |
1090 | if (isAdd) |
1091 | Imm |= 0x80; |
1092 | |
1093 | assert(Qm < 8 && "Qm is supposed to be encodable in 3 bits" ); |
1094 | |
1095 | return (Qm << 8) | Imm; |
1096 | } |
1097 | |
1098 | /// getT2AddrModeImm8s4OpValue - Return encoding info for |
1099 | /// 'reg +/- imm8<<2' operand. |
1100 | uint32_t ARMMCCodeEmitter:: |
1101 | getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, |
1102 | SmallVectorImpl<MCFixup> &Fixups, |
1103 | const MCSubtargetInfo &STI) const { |
1104 | // {12-9} = reg |
1105 | // {8} = (U)nsigned (add == '1', sub == '0') |
1106 | // {7-0} = imm8 |
1107 | unsigned Reg, Imm8; |
1108 | bool isAdd = true; |
1109 | // If The first operand isn't a register, we have a label reference. |
1110 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
1111 | if (!MO.isReg()) { |
1112 | Reg = CTX.getRegisterInfo()->getEncodingValue(RegNo: ARM::PC); // Rn is PC. |
1113 | Imm8 = 0; |
1114 | isAdd = false ; // 'U' bit is set as part of the fixup. |
1115 | |
1116 | assert(MO.isExpr() && "Unexpected machine operand type!" ); |
1117 | const MCExpr *Expr = MO.getExpr(); |
1118 | MCFixupKind Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); |
1119 | Fixups.push_back(Elt: MCFixup::create(Offset: 0, Value: Expr, Kind, Loc: MI.getLoc())); |
1120 | |
1121 | ++MCNumCPRelocations; |
1122 | } else |
1123 | isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm&: Imm8, Fixups, STI); |
1124 | |
1125 | // FIXME: The immediate operand should have already been encoded like this |
1126 | // before ever getting here. The encoder method should just need to combine |
1127 | // the MI operands for the register and the offset into a single |
1128 | // representation for the complex operand in the .td file. This isn't just |
1129 | // style, unfortunately. As-is, we can't represent the distinct encoding |
1130 | // for #-0. |
1131 | assert(((Imm8 & 0x3) == 0) && "Not a valid immediate!" ); |
1132 | uint32_t Binary = (Imm8 >> 2) & 0xff; |
1133 | // Immediate is always encoded as positive. The 'U' bit controls add vs sub. |
1134 | if (isAdd) |
1135 | Binary |= (1 << 8); |
1136 | Binary |= (Reg << 9); |
1137 | return Binary; |
1138 | } |
1139 | |
1140 | /// getT2AddrModeImm7s4OpValue - Return encoding info for |
1141 | /// 'reg +/- imm7<<2' operand. |
1142 | uint32_t |
1143 | ARMMCCodeEmitter::getT2AddrModeImm7s4OpValue(const MCInst &MI, unsigned OpIdx, |
1144 | SmallVectorImpl<MCFixup> &Fixups, |
1145 | const MCSubtargetInfo &STI) const { |
1146 | // {11-8} = reg |
1147 | // {7} = (A)dd (add == '1', sub == '0') |
1148 | // {6-0} = imm7 |
1149 | unsigned Reg, Imm7; |
1150 | // If The first operand isn't a register, we have a label reference. |
1151 | bool isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm&: Imm7, Fixups, STI); |
1152 | |
1153 | // FIXME: The immediate operand should have already been encoded like this |
1154 | // before ever getting here. The encoder method should just need to combine |
1155 | // the MI operands for the register and the offset into a single |
1156 | // representation for the complex operand in the .td file. This isn't just |
1157 | // style, unfortunately. As-is, we can't represent the distinct encoding |
1158 | // for #-0. |
1159 | uint32_t Binary = (Imm7 >> 2) & 0xff; |
1160 | // Immediate is always encoded as positive. The 'A' bit controls add vs sub. |
1161 | if (isAdd) |
1162 | Binary |= (1 << 7); |
1163 | Binary |= (Reg << 8); |
1164 | return Binary; |
1165 | } |
1166 | |
1167 | /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for |
1168 | /// 'reg + imm8<<2' operand. |
1169 | uint32_t ARMMCCodeEmitter:: |
1170 | getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx, |
1171 | SmallVectorImpl<MCFixup> &Fixups, |
1172 | const MCSubtargetInfo &STI) const { |
1173 | // {11-8} = reg |
1174 | // {7-0} = imm8 |
1175 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
1176 | const MCOperand &MO1 = MI.getOperand(i: OpIdx + 1); |
1177 | unsigned Reg = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO.getReg()); |
1178 | unsigned Imm8 = MO1.getImm(); |
1179 | return (Reg << 8) | Imm8; |
1180 | } |
1181 | |
1182 | uint32_t ARMMCCodeEmitter::getHiLoImmOpValue(const MCInst &MI, unsigned OpIdx, |
1183 | SmallVectorImpl<MCFixup> &Fixups, |
1184 | const MCSubtargetInfo &STI) const { |
1185 | // {20-16} = imm{15-12} |
1186 | // {11-0} = imm{11-0} |
1187 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
1188 | if (MO.isImm()) |
1189 | // Hi / lo bits already extracted during earlier passes. |
1190 | return static_cast<unsigned>(MO.getImm()); |
1191 | |
1192 | // Handle :upper16:, :lower16:, :upper8_15:, :upper0_7:, :lower8_15: |
1193 | // :lower0_7: assembly prefixes. |
1194 | const MCExpr *E = MO.getExpr(); |
1195 | MCFixupKind Kind; |
1196 | if (E->getKind() == MCExpr::Target) { |
1197 | const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(Val: E); |
1198 | E = ARM16Expr->getSubExpr(); |
1199 | |
1200 | if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Val: E)) { |
1201 | const int64_t Value = MCE->getValue(); |
1202 | if (Value > UINT32_MAX) |
1203 | report_fatal_error(reason: "constant value truncated (limited to 32-bit)" ); |
1204 | |
1205 | switch (ARM16Expr->getKind()) { |
1206 | case ARMMCExpr::VK_ARM_HI16: |
1207 | return (int32_t(Value) & 0xffff0000) >> 16; |
1208 | case ARMMCExpr::VK_ARM_LO16: |
1209 | return (int32_t(Value) & 0x0000ffff); |
1210 | |
1211 | case ARMMCExpr::VK_ARM_HI_8_15: |
1212 | return (int32_t(Value) & 0xff000000) >> 24; |
1213 | case ARMMCExpr::VK_ARM_HI_0_7: |
1214 | return (int32_t(Value) & 0x00ff0000) >> 16; |
1215 | case ARMMCExpr::VK_ARM_LO_8_15: |
1216 | return (int32_t(Value) & 0x0000ff00) >> 8; |
1217 | case ARMMCExpr::VK_ARM_LO_0_7: |
1218 | return (int32_t(Value) & 0x000000ff); |
1219 | |
1220 | default: llvm_unreachable("Unsupported ARMFixup" ); |
1221 | } |
1222 | } |
1223 | |
1224 | switch (ARM16Expr->getKind()) { |
1225 | default: llvm_unreachable("Unsupported ARMFixup" ); |
1226 | case ARMMCExpr::VK_ARM_HI16: |
1227 | Kind = MCFixupKind(isThumb(STI) ? ARM::fixup_t2_movt_hi16 |
1228 | : ARM::fixup_arm_movt_hi16); |
1229 | break; |
1230 | case ARMMCExpr::VK_ARM_LO16: |
1231 | Kind = MCFixupKind(isThumb(STI) ? ARM::fixup_t2_movw_lo16 |
1232 | : ARM::fixup_arm_movw_lo16); |
1233 | break; |
1234 | case ARMMCExpr::VK_ARM_HI_8_15: |
1235 | if (!isThumb(STI)) |
1236 | llvm_unreachable(":upper_8_15: not supported in Arm state" ); |
1237 | Kind = MCFixupKind(ARM::fixup_arm_thumb_upper_8_15); |
1238 | break; |
1239 | case ARMMCExpr::VK_ARM_HI_0_7: |
1240 | if (!isThumb(STI)) |
1241 | llvm_unreachable(":upper_0_7: not supported in Arm state" ); |
1242 | Kind = MCFixupKind(ARM::fixup_arm_thumb_upper_0_7); |
1243 | break; |
1244 | case ARMMCExpr::VK_ARM_LO_8_15: |
1245 | if (!isThumb(STI)) |
1246 | llvm_unreachable(":lower_8_15: not supported in Arm state" ); |
1247 | Kind = MCFixupKind(ARM::fixup_arm_thumb_lower_8_15); |
1248 | break; |
1249 | case ARMMCExpr::VK_ARM_LO_0_7: |
1250 | if (!isThumb(STI)) |
1251 | llvm_unreachable(":lower_0_7: not supported in Arm state" ); |
1252 | Kind = MCFixupKind(ARM::fixup_arm_thumb_lower_0_7); |
1253 | break; |
1254 | } |
1255 | |
1256 | Fixups.push_back(Elt: MCFixup::create(Offset: 0, Value: E, Kind, Loc: MI.getLoc())); |
1257 | return 0; |
1258 | } |
1259 | // If the expression doesn't have :upper16:, :lower16: on it, it's just a |
1260 | // plain immediate expression, previously those evaluated to the lower 16 bits |
1261 | // of the expression regardless of whether we have a movt or a movw, but that |
1262 | // led to misleadingly results. This is disallowed in the AsmParser in |
1263 | // validateInstruction() so this should never happen. The same holds for |
1264 | // thumb1 :upper8_15:, :upper0_7:, lower8_15: or :lower0_7: with movs or adds. |
1265 | llvm_unreachable("expression without :upper16:, :lower16:, :upper8_15:," |
1266 | ":upper0_7:, lower8_15: or :lower0_7:" ); |
1267 | } |
1268 | |
1269 | uint32_t ARMMCCodeEmitter:: |
1270 | getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx, |
1271 | SmallVectorImpl<MCFixup> &Fixups, |
1272 | const MCSubtargetInfo &STI) const { |
1273 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
1274 | const MCOperand &MO1 = MI.getOperand(i: OpIdx+1); |
1275 | const MCOperand &MO2 = MI.getOperand(i: OpIdx+2); |
1276 | unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO.getReg()); |
1277 | unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO1.getReg()); |
1278 | unsigned ShImm = ARM_AM::getAM2Offset(AM2Opc: MO2.getImm()); |
1279 | bool isAdd = ARM_AM::getAM2Op(AM2Opc: MO2.getImm()) == ARM_AM::add; |
1280 | ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(AM2Opc: MO2.getImm()); |
1281 | unsigned SBits = getShiftOp(ShOpc: ShOp); |
1282 | |
1283 | // While "lsr #32" and "asr #32" exist, they are encoded with a 0 in the shift |
1284 | // amount. However, it would be an easy mistake to make so check here. |
1285 | assert((ShImm & ~0x1f) == 0 && "Out of range shift amount" ); |
1286 | |
1287 | // {16-13} = Rn |
1288 | // {12} = isAdd |
1289 | // {11-0} = shifter |
1290 | // {3-0} = Rm |
1291 | // {4} = 0 |
1292 | // {6-5} = type |
1293 | // {11-7} = imm |
1294 | uint32_t Binary = Rm; |
1295 | Binary |= Rn << 13; |
1296 | Binary |= SBits << 5; |
1297 | Binary |= ShImm << 7; |
1298 | if (isAdd) |
1299 | Binary |= 1 << 12; |
1300 | return Binary; |
1301 | } |
1302 | |
1303 | uint32_t ARMMCCodeEmitter:: |
1304 | getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx, |
1305 | SmallVectorImpl<MCFixup> &Fixups, |
1306 | const MCSubtargetInfo &STI) const { |
1307 | // {13} 1 == imm12, 0 == Rm |
1308 | // {12} isAdd |
1309 | // {11-0} imm12/Rm |
1310 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
1311 | const MCOperand &MO1 = MI.getOperand(i: OpIdx+1); |
1312 | unsigned Imm = MO1.getImm(); |
1313 | bool isAdd = ARM_AM::getAM2Op(AM2Opc: Imm) == ARM_AM::add; |
1314 | bool isReg = MO.getReg() != 0; |
1315 | uint32_t Binary = ARM_AM::getAM2Offset(AM2Opc: Imm); |
1316 | // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12 |
1317 | if (isReg) { |
1318 | ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(AM2Opc: Imm); |
1319 | Binary <<= 7; // Shift amount is bits [11:7] |
1320 | Binary |= getShiftOp(ShOpc: ShOp) << 5; // Shift type is bits [6:5] |
1321 | Binary |= CTX.getRegisterInfo()->getEncodingValue(RegNo: MO.getReg()); // Rm is bits [3:0] |
1322 | } |
1323 | return Binary | (isAdd << 12) | (isReg << 13); |
1324 | } |
1325 | |
1326 | uint32_t ARMMCCodeEmitter:: |
1327 | getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx, |
1328 | SmallVectorImpl<MCFixup> &Fixups, |
1329 | const MCSubtargetInfo &STI) const { |
1330 | // {4} isAdd |
1331 | // {3-0} Rm |
1332 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
1333 | const MCOperand &MO1 = MI.getOperand(i: OpIdx+1); |
1334 | bool isAdd = MO1.getImm() != 0; |
1335 | return CTX.getRegisterInfo()->getEncodingValue(RegNo: MO.getReg()) | (isAdd << 4); |
1336 | } |
1337 | |
1338 | uint32_t ARMMCCodeEmitter:: |
1339 | getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx, |
1340 | SmallVectorImpl<MCFixup> &Fixups, |
1341 | const MCSubtargetInfo &STI) const { |
1342 | // {9} 1 == imm8, 0 == Rm |
1343 | // {8} isAdd |
1344 | // {7-4} imm7_4/zero |
1345 | // {3-0} imm3_0/Rm |
1346 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
1347 | const MCOperand &MO1 = MI.getOperand(i: OpIdx+1); |
1348 | unsigned Imm = MO1.getImm(); |
1349 | bool isAdd = ARM_AM::getAM3Op(AM3Opc: Imm) == ARM_AM::add; |
1350 | bool isImm = MO.getReg() == 0; |
1351 | uint32_t Imm8 = ARM_AM::getAM3Offset(AM3Opc: Imm); |
1352 | // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 |
1353 | if (!isImm) |
1354 | Imm8 = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO.getReg()); |
1355 | return Imm8 | (isAdd << 8) | (isImm << 9); |
1356 | } |
1357 | |
1358 | uint32_t ARMMCCodeEmitter:: |
1359 | getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, |
1360 | SmallVectorImpl<MCFixup> &Fixups, |
1361 | const MCSubtargetInfo &STI) const { |
1362 | // {13} 1 == imm8, 0 == Rm |
1363 | // {12-9} Rn |
1364 | // {8} isAdd |
1365 | // {7-4} imm7_4/zero |
1366 | // {3-0} imm3_0/Rm |
1367 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
1368 | const MCOperand &MO1 = MI.getOperand(i: OpIdx+1); |
1369 | const MCOperand &MO2 = MI.getOperand(i: OpIdx+2); |
1370 | |
1371 | // If The first operand isn't a register, we have a label reference. |
1372 | if (!MO.isReg()) { |
1373 | unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(RegNo: ARM::PC); // Rn is PC. |
1374 | |
1375 | assert(MO.isExpr() && "Unexpected machine operand type!" ); |
1376 | const MCExpr *Expr = MO.getExpr(); |
1377 | MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10_unscaled); |
1378 | Fixups.push_back(Elt: MCFixup::create(Offset: 0, Value: Expr, Kind, Loc: MI.getLoc())); |
1379 | |
1380 | ++MCNumCPRelocations; |
1381 | return (Rn << 9) | (1 << 13); |
1382 | } |
1383 | unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO.getReg()); |
1384 | unsigned Imm = MO2.getImm(); |
1385 | bool isAdd = ARM_AM::getAM3Op(AM3Opc: Imm) == ARM_AM::add; |
1386 | bool isImm = MO1.getReg() == 0; |
1387 | uint32_t Imm8 = ARM_AM::getAM3Offset(AM3Opc: Imm); |
1388 | // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8 |
1389 | if (!isImm) |
1390 | Imm8 = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO1.getReg()); |
1391 | return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13); |
1392 | } |
1393 | |
1394 | /// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands. |
1395 | uint32_t ARMMCCodeEmitter:: |
1396 | getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, |
1397 | SmallVectorImpl<MCFixup> &Fixups, |
1398 | const MCSubtargetInfo &STI) const { |
1399 | // [SP, #imm] |
1400 | // {7-0} = imm8 |
1401 | const MCOperand &MO1 = MI.getOperand(i: OpIdx + 1); |
1402 | assert(MI.getOperand(OpIdx).getReg() == ARM::SP && |
1403 | "Unexpected base register!" ); |
1404 | |
1405 | // The immediate is already shifted for the implicit zeroes, so no change |
1406 | // here. |
1407 | return MO1.getImm() & 0xff; |
1408 | } |
1409 | |
1410 | /// getAddrModeISOpValue - Encode the t_addrmode_is# operands. |
1411 | uint32_t ARMMCCodeEmitter:: |
1412 | getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, |
1413 | SmallVectorImpl<MCFixup> &Fixups, |
1414 | const MCSubtargetInfo &STI) const { |
1415 | // [Rn, #imm] |
1416 | // {7-3} = imm5 |
1417 | // {2-0} = Rn |
1418 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
1419 | const MCOperand &MO1 = MI.getOperand(i: OpIdx + 1); |
1420 | unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO.getReg()); |
1421 | unsigned Imm5 = MO1.getImm(); |
1422 | return ((Imm5 & 0x1f) << 3) | Rn; |
1423 | } |
1424 | |
1425 | /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. |
1426 | uint32_t ARMMCCodeEmitter:: |
1427 | getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, |
1428 | SmallVectorImpl<MCFixup> &Fixups, |
1429 | const MCSubtargetInfo &STI) const { |
1430 | const MCOperand MO = MI.getOperand(i: OpIdx); |
1431 | if (MO.isExpr()) |
1432 | return ::getBranchTargetOpValue(MI, OpIdx, FixupKind: ARM::fixup_arm_thumb_cp, Fixups, STI); |
1433 | return (MO.getImm() >> 2); |
1434 | } |
1435 | |
1436 | /// getAddrMode5OpValue - Return encoding info for 'reg +/- (imm8 << 2)' operand. |
1437 | uint32_t ARMMCCodeEmitter:: |
1438 | getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, |
1439 | SmallVectorImpl<MCFixup> &Fixups, |
1440 | const MCSubtargetInfo &STI) const { |
1441 | // {12-9} = reg |
1442 | // {8} = (U)nsigned (add == '1', sub == '0') |
1443 | // {7-0} = imm8 |
1444 | unsigned Reg, Imm8; |
1445 | bool isAdd; |
1446 | // If The first operand isn't a register, we have a label reference. |
1447 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
1448 | if (!MO.isReg()) { |
1449 | Reg = CTX.getRegisterInfo()->getEncodingValue(RegNo: ARM::PC); // Rn is PC. |
1450 | Imm8 = 0; |
1451 | isAdd = false; // 'U' bit is handled as part of the fixup. |
1452 | |
1453 | assert(MO.isExpr() && "Unexpected machine operand type!" ); |
1454 | const MCExpr *Expr = MO.getExpr(); |
1455 | MCFixupKind Kind; |
1456 | if (isThumb2(STI)) |
1457 | Kind = MCFixupKind(ARM::fixup_t2_pcrel_10); |
1458 | else |
1459 | Kind = MCFixupKind(ARM::fixup_arm_pcrel_10); |
1460 | Fixups.push_back(Elt: MCFixup::create(Offset: 0, Value: Expr, Kind, Loc: MI.getLoc())); |
1461 | |
1462 | ++MCNumCPRelocations; |
1463 | } else { |
1464 | EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm&: Imm8, Fixups, STI); |
1465 | isAdd = ARM_AM::getAM5Op(AM5Opc: Imm8) == ARM_AM::add; |
1466 | } |
1467 | |
1468 | uint32_t Binary = ARM_AM::getAM5Offset(AM5Opc: Imm8); |
1469 | // Immediate is always encoded as positive. The 'U' bit controls add vs sub. |
1470 | if (isAdd) |
1471 | Binary |= (1 << 8); |
1472 | Binary |= (Reg << 9); |
1473 | return Binary; |
1474 | } |
1475 | |
1476 | /// getAddrMode5FP16OpValue - Return encoding info for 'reg +/- (imm8 << 1)' operand. |
1477 | uint32_t ARMMCCodeEmitter:: |
1478 | getAddrMode5FP16OpValue(const MCInst &MI, unsigned OpIdx, |
1479 | SmallVectorImpl<MCFixup> &Fixups, |
1480 | const MCSubtargetInfo &STI) const { |
1481 | // {12-9} = reg |
1482 | // {8} = (U)nsigned (add == '1', sub == '0') |
1483 | // {7-0} = imm8 |
1484 | unsigned Reg, Imm8; |
1485 | bool isAdd; |
1486 | // If The first operand isn't a register, we have a label reference. |
1487 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
1488 | if (!MO.isReg()) { |
1489 | Reg = CTX.getRegisterInfo()->getEncodingValue(RegNo: ARM::PC); // Rn is PC. |
1490 | Imm8 = 0; |
1491 | isAdd = false; // 'U' bit is handled as part of the fixup. |
1492 | |
1493 | assert(MO.isExpr() && "Unexpected machine operand type!" ); |
1494 | const MCExpr *Expr = MO.getExpr(); |
1495 | MCFixupKind Kind; |
1496 | if (isThumb2(STI)) |
1497 | Kind = MCFixupKind(ARM::fixup_t2_pcrel_9); |
1498 | else |
1499 | Kind = MCFixupKind(ARM::fixup_arm_pcrel_9); |
1500 | Fixups.push_back(Elt: MCFixup::create(Offset: 0, Value: Expr, Kind, Loc: MI.getLoc())); |
1501 | |
1502 | ++MCNumCPRelocations; |
1503 | } else { |
1504 | EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm&: Imm8, Fixups, STI); |
1505 | isAdd = ARM_AM::getAM5Op(AM5Opc: Imm8) == ARM_AM::add; |
1506 | } |
1507 | |
1508 | uint32_t Binary = ARM_AM::getAM5Offset(AM5Opc: Imm8); |
1509 | // Immediate is always encoded as positive. The 'U' bit controls add vs sub. |
1510 | if (isAdd) |
1511 | Binary |= (1 << 8); |
1512 | Binary |= (Reg << 9); |
1513 | return Binary; |
1514 | } |
1515 | |
1516 | unsigned ARMMCCodeEmitter:: |
1517 | getSORegRegOpValue(const MCInst &MI, unsigned OpIdx, |
1518 | SmallVectorImpl<MCFixup> &Fixups, |
1519 | const MCSubtargetInfo &STI) const { |
1520 | // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be |
1521 | // shifted. The second is Rs, the amount to shift by, and the third specifies |
1522 | // the type of the shift. |
1523 | // |
1524 | // {3-0} = Rm. |
1525 | // {4} = 1 |
1526 | // {6-5} = type |
1527 | // {11-8} = Rs |
1528 | // {7} = 0 |
1529 | |
1530 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
1531 | const MCOperand &MO1 = MI.getOperand(i: OpIdx + 1); |
1532 | const MCOperand &MO2 = MI.getOperand(i: OpIdx + 2); |
1533 | ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Op: MO2.getImm()); |
1534 | |
1535 | // Encode Rm. |
1536 | unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO.getReg()); |
1537 | |
1538 | // Encode the shift opcode. |
1539 | unsigned SBits = 0; |
1540 | unsigned Rs = MO1.getReg(); |
1541 | if (Rs) { |
1542 | // Set shift operand (bit[7:4]). |
1543 | // LSL - 0001 |
1544 | // LSR - 0011 |
1545 | // ASR - 0101 |
1546 | // ROR - 0111 |
1547 | switch (SOpc) { |
1548 | default: llvm_unreachable("Unknown shift opc!" ); |
1549 | case ARM_AM::lsl: SBits = 0x1; break; |
1550 | case ARM_AM::lsr: SBits = 0x3; break; |
1551 | case ARM_AM::asr: SBits = 0x5; break; |
1552 | case ARM_AM::ror: SBits = 0x7; break; |
1553 | } |
1554 | } |
1555 | |
1556 | Binary |= SBits << 4; |
1557 | |
1558 | // Encode the shift operation Rs. |
1559 | // Encode Rs bit[11:8]. |
1560 | assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0); |
1561 | return Binary | (CTX.getRegisterInfo()->getEncodingValue(RegNo: Rs) << ARMII::RegRsShift); |
1562 | } |
1563 | |
1564 | unsigned ARMMCCodeEmitter:: |
1565 | getSORegImmOpValue(const MCInst &MI, unsigned OpIdx, |
1566 | SmallVectorImpl<MCFixup> &Fixups, |
1567 | const MCSubtargetInfo &STI) const { |
1568 | // Sub-operands are [reg, imm]. The first register is Rm, the reg to be |
1569 | // shifted. The second is the amount to shift by. |
1570 | // |
1571 | // {3-0} = Rm. |
1572 | // {4} = 0 |
1573 | // {6-5} = type |
1574 | // {11-7} = imm |
1575 | |
1576 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
1577 | const MCOperand &MO1 = MI.getOperand(i: OpIdx + 1); |
1578 | ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Op: MO1.getImm()); |
1579 | |
1580 | // Encode Rm. |
1581 | unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO.getReg()); |
1582 | |
1583 | // Encode the shift opcode. |
1584 | unsigned SBits = 0; |
1585 | |
1586 | // Set shift operand (bit[6:4]). |
1587 | // LSL - 000 |
1588 | // LSR - 010 |
1589 | // ASR - 100 |
1590 | // ROR - 110 |
1591 | // RRX - 110 and bit[11:8] clear. |
1592 | switch (SOpc) { |
1593 | default: llvm_unreachable("Unknown shift opc!" ); |
1594 | case ARM_AM::lsl: SBits = 0x0; break; |
1595 | case ARM_AM::lsr: SBits = 0x2; break; |
1596 | case ARM_AM::asr: SBits = 0x4; break; |
1597 | case ARM_AM::ror: SBits = 0x6; break; |
1598 | case ARM_AM::rrx: |
1599 | Binary |= 0x60; |
1600 | return Binary; |
1601 | } |
1602 | |
1603 | // Encode shift_imm bit[11:7]. |
1604 | Binary |= SBits << 4; |
1605 | unsigned Offset = ARM_AM::getSORegOffset(Op: MO1.getImm()); |
1606 | assert(Offset < 32 && "Offset must be in range 0-31!" ); |
1607 | return Binary | (Offset << 7); |
1608 | } |
1609 | |
1610 | |
1611 | unsigned ARMMCCodeEmitter:: |
1612 | getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, |
1613 | SmallVectorImpl<MCFixup> &Fixups, |
1614 | const MCSubtargetInfo &STI) const { |
1615 | const MCOperand &MO1 = MI.getOperand(i: OpNum); |
1616 | const MCOperand &MO2 = MI.getOperand(i: OpNum+1); |
1617 | const MCOperand &MO3 = MI.getOperand(i: OpNum+2); |
1618 | |
1619 | // Encoded as [Rn, Rm, imm]. |
1620 | // FIXME: Needs fixup support. |
1621 | unsigned Value = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO1.getReg()); |
1622 | Value <<= 4; |
1623 | Value |= CTX.getRegisterInfo()->getEncodingValue(RegNo: MO2.getReg()); |
1624 | Value <<= 2; |
1625 | Value |= MO3.getImm(); |
1626 | |
1627 | return Value; |
1628 | } |
1629 | |
1630 | template<unsigned Bits, unsigned Shift> |
1631 | unsigned ARMMCCodeEmitter:: |
1632 | getT2AddrModeImmOpValue(const MCInst &MI, unsigned OpNum, |
1633 | SmallVectorImpl<MCFixup> &Fixups, |
1634 | const MCSubtargetInfo &STI) const { |
1635 | const MCOperand &MO1 = MI.getOperand(i: OpNum); |
1636 | const MCOperand &MO2 = MI.getOperand(i: OpNum+1); |
1637 | |
1638 | // FIXME: Needs fixup support. |
1639 | unsigned Value = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO1.getReg()); |
1640 | |
1641 | // If the immediate is B bits long, we need B+1 bits in order |
1642 | // to represent the (inverse of the) sign bit. |
1643 | Value <<= (Bits + 1); |
1644 | int32_t tmp = (int32_t)MO2.getImm(); |
1645 | if (tmp == INT32_MIN) { // represents subtracting zero rather than adding it |
1646 | tmp = 0; |
1647 | } else if (tmp < 0) { |
1648 | tmp = abs(x: tmp); |
1649 | } else { |
1650 | Value |= (1U << Bits); // Set the ADD bit |
1651 | } |
1652 | Value |= (tmp >> Shift) & ((1U << Bits) - 1); |
1653 | return Value; |
1654 | } |
1655 | |
1656 | unsigned ARMMCCodeEmitter:: |
1657 | getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum, |
1658 | SmallVectorImpl<MCFixup> &Fixups, |
1659 | const MCSubtargetInfo &STI) const { |
1660 | const MCOperand &MO1 = MI.getOperand(i: OpNum); |
1661 | |
1662 | // FIXME: Needs fixup support. |
1663 | unsigned Value = 0; |
1664 | auto tmp = static_cast<uint32_t>(MO1.getImm()); |
1665 | if (static_cast<int32_t>(tmp) < 0) |
1666 | tmp = -tmp; |
1667 | else |
1668 | Value |= 256; // Set the ADD bit |
1669 | Value |= tmp & 255; |
1670 | return Value; |
1671 | } |
1672 | |
1673 | unsigned ARMMCCodeEmitter:: |
1674 | getT2SORegOpValue(const MCInst &MI, unsigned OpIdx, |
1675 | SmallVectorImpl<MCFixup> &Fixups, |
1676 | const MCSubtargetInfo &STI) const { |
1677 | // Sub-operands are [reg, imm]. The first register is Rm, the reg to be |
1678 | // shifted. The second is the amount to shift by. |
1679 | // |
1680 | // {3-0} = Rm. |
1681 | // {4} = 0 |
1682 | // {6-5} = type |
1683 | // {11-7} = imm |
1684 | |
1685 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
1686 | const MCOperand &MO1 = MI.getOperand(i: OpIdx + 1); |
1687 | ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Op: MO1.getImm()); |
1688 | |
1689 | // Encode Rm. |
1690 | unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(RegNo: MO.getReg()); |
1691 | |
1692 | // Encode the shift opcode. |
1693 | unsigned SBits = 0; |
1694 | // Set shift operand (bit[6:4]). |
1695 | // LSL - 000 |
1696 | // LSR - 010 |
1697 | // ASR - 100 |
1698 | // ROR - 110 |
1699 | switch (SOpc) { |
1700 | default: llvm_unreachable("Unknown shift opc!" ); |
1701 | case ARM_AM::lsl: SBits = 0x0; break; |
1702 | case ARM_AM::lsr: SBits = 0x2; break; |
1703 | case ARM_AM::asr: SBits = 0x4; break; |
1704 | case ARM_AM::rrx: [[fallthrough]]; |
1705 | case ARM_AM::ror: SBits = 0x6; break; |
1706 | } |
1707 | |
1708 | Binary |= SBits << 4; |
1709 | if (SOpc == ARM_AM::rrx) |
1710 | return Binary; |
1711 | |
1712 | // Encode shift_imm bit[11:7]. |
1713 | return Binary | ARM_AM::getSORegOffset(Op: MO1.getImm()) << 7; |
1714 | } |
1715 | |
1716 | unsigned ARMMCCodeEmitter:: |
1717 | getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, |
1718 | SmallVectorImpl<MCFixup> &Fixups, |
1719 | const MCSubtargetInfo &STI) const { |
1720 | // 10 bits. lower 5 bits are the lsb of the mask, high five bits are the |
1721 | // msb of the mask. |
1722 | const MCOperand &MO = MI.getOperand(i: Op); |
1723 | uint32_t v = ~MO.getImm(); |
1724 | uint32_t lsb = llvm::countr_zero(Val: v); |
1725 | uint32_t msb = llvm::Log2_32(Value: v); |
1726 | assert(v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!" ); |
1727 | return lsb | (msb << 5); |
1728 | } |
1729 | |
1730 | unsigned ARMMCCodeEmitter:: |
1731 | getRegisterListOpValue(const MCInst &MI, unsigned Op, |
1732 | SmallVectorImpl<MCFixup> &Fixups, |
1733 | const MCSubtargetInfo &STI) const { |
1734 | // VLDM/VSTM/VSCCLRM: |
1735 | // {12-8} = Vd |
1736 | // {7-0} = Number of registers |
1737 | // |
1738 | // LDM/STM: |
1739 | // {15-0} = Bitfield of GPRs. |
1740 | unsigned Reg = MI.getOperand(i: Op).getReg(); |
1741 | bool SPRRegs = ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg); |
1742 | bool DPRRegs = ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg); |
1743 | |
1744 | unsigned Binary = 0; |
1745 | |
1746 | if (SPRRegs || DPRRegs) { |
1747 | // VLDM/VSTM/VSCCLRM |
1748 | unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(RegNo: Reg); |
1749 | unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff; |
1750 | Binary |= (RegNo & 0x1f) << 8; |
1751 | |
1752 | // Ignore VPR |
1753 | if (MI.getOpcode() == ARM::VSCCLRMD || MI.getOpcode() == ARM::VSCCLRMS) |
1754 | --NumRegs; |
1755 | if (SPRRegs) |
1756 | Binary |= NumRegs; |
1757 | else |
1758 | Binary |= NumRegs * 2; |
1759 | } else { |
1760 | const MCRegisterInfo &MRI = *CTX.getRegisterInfo(); |
1761 | assert(is_sorted(drop_begin(MI, Op), |
1762 | [&](const MCOperand &LHS, const MCOperand &RHS) { |
1763 | return MRI.getEncodingValue(LHS.getReg()) < |
1764 | MRI.getEncodingValue(RHS.getReg()); |
1765 | })); |
1766 | for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) { |
1767 | unsigned RegNo = MRI.getEncodingValue(RegNo: MI.getOperand(i: I).getReg()); |
1768 | Binary |= 1 << RegNo; |
1769 | } |
1770 | } |
1771 | |
1772 | return Binary; |
1773 | } |
1774 | |
1775 | /// getAddrMode6AddressOpValue - Encode an addrmode6 register number along |
1776 | /// with the alignment operand. |
1777 | unsigned ARMMCCodeEmitter:: |
1778 | getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, |
1779 | SmallVectorImpl<MCFixup> &Fixups, |
1780 | const MCSubtargetInfo &STI) const { |
1781 | const MCOperand &Reg = MI.getOperand(i: Op); |
1782 | const MCOperand &Imm = MI.getOperand(i: Op + 1); |
1783 | |
1784 | unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(RegNo: Reg.getReg()); |
1785 | unsigned Align = 0; |
1786 | |
1787 | switch (Imm.getImm()) { |
1788 | default: break; |
1789 | case 2: |
1790 | case 4: |
1791 | case 8: Align = 0x01; break; |
1792 | case 16: Align = 0x02; break; |
1793 | case 32: Align = 0x03; break; |
1794 | } |
1795 | |
1796 | return RegNo | (Align << 4); |
1797 | } |
1798 | |
1799 | /// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number |
1800 | /// along with the alignment operand for use in VST1 and VLD1 with size 32. |
1801 | unsigned ARMMCCodeEmitter:: |
1802 | getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, |
1803 | SmallVectorImpl<MCFixup> &Fixups, |
1804 | const MCSubtargetInfo &STI) const { |
1805 | const MCOperand &Reg = MI.getOperand(i: Op); |
1806 | const MCOperand &Imm = MI.getOperand(i: Op + 1); |
1807 | |
1808 | unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(RegNo: Reg.getReg()); |
1809 | unsigned Align = 0; |
1810 | |
1811 | switch (Imm.getImm()) { |
1812 | default: break; |
1813 | case 8: |
1814 | case 16: |
1815 | case 32: // Default '0' value for invalid alignments of 8, 16, 32 bytes. |
1816 | case 2: Align = 0x00; break; |
1817 | case 4: Align = 0x03; break; |
1818 | } |
1819 | |
1820 | return RegNo | (Align << 4); |
1821 | } |
1822 | |
1823 | |
1824 | /// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and |
1825 | /// alignment operand for use in VLD-dup instructions. This is the same as |
1826 | /// getAddrMode6AddressOpValue except for the alignment encoding, which is |
1827 | /// different for VLD4-dup. |
1828 | unsigned ARMMCCodeEmitter:: |
1829 | getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, |
1830 | SmallVectorImpl<MCFixup> &Fixups, |
1831 | const MCSubtargetInfo &STI) const { |
1832 | const MCOperand &Reg = MI.getOperand(i: Op); |
1833 | const MCOperand &Imm = MI.getOperand(i: Op + 1); |
1834 | |
1835 | unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(RegNo: Reg.getReg()); |
1836 | unsigned Align = 0; |
1837 | |
1838 | switch (Imm.getImm()) { |
1839 | default: break; |
1840 | case 2: |
1841 | case 4: |
1842 | case 8: Align = 0x01; break; |
1843 | case 16: Align = 0x03; break; |
1844 | } |
1845 | |
1846 | return RegNo | (Align << 4); |
1847 | } |
1848 | |
1849 | unsigned ARMMCCodeEmitter:: |
1850 | getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, |
1851 | SmallVectorImpl<MCFixup> &Fixups, |
1852 | const MCSubtargetInfo &STI) const { |
1853 | const MCOperand &MO = MI.getOperand(i: Op); |
1854 | if (MO.getReg() == 0) return 0x0D; |
1855 | return CTX.getRegisterInfo()->getEncodingValue(RegNo: MO.getReg()); |
1856 | } |
1857 | |
1858 | unsigned ARMMCCodeEmitter:: |
1859 | getShiftRight8Imm(const MCInst &MI, unsigned Op, |
1860 | SmallVectorImpl<MCFixup> &Fixups, |
1861 | const MCSubtargetInfo &STI) const { |
1862 | return 8 - MI.getOperand(i: Op).getImm(); |
1863 | } |
1864 | |
1865 | unsigned ARMMCCodeEmitter:: |
1866 | getShiftRight16Imm(const MCInst &MI, unsigned Op, |
1867 | SmallVectorImpl<MCFixup> &Fixups, |
1868 | const MCSubtargetInfo &STI) const { |
1869 | return 16 - MI.getOperand(i: Op).getImm(); |
1870 | } |
1871 | |
1872 | unsigned ARMMCCodeEmitter:: |
1873 | getShiftRight32Imm(const MCInst &MI, unsigned Op, |
1874 | SmallVectorImpl<MCFixup> &Fixups, |
1875 | const MCSubtargetInfo &STI) const { |
1876 | return 32 - MI.getOperand(i: Op).getImm(); |
1877 | } |
1878 | |
1879 | unsigned ARMMCCodeEmitter:: |
1880 | getShiftRight64Imm(const MCInst &MI, unsigned Op, |
1881 | SmallVectorImpl<MCFixup> &Fixups, |
1882 | const MCSubtargetInfo &STI) const { |
1883 | return 64 - MI.getOperand(i: Op).getImm(); |
1884 | } |
1885 | |
1886 | void ARMMCCodeEmitter::encodeInstruction(const MCInst &MI, |
1887 | SmallVectorImpl<char> &CB, |
1888 | SmallVectorImpl<MCFixup> &Fixups, |
1889 | const MCSubtargetInfo &STI) const { |
1890 | // Pseudo instructions don't get encoded. |
1891 | const MCInstrDesc &Desc = MCII.get(Opcode: MI.getOpcode()); |
1892 | uint64_t TSFlags = Desc.TSFlags; |
1893 | if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo) |
1894 | return; |
1895 | |
1896 | int Size; |
1897 | if (Desc.getSize() == 2 || Desc.getSize() == 4) |
1898 | Size = Desc.getSize(); |
1899 | else |
1900 | llvm_unreachable("Unexpected instruction size!" ); |
1901 | |
1902 | auto Endian = |
1903 | IsLittleEndian ? llvm::endianness::little : llvm::endianness::big; |
1904 | uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, STI); |
1905 | if (Size == 2) { |
1906 | support::endian::write<uint16_t>(Out&: CB, V: Binary, E: Endian); |
1907 | } else if (isThumb(STI)) { |
1908 | // Thumb 32-bit wide instructions need to emit the high order halfword |
1909 | // first. |
1910 | support::endian::write<uint16_t>(Out&: CB, V: Binary >> 16, E: Endian); |
1911 | support::endian::write<uint16_t>(Out&: CB, V: Binary & 0xffff, E: Endian); |
1912 | } else { |
1913 | support::endian::write<uint32_t>(Out&: CB, V: Binary, E: Endian); |
1914 | } |
1915 | ++MCNumEmitted; // Keep track of the # of mi's emitted. |
1916 | } |
1917 | |
1918 | template <bool isNeg, ARM::Fixups fixup> |
1919 | uint32_t |
1920 | ARMMCCodeEmitter::getBFTargetOpValue(const MCInst &MI, unsigned OpIdx, |
1921 | SmallVectorImpl<MCFixup> &Fixups, |
1922 | const MCSubtargetInfo &STI) const { |
1923 | const MCOperand MO = MI.getOperand(i: OpIdx); |
1924 | if (MO.isExpr()) |
1925 | return ::getBranchTargetOpValue(MI, OpIdx, FixupKind: fixup, Fixups, STI); |
1926 | return isNeg ? -(MO.getImm() >> 1) : (MO.getImm() >> 1); |
1927 | } |
1928 | |
1929 | uint32_t |
1930 | ARMMCCodeEmitter::getBFAfterTargetOpValue(const MCInst &MI, unsigned OpIdx, |
1931 | SmallVectorImpl<MCFixup> &Fixups, |
1932 | const MCSubtargetInfo &STI) const { |
1933 | const MCOperand MO = MI.getOperand(i: OpIdx); |
1934 | const MCOperand BranchMO = MI.getOperand(i: 0); |
1935 | |
1936 | if (MO.isExpr()) { |
1937 | assert(BranchMO.isExpr()); |
1938 | const MCExpr *DiffExpr = MCBinaryExpr::createSub( |
1939 | LHS: MO.getExpr(), RHS: BranchMO.getExpr(), Ctx&: CTX); |
1940 | MCFixupKind Kind = MCFixupKind(ARM::fixup_bfcsel_else_target); |
1941 | Fixups.push_back(Elt: llvm::MCFixup::create(Offset: 0, Value: DiffExpr, Kind, Loc: MI.getLoc())); |
1942 | return 0; |
1943 | } |
1944 | |
1945 | assert(MO.isImm() && BranchMO.isImm()); |
1946 | int Diff = MO.getImm() - BranchMO.getImm(); |
1947 | assert(Diff == 4 || Diff == 2); |
1948 | |
1949 | return Diff == 4; |
1950 | } |
1951 | |
1952 | uint32_t ARMMCCodeEmitter::getVPTMaskOpValue(const MCInst &MI, unsigned OpIdx, |
1953 | SmallVectorImpl<MCFixup> &Fixups, |
1954 | const MCSubtargetInfo &STI)const { |
1955 | const MCOperand MO = MI.getOperand(i: OpIdx); |
1956 | assert(MO.isImm() && "Unexpected operand type!" ); |
1957 | |
1958 | int Value = MO.getImm(); |
1959 | int Imm = 0; |
1960 | |
1961 | // VPT Masks are actually encoded as a series of invert/don't invert bits, |
1962 | // rather than true/false bits. |
1963 | unsigned PrevBit = 0; |
1964 | for (int i = 3; i >= 0; --i) { |
1965 | unsigned Bit = (Value >> i) & 1; |
1966 | |
1967 | // Check if we are at the end of the mask. |
1968 | if ((Value & ~(~0U << i)) == 0) { |
1969 | Imm |= (1 << i); |
1970 | break; |
1971 | } |
1972 | |
1973 | // Convert the bit in the mask based on the previous bit. |
1974 | if (Bit != PrevBit) |
1975 | Imm |= (1 << i); |
1976 | |
1977 | PrevBit = Bit; |
1978 | } |
1979 | |
1980 | return Imm; |
1981 | } |
1982 | |
1983 | uint32_t ARMMCCodeEmitter::getRestrictedCondCodeOpValue( |
1984 | const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups, |
1985 | const MCSubtargetInfo &STI) const { |
1986 | |
1987 | const MCOperand MO = MI.getOperand(i: OpIdx); |
1988 | assert(MO.isImm() && "Unexpected operand type!" ); |
1989 | |
1990 | switch (MO.getImm()) { |
1991 | default: |
1992 | assert(0 && "Unexpected Condition!" ); |
1993 | return 0; |
1994 | case ARMCC::HS: |
1995 | case ARMCC::EQ: |
1996 | return 0; |
1997 | case ARMCC::HI: |
1998 | case ARMCC::NE: |
1999 | return 1; |
2000 | case ARMCC::GE: |
2001 | return 4; |
2002 | case ARMCC::LT: |
2003 | return 5; |
2004 | case ARMCC::GT: |
2005 | return 6; |
2006 | case ARMCC::LE: |
2007 | return 7; |
2008 | } |
2009 | } |
2010 | |
2011 | uint32_t ARMMCCodeEmitter:: |
2012 | getPowerTwoOpValue(const MCInst &MI, unsigned OpIdx, |
2013 | SmallVectorImpl<MCFixup> &Fixups, |
2014 | const MCSubtargetInfo &STI) const { |
2015 | const MCOperand &MO = MI.getOperand(i: OpIdx); |
2016 | assert(MO.isImm() && "Unexpected operand type!" ); |
2017 | return llvm::countr_zero(Val: (uint64_t)MO.getImm()); |
2018 | } |
2019 | |
2020 | template <unsigned start> |
2021 | uint32_t ARMMCCodeEmitter:: |
2022 | getMVEPairVectorIndexOpValue(const MCInst &MI, unsigned OpIdx, |
2023 | SmallVectorImpl<MCFixup> &Fixups, |
2024 | const MCSubtargetInfo &STI) const { |
2025 | const MCOperand MO = MI.getOperand(i: OpIdx); |
2026 | assert(MO.isImm() && "Unexpected operand type!" ); |
2027 | |
2028 | int Value = MO.getImm(); |
2029 | return Value - start; |
2030 | } |
2031 | |
2032 | #include "ARMGenMCCodeEmitter.inc" |
2033 | |
2034 | MCCodeEmitter *llvm::createARMLEMCCodeEmitter(const MCInstrInfo &MCII, |
2035 | MCContext &Ctx) { |
2036 | return new ARMMCCodeEmitter(MCII, Ctx, true); |
2037 | } |
2038 | |
2039 | MCCodeEmitter *llvm::createARMBEMCCodeEmitter(const MCInstrInfo &MCII, |
2040 | MCContext &Ctx) { |
2041 | return new ARMMCCodeEmitter(MCII, Ctx, false); |
2042 | } |
2043 | |