// Copyright 2015 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 ssa

import (
	"cmd/compile/internal/ir"
	"cmd/compile/internal/types"
	"fmt"
)

// A place that an ssa variable can reside.
type Location interface {
	String() string // name to use in assembly templates: AX, 16(SP), ...
}

// A Register is a machine register, like AX.
// They are numbered densely from 0 (for each architecture).
type Register struct {
	num    int32 // dense numbering
	objNum int16 // register number from cmd/internal/obj/$ARCH
	gcNum  int16 // GC register map number (dense numbering of registers that can contain pointers)
	name   string
}

func (r *Register) String() string {
	return r.name
}

// ObjNum returns the register number from cmd/internal/obj/$ARCH that
// corresponds to this register.
func (r *Register) ObjNum() int16 {
	return r.objNum
}

// GCNum returns the runtime GC register index of r, or -1 if this
// register can't contain pointers.
func (r *Register) GCNum() int16 {
	return r.gcNum
}

// A LocalSlot is a location in the stack frame, which identifies and stores
// part or all of a PPARAM, PPARAMOUT, or PAUTO ONAME node.
// It can represent a whole variable, part of a larger stack slot, or part of a
// variable that has been decomposed into multiple stack slots.
// As an example, a string could have the following configurations:
//
//           stack layout              LocalSlots
//
// Optimizations are disabled. s is on the stack and represented in its entirety.
// [ ------- s string ---- ] { N: s, Type: string, Off: 0 }
//
// s was not decomposed, but the SSA operates on its parts individually, so
// there is a LocalSlot for each of its fields that points into the single stack slot.
// [ ------- s string ---- ] { N: s, Type: *uint8, Off: 0 }, {N: s, Type: int, Off: 8}
//
// s was decomposed. Each of its fields is in its own stack slot and has its own LocalSLot.
// [ ptr *uint8 ] [ len int] { N: ptr, Type: *uint8, Off: 0, SplitOf: parent, SplitOffset: 0},
//                           { N: len, Type: int, Off: 0, SplitOf: parent, SplitOffset: 8}
//                           parent = &{N: s, Type: string}
type LocalSlot struct {
	N    *ir.Name    // an ONAME *ir.Name representing a stack location.
	Type *types.Type // type of slot
	Off  int64       // offset of slot in N

	SplitOf     *LocalSlot // slot is a decomposition of SplitOf
	SplitOffset int64      // .. at this offset.
}

func (s LocalSlot) String() string {
	if s.Off == 0 {
		return fmt.Sprintf("%v[%v]", s.N, s.Type)
	}
	return fmt.Sprintf("%v+%d[%v]", s.N, s.Off, s.Type)
}

type LocPair [2]Location

func (t LocPair) String() string {
	n0, n1 := "nil", "nil"
	if t[0] != nil {
		n0 = t[0].String()
	}
	if t[1] != nil {
		n1 = t[1].String()
	}
	return fmt.Sprintf("<%s,%s>", n0, n1)
}

type LocResults []Location

func (t LocResults) String() string {
	s := "<"
	a := ""
	for _, r := range t {
		a += s
		s = ","
		a += r.String()
	}
	a += ">"
	return a
}

type Spill struct {
	Type   *types.Type
	Offset int64
	Reg    int16
}
