// Copyright 2018 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 main

import (
	"bytes"
	"log"
	"strings"
)

// ytab is ytabList element.
type ytab struct {
	Zcase   string
	Zoffset int
	ArgList string // Ytypes that are matched by this ytab.
}

// ytabList is a named set of ytab objects.
// In asm6.go represented as []ytab.
type ytabList struct {
	Name  string
	Ytabs []ytab
}

// optab describes instruction encodings for specific opcode.
type optab struct {
	Opcode   string
	YtabList *ytabList
	OpLines  []string
}

type generator struct {
	ctx       *context
	ytabLists map[string]*ytabList
}

// generateOptabs fills ctx.optabs and ctx.ytabLists with objects created
// from decoded instructions.
func generateOptabs(ctx *context) {
	gen := generator{ctx: ctx, ytabLists: make(map[string]*ytabList)}
	optabs := make(map[string]*optab)
	for _, g := range ctx.groups {
		optabs[g.opcode] = gen.GenerateGroup(g)
	}
	ctx.optabs = optabs
	ctx.ytabLists = gen.ytabLists
}

// GenerateGroup converts g into optab.
// Populates internal ytab list map.
func (gen *generator) GenerateGroup(g *instGroup) *optab {
	var opLines []string
	for _, inst := range g.list {
		opLines = append(opLines, gen.generateOpLine(inst))
	}
	return &optab{
		Opcode:   "A" + g.opcode,
		OpLines:  opLines,
		YtabList: gen.internYtabList(g),
	}
}

// generateOpLine returns string that describes opBytes for single instruction form.
func (gen *generator) generateOpLine(inst *instruction) string {
	parts := []string{gen.prefixExpr(inst)}
	if inst.pset.Is("EVEX") {
		parts = append(parts, gen.evexPrefixExpr(inst))
	}
	parts = append(parts, inst.enc.opbyte)
	if inst.enc.opdigit != "" {
		parts = append(parts, inst.enc.opdigit)
	}
	return strings.Join(parts, ", ")
}

func (gen *generator) prefixExpr(inst *instruction) string {
	enc := inst.enc
	return gen.joinPrefixParts([]string{
		// Special constant that makes AVX byte different from 0x0F,
		// making it unnecessary to check for both VEX+EVEX when
		// assigning dealing with legacy instructions that skip it
		// without advancing "z" counter.
		"avxEscape",
		enc.vex.L,
		enc.vex.P,
		enc.vex.M,
		enc.vex.W,
	})
}

func (gen *generator) evexPrefixExpr(inst *instruction) string {
	enc := inst.enc
	parts := []string{
		enc.evexScale,
		enc.evexBcstScale,
	}
	if enc.evex.SAE {
		parts = append(parts, "evexSaeEnabled")
	}
	if enc.evex.Rounding {
		parts = append(parts, "evexRoundingEnabled")
	}
	if enc.evex.Zeroing {
		parts = append(parts, "evexZeroingEnabled")
	}
	return gen.joinPrefixParts(parts)
}

// joinPrefixParts returns the Go OR-expression for every non-empty name.
// If every name is empty, returns "0".
func (gen *generator) joinPrefixParts(names []string) string {
	filterEmptyStrings := func(xs []string) []string {
		ys := xs[:0]
		for _, x := range xs {
			if x != "" {
				ys = append(ys, x)
			}
		}
		return ys
	}

	names = filterEmptyStrings(names)
	if len(names) == 0 {
		return "0"
	}
	return strings.Join(names, "|")
}

// internYtabList returns ytabList for given group.
//
// Returned ytab lists are interned.
// Same ytab list can be returned for different groups.
func (gen *generator) internYtabList(g *instGroup) *ytabList {
	var key string
	{
		var buf bytes.Buffer
		for _, inst := range g.list {
			buf.WriteString(inst.zform)
			buf.WriteByte('=')
			buf.WriteString(inst.YtypeListString())
			buf.WriteByte(';')
		}
		key = buf.String()
	}
	if ylist := gen.ytabLists[key]; ylist != nil {
		return ylist
	}

	var ytabs []ytab
	for _, inst := range g.list {
		zoffset := 2
		if inst.pset.Is("EVEX") {
			zoffset++ // Always at least 3 bytes
		}
		if inst.enc.opdigit != "" {
			zoffset++
		}

		if inst.mask != nil {
			ytabs = append(ytabs, gen.makeMaskYtabs(zoffset, inst)...)
		} else {
			ytabs = append(ytabs, gen.makeYtab(zoffset, inst.zform, inst.args))
		}
	}
	ylist := &ytabList{
		Name:  "_y" + strings.ToLower(g.opcode),
		Ytabs: ytabs,
	}
	gen.ytabLists[key] = ylist
	return ylist
}

var zcaseByZform = map[string]string{
	"evex imm8 reg kmask reg/mem":          "Zevex_i_r_k_rm",
	"evex imm8 reg reg/mem":                "Zevex_i_r_rm",
	"evex imm8 reg/mem kmask reg":          "Zevex_i_rm_k_r",
	"evex imm8 reg/mem kmask regV opdigit": "Zevex_i_rm_k_vo",
	"evex imm8 reg/mem reg":                "Zevex_i_rm_r",
	"evex imm8 reg/mem regV opdigit":       "Zevex_i_rm_vo",
	"evex imm8 reg/mem regV kmask reg":     "Zevex_i_rm_v_k_r",
	"evex imm8 reg/mem regV reg":           "Zevex_i_rm_v_r",
	"evex kmask reg/mem opdigit":           "Zevex_k_rmo",
	"evex reg kmask reg/mem":               "Zevex_r_k_rm",
	"evex reg reg/mem":                     "Zevex_r_v_rm",
	"evex reg regV kmask reg/mem":          "Zevex_r_v_k_rm",
	"evex reg regV reg/mem":                "Zevex_r_v_rm",
	"evex reg/mem kmask reg":               "Zevex_rm_k_r",
	"evex reg/mem reg":                     "Zevex_rm_v_r",
	"evex reg/mem regV kmask reg":          "Zevex_rm_v_k_r",
	"evex reg/mem regV reg":                "Zevex_rm_v_r",

	"":                          "Zvex",
	"imm8 reg reg/mem":          "Zvex_i_r_rm",
	"imm8 reg/mem reg":          "Zvex_i_rm_r",
	"imm8 reg/mem regV opdigit": "Zvex_i_rm_vo",
	"imm8 reg/mem regV reg":     "Zvex_i_rm_v_r",
	"reg reg/mem":               "Zvex_r_v_rm",
	"reg regV reg/mem":          "Zvex_r_v_rm",
	"reg/mem opdigit":           "Zvex_rm_v_ro",
	"reg/mem reg":               "Zvex_rm_v_r",
	"reg/mem regV opdigit":      "Zvex_rm_r_vo",
	"reg/mem regV reg":          "Zvex_rm_v_r",
	"reg/mem":                   "Zvex_rm_v_r",
	"regIH reg/mem regV reg":    "Zvex_hr_rm_v_r",
	"regV reg/mem reg":          "Zvex_v_rm_r",
}

func (gen *generator) makeYtab(zoffset int, zform string, args []*argument) ytab {
	var ytypes []string
	for _, arg := range args {
		if arg.ytype != "Ynone" {
			ytypes = append(ytypes, arg.ytype)
		}
	}
	argList := strings.Join(ytypes, ", ")
	zcase := zcaseByZform[zform]
	if zcase == "" {
		log.Fatalf("no zcase for %q", zform)
	}
	return ytab{
		Zcase:   zcase,
		Zoffset: zoffset,
		ArgList: argList,
	}
}

// makeMaskYtabs returns 2 ytabs created from instruction with MASK1() argument.
//
// This is required due to how masking is implemented in asm6.
// Single MASK1() instruction produces 2 ytabs, for example:
//	1. OP xmm, mem     | Yxr, Yxm         | Does not permit K arguments (K0 implied)
//	2. OP xmm, K2, mem | Yxr, Yknot0, Yxm | Does not permit K0 argument
//
// This function also exploits that both ytab entries have same opbytes,
// hence it is efficient to emit only one opbytes line and 0 Z-offset
// for first ytab object.
func (gen *generator) makeMaskYtabs(zoffset int, inst *instruction) []ytab {
	var k0 ytab
	{
		zform := strings.Replace(inst.zform, "MASK1() ", "", 1)
		inst.mask.ytype = "Ynone"
		k0 = gen.makeYtab(0, zform, inst.args)
	}
	var knot0 ytab
	{
		zform := strings.Replace(inst.zform, "MASK1() ", "kmask ", 1)
		inst.mask.ytype = "Yknot0"
		knot0 = gen.makeYtab(zoffset, zform, inst.args)
	}

	inst.mask.ytype = "MASK1()" // Restore Y-type
	return []ytab{k0, knot0}
}
