// Do not edit. Bootstrap copy of /Volumes/Android/buildbot/src/android/build-tools/out/obj/go/src/cmd/compile/internal/gc/align.go

//line /Volumes/Android/buildbot/src/android/build-tools/out/obj/go/src/cmd/compile/internal/gc/align.go:1
// 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 "bootstrap/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.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 {
		Fatal("dowidth without betypeinit")
	}

	if t == nil {
		return
	}

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

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

		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", 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 == 0 {
			Yyerror("invalid recursive type %v", t)
		}
		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", t) // probably [...]T
		}

	case TSTRUCT:
		if t.Funarg != 0 {
			Fatal("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 {
			Fatal("invalid alignment for %v", t)
		}
		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", t)
	}

	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
}

var itable *Type // distinguished *byte

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)
	t.Sym.Def.Name = new(Name)

	dowidth(Types[TUNSAFEPTR])

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

	for i := TINT8; i <= TUINT64; i++ {
		Isint[i] = 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 i := 0; i < NTYPE; i++ {
		if Isint[i] || i == TIDEAL {
			okforeq[i] = true
			okforcmp[i] = true
			okforarith[i] = true
			okforadd[i] = true
			okforand[i] = true
			okforconst[i] = true
			issimple[i] = true
			Minintval[i] = new(Mpint)
			Maxintval[i] = new(Mpint)
		}

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

		if Iscomplex[i] {
			okforeq[i] = true
			okforadd[i] = true
			okforarith[i] = true
			okforconst[i] = true
			issimple[i] = 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] = 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)
		s1.Def.Name = new(Name)
	}

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