14 #define DEBUG_TYPE "asm-printer"
27 #define GET_INSTRUCTION_NAME
28 #define PRINT_ALIAS_INSTR
29 #include "AArch64GenAsmWriter.inc"
32 assert(!(Value & ~((1ULL << BitWidth)-1)) &&
"immediate not n-bit");
33 if (Value & (1ULL << (BitWidth - 1)))
34 return static_cast<int64_t
>(Value) - (1LL << BitWidth);
66 unsigned OptionHi = ExtImm >> 1;
67 unsigned S = ExtImm & 1;
68 bool IsLSL = OptionHi == 1 && RmSize == 64;
73 Ext = (RmSize == 32) ?
"uxtw" :
"lsl";
76 Ext = (RmSize == 32) ?
"sxtw" :
"sxtx";
84 unsigned ShiftAmt =
Log2_32(MemSize);
85 O <<
" #" << ShiftAmt;
96 if (Imm12Op.
isImm()) {
97 int64_t Imm12 = Imm12Op.
getImm();
98 assert(Imm12 >= 0 &&
"Invalid immediate for add/sub imm");
101 assert(Imm12Op.
isExpr() &&
"Unexpected shift operand type");
102 O <<
"#" << *Imm12Op.
getExpr();
122 template<
unsigned RegW
idth>
void
126 unsigned LSB = ImmROp.
getImm() == 0 ? 0 : RegWidth - ImmROp.
getImm();
134 unsigned Width = ImmSOp.
getImm() + 1;
145 unsigned ImmR = ImmROp.
getImm();
146 unsigned ImmS = ImmSOp.
getImm();
148 assert(ImmS >= ImmR &&
"Invalid ImmR, ImmS combination for bitfield extract");
150 O <<
'#' << (ImmS - ImmR + 1);
167 O <<
'#' << (64 - ScaleOp.
getImm());
175 assert(MOImm8.
isImm()
176 &&
"Immediate operand required for floating-point immediate inst");
179 uint32_t Fraction = Imm8 & 0xf;
180 uint32_t Exponent = (Imm8 >> 4) & 0x7;
181 uint32_t Negative = (Imm8 >> 7) & 0x1;
183 float Val = 1.0f + Fraction / 16.0f;
188 if (Exponent & 0x4) {
189 Val /= 1 << (7 - Exponent);
191 Val *= 1 << (Exponent + 1);
194 Val = Negative ? -Val : Val;
196 o <<
'#' <<
format(
"%.8f", Val);
209 O << A64CondCodeToString(static_cast<A64CC::CondCodes>(MO.
getImm()));
212 template <
unsigned field_w
idth,
unsigned scale>
void
224 uint64_t UImm = MO.
getImm();
225 uint64_t Sign = UImm & (1LL << (field_width - 1));
226 int64_t SImm = scale * ((UImm & ~Sign) - Sign);
231 template<
unsigned RegW
idth>
void
247 uint32_t Imm = MOImm.
getImm() * MemSize;
270 default:
llvm_unreachable(
"Invalid shift specifier in logical instruction");
282 if (UImm16MO.
isImm()) {
283 O <<
'#' << UImm16MO.
getImm();
285 if (ShiftMO.
getImm() != 0)
286 O <<
", lsl #" << (ShiftMO.
getImm() * 16);
291 O <<
"#" << *UImm16MO.
getExpr();
334 if (Reg0 == AArch64::XSP || Reg1 == AArch64::XSP)
339 if (Ext == LSLEquiv) {
362 template<
int MemScale>
void
368 O <<
"#" << (Imm * MemScale);
385 }
else if (Op.
isImm()) {
388 assert(Op.
isExpr() &&
"unknown operand kind in printOperand");
393 if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) {
418 template <A64SE::ShiftExtSpecifiers Ext,
bool isHalf>
425 "Immediate operand required for Neon vector immediate inst.");
433 int64_t Imm = MO.
getImm();
436 if ((!IsLSL || (IsLSL && isHalf)) && Imm != 0 && Imm != 1)
440 if (IsLSL && (Imm < 0 || Imm > 3))
469 assert(MOUImm.
isImm() &&
470 "Immediate operand required for Neon vector immediate inst.");
472 unsigned Imm = MOUImm.
getImm();
483 assert(MOUImm.
isImm()
484 &&
"Immediate operand required for Neon vector immediate inst.");
486 unsigned Imm = MOUImm.
getImm();
495 assert(MOUImm8.
isImm() &&
496 "Immediate operand required for Neon vector immediate bytemask inst.");
498 uint32_t UImm8 = MOUImm8.
getImm();
502 for (
unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) {
503 if ((UImm8 >> ByteNum) & 1)
504 Mask |= (uint64_t)0xff << (8 * ByteNum);
515 template <A64Layout::VectorLayout Layout,
unsigned Count>
518 assert(Count >= 1 && Count <= 4 &&
"Invalid Number of Vectors");
525 unsigned SubRegIdx = IsVec64 ? AArch64::dsub_0 : AArch64::qsub_0;
526 for (
unsigned I = 0;
I < Count;
I++) {
529 O << Name << LayoutStr;
536 O << Name << LayoutStr;
virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot)
void printBFIWidthOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void printNeonMovImmShiftOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
bool isLogicalImmBits(unsigned RegWidth, uint32_t Bits, uint64_t &Imm)
void printSysRegOperand(const A64SysReg::SysRegMapper &Mapper, const MCInst *MI, unsigned OpNum, raw_ostream &O)
void printInstruction(const MCInst *MI, raw_ostream &O)
void printBFILSBOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
void printFPImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &o)
bool isStackReg(unsigned RegNo)
void printOffsetSImm9Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
bool printAliasInstr(const MCInst *MI, raw_ostream &O)
#define llvm_unreachable(msg)
void printCVTFixedPosOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
void printRegName(raw_ostream &O, unsigned RegNum) const
printRegName - Print the assembler register name.
format_object1< T > format(const char *Fmt, const T &Val)
void printAddSubImmLSL12Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
unsigned getReg() const
getReg - Returns the register number.
raw_ostream & write_hex(unsigned long long N)
write_hex - Output N in hexadecimal, without any prefix or padding.
void printRegExtendOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
void printUImmHexOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
void printLabelOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
const MCExpr * getExpr() const
static const char * A64VectorLayoutToString(A64Layout::VectorLayout Layout)
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
void printNeonUImm0Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
void printLogicalImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
void printCRxOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
void printOffsetUImm12Operand(const MCInst *MI, unsigned OpNum, raw_ostream &o)
AArch64InstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI)
void printVPRRegister(const MCInst *MI, unsigned OpNo, raw_ostream &O)
uint64_t getFeatureBits() const
void printVectorList(const MCInst *MI, unsigned OpNum, raw_ostream &O)
void printSImm7ScaledOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
static int64_t unpackSignedImm(int BitWidth, uint64_t Value)
static const char * getRegisterName(unsigned RegNo)
void printShiftOperand(const char *name, const MCInst *MI, unsigned OpIdx, raw_ostream &O)
unsigned Log2_32(uint32_t Value)
void printBareImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
unsigned getOpcode() const
void printBFXWidthOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
std::string toString(uint32_t Bits, bool &Valid) const
StringRef toString(uint32_t Value, bool &Valid) const
void printMoveWideImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
void printAddrRegExtendOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
void printNeonUImm64MaskOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
LLVM Value Representation.
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
void setAvailableFeatures(uint64_t Value)
void printFPZeroOperand(const MCInst *MI, unsigned OpNum, raw_ostream &o)
const MCRegisterInfo & MRI
void printUImmBareOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
void printCondCodeOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
void printAddSubImmLSL0Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
const MCOperand & getOperand(unsigned i) const
void printNamedImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O)
const MCRegisterInfo & MRI