// 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) {
	o := int32(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 {
	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 {
			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) {
	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 := int64(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 {
			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) {
	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() {
	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() {
	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

	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[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 */
	var s1 *Sym
	var etype int
	var sameas int
	var s *Sym
	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 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 {
		Fatal("argsize too big")
	}
	return int(w)
}
