// Copyright 2009 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 gc

import "cmd/internal/obj"

// machine size and rounding alignment is dictated around
// the size of a pointer, set in betypeinit (see ../amd64/galign.go).
var defercalc int

func Rnd(o int64, r int64) int64 {
	if r < 1 || r > 8 || r&(r-1) != 0 {
		Fatalf("rnd %d", r)
	}
	return (o + r - 1) &^ (r - 1)
}

func offmod(t *Type) {
	o := int32(0)
	for f := t.Type; f != nil; f = f.Down {
		if f.Etype != TFIELD {
			Fatalf("offmod: not TFIELD: %v", Tconv(f, obj.FmtLong))
		}
		f.Width = int64(o)
		o += int32(Widthptr)
		if int64(o) >= Thearch.MAXWIDTH {
			Yyerror("interface too large")
			o = int32(Widthptr)
		}
	}
}

func widstruct(errtype *Type, t *Type, o int64, flag int) int64 {
	starto := o
	maxalign := int32(flag)
	if maxalign < 1 {
		maxalign = 1
	}
	lastzero := int64(0)
	var w int64
	for f := t.Type; f != nil; f = f.Down {
		if f.Etype != TFIELD {
			Fatalf("widstruct: not TFIELD: %v", Tconv(f, obj.FmtLong))
		}
		if f.Type == nil {
			// broken field, just skip it so that other valid fields
			// get a width.
			continue
		}

		dowidth(f.Type)
		if int32(f.Type.Align) > maxalign {
			maxalign = int32(f.Type.Align)
		}
		if f.Type.Width < 0 {
			Fatalf("invalid width %d", f.Type.Width)
		}
		w = f.Type.Width
		if f.Type.Align > 0 {
			o = Rnd(o, int64(f.Type.Align))
		}
		f.Width = o // really offset for TFIELD
		if f.Nname != nil {
			// this same stackparam logic is in addrescapes
			// in typecheck.go.  usually addrescapes runs after
			// widstruct, in which case we could drop this,
			// but function closure functions are the exception.
			if f.Nname.Name.Param.Stackparam != nil {
				f.Nname.Name.Param.Stackparam.Xoffset = o
				f.Nname.Xoffset = 0
			} else {
				f.Nname.Xoffset = o
			}
		}

		if w == 0 {
			lastzero = o
		}
		o += w
		if o >= Thearch.MAXWIDTH {
			Yyerror("type %v too large", Tconv(errtype, obj.FmtLong))
			o = 8 // small but nonzero
		}
	}

	// For nonzero-sized structs which end in a zero-sized thing, we add
	// an extra byte of padding to the type. This padding ensures that
	// taking the address of the zero-sized thing can't manufacture a
	// pointer to the next object in the heap. See issue 9401.
	if flag == 1 && o > starto && o == lastzero {
		o++
	}

	// final width is rounded
	if flag != 0 {
		o = Rnd(o, int64(maxalign))
	}
	t.Align = uint8(maxalign)

	// type width only includes back to first field's offset
	t.Width = o - starto

	return o
}

func dowidth(t *Type) {
	if Widthptr == 0 {
		Fatalf("dowidth without betypeinit")
	}

	if t == nil {
		return
	}

	if t.Width > 0 {
		if t.Align == 0 {
			// See issue 11354
			Fatalf("zero alignment with nonzero size %v", t)
		}
		return
	}

	if t.Width == -2 {
		if !t.Broke {
			t.Broke = true
			yyerrorl(int32(t.Lineno), "invalid recursive type %v", t)
		}

		t.Width = 0
		return
	}

	// break infinite recursion if the broken recursive type
	// is referenced again
	if t.Broke && t.Width == 0 {
		return
	}

	// defer checkwidth calls until after we're done
	defercalc++

	lno := lineno
	lineno = int32(t.Lineno)
	t.Width = -2
	t.Align = 0

	et := t.Etype
	switch et {
	case TFUNC, TCHAN, TMAP, TSTRING:
		break

	// simtype == 0 during bootstrap
	default:
		if Simtype[t.Etype] != 0 {
			et = Simtype[t.Etype]
		}
	}

	w := int64(0)
	switch et {
	default:
		Fatalf("dowidth: unknown type: %v", t)

	// compiler-specific stuff
	case TINT8, TUINT8, TBOOL:
		// bool is int8
		w = 1

	case TINT16, TUINT16:
		w = 2

	case TINT32, TUINT32, TFLOAT32:
		w = 4

	case TINT64, TUINT64, TFLOAT64, TCOMPLEX64:
		w = 8
		t.Align = uint8(Widthreg)

	case TCOMPLEX128:
		w = 16
		t.Align = uint8(Widthreg)

	case TPTR32:
		w = 4
		checkwidth(t.Type)

	case TPTR64:
		w = 8
		checkwidth(t.Type)

	case TUNSAFEPTR:
		w = int64(Widthptr)

	case TINTER: // implemented as 2 pointers
		w = 2 * int64(Widthptr)

		t.Align = uint8(Widthptr)
		offmod(t)

	case TCHAN: // implemented as pointer
		w = int64(Widthptr)

		checkwidth(t.Type)

		// make fake type to check later to
		// trigger channel argument check.
		t1 := typ(TCHANARGS)

		t1.Type = t
		checkwidth(t1)

	case TCHANARGS:
		t1 := t.Type
		dowidth(t.Type) // just in case
		if t1.Type.Width >= 1<<16 {
			Yyerror("channel element type too large (>64kB)")
		}
		t.Width = 1

	case TMAP: // implemented as pointer
		w = int64(Widthptr)

		checkwidth(t.Type)
		checkwidth(t.Down)

	case TFORW: // should have been filled in
		if !t.Broke {
			Yyerror("invalid recursive type %v", t)
		}
		w = 1 // anything will do

	// dummy type; should be replaced before use.
	case TANY:
		if Debug['A'] == 0 {
			Fatalf("dowidth any")
		}
		w = 1 // anything will do

	case TSTRING:
		if sizeof_String == 0 {
			Fatalf("early dowidth string")
		}
		w = int64(sizeof_String)
		t.Align = uint8(Widthptr)

	case TARRAY:
		if t.Type == nil {
			break
		}
		if t.Bound >= 0 {
			dowidth(t.Type)
			if t.Type.Width != 0 {
				cap := (uint64(Thearch.MAXWIDTH) - 1) / uint64(t.Type.Width)
				if uint64(t.Bound) > cap {
					Yyerror("type %v larger than address space", Tconv(t, obj.FmtLong))
				}
			}

			w = t.Bound * t.Type.Width
			t.Align = t.Type.Align
		} else if t.Bound == -1 {
			w = int64(sizeof_Array)
			checkwidth(t.Type)
			t.Align = uint8(Widthptr)
		} else if t.Bound == -100 {
			if !t.Broke {
				Yyerror("use of [...] array outside of array literal")
				t.Broke = true
			}
		} else {
			Fatalf("dowidth %v", t) // probably [...]T
		}

	case TSTRUCT:
		if t.Funarg {
			Fatalf("dowidth fn struct %v", t)
		}
		w = widstruct(t, t, 0, 1)

	// make fake type to check later to
	// trigger function argument computation.
	case TFUNC:
		t1 := typ(TFUNCARGS)

		t1.Type = t
		checkwidth(t1)

		// width of func type is pointer
		w = int64(Widthptr)

	// function is 3 cated structures;
	// compute their widths as side-effect.
	case TFUNCARGS:
		t1 := t.Type

		w = widstruct(t.Type, *getthis(t1), 0, 0)
		w = widstruct(t.Type, *getinarg(t1), w, Widthreg)
		w = widstruct(t.Type, *Getoutarg(t1), w, Widthreg)
		t1.Argwid = w
		if w%int64(Widthreg) != 0 {
			Warn("bad type %v %d\n", t1, w)
		}
		t.Align = 1
	}

	if Widthptr == 4 && w != int64(int32(w)) {
		Yyerror("type %v too large", t)
	}

	t.Width = w
	if t.Align == 0 {
		if w > 8 || w&(w-1) != 0 {
			Fatalf("invalid alignment for %v", t)
		}
		t.Align = uint8(w)
	}

	lineno = lno

	if defercalc == 1 {
		resumecheckwidth()
	} else {
		defercalc--
	}
}

// when a type's width should be known, we call checkwidth
// to compute it.  during a declaration like
//
//	type T *struct { next T }
//
// it is necessary to defer the calculation of the struct width
// until after T has been initialized to be a pointer to that struct.
// similarly, during import processing structs may be used
// before their definition.  in those situations, calling
// defercheckwidth() stops width calculations until
// resumecheckwidth() is called, at which point all the
// checkwidths that were deferred are executed.
// dowidth should only be called when the type's size
// is needed immediately.  checkwidth makes sure the
// size is evaluated eventually.
type TypeList struct {
	t    *Type
	next *TypeList
}

var tlfree *TypeList

var tlq *TypeList

func checkwidth(t *Type) {
	if t == nil {
		return
	}

	// function arg structs should not be checked
	// outside of the enclosing function.
	if t.Funarg {
		Fatalf("checkwidth %v", t)
	}

	if defercalc == 0 {
		dowidth(t)
		return
	}

	if t.Deferwidth {
		return
	}
	t.Deferwidth = true

	l := tlfree
	if l != nil {
		tlfree = l.next
	} else {
		l = new(TypeList)
	}

	l.t = t
	l.next = tlq
	tlq = l
}

func defercheckwidth() {
	// we get out of sync on syntax errors, so don't be pedantic.
	if defercalc != 0 && nerrors == 0 {
		Fatalf("defercheckwidth")
	}
	defercalc = 1
}

func resumecheckwidth() {
	if defercalc == 0 {
		Fatalf("resumecheckwidth")
	}
	for l := tlq; l != nil; l = tlq {
		l.t.Deferwidth = false
		tlq = l.next
		dowidth(l.t)
		l.next = tlfree
		tlfree = l
	}

	defercalc = 0
}

var itable *Type // distinguished *byte

func typeinit() {
	if Widthptr == 0 {
		Fatalf("typeinit before betypeinit")
	}

	for et := EType(0); et < NTYPE; et++ {
		Simtype[et] = et
	}

	Types[TPTR32] = typ(TPTR32)
	dowidth(Types[TPTR32])

	Types[TPTR64] = typ(TPTR64)
	dowidth(Types[TPTR64])

	t := typ(TUNSAFEPTR)
	Types[TUNSAFEPTR] = t
	t.Sym = Pkglookup("Pointer", unsafepkg)
	t.Sym.Def = typenod(t)
	t.Sym.Def.Name = new(Name)

	dowidth(Types[TUNSAFEPTR])

	Tptr = TPTR32
	if Widthptr == 8 {
		Tptr = TPTR64
	}

	for et := TINT8; et <= TUINT64; et++ {
		Isint[et] = true
	}
	Isint[TINT] = true
	Isint[TUINT] = true
	Isint[TUINTPTR] = true

	Isfloat[TFLOAT32] = true
	Isfloat[TFLOAT64] = true

	Iscomplex[TCOMPLEX64] = true
	Iscomplex[TCOMPLEX128] = true

	Isptr[TPTR32] = true
	Isptr[TPTR64] = true

	isforw[TFORW] = true

	Issigned[TINT] = true
	Issigned[TINT8] = true
	Issigned[TINT16] = true
	Issigned[TINT32] = true
	Issigned[TINT64] = true

	// initialize okfor
	for et := EType(0); et < NTYPE; et++ {
		if Isint[et] || et == TIDEAL {
			okforeq[et] = true
			okforcmp[et] = true
			okforarith[et] = true
			okforadd[et] = true
			okforand[et] = true
			okforconst[et] = true
			issimple[et] = true
			Minintval[et] = new(Mpint)
			Maxintval[et] = new(Mpint)
		}

		if Isfloat[et] {
			okforeq[et] = true
			okforcmp[et] = true
			okforadd[et] = true
			okforarith[et] = true
			okforconst[et] = true
			issimple[et] = true
			minfltval[et] = newMpflt()
			maxfltval[et] = newMpflt()
		}

		if Iscomplex[et] {
			okforeq[et] = true
			okforadd[et] = true
			okforarith[et] = true
			okforconst[et] = true
			issimple[et] = true
		}
	}

	issimple[TBOOL] = true

	okforadd[TSTRING] = true

	okforbool[TBOOL] = true

	okforcap[TARRAY] = true
	okforcap[TCHAN] = true

	okforconst[TBOOL] = true
	okforconst[TSTRING] = true

	okforlen[TARRAY] = true
	okforlen[TCHAN] = true
	okforlen[TMAP] = true
	okforlen[TSTRING] = true

	okforeq[TPTR32] = true
	okforeq[TPTR64] = true
	okforeq[TUNSAFEPTR] = true
	okforeq[TINTER] = true
	okforeq[TCHAN] = true
	okforeq[TSTRING] = true
	okforeq[TBOOL] = true
	okforeq[TMAP] = true    // nil only; refined in typecheck
	okforeq[TFUNC] = true   // nil only; refined in typecheck
	okforeq[TARRAY] = true  // nil slice only; refined in typecheck
	okforeq[TSTRUCT] = true // it's complicated; refined in typecheck

	okforcmp[TSTRING] = true

	var i int
	for i = 0; i < len(okfor); i++ {
		okfor[i] = okfornone[:]
	}

	// binary
	okfor[OADD] = okforadd[:]

	okfor[OAND] = okforand[:]
	okfor[OANDAND] = okforbool[:]
	okfor[OANDNOT] = okforand[:]
	okfor[ODIV] = okforarith[:]
	okfor[OEQ] = okforeq[:]
	okfor[OGE] = okforcmp[:]
	okfor[OGT] = okforcmp[:]
	okfor[OLE] = okforcmp[:]
	okfor[OLT] = okforcmp[:]
	okfor[OMOD] = okforand[:]
	okfor[OHMUL] = okforarith[:]
	okfor[OMUL] = okforarith[:]
	okfor[ONE] = okforeq[:]
	okfor[OOR] = okforand[:]
	okfor[OOROR] = okforbool[:]
	okfor[OSUB] = okforarith[:]
	okfor[OXOR] = okforand[:]
	okfor[OLSH] = okforand[:]
	okfor[ORSH] = okforand[:]

	// unary
	okfor[OCOM] = okforand[:]

	okfor[OMINUS] = okforarith[:]
	okfor[ONOT] = okforbool[:]
	okfor[OPLUS] = okforarith[:]

	// special
	okfor[OCAP] = okforcap[:]

	okfor[OLEN] = okforlen[:]

	// comparison
	iscmp[OLT] = true

	iscmp[OGT] = true
	iscmp[OGE] = true
	iscmp[OLE] = true
	iscmp[OEQ] = true
	iscmp[ONE] = true

	mpatofix(Maxintval[TINT8], "0x7f")
	mpatofix(Minintval[TINT8], "-0x80")
	mpatofix(Maxintval[TINT16], "0x7fff")
	mpatofix(Minintval[TINT16], "-0x8000")
	mpatofix(Maxintval[TINT32], "0x7fffffff")
	mpatofix(Minintval[TINT32], "-0x80000000")
	mpatofix(Maxintval[TINT64], "0x7fffffffffffffff")
	mpatofix(Minintval[TINT64], "-0x8000000000000000")

	mpatofix(Maxintval[TUINT8], "0xff")
	mpatofix(Maxintval[TUINT16], "0xffff")
	mpatofix(Maxintval[TUINT32], "0xffffffff")
	mpatofix(Maxintval[TUINT64], "0xffffffffffffffff")

	// f is valid float if min < f < max.  (min and max are not themselves valid.)
	mpatoflt(maxfltval[TFLOAT32], "33554431p103") // 2^24-1 p (127-23) + 1/2 ulp
	mpatoflt(minfltval[TFLOAT32], "-33554431p103")
	mpatoflt(maxfltval[TFLOAT64], "18014398509481983p970") // 2^53-1 p (1023-52) + 1/2 ulp
	mpatoflt(minfltval[TFLOAT64], "-18014398509481983p970")

	maxfltval[TCOMPLEX64] = maxfltval[TFLOAT32]
	minfltval[TCOMPLEX64] = minfltval[TFLOAT32]
	maxfltval[TCOMPLEX128] = maxfltval[TFLOAT64]
	minfltval[TCOMPLEX128] = minfltval[TFLOAT64]

	// for walk to use in error messages
	Types[TFUNC] = functype(nil, nil, nil)

	// types used in front end
	// types[TNIL] got set early in lexinit
	Types[TIDEAL] = typ(TIDEAL)

	Types[TINTER] = typ(TINTER)

	// simple aliases
	Simtype[TMAP] = Tptr

	Simtype[TCHAN] = Tptr
	Simtype[TFUNC] = Tptr
	Simtype[TUNSAFEPTR] = Tptr

	Array_array = int(Rnd(0, int64(Widthptr)))
	Array_nel = int(Rnd(int64(Array_array)+int64(Widthptr), int64(Widthint)))
	Array_cap = int(Rnd(int64(Array_nel)+int64(Widthint), int64(Widthint)))
	sizeof_Array = int(Rnd(int64(Array_cap)+int64(Widthint), int64(Widthptr)))

	// string is same as slice wo the cap
	sizeof_String = int(Rnd(int64(Array_nel)+int64(Widthint), int64(Widthptr)))

	dowidth(Types[TSTRING])
	dowidth(idealstring)

	itable = typ(Tptr)
	itable.Type = Types[TUINT8]
}

// compute total size of f's in/out arguments.
func Argsize(t *Type) int {
	var save Iter
	var x int64

	w := int64(0)

	fp := Structfirst(&save, Getoutarg(t))
	for fp != nil {
		x = fp.Width + fp.Type.Width
		if x > w {
			w = x
		}
		fp = structnext(&save)
	}

	fp = funcfirst(&save, t)
	for fp != nil {
		x = fp.Width + fp.Type.Width
		if x > w {
			w = x
		}
		fp = funcnext(&save)
	}

	w = (w + int64(Widthptr) - 1) &^ (int64(Widthptr) - 1)
	if int64(int(w)) != w {
		Fatalf("argsize too big")
	}
	return int(w)
}
