//===-- ARMAddressingModes.h - ARM Addressing Modes -------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the ARM addressing mode implementation stuff.
//
//===----------------------------------------------------------------------===//

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

#ifndef CS_LLVM_TARGET_ARM_ARMADDRESSINGMODES_H
#define CS_LLVM_TARGET_ARM_ARMADDRESSINGMODES_H

#include "../../include/platform.h"
#include "../../MathExtras.h"

/// ARM_AM - ARM Addressing Mode Stuff
typedef enum ARM_AM_ShiftOpc {
	ARM_AM_no_shift = 0,
	ARM_AM_asr,
	ARM_AM_lsl,
	ARM_AM_lsr,
	ARM_AM_ror,
	ARM_AM_rrx
} ARM_AM_ShiftOpc;

typedef enum ARM_AM_AddrOpc {
	ARM_AM_sub = 0,
	ARM_AM_add
} ARM_AM_AddrOpc;

static inline char *ARM_AM_getAddrOpcStr(ARM_AM_AddrOpc Op)
{
	return Op == ARM_AM_sub ? "-" : "";
}

static inline char *ARM_AM_getShiftOpcStr(ARM_AM_ShiftOpc Op)
{
	switch (Op) {
		default: return "";	//llvm_unreachable("Unknown shift opc!");
		case ARM_AM_asr: return "asr";
		case ARM_AM_lsl: return "lsl";
		case ARM_AM_lsr: return "lsr";
		case ARM_AM_ror: return "ror";
		case ARM_AM_rrx: return "rrx";
	}
}

static inline unsigned ARM_AM_getShiftOpcEncoding(ARM_AM_ShiftOpc Op)
{
	switch (Op) {
		default: return (unsigned int)-1;	//llvm_unreachable("Unknown shift opc!");
		case ARM_AM_asr: return 2;
		case ARM_AM_lsl: return 0;
		case ARM_AM_lsr: return 1;
		case ARM_AM_ror: return 3;
	}
}

typedef enum ARM_AM_AMSubMode {
	ARM_AM_bad_am_submode = 0,
	ARM_AM_ia,
	ARM_AM_ib,
	ARM_AM_da,
	ARM_AM_db
} ARM_AM_AMSubMode;

static inline const char *ARM_AM_getAMSubModeStr(ARM_AM_AMSubMode Mode)
{
	switch (Mode) {
		default: return "";
		case ARM_AM_ia: return "ia";
		case ARM_AM_ib: return "ib";
		case ARM_AM_da: return "da";
		case ARM_AM_db: return "db";
	}
}

/// rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
///
static inline unsigned rotr32(unsigned Val, unsigned Amt)
{
	//assert(Amt < 32 && "Invalid rotate amount");
	return (Val >> Amt) | (Val << ((32-Amt)&31));
}

/// rotl32 - Rotate a 32-bit unsigned value left by a specified # bits.
///
static inline unsigned rotl32(unsigned Val, unsigned Amt)
{
	//assert(Amt < 32 && "Invalid rotate amount");
	return (Val << Amt) | (Val >> ((32-Amt)&31));
}

//===--------------------------------------------------------------------===//
// Addressing Mode #1: shift_operand with registers
//===--------------------------------------------------------------------===//
//
// This 'addressing mode' is used for arithmetic instructions.  It can
// represent things like:
//   reg
//   reg [asr|lsl|lsr|ror|rrx] reg
//   reg [asr|lsl|lsr|ror|rrx] imm
//
// This is stored three operands [rega, regb, opc].  The first is the base
// reg, the second is the shift amount (or reg0 if not present or imm).  The
// third operand encodes the shift opcode and the imm if a reg isn't present.
//
static inline unsigned getSORegOpc(ARM_AM_ShiftOpc ShOp, unsigned Imm)
{
	return ShOp | (Imm << 3);
}

static inline unsigned getSORegOffset(unsigned Op)
{
	return Op >> 3;
}

static inline ARM_AM_ShiftOpc ARM_AM_getSORegShOp(unsigned Op)
{
	return (ARM_AM_ShiftOpc)(Op & 7);
}

/// getSOImmValImm - Given an encoded imm field for the reg/imm form, return
/// the 8-bit imm value.
static inline unsigned getSOImmValImm(unsigned Imm)
{
	return Imm & 0xFF;
}

/// getSOImmValRot - Given an encoded imm field for the reg/imm form, return
/// the rotate amount.
static inline unsigned getSOImmValRot(unsigned Imm)
{
	return (Imm >> 8) * 2;
}

/// getSOImmValRotate - Try to handle Imm with an immediate shifter operand,
/// computing the rotate amount to use.  If this immediate value cannot be
/// handled with a single shifter-op, determine a good rotate amount that will
/// take a maximal chunk of bits out of the immediate.
static inline unsigned getSOImmValRotate(unsigned Imm)
{
	unsigned TZ, RotAmt;
	// 8-bit (or less) immediates are trivially shifter_operands with a rotate
	// of zero.
	if ((Imm & ~255U) == 0) return 0;

	// Use CTZ to compute the rotate amount.
	TZ = CountTrailingZeros_32(Imm);

	// Rotate amount must be even.  Something like 0x200 must be rotated 8 bits,
	// not 9.
	RotAmt = TZ & ~1;

	// If we can handle this spread, return it.
	if ((rotr32(Imm, RotAmt) & ~255U) == 0)
		return (32-RotAmt)&31;  // HW rotates right, not left.

	// For values like 0xF000000F, we should ignore the low 6 bits, then
	// retry the hunt.
	if (Imm & 63U) {
		unsigned TZ2 = CountTrailingZeros_32(Imm & ~63U);
		unsigned RotAmt2 = TZ2 & ~1;
		if ((rotr32(Imm, RotAmt2) & ~255U) == 0)
			return (32-RotAmt2)&31;  // HW rotates right, not left.
	}

	// Otherwise, we have no way to cover this span of bits with a single
	// shifter_op immediate.  Return a chunk of bits that will be useful to
	// handle.
	return (32-RotAmt)&31;  // HW rotates right, not left.
}

/// getSOImmVal - Given a 32-bit immediate, if it is something that can fit
/// into an shifter_operand immediate operand, return the 12-bit encoding for
/// it.  If not, return -1.
static inline int getSOImmVal(unsigned Arg)
{
	unsigned RotAmt;
	// 8-bit (or less) immediates are trivially shifter_operands with a rotate
	// of zero.
	if ((Arg & ~255U) == 0) return Arg;

	RotAmt = getSOImmValRotate(Arg);

	// If this cannot be handled with a single shifter_op, bail out.
	if (rotr32(~255U, RotAmt) & Arg)
		return -1;

	// Encode this correctly.
	return rotl32(Arg, RotAmt) | ((RotAmt>>1) << 8);
}

/// isSOImmTwoPartVal - Return true if the specified value can be obtained by
/// or'ing together two SOImmVal's.
static inline bool isSOImmTwoPartVal(unsigned V)
{
	// If this can be handled with a single shifter_op, bail out.
	V = rotr32(~255U, getSOImmValRotate(V)) & V;
	if (V == 0)
		return false;

	// If this can be handled with two shifter_op's, accept.
	V = rotr32(~255U, getSOImmValRotate(V)) & V;
	return V == 0;
}

/// getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal,
/// return the first chunk of it.
static inline unsigned getSOImmTwoPartFirst(unsigned V)
{
	return rotr32(255U, getSOImmValRotate(V)) & V;
}

/// getSOImmTwoPartSecond - If V is a value that satisfies isSOImmTwoPartVal,
/// return the second chunk of it.
static inline unsigned getSOImmTwoPartSecond(unsigned V)
{
	// Mask out the first hunk.
	V = rotr32(~255U, getSOImmValRotate(V)) & V;

	// Take what's left.
	//assert(V == (rotr32(255U, getSOImmValRotate(V)) & V));
	return V;
}

/// getThumbImmValShift - Try to handle Imm with a 8-bit immediate followed
/// by a left shift. Returns the shift amount to use.
static inline unsigned getThumbImmValShift(unsigned Imm)
{
	// 8-bit (or less) immediates are trivially immediate operand with a shift
	// of zero.
	if ((Imm & ~255U) == 0) return 0;

	// Use CTZ to compute the shift amount.
	return CountTrailingZeros_32(Imm);
}

/// isThumbImmShiftedVal - Return true if the specified value can be obtained
/// by left shifting a 8-bit immediate.
static inline bool isThumbImmShiftedVal(unsigned V)
{
	// If this can be handled with
	V = (~255U << getThumbImmValShift(V)) & V;
	return V == 0;
}

/// getThumbImm16ValShift - Try to handle Imm with a 16-bit immediate followed
/// by a left shift. Returns the shift amount to use.
static inline unsigned getThumbImm16ValShift(unsigned Imm)
{
	// 16-bit (or less) immediates are trivially immediate operand with a shift
	// of zero.
	if ((Imm & ~65535U) == 0) return 0;

	// Use CTZ to compute the shift amount.
	return CountTrailingZeros_32(Imm);
}

/// isThumbImm16ShiftedVal - Return true if the specified value can be
/// obtained by left shifting a 16-bit immediate.
static inline bool isThumbImm16ShiftedVal(unsigned V)
{
	// If this can be handled with
	V = (~65535U << getThumbImm16ValShift(V)) & V;
	return V == 0;
}

/// getThumbImmNonShiftedVal - If V is a value that satisfies
/// isThumbImmShiftedVal, return the non-shiftd value.
static inline unsigned getThumbImmNonShiftedVal(unsigned V)
{
	return V >> getThumbImmValShift(V);
}


/// getT2SOImmValSplat - Return the 12-bit encoded representation
/// if the specified value can be obtained by splatting the low 8 bits
/// into every other byte or every byte of a 32-bit value. i.e.,
///     00000000 00000000 00000000 abcdefgh    control = 0
///     00000000 abcdefgh 00000000 abcdefgh    control = 1
///     abcdefgh 00000000 abcdefgh 00000000    control = 2
///     abcdefgh abcdefgh abcdefgh abcdefgh    control = 3
/// Return -1 if none of the above apply.
/// See ARM Reference Manual A6.3.2.
static inline int getT2SOImmValSplatVal(unsigned V)
{
	unsigned u, Vs, Imm;
	// control = 0
	if ((V & 0xffffff00) == 0)
		return V;

	// If the value is zeroes in the first byte, just shift those off
	Vs = ((V & 0xff) == 0) ? V >> 8 : V;
	// Any passing value only has 8 bits of payload, splatted across the word
	Imm = Vs & 0xff;
	// Likewise, any passing values have the payload splatted into the 3rd byte
	u = Imm | (Imm << 16);

	// control = 1 or 2
	if (Vs == u)
		return (((Vs == V) ? 1 : 2) << 8) | Imm;

	// control = 3
	if (Vs == (u | (u << 8)))
		return (3 << 8) | Imm;

	return -1;
}

/// getT2SOImmValRotateVal - Return the 12-bit encoded representation if the
/// specified value is a rotated 8-bit value. Return -1 if no rotation
/// encoding is possible.
/// See ARM Reference Manual A6.3.2.
static inline int getT2SOImmValRotateVal(unsigned V)
{
	unsigned RotAmt = CountLeadingZeros_32(V);
	if (RotAmt >= 24)
		return -1;

	// If 'Arg' can be handled with a single shifter_op return the value.
	if ((rotr32(0xff000000U, RotAmt) & V) == V)
		return (rotr32(V, 24 - RotAmt) & 0x7f) | ((RotAmt + 8) << 7);

	return -1;
}

/// getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit
/// into a Thumb-2 shifter_operand immediate operand, return the 12-bit
/// encoding for it.  If not, return -1.
/// See ARM Reference Manual A6.3.2.
static inline int getT2SOImmVal(unsigned Arg)
{
	int Rot;
	// If 'Arg' is an 8-bit splat, then get the encoded value.
	int Splat = getT2SOImmValSplatVal(Arg);
	if (Splat != -1)
		return Splat;

	// If 'Arg' can be handled with a single shifter_op return the value.
	Rot = getT2SOImmValRotateVal(Arg);
	if (Rot != -1)
		return Rot;

	return -1;
}

static inline unsigned getT2SOImmValRotate(unsigned V)
{
	unsigned RotAmt;

	if ((V & ~255U) == 0)
		return 0;

	// Use CTZ to compute the rotate amount.
	RotAmt = CountTrailingZeros_32(V);
	return (32 - RotAmt) & 31;
}

static inline bool isT2SOImmTwoPartVal (unsigned Imm)
{
	unsigned V = Imm;
	// Passing values can be any combination of splat values and shifter
	// values. If this can be handled with a single shifter or splat, bail
	// out. Those should be handled directly, not with a two-part val.
	if (getT2SOImmValSplatVal(V) != -1)
		return false;
	V = rotr32 (~255U, getT2SOImmValRotate(V)) & V;
	if (V == 0)
		return false;

	// If this can be handled as an immediate, accept.
	if (getT2SOImmVal(V) != -1) return true;

	// Likewise, try masking out a splat value first.
	V = Imm;
	if (getT2SOImmValSplatVal(V & 0xff00ff00U) != -1)
		V &= ~0xff00ff00U;
	else if (getT2SOImmValSplatVal(V & 0x00ff00ffU) != -1)
		V &= ~0x00ff00ffU;
	// If what's left can be handled as an immediate, accept.
	if (getT2SOImmVal(V) != -1) return true;

	// Otherwise, do not accept.
	return false;
}

static inline unsigned getT2SOImmTwoPartFirst(unsigned Imm)
{
	//assert (isT2SOImmTwoPartVal(Imm) &&
	//        "Immedate cannot be encoded as two part immediate!");
	// Try a shifter operand as one part
	unsigned V = rotr32 (~(unsigned int)255, getT2SOImmValRotate(Imm)) & Imm;
	// If the rest is encodable as an immediate, then return it.
	if (getT2SOImmVal(V) != -1) return V;

	// Try masking out a splat value first.
	if (getT2SOImmValSplatVal(Imm & 0xff00ff00U) != -1)
		return Imm & 0xff00ff00U;

	// The other splat is all that's left as an option.
	//assert (getT2SOImmValSplatVal(Imm & 0x00ff00ffU) != -1);
	return Imm & 0x00ff00ffU;
}

static inline unsigned getT2SOImmTwoPartSecond(unsigned Imm)
{
	// Mask out the first hunk
	Imm ^= getT2SOImmTwoPartFirst(Imm);
	// Return what's left
	//assert (getT2SOImmVal(Imm) != -1 &&
	//        "Unable to encode second part of T2 two part SO immediate");
	return Imm;
}


//===--------------------------------------------------------------------===//
// Addressing Mode #2
//===--------------------------------------------------------------------===//
//
// This is used for most simple load/store instructions.
//
// addrmode2 := reg +/- reg shop imm
// addrmode2 := reg +/- imm12
//
// The first operand is always a Reg.  The second operand is a reg if in
// reg/reg form, otherwise it's reg#0.  The third field encodes the operation
// in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The
// fourth operand 16-17 encodes the index mode.
//
// If this addressing mode is a frame index (before prolog/epilog insertion
// and code rewriting), this operand will have the form:  FI#, reg0, <offs>
// with no shift amount for the frame offset.
//
static inline unsigned ARM_AM_getAM2Opc(ARM_AM_AddrOpc Opc, unsigned Imm12, ARM_AM_ShiftOpc SO,
		unsigned IdxMode)
{
	//assert(Imm12 < (1 << 12) && "Imm too large!");
	bool isSub = Opc == ARM_AM_sub;
	return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ;
}

static inline unsigned getAM2Offset(unsigned AM2Opc)
{
	return AM2Opc & ((1 << 12)-1);
}

static inline ARM_AM_AddrOpc getAM2Op(unsigned AM2Opc)
{
	return ((AM2Opc >> 12) & 1) ? ARM_AM_sub : ARM_AM_add;
}

static inline ARM_AM_ShiftOpc getAM2ShiftOpc(unsigned AM2Opc)
{
	return (ARM_AM_ShiftOpc)((AM2Opc >> 13) & 7);
}

static inline unsigned getAM2IdxMode(unsigned AM2Opc)
{
	return (AM2Opc >> 16);
}

//===--------------------------------------------------------------------===//
// Addressing Mode #3
//===--------------------------------------------------------------------===//
//
// This is used for sign-extending loads, and load/store-pair instructions.
//
// addrmode3 := reg +/- reg
// addrmode3 := reg +/- imm8
//
// The first operand is always a Reg.  The second operand is a reg if in
// reg/reg form, otherwise it's reg#0.  The third field encodes the operation
// in bit 8, the immediate in bits 0-7. The fourth operand 9-10 encodes the
// index mode.

/// getAM3Opc - This function encodes the addrmode3 opc field.
static inline unsigned getAM3Opc(ARM_AM_AddrOpc Opc, unsigned char Offset,
		unsigned IdxMode)
{
	bool isSub = Opc == ARM_AM_sub;
	return ((int)isSub << 8) | Offset | (IdxMode << 9);
}

static inline unsigned char getAM3Offset(unsigned AM3Opc)
{
	return AM3Opc & 0xFF;
}

static inline ARM_AM_AddrOpc getAM3Op(unsigned AM3Opc)
{
	return ((AM3Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
}

static inline unsigned getAM3IdxMode(unsigned AM3Opc)
{
	return (AM3Opc >> 9);
}

//===--------------------------------------------------------------------===//
// Addressing Mode #4
//===--------------------------------------------------------------------===//
//
// This is used for load / store multiple instructions.
//
// addrmode4 := reg, <mode>
//
// The four modes are:
//    IA - Increment after
//    IB - Increment before
//    DA - Decrement after
//    DB - Decrement before
// For VFP instructions, only the IA and DB modes are valid.

static inline ARM_AM_AMSubMode getAM4SubMode(unsigned Mode)
{
	return (ARM_AM_AMSubMode)(Mode & 0x7);
}

static inline unsigned getAM4ModeImm(ARM_AM_AMSubMode SubMode)
{
	return (int)SubMode;
}

//===--------------------------------------------------------------------===//
// Addressing Mode #5
//===--------------------------------------------------------------------===//
//
// This is used for coprocessor instructions, such as FP load/stores.
//
// addrmode5 := reg +/- imm8*4
//
// The first operand is always a Reg.  The second operand encodes the
// operation in bit 8 and the immediate in bits 0-7.

/// getAM5Opc - This function encodes the addrmode5 opc field.
static inline unsigned ARM_AM_getAM5Opc(ARM_AM_AddrOpc Opc, unsigned char Offset)
{
	bool isSub = Opc == ARM_AM_sub;
	return ((int)isSub << 8) | Offset;
}
static inline unsigned char ARM_AM_getAM5Offset(unsigned AM5Opc)
{
	return AM5Opc & 0xFF;
}
static inline ARM_AM_AddrOpc ARM_AM_getAM5Op(unsigned AM5Opc)
{
	return ((AM5Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
}

//===--------------------------------------------------------------------===//
// Addressing Mode #6
//===--------------------------------------------------------------------===//
//
// This is used for NEON load / store instructions.
//
// addrmode6 := reg with optional alignment
//
// This is stored in two operands [regaddr, align].  The first is the
// address register.  The second operand is the value of the alignment
// specifier in bytes or zero if no explicit alignment.
// Valid alignments depend on the specific instruction.

//===--------------------------------------------------------------------===//
// NEON Modified Immediates
//===--------------------------------------------------------------------===//
//
// Several NEON instructions (e.g., VMOV) take a "modified immediate"
// vector operand, where a small immediate encoded in the instruction
// specifies a full NEON vector value.  These modified immediates are
// represented here as encoded integers.  The low 8 bits hold the immediate
// value; bit 12 holds the "Op" field of the instruction, and bits 11-8 hold
// the "Cmode" field of the instruction.  The interfaces below treat the
// Op and Cmode values as a single 5-bit value.

static inline unsigned createNEONModImm(unsigned OpCmode, unsigned Val)
{
	return (OpCmode << 8) | Val;
}
static inline unsigned getNEONModImmOpCmode(unsigned ModImm)
{
	return (ModImm >> 8) & 0x1f;
}
static inline unsigned getNEONModImmVal(unsigned ModImm)
{
	return ModImm & 0xff;
}

/// decodeNEONModImm - Decode a NEON modified immediate value into the
/// element value and the element size in bits.  (If the element size is
/// smaller than the vector, it is splatted into all the elements.)
static inline uint64_t ARM_AM_decodeNEONModImm(unsigned ModImm, unsigned *EltBits)
{
	unsigned OpCmode = getNEONModImmOpCmode(ModImm);
	unsigned Imm8 = getNEONModImmVal(ModImm);
	uint64_t Val = 0;
	unsigned ByteNum;

	if (OpCmode == 0xe) {
		// 8-bit vector elements
		Val = Imm8;
		*EltBits = 8;
	} else if ((OpCmode & 0xc) == 0x8) {
		// 16-bit vector elements
		ByteNum = (OpCmode & 0x6) >> 1;
		Val = (uint64_t)Imm8 << (8 * ByteNum);
		*EltBits = 16;
	} else if ((OpCmode & 0x8) == 0) {
		// 32-bit vector elements, zero with one byte set
		ByteNum = (OpCmode & 0x6) >> 1;
		Val = (uint64_t)Imm8 << (8 * ByteNum);
		*EltBits = 32;
	} else if ((OpCmode & 0xe) == 0xc) {
		// 32-bit vector elements, one byte with low bits set
		ByteNum = 1 + (OpCmode & 0x1);
		Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum)));
		*EltBits = 32;
	} else if (OpCmode == 0x1e) {
		// 64-bit vector elements
		for (ByteNum = 0; ByteNum < 8; ++ByteNum) {
			if ((ModImm >> ByteNum) & 1)
				Val |= (uint64_t)0xff << (8 * ByteNum);
		}
		*EltBits = 64;
	} else {
		//llvm_unreachable("Unsupported NEON immediate");
	}
	return Val;
}

ARM_AM_AMSubMode getLoadStoreMultipleSubMode(int Opcode);

//===--------------------------------------------------------------------===//
// Floating-point Immediates
//
static inline float getFPImmFloat(unsigned Imm)
{
	// We expect an 8-bit binary encoding of a floating-point number here.
	union {
		uint32_t I;
		float F;
	} FPUnion;

	uint8_t Sign = (Imm >> 7) & 0x1;
	uint8_t Exp = (Imm >> 4) & 0x7;
	uint8_t Mantissa = Imm & 0xf;

	//   8-bit FP    iEEEE Float Encoding
	//   abcd efgh   aBbbbbbc defgh000 00000000 00000000
	//
	// where B = NOT(b);

	FPUnion.I = 0;
	FPUnion.I |= Sign << 31;
	FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
	FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
	FPUnion.I |= (Exp & 0x3) << 23;
	FPUnion.I |= Mantissa << 19;
	return FPUnion.F;
}

#endif

