LLVM 20.0.0git
AArch64MCCodeEmitter.cpp
Go to the documentation of this file.
1//=- AArch64/AArch64MCCodeEmitter.cpp - Convert AArch64 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 AArch64MCCodeEmitter class.
10//
11//===----------------------------------------------------------------------===//
12
17#include "llvm/ADT/Statistic.h"
20#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCFixup.h"
22#include "llvm/MC/MCInst.h"
23#include "llvm/MC/MCInstrInfo.h"
29#include <cassert>
30#include <cstdint>
31
32using namespace llvm;
33
34#define DEBUG_TYPE "mccodeemitter"
35
36STATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
37STATISTIC(MCNumFixups, "Number of MC fixups created.");
38
39namespace {
40
41class AArch64MCCodeEmitter : public MCCodeEmitter {
42 MCContext &Ctx;
43
44public:
45 AArch64MCCodeEmitter(const MCInstrInfo &, MCContext &ctx) : Ctx(ctx) {}
46 AArch64MCCodeEmitter(const AArch64MCCodeEmitter &) = delete;
47 void operator=(const AArch64MCCodeEmitter &) = delete;
48 ~AArch64MCCodeEmitter() override = default;
49
50 // getBinaryCodeForInstr - TableGen'erated function for getting the
51 // binary encoding for an instruction.
52 uint64_t getBinaryCodeForInstr(const MCInst &MI,
54 const MCSubtargetInfo &STI) const;
55
56 /// getMachineOpValue - Return binary encoding of operand. If the machine
57 /// operand requires relocation, record the relocation and return zero.
58 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
60 const MCSubtargetInfo &STI) const;
61
62 /// getLdStUImm12OpValue - Return encoding info for 12-bit unsigned immediate
63 /// attached to a load, store or prfm instruction. If operand requires a
64 /// relocation, record it and return zero in that part of the encoding.
65 template <uint32_t FixupKind>
66 uint32_t getLdStUImm12OpValue(const MCInst &MI, unsigned OpIdx,
68 const MCSubtargetInfo &STI) const;
69
70 /// getAdrLabelOpValue - Return encoding info for 21-bit immediate ADR label
71 /// target.
72 uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
74 const MCSubtargetInfo &STI) const;
75
76 /// getAddSubImmOpValue - Return encoding for the 12-bit immediate value and
77 /// the 2-bit shift field.
78 uint32_t getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
80 const MCSubtargetInfo &STI) const;
81
82 /// getCondBranchTargetOpValue - Return the encoded value for a conditional
83 /// branch target.
84 uint32_t getCondBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
86 const MCSubtargetInfo &STI) const;
87
88 /// getCondCompBranchTargetOpValue - Return the encoded value for a
89 /// conditional compare-and-branch target.
90 uint32_t getCondCompBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
92 const MCSubtargetInfo &STI) const;
93
94 /// getPAuthPCRelOpValue - Return the encoded value for a pointer
95 /// authentication pc-relative operand.
96 uint32_t getPAuthPCRelOpValue(const MCInst &MI, unsigned OpIdx,
98 const MCSubtargetInfo &STI) const;
99
100 /// getLoadLiteralOpValue - Return the encoded value for a load-literal
101 /// pc-relative address.
102 uint32_t getLoadLiteralOpValue(const MCInst &MI, unsigned OpIdx,
104 const MCSubtargetInfo &STI) const;
105
106 /// getMemExtendOpValue - Return the encoded value for a reg-extend load/store
107 /// instruction: bit 0 is whether a shift is present, bit 1 is whether the
108 /// operation is a sign extend (as opposed to a zero extend).
109 uint32_t getMemExtendOpValue(const MCInst &MI, unsigned OpIdx,
111 const MCSubtargetInfo &STI) const;
112
113 /// getTestBranchTargetOpValue - Return the encoded value for a test-bit-and-
114 /// branch target.
115 uint32_t getTestBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
117 const MCSubtargetInfo &STI) const;
118
119 /// getBranchTargetOpValue - Return the encoded value for an unconditional
120 /// branch target.
121 uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
123 const MCSubtargetInfo &STI) const;
124
125 /// getMoveWideImmOpValue - Return the encoded value for the immediate operand
126 /// of a MOVZ or MOVK instruction.
127 uint32_t getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
129 const MCSubtargetInfo &STI) const;
130
131 /// getVecShifterOpValue - Return the encoded value for the vector shifter.
132 uint32_t getVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
134 const MCSubtargetInfo &STI) const;
135
136 /// getMoveVecShifterOpValue - Return the encoded value for the vector move
137 /// shifter (MSL).
138 uint32_t getMoveVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
140 const MCSubtargetInfo &STI) const;
141
142 /// getFixedPointScaleOpValue - Return the encoded value for the
143 // FP-to-fixed-point scale factor.
144 uint32_t getFixedPointScaleOpValue(const MCInst &MI, unsigned OpIdx,
146 const MCSubtargetInfo &STI) const;
147
148 uint32_t getVecShiftR64OpValue(const MCInst &MI, unsigned OpIdx,
150 const MCSubtargetInfo &STI) const;
151 uint32_t getVecShiftR32OpValue(const MCInst &MI, unsigned OpIdx,
153 const MCSubtargetInfo &STI) const;
154 uint32_t getVecShiftR16OpValue(const MCInst &MI, unsigned OpIdx,
156 const MCSubtargetInfo &STI) const;
157 uint32_t getVecShiftR8OpValue(const MCInst &MI, unsigned OpIdx,
159 const MCSubtargetInfo &STI) const;
160 uint32_t getVecShiftL64OpValue(const MCInst &MI, unsigned OpIdx,
162 const MCSubtargetInfo &STI) const;
163 uint32_t getVecShiftL32OpValue(const MCInst &MI, unsigned OpIdx,
165 const MCSubtargetInfo &STI) const;
166 uint32_t getVecShiftL16OpValue(const MCInst &MI, unsigned OpIdx,
168 const MCSubtargetInfo &STI) const;
169 uint32_t getVecShiftL8OpValue(const MCInst &MI, unsigned OpIdx,
171 const MCSubtargetInfo &STI) const;
172
173 uint32_t getImm8OptLsl(const MCInst &MI, unsigned OpIdx,
175 const MCSubtargetInfo &STI) const;
176 uint32_t getSVEIncDecImm(const MCInst &MI, unsigned OpIdx,
178 const MCSubtargetInfo &STI) const;
179
180 unsigned fixMOVZ(const MCInst &MI, unsigned EncodedValue,
181 const MCSubtargetInfo &STI) const;
182
185 const MCSubtargetInfo &STI) const override;
186
187 unsigned fixMulHigh(const MCInst &MI, unsigned EncodedValue,
188 const MCSubtargetInfo &STI) const;
189
190 template<int hasRs, int hasRt2> unsigned
191 fixLoadStoreExclusive(const MCInst &MI, unsigned EncodedValue,
192 const MCSubtargetInfo &STI) const;
193
194 unsigned fixOneOperandFPComparison(const MCInst &MI, unsigned EncodedValue,
195 const MCSubtargetInfo &STI) const;
196
197 template <unsigned Multiple, unsigned Min, unsigned Max>
198 uint32_t EncodeRegMul_MinMax(const MCInst &MI, unsigned OpIdx,
200 const MCSubtargetInfo &STI) const;
201 uint32_t EncodeZK(const MCInst &MI, unsigned OpIdx,
203 const MCSubtargetInfo &STI) const;
204 uint32_t EncodePNR_p8to15(const MCInst &MI, unsigned OpIdx,
206 const MCSubtargetInfo &STI) const;
207
208 uint32_t EncodeZPR2StridedRegisterClass(const MCInst &MI, unsigned OpIdx,
210 const MCSubtargetInfo &STI) const;
211 uint32_t EncodeZPR4StridedRegisterClass(const MCInst &MI, unsigned OpIdx,
213 const MCSubtargetInfo &STI) const;
214
215 uint32_t EncodeMatrixTileListRegisterClass(const MCInst &MI, unsigned OpIdx,
217 const MCSubtargetInfo &STI) const;
218 template <unsigned BaseReg>
219 uint32_t encodeMatrixIndexGPR32(const MCInst &MI, unsigned OpIdx,
221 const MCSubtargetInfo &STI) const;
222};
223
224} // end anonymous namespace
225
226/// getMachineOpValue - Return binary encoding of operand. If the machine
227/// operand requires relocation, record the relocation and return zero.
228unsigned
229AArch64MCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
231 const MCSubtargetInfo &STI) const {
232 if (MO.isReg())
233 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
234
235 assert(MO.isImm() && "did not expect relocated expression");
236 return static_cast<unsigned>(MO.getImm());
237}
238
239template<unsigned FixupKind> uint32_t
240AArch64MCCodeEmitter::getLdStUImm12OpValue(const MCInst &MI, unsigned OpIdx,
242 const MCSubtargetInfo &STI) const {
243 const MCOperand &MO = MI.getOperand(OpIdx);
244 uint32_t ImmVal = 0;
245
246 if (MO.isImm())
247 ImmVal = static_cast<uint32_t>(MO.getImm());
248 else {
249 assert(MO.isExpr() && "unable to encode load/store imm operand");
250 MCFixupKind Kind = MCFixupKind(FixupKind);
251 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
252 ++MCNumFixups;
253 }
254
255 return ImmVal;
256}
257
258/// getAdrLabelOpValue - Return encoding info for 21-bit immediate ADR label
259/// target.
261AArch64MCCodeEmitter::getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
263 const MCSubtargetInfo &STI) const {
264 const MCOperand &MO = MI.getOperand(OpIdx);
265
266 // If the destination is an immediate, we have nothing to do.
267 if (MO.isImm())
268 return MO.getImm();
269 assert(MO.isExpr() && "Unexpected target type!");
270 const MCExpr *Expr = MO.getExpr();
271
272 MCFixupKind Kind = MI.getOpcode() == AArch64::ADR
275 Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
276
277 MCNumFixups += 1;
278
279 // All of the information is in the fixup.
280 return 0;
281}
282
283/// getAddSubImmOpValue - Return encoding for the 12-bit immediate value and
284/// the 2-bit shift field. The shift field is stored in bits 13-14 of the
285/// return value.
287AArch64MCCodeEmitter::getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
289 const MCSubtargetInfo &STI) const {
290 // Suboperands are [imm, shifter].
291 const MCOperand &MO = MI.getOperand(OpIdx);
292 const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
294 "unexpected shift type for add/sub immediate");
295 unsigned ShiftVal = AArch64_AM::getShiftValue(MO1.getImm());
296 assert((ShiftVal == 0 || ShiftVal == 12) &&
297 "unexpected shift value for add/sub immediate");
298 if (MO.isImm())
299 return MO.getImm() | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
300 assert(MO.isExpr() && "Unable to encode MCOperand!");
301 const MCExpr *Expr = MO.getExpr();
302
303 // Encode the 12 bits of the fixup.
305 Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
306
307 ++MCNumFixups;
308
309 // Set the shift bit of the add instruction for relocation types
310 // R_AARCH64_TLSLE_ADD_TPREL_HI12 and R_AARCH64_TLSLD_ADD_DTPREL_HI12.
311 if (const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(Expr)) {
312 AArch64MCExpr::VariantKind RefKind = A64E->getKind();
313 if (RefKind == AArch64MCExpr::VK_TPREL_HI12 ||
316 ShiftVal = 12;
317 }
318 return ShiftVal == 0 ? 0 : (1 << ShiftVal);
319}
320
321/// getCondBranchTargetOpValue - Return the encoded value for a conditional
322/// branch target.
323uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue(
324 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
325 const MCSubtargetInfo &STI) const {
326 const MCOperand &MO = MI.getOperand(OpIdx);
327
328 // If the destination is an immediate, we have nothing to do.
329 if (MO.isImm())
330 return MO.getImm();
331 assert(MO.isExpr() && "Unexpected target type!");
332
334 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
335
336 ++MCNumFixups;
337
338 // All of the information is in the fixup.
339 return 0;
340}
341
342/// getCondCompBranchTargetOpValue - Return the encoded value for a conditional
343/// compare-and-branch target.
344uint32_t AArch64MCCodeEmitter::getCondCompBranchTargetOpValue(
345 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
346 const MCSubtargetInfo &STI) const {
347 const MCOperand &MO = MI.getOperand(OpIdx);
348
349 // If the destination is an immediate, we have nothing to do.
350 if (MO.isImm())
351 return MO.getImm();
352 assert(MO.isExpr() && "Unexpected target type!");
353
355 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
356
357 ++MCNumFixups;
358
359 // All of the information is in the fixup.
360 return 0;
361}
362
363/// getPAuthPCRelOpValue - Return the encoded value for a pointer
364/// authentication pc-relative operand.
366AArch64MCCodeEmitter::getPAuthPCRelOpValue(const MCInst &MI, unsigned OpIdx,
368 const MCSubtargetInfo &STI) const {
369 const MCOperand &MO = MI.getOperand(OpIdx);
370
371 // If the destination is an immediate, invert sign as it's a negative value
372 // that should be encoded as unsigned
373 if (MO.isImm())
374 return -(MO.getImm());
375 assert(MO.isExpr() && "Unexpected target type!");
376
378 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
379
380 ++MCNumFixups;
381
382 // All of the information is in the fixup.
383 return 0;
384}
385
386/// getLoadLiteralOpValue - Return the encoded value for a load-literal
387/// pc-relative address.
389AArch64MCCodeEmitter::getLoadLiteralOpValue(const MCInst &MI, unsigned OpIdx,
391 const MCSubtargetInfo &STI) const {
392 const MCOperand &MO = MI.getOperand(OpIdx);
393
394 // If the destination is an immediate, we have nothing to do.
395 if (MO.isImm())
396 return MO.getImm();
397 assert(MO.isExpr() && "Unexpected target type!");
398
400 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
401
402 ++MCNumFixups;
403
404 // All of the information is in the fixup.
405 return 0;
406}
407
409AArch64MCCodeEmitter::getMemExtendOpValue(const MCInst &MI, unsigned OpIdx,
411 const MCSubtargetInfo &STI) const {
412 unsigned SignExtend = MI.getOperand(OpIdx).getImm();
413 unsigned DoShift = MI.getOperand(OpIdx + 1).getImm();
414 return (SignExtend << 1) | DoShift;
415}
416
418AArch64MCCodeEmitter::getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
420 const MCSubtargetInfo &STI) const {
421 const MCOperand &MO = MI.getOperand(OpIdx);
422
423 if (MO.isImm())
424 return MO.getImm();
425 assert(MO.isExpr() && "Unexpected movz/movk immediate");
426
427 Fixups.push_back(MCFixup::create(
429
430 ++MCNumFixups;
431
432 return 0;
433}
434
435/// getTestBranchTargetOpValue - Return the encoded value for a test-bit-and-
436/// branch target.
437uint32_t AArch64MCCodeEmitter::getTestBranchTargetOpValue(
438 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
439 const MCSubtargetInfo &STI) const {
440 const MCOperand &MO = MI.getOperand(OpIdx);
441
442 // If the destination is an immediate, we have nothing to do.
443 if (MO.isImm())
444 return MO.getImm();
445 assert(MO.isExpr() && "Unexpected ADR target type!");
446
448 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
449
450 ++MCNumFixups;
451
452 // All of the information is in the fixup.
453 return 0;
454}
455
456/// getBranchTargetOpValue - Return the encoded value for an unconditional
457/// branch target.
459AArch64MCCodeEmitter::getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
461 const MCSubtargetInfo &STI) const {
462 const MCOperand &MO = MI.getOperand(OpIdx);
463
464 // If the destination is an immediate, we have nothing to do.
465 if (MO.isImm())
466 return MO.getImm();
467 assert(MO.isExpr() && "Unexpected ADR target type!");
468
469 MCFixupKind Kind = MI.getOpcode() == AArch64::BL
472 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
473
474 ++MCNumFixups;
475
476 // All of the information is in the fixup.
477 return 0;
478}
479
480/// getVecShifterOpValue - Return the encoded value for the vector shifter:
481///
482/// 00 -> 0
483/// 01 -> 8
484/// 10 -> 16
485/// 11 -> 24
487AArch64MCCodeEmitter::getVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
489 const MCSubtargetInfo &STI) const {
490 const MCOperand &MO = MI.getOperand(OpIdx);
491 assert(MO.isImm() && "Expected an immediate value for the shift amount!");
492
493 switch (MO.getImm()) {
494 default:
495 break;
496 case 0:
497 return 0;
498 case 8:
499 return 1;
500 case 16:
501 return 2;
502 case 24:
503 return 3;
504 }
505
506 llvm_unreachable("Invalid value for vector shift amount!");
507}
508
509/// getFixedPointScaleOpValue - Return the encoded value for the
510// FP-to-fixed-point scale factor.
511uint32_t AArch64MCCodeEmitter::getFixedPointScaleOpValue(
512 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
513 const MCSubtargetInfo &STI) const {
514 const MCOperand &MO = MI.getOperand(OpIdx);
515 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
516 return 64 - MO.getImm();
517}
518
520AArch64MCCodeEmitter::getVecShiftR64OpValue(const MCInst &MI, unsigned OpIdx,
522 const MCSubtargetInfo &STI) const {
523 const MCOperand &MO = MI.getOperand(OpIdx);
524 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
525 return 64 - MO.getImm();
526}
527
529AArch64MCCodeEmitter::getVecShiftR32OpValue(const MCInst &MI, unsigned OpIdx,
531 const MCSubtargetInfo &STI) const {
532 const MCOperand &MO = MI.getOperand(OpIdx);
533 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
534 return 32 - MO.getImm();
535}
536
538AArch64MCCodeEmitter::getVecShiftR16OpValue(const MCInst &MI, unsigned OpIdx,
540 const MCSubtargetInfo &STI) const {
541 const MCOperand &MO = MI.getOperand(OpIdx);
542 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
543 return 16 - MO.getImm();
544}
545
547AArch64MCCodeEmitter::getVecShiftR8OpValue(const MCInst &MI, unsigned OpIdx,
549 const MCSubtargetInfo &STI) const {
550 const MCOperand &MO = MI.getOperand(OpIdx);
551 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
552 return 8 - MO.getImm();
553}
554
556AArch64MCCodeEmitter::getVecShiftL64OpValue(const MCInst &MI, unsigned OpIdx,
558 const MCSubtargetInfo &STI) const {
559 const MCOperand &MO = MI.getOperand(OpIdx);
560 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
561 return MO.getImm() - 64;
562}
563
565AArch64MCCodeEmitter::getVecShiftL32OpValue(const MCInst &MI, unsigned OpIdx,
567 const MCSubtargetInfo &STI) const {
568 const MCOperand &MO = MI.getOperand(OpIdx);
569 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
570 return MO.getImm() - 32;
571}
572
574AArch64MCCodeEmitter::getVecShiftL16OpValue(const MCInst &MI, unsigned OpIdx,
576 const MCSubtargetInfo &STI) const {
577 const MCOperand &MO = MI.getOperand(OpIdx);
578 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
579 return MO.getImm() - 16;
580}
581
583AArch64MCCodeEmitter::getVecShiftL8OpValue(const MCInst &MI, unsigned OpIdx,
585 const MCSubtargetInfo &STI) const {
586 const MCOperand &MO = MI.getOperand(OpIdx);
587 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
588 return MO.getImm() - 8;
589}
590
591template <unsigned Multiple, unsigned Min, unsigned Max>
593AArch64MCCodeEmitter::EncodeRegMul_MinMax(const MCInst &MI, unsigned OpIdx,
595 const MCSubtargetInfo &STI) const {
596 assert(llvm::isPowerOf2_32(Multiple) && "Multiple is not a power of 2");
597 auto RegOpnd = MI.getOperand(OpIdx).getReg();
598 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
599 assert(RegVal >= Min && RegVal <= Max && (RegVal & (Multiple - 1)) == 0);
600 return (RegVal - Min) / Multiple;
601}
602
603// Zk Is the name of the control vector register Z20-Z23 or Z28-Z31, encoded in
604// the "K:Zk" fields. Z20-Z23 = 000, 001,010, 011 and Z28-Z31 = 100, 101, 110,
605// 111
606uint32_t AArch64MCCodeEmitter::EncodeZK(const MCInst &MI, unsigned OpIdx,
608 const MCSubtargetInfo &STI) const {
609 auto RegOpnd = MI.getOperand(OpIdx).getReg();
610 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
611
612 // ZZ8-Z31 => Reg is in 3..7 (offset 24)
613 if (RegOpnd > AArch64::Z27)
614 return (RegVal - 24);
615
616 assert((RegOpnd > AArch64::Z19 && RegOpnd < AArch64::Z24) &&
617 "Expected ZK in Z20..Z23 or Z28..Z31");
618 // Z20-Z23 => Reg is in 0..3 (offset 20)
619 return (RegVal - 20);
620}
621
623AArch64MCCodeEmitter::EncodePNR_p8to15(const MCInst &MI, unsigned OpIdx,
625 const MCSubtargetInfo &STI) const {
626 auto RegOpnd = MI.getOperand(OpIdx).getReg();
627 return RegOpnd - AArch64::PN8;
628}
629
630uint32_t AArch64MCCodeEmitter::EncodeZPR2StridedRegisterClass(
631 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
632 const MCSubtargetInfo &STI) const {
633 auto RegOpnd = MI.getOperand(OpIdx).getReg();
634 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
635 unsigned T = (RegVal & 0x10) >> 1;
636 unsigned Zt = RegVal & 0x7;
637 return T | Zt;
638}
639
640uint32_t AArch64MCCodeEmitter::EncodeZPR4StridedRegisterClass(
641 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
642 const MCSubtargetInfo &STI) const {
643 auto RegOpnd = MI.getOperand(OpIdx).getReg();
644 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
645 unsigned T = (RegVal & 0x10) >> 2;
646 unsigned Zt = RegVal & 0x3;
647 return T | Zt;
648}
649
650uint32_t AArch64MCCodeEmitter::EncodeMatrixTileListRegisterClass(
651 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
652 const MCSubtargetInfo &STI) const {
653 unsigned RegMask = MI.getOperand(OpIdx).getImm();
654 assert(RegMask <= 0xFF && "Invalid register mask!");
655 return RegMask;
656}
657
658template <unsigned BaseReg>
660AArch64MCCodeEmitter::encodeMatrixIndexGPR32(const MCInst &MI, unsigned OpIdx,
662 const MCSubtargetInfo &STI) const {
663 auto RegOpnd = MI.getOperand(OpIdx).getReg();
664 return RegOpnd - BaseReg;
665}
666
668AArch64MCCodeEmitter::getImm8OptLsl(const MCInst &MI, unsigned OpIdx,
670 const MCSubtargetInfo &STI) const {
671 // Test shift
672 auto ShiftOpnd = MI.getOperand(OpIdx + 1).getImm();
674 "Unexpected shift type for imm8_opt_lsl immediate.");
675
676 unsigned ShiftVal = AArch64_AM::getShiftValue(ShiftOpnd);
677 assert((ShiftVal == 0 || ShiftVal == 8) &&
678 "Unexpected shift value for imm8_opt_lsl immediate.");
679
680 // Test immediate
681 auto Immediate = MI.getOperand(OpIdx).getImm();
682 return (Immediate & 0xff) | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
683}
684
686AArch64MCCodeEmitter::getSVEIncDecImm(const MCInst &MI, unsigned OpIdx,
688 const MCSubtargetInfo &STI) const {
689 const MCOperand &MO = MI.getOperand(OpIdx);
690 assert(MO.isImm() && "Expected an immediate value!");
691 // Normalize 1-16 range to 0-15.
692 return MO.getImm() - 1;
693}
694
695/// getMoveVecShifterOpValue - Return the encoded value for the vector move
696/// shifter (MSL).
697uint32_t AArch64MCCodeEmitter::getMoveVecShifterOpValue(
698 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
699 const MCSubtargetInfo &STI) const {
700 const MCOperand &MO = MI.getOperand(OpIdx);
701 assert(MO.isImm() &&
702 "Expected an immediate value for the move shift amount!");
703 unsigned ShiftVal = AArch64_AM::getShiftValue(MO.getImm());
704 assert((ShiftVal == 8 || ShiftVal == 16) && "Invalid shift amount!");
705 return ShiftVal == 8 ? 0 : 1;
706}
707
708unsigned AArch64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue,
709 const MCSubtargetInfo &STI) const {
710 // If one of the signed fixup kinds is applied to a MOVZ instruction, the
711 // eventual result could be either a MOVZ or a MOVN. It's the MCCodeEmitter's
712 // job to ensure that any bits possibly affected by this are 0. This means we
713 // must zero out bit 30 (essentially emitting a MOVN).
714 MCOperand UImm16MO = MI.getOperand(1);
715
716 // Nothing to do if there's no fixup.
717 if (UImm16MO.isImm())
718 return EncodedValue;
719
720 const MCExpr *E = UImm16MO.getExpr();
721 if (const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(E)) {
722 switch (A64E->getKind()) {
730 return EncodedValue & ~(1u << 30);
731 default:
732 // Nothing to do for an unsigned fixup.
733 return EncodedValue;
734 }
735 }
736
737 return EncodedValue;
738}
739
740void AArch64MCCodeEmitter::encodeInstruction(const MCInst &MI,
742
744 const MCSubtargetInfo &STI) const {
745 if (MI.getOpcode() == AArch64::TLSDESCCALL) {
746 // This is a directive which applies an R_AARCH64_TLSDESC_CALL to the
747 // following (BLR) instruction. It doesn't emit any code itself so it
748 // doesn't go through the normal TableGenerated channels.
749 auto Reloc = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32
750 ? ELF::R_AARCH64_P32_TLSDESC_CALL
751 : ELF::R_AARCH64_TLSDESC_CALL;
752 Fixups.push_back(
753 MCFixup::create(0, MI.getOperand(0).getExpr(),
755 return;
756 }
757
758 if (MI.getOpcode() == AArch64::SPACE) {
759 // SPACE just increases basic block size, in both cases no actual code.
760 return;
761 }
762
763 uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
764 support::endian::write<uint32_t>(CB, Binary, llvm::endianness::little);
765 ++MCNumEmitted; // Keep track of the # of mi's emitted.
766}
767
768unsigned
769AArch64MCCodeEmitter::fixMulHigh(const MCInst &MI,
770 unsigned EncodedValue,
771 const MCSubtargetInfo &STI) const {
772 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
773 // (i.e. all bits 1) but is ignored by the processor.
774 EncodedValue |= 0x1f << 10;
775 return EncodedValue;
776}
777
778template<int hasRs, int hasRt2> unsigned
779AArch64MCCodeEmitter::fixLoadStoreExclusive(const MCInst &MI,
780 unsigned EncodedValue,
781 const MCSubtargetInfo &STI) const {
782 if (!hasRs) EncodedValue |= 0x001F0000;
783 if (!hasRt2) EncodedValue |= 0x00007C00;
784
785 return EncodedValue;
786}
787
788unsigned AArch64MCCodeEmitter::fixOneOperandFPComparison(
789 const MCInst &MI, unsigned EncodedValue, const MCSubtargetInfo &STI) const {
790 // The Rm field of FCMP and friends is unused - it should be assembled
791 // as 0, but is ignored by the processor.
792 EncodedValue &= ~(0x1f << 16);
793 return EncodedValue;
794}
795
796#include "AArch64GenMCCodeEmitter.inc"
797
799 MCContext &Ctx) {
800 return new AArch64MCCodeEmitter(MCII, Ctx);
801}
static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, unsigned FixupKind, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI)
getBranchTargetOpValue - Helper function to get the branch target operand, which is either an immedia...
IRTranslator LLVM IR MI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:166
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:21
virtual void encodeInstruction(const MCInst &Inst, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
Encode the given Inst to bytes and append to CB.
MCCodeEmitter & operator=(const MCCodeEmitter &)=delete
Context object for machine code objects.
Definition: MCContext.h:83
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:87
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:185
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:37
int64_t getImm() const
Definition: MCInst.h:81
bool isImm() const
Definition: MCInst.h:63
bool isReg() const
Definition: MCInst.h:62
MCRegister getReg() const
Returns the register number.
Definition: MCInst.h:70
const MCExpr * getExpr() const
Definition: MCInst.h:115
bool isExpr() const
Definition: MCInst.h:66
Generic base class for all target subtargets.
const Triple & getTargetTriple() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
EnvironmentType getEnvironment() const
Get the parsed environment type of this triple.
Definition: Triple.h:400
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:291
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
Definition: MCFixup.h:50
MCCodeEmitter * createAArch64MCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)