// Copyright 2014 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package armasm

import (
	"encoding/binary"
	"fmt"
)

// An instFormat describes the format of an instruction encoding.
// An instruction with 32-bit value x matches the format if x&mask == value
// and the condition matches.
// The condition matches if x>>28 == 0xF && value>>28==0xF
// or if x>>28 != 0xF and value>>28 == 0.
// If x matches the format, then the rest of the fields describe how to interpret x.
// The opBits describe bits that should be extracted from x and added to the opcode.
// For example opBits = 0x1234 means that the value
//
//	(2 bits at offset 1) followed by (4 bits at offset 3)
//
// should be added to op.
// Finally the args describe how to decode the instruction arguments.
// args is stored as a fixed-size array; if there are fewer than len(args) arguments,
// args[i] == 0 marks the end of the argument list.
type instFormat struct {
	mask     uint32
	value    uint32
	priority int8
	op       Op
	opBits   uint64
	args     instArgs
}

type instArgs [4]instArg

var (
	errMode    = fmt.Errorf("unsupported execution mode")
	errShort   = fmt.Errorf("truncated instruction")
	errUnknown = fmt.Errorf("unknown instruction")
)

var decoderCover []bool

// Decode decodes the leading bytes in src as a single instruction.
func Decode(src []byte, mode Mode) (inst Inst, err error) {
	if mode != ModeARM {
		return Inst{}, errMode
	}
	if len(src) < 4 {
		return Inst{}, errShort
	}

	if decoderCover == nil {
		decoderCover = make([]bool, len(instFormats))
	}

	x := binary.LittleEndian.Uint32(src)

	// The instFormat table contains both conditional and unconditional instructions.
	// Considering only the top 4 bits, the conditional instructions use mask=0, value=0,
	// while the unconditional instructions use mask=f, value=f.
	// Prepare a version of x with the condition cleared to 0 in conditional instructions
	// and then assume mask=f during matching.
	const condMask = 0xf0000000
	xNoCond := x
	if x&condMask != condMask {
		xNoCond &^= condMask
	}
	var priority int8
Search:
	for i := range instFormats {
		f := &instFormats[i]
		if xNoCond&(f.mask|condMask) != f.value || f.priority <= priority {
			continue
		}
		delta := uint32(0)
		deltaShift := uint(0)
		for opBits := f.opBits; opBits != 0; opBits >>= 16 {
			n := uint(opBits & 0xFF)
			off := uint((opBits >> 8) & 0xFF)
			delta |= (x >> off) & (1<<n - 1) << deltaShift
			deltaShift += n
		}
		op := f.op + Op(delta)

		// Special case: BKPT encodes with condition but cannot have one.
		if op&^15 == BKPT_EQ && op != BKPT {
			continue Search
		}

		var args Args
		for j, aop := range f.args {
			if aop == 0 {
				break
			}
			arg := decodeArg(aop, x)
			if arg == nil { // cannot decode argument
				continue Search
			}
			args[j] = arg
		}

		decoderCover[i] = true

		inst = Inst{
			Op:   op,
			Args: args,
			Enc:  x,
			Len:  4,
		}
		priority = f.priority
		continue Search
	}
	if inst.Op != 0 {
		return inst, nil
	}
	return Inst{}, errUnknown
}

// An instArg describes the encoding of a single argument.
// In the names used for arguments, _p_ means +, _m_ means -,
// _pm_ means ± (usually keyed by the U bit).
// The _W suffix indicates a general addressing mode based on the P and W bits.
// The _offset and _postindex suffixes force the given addressing mode.
// The rest should be somewhat self-explanatory, at least given
// the decodeArg function.
type instArg uint8

const (
	_ instArg = iota
	arg_APSR
	arg_FPSCR
	arg_Dn_half
	arg_R1_0
	arg_R1_12
	arg_R2_0
	arg_R2_12
	arg_R_0
	arg_R_12
	arg_R_12_nzcv
	arg_R_16
	arg_R_16_WB
	arg_R_8
	arg_R_rotate
	arg_R_shift_R
	arg_R_shift_imm
	arg_SP
	arg_Sd
	arg_Sd_Dd
	arg_Dd_Sd
	arg_Sm
	arg_Sm_Dm
	arg_Sn
	arg_Sn_Dn
	arg_const
	arg_endian
	arg_fbits
	arg_fp_0
	arg_imm24
	arg_imm5
	arg_imm5_32
	arg_imm5_nz
	arg_imm_12at8_4at0
	arg_imm_4at16_12at0
	arg_imm_vfp
	arg_label24
	arg_label24H
	arg_label_m_12
	arg_label_p_12
	arg_label_pm_12
	arg_label_pm_4_4
	arg_lsb_width
	arg_mem_R
	arg_mem_R_pm_R_W
	arg_mem_R_pm_R_postindex
	arg_mem_R_pm_R_shift_imm_W
	arg_mem_R_pm_R_shift_imm_offset
	arg_mem_R_pm_R_shift_imm_postindex
	arg_mem_R_pm_imm12_W
	arg_mem_R_pm_imm12_offset
	arg_mem_R_pm_imm12_postindex
	arg_mem_R_pm_imm8_W
	arg_mem_R_pm_imm8_postindex
	arg_mem_R_pm_imm8at0_offset
	arg_option
	arg_registers
	arg_registers1
	arg_registers2
	arg_satimm4
	arg_satimm5
	arg_satimm4m1
	arg_satimm5m1
	arg_widthm1
)

// decodeArg decodes the arg described by aop from the instruction bits x.
// It returns nil if x cannot be decoded according to aop.
func decodeArg(aop instArg, x uint32) Arg {
	switch aop {
	default:
		return nil

	case arg_APSR:
		return APSR
	case arg_FPSCR:
		return FPSCR

	case arg_R_0:
		return Reg(x & (1<<4 - 1))
	case arg_R_8:
		return Reg((x >> 8) & (1<<4 - 1))
	case arg_R_12:
		return Reg((x >> 12) & (1<<4 - 1))
	case arg_R_16:
		return Reg((x >> 16) & (1<<4 - 1))

	case arg_R_12_nzcv:
		r := Reg((x >> 12) & (1<<4 - 1))
		if r == R15 {
			return APSR_nzcv
		}
		return r

	case arg_R_16_WB:
		mode := AddrLDM
		if (x>>21)&1 != 0 {
			mode = AddrLDM_WB
		}
		return Mem{Base: Reg((x >> 16) & (1<<4 - 1)), Mode: mode}

	case arg_R_rotate:
		Rm := Reg(x & (1<<4 - 1))
		typ, count := decodeShift(x)
		// ROR #0 here means ROR #0, but decodeShift rewrites to RRX #1.
		if typ == RotateRightExt {
			return Rm
		}
		return RegShift{Rm, typ, count}

	case arg_R_shift_R:
		Rm := Reg(x & (1<<4 - 1))
		Rs := Reg((x >> 8) & (1<<4 - 1))
		typ := Shift((x >> 5) & (1<<2 - 1))
		return RegShiftReg{Rm, typ, Rs}

	case arg_R_shift_imm:
		Rm := Reg(x & (1<<4 - 1))
		typ, count := decodeShift(x)
		if typ == ShiftLeft && count == 0 {
			return Reg(Rm)
		}
		return RegShift{Rm, typ, count}

	case arg_R1_0:
		return Reg((x & (1<<4 - 1)))
	case arg_R1_12:
		return Reg(((x >> 12) & (1<<4 - 1)))
	case arg_R2_0:
		return Reg((x & (1<<4 - 1)) | 1)
	case arg_R2_12:
		return Reg(((x >> 12) & (1<<4 - 1)) | 1)

	case arg_SP:
		return SP

	case arg_Sd_Dd:
		v := (x >> 12) & (1<<4 - 1)
		vx := (x >> 22) & 1
		sz := (x >> 8) & 1
		if sz != 0 {
			return D0 + Reg(vx<<4+v)
		} else {
			return S0 + Reg(v<<1+vx)
		}

	case arg_Dd_Sd:
		return decodeArg(arg_Sd_Dd, x^(1<<8))

	case arg_Sd:
		v := (x >> 12) & (1<<4 - 1)
		vx := (x >> 22) & 1
		return S0 + Reg(v<<1+vx)

	case arg_Sm_Dm:
		v := (x >> 0) & (1<<4 - 1)
		vx := (x >> 5) & 1
		sz := (x >> 8) & 1
		if sz != 0 {
			return D0 + Reg(vx<<4+v)
		} else {
			return S0 + Reg(v<<1+vx)
		}

	case arg_Sm:
		v := (x >> 0) & (1<<4 - 1)
		vx := (x >> 5) & 1
		return S0 + Reg(v<<1+vx)

	case arg_Dn_half:
		v := (x >> 16) & (1<<4 - 1)
		vx := (x >> 7) & 1
		return RegX{D0 + Reg(vx<<4+v), int((x >> 21) & 1)}

	case arg_Sn_Dn:
		v := (x >> 16) & (1<<4 - 1)
		vx := (x >> 7) & 1
		sz := (x >> 8) & 1
		if sz != 0 {
			return D0 + Reg(vx<<4+v)
		} else {
			return S0 + Reg(v<<1+vx)
		}

	case arg_Sn:
		v := (x >> 16) & (1<<4 - 1)
		vx := (x >> 7) & 1
		return S0 + Reg(v<<1+vx)

	case arg_const:
		v := x & (1<<8 - 1)
		rot := (x >> 8) & (1<<4 - 1) * 2
		if rot > 0 && v&3 == 0 {
			// could rotate less
			return ImmAlt{uint8(v), uint8(rot)}
		}
		if rot >= 24 && ((v<<(32-rot))&0xFF)>>(32-rot) == v {
			// could wrap around to rot==0.
			return ImmAlt{uint8(v), uint8(rot)}
		}
		return Imm(v>>rot | v<<(32-rot))

	case arg_endian:
		return Endian((x >> 9) & 1)

	case arg_fbits:
		return Imm((16 << ((x >> 7) & 1)) - ((x&(1<<4-1))<<1 | (x>>5)&1))

	case arg_fp_0:
		return Imm(0)

	case arg_imm24:
		return Imm(x & (1<<24 - 1))

	case arg_imm5:
		return Imm((x >> 7) & (1<<5 - 1))

	case arg_imm5_32:
		x = (x >> 7) & (1<<5 - 1)
		if x == 0 {
			x = 32
		}
		return Imm(x)

	case arg_imm5_nz:
		x = (x >> 7) & (1<<5 - 1)
		if x == 0 {
			return nil
		}
		return Imm(x)

	case arg_imm_4at16_12at0:
		return Imm((x>>16)&(1<<4-1)<<12 | x&(1<<12-1))

	case arg_imm_12at8_4at0:
		return Imm((x>>8)&(1<<12-1)<<4 | x&(1<<4-1))

	case arg_imm_vfp:
		x = (x>>16)&(1<<4-1)<<4 | x&(1<<4-1)
		return Imm(x)

	case arg_label24:
		imm := (x & (1<<24 - 1)) << 2
		return PCRel(int32(imm<<6) >> 6)

	case arg_label24H:
		h := (x >> 24) & 1
		imm := (x&(1<<24-1))<<2 | h<<1
		return PCRel(int32(imm<<6) >> 6)

	case arg_label_m_12:
		d := int32(x & (1<<12 - 1))
		return Mem{Base: PC, Mode: AddrOffset, Offset: int16(-d)}

	case arg_label_p_12:
		d := int32(x & (1<<12 - 1))
		return Mem{Base: PC, Mode: AddrOffset, Offset: int16(d)}

	case arg_label_pm_12:
		d := int32(x & (1<<12 - 1))
		u := (x >> 23) & 1
		if u == 0 {
			d = -d
		}
		return Mem{Base: PC, Mode: AddrOffset, Offset: int16(d)}

	case arg_label_pm_4_4:
		d := int32((x>>8)&(1<<4-1)<<4 | x&(1<<4-1))
		u := (x >> 23) & 1
		if u == 0 {
			d = -d
		}
		return PCRel(d)

	case arg_lsb_width:
		lsb := (x >> 7) & (1<<5 - 1)
		msb := (x >> 16) & (1<<5 - 1)
		if msb < lsb || msb >= 32 {
			return nil
		}
		return Imm(msb + 1 - lsb)

	case arg_mem_R:
		Rn := Reg((x >> 16) & (1<<4 - 1))
		return Mem{Base: Rn, Mode: AddrOffset}

	case arg_mem_R_pm_R_postindex:
		// Treat [<Rn>],+/-<Rm> like [<Rn>,+/-<Rm>{,<shift>}]{!}
		// by forcing shift bits to <<0 and P=0, W=0 (postindex=true).
		return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5|1<<24|1<<21))

	case arg_mem_R_pm_R_W:
		// Treat [<Rn>,+/-<Rm>]{!} like [<Rn>,+/-<Rm>{,<shift>}]{!}
		// by forcing shift bits to <<0.
		return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5))

	case arg_mem_R_pm_R_shift_imm_offset:
		// Treat [<Rn>],+/-<Rm>{,<shift>} like [<Rn>,+/-<Rm>{,<shift>}]{!}
		// by forcing P=1, W=0 (index=false, wback=false).
		return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^(1<<21)|1<<24)

	case arg_mem_R_pm_R_shift_imm_postindex:
		// Treat [<Rn>],+/-<Rm>{,<shift>} like [<Rn>,+/-<Rm>{,<shift>}]{!}
		// by forcing P=0, W=0 (postindex=true).
		return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^(1<<24|1<<21))

	case arg_mem_R_pm_R_shift_imm_W:
		Rn := Reg((x >> 16) & (1<<4 - 1))
		Rm := Reg(x & (1<<4 - 1))
		typ, count := decodeShift(x)
		u := (x >> 23) & 1
		w := (x >> 21) & 1
		p := (x >> 24) & 1
		if p == 0 && w == 1 {
			return nil
		}
		sign := int8(+1)
		if u == 0 {
			sign = -1
		}
		mode := AddrMode(uint8(p<<1) | uint8(w^1))
		return Mem{Base: Rn, Mode: mode, Sign: sign, Index: Rm, Shift: typ, Count: count}

	case arg_mem_R_pm_imm12_offset:
		// Treat [<Rn>,#+/-<imm12>] like [<Rn>{,#+/-<imm12>}]{!}
		// by forcing P=1, W=0 (index=false, wback=false).
		return decodeArg(arg_mem_R_pm_imm12_W, x&^(1<<21)|1<<24)

	case arg_mem_R_pm_imm12_postindex:
		// Treat [<Rn>],#+/-<imm12> like [<Rn>{,#+/-<imm12>}]{!}
		// by forcing P=0, W=0 (postindex=true).
		return decodeArg(arg_mem_R_pm_imm12_W, x&^(1<<24|1<<21))

	case arg_mem_R_pm_imm12_W:
		Rn := Reg((x >> 16) & (1<<4 - 1))
		u := (x >> 23) & 1
		w := (x >> 21) & 1
		p := (x >> 24) & 1
		if p == 0 && w == 1 {
			return nil
		}
		sign := int8(+1)
		if u == 0 {
			sign = -1
		}
		imm := int16(x & (1<<12 - 1))
		mode := AddrMode(uint8(p<<1) | uint8(w^1))
		return Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm}

	case arg_mem_R_pm_imm8_postindex:
		// Treat [<Rn>],#+/-<imm8> like [<Rn>{,#+/-<imm8>}]{!}
		// by forcing P=0, W=0 (postindex=true).
		return decodeArg(arg_mem_R_pm_imm8_W, x&^(1<<24|1<<21))

	case arg_mem_R_pm_imm8_W:
		Rn := Reg((x >> 16) & (1<<4 - 1))
		u := (x >> 23) & 1
		w := (x >> 21) & 1
		p := (x >> 24) & 1
		if p == 0 && w == 1 {
			return nil
		}
		sign := int8(+1)
		if u == 0 {
			sign = -1
		}
		imm := int16((x>>8)&(1<<4-1)<<4 | x&(1<<4-1))
		mode := AddrMode(uint8(p<<1) | uint8(w^1))
		return Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm}

	case arg_mem_R_pm_imm8at0_offset:
		Rn := Reg((x >> 16) & (1<<4 - 1))
		u := (x >> 23) & 1
		sign := int8(+1)
		if u == 0 {
			sign = -1
		}
		imm := int16(x&(1<<8-1)) << 2
		return Mem{Base: Rn, Mode: AddrOffset, Offset: int16(sign) * imm}

	case arg_option:
		return Imm(x & (1<<4 - 1))

	case arg_registers:
		return RegList(x & (1<<16 - 1))

	case arg_registers2:
		x &= 1<<16 - 1
		n := 0
		for i := 0; i < 16; i++ {
			if x>>uint(i)&1 != 0 {
				n++
			}
		}
		if n < 2 {
			return nil
		}
		return RegList(x)

	case arg_registers1:
		Rt := (x >> 12) & (1<<4 - 1)
		return RegList(1 << Rt)

	case arg_satimm4:
		return Imm((x >> 16) & (1<<4 - 1))

	case arg_satimm5:
		return Imm((x >> 16) & (1<<5 - 1))

	case arg_satimm4m1:
		return Imm((x>>16)&(1<<4-1) + 1)

	case arg_satimm5m1:
		return Imm((x>>16)&(1<<5-1) + 1)

	case arg_widthm1:
		return Imm((x>>16)&(1<<5-1) + 1)

	}
}

// decodeShift decodes the shift-by-immediate encoded in x.
func decodeShift(x uint32) (Shift, uint8) {
	count := (x >> 7) & (1<<5 - 1)
	typ := Shift((x >> 5) & (1<<2 - 1))
	switch typ {
	case ShiftRight, ShiftRightSigned:
		if count == 0 {
			count = 32
		}
	case RotateRight:
		if count == 0 {
			typ = RotateRightExt
			count = 1
		}
	}
	return typ, uint8(count)
}
