// 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"
)

type Inst struct {
	Op        Op     // Opcode mnemonic
	Enc       uint32 // Raw encoding bits (if Len == 8, this is the prefix word)
	Len       int    // Length of encoding in bytes.
	SuffixEnc uint32 // Raw encoding bits of second word (if Len == 8)
	Args      Args   // Instruction arguments, in Power ISA manual order.
}

func (i Inst) String() string {
	var buf bytes.Buffer
	buf.WriteString(i.Op.String())
	for j, arg := range i.Args {
		if arg == nil {
			break
		}
		if j == 0 {
			buf.WriteString(" ")
		} else {
			buf.WriteString(", ")
		}
		buf.WriteString(arg.String())
	}
	return buf.String()
}

// An Op is an instruction operation.
type Op uint16

func (o Op) String() string {
	if int(o) >= len(opstr) || opstr[o] == "" {
		return fmt.Sprintf("Op(%d)", int(o))
	}
	return opstr[o]
}

// An Arg is a single instruction argument, one of these types: Reg, CondReg, SpReg, Imm, PCRel, Label, or Offset.
type Arg interface {
	IsArg()
	String() string
}

// An Args holds the instruction arguments.
// If an instruction has fewer than 6 arguments,
// the final elements in the array are nil.
type Args [6]Arg

// A Reg is a single register. The zero value means R0, not the absence of a register.
// It also includes special registers.
type Reg uint16

const (
	_ Reg = iota
	R0
	R1
	R2
	R3
	R4
	R5
	R6
	R7
	R8
	R9
	R10
	R11
	R12
	R13
	R14
	R15
	R16
	R17
	R18
	R19
	R20
	R21
	R22
	R23
	R24
	R25
	R26
	R27
	R28
	R29
	R30
	R31
	F0
	F1
	F2
	F3
	F4
	F5
	F6
	F7
	F8
	F9
	F10
	F11
	F12
	F13
	F14
	F15
	F16
	F17
	F18
	F19
	F20
	F21
	F22
	F23
	F24
	F25
	F26
	F27
	F28
	F29
	F30
	F31
	V0 // VSX extension, F0 is V0[0:63].
	V1
	V2
	V3
	V4
	V5
	V6
	V7
	V8
	V9
	V10
	V11
	V12
	V13
	V14
	V15
	V16
	V17
	V18
	V19
	V20
	V21
	V22
	V23
	V24
	V25
	V26
	V27
	V28
	V29
	V30
	V31
	VS0
	VS1
	VS2
	VS3
	VS4
	VS5
	VS6
	VS7
	VS8
	VS9
	VS10
	VS11
	VS12
	VS13
	VS14
	VS15
	VS16
	VS17
	VS18
	VS19
	VS20
	VS21
	VS22
	VS23
	VS24
	VS25
	VS26
	VS27
	VS28
	VS29
	VS30
	VS31
	VS32
	VS33
	VS34
	VS35
	VS36
	VS37
	VS38
	VS39
	VS40
	VS41
	VS42
	VS43
	VS44
	VS45
	VS46
	VS47
	VS48
	VS49
	VS50
	VS51
	VS52
	VS53
	VS54
	VS55
	VS56
	VS57
	VS58
	VS59
	VS60
	VS61
	VS62
	VS63
	A0 // MMA registers.  These are effectively shadow registers of four adjacent VSR's [An*4,An*4+3]
	A1
	A2
	A3
	A4
	A5
	A6
	A7
)

func (Reg) IsArg() {}
func (r Reg) String() string {
	switch {
	case R0 <= r && r <= R31:
		return fmt.Sprintf("r%d", int(r-R0))
	case F0 <= r && r <= F31:
		return fmt.Sprintf("f%d", int(r-F0))
	case V0 <= r && r <= V31:
		return fmt.Sprintf("v%d", int(r-V0))
	case VS0 <= r && r <= VS63:
		return fmt.Sprintf("vs%d", int(r-VS0))
	case A0 <= r && r <= A7:
		return fmt.Sprintf("a%d", int(r-A0))
	default:
		return fmt.Sprintf("Reg(%d)", int(r))
	}
}

// CondReg is a bit or field in the condition register.
type CondReg int8

const (
	_ CondReg = iota
	// Condition Regster bits
	Cond0LT
	Cond0GT
	Cond0EQ
	Cond0SO
	Cond1LT
	Cond1GT
	Cond1EQ
	Cond1SO
	Cond2LT
	Cond2GT
	Cond2EQ
	Cond2SO
	Cond3LT
	Cond3GT
	Cond3EQ
	Cond3SO
	Cond4LT
	Cond4GT
	Cond4EQ
	Cond4SO
	Cond5LT
	Cond5GT
	Cond5EQ
	Cond5SO
	Cond6LT
	Cond6GT
	Cond6EQ
	Cond6SO
	Cond7LT
	Cond7GT
	Cond7EQ
	Cond7SO
	// Condition Register Fields
	CR0
	CR1
	CR2
	CR3
	CR4
	CR5
	CR6
	CR7
)

func (CondReg) IsArg() {}
func (c CondReg) String() string {
	switch {
	default:
		return fmt.Sprintf("CondReg(%d)", int(c))
	case c >= CR0:
		return fmt.Sprintf("CR%d", int(c-CR0))
	case c >= Cond0LT && c < CR0:
		return fmt.Sprintf("Cond%d%s", int((c-Cond0LT)/4), [4]string{"LT", "GT", "EQ", "SO"}[(c-Cond0LT)%4])
	}
}

// SpReg is a special register, its meaning depends on Op.
type SpReg uint16

const (
	SpRegZero SpReg = 0
)

func (SpReg) IsArg() {}
func (s SpReg) String() string {
	return fmt.Sprintf("SpReg(%d)", int(s))
}

// PCRel is a PC-relative offset, used only in branch instructions.
type PCRel int32

func (PCRel) IsArg() {}
func (r PCRel) String() string {
	return fmt.Sprintf("PC%+#x", int32(r))
}

// A Label is a code (text) address, used only in absolute branch instructions.
type Label uint32

func (Label) IsArg() {}
func (l Label) String() string {
	return fmt.Sprintf("%#x", uint32(l))
}

// Imm represents an immediate number.
type Imm int64

func (Imm) IsArg() {}
func (i Imm) String() string {
	return fmt.Sprintf("%d", int32(i))
}

// Offset represents a memory offset immediate.
type Offset int64

func (Offset) IsArg() {}
func (o Offset) String() string {
	return fmt.Sprintf("%+d", int32(o))
}
