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

import (
	"bytes"
	"fmt"
	"strings"
)

var (
	// bit 3 of index is a negated check.
	condBit = [8]string{
		"lt", "gt", "eq", "so",
		"ge", "le", "ne", "ns"}
)

// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils.
// This form typically matches the syntax defined in the Power ISA Reference Manual.
func GNUSyntax(inst Inst, pc uint64) string {
	var buf bytes.Buffer
	// When there are all 0s, identify them as the disassembler
	// in binutils would.
	if inst.Enc == 0 {
		return ".long 0x0"
	} else if inst.Op == 0 {
		return "error: unknown instruction"
	}

	PC := pc
	// Special handling for some ops
	startArg := 0
	sep := " "
	opName := inst.Op.String()
	argList := inst.Args[:]

	switch opName {
	case "bc", "bcl", "bca", "bcla", "bclr", "bclrl", "bcctr", "bcctrl", "bctar", "bctarl":
		sfx := inst.Op.String()[2:]
		bo := int(inst.Args[0].(Imm))
		bi := inst.Args[1].(CondReg)
		atsfx := [4]string{"", "?", "-", "+"}
		decsfx := [2]string{"dnz", "dz"}

		//BO field is... complicated (z == ignored bit, at == prediction hint)
		//Paraphrased from ISA 3.1 Book I Section 2.4:
		//
		//0000z -> decrement ctr, b if ctr != 0 and CRbi == 0
		//0001z -> decrement ctr, b if ctr == 0 and CRbi == 0
		//001at -> b if CRbi == 0
		//0100z -> decrement ctr, b if ctr != 0 and CRbi == 1
		//0101z -> decrement ctr, b if ctr == 0 and CRbi == 1
		//011at -> b if CRbi == 1
		//1a00t -> decrement ctr, b if ctr != 0
		//1a01t -> decrement ctr, b if ctr == 0
		//1z1zz -> b always

		// Decoding (in this order) we get
		// BO & 0b00100 == 0b00000 -> dz if BO[1], else dnz (not simplified for bcctrl forms)
		// BO & 0b10000 == 0b10000 -> (bc and bca forms not simplified), at = B[4]B[0] if B[2] != 0, done
		// BO & 0b10000 == 0b00000 -> t if BO[3], else f
		// BO & 0b10100 == 0b00100 -> at = B[0:1]

		// BI fields rename as follows:
		// less than            : lt BI%4==0 && test == t
		// less than or equal   : le BI%4==1 && test == f
		// equal 		: eq BI%4==2 && test == t
		// greater than or equal: ge BI%4==0 && test == f
		// greater than		: gt BI%4==1 && test == t
		// not less than	: nl BI%4==0 && test == f
		// not equal		: ne BI%4==2 && test == f
		// not greater than	: ng BI%4==1 && test == f
		// summary overflow	: so BI%4==3 && test == t
		// not summary overflow : ns BI%4==3 && test == f
		// unordered		: un BI%4==3 && test == t
		// not unordered	: nu BI%4==3 && test == f
		//
		// Note, there are only 8 possible tests, but quite a few more
		// ways to name fields.  For simplicity, we choose those in condBit.

		at := 0   // 0 == no hint, 1 == reserved, 2 == not likely, 3 == likely
		form := 1 // 1 == n/a,  0 == cr bit not set, 4 == cr bit set
		cr := (bi - Cond0LT) / 4
		bh := -1 // Only for lr/tar/ctr variants.
		switch opName {
		case "bclr", "bclrl", "bcctr", "bcctrl", "bctar", "bctarl":
			bh = int(inst.Args[2].(Imm))
		}

		if bo&0x14 == 0x14 {
			if bo == 0x14 && bi == Cond0LT { // preferred form of unconditional branch
				// Likewise, avoid printing fake b/ba/bl/bla
				if opName != "bc" && opName != "bca" && opName != "bcl" && opName != "bcla" {
					startArg = 2
				}
			}
		} else if bo&0x04 == 0 { // ctr is decremented
			if opName != "bcctr" && opName != "bcctrl" {
				startArg = 1
				tf := ""
				if bo&0x10 == 0x00 {
					tf = "f"
					if bo&0x08 == 0x08 {
						tf = "t"
					}
				}
				sfx = decsfx[(bo>>1)&1] + tf + sfx
			}
			if bo&0x10 == 0x10 {
				if opName != "bcctr" && opName != "bcctrl" {
					startArg = 2
				}
				if bi != Cond0LT {
					// A non-zero BI bit was encoded, but ignored by BO
					startArg = 0
				}
				at = ((bo & 0x8) >> 2) | (bo & 0x1)
			} else if bo&0x4 == 0x4 {
				at = bo & 0x3
			}
		} else if bo&0x10 == 0x10 { // BI field is not used
			if opName != "bca" && opName != "bc" {
				at = ((bo & 0x8) >> 2) | (bo & 0x1)
				startArg = 2
			}
			// If BI is encoded as a bit other than 0, no mnemonic.
			if bo&0x14 == 0x14 {
				startArg = 0
			}
		} else {
			form = (bo & 0x8) >> 1
			startArg = 2
			if bo&0x14 == 0x04 {
				at = bo & 0x3
			}
		}
		sfx += atsfx[at]

		if form != 1 {
			bit := int((bi-Cond0LT)%4) | (^form)&0x4
			sfx = condBit[bit] + sfx
		}

		if at != 1 && startArg > 0 && bh <= 0 {
			str := fmt.Sprintf("b%s", sfx)
			if startArg > 1 && (cr != 0 || bh > 0) {
				str += fmt.Sprintf(" cr%d", cr)
				sep = ","
			}
			buf.WriteString(str)
			if startArg < 2 && bh == 0 {
				str := fmt.Sprintf(" %s",
					gnuArg(&inst, 1, inst.Args[1], PC))
				buf.WriteString(str)
				startArg = 3
			} else if bh == 0 {
				startArg = 3
			}
		} else {
			if startArg == 0 || bh > 0 || at == 1 {
				buf.WriteString(inst.Op.String())
				buf.WriteString(atsfx[at])
				startArg = 0
			} else {
				buf.WriteString("b" + sfx)
			}
			if bh == 0 {
				str := fmt.Sprintf(" %d,%s", bo, gnuArg(&inst, 1, inst.Args[1], PC))
				buf.WriteString(str)
				startArg = 3
			}
		}

	case "mtspr":
		opcode := inst.Op.String()
		buf.WriteString(opcode[0:2])
		switch spr := inst.Args[0].(type) {
		case SpReg:
			switch spr {
			case 1:
				buf.WriteString("xer")
				startArg = 1
			case 8:
				buf.WriteString("lr")
				startArg = 1
			case 9:
				buf.WriteString("ctr")
				startArg = 1
			default:
				buf.WriteString("spr")
			}
		default:
			buf.WriteString("spr")
		}

	case "mfspr":
		opcode := inst.Op.String()
		buf.WriteString(opcode[0:2])
		arg := inst.Args[0]
		switch spr := inst.Args[1].(type) {
		case SpReg:
			switch spr {
			case 1:
				buf.WriteString("xer ")
				buf.WriteString(gnuArg(&inst, 0, arg, PC))
				startArg = 2
			case 8:
				buf.WriteString("lr ")
				buf.WriteString(gnuArg(&inst, 0, arg, PC))
				startArg = 2
			case 9:
				buf.WriteString("ctr ")
				buf.WriteString(gnuArg(&inst, 0, arg, PC))
				startArg = 2
			case 268:
				buf.WriteString("tb ")
				buf.WriteString(gnuArg(&inst, 0, arg, PC))
				startArg = 2
			default:
				buf.WriteString("spr")
			}
		default:
			buf.WriteString("spr")
		}

	case "mtfsfi", "mtfsfi.":
		buf.WriteString(opName)
		l := inst.Args[2].(Imm)
		if l == 0 {
			// L == 0 is an extended mnemonic for the same.
			asm := fmt.Sprintf(" %s,%s",
				gnuArg(&inst, 0, inst.Args[0], PC),
				gnuArg(&inst, 1, inst.Args[1], PC))
			buf.WriteString(asm)
			startArg = 3
		}

	case "paste.":
		buf.WriteString(opName)
		l := inst.Args[2].(Imm)
		if l == 1 {
			// L == 1 is an extended mnemonic for the same.
			asm := fmt.Sprintf(" %s,%s",
				gnuArg(&inst, 0, inst.Args[0], PC),
				gnuArg(&inst, 1, inst.Args[1], PC))
			buf.WriteString(asm)
			startArg = 3
		}

	case "mtfsf", "mtfsf.":
		buf.WriteString(opName)
		l := inst.Args[3].(Imm)
		if l == 0 {
			// L == 0 is an extended mnemonic for the same.
			asm := fmt.Sprintf(" %s,%s,%s",
				gnuArg(&inst, 0, inst.Args[0], PC),
				gnuArg(&inst, 1, inst.Args[1], PC),
				gnuArg(&inst, 2, inst.Args[2], PC))
			buf.WriteString(asm)
			startArg = 4
		}

	case "sync":
		lsc := inst.Args[0].(Imm)<<4 | inst.Args[1].(Imm)
		switch lsc {
		case 0x00:
			buf.WriteString("hwsync")
			startArg = 2
		case 0x10:
			buf.WriteString("lwsync")
			startArg = 2
		default:
			buf.WriteString(opName)
		}

	case "lbarx", "lharx", "lwarx", "ldarx":
		// If EH == 0, omit printing EH.
		eh := inst.Args[3].(Imm)
		if eh == 0 {
			argList = inst.Args[:3]
		}
		buf.WriteString(inst.Op.String())

	default:
		buf.WriteString(inst.Op.String())
	}
	for i, arg := range argList {
		if arg == nil {
			break
		}
		if i < startArg {
			continue
		}
		text := gnuArg(&inst, i, arg, PC)
		if text == "" {
			continue
		}
		buf.WriteString(sep)
		sep = ","
		buf.WriteString(text)
	}
	return buf.String()
}

// gnuArg formats arg (which is the argIndex's arg in inst) according to GNU rules.
// NOTE: because GNUSyntax is the only caller of this func, and it receives a copy
//       of inst, it's ok to modify inst.Args here.
func gnuArg(inst *Inst, argIndex int, arg Arg, pc uint64) string {
	// special cases for load/store instructions
	if _, ok := arg.(Offset); ok {
		if argIndex+1 == len(inst.Args) || inst.Args[argIndex+1] == nil {
			panic(fmt.Errorf("wrong table: offset not followed by register"))
		}
	}
	switch arg := arg.(type) {
	case Reg:
		if isLoadStoreOp(inst.Op) && argIndex == 1 && arg == R0 {
			return "0"
		}
		return arg.String()
	case CondReg:
		// The CondReg can either be found in a CMP, where the
		// condition register field is being set, or in an instruction
		// like a branch or isel that is testing a bit in a condition
		// register field.
		if arg == CR0 && strings.HasPrefix(inst.Op.String(), "cmp") {
			return "" // don't show cr0 for cmp instructions
		} else if arg >= CR0 {
			return fmt.Sprintf("cr%d", int(arg-CR0))
		}
		bit := condBit[(arg-Cond0LT)%4]
		if arg <= Cond0SO {
			return bit
		}
		return fmt.Sprintf("4*cr%d+%s", int(arg-Cond0LT)/4, bit)
	case Imm:
		return fmt.Sprintf("%d", arg)
	case SpReg:
		switch int(arg) {
		case 1:
			return "xer"
		case 8:
			return "lr"
		case 9:
			return "ctr"
		case 268:
			return "tb"
		default:
			return fmt.Sprintf("%d", int(arg))
		}
	case PCRel:
		// If the arg is 0, use the relative address format.
		// Otherwise the pc is meaningful, use absolute address.
		if int(arg) == 0 {
			return fmt.Sprintf(".%+#x", int(arg))
		}
		addr := pc + uint64(int64(arg))
		return fmt.Sprintf("%#x", addr)
	case Label:
		return fmt.Sprintf("%#x", uint32(arg))
	case Offset:
		reg := inst.Args[argIndex+1].(Reg)
		removeArg(inst, argIndex+1)
		if reg == R0 {
			return fmt.Sprintf("%d(0)", int(arg))
		}
		return fmt.Sprintf("%d(r%d)", int(arg), reg-R0)
	}
	return fmt.Sprintf("???(%v)", arg)
}

// removeArg removes the arg in inst.Args[index].
func removeArg(inst *Inst, index int) {
	for i := index; i < len(inst.Args); i++ {
		if i+1 < len(inst.Args) {
			inst.Args[i] = inst.Args[i+1]
		} else {
			inst.Args[i] = nil
		}
	}
}

// isLoadStoreOp returns true if op is a load or store instruction
func isLoadStoreOp(op Op) bool {
	switch op {
	case LBZ, LBZU, LBZX, LBZUX:
		return true
	case LHZ, LHZU, LHZX, LHZUX:
		return true
	case LHA, LHAU, LHAX, LHAUX:
		return true
	case LWZ, LWZU, LWZX, LWZUX:
		return true
	case LWA, LWAX, LWAUX:
		return true
	case LD, LDU, LDX, LDUX:
		return true
	case LQ:
		return true
	case STB, STBU, STBX, STBUX:
		return true
	case STH, STHU, STHX, STHUX:
		return true
	case STW, STWU, STWX, STWUX:
		return true
	case STD, STDU, STDX, STDUX:
		return true
	case STQ:
		return true
	case LHBRX, LWBRX, STHBRX, STWBRX:
		return true
	case LBARX, LWARX, LHARX, LDARX:
		return true
	}
	return false
}
