1 //=- AArch64/AArch64MCCodeEmitter.cpp - Convert AArch64 code to machine code-=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the AArch64MCCodeEmitter class.
12 //===----------------------------------------------------------------------===//
14 #include "MCTargetDesc/AArch64AddressingModes.h"
15 #include "MCTargetDesc/AArch64FixupKinds.h"
16 #include "MCTargetDesc/AArch64MCExpr.h"
17 #include "Utils/AArch64BaseInfo.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/Statistic.h"
20 #include "llvm/MC/MCCodeEmitter.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCFixup.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCRegisterInfo.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/Endian.h"
29 #include "llvm/Support/EndianStream.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/raw_ostream.h"
37 #define DEBUG_TYPE "mccodeemitter"
39 STATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
40 STATISTIC(MCNumFixups, "Number of MC fixups created.");
44 class AArch64MCCodeEmitter : public MCCodeEmitter {
46 const MCInstrInfo &MCII;
49 AArch64MCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
50 : Ctx(ctx), MCII(mcii) {}
51 AArch64MCCodeEmitter(const AArch64MCCodeEmitter &) = delete;
52 void operator=(const AArch64MCCodeEmitter &) = delete;
53 ~AArch64MCCodeEmitter() override = default;
55 // getBinaryCodeForInstr - TableGen'erated function for getting the
56 // binary encoding for an instruction.
57 uint64_t getBinaryCodeForInstr(const MCInst &MI,
58 SmallVectorImpl<MCFixup> &Fixups,
59 const MCSubtargetInfo &STI) const;
61 /// getMachineOpValue - Return binary encoding of operand. If the machine
62 /// operand requires relocation, record the relocation and return zero.
63 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
64 SmallVectorImpl<MCFixup> &Fixups,
65 const MCSubtargetInfo &STI) const;
67 /// getLdStUImm12OpValue - Return encoding info for 12-bit unsigned immediate
68 /// attached to a load, store or prfm instruction. If operand requires a
69 /// relocation, record it and return zero in that part of the encoding.
70 template <uint32_t FixupKind>
71 uint32_t getLdStUImm12OpValue(const MCInst &MI, unsigned OpIdx,
72 SmallVectorImpl<MCFixup> &Fixups,
73 const MCSubtargetInfo &STI) const;
75 /// getAdrLabelOpValue - Return encoding info for 21-bit immediate ADR label
77 uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
78 SmallVectorImpl<MCFixup> &Fixups,
79 const MCSubtargetInfo &STI) const;
81 /// getAddSubImmOpValue - Return encoding for the 12-bit immediate value and
82 /// the 2-bit shift field.
83 uint32_t getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
84 SmallVectorImpl<MCFixup> &Fixups,
85 const MCSubtargetInfo &STI) const;
87 /// getCondBranchTargetOpValue - Return the encoded value for a conditional
89 uint32_t getCondBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
90 SmallVectorImpl<MCFixup> &Fixups,
91 const MCSubtargetInfo &STI) const;
93 /// getLoadLiteralOpValue - Return the encoded value for a load-literal
94 /// pc-relative address.
95 uint32_t getLoadLiteralOpValue(const MCInst &MI, unsigned OpIdx,
96 SmallVectorImpl<MCFixup> &Fixups,
97 const MCSubtargetInfo &STI) const;
99 /// getMemExtendOpValue - Return the encoded value for a reg-extend load/store
100 /// instruction: bit 0 is whether a shift is present, bit 1 is whether the
101 /// operation is a sign extend (as opposed to a zero extend).
102 uint32_t getMemExtendOpValue(const MCInst &MI, unsigned OpIdx,
103 SmallVectorImpl<MCFixup> &Fixups,
104 const MCSubtargetInfo &STI) const;
106 /// getTestBranchTargetOpValue - Return the encoded value for a test-bit-and-
108 uint32_t getTestBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
109 SmallVectorImpl<MCFixup> &Fixups,
110 const MCSubtargetInfo &STI) const;
112 /// getBranchTargetOpValue - Return the encoded value for an unconditional
114 uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
115 SmallVectorImpl<MCFixup> &Fixups,
116 const MCSubtargetInfo &STI) const;
118 /// getMoveWideImmOpValue - Return the encoded value for the immediate operand
119 /// of a MOVZ or MOVK instruction.
120 uint32_t getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
121 SmallVectorImpl<MCFixup> &Fixups,
122 const MCSubtargetInfo &STI) const;
124 /// getVecShifterOpValue - Return the encoded value for the vector shifter.
125 uint32_t getVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
126 SmallVectorImpl<MCFixup> &Fixups,
127 const MCSubtargetInfo &STI) const;
129 /// getMoveVecShifterOpValue - Return the encoded value for the vector move
131 uint32_t getMoveVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
132 SmallVectorImpl<MCFixup> &Fixups,
133 const MCSubtargetInfo &STI) const;
135 /// getFixedPointScaleOpValue - Return the encoded value for the
136 // FP-to-fixed-point scale factor.
137 uint32_t getFixedPointScaleOpValue(const MCInst &MI, unsigned OpIdx,
138 SmallVectorImpl<MCFixup> &Fixups,
139 const MCSubtargetInfo &STI) const;
141 uint32_t getVecShiftR64OpValue(const MCInst &MI, unsigned OpIdx,
142 SmallVectorImpl<MCFixup> &Fixups,
143 const MCSubtargetInfo &STI) const;
144 uint32_t getVecShiftR32OpValue(const MCInst &MI, unsigned OpIdx,
145 SmallVectorImpl<MCFixup> &Fixups,
146 const MCSubtargetInfo &STI) const;
147 uint32_t getVecShiftR16OpValue(const MCInst &MI, unsigned OpIdx,
148 SmallVectorImpl<MCFixup> &Fixups,
149 const MCSubtargetInfo &STI) const;
150 uint32_t getVecShiftR8OpValue(const MCInst &MI, unsigned OpIdx,
151 SmallVectorImpl<MCFixup> &Fixups,
152 const MCSubtargetInfo &STI) const;
153 uint32_t getVecShiftL64OpValue(const MCInst &MI, unsigned OpIdx,
154 SmallVectorImpl<MCFixup> &Fixups,
155 const MCSubtargetInfo &STI) const;
156 uint32_t getVecShiftL32OpValue(const MCInst &MI, unsigned OpIdx,
157 SmallVectorImpl<MCFixup> &Fixups,
158 const MCSubtargetInfo &STI) const;
159 uint32_t getVecShiftL16OpValue(const MCInst &MI, unsigned OpIdx,
160 SmallVectorImpl<MCFixup> &Fixups,
161 const MCSubtargetInfo &STI) const;
162 uint32_t getVecShiftL8OpValue(const MCInst &MI, unsigned OpIdx,
163 SmallVectorImpl<MCFixup> &Fixups,
164 const MCSubtargetInfo &STI) const;
166 unsigned fixMOVZ(const MCInst &MI, unsigned EncodedValue,
167 const MCSubtargetInfo &STI) const;
169 void encodeInstruction(const MCInst &MI, raw_ostream &OS,
170 SmallVectorImpl<MCFixup> &Fixups,
171 const MCSubtargetInfo &STI) const override;
173 unsigned fixMulHigh(const MCInst &MI, unsigned EncodedValue,
174 const MCSubtargetInfo &STI) const;
176 template<int hasRs, int hasRt2> unsigned
177 fixLoadStoreExclusive(const MCInst &MI, unsigned EncodedValue,
178 const MCSubtargetInfo &STI) const;
180 unsigned fixOneOperandFPComparison(const MCInst &MI, unsigned EncodedValue,
181 const MCSubtargetInfo &STI) const;
184 uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
185 void verifyInstructionPredicates(const MCInst &MI,
186 uint64_t AvailableFeatures) const;
189 } // end anonymous namespace
191 /// getMachineOpValue - Return binary encoding of operand. If the machine
192 /// operand requires relocation, record the relocation and return zero.
194 AArch64MCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
195 SmallVectorImpl<MCFixup> &Fixups,
196 const MCSubtargetInfo &STI) const {
198 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
200 assert(MO.isImm() && "did not expect relocated expression");
201 return static_cast<unsigned>(MO.getImm());
204 template<unsigned FixupKind> uint32_t
205 AArch64MCCodeEmitter::getLdStUImm12OpValue(const MCInst &MI, unsigned OpIdx,
206 SmallVectorImpl<MCFixup> &Fixups,
207 const MCSubtargetInfo &STI) const {
208 const MCOperand &MO = MI.getOperand(OpIdx);
212 ImmVal = static_cast<uint32_t>(MO.getImm());
214 assert(MO.isExpr() && "unable to encode load/store imm operand");
215 MCFixupKind Kind = MCFixupKind(FixupKind);
216 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
223 /// getAdrLabelOpValue - Return encoding info for 21-bit immediate ADR label
226 AArch64MCCodeEmitter::getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
227 SmallVectorImpl<MCFixup> &Fixups,
228 const MCSubtargetInfo &STI) const {
229 const MCOperand &MO = MI.getOperand(OpIdx);
231 // If the destination is an immediate, we have nothing to do.
234 assert(MO.isExpr() && "Unexpected target type!");
235 const MCExpr *Expr = MO.getExpr();
237 MCFixupKind Kind = MI.getOpcode() == AArch64::ADR
238 ? MCFixupKind(AArch64::fixup_aarch64_pcrel_adr_imm21)
239 : MCFixupKind(AArch64::fixup_aarch64_pcrel_adrp_imm21);
240 Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
244 // All of the information is in the fixup.
248 /// getAddSubImmOpValue - Return encoding for the 12-bit immediate value and
249 /// the 2-bit shift field. The shift field is stored in bits 13-14 of the
252 AArch64MCCodeEmitter::getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
253 SmallVectorImpl<MCFixup> &Fixups,
254 const MCSubtargetInfo &STI) const {
255 // Suboperands are [imm, shifter].
256 const MCOperand &MO = MI.getOperand(OpIdx);
257 const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
258 assert(AArch64_AM::getShiftType(MO1.getImm()) == AArch64_AM::LSL &&
259 "unexpected shift type for add/sub immediate");
260 unsigned ShiftVal = AArch64_AM::getShiftValue(MO1.getImm());
261 assert((ShiftVal == 0 || ShiftVal == 12) &&
262 "unexpected shift value for add/sub immediate");
264 return MO.getImm() | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
265 assert(MO.isExpr() && "Unable to encode MCOperand!");
266 const MCExpr *Expr = MO.getExpr();
268 // Encode the 12 bits of the fixup.
269 MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_add_imm12);
270 Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
274 // Set the shift bit of the add instruction for relocation types
275 // R_AARCH64_TLSLE_ADD_TPREL_HI12 and R_AARCH64_TLSLD_ADD_DTPREL_HI12.
276 if (const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(Expr)) {
277 AArch64MCExpr::VariantKind RefKind = A64E->getKind();
278 if (RefKind == AArch64MCExpr::VK_TPREL_HI12 ||
279 RefKind == AArch64MCExpr::VK_DTPREL_HI12)
282 return ShiftVal == 0 ? 0 : (1 << ShiftVal);
285 /// getCondBranchTargetOpValue - Return the encoded value for a conditional
287 uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue(
288 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
289 const MCSubtargetInfo &STI) const {
290 const MCOperand &MO = MI.getOperand(OpIdx);
292 // If the destination is an immediate, we have nothing to do.
295 assert(MO.isExpr() && "Unexpected target type!");
297 MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_pcrel_branch19);
298 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
302 // All of the information is in the fixup.
306 /// getLoadLiteralOpValue - Return the encoded value for a load-literal
307 /// pc-relative address.
309 AArch64MCCodeEmitter::getLoadLiteralOpValue(const MCInst &MI, unsigned OpIdx,
310 SmallVectorImpl<MCFixup> &Fixups,
311 const MCSubtargetInfo &STI) const {
312 const MCOperand &MO = MI.getOperand(OpIdx);
314 // If the destination is an immediate, we have nothing to do.
317 assert(MO.isExpr() && "Unexpected target type!");
319 MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_ldr_pcrel_imm19);
320 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
324 // All of the information is in the fixup.
329 AArch64MCCodeEmitter::getMemExtendOpValue(const MCInst &MI, unsigned OpIdx,
330 SmallVectorImpl<MCFixup> &Fixups,
331 const MCSubtargetInfo &STI) const {
332 unsigned SignExtend = MI.getOperand(OpIdx).getImm();
333 unsigned DoShift = MI.getOperand(OpIdx + 1).getImm();
334 return (SignExtend << 1) | DoShift;
338 AArch64MCCodeEmitter::getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
339 SmallVectorImpl<MCFixup> &Fixups,
340 const MCSubtargetInfo &STI) const {
341 const MCOperand &MO = MI.getOperand(OpIdx);
345 assert(MO.isExpr() && "Unexpected movz/movk immediate");
347 Fixups.push_back(MCFixup::create(
348 0, MO.getExpr(), MCFixupKind(AArch64::fixup_aarch64_movw), MI.getLoc()));
355 /// getTestBranchTargetOpValue - Return the encoded value for a test-bit-and-
357 uint32_t AArch64MCCodeEmitter::getTestBranchTargetOpValue(
358 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
359 const MCSubtargetInfo &STI) const {
360 const MCOperand &MO = MI.getOperand(OpIdx);
362 // If the destination is an immediate, we have nothing to do.
365 assert(MO.isExpr() && "Unexpected ADR target type!");
367 MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_pcrel_branch14);
368 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
372 // All of the information is in the fixup.
376 /// getBranchTargetOpValue - Return the encoded value for an unconditional
379 AArch64MCCodeEmitter::getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
380 SmallVectorImpl<MCFixup> &Fixups,
381 const MCSubtargetInfo &STI) const {
382 const MCOperand &MO = MI.getOperand(OpIdx);
384 // If the destination is an immediate, we have nothing to do.
387 assert(MO.isExpr() && "Unexpected ADR target type!");
389 MCFixupKind Kind = MI.getOpcode() == AArch64::BL
390 ? MCFixupKind(AArch64::fixup_aarch64_pcrel_call26)
391 : MCFixupKind(AArch64::fixup_aarch64_pcrel_branch26);
392 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
396 // All of the information is in the fixup.
400 /// getVecShifterOpValue - Return the encoded value for the vector shifter:
407 AArch64MCCodeEmitter::getVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
408 SmallVectorImpl<MCFixup> &Fixups,
409 const MCSubtargetInfo &STI) const {
410 const MCOperand &MO = MI.getOperand(OpIdx);
411 assert(MO.isImm() && "Expected an immediate value for the shift amount!");
413 switch (MO.getImm()) {
426 llvm_unreachable("Invalid value for vector shift amount!");
429 /// getFixedPointScaleOpValue - Return the encoded value for the
430 // FP-to-fixed-point scale factor.
431 uint32_t AArch64MCCodeEmitter::getFixedPointScaleOpValue(
432 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
433 const MCSubtargetInfo &STI) const {
434 const MCOperand &MO = MI.getOperand(OpIdx);
435 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
436 return 64 - MO.getImm();
440 AArch64MCCodeEmitter::getVecShiftR64OpValue(const MCInst &MI, unsigned OpIdx,
441 SmallVectorImpl<MCFixup> &Fixups,
442 const MCSubtargetInfo &STI) const {
443 const MCOperand &MO = MI.getOperand(OpIdx);
444 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
445 return 64 - MO.getImm();
449 AArch64MCCodeEmitter::getVecShiftR32OpValue(const MCInst &MI, unsigned OpIdx,
450 SmallVectorImpl<MCFixup> &Fixups,
451 const MCSubtargetInfo &STI) const {
452 const MCOperand &MO = MI.getOperand(OpIdx);
453 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
454 return 32 - MO.getImm();
458 AArch64MCCodeEmitter::getVecShiftR16OpValue(const MCInst &MI, unsigned OpIdx,
459 SmallVectorImpl<MCFixup> &Fixups,
460 const MCSubtargetInfo &STI) const {
461 const MCOperand &MO = MI.getOperand(OpIdx);
462 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
463 return 16 - MO.getImm();
467 AArch64MCCodeEmitter::getVecShiftR8OpValue(const MCInst &MI, unsigned OpIdx,
468 SmallVectorImpl<MCFixup> &Fixups,
469 const MCSubtargetInfo &STI) const {
470 const MCOperand &MO = MI.getOperand(OpIdx);
471 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
472 return 8 - MO.getImm();
476 AArch64MCCodeEmitter::getVecShiftL64OpValue(const MCInst &MI, unsigned OpIdx,
477 SmallVectorImpl<MCFixup> &Fixups,
478 const MCSubtargetInfo &STI) const {
479 const MCOperand &MO = MI.getOperand(OpIdx);
480 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
481 return MO.getImm() - 64;
485 AArch64MCCodeEmitter::getVecShiftL32OpValue(const MCInst &MI, unsigned OpIdx,
486 SmallVectorImpl<MCFixup> &Fixups,
487 const MCSubtargetInfo &STI) const {
488 const MCOperand &MO = MI.getOperand(OpIdx);
489 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
490 return MO.getImm() - 32;
494 AArch64MCCodeEmitter::getVecShiftL16OpValue(const MCInst &MI, unsigned OpIdx,
495 SmallVectorImpl<MCFixup> &Fixups,
496 const MCSubtargetInfo &STI) const {
497 const MCOperand &MO = MI.getOperand(OpIdx);
498 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
499 return MO.getImm() - 16;
503 AArch64MCCodeEmitter::getVecShiftL8OpValue(const MCInst &MI, unsigned OpIdx,
504 SmallVectorImpl<MCFixup> &Fixups,
505 const MCSubtargetInfo &STI) const {
506 const MCOperand &MO = MI.getOperand(OpIdx);
507 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
508 return MO.getImm() - 8;
511 /// getMoveVecShifterOpValue - Return the encoded value for the vector move
513 uint32_t AArch64MCCodeEmitter::getMoveVecShifterOpValue(
514 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
515 const MCSubtargetInfo &STI) const {
516 const MCOperand &MO = MI.getOperand(OpIdx);
518 "Expected an immediate value for the move shift amount!");
519 unsigned ShiftVal = AArch64_AM::getShiftValue(MO.getImm());
520 assert((ShiftVal == 8 || ShiftVal == 16) && "Invalid shift amount!");
521 return ShiftVal == 8 ? 0 : 1;
524 unsigned AArch64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue,
525 const MCSubtargetInfo &STI) const {
526 // If one of the signed fixup kinds is applied to a MOVZ instruction, the
527 // eventual result could be either a MOVZ or a MOVN. It's the MCCodeEmitter's
528 // job to ensure that any bits possibly affected by this are 0. This means we
529 // must zero out bit 30 (essentially emitting a MOVN).
530 MCOperand UImm16MO = MI.getOperand(1);
532 // Nothing to do if there's no fixup.
533 if (UImm16MO.isImm())
536 const AArch64MCExpr *A64E = cast<AArch64MCExpr>(UImm16MO.getExpr());
537 switch (A64E->getKind()) {
538 case AArch64MCExpr::VK_DTPREL_G2:
539 case AArch64MCExpr::VK_DTPREL_G1:
540 case AArch64MCExpr::VK_DTPREL_G0:
541 case AArch64MCExpr::VK_GOTTPREL_G1:
542 case AArch64MCExpr::VK_TPREL_G2:
543 case AArch64MCExpr::VK_TPREL_G1:
544 case AArch64MCExpr::VK_TPREL_G0:
545 return EncodedValue & ~(1u << 30);
547 // Nothing to do for an unsigned fixup.
552 return EncodedValue & ~(1u << 30);
555 void AArch64MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
556 SmallVectorImpl<MCFixup> &Fixups,
557 const MCSubtargetInfo &STI) const {
558 verifyInstructionPredicates(MI,
559 computeAvailableFeatures(STI.getFeatureBits()));
561 if (MI.getOpcode() == AArch64::TLSDESCCALL) {
562 // This is a directive which applies an R_AARCH64_TLSDESC_CALL to the
563 // following (BLR) instruction. It doesn't emit any code itself so it
564 // doesn't go through the normal TableGenerated channels.
565 MCFixupKind Fixup = MCFixupKind(AArch64::fixup_aarch64_tlsdesc_call);
566 Fixups.push_back(MCFixup::create(0, MI.getOperand(0).getExpr(), Fixup));
568 } else if (MI.getOpcode() == AArch64::CompilerBarrier) {
569 // This just prevents the compiler from reordering accesses, no actual code.
573 uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
574 support::endian::Writer<support::little>(OS).write<uint32_t>(Binary);
575 ++MCNumEmitted; // Keep track of the # of mi's emitted.
579 AArch64MCCodeEmitter::fixMulHigh(const MCInst &MI,
580 unsigned EncodedValue,
581 const MCSubtargetInfo &STI) const {
582 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
583 // (i.e. all bits 1) but is ignored by the processor.
584 EncodedValue |= 0x1f << 10;
588 template<int hasRs, int hasRt2> unsigned
589 AArch64MCCodeEmitter::fixLoadStoreExclusive(const MCInst &MI,
590 unsigned EncodedValue,
591 const MCSubtargetInfo &STI) const {
592 if (!hasRs) EncodedValue |= 0x001F0000;
593 if (!hasRt2) EncodedValue |= 0x00007C00;
598 unsigned AArch64MCCodeEmitter::fixOneOperandFPComparison(
599 const MCInst &MI, unsigned EncodedValue, const MCSubtargetInfo &STI) const {
600 // The Rm field of FCMP and friends is unused - it should be assembled
601 // as 0, but is ignored by the processor.
602 EncodedValue &= ~(0x1f << 16);
606 #define ENABLE_INSTR_PREDICATE_VERIFIER
607 #include "AArch64GenMCCodeEmitter.inc"
609 MCCodeEmitter *llvm::createAArch64MCCodeEmitter(const MCInstrInfo &MCII,
610 const MCRegisterInfo &MRI,
612 return new AArch64MCCodeEmitter(MCII, Ctx);