github.com/rsc/tmp@v0.0.0-20240517235954-6deaab19748b/bootstrap/internal/gc/align.go (about)

     1  // Do not edit. Bootstrap copy of /Users/rsc/g/go/src/cmd/internal/gc/align.go
     2  
     3  // Copyright 2009 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  package gc
     8  
     9  import "rsc.io/tmp/bootstrap/internal/obj"
    10  
    11  /*
    12   * machine size and rounding
    13   * alignment is dictated around
    14   * the size of a pointer, set in betypeinit
    15   * (see ../6g/galign.c).
    16   */
    17  var defercalc int
    18  
    19  func Rnd(o int64, r int64) int64 {
    20  	if r < 1 || r > 8 || r&(r-1) != 0 {
    21  		Fatal("rnd %d", r)
    22  	}
    23  	return (o + r - 1) &^ (r - 1)
    24  }
    25  
    26  func offmod(t *Type) {
    27  	o := int32(0)
    28  	for f := t.Type; f != nil; f = f.Down {
    29  		if f.Etype != TFIELD {
    30  			Fatal("offmod: not TFIELD: %v", Tconv(f, obj.FmtLong))
    31  		}
    32  		f.Width = int64(o)
    33  		o += int32(Widthptr)
    34  		if int64(o) >= Thearch.MAXWIDTH {
    35  			Yyerror("interface too large")
    36  			o = int32(Widthptr)
    37  		}
    38  	}
    39  }
    40  
    41  func widstruct(errtype *Type, t *Type, o int64, flag int) int64 {
    42  	starto := o
    43  	maxalign := int32(flag)
    44  	if maxalign < 1 {
    45  		maxalign = 1
    46  	}
    47  	lastzero := int64(0)
    48  	var w int64
    49  	for f := t.Type; f != nil; f = f.Down {
    50  		if f.Etype != TFIELD {
    51  			Fatal("widstruct: not TFIELD: %v", Tconv(f, obj.FmtLong))
    52  		}
    53  		if f.Type == nil {
    54  			// broken field, just skip it so that other valid fields
    55  			// get a width.
    56  			continue
    57  		}
    58  
    59  		dowidth(f.Type)
    60  		if int32(f.Type.Align) > maxalign {
    61  			maxalign = int32(f.Type.Align)
    62  		}
    63  		if f.Type.Width < 0 {
    64  			Fatal("invalid width %d", f.Type.Width)
    65  		}
    66  		w = f.Type.Width
    67  		if f.Type.Align > 0 {
    68  			o = Rnd(o, int64(f.Type.Align))
    69  		}
    70  		f.Width = o // really offset for TFIELD
    71  		if f.Nname != nil {
    72  			// this same stackparam logic is in addrescapes
    73  			// in typecheck.c.  usually addrescapes runs after
    74  			// widstruct, in which case we could drop this,
    75  			// but function closure functions are the exception.
    76  			if f.Nname.Stackparam != nil {
    77  				f.Nname.Stackparam.Xoffset = o
    78  				f.Nname.Xoffset = 0
    79  			} else {
    80  				f.Nname.Xoffset = o
    81  			}
    82  		}
    83  
    84  		if w == 0 {
    85  			lastzero = o
    86  		}
    87  		o += w
    88  		if o >= Thearch.MAXWIDTH {
    89  			Yyerror("type %v too large", Tconv(errtype, obj.FmtLong))
    90  			o = 8 // small but nonzero
    91  		}
    92  	}
    93  
    94  	// For nonzero-sized structs which end in a zero-sized thing, we add
    95  	// an extra byte of padding to the type.  This padding ensures that
    96  	// taking the address of the zero-sized thing can't manufacture a
    97  	// pointer to the next object in the heap.  See issue 9401.
    98  	if flag == 1 && o > starto && o == lastzero {
    99  		o++
   100  	}
   101  
   102  	// final width is rounded
   103  	if flag != 0 {
   104  		o = Rnd(o, int64(maxalign))
   105  	}
   106  	t.Align = uint8(maxalign)
   107  
   108  	// type width only includes back to first field's offset
   109  	t.Width = o - starto
   110  
   111  	return o
   112  }
   113  
   114  func dowidth(t *Type) {
   115  	if Widthptr == 0 {
   116  		Fatal("dowidth without betypeinit")
   117  	}
   118  
   119  	if t == nil {
   120  		return
   121  	}
   122  
   123  	if t.Width > 0 {
   124  		return
   125  	}
   126  
   127  	if t.Width == -2 {
   128  		lno := int(lineno)
   129  		lineno = int32(t.Lineno)
   130  		if t.Broke == 0 {
   131  			t.Broke = 1
   132  			Yyerror("invalid recursive type %v", t)
   133  		}
   134  
   135  		t.Width = 0
   136  		lineno = int32(lno)
   137  		return
   138  	}
   139  
   140  	// break infinite recursion if the broken recursive type
   141  	// is referenced again
   142  	if t.Broke != 0 && t.Width == 0 {
   143  		return
   144  	}
   145  
   146  	// defer checkwidth calls until after we're done
   147  	defercalc++
   148  
   149  	lno := int(lineno)
   150  	lineno = int32(t.Lineno)
   151  	t.Width = -2
   152  	t.Align = 0
   153  
   154  	et := int32(t.Etype)
   155  	switch et {
   156  	case TFUNC, TCHAN, TMAP, TSTRING:
   157  		break
   158  
   159  		/* simtype == 0 during bootstrap */
   160  	default:
   161  		if Simtype[t.Etype] != 0 {
   162  			et = int32(Simtype[t.Etype])
   163  		}
   164  	}
   165  
   166  	w := int64(0)
   167  	switch et {
   168  	default:
   169  		Fatal("dowidth: unknown type: %v", t)
   170  
   171  		/* compiler-specific stuff */
   172  	case TINT8, TUINT8, TBOOL:
   173  		// bool is int8
   174  		w = 1
   175  
   176  	case TINT16, TUINT16:
   177  		w = 2
   178  
   179  	case TINT32, TUINT32, TFLOAT32:
   180  		w = 4
   181  
   182  	case TINT64, TUINT64, TFLOAT64, TCOMPLEX64:
   183  		w = 8
   184  		t.Align = uint8(Widthreg)
   185  
   186  	case TCOMPLEX128:
   187  		w = 16
   188  		t.Align = uint8(Widthreg)
   189  
   190  	case TPTR32:
   191  		w = 4
   192  		checkwidth(t.Type)
   193  
   194  	case TPTR64:
   195  		w = 8
   196  		checkwidth(t.Type)
   197  
   198  	case TUNSAFEPTR:
   199  		w = int64(Widthptr)
   200  
   201  	case TINTER: // implemented as 2 pointers
   202  		w = 2 * int64(Widthptr)
   203  
   204  		t.Align = uint8(Widthptr)
   205  		offmod(t)
   206  
   207  	case TCHAN: // implemented as pointer
   208  		w = int64(Widthptr)
   209  
   210  		checkwidth(t.Type)
   211  
   212  		// make fake type to check later to
   213  		// trigger channel argument check.
   214  		t1 := typ(TCHANARGS)
   215  
   216  		t1.Type = t
   217  		checkwidth(t1)
   218  
   219  	case TCHANARGS:
   220  		t1 := t.Type
   221  		dowidth(t.Type) // just in case
   222  		if t1.Type.Width >= 1<<16 {
   223  			Yyerror("channel element type too large (>64kB)")
   224  		}
   225  		t.Width = 1
   226  
   227  	case TMAP: // implemented as pointer
   228  		w = int64(Widthptr)
   229  
   230  		checkwidth(t.Type)
   231  		checkwidth(t.Down)
   232  
   233  	case TFORW: // should have been filled in
   234  		if t.Broke == 0 {
   235  			Yyerror("invalid recursive type %v", t)
   236  		}
   237  		w = 1 // anything will do
   238  
   239  		// dummy type; should be replaced before use.
   240  	case TANY:
   241  		if Debug['A'] == 0 {
   242  			Fatal("dowidth any")
   243  		}
   244  		w = 1 // anything will do
   245  
   246  	case TSTRING:
   247  		if sizeof_String == 0 {
   248  			Fatal("early dowidth string")
   249  		}
   250  		w = int64(sizeof_String)
   251  		t.Align = uint8(Widthptr)
   252  
   253  	case TARRAY:
   254  		if t.Type == nil {
   255  			break
   256  		}
   257  		if t.Bound >= 0 {
   258  			dowidth(t.Type)
   259  			if t.Type.Width != 0 {
   260  				cap := (uint64(Thearch.MAXWIDTH) - 1) / uint64(t.Type.Width)
   261  				if uint64(t.Bound) > cap {
   262  					Yyerror("type %v larger than address space", Tconv(t, obj.FmtLong))
   263  				}
   264  			}
   265  
   266  			w = t.Bound * t.Type.Width
   267  			t.Align = t.Type.Align
   268  		} else if t.Bound == -1 {
   269  			w = int64(sizeof_Array)
   270  			checkwidth(t.Type)
   271  			t.Align = uint8(Widthptr)
   272  		} else if t.Bound == -100 {
   273  			if t.Broke == 0 {
   274  				Yyerror("use of [...] array outside of array literal")
   275  				t.Broke = 1
   276  			}
   277  		} else {
   278  			Fatal("dowidth %v", t) // probably [...]T
   279  		}
   280  
   281  	case TSTRUCT:
   282  		if t.Funarg != 0 {
   283  			Fatal("dowidth fn struct %v", t)
   284  		}
   285  		w = widstruct(t, t, 0, 1)
   286  
   287  		// make fake type to check later to
   288  	// trigger function argument computation.
   289  	case TFUNC:
   290  		t1 := typ(TFUNCARGS)
   291  
   292  		t1.Type = t
   293  		checkwidth(t1)
   294  
   295  		// width of func type is pointer
   296  		w = int64(Widthptr)
   297  
   298  		// function is 3 cated structures;
   299  	// compute their widths as side-effect.
   300  	case TFUNCARGS:
   301  		t1 := t.Type
   302  
   303  		w = widstruct(t.Type, *getthis(t1), 0, 0)
   304  		w = widstruct(t.Type, *getinarg(t1), w, Widthreg)
   305  		w = widstruct(t.Type, *Getoutarg(t1), w, Widthreg)
   306  		t1.Argwid = w
   307  		if w%int64(Widthreg) != 0 {
   308  			Warn("bad type %v %d\n", t1, w)
   309  		}
   310  		t.Align = 1
   311  	}
   312  
   313  	if Widthptr == 4 && w != int64(int32(w)) {
   314  		Yyerror("type %v too large", t)
   315  	}
   316  
   317  	t.Width = w
   318  	if t.Align == 0 {
   319  		if w > 8 || w&(w-1) != 0 {
   320  			Fatal("invalid alignment for %v", t)
   321  		}
   322  		t.Align = uint8(w)
   323  	}
   324  
   325  	lineno = int32(lno)
   326  
   327  	if defercalc == 1 {
   328  		resumecheckwidth()
   329  	} else {
   330  		defercalc--
   331  	}
   332  }
   333  
   334  /*
   335   * when a type's width should be known, we call checkwidth
   336   * to compute it.  during a declaration like
   337   *
   338   *	type T *struct { next T }
   339   *
   340   * it is necessary to defer the calculation of the struct width
   341   * until after T has been initialized to be a pointer to that struct.
   342   * similarly, during import processing structs may be used
   343   * before their definition.  in those situations, calling
   344   * defercheckwidth() stops width calculations until
   345   * resumecheckwidth() is called, at which point all the
   346   * checkwidths that were deferred are executed.
   347   * dowidth should only be called when the type's size
   348   * is needed immediately.  checkwidth makes sure the
   349   * size is evaluated eventually.
   350   */
   351  type TypeList struct {
   352  	t    *Type
   353  	next *TypeList
   354  }
   355  
   356  var tlfree *TypeList
   357  
   358  var tlq *TypeList
   359  
   360  func checkwidth(t *Type) {
   361  	if t == nil {
   362  		return
   363  	}
   364  
   365  	// function arg structs should not be checked
   366  	// outside of the enclosing function.
   367  	if t.Funarg != 0 {
   368  		Fatal("checkwidth %v", t)
   369  	}
   370  
   371  	if defercalc == 0 {
   372  		dowidth(t)
   373  		return
   374  	}
   375  
   376  	if t.Deferwidth != 0 {
   377  		return
   378  	}
   379  	t.Deferwidth = 1
   380  
   381  	l := tlfree
   382  	if l != nil {
   383  		tlfree = l.next
   384  	} else {
   385  		l = new(TypeList)
   386  	}
   387  
   388  	l.t = t
   389  	l.next = tlq
   390  	tlq = l
   391  }
   392  
   393  func defercheckwidth() {
   394  	// we get out of sync on syntax errors, so don't be pedantic.
   395  	if defercalc != 0 && nerrors == 0 {
   396  		Fatal("defercheckwidth")
   397  	}
   398  	defercalc = 1
   399  }
   400  
   401  func resumecheckwidth() {
   402  	if defercalc == 0 {
   403  		Fatal("resumecheckwidth")
   404  	}
   405  	for l := tlq; l != nil; l = tlq {
   406  		l.t.Deferwidth = 0
   407  		tlq = l.next
   408  		dowidth(l.t)
   409  		l.next = tlfree
   410  		tlfree = l
   411  	}
   412  
   413  	defercalc = 0
   414  }
   415  
   416  var itable *Type // distinguished *byte
   417  
   418  func typeinit() {
   419  	if Widthptr == 0 {
   420  		Fatal("typeinit before betypeinit")
   421  	}
   422  
   423  	for i := 0; i < NTYPE; i++ {
   424  		Simtype[i] = uint8(i)
   425  	}
   426  
   427  	Types[TPTR32] = typ(TPTR32)
   428  	dowidth(Types[TPTR32])
   429  
   430  	Types[TPTR64] = typ(TPTR64)
   431  	dowidth(Types[TPTR64])
   432  
   433  	t := typ(TUNSAFEPTR)
   434  	Types[TUNSAFEPTR] = t
   435  	t.Sym = Pkglookup("Pointer", unsafepkg)
   436  	t.Sym.Def = typenod(t)
   437  
   438  	dowidth(Types[TUNSAFEPTR])
   439  
   440  	Tptr = TPTR32
   441  	if Widthptr == 8 {
   442  		Tptr = TPTR64
   443  	}
   444  
   445  	for i := TINT8; i <= TUINT64; i++ {
   446  		Isint[i] = true
   447  	}
   448  	Isint[TINT] = true
   449  	Isint[TUINT] = true
   450  	Isint[TUINTPTR] = true
   451  
   452  	Isfloat[TFLOAT32] = true
   453  	Isfloat[TFLOAT64] = true
   454  
   455  	Iscomplex[TCOMPLEX64] = true
   456  	Iscomplex[TCOMPLEX128] = true
   457  
   458  	Isptr[TPTR32] = true
   459  	Isptr[TPTR64] = true
   460  
   461  	isforw[TFORW] = true
   462  
   463  	Issigned[TINT] = true
   464  	Issigned[TINT8] = true
   465  	Issigned[TINT16] = true
   466  	Issigned[TINT32] = true
   467  	Issigned[TINT64] = true
   468  
   469  	/*
   470  	 * initialize okfor
   471  	 */
   472  	for i := 0; i < NTYPE; i++ {
   473  		if Isint[i] || i == TIDEAL {
   474  			okforeq[i] = true
   475  			okforcmp[i] = true
   476  			okforarith[i] = true
   477  			okforadd[i] = true
   478  			okforand[i] = true
   479  			okforconst[i] = true
   480  			issimple[i] = true
   481  			Minintval[i] = new(Mpint)
   482  			Maxintval[i] = new(Mpint)
   483  		}
   484  
   485  		if Isfloat[i] {
   486  			okforeq[i] = true
   487  			okforcmp[i] = true
   488  			okforadd[i] = true
   489  			okforarith[i] = true
   490  			okforconst[i] = true
   491  			issimple[i] = true
   492  			minfltval[i] = newMpflt()
   493  			maxfltval[i] = newMpflt()
   494  		}
   495  
   496  		if Iscomplex[i] {
   497  			okforeq[i] = true
   498  			okforadd[i] = true
   499  			okforarith[i] = true
   500  			okforconst[i] = true
   501  			issimple[i] = true
   502  		}
   503  	}
   504  
   505  	issimple[TBOOL] = true
   506  
   507  	okforadd[TSTRING] = true
   508  
   509  	okforbool[TBOOL] = true
   510  
   511  	okforcap[TARRAY] = true
   512  	okforcap[TCHAN] = true
   513  
   514  	okforconst[TBOOL] = true
   515  	okforconst[TSTRING] = true
   516  
   517  	okforlen[TARRAY] = true
   518  	okforlen[TCHAN] = true
   519  	okforlen[TMAP] = true
   520  	okforlen[TSTRING] = true
   521  
   522  	okforeq[TPTR32] = true
   523  	okforeq[TPTR64] = true
   524  	okforeq[TUNSAFEPTR] = true
   525  	okforeq[TINTER] = true
   526  	okforeq[TCHAN] = true
   527  	okforeq[TSTRING] = true
   528  	okforeq[TBOOL] = true
   529  	okforeq[TMAP] = true    // nil only; refined in typecheck
   530  	okforeq[TFUNC] = true   // nil only; refined in typecheck
   531  	okforeq[TARRAY] = true  // nil slice only; refined in typecheck
   532  	okforeq[TSTRUCT] = true // it's complicated; refined in typecheck
   533  
   534  	okforcmp[TSTRING] = true
   535  
   536  	var i int
   537  	for i = 0; i < len(okfor); i++ {
   538  		okfor[i] = okfornone[:]
   539  	}
   540  
   541  	// binary
   542  	okfor[OADD] = okforadd[:]
   543  
   544  	okfor[OAND] = okforand[:]
   545  	okfor[OANDAND] = okforbool[:]
   546  	okfor[OANDNOT] = okforand[:]
   547  	okfor[ODIV] = okforarith[:]
   548  	okfor[OEQ] = okforeq[:]
   549  	okfor[OGE] = okforcmp[:]
   550  	okfor[OGT] = okforcmp[:]
   551  	okfor[OLE] = okforcmp[:]
   552  	okfor[OLT] = okforcmp[:]
   553  	okfor[OMOD] = okforand[:]
   554  	okfor[OMUL] = okforarith[:]
   555  	okfor[ONE] = okforeq[:]
   556  	okfor[OOR] = okforand[:]
   557  	okfor[OOROR] = okforbool[:]
   558  	okfor[OSUB] = okforarith[:]
   559  	okfor[OXOR] = okforand[:]
   560  	okfor[OLSH] = okforand[:]
   561  	okfor[ORSH] = okforand[:]
   562  
   563  	// unary
   564  	okfor[OCOM] = okforand[:]
   565  
   566  	okfor[OMINUS] = okforarith[:]
   567  	okfor[ONOT] = okforbool[:]
   568  	okfor[OPLUS] = okforarith[:]
   569  
   570  	// special
   571  	okfor[OCAP] = okforcap[:]
   572  
   573  	okfor[OLEN] = okforlen[:]
   574  
   575  	// comparison
   576  	iscmp[OLT] = true
   577  
   578  	iscmp[OGT] = true
   579  	iscmp[OGE] = true
   580  	iscmp[OLE] = true
   581  	iscmp[OEQ] = true
   582  	iscmp[ONE] = true
   583  
   584  	mpatofix(Maxintval[TINT8], "0x7f")
   585  	mpatofix(Minintval[TINT8], "-0x80")
   586  	mpatofix(Maxintval[TINT16], "0x7fff")
   587  	mpatofix(Minintval[TINT16], "-0x8000")
   588  	mpatofix(Maxintval[TINT32], "0x7fffffff")
   589  	mpatofix(Minintval[TINT32], "-0x80000000")
   590  	mpatofix(Maxintval[TINT64], "0x7fffffffffffffff")
   591  	mpatofix(Minintval[TINT64], "-0x8000000000000000")
   592  
   593  	mpatofix(Maxintval[TUINT8], "0xff")
   594  	mpatofix(Maxintval[TUINT16], "0xffff")
   595  	mpatofix(Maxintval[TUINT32], "0xffffffff")
   596  	mpatofix(Maxintval[TUINT64], "0xffffffffffffffff")
   597  
   598  	/* f is valid float if min < f < max.  (min and max are not themselves valid.) */
   599  	mpatoflt(maxfltval[TFLOAT32], "33554431p103") /* 2^24-1 p (127-23) + 1/2 ulp*/
   600  	mpatoflt(minfltval[TFLOAT32], "-33554431p103")
   601  	mpatoflt(maxfltval[TFLOAT64], "18014398509481983p970") /* 2^53-1 p (1023-52) + 1/2 ulp */
   602  	mpatoflt(minfltval[TFLOAT64], "-18014398509481983p970")
   603  
   604  	maxfltval[TCOMPLEX64] = maxfltval[TFLOAT32]
   605  	minfltval[TCOMPLEX64] = minfltval[TFLOAT32]
   606  	maxfltval[TCOMPLEX128] = maxfltval[TFLOAT64]
   607  	minfltval[TCOMPLEX128] = minfltval[TFLOAT64]
   608  
   609  	/* for walk to use in error messages */
   610  	Types[TFUNC] = functype(nil, nil, nil)
   611  
   612  	/* types used in front end */
   613  	// types[TNIL] got set early in lexinit
   614  	Types[TIDEAL] = typ(TIDEAL)
   615  
   616  	Types[TINTER] = typ(TINTER)
   617  
   618  	/* simple aliases */
   619  	Simtype[TMAP] = uint8(Tptr)
   620  
   621  	Simtype[TCHAN] = uint8(Tptr)
   622  	Simtype[TFUNC] = uint8(Tptr)
   623  	Simtype[TUNSAFEPTR] = uint8(Tptr)
   624  
   625  	/* pick up the backend thearch.typedefs */
   626  	var s1 *Sym
   627  	var etype int
   628  	var sameas int
   629  	var s *Sym
   630  	for i = range Thearch.Typedefs {
   631  		s = Lookup(Thearch.Typedefs[i].Name)
   632  		s1 = Pkglookup(Thearch.Typedefs[i].Name, builtinpkg)
   633  
   634  		etype = Thearch.Typedefs[i].Etype
   635  		if etype < 0 || etype >= len(Types) {
   636  			Fatal("typeinit: %s bad etype", s.Name)
   637  		}
   638  		sameas = Thearch.Typedefs[i].Sameas
   639  		if sameas < 0 || sameas >= len(Types) {
   640  			Fatal("typeinit: %s bad sameas", s.Name)
   641  		}
   642  		Simtype[etype] = uint8(sameas)
   643  		minfltval[etype] = minfltval[sameas]
   644  		maxfltval[etype] = maxfltval[sameas]
   645  		Minintval[etype] = Minintval[sameas]
   646  		Maxintval[etype] = Maxintval[sameas]
   647  
   648  		t = Types[etype]
   649  		if t != nil {
   650  			Fatal("typeinit: %s already defined", s.Name)
   651  		}
   652  
   653  		t = typ(etype)
   654  		t.Sym = s1
   655  
   656  		dowidth(t)
   657  		Types[etype] = t
   658  		s1.Def = typenod(t)
   659  	}
   660  
   661  	Array_array = int(Rnd(0, int64(Widthptr)))
   662  	Array_nel = int(Rnd(int64(Array_array)+int64(Widthptr), int64(Widthint)))
   663  	Array_cap = int(Rnd(int64(Array_nel)+int64(Widthint), int64(Widthint)))
   664  	sizeof_Array = int(Rnd(int64(Array_cap)+int64(Widthint), int64(Widthptr)))
   665  
   666  	// string is same as slice wo the cap
   667  	sizeof_String = int(Rnd(int64(Array_nel)+int64(Widthint), int64(Widthptr)))
   668  
   669  	dowidth(Types[TSTRING])
   670  	dowidth(idealstring)
   671  
   672  	itable = typ(Tptr)
   673  	itable.Type = Types[TUINT8]
   674  }
   675  
   676  /*
   677   * compute total size of f's in/out arguments.
   678   */
   679  func Argsize(t *Type) int {
   680  	var save Iter
   681  	var x int64
   682  
   683  	w := int64(0)
   684  
   685  	fp := Structfirst(&save, Getoutarg(t))
   686  	for fp != nil {
   687  		x = fp.Width + fp.Type.Width
   688  		if x > w {
   689  			w = x
   690  		}
   691  		fp = structnext(&save)
   692  	}
   693  
   694  	fp = funcfirst(&save, t)
   695  	for fp != nil {
   696  		x = fp.Width + fp.Type.Width
   697  		if x > w {
   698  			w = x
   699  		}
   700  		fp = funcnext(&save)
   701  	}
   702  
   703  	w = (w + int64(Widthptr) - 1) &^ (int64(Widthptr) - 1)
   704  	if int64(int(w)) != w {
   705  		Fatal("argsize too big")
   706  	}
   707  	return int(w)
   708  }