// 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 x86asm

import (
	"fmt"
	"strings"
)

// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils.
// This general form is often called ``AT&T syntax'' as a reference to AT&T System V Unix.
func GNUSyntax(inst Inst, pc uint64, symname SymLookup) string {
	// Rewrite instruction to mimic GNU peculiarities.
	// Note that inst has been passed by value and contains
	// no pointers, so any changes we make here are local
	// and will not propagate back out to the caller.

	if symname == nil {
		symname = func(uint64) (string, uint64) { return "", 0 }
	}

	// Adjust opcode [sic].
	switch inst.Op {
	case FDIV, FDIVR, FSUB, FSUBR, FDIVP, FDIVRP, FSUBP, FSUBRP:
		// DC E0, DC F0: libopcodes swaps FSUBR/FSUB and FDIVR/FDIV, at least
		// if you believe the Intel manual is correct (the encoding is irregular as given;
		// libopcodes uses the more regular expected encoding).
		// TODO(rsc): Test to ensure Intel manuals are correct and report to libopcodes maintainers?
		// NOTE: iant thinks this is deliberate, but we can't find the history.
		_, reg1 := inst.Args[0].(Reg)
		_, reg2 := inst.Args[1].(Reg)
		if reg1 && reg2 && (inst.Opcode>>24 == 0xDC || inst.Opcode>>24 == 0xDE) {
			switch inst.Op {
			case FDIV:
				inst.Op = FDIVR
			case FDIVR:
				inst.Op = FDIV
			case FSUB:
				inst.Op = FSUBR
			case FSUBR:
				inst.Op = FSUB
			case FDIVP:
				inst.Op = FDIVRP
			case FDIVRP:
				inst.Op = FDIVP
			case FSUBP:
				inst.Op = FSUBRP
			case FSUBRP:
				inst.Op = FSUBP
			}
		}

	case MOVNTSD:
		// MOVNTSD is F2 0F 2B /r.
		// MOVNTSS is F3 0F 2B /r (supposedly; not in manuals).
		// Usually inner prefixes win for display,
		// so that F3 F2 0F 2B 11 is REP MOVNTSD
		// and F2 F3 0F 2B 11 is REPN MOVNTSS.
		// Libopcodes always prefers MOVNTSS regardless of prefix order.
		if countPrefix(&inst, 0xF3) > 0 {
			found := false
			for i := len(inst.Prefix) - 1; i >= 0; i-- {
				switch inst.Prefix[i] & 0xFF {
				case 0xF3:
					if !found {
						found = true
						inst.Prefix[i] |= PrefixImplicit
					}
				case 0xF2:
					inst.Prefix[i] &^= PrefixImplicit
				}
			}
			inst.Op = MOVNTSS
		}
	}

	// Add implicit arguments.
	switch inst.Op {
	case MONITOR:
		inst.Args[0] = EDX
		inst.Args[1] = ECX
		inst.Args[2] = EAX
		if inst.AddrSize == 16 {
			inst.Args[2] = AX
		}

	case MWAIT:
		if inst.Mode == 64 {
			inst.Args[0] = RCX
			inst.Args[1] = RAX
		} else {
			inst.Args[0] = ECX
			inst.Args[1] = EAX
		}
	}

	// Adjust which prefixes will be displayed.
	// The rule is to display all the prefixes not implied by
	// the usual instruction display, that is, all the prefixes
	// except the ones with PrefixImplicit set.
	// However, of course, there are exceptions to the rule.
	switch inst.Op {
	case CRC32:
		// CRC32 has a mandatory F2 prefix.
		// If there are multiple F2s and no F3s, the extra F2s do not print.
		// (And Decode has already marked them implicit.)
		// However, if there is an F3 anywhere, then the extra F2s do print.
		// If there are multiple F2 prefixes *and* an (ignored) F3,
		// then libopcodes prints the extra F2s as REPNs.
		if countPrefix(&inst, 0xF2) > 1 {
			unmarkImplicit(&inst, 0xF2)
			markLastImplicit(&inst, 0xF2)
		}

		// An unused data size override should probably be shown,
		// to distinguish DATA16 CRC32B from plain CRC32B,
		// but libopcodes always treats the final override as implicit
		// and the others as explicit.
		unmarkImplicit(&inst, PrefixDataSize)
		markLastImplicit(&inst, PrefixDataSize)

	case CVTSI2SD, CVTSI2SS:
		if !isMem(inst.Args[1]) {
			markLastImplicit(&inst, PrefixDataSize)
		}

	case CVTSD2SI, CVTSS2SI, CVTTSD2SI, CVTTSS2SI,
		ENTER, FLDENV, FNSAVE, FNSTENV, FRSTOR, LGDT, LIDT, LRET,
		POP, PUSH, RET, SGDT, SIDT, SYSRET, XBEGIN:
		markLastImplicit(&inst, PrefixDataSize)

	case LOOP, LOOPE, LOOPNE, MONITOR:
		markLastImplicit(&inst, PrefixAddrSize)

	case MOV:
		// The 16-bit and 32-bit forms of MOV Sreg, dst and MOV src, Sreg
		// cannot be distinguished when src or dst refers to memory, because
		// Sreg is always a 16-bit value, even when we're doing a 32-bit
		// instruction. Because the instruction tables distinguished these two,
		// any operand size prefix has been marked as used (to decide which
		// branch to take). Unmark it, so that it will show up in disassembly,
		// so that the reader can tell the size of memory operand.
		// up with the same arguments
		dst, _ := inst.Args[0].(Reg)
		src, _ := inst.Args[1].(Reg)
		if ES <= src && src <= GS && isMem(inst.Args[0]) || ES <= dst && dst <= GS && isMem(inst.Args[1]) {
			unmarkImplicit(&inst, PrefixDataSize)
		}

	case MOVDQU:
		if countPrefix(&inst, 0xF3) > 1 {
			unmarkImplicit(&inst, 0xF3)
			markLastImplicit(&inst, 0xF3)
		}

	case MOVQ2DQ:
		markLastImplicit(&inst, PrefixDataSize)

	case SLDT, SMSW, STR, FXRSTOR, XRSTOR, XSAVE, XSAVEOPT, CMPXCHG8B:
		if isMem(inst.Args[0]) {
			unmarkImplicit(&inst, PrefixDataSize)
		}

	case SYSEXIT:
		unmarkImplicit(&inst, PrefixDataSize)
	}

	if isCondJmp[inst.Op] || isLoop[inst.Op] || inst.Op == JCXZ || inst.Op == JECXZ || inst.Op == JRCXZ {
		if countPrefix(&inst, PrefixCS) > 0 && countPrefix(&inst, PrefixDS) > 0 {
			for i, p := range inst.Prefix {
				switch p & 0xFFF {
				case PrefixPN, PrefixPT:
					inst.Prefix[i] &= 0xF0FF // cut interpretation bits, producing original segment prefix
				}
			}
		}
	}

	// XACQUIRE/XRELEASE adjustment.
	if inst.Op == MOV {
		// MOV into memory is a candidate for turning REP into XRELEASE.
		// However, if the REP is followed by a REPN, that REPN blocks the
		// conversion.
		haveREPN := false
		for i := len(inst.Prefix) - 1; i >= 0; i-- {
			switch inst.Prefix[i] &^ PrefixIgnored {
			case PrefixREPN:
				haveREPN = true
			case PrefixXRELEASE:
				if haveREPN {
					inst.Prefix[i] = PrefixREP
				}
			}
		}
	}

	// We only format the final F2/F3 as XRELEASE/XACQUIRE.
	haveXA := false
	haveXR := false
	for i := len(inst.Prefix) - 1; i >= 0; i-- {
		switch inst.Prefix[i] &^ PrefixIgnored {
		case PrefixXRELEASE:
			if !haveXR {
				haveXR = true
			} else {
				inst.Prefix[i] = PrefixREP
			}

		case PrefixXACQUIRE:
			if !haveXA {
				haveXA = true
			} else {
				inst.Prefix[i] = PrefixREPN
			}
		}
	}

	// Determine opcode.
	op := strings.ToLower(inst.Op.String())
	if alt := gnuOp[inst.Op]; alt != "" {
		op = alt
	}

	// Determine opcode suffix.
	// Libopcodes omits the suffix if the width of the operation
	// can be inferred from a register arguments. For example,
	// add $1, %ebx has no suffix because you can tell from the
	// 32-bit register destination that it is a 32-bit add,
	// but in addl $1, (%ebx), the destination is memory, so the
	// size is not evident without the l suffix.
	needSuffix := true
SuffixLoop:
	for i, a := range inst.Args {
		if a == nil {
			break
		}
		switch a := a.(type) {
		case Reg:
			switch inst.Op {
			case MOVSX, MOVZX:
				continue

			case SHL, SHR, RCL, RCR, ROL, ROR, SAR:
				if i == 1 {
					// shift count does not tell us operand size
					continue
				}

			case CRC32:
				// The source argument does tell us operand size,
				// but libopcodes still always puts a suffix on crc32.
				continue

			case PUSH, POP:
				// Even though segment registers are 16-bit, push and pop
				// can save/restore them from 32-bit slots, so they
				// do not imply operand size.
				if ES <= a && a <= GS {
					continue
				}

			case CVTSI2SD, CVTSI2SS:
				// The integer register argument takes priority.
				if X0 <= a && a <= X15 {
					continue
				}
			}

			if AL <= a && a <= R15 || ES <= a && a <= GS || X0 <= a && a <= X15 || M0 <= a && a <= M7 {
				needSuffix = false
				break SuffixLoop
			}
		}
	}

	if needSuffix {
		switch inst.Op {
		case CMPXCHG8B, FLDCW, FNSTCW, FNSTSW, LDMXCSR, LLDT, LMSW, LTR, PCLMULQDQ,
			SETA, SETAE, SETB, SETBE, SETE, SETG, SETGE, SETL, SETLE, SETNE, SETNO, SETNP, SETNS, SETO, SETP, SETS,
			SLDT, SMSW, STMXCSR, STR, VERR, VERW:
			// For various reasons, libopcodes emits no suffix for these instructions.

		case CRC32:
			op += byteSizeSuffix(argBytes(&inst, inst.Args[1]))

		case LGDT, LIDT, SGDT, SIDT:
			op += byteSizeSuffix(inst.DataSize / 8)

		case MOVZX, MOVSX:
			// Integer size conversions get two suffixes.
			op = op[:4] + byteSizeSuffix(argBytes(&inst, inst.Args[1])) + byteSizeSuffix(argBytes(&inst, inst.Args[0]))

		case LOOP, LOOPE, LOOPNE:
			// Add w suffix to indicate use of CX register instead of ECX.
			if inst.AddrSize == 16 {
				op += "w"
			}

		case CALL, ENTER, JMP, LCALL, LEAVE, LJMP, LRET, RET, SYSRET, XBEGIN:
			// Add w suffix to indicate use of 16-bit target.
			// Exclude JMP rel8.
			if inst.Opcode>>24 == 0xEB {
				break
			}
			if inst.DataSize == 16 && inst.Mode != 16 {
				markLastImplicit(&inst, PrefixDataSize)
				op += "w"
			} else if inst.Mode == 64 {
				op += "q"
			}

		case FRSTOR, FNSAVE, FNSTENV, FLDENV:
			// Add s suffix to indicate shortened FPU state (I guess).
			if inst.DataSize == 16 {
				op += "s"
			}

		case PUSH, POP:
			if markLastImplicit(&inst, PrefixDataSize) {
				op += byteSizeSuffix(inst.DataSize / 8)
			} else if inst.Mode == 64 {
				op += "q"
			} else {
				op += byteSizeSuffix(inst.MemBytes)
			}

		default:
			if isFloat(inst.Op) {
				// I can't explain any of this, but it's what libopcodes does.
				switch inst.MemBytes {
				default:
					if (inst.Op == FLD || inst.Op == FSTP) && isMem(inst.Args[0]) {
						op += "t"
					}
				case 4:
					if isFloatInt(inst.Op) {
						op += "l"
					} else {
						op += "s"
					}
				case 8:
					if isFloatInt(inst.Op) {
						op += "ll"
					} else {
						op += "l"
					}
				}
				break
			}

			op += byteSizeSuffix(inst.MemBytes)
		}
	}

	// Adjust special case opcodes.
	switch inst.Op {
	case 0:
		if inst.Prefix[0] != 0 {
			return strings.ToLower(inst.Prefix[0].String())
		}

	case INT:
		if inst.Opcode>>24 == 0xCC {
			inst.Args[0] = nil
			op = "int3"
		}

	case CMPPS, CMPPD, CMPSD_XMM, CMPSS:
		imm, ok := inst.Args[2].(Imm)
		if ok && 0 <= imm && imm < 8 {
			inst.Args[2] = nil
			op = cmppsOps[imm] + op[3:]
		}

	case PCLMULQDQ:
		imm, ok := inst.Args[2].(Imm)
		if ok && imm&^0x11 == 0 {
			inst.Args[2] = nil
			op = pclmulqOps[(imm&0x10)>>3|(imm&1)]
		}

	case XLATB:
		if markLastImplicit(&inst, PrefixAddrSize) {
			op = "xlat" // not xlatb
		}
	}

	// Build list of argument strings.
	var (
		usedPrefixes bool     // segment prefixes consumed by Mem formatting
		args         []string // formatted arguments
	)
	for i, a := range inst.Args {
		if a == nil {
			break
		}
		switch inst.Op {
		case MOVSB, MOVSW, MOVSD, MOVSQ, OUTSB, OUTSW, OUTSD:
			if i == 0 {
				usedPrefixes = true // disable use of prefixes for first argument
			} else {
				usedPrefixes = false
			}
		}
		if a == Imm(1) && (inst.Opcode>>24)&^1 == 0xD0 {
			continue
		}
		args = append(args, gnuArg(&inst, pc, symname, a, &usedPrefixes))
	}

	// The default is to print the arguments in reverse Intel order.
	// A few instructions inhibit this behavior.
	switch inst.Op {
	case BOUND, LCALL, ENTER, LJMP:
		// no reverse
	default:
		// reverse args
		for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
			args[i], args[j] = args[j], args[i]
		}
	}

	// Build prefix string.
	// Must be after argument formatting, which can turn off segment prefixes.
	var (
		prefix       = "" // output string
		numAddr      = 0
		numData      = 0
		implicitData = false
	)
	for _, p := range inst.Prefix {
		if p&0xFF == PrefixDataSize && p&PrefixImplicit != 0 {
			implicitData = true
		}
	}
	for _, p := range inst.Prefix {
		if p == 0 || p.IsVEX() {
			break
		}
		if p&PrefixImplicit != 0 {
			continue
		}
		switch p &^ (PrefixIgnored | PrefixInvalid) {
		default:
			if p.IsREX() {
				if p&0xFF == PrefixREX {
					prefix += "rex "
				} else {
					prefix += "rex." + p.String()[4:] + " "
				}
				break
			}
			prefix += strings.ToLower(p.String()) + " "

		case PrefixPN:
			op += ",pn"
			continue

		case PrefixPT:
			op += ",pt"
			continue

		case PrefixAddrSize, PrefixAddr16, PrefixAddr32:
			// For unknown reasons, if the addr16 prefix is repeated,
			// libopcodes displays all but the last as addr32, even though
			// the addressing form used in a memory reference is clearly
			// still 16-bit.
			n := 32
			if inst.Mode == 32 {
				n = 16
			}
			numAddr++
			if countPrefix(&inst, PrefixAddrSize) > numAddr {
				n = inst.Mode
			}
			prefix += fmt.Sprintf("addr%d ", n)
			continue

		case PrefixData16, PrefixData32:
			if implicitData && countPrefix(&inst, PrefixDataSize) > 1 {
				// Similar to the addr32 logic above, but it only kicks in
				// when something used the data size prefix (one is implicit).
				n := 16
				if inst.Mode == 16 {
					n = 32
				}
				numData++
				if countPrefix(&inst, PrefixDataSize) > numData {
					if inst.Mode == 16 {
						n = 16
					} else {
						n = 32
					}
				}
				prefix += fmt.Sprintf("data%d ", n)
				continue
			}
			prefix += strings.ToLower(p.String()) + " "
		}
	}

	// Finally! Put it all together.
	text := prefix + op
	if args != nil {
		text += " "
		// Indirect call/jmp gets a star to distinguish from direct jump address.
		if (inst.Op == CALL || inst.Op == JMP || inst.Op == LJMP || inst.Op == LCALL) && (isMem(inst.Args[0]) || isReg(inst.Args[0])) {
			text += "*"
		}
		text += strings.Join(args, ",")
	}
	return text
}

// gnuArg returns the GNU syntax for the argument x from the instruction inst.
// If *usedPrefixes is false and x is a Mem, then the formatting
// includes any segment prefixes and sets *usedPrefixes to true.
func gnuArg(inst *Inst, pc uint64, symname SymLookup, x Arg, usedPrefixes *bool) string {
	if x == nil {
		return "<nil>"
	}
	switch x := x.(type) {
	case Reg:
		switch inst.Op {
		case CVTSI2SS, CVTSI2SD, CVTSS2SI, CVTSD2SI, CVTTSD2SI, CVTTSS2SI:
			if inst.DataSize == 16 && EAX <= x && x <= R15L {
				x -= EAX - AX
			}

		case IN, INSB, INSW, INSD, OUT, OUTSB, OUTSW, OUTSD:
			// DX is the port, but libopcodes prints it as if it were a memory reference.
			if x == DX {
				return "(%dx)"
			}
		case VMOVDQA, VMOVDQU, VMOVNTDQA, VMOVNTDQ:
			return strings.Replace(gccRegName[x], "xmm", "ymm", -1)
		}
		return gccRegName[x]
	case Mem:
		seg := ""
		var haveCS, haveDS, haveES, haveFS, haveGS, haveSS bool
		switch x.Segment {
		case CS:
			haveCS = true
		case DS:
			haveDS = true
		case ES:
			haveES = true
		case FS:
			haveFS = true
		case GS:
			haveGS = true
		case SS:
			haveSS = true
		}
		switch inst.Op {
		case INSB, INSW, INSD, STOSB, STOSW, STOSD, STOSQ, SCASB, SCASW, SCASD, SCASQ:
			// These do not accept segment prefixes, at least in the GNU rendering.
		default:
			if *usedPrefixes {
				break
			}
			for i := len(inst.Prefix) - 1; i >= 0; i-- {
				p := inst.Prefix[i] &^ PrefixIgnored
				if p == 0 {
					continue
				}
				switch p {
				case PrefixCS:
					if !haveCS {
						haveCS = true
						inst.Prefix[i] |= PrefixImplicit
					}
				case PrefixDS:
					if !haveDS {
						haveDS = true
						inst.Prefix[i] |= PrefixImplicit
					}
				case PrefixES:
					if !haveES {
						haveES = true
						inst.Prefix[i] |= PrefixImplicit
					}
				case PrefixFS:
					if !haveFS {
						haveFS = true
						inst.Prefix[i] |= PrefixImplicit
					}
				case PrefixGS:
					if !haveGS {
						haveGS = true
						inst.Prefix[i] |= PrefixImplicit
					}
				case PrefixSS:
					if !haveSS {
						haveSS = true
						inst.Prefix[i] |= PrefixImplicit
					}
				}
			}
			*usedPrefixes = true
		}
		if haveCS {
			seg += "%cs:"
		}
		if haveDS {
			seg += "%ds:"
		}
		if haveSS {
			seg += "%ss:"
		}
		if haveES {
			seg += "%es:"
		}
		if haveFS {
			seg += "%fs:"
		}
		if haveGS {
			seg += "%gs:"
		}
		disp := ""
		if x.Disp != 0 {
			disp = fmt.Sprintf("%#x", x.Disp)
		}
		if x.Scale == 0 || x.Index == 0 && x.Scale == 1 && (x.Base == ESP || x.Base == RSP || x.Base == 0 && inst.Mode == 64) {
			if x.Base == 0 {
				return seg + disp
			}
			return fmt.Sprintf("%s%s(%s)", seg, disp, gccRegName[x.Base])
		}
		base := gccRegName[x.Base]
		if x.Base == 0 {
			base = ""
		}
		index := gccRegName[x.Index]
		if x.Index == 0 {
			if inst.AddrSize == 64 {
				index = "%riz"
			} else {
				index = "%eiz"
			}
		}
		if AX <= x.Base && x.Base <= DI {
			// 16-bit addressing - no scale
			return fmt.Sprintf("%s%s(%s,%s)", seg, disp, base, index)
		}
		return fmt.Sprintf("%s%s(%s,%s,%d)", seg, disp, base, index, x.Scale)
	case Rel:
		if pc == 0 {
			return fmt.Sprintf(".%+#x", int64(x))
		} else {
			addr := pc + uint64(inst.Len) + uint64(x)
			if s, base := symname(addr); s != "" && addr == base {
				return fmt.Sprintf("%s", s)
			} else {
				addr := pc + uint64(inst.Len) + uint64(x)
				return fmt.Sprintf("%#x", addr)
			}
		}
	case Imm:
		if s, base := symname(uint64(x)); s != "" {
			suffix := ""
			if uint64(x) != base {
				suffix = fmt.Sprintf("%+d", uint64(x)-base)
			}
			return fmt.Sprintf("$%s%s", s, suffix)
		}
		if inst.Mode == 32 {
			return fmt.Sprintf("$%#x", uint32(x))
		}
		return fmt.Sprintf("$%#x", int64(x))
	}
	return x.String()
}

var gccRegName = [...]string{
	0:    "REG0",
	AL:   "%al",
	CL:   "%cl",
	BL:   "%bl",
	DL:   "%dl",
	AH:   "%ah",
	CH:   "%ch",
	BH:   "%bh",
	DH:   "%dh",
	SPB:  "%spl",
	BPB:  "%bpl",
	SIB:  "%sil",
	DIB:  "%dil",
	R8B:  "%r8b",
	R9B:  "%r9b",
	R10B: "%r10b",
	R11B: "%r11b",
	R12B: "%r12b",
	R13B: "%r13b",
	R14B: "%r14b",
	R15B: "%r15b",
	AX:   "%ax",
	CX:   "%cx",
	BX:   "%bx",
	DX:   "%dx",
	SP:   "%sp",
	BP:   "%bp",
	SI:   "%si",
	DI:   "%di",
	R8W:  "%r8w",
	R9W:  "%r9w",
	R10W: "%r10w",
	R11W: "%r11w",
	R12W: "%r12w",
	R13W: "%r13w",
	R14W: "%r14w",
	R15W: "%r15w",
	EAX:  "%eax",
	ECX:  "%ecx",
	EDX:  "%edx",
	EBX:  "%ebx",
	ESP:  "%esp",
	EBP:  "%ebp",
	ESI:  "%esi",
	EDI:  "%edi",
	R8L:  "%r8d",
	R9L:  "%r9d",
	R10L: "%r10d",
	R11L: "%r11d",
	R12L: "%r12d",
	R13L: "%r13d",
	R14L: "%r14d",
	R15L: "%r15d",
	RAX:  "%rax",
	RCX:  "%rcx",
	RDX:  "%rdx",
	RBX:  "%rbx",
	RSP:  "%rsp",
	RBP:  "%rbp",
	RSI:  "%rsi",
	RDI:  "%rdi",
	R8:   "%r8",
	R9:   "%r9",
	R10:  "%r10",
	R11:  "%r11",
	R12:  "%r12",
	R13:  "%r13",
	R14:  "%r14",
	R15:  "%r15",
	IP:   "%ip",
	EIP:  "%eip",
	RIP:  "%rip",
	F0:   "%st",
	F1:   "%st(1)",
	F2:   "%st(2)",
	F3:   "%st(3)",
	F4:   "%st(4)",
	F5:   "%st(5)",
	F6:   "%st(6)",
	F7:   "%st(7)",
	M0:   "%mm0",
	M1:   "%mm1",
	M2:   "%mm2",
	M3:   "%mm3",
	M4:   "%mm4",
	M5:   "%mm5",
	M6:   "%mm6",
	M7:   "%mm7",
	X0:   "%xmm0",
	X1:   "%xmm1",
	X2:   "%xmm2",
	X3:   "%xmm3",
	X4:   "%xmm4",
	X5:   "%xmm5",
	X6:   "%xmm6",
	X7:   "%xmm7",
	X8:   "%xmm8",
	X9:   "%xmm9",
	X10:  "%xmm10",
	X11:  "%xmm11",
	X12:  "%xmm12",
	X13:  "%xmm13",
	X14:  "%xmm14",
	X15:  "%xmm15",
	CS:   "%cs",
	SS:   "%ss",
	DS:   "%ds",
	ES:   "%es",
	FS:   "%fs",
	GS:   "%gs",
	GDTR: "%gdtr",
	IDTR: "%idtr",
	LDTR: "%ldtr",
	MSW:  "%msw",
	TASK: "%task",
	CR0:  "%cr0",
	CR1:  "%cr1",
	CR2:  "%cr2",
	CR3:  "%cr3",
	CR4:  "%cr4",
	CR5:  "%cr5",
	CR6:  "%cr6",
	CR7:  "%cr7",
	CR8:  "%cr8",
	CR9:  "%cr9",
	CR10: "%cr10",
	CR11: "%cr11",
	CR12: "%cr12",
	CR13: "%cr13",
	CR14: "%cr14",
	CR15: "%cr15",
	DR0:  "%db0",
	DR1:  "%db1",
	DR2:  "%db2",
	DR3:  "%db3",
	DR4:  "%db4",
	DR5:  "%db5",
	DR6:  "%db6",
	DR7:  "%db7",
	TR0:  "%tr0",
	TR1:  "%tr1",
	TR2:  "%tr2",
	TR3:  "%tr3",
	TR4:  "%tr4",
	TR5:  "%tr5",
	TR6:  "%tr6",
	TR7:  "%tr7",
}

var gnuOp = map[Op]string{
	CBW:       "cbtw",
	CDQ:       "cltd",
	CMPSD:     "cmpsl",
	CMPSD_XMM: "cmpsd",
	CWD:       "cwtd",
	CWDE:      "cwtl",
	CQO:       "cqto",
	INSD:      "insl",
	IRET:      "iretw",
	IRETD:     "iret",
	IRETQ:     "iretq",
	LODSB:     "lods",
	LODSD:     "lods",
	LODSQ:     "lods",
	LODSW:     "lods",
	MOVSD:     "movsl",
	MOVSD_XMM: "movsd",
	OUTSD:     "outsl",
	POPA:      "popaw",
	POPAD:     "popa",
	POPF:      "popfw",
	POPFD:     "popf",
	PUSHA:     "pushaw",
	PUSHAD:    "pusha",
	PUSHF:     "pushfw",
	PUSHFD:    "pushf",
	SCASB:     "scas",
	SCASD:     "scas",
	SCASQ:     "scas",
	SCASW:     "scas",
	STOSB:     "stos",
	STOSD:     "stos",
	STOSQ:     "stos",
	STOSW:     "stos",
	XLATB:     "xlat",
}

var cmppsOps = []string{
	"cmpeq",
	"cmplt",
	"cmple",
	"cmpunord",
	"cmpneq",
	"cmpnlt",
	"cmpnle",
	"cmpord",
}

var pclmulqOps = []string{
	"pclmullqlqdq",
	"pclmulhqlqdq",
	"pclmullqhqdq",
	"pclmulhqhqdq",
}

func countPrefix(inst *Inst, target Prefix) int {
	n := 0
	for _, p := range inst.Prefix {
		if p&0xFF == target&0xFF {
			n++
		}
	}
	return n
}

func markLastImplicit(inst *Inst, prefix Prefix) bool {
	for i := len(inst.Prefix) - 1; i >= 0; i-- {
		p := inst.Prefix[i]
		if p&0xFF == prefix {
			inst.Prefix[i] |= PrefixImplicit
			return true
		}
	}
	return false
}

func unmarkImplicit(inst *Inst, prefix Prefix) {
	for i := len(inst.Prefix) - 1; i >= 0; i-- {
		p := inst.Prefix[i]
		if p&0xFF == prefix {
			inst.Prefix[i] &^= PrefixImplicit
		}
	}
}

func byteSizeSuffix(b int) string {
	switch b {
	case 1:
		return "b"
	case 2:
		return "w"
	case 4:
		return "l"
	case 8:
		return "q"
	}
	return ""
}

func argBytes(inst *Inst, arg Arg) int {
	if isMem(arg) {
		return inst.MemBytes
	}
	return regBytes(arg)
}

func isFloat(op Op) bool {
	switch op {
	case FADD, FCOM, FCOMP, FDIV, FDIVR, FIADD, FICOM, FICOMP, FIDIV, FIDIVR, FILD, FIMUL, FIST, FISTP, FISTTP, FISUB, FISUBR, FLD, FMUL, FST, FSTP, FSUB, FSUBR:
		return true
	}
	return false
}

func isFloatInt(op Op) bool {
	switch op {
	case FIADD, FICOM, FICOMP, FIDIV, FIDIVR, FILD, FIMUL, FIST, FISTP, FISTTP, FISUB, FISUBR:
		return true
	}
	return false
}
