// 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 ../6g/galign.c).
 */
var defercalc int

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

func offmod(t *Type) {
	var f *Type
	var o int32

	o = 0
	for f = t.Type; f != nil; f = f.Down {
		if f.Etype != TFIELD {
			Fatal("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 {
	var f *Type
	var w int64
	var maxalign int32
	var starto int64
	var lastzero int64

	starto = o
	maxalign = int32(flag)
	if maxalign < 1 {
		maxalign = 1
	}
	lastzero = 0
	for f = t.Type; f != nil; f = f.Down {
		if f.Etype != TFIELD {
			Fatal("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 {
			Fatal("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.c.  usually addrescapes runs after
			// widstruct, in which case we could drop this,
			// but function closure functions are the exception.
			if f.Nname.Stackparam != nil {
				f.Nname.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) {
	var et int32
	var w int64
	var lno int
	var t1 *Type

	if Widthptr == 0 {
		Fatal("dowidth without betypeinit")
	}

	if t == nil {
		return
	}

	if t.Width > 0 {
		return
	}

	if t.Width == -2 {
		lno = int(lineno)
		lineno = int32(t.Lineno)
		if t.Broke == 0 {
			t.Broke = 1
			Yyerror("invalid recursive type %v", Tconv(t, 0))
		}

		t.Width = 0
		lineno = int32(lno)
		return
	}

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

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

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

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

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

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

		/* 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 == 0 {
			Yyerror("invalid recursive type %v", Tconv(t, 0))
		}
		w = 1 // anything will do

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

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

	case TARRAY:
		if t.Type == nil {
			break
		}
		if t.Bound >= 0 {
			var cap uint64

			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 == 0 {
				Yyerror("use of [...] array outside of array literal")
				t.Broke = 1
			}
		} else {
			Fatal("dowidth %v", Tconv(t, 0)) // probably [...]T
		}

	case TSTRUCT:
		if t.Funarg != 0 {
			Fatal("dowidth fn struct %v", Tconv(t, 0))
		}
		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", Tconv(t1, 0), w)
		}
		t.Align = 1
	}

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

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

	lineno = int32(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) {
	var l *TypeList

	if t == nil {
		return
	}

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

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

	if t.Deferwidth != 0 {
		return
	}
	t.Deferwidth = 1

	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 {
		Fatal("defercheckwidth")
	}
	defercalc = 1
}

func resumecheckwidth() {
	var l *TypeList

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

	defercalc = 0
}

func typeinit() {
	var i int
	var etype int
	var sameas int
	var t *Type
	var s *Sym
	var s1 *Sym

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

	for i = 0; i < NTYPE; i++ {
		Simtype[i] = uint8(i)
	}

	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)

	dowidth(Types[TUNSAFEPTR])

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

	for i = TINT8; i <= TUINT64; i++ {
		Isint[i] = 1
	}
	Isint[TINT] = 1
	Isint[TUINT] = 1
	Isint[TUINTPTR] = 1

	Isfloat[TFLOAT32] = 1
	Isfloat[TFLOAT64] = 1

	Iscomplex[TCOMPLEX64] = 1
	Iscomplex[TCOMPLEX128] = 1

	Isptr[TPTR32] = 1
	Isptr[TPTR64] = 1

	isforw[TFORW] = 1

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

	/*
	 * initialize okfor
	 */
	for i = 0; i < NTYPE; i++ {
		if Isint[i] != 0 || i == TIDEAL {
			okforeq[i] = 1
			okforcmp[i] = 1
			okforarith[i] = 1
			okforadd[i] = 1
			okforand[i] = 1
			okforconst[i] = 1
			issimple[i] = 1
			Minintval[i] = new(Mpint)
			Maxintval[i] = new(Mpint)
		}

		if Isfloat[i] != 0 {
			okforeq[i] = 1
			okforcmp[i] = 1
			okforadd[i] = 1
			okforarith[i] = 1
			okforconst[i] = 1
			issimple[i] = 1
			minfltval[i] = new(Mpflt)
			maxfltval[i] = new(Mpflt)
		}

		if Iscomplex[i] != 0 {
			okforeq[i] = 1
			okforadd[i] = 1
			okforarith[i] = 1
			okforconst[i] = 1
			issimple[i] = 1
		}
	}

	issimple[TBOOL] = 1

	okforadd[TSTRING] = 1

	okforbool[TBOOL] = 1

	okforcap[TARRAY] = 1
	okforcap[TCHAN] = 1

	okforconst[TBOOL] = 1
	okforconst[TSTRING] = 1

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

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

	okforcmp[TSTRING] = 1

	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[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] = 1

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

	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] = uint8(Tptr)

	Simtype[TCHAN] = uint8(Tptr)
	Simtype[TFUNC] = uint8(Tptr)
	Simtype[TUNSAFEPTR] = uint8(Tptr)

	/* pick up the backend thearch.typedefs */
	for i = range Thearch.Typedefs {
		s = Lookup(Thearch.Typedefs[i].Name)
		s1 = Pkglookup(Thearch.Typedefs[i].Name, builtinpkg)

		etype = Thearch.Typedefs[i].Etype
		if etype < 0 || etype >= len(Types) {
			Fatal("typeinit: %s bad etype", s.Name)
		}
		sameas = Thearch.Typedefs[i].Sameas
		if sameas < 0 || sameas >= len(Types) {
			Fatal("typeinit: %s bad sameas", s.Name)
		}
		Simtype[etype] = uint8(sameas)
		minfltval[etype] = minfltval[sameas]
		maxfltval[etype] = maxfltval[sameas]
		Minintval[etype] = Minintval[sameas]
		Maxintval[etype] = Maxintval[sameas]

		t = Types[etype]
		if t != nil {
			Fatal("typeinit: %s already defined", s.Name)
		}

		t = typ(etype)
		t.Sym = s1

		dowidth(t)
		Types[etype] = t
		s1.Def = typenod(t)
	}

	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)
}

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

	w = 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 {
		Fatal("argsize too big")
	}
	return int(w)
}
