14 #define DEBUG_TYPE "mccodeemitter"
37 AArch64MCCodeEmitter(
MCContext &ctx) : Ctx(ctx) {}
39 ~AArch64MCCodeEmitter() {}
41 unsigned getAddSubImmOpValue(
const MCInst &
MI,
unsigned OpIdx,
44 unsigned getAdrpLabelOpValue(
const MCInst &MI,
unsigned OpIdx,
48 unsigned getOffsetUImm12OpValue(
const MCInst &MI,
unsigned OpIdx,
50 return getOffsetUImm12OpValue(MI, OpIdx, Fixups, MemSize);
53 unsigned getOffsetUImm12OpValue(
const MCInst &MI,
unsigned OpIdx,
57 unsigned getBitfield32LSLOpValue(
const MCInst &MI,
unsigned OpIdx,
59 unsigned getBitfield64LSLOpValue(
const MCInst &MI,
unsigned OpIdx,
62 unsigned getShiftRightImm8(
const MCInst &MI,
unsigned Op,
64 unsigned getShiftRightImm16(
const MCInst &MI,
unsigned Op,
66 unsigned getShiftRightImm32(
const MCInst &MI,
unsigned Op,
68 unsigned getShiftRightImm64(
const MCInst &MI,
unsigned Op,
71 unsigned getShiftLeftImm8(
const MCInst &MI,
unsigned Op,
73 unsigned getShiftLeftImm16(
const MCInst &MI,
unsigned Op,
75 unsigned getShiftLeftImm32(
const MCInst &MI,
unsigned Op,
77 unsigned getShiftLeftImm64(
const MCInst &MI,
unsigned Op,
82 template<AArch64::Fixups fixupDesired>
83 unsigned getLabelOpValue(
const MCInst &MI,
unsigned OpIdx,
86 unsigned getLoadLitLabelOpValue(
const MCInst &MI,
unsigned OpIdx,
90 unsigned getMoveWideImmOpValue(
const MCInst &MI,
unsigned OpIdx,
94 unsigned getAddressWithFixup(
const MCOperand &MO,
101 uint64_t getBinaryCodeForInstr(
const MCInst &MI,
114 void EmitInstruction(uint32_t Val,
raw_ostream &OS)
const {
116 for (
unsigned i = 0; i != 4; ++i) {
117 EmitByte(Val & 0xff, OS);
126 template<
int hasRs,
int hasRt2>
unsigned
127 fixLoadStoreExclusive(
const MCInst &MI,
unsigned EncodedValue)
const;
129 unsigned fixMOVZ(
const MCInst &MI,
unsigned EncodedValue)
const;
131 unsigned fixMulHigh(
const MCInst &MI,
unsigned EncodedValue)
const;
138 unsigned AArch64MCCodeEmitter::getAddressWithFixup(
const MCOperand &MO,
145 assert(MO.
isImm() &&
"Unexpected address requested");
156 unsigned AArch64MCCodeEmitter::
157 getOffsetUImm12OpValue(
const MCInst &
MI,
unsigned OpIdx,
164 assert(ImmOp.
isExpr() &&
"Unexpected operand type");
169 switch (Expr->getKind()) {
177 assert(MemSize <= 16 &&
"Invalid fixup for operation");
178 FixupKind = FixupsBySize[
Log2_32(MemSize)];
182 assert(MemSize == 8 &&
"Invalid fixup for operation");
186 static const unsigned FixupsBySize[] = {
192 assert(MemSize <= 8 &&
"Invalid fixup for operation");
193 FixupKind = FixupsBySize[
Log2_32(MemSize)];
197 static const unsigned FixupsBySize[] = {
203 assert(MemSize <= 8 &&
"Invalid fixup for operation");
204 FixupKind = FixupsBySize[
Log2_32(MemSize)];
208 assert(MemSize == 8 &&
"Invalid fixup for operation");
212 static const unsigned FixupsBySize[] = {
218 assert(MemSize <= 8 &&
"Invalid fixup for operation");
219 FixupKind = FixupsBySize[
Log2_32(MemSize)];
223 static const unsigned FixupsBySize[] = {
229 assert(MemSize <= 8 &&
"Invalid fixup for operation");
230 FixupKind = FixupsBySize[
Log2_32(MemSize)];
234 assert(MemSize == 8 &&
"Invalid fixup for operation");
239 return getAddressWithFixup(ImmOp, FixupKind, Fixups);
243 AArch64MCCodeEmitter::getAddSubImmOpValue(
const MCInst &MI,
unsigned OpIdx,
247 return static_cast<unsigned>(MO.
getImm());
251 unsigned FixupKind = 0;
252 switch(cast<AArch64MCExpr>(MO.
getExpr())->getKind()) {
272 return getAddressWithFixup(MO, FixupKind, Fixups);
276 AArch64MCCodeEmitter::getAdrpLabelOpValue(
const MCInst &MI,
unsigned OpIdx,
281 return static_cast<unsigned>(MO.
getImm());
287 Modifier = Expr->getKind();
289 unsigned FixupKind = 0;
307 return getAddressWithFixup(MO, FixupKind, Fixups);
311 AArch64MCCodeEmitter::getBitfield32LSLOpValue(
const MCInst &MI,
unsigned OpIdx,
315 assert(MO.
isImm() &&
"Only immediate expected for shift");
317 return ((32 - MO.
getImm()) & 0x1f) | (31 - MO.
getImm()) << 6;
321 AArch64MCCodeEmitter::getBitfield64LSLOpValue(
const MCInst &MI,
unsigned OpIdx,
325 assert(MO.
isImm() &&
"Only immediate expected for shift");
327 return ((64 - MO.
getImm()) & 0x3f) | (63 - MO.
getImm()) << 6;
330 unsigned AArch64MCCodeEmitter::getShiftRightImm8(
335 unsigned AArch64MCCodeEmitter::getShiftRightImm16(
340 unsigned AArch64MCCodeEmitter::getShiftRightImm32(
345 unsigned AArch64MCCodeEmitter::getShiftRightImm64(
350 unsigned AArch64MCCodeEmitter::getShiftLeftImm8(
355 unsigned AArch64MCCodeEmitter::getShiftLeftImm16(
360 unsigned AArch64MCCodeEmitter::getShiftLeftImm32(
365 unsigned AArch64MCCodeEmitter::getShiftLeftImm64(
370 template<AArch64::Fixups fixupDesired>
unsigned
371 AArch64MCCodeEmitter::getLabelOpValue(
const MCInst &MI,
377 return getAddressWithFixup(MO, fixupDesired, Fixups);
384 AArch64MCCodeEmitter::getLoadLitLabelOpValue(
const MCInst &MI,
395 if (isa<AArch64MCExpr>(MO.
getExpr())) {
396 assert(dyn_cast<AArch64MCExpr>(MO.
getExpr())->getKind()
398 &&
"Invalid symbol modifier for literal load");
404 return getAddressWithFixup(MO, FixupKind, Fixups);
409 AArch64MCCodeEmitter::getMachineOpValue(
const MCInst &MI,
413 return Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg());
414 }
else if (MO.
isImm()) {
415 return static_cast<unsigned>(MO.
getImm());
423 AArch64MCCodeEmitter::getMoveWideImmOpValue(
const MCInst &MI,
unsigned OpIdx,
428 unsigned Result =
static_cast<unsigned>(ShiftMO.
getImm()) << 16;
430 if (UImm16MO.
isImm()) {
431 Result |= UImm16MO.
getImm();
485 return Result | getAddressWithFixup(UImm16MO, requestedFixup, Fixups);
488 template<
int hasRs,
int hasRt2>
unsigned
489 AArch64MCCodeEmitter::fixLoadStoreExclusive(
const MCInst &MI,
490 unsigned EncodedValue)
const {
491 if (!hasRs) EncodedValue |= 0x001F0000;
492 if (!hasRt2) EncodedValue |= 0x00007C00;
498 AArch64MCCodeEmitter::fixMOVZ(
const MCInst &MI,
unsigned EncodedValue)
const {
506 if (UImm16MO.
isImm())
521 return EncodedValue & ~(1u << 30);
531 AArch64MCCodeEmitter::fixMulHigh(
const MCInst &MI,
532 unsigned EncodedValue)
const {
535 EncodedValue |= 0x1f << 10;
543 return new AArch64MCCodeEmitter(Ctx);
546 void AArch64MCCodeEmitter::
560 uint32_t
Binary = getBinaryCodeForInstr(MI, Fixups);
562 EmitInstruction(Binary, OS);
566 #include "AArch64GenMCCodeEmitter.inc"
void push_back(const T &Elt)
MCCodeEmitter * createAArch64MCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI, MCContext &Ctx)
static const AArch64MCExpr * CreateTLSDesc(const MCExpr *Expr, MCContext &Ctx)
#define llvm_unreachable(msg)
VariantKind getKind() const
getOpcode - Get the kind of this expression.
unsigned getReg() const
getReg - Returns the register number.
const MCExpr * getExpr() const
MCCodeEmitter - Generic instruction encoding interface.
MCFixupKind
MCFixupKind - Extensible enumeration to represent the type of a fixup.
#define LLVM_DELETED_FUNCTION
unsigned Log2_32(uint32_t Value)
unsigned getOpcode() const
static MCFixup Create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
const MCRegisterInfo & MRI
const MCOperand & getOperand(unsigned i) const