//==-- AArch64InstPrinter.cpp - Convert AArch64 MCInst to assembly syntax --==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class prints an AArch64 MCInst to a .s file.
//
//===----------------------------------------------------------------------===//

/* Capstone Disassembler Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>

#include "AArch64InstPrinter.h"
#include "AArch64BaseInfo.h"
#include "../../MCInst.h"
#include "../../cs_priv.h"
#include "../../SStream.h"
#include "../../MCRegisterInfo.h"
#include "../../MathExtras.h"
#include "../../utils.h"

#include "mapping.h"

static char *getRegisterName(unsigned RegNo);
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);

// FIXME: make this status session's specific, not global like this
static bool doing_mem = false;
static void set_mem_access(MCInst *MI, bool status)
{
	if (MI->csh->detail != CS_OPT_ON)
		return;

	doing_mem = status;

	if (doing_mem) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_MEM;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].mem.base = ARM64_REG_INVALID;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].mem.index = ARM64_REG_INVALID;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].mem.disp = 0;
	} else {
		// done, create the next operand slot
		MI->flat_insn.arm64.op_count++;
	}
}

static int64_t unpackSignedImm(int BitWidth, uint64_t Value)
{
	//assert(!(Value & ~((1ULL << BitWidth)-1)) && "immediate not n-bit");
	if (Value & (1ULL <<  (BitWidth - 1)))
		return (int64_t)Value - (1LL << BitWidth);
	else
		return Value;
}

static void printOffsetSImm9Operand(MCInst *MI, unsigned OpNum, SStream *O)
{
	MCOperand *MOImm = MCInst_getOperand(MI, OpNum);
	int32_t Imm = unpackSignedImm(9, MCOperand_getImm(MOImm));

	if (Imm > HEX_THRESHOLD)
		SStream_concat(O, "#0x%x", Imm);
	else
		SStream_concat(O, "#%u", Imm);

	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = Imm;
		MI->flat_insn.arm64.op_count++;
	}
}

static void printAddrRegExtendOperand(MCInst *MI, unsigned OpNum,
		SStream *O, unsigned MemSize, unsigned RmSize)
{
	unsigned ExtImm = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
	unsigned OptionHi = ExtImm >> 1;
	unsigned S = ExtImm & 1;
	bool IsLSL = OptionHi == 1 && RmSize == 64;

	char *Ext = 0;
	switch (OptionHi) {
		case 1:
			if (RmSize == 32) {
				Ext = "uxtw";
				if (MI->csh->detail)
					MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].ext = ARM64_EXT_UXTW;
			} else {
				Ext = "lsl";
			}
			break;
		case 3:
			if (RmSize == 32) {
				Ext = "sxtw";
				if (MI->csh->detail)
					MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].ext = ARM64_EXT_SXTW;
			} else {
				Ext = "sxtx";
				if (MI->csh->detail)
					MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].ext = ARM64_EXT_SXTX;
			}
			break;
		default:
			break; //llvm_unreachable("Incorrect Option on load/store (reg offset)");
	}
	SStream_concat(O, Ext);

	if (S) {
		unsigned ShiftAmt = Log2_32(MemSize);
		if (ShiftAmt > HEX_THRESHOLD)
			SStream_concat(O, " #0x%x", ShiftAmt);
		else
			SStream_concat(O, " #%u", ShiftAmt);
			if (MI->csh->detail) {
				if (doing_mem) {
					MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].shift.type = ARM64_SFT_LSL;
					MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].shift.value = ShiftAmt;
				} else {
					MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.type = ARM64_SFT_LSL;
					MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.value = ShiftAmt;
				}
			}
	} else if (IsLSL) {
		SStream_concat(O, " #0");
	}
}

static void printAddSubImmLSL0Operand(MCInst *MI, unsigned OpNum, SStream *O)
{
	MCOperand *Imm12Op = MCInst_getOperand(MI, OpNum);

	if (MCOperand_isImm(Imm12Op)) {
		int64_t Imm12 = MCOperand_getImm(Imm12Op);
		//assert(Imm12 >= 0 && "Invalid immediate for add/sub imm");
		if (Imm12 > HEX_THRESHOLD)
			SStream_concat(O, "#0x%"PRIx64, Imm12);
		else
			SStream_concat(O, "#%u"PRIu64, Imm12);
		if (MI->csh->detail) {
			MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
			MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = Imm12;
			MI->flat_insn.arm64.op_count++;
		}
	}
}

static void printAddSubImmLSL12Operand(MCInst *MI, unsigned OpNum, SStream *O)
{
	printAddSubImmLSL0Operand(MI, OpNum, O);

	SStream_concat(O, ", lsl #12");
	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.type = ARM64_SFT_LSL;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.value = 12;
	}
}

static void printBareImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
{
	MCOperand *MO = MCInst_getOperand(MI, OpNum);
	uint64_t imm = MCOperand_getImm(MO);
	if (imm > HEX_THRESHOLD)
		SStream_concat(O, "0x%"PRIx64, imm);
	else
		SStream_concat(O, "%"PRIu64, imm);
	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = imm;
		MI->flat_insn.arm64.op_count++;
	}
}

static void printBFILSBOperand(MCInst *MI, unsigned OpNum,
		SStream *O, unsigned RegWidth)
{
	MCOperand *ImmROp = MCInst_getOperand(MI, OpNum);
	unsigned LSB = MCOperand_getImm(ImmROp) == 0 ? 0 : RegWidth - MCOperand_getImm(ImmROp);

	if (LSB > HEX_THRESHOLD)
		SStream_concat(O, "#0x%x", LSB);
	else
		SStream_concat(O, "#%u", LSB);
	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = LSB;
		MI->flat_insn.arm64.op_count++;
	}
}

static void printBFIWidthOperand(MCInst *MI, unsigned OpNum, SStream *O)
{
	MCOperand *ImmSOp = MCInst_getOperand(MI, OpNum);
	unsigned Width = MCOperand_getImm(ImmSOp) + 1;

	if (Width > HEX_THRESHOLD)
		SStream_concat(O, "#0x%x", Width);
	else
		SStream_concat(O, "#%u", Width);
}

static void printBFXWidthOperand(MCInst *MI, unsigned OpNum, SStream *O)
{
	MCOperand *ImmSOp = MCInst_getOperand(MI, OpNum);
	MCOperand *ImmROp = MCInst_getOperand(MI, OpNum - 1);

	unsigned ImmR = MCOperand_getImm(ImmROp);
	unsigned ImmS = MCOperand_getImm(ImmSOp);

	//assert(ImmS >= ImmR && "Invalid ImmR, ImmS combination for bitfield extract");

	if (ImmS - ImmR + 1 > HEX_THRESHOLD)
		SStream_concat(O, "#0x%x", (ImmS - ImmR + 1));
	else
		SStream_concat(O, "#%u", (ImmS - ImmR + 1));

	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = ImmS - ImmR + 1;
		MI->flat_insn.arm64.op_count++;
	}
}

static void printCRxOperand(MCInst *MI, unsigned OpNum, SStream *O)
{
	MCOperand *CRx = MCInst_getOperand(MI, OpNum);
	SStream_concat(O, "c%"PRIu64, MCOperand_getImm(CRx));

	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_CIMM;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = MCOperand_getImm(CRx);
		MI->flat_insn.arm64.op_count++;
	}
}

static void printCVTFixedPosOperand(MCInst *MI, unsigned OpNum, SStream *O)
{
	MCOperand *ScaleOp = MCInst_getOperand(MI, OpNum);

	if (64 - MCOperand_getImm(ScaleOp) > HEX_THRESHOLD)
		SStream_concat(O, "#0x%x", 64 - MCOperand_getImm(ScaleOp));
	else
		SStream_concat(O, "#%u", 64 - MCOperand_getImm(ScaleOp));
	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = 64 - MCOperand_getImm(ScaleOp);
		MI->flat_insn.arm64.op_count++;
	}
}

static void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
{
	MCOperand *MOImm8 = MCInst_getOperand(MI, OpNum);

	//assert(MOImm8.isImm()
	//       && "Immediate operand required for floating-point immediate inst");

	uint32_t Imm8 = MCOperand_getImm(MOImm8);
	uint32_t Fraction = Imm8 & 0xf;
	uint32_t Exponent = (Imm8 >> 4) & 0x7;
	uint32_t Negative = (Imm8 >> 7) & 0x1;

	float Val = 1.0f + Fraction / 16.0f;

	// That is:
	// 000 -> 2^1,  001 -> 2^2,  010 -> 2^3,  011 -> 2^4,
	// 100 -> 2^-3, 101 -> 2^-2, 110 -> 2^-1, 111 -> 2^0
	if (Exponent & 0x4) {
		Val /= 1 << (7 - Exponent);
	} else {
		Val *= 1 << (Exponent + 1);
	}

	Val = Negative ? -Val : Val;

	//o << '#' << format("%.8f", Val);
	SStream_concat(O, "#%.8f", Val);
	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_FP;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].fp = Val;
		MI->flat_insn.arm64.op_count++;
	}
}

static void printFPZeroOperand(MCInst *MI, unsigned OpNum, SStream *O)
{
	SStream_concat(O, "#0.0");
	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_FP;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].fp = 0;
		MI->flat_insn.arm64.op_count++;
	}
}

static void printCondCodeOperand(MCInst *MI, unsigned OpNum, SStream *O)
{
	MCOperand *MO = MCInst_getOperand(MI, OpNum);
	SStream_concat(O, A64CondCodeToString((A64CC_CondCodes)(MCOperand_getImm(MO))));
	if (MI->csh->detail)
		MI->flat_insn.arm64.cc = MCOperand_getImm(MO) + 1;
}

static void printLabelOperand(MCInst *MI, unsigned OpNum,
		SStream *O, unsigned field_width, unsigned scale)
{
	MCOperand *MO = MCInst_getOperand(MI, OpNum);

	if (!MCOperand_isImm(MO)) {
		printOperand(MI, OpNum, O);
		return;
	}

	// The immediate of LDR (lit) instructions is a signed 19-bit immediate, which
	// is multiplied by 4 (because all A64 instructions are 32-bits wide).
	uint64_t UImm = MCOperand_getImm(MO);
	uint64_t Sign = UImm & (1LL << (field_width - 1));
	int64_t SImm = scale * ((UImm & ~Sign) - Sign);

	// this is a relative address, so add with the address
	// of current instruction
	SImm += MI->address;

	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = SImm;
		MI->flat_insn.arm64.op_count++;
	}

	if (SImm > HEX_THRESHOLD)
		SStream_concat(O, "#0x%"PRIx64, SImm);
	else
		SStream_concat(O, "#%"PRIu64, SImm);
}

static void printLogicalImmOperand(MCInst *MI, unsigned OpNum,
		SStream *O, unsigned RegWidth)
{
	MCOperand *MO = MCInst_getOperand(MI, OpNum);
	uint64_t Val;
	A64Imms_isLogicalImmBits(RegWidth, MCOperand_getImm(MO), &Val);
	if (Val > HEX_THRESHOLD)
		SStream_concat(O, "#0x%"PRIx64, Val);
	else
		SStream_concat(O, "#%"PRIu64, Val);
	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = Val;
		MI->flat_insn.arm64.op_count++;
	}
}

static void printOffsetUImm12Operand(MCInst *MI, unsigned OpNum,
		SStream *O, int MemSize)
{
	MCOperand *MOImm = MCInst_getOperand(MI, OpNum);

	if (MCOperand_isImm(MOImm)) {
		uint32_t Imm = MCOperand_getImm(MOImm) * MemSize;

		if (Imm > HEX_THRESHOLD)
			SStream_concat(O, "#0x%x", Imm);
		else
			SStream_concat(O, "#%u", Imm);

		if (MI->csh->detail) {
			if (doing_mem) {
				MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].mem.disp = Imm;
			} else {
				MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
				MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = Imm;
				MI->flat_insn.arm64.op_count++;
			}
		}
	}
}

static void printShiftOperand(MCInst *MI,  unsigned OpNum,
		SStream *O, A64SE_ShiftExtSpecifiers Shift)
{
	MCOperand *MO = MCInst_getOperand(MI, OpNum);

	// LSL #0 is not printed
	if (Shift == A64SE_LSL && MCOperand_isImm(MO) && MCOperand_getImm(MO) == 0)
		return;

	switch (Shift) {
		case A64SE_LSL: SStream_concat(O, "lsl"); break;
		case A64SE_LSR: SStream_concat(O, "lsr"); break;
		case A64SE_ASR: SStream_concat(O, "asr"); break;
		case A64SE_ROR: SStream_concat(O, "ror"); break;
		default: break; // llvm_unreachable("Invalid shift specifier in logical instruction");
	}

	unsigned int imm = MCOperand_getImm(MO);
	if (imm > HEX_THRESHOLD)
		SStream_concat(O, " #0x%x", imm);
	else
		SStream_concat(O, " #%u", imm);
	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.type = Shift + 1;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.value = imm;
	}
}

static void printMoveWideImmOperand(MCInst *MI,  unsigned OpNum, SStream *O)
{
	MCOperand *UImm16MO = MCInst_getOperand(MI, OpNum);
	MCOperand *ShiftMO = MCInst_getOperand(MI, OpNum + 1);

	if (MCOperand_isImm(UImm16MO)) {
		uint64_t imm = MCOperand_getImm(UImm16MO);
		if (imm > HEX_THRESHOLD)
			SStream_concat(O, "#0x%"PRIx64, imm);
		else
			SStream_concat(O, "#%"PRIu64, imm);
		if (MI->csh->detail) {
			MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
			MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = imm;
			MI->flat_insn.arm64.op_count++;
		}

		if (MCOperand_getImm(ShiftMO) != 0) {
			unsigned int shift = MCOperand_getImm(ShiftMO) * 16;
			if (shift > HEX_THRESHOLD)
				SStream_concat(O, ", lsl #0x%x", shift);
			else
				SStream_concat(O, ", lsl #%u", shift);
			if (MI->csh->detail) {
				MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.type = ARM64_SFT_LSL;
				MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.value = shift;
			}
		}

		return;
	}
}

static void printNamedImmOperand(NamedImmMapper *Mapper,
		MCInst *MI, unsigned OpNum, SStream *O)
{
	bool ValidName;
	MCOperand *MO = MCInst_getOperand(MI, OpNum);
	char *Name = NamedImmMapper_toString(Mapper, MCOperand_getImm(MO), &ValidName);

	if (ValidName)
		SStream_concat(O, Name);
	else {
		uint64_t imm = MCOperand_getImm(MO);
		if (imm > HEX_THRESHOLD)
			SStream_concat(O, "#0x%"PRIx64, imm);
		else
			SStream_concat(O, "#%"PRIu64, imm);
		if (MI->csh->detail) {
			MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
			MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = imm;
			MI->flat_insn.arm64.op_count++;
		}
	}
}

static void printSysRegOperand(SysRegMapper *Mapper,
		MCInst *MI, unsigned OpNum, SStream *O)
{
	bool ValidName;
	char Name[128];

	MCOperand *MO = MCInst_getOperand(MI, OpNum);

	SysRegMapper_toString(Mapper, MCOperand_getImm(MO), &ValidName, Name);
	if (ValidName) {
		SStream_concat(O, Name);
	}
}

#define GET_REGINFO_ENUM
#include "AArch64GenRegisterInfo.inc"

static inline bool isStackReg(unsigned RegNo)
{
	return RegNo == AArch64_XSP || RegNo == AArch64_WSP;
}

static void printRegExtendOperand(MCInst *MI, unsigned OpNum, SStream *O,
		A64SE_ShiftExtSpecifiers Ext)
{
	// FIXME: In principle TableGen should be able to detect this itself far more
	// easily. We will only accumulate more of these hacks.
	unsigned Reg0 = MCOperand_getReg(MCInst_getOperand(MI, 0));
	unsigned Reg1 = MCOperand_getReg(MCInst_getOperand(MI, 1));

	if (isStackReg(Reg0) || isStackReg(Reg1)) {
		A64SE_ShiftExtSpecifiers LSLEquiv;

		if (Reg0 == AArch64_XSP || Reg1 == AArch64_XSP)
			LSLEquiv = A64SE_UXTX;
		else
			LSLEquiv = A64SE_UXTW;

		if (Ext == LSLEquiv) {
			unsigned int shift = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
			if (shift > HEX_THRESHOLD)
				SStream_concat(O, "lsl #0x%x", shift);
			else
				SStream_concat(O, "lsl #%u", shift);
			if (MI->csh->detail) {
				MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.type = ARM64_SFT_LSL;
				MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.value = shift;
				MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].ext = Ext - 4;
			}
			return;
		}
	}

	switch (Ext) {
		case A64SE_UXTB: SStream_concat(O, "uxtb"); break;
		case A64SE_UXTH: SStream_concat(O, "uxth"); break;
		case A64SE_UXTW: SStream_concat(O, "uxtw"); break;
		case A64SE_UXTX: SStream_concat(O, "uxtx"); break;
		case A64SE_SXTB: SStream_concat(O, "sxtb"); break;
		case A64SE_SXTH: SStream_concat(O, "sxth"); break;
		case A64SE_SXTW: SStream_concat(O, "sxtw"); break;
		case A64SE_SXTX: SStream_concat(O, "sxtx"); break;
		default: break; //llvm_unreachable("Unexpected shift type for printing");
	}

	if (MI->csh->detail)
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].ext = Ext - 4;
	MCOperand *MO = MCInst_getOperand(MI, OpNum);
	if (MCOperand_getImm(MO) != 0) {
		unsigned int shift = MCOperand_getImm(MO);
		if (shift > HEX_THRESHOLD)
			SStream_concat(O, " #0x%x", shift);
		else
			SStream_concat(O, " #%u", shift);
		if (MI->csh->detail) {
			MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.type = ARM64_SFT_LSL;
			MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.value = shift;
		}
	}
}

static void printSImm7ScaledOperand(MCInst *MI, unsigned OpNum,
		SStream *O, int MemScale)
{
	MCOperand *MOImm = MCInst_getOperand(MI, OpNum);
	int32_t Imm = unpackSignedImm(7, MCOperand_getImm(MOImm));

	if (Imm * MemScale > HEX_THRESHOLD)
		SStream_concat(O, "#0x%x", Imm * MemScale);
	else
		SStream_concat(O, "#%u", Imm * MemScale);
	if (MI->csh->detail) {
		if (doing_mem) {
			MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].mem.disp = Imm * MemScale;
		} else {
			MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
			MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = Imm * MemScale;
			MI->flat_insn.arm64.op_count++;
		}
	}
}

// TODO: handle this Vd register??
static void printVPRRegister(MCInst *MI, unsigned OpNo, SStream *O)
{
	unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNo));
	char *Name = strdup(getRegisterName(Reg));
	Name[0] = 'v';
	SStream_concat(O, "%s", Name);
	free(Name);
	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_REG;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].reg = Reg;
		MI->flat_insn.arm64.op_count++;
	}
}

static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
	MCOperand *Op = MCInst_getOperand(MI, OpNo);
	if (MCOperand_isReg(Op)) {
		unsigned Reg = MCOperand_getReg(Op);
		SStream_concat(O, getRegisterName(Reg));
		if (MI->csh->detail) {
			if (doing_mem) {
				if (MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].mem.base == ARM64_REG_INVALID) {
					MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].mem.base = Reg;
				} else {
					MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].mem.index = Reg;
				}
			} else {
				MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_REG;
				MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].reg = Reg;
				MI->flat_insn.arm64.op_count++;
			}
		}
	} else if (MCOperand_isImm(Op)) {
		int64_t imm = MCOperand_getImm(Op);
		if (imm > HEX_THRESHOLD)
			SStream_concat(O, "#0x%"PRIx64, imm);
		else
			SStream_concat(O, "#%"PRIu64, imm);
		if (MI->csh->detail) {
			if (doing_mem) {
				MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].mem.disp = imm;
			} else {
				MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
				MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = imm;
				MI->flat_insn.arm64.op_count++;
			}
		}
	}
}

#define GET_INSTRINFO_ENUM
#include "AArch64GenInstrInfo.inc"

static void printNeonMovImmShiftOperand(MCInst *MI, unsigned OpNum,
		SStream *O, A64SE_ShiftExtSpecifiers Ext, bool isHalf)
{
	MCOperand *MO = MCInst_getOperand(MI, OpNum);

	//assert(MO.isImm() &&
	//       "Immediate operand required for Neon vector immediate inst.");

	bool IsLSL = false;
	if (Ext == A64SE_LSL)
		IsLSL = true;
	else if (Ext != A64SE_MSL) {
		//llvm_unreachable("Invalid shift specifier in movi instruction");
	}

	int64_t Imm = MCOperand_getImm(MO);

	// MSL and LSLH accepts encoded shift amount 0 or 1.
	if ((!IsLSL || (IsLSL && isHalf)) && Imm != 0 && Imm != 1) {
		// llvm_unreachable("Invalid shift amount in movi instruction");
	}

	// LSH accepts encoded shift amount 0, 1, 2 or 3.
	if (IsLSL && (Imm < 0 || Imm > 3)) {
		//llvm_unreachable("Invalid shift amount in movi instruction");
	}

	// Print shift amount as multiple of 8 with MSL encoded shift amount
	// 0 and 1 printed as 8 and 16.
	if (!IsLSL)
		Imm++;
	Imm *= 8;

	// LSL #0 is not printed
	if (IsLSL) {
		if (Imm == 0)
			return;
		SStream_concat(O, ", lsl");
		if (MI->csh->detail)
			MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.type = ARM64_SFT_LSL;
	} else {
		SStream_concat(O, ", msl");
		if (MI->csh->detail)
			MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.type = ARM64_SFT_MSL;
	}

	if (Imm > HEX_THRESHOLD)
		SStream_concat(O, " #0x%"PRIx64, Imm);
	else
		SStream_concat(O, " #%"PRIu64, Imm);
	if (MI->csh->detail)
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count - 1].shift.value = Imm;
}

static void printNeonUImm0Operand(MCInst *MI, unsigned OpNum, SStream *O)
{
	SStream_concat(O, "#0");
	// FIXME: vector ZERO
	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = 0;
		MI->flat_insn.arm64.op_count++;
	}
}

static void printUImmHexOperand(MCInst *MI, unsigned OpNum, SStream *O)
{
	MCOperand *MOUImm = MCInst_getOperand(MI, OpNum);

	//assert(MOUImm.isImm() &&
	//       "Immediate operand required for Neon vector immediate inst.");

	unsigned Imm = MCOperand_getImm(MOUImm);

	if (Imm > HEX_THRESHOLD)
		SStream_concat(O, "#0x%x", Imm);
	else
		SStream_concat(O, "#%u", Imm);
	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = Imm;
		MI->flat_insn.arm64.op_count++;
	}
}

static void printUImmBareOperand(MCInst *MI, unsigned OpNum, SStream *O)
{
	MCOperand *MOUImm = MCInst_getOperand(MI, OpNum);

	//assert(MOUImm.isImm()
	//		&& "Immediate operand required for Neon vector immediate inst.");

	unsigned Imm = MCOperand_getImm(MOUImm);
	if (Imm > HEX_THRESHOLD)
		SStream_concat(O, "0x%x", Imm);
	else
		SStream_concat(O, "%u", Imm);

	if (MI->csh->detail) {
		if (doing_mem) {
			MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].mem.disp = Imm;
		} else {
			// FIXME: never has false branch??
		}
	}
}

static void printNeonUImm64MaskOperand(MCInst *MI, unsigned OpNum, SStream *O)
{
	MCOperand *MOUImm8 = MCInst_getOperand(MI, OpNum);

	//assert(MOUImm8.isImm() &&
	//       "Immediate operand required for Neon vector immediate bytemask inst.");

	uint32_t UImm8 = MCOperand_getImm(MOUImm8);
	uint64_t Mask = 0;

	// Replicates 0x00 or 0xff byte in a 64-bit vector
	unsigned ByteNum;
	for (ByteNum = 0; ByteNum < 8; ++ByteNum) {
		if ((UImm8 >> ByteNum) & 1)
			Mask |= (uint64_t)0xff << (8 * ByteNum);
	}

	if (Mask > HEX_THRESHOLD)
		SStream_concat(O, "#0x%"PRIx64, Mask);
	else
		SStream_concat(O, "#%"PRIu64, Mask);
	if (MI->csh->detail) {
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].type = ARM64_OP_IMM;
		MI->flat_insn.arm64.operands[MI->flat_insn.arm64.op_count].imm = Mask;
		MI->flat_insn.arm64.op_count++;
	}
}

static void printMRSOperand(MCInst *MI, unsigned OpNum, SStream *O)
{
	printSysRegOperand(&AArch64_MRSMapper, MI, OpNum, O);
}

static void printMSROperand(MCInst *MI, unsigned OpNum, SStream *O)
{
	printSysRegOperand(&AArch64_MSRMapper, MI, OpNum, O);
}

// If Count > 1, there are two valid kinds of vector list:
//   (1) {Vn.layout, Vn+1.layout, ... , Vm.layout}
//   (2) {Vn.layout - Vm.layout}
// We choose the first kind as output.
static void printVectorList(MCInst *MI, unsigned OpNum,
		SStream *O, MCRegisterInfo *MRI, A64Layout_VectorLayout Layout, unsigned Count)
{
	//assert(Count >= 1 && Count <= 4 && "Invalid Number of Vectors");

	unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
	const char *LayoutStr = A64VectorLayoutToString(Layout);
	SStream_concat(O, "{");
	if (Count > 1) { // Print sub registers separately
		bool IsVec64 = (Layout < A64Layout_VL_16B);
		unsigned SubRegIdx = IsVec64 ? AArch64_dsub_0 : AArch64_qsub_0;
		unsigned I;
		for (I = 0; I < Count; I++) {
			char *Name = strdup(getRegisterName(MCRegisterInfo_getSubReg(MRI, Reg, SubRegIdx++)));
			Name[0] = 'v';
			SStream_concat(O, "%s%s", Name, LayoutStr);
			if (I != Count - 1)
				SStream_concat(O, ", ");
			free(Name);
		}
	} else { // Print the register directly when NumVecs is 1.
		char *Name = strdup(getRegisterName(Reg));
		Name[0] = 'v';
		SStream_concat(O, "%s%s", Name, LayoutStr);
		free(Name);
	}
	SStream_concat(O, "}");
}

#define PRINT_ALIAS_INSTR
#include "AArch64GenAsmWriter.inc"

void AArch64_post_printer(csh handle, cs_insn *flat_insn, char *insn_asm)
{
	// check if this insn requests write-back
	if (strrchr(insn_asm, '!') != NULL)
		flat_insn->detail->arm64.writeback = true;
}

void AArch64_printInst(MCInst *MI, SStream *O, void *Info)
{
	if (printAliasInstr(MI, O, Info)) {
		char *mnem = strdup(O->buffer);
		char *tab = strchr(mnem, '\t');
		if (tab) {
			*tab = '\0';
		}
		// reflect the new insn name (alias) in the opcode
		unsigned int id = AArch64_map_insn(mnem);
		MCInst_setOpcode(MI, AArch64_get_insn_id2(id));
		MCInst_setOpcodePub(MI, id);
		free(mnem);
	} else
		AArch64InstPrinter_printInstruction(MI, O, Info);
}

