The Go Programming Language

Text file src/cmd/8g/gsubr.c

     1	// Derived from Inferno utils/8c/txt.c
     2	// http://code.google.com/p/inferno-os/source/browse/utils/8c/txt.c
     3	//
     4	//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     5	//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6	//	Portions Copyright © 1997-1999 Vita Nuova Limited
     7	//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8	//	Portions Copyright © 2004,2006 Bruce Ellis
     9	//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10	//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11	//	Portions Copyright © 2009 The Go Authors.  All rights reserved.
    12	//
    13	// Permission is hereby granted, free of charge, to any person obtaining a copy
    14	// of this software and associated documentation files (the "Software"), to deal
    15	// in the Software without restriction, including without limitation the rights
    16	// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17	// copies of the Software, and to permit persons to whom the Software is
    18	// furnished to do so, subject to the following conditions:
    19	//
    20	// The above copyright notice and this permission notice shall be included in
    21	// all copies or substantial portions of the Software.
    22	//
    23	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24	// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25	// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26	// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27	// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28	// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29	// THE SOFTWARE.
    30	
    31	#include "gg.h"
    32	
    33	// TODO(rsc): Can make this bigger if we move
    34	// the text segment up higher in 8l for all GOOS.
    35	uint32 unmappedzero = 4096;
    36	
    37	#define	CASE(a,b)	(((a)<<16)|((b)<<0))
    38	
    39	void
    40	clearp(Prog *p)
    41	{
    42		p->as = AEND;
    43		p->from.type = D_NONE;
    44		p->from.index = D_NONE;
    45		p->to.type = D_NONE;
    46		p->to.index = D_NONE;
    47		p->loc = pcloc;
    48		pcloc++;
    49	}
    50	
    51	/*
    52	 * generate and return proc with p->as = as,
    53	 * linked into program.  pc is next instruction.
    54	 */
    55	Prog*
    56	prog(int as)
    57	{
    58		Prog *p;
    59	
    60		p = pc;
    61		pc = mal(sizeof(*pc));
    62	
    63		clearp(pc);
    64	
    65		if(lineno == 0) {
    66			if(debug['K'])
    67				warn("prog: line 0");
    68		}
    69	
    70		p->as = as;
    71		p->lineno = lineno;
    72		p->link = pc;
    73		return p;
    74	}
    75	
    76	/*
    77	 * generate a branch.
    78	 * t is ignored.
    79	 */
    80	Prog*
    81	gbranch(int as, Type *t)
    82	{
    83		Prog *p;
    84	
    85		p = prog(as);
    86		p->to.type = D_BRANCH;
    87		p->to.branch = P;
    88		return p;
    89	}
    90	
    91	/*
    92	 * patch previous branch to jump to to.
    93	 */
    94	void
    95	patch(Prog *p, Prog *to)
    96	{
    97		if(p->to.type != D_BRANCH)
    98			fatal("patch: not a branch");
    99		p->to.branch = to;
   100		p->to.offset = to->loc;
   101	}
   102	
   103	Prog*
   104	unpatch(Prog *p)
   105	{
   106		Prog *q;
   107	
   108		if(p->to.type != D_BRANCH)
   109			fatal("unpatch: not a branch");
   110		q = p->to.branch;
   111		p->to.branch = P;
   112		p->to.offset = 0;
   113		return q;
   114	}
   115	
   116	/*
   117	 * start a new Prog list.
   118	 */
   119	Plist*
   120	newplist(void)
   121	{
   122		Plist *pl;
   123	
   124		pl = mal(sizeof(*pl));
   125		if(plist == nil)
   126			plist = pl;
   127		else
   128			plast->link = pl;
   129		plast = pl;
   130	
   131		pc = mal(sizeof(*pc));
   132		clearp(pc);
   133		pl->firstpc = pc;
   134	
   135		return pl;
   136	}
   137	
   138	void
   139	clearstk(void)
   140	{
   141		Plist *pl;
   142		Prog *p1, *p2;
   143		Node sp, di, cx, con, ax;
   144	
   145		if(plast->firstpc->to.offset <= 0)
   146			return;
   147	
   148		// reestablish context for inserting code
   149		// at beginning of function.
   150		pl = plast;
   151		p1 = pl->firstpc;
   152		p2 = p1->link;
   153		pc = mal(sizeof(*pc));
   154		clearp(pc);
   155		p1->link = pc;
   156		
   157		// zero stack frame
   158		nodreg(&sp, types[tptr], D_SP);
   159		nodreg(&di, types[tptr], D_DI);
   160		nodreg(&cx, types[TUINT32], D_CX);
   161		nodconst(&con, types[TUINT32], p1->to.offset / widthptr);
   162		gins(ACLD, N, N);
   163		gins(AMOVL, &sp, &di);
   164		gins(AMOVL, &con, &cx);
   165		nodconst(&con, types[TUINT32], 0);
   166		nodreg(&ax, types[TUINT32], D_AX);
   167		gins(AMOVL, &con, &ax);
   168		gins(AREP, N, N);
   169		gins(ASTOSL, N, N);
   170	
   171		// continue with original code.
   172		gins(ANOP, N, N)->link = p2;
   173		pc = P;
   174	}	
   175	
   176	void
   177	gused(Node *n)
   178	{
   179		gins(ANOP, n, N);	// used
   180	}
   181	
   182	Prog*
   183	gjmp(Prog *to)
   184	{
   185		Prog *p;
   186	
   187		p = gbranch(AJMP, T);
   188		if(to != P)
   189			patch(p, to);
   190		return p;
   191	}
   192	
   193	void
   194	ggloblnod(Node *nam, int32 width)
   195	{
   196		Prog *p;
   197	
   198		p = gins(AGLOBL, nam, N);
   199		p->lineno = nam->lineno;
   200		p->to.sym = S;
   201		p->to.type = D_CONST;
   202		p->to.offset = width;
   203		if(nam->readonly)
   204			p->from.scale = RODATA;
   205	}
   206	
   207	void
   208	ggloblsym(Sym *s, int32 width, int dupok)
   209	{
   210		Prog *p;
   211	
   212		p = gins(AGLOBL, N, N);
   213		p->from.type = D_EXTERN;
   214		p->from.index = D_NONE;
   215		p->from.sym = s;
   216		p->to.type = D_CONST;
   217		p->to.index = D_NONE;
   218		p->to.offset = width;
   219		if(dupok)
   220			p->from.scale = DUPOK;
   221		p->from.scale |= RODATA;
   222	}
   223	
   224	int
   225	isfat(Type *t)
   226	{
   227		if(t != T)
   228		switch(t->etype) {
   229		case TSTRUCT:
   230		case TARRAY:
   231		case TSTRING:
   232		case TINTER:	// maybe remove later
   233			return 1;
   234		}
   235		return 0;
   236	}
   237	
   238	/*
   239	 * naddr of func generates code for address of func.
   240	 * if using opcode that can take address implicitly,
   241	 * call afunclit to fix up the argument.
   242	 */
   243	void
   244	afunclit(Addr *a)
   245	{
   246		if(a->type == D_ADDR && a->index == D_EXTERN) {
   247			a->type = D_EXTERN;
   248			a->index = D_NONE;
   249		}
   250	}
   251	
   252	/*
   253	 * return Axxx for Oxxx on type t.
   254	 */
   255	int
   256	optoas(int op, Type *t)
   257	{
   258		int a;
   259	
   260		if(t == T)
   261			fatal("optoas: t is nil");
   262	
   263		a = AGOK;
   264		switch(CASE(op, simtype[t->etype])) {
   265		default:
   266			fatal("optoas: no entry %O-%T", op, t);
   267			break;
   268	
   269		case CASE(OADDR, TPTR32):
   270			a = ALEAL;
   271			break;
   272	
   273		case CASE(OEQ, TBOOL):
   274		case CASE(OEQ, TINT8):
   275		case CASE(OEQ, TUINT8):
   276		case CASE(OEQ, TINT16):
   277		case CASE(OEQ, TUINT16):
   278		case CASE(OEQ, TINT32):
   279		case CASE(OEQ, TUINT32):
   280		case CASE(OEQ, TINT64):
   281		case CASE(OEQ, TUINT64):
   282		case CASE(OEQ, TPTR32):
   283		case CASE(OEQ, TPTR64):
   284		case CASE(OEQ, TFLOAT32):
   285		case CASE(OEQ, TFLOAT64):
   286			a = AJEQ;
   287			break;
   288	
   289		case CASE(ONE, TBOOL):
   290		case CASE(ONE, TINT8):
   291		case CASE(ONE, TUINT8):
   292		case CASE(ONE, TINT16):
   293		case CASE(ONE, TUINT16):
   294		case CASE(ONE, TINT32):
   295		case CASE(ONE, TUINT32):
   296		case CASE(ONE, TINT64):
   297		case CASE(ONE, TUINT64):
   298		case CASE(ONE, TPTR32):
   299		case CASE(ONE, TPTR64):
   300		case CASE(ONE, TFLOAT32):
   301		case CASE(ONE, TFLOAT64):
   302			a = AJNE;
   303			break;
   304	
   305		case CASE(OLT, TINT8):
   306		case CASE(OLT, TINT16):
   307		case CASE(OLT, TINT32):
   308		case CASE(OLT, TINT64):
   309			a = AJLT;
   310			break;
   311	
   312		case CASE(OLT, TUINT8):
   313		case CASE(OLT, TUINT16):
   314		case CASE(OLT, TUINT32):
   315		case CASE(OLT, TUINT64):
   316			a = AJCS;
   317			break;
   318	
   319		case CASE(OLE, TINT8):
   320		case CASE(OLE, TINT16):
   321		case CASE(OLE, TINT32):
   322		case CASE(OLE, TINT64):
   323			a = AJLE;
   324			break;
   325	
   326		case CASE(OLE, TUINT8):
   327		case CASE(OLE, TUINT16):
   328		case CASE(OLE, TUINT32):
   329		case CASE(OLE, TUINT64):
   330			a = AJLS;
   331			break;
   332	
   333		case CASE(OGT, TINT8):
   334		case CASE(OGT, TINT16):
   335		case CASE(OGT, TINT32):
   336		case CASE(OGT, TINT64):
   337			a = AJGT;
   338			break;
   339	
   340		case CASE(OGT, TUINT8):
   341		case CASE(OGT, TUINT16):
   342		case CASE(OGT, TUINT32):
   343		case CASE(OGT, TUINT64):
   344		case CASE(OLT, TFLOAT32):
   345		case CASE(OLT, TFLOAT64):
   346			a = AJHI;
   347			break;
   348	
   349		case CASE(OGE, TINT8):
   350		case CASE(OGE, TINT16):
   351		case CASE(OGE, TINT32):
   352		case CASE(OGE, TINT64):
   353			a = AJGE;
   354			break;
   355	
   356		case CASE(OGE, TUINT8):
   357		case CASE(OGE, TUINT16):
   358		case CASE(OGE, TUINT32):
   359		case CASE(OGE, TUINT64):
   360		case CASE(OLE, TFLOAT32):
   361		case CASE(OLE, TFLOAT64):
   362			a = AJCC;
   363			break;
   364	
   365		case CASE(OCMP, TBOOL):
   366		case CASE(OCMP, TINT8):
   367		case CASE(OCMP, TUINT8):
   368			a = ACMPB;
   369			break;
   370	
   371		case CASE(OCMP, TINT16):
   372		case CASE(OCMP, TUINT16):
   373			a = ACMPW;
   374			break;
   375	
   376		case CASE(OCMP, TINT32):
   377		case CASE(OCMP, TUINT32):
   378		case CASE(OCMP, TPTR32):
   379			a = ACMPL;
   380			break;
   381	
   382		case CASE(OAS, TBOOL):
   383		case CASE(OAS, TINT8):
   384		case CASE(OAS, TUINT8):
   385			a = AMOVB;
   386			break;
   387	
   388		case CASE(OAS, TINT16):
   389		case CASE(OAS, TUINT16):
   390			a = AMOVW;
   391			break;
   392	
   393		case CASE(OAS, TINT32):
   394		case CASE(OAS, TUINT32):
   395		case CASE(OAS, TPTR32):
   396			a = AMOVL;
   397			break;
   398	
   399		case CASE(OADD, TINT8):
   400		case CASE(OADD, TUINT8):
   401			a = AADDB;
   402			break;
   403	
   404		case CASE(OADD, TINT16):
   405		case CASE(OADD, TUINT16):
   406			a = AADDW;
   407			break;
   408	
   409		case CASE(OADD, TINT32):
   410		case CASE(OADD, TUINT32):
   411		case CASE(OADD, TPTR32):
   412			a = AADDL;
   413			break;
   414	
   415		case CASE(OSUB, TINT8):
   416		case CASE(OSUB, TUINT8):
   417			a = ASUBB;
   418			break;
   419	
   420		case CASE(OSUB, TINT16):
   421		case CASE(OSUB, TUINT16):
   422			a = ASUBW;
   423			break;
   424	
   425		case CASE(OSUB, TINT32):
   426		case CASE(OSUB, TUINT32):
   427		case CASE(OSUB, TPTR32):
   428			a = ASUBL;
   429			break;
   430	
   431		case CASE(OINC, TINT8):
   432		case CASE(OINC, TUINT8):
   433			a = AINCB;
   434			break;
   435	
   436		case CASE(OINC, TINT16):
   437		case CASE(OINC, TUINT16):
   438			a = AINCW;
   439			break;
   440	
   441		case CASE(OINC, TINT32):
   442		case CASE(OINC, TUINT32):
   443		case CASE(OINC, TPTR32):
   444			a = AINCL;
   445			break;
   446	
   447		case CASE(ODEC, TINT8):
   448		case CASE(ODEC, TUINT8):
   449			a = ADECB;
   450			break;
   451	
   452		case CASE(ODEC, TINT16):
   453		case CASE(ODEC, TUINT16):
   454			a = ADECW;
   455			break;
   456	
   457		case CASE(ODEC, TINT32):
   458		case CASE(ODEC, TUINT32):
   459		case CASE(ODEC, TPTR32):
   460			a = ADECL;
   461			break;
   462	
   463		case CASE(OCOM, TINT8):
   464		case CASE(OCOM, TUINT8):
   465			a = ANOTB;
   466			break;
   467	
   468		case CASE(OCOM, TINT16):
   469		case CASE(OCOM, TUINT16):
   470			a = ANOTW;
   471			break;
   472	
   473		case CASE(OCOM, TINT32):
   474		case CASE(OCOM, TUINT32):
   475		case CASE(OCOM, TPTR32):
   476			a = ANOTL;
   477			break;
   478	
   479		case CASE(OMINUS, TINT8):
   480		case CASE(OMINUS, TUINT8):
   481			a = ANEGB;
   482			break;
   483	
   484		case CASE(OMINUS, TINT16):
   485		case CASE(OMINUS, TUINT16):
   486			a = ANEGW;
   487			break;
   488	
   489		case CASE(OMINUS, TINT32):
   490		case CASE(OMINUS, TUINT32):
   491		case CASE(OMINUS, TPTR32):
   492			a = ANEGL;
   493			break;
   494	
   495		case CASE(OAND, TINT8):
   496		case CASE(OAND, TUINT8):
   497			a = AANDB;
   498			break;
   499	
   500		case CASE(OAND, TINT16):
   501		case CASE(OAND, TUINT16):
   502			a = AANDW;
   503			break;
   504	
   505		case CASE(OAND, TINT32):
   506		case CASE(OAND, TUINT32):
   507		case CASE(OAND, TPTR32):
   508			a = AANDL;
   509			break;
   510	
   511		case CASE(OOR, TINT8):
   512		case CASE(OOR, TUINT8):
   513			a = AORB;
   514			break;
   515	
   516		case CASE(OOR, TINT16):
   517		case CASE(OOR, TUINT16):
   518			a = AORW;
   519			break;
   520	
   521		case CASE(OOR, TINT32):
   522		case CASE(OOR, TUINT32):
   523		case CASE(OOR, TPTR32):
   524			a = AORL;
   525			break;
   526	
   527		case CASE(OXOR, TINT8):
   528		case CASE(OXOR, TUINT8):
   529			a = AXORB;
   530			break;
   531	
   532		case CASE(OXOR, TINT16):
   533		case CASE(OXOR, TUINT16):
   534			a = AXORW;
   535			break;
   536	
   537		case CASE(OXOR, TINT32):
   538		case CASE(OXOR, TUINT32):
   539		case CASE(OXOR, TPTR32):
   540			a = AXORL;
   541			break;
   542	
   543		case CASE(OLSH, TINT8):
   544		case CASE(OLSH, TUINT8):
   545			a = ASHLB;
   546			break;
   547	
   548		case CASE(OLSH, TINT16):
   549		case CASE(OLSH, TUINT16):
   550			a = ASHLW;
   551			break;
   552	
   553		case CASE(OLSH, TINT32):
   554		case CASE(OLSH, TUINT32):
   555		case CASE(OLSH, TPTR32):
   556			a = ASHLL;
   557			break;
   558	
   559		case CASE(ORSH, TUINT8):
   560			a = ASHRB;
   561			break;
   562	
   563		case CASE(ORSH, TUINT16):
   564			a = ASHRW;
   565			break;
   566	
   567		case CASE(ORSH, TUINT32):
   568		case CASE(ORSH, TPTR32):
   569			a = ASHRL;
   570			break;
   571	
   572		case CASE(ORSH, TINT8):
   573			a = ASARB;
   574			break;
   575	
   576		case CASE(ORSH, TINT16):
   577			a = ASARW;
   578			break;
   579	
   580		case CASE(ORSH, TINT32):
   581			a = ASARL;
   582			break;
   583	
   584		case CASE(OMUL, TINT8):
   585		case CASE(OMUL, TUINT8):
   586			a = AIMULB;
   587			break;
   588	
   589		case CASE(OMUL, TINT16):
   590		case CASE(OMUL, TUINT16):
   591			a = AIMULW;
   592			break;
   593	
   594		case CASE(OMUL, TINT32):
   595		case CASE(OMUL, TUINT32):
   596		case CASE(OMUL, TPTR32):
   597			a = AIMULL;
   598			break;
   599	
   600		case CASE(ODIV, TINT8):
   601		case CASE(OMOD, TINT8):
   602			a = AIDIVB;
   603			break;
   604	
   605		case CASE(ODIV, TUINT8):
   606		case CASE(OMOD, TUINT8):
   607			a = ADIVB;
   608			break;
   609	
   610		case CASE(ODIV, TINT16):
   611		case CASE(OMOD, TINT16):
   612			a = AIDIVW;
   613			break;
   614	
   615		case CASE(ODIV, TUINT16):
   616		case CASE(OMOD, TUINT16):
   617			a = ADIVW;
   618			break;
   619	
   620		case CASE(ODIV, TINT32):
   621		case CASE(OMOD, TINT32):
   622			a = AIDIVL;
   623			break;
   624	
   625		case CASE(ODIV, TUINT32):
   626		case CASE(ODIV, TPTR32):
   627		case CASE(OMOD, TUINT32):
   628		case CASE(OMOD, TPTR32):
   629			a = ADIVL;
   630			break;
   631	
   632		case CASE(OEXTEND, TINT16):
   633			a = ACWD;
   634			break;
   635	
   636		case CASE(OEXTEND, TINT32):
   637			a = ACDQ;
   638			break;
   639		}
   640		return a;
   641	}
   642	
   643	#define FCASE(a, b, c)  (((a)<<16)|((b)<<8)|(c))
   644	int
   645	foptoas(int op, Type *t, int flg)
   646	{
   647		int et;
   648	
   649		et = simtype[t->etype];
   650	
   651		// If we need Fpop, it means we're working on
   652		// two different floating-point registers, not memory.
   653		// There the instruction only has a float64 form.
   654		if(flg & Fpop)
   655			et = TFLOAT64;
   656	
   657		// clear Frev if unneeded
   658		switch(op) {
   659		case OADD:
   660		case OMUL:
   661			flg &= ~Frev;
   662			break;
   663		}
   664	
   665		switch(FCASE(op, et, flg)) {
   666		case FCASE(OADD, TFLOAT32, 0):
   667			return AFADDF;
   668		case FCASE(OADD, TFLOAT64, 0):
   669			return AFADDD;
   670		case FCASE(OADD, TFLOAT64, Fpop):
   671			return AFADDDP;
   672	
   673		case FCASE(OSUB, TFLOAT32, 0):
   674			return AFSUBF;
   675		case FCASE(OSUB, TFLOAT32, Frev):
   676			return AFSUBRF;
   677	
   678		case FCASE(OSUB, TFLOAT64, 0):
   679			return AFSUBD;
   680		case FCASE(OSUB, TFLOAT64, Frev):
   681			return AFSUBRD;
   682		case FCASE(OSUB, TFLOAT64, Fpop):
   683			return AFSUBDP;
   684		case FCASE(OSUB, TFLOAT64, Fpop|Frev):
   685			return AFSUBRDP;
   686	
   687		case FCASE(OMUL, TFLOAT32, 0):
   688			return AFMULF;
   689		case FCASE(OMUL, TFLOAT64, 0):
   690			return AFMULD;
   691		case FCASE(OMUL, TFLOAT64, Fpop):
   692			return AFMULDP;
   693	
   694		case FCASE(ODIV, TFLOAT32, 0):
   695			return AFDIVF;
   696		case FCASE(ODIV, TFLOAT32, Frev):
   697			return AFDIVRF;
   698	
   699		case FCASE(ODIV, TFLOAT64, 0):
   700			return AFDIVD;
   701		case FCASE(ODIV, TFLOAT64, Frev):
   702			return AFDIVRD;
   703		case FCASE(ODIV, TFLOAT64, Fpop):
   704			return AFDIVDP;
   705		case FCASE(ODIV, TFLOAT64, Fpop|Frev):
   706			return AFDIVRDP;
   707	
   708		case FCASE(OCMP, TFLOAT32, 0):
   709			return AFCOMF;
   710		case FCASE(OCMP, TFLOAT32, Fpop):
   711			return AFCOMFP;
   712		case FCASE(OCMP, TFLOAT64, 0):
   713			return AFCOMD;
   714		case FCASE(OCMP, TFLOAT64, Fpop):
   715			return AFCOMDP;
   716		case FCASE(OCMP, TFLOAT64, Fpop2):
   717			return AFCOMDPP;
   718		
   719		case FCASE(OMINUS, TFLOAT32, 0):
   720			return AFCHS;
   721		case FCASE(OMINUS, TFLOAT64, 0):
   722			return AFCHS;
   723		}
   724	
   725		fatal("foptoas %O %T %#x", op, t, flg);
   726		return 0;
   727	}
   728	
   729	static	int	resvd[] =
   730	{
   731	//	D_DI,	// for movstring
   732	//	D_SI,	// for movstring
   733	
   734		D_AX,	// for divide
   735		D_CX,	// for shift
   736		D_DX,	// for divide
   737		D_SP,	// for stack
   738	
   739		D_BL,	// because D_BX can be allocated
   740		D_BH,
   741	};
   742	
   743	void
   744	ginit(void)
   745	{
   746		int i;
   747	
   748		for(i=0; i<nelem(reg); i++)
   749			reg[i] = 1;
   750		for(i=D_AL; i<=D_DI; i++)
   751			reg[i] = 0;
   752		for(i=0; i<nelem(resvd); i++)
   753			reg[resvd[i]]++;
   754	}
   755	
   756	ulong regpc[D_NONE];
   757	
   758	void
   759	gclean(void)
   760	{
   761		int i;
   762	
   763		for(i=0; i<nelem(resvd); i++)
   764			reg[resvd[i]]--;
   765	
   766		for(i=D_AL; i<=D_DI; i++)
   767			if(reg[i])
   768				yyerror("reg %R left allocated at %ux", i, regpc[i]);
   769	}
   770	
   771	int32
   772	anyregalloc(void)
   773	{
   774		int i, j;
   775	
   776		for(i=D_AL; i<=D_DI; i++) {
   777			if(reg[i] == 0)
   778				goto ok;
   779			for(j=0; j<nelem(resvd); j++)
   780				if(resvd[j] == i)
   781					goto ok;
   782			return 1;
   783		ok:;
   784		}
   785		return 0;
   786	}
   787	
   788	/*
   789	 * allocate register of type t, leave in n.
   790	 * if o != N, o is desired fixed register.
   791	 * caller must regfree(n).
   792	 */
   793	void
   794	regalloc(Node *n, Type *t, Node *o)
   795	{
   796		int i, et;
   797	
   798		if(t == T)
   799			fatal("regalloc: t nil");
   800		et = simtype[t->etype];
   801	
   802		switch(et) {
   803		case TINT8:
   804		case TUINT8:
   805		case TINT16:
   806		case TUINT16:
   807		case TINT32:
   808		case TUINT32:
   809		case TINT64:
   810		case TUINT64:
   811		case TPTR32:
   812		case TPTR64:
   813		case TBOOL:
   814			if(o != N && o->op == OREGISTER) {
   815				i = o->val.u.reg;
   816				if(i >= D_AX && i <= D_DI)
   817					goto out;
   818			}
   819			for(i=D_AX; i<=D_DI; i++)
   820				if(reg[i] == 0)
   821					goto out;
   822	
   823			fprint(2, "registers allocated at\n");
   824			for(i=D_AX; i<=D_DI; i++)
   825				fprint(2, "\t%R\t%#ux\n", i, regpc[i]);
   826			yyerror("out of fixed registers");
   827			goto err;
   828	
   829		case TFLOAT32:
   830		case TFLOAT64:
   831			i = D_F0;
   832			goto out;
   833		}
   834		yyerror("regalloc: unknown type %T", t);
   835		i = 0;
   836	
   837	err:
   838		nodreg(n, t, 0);
   839		return;
   840	
   841	out:
   842		if (i == D_SP)
   843			print("alloc SP\n");
   844		if(reg[i] == 0) {
   845			regpc[i] = (ulong)__builtin_return_address(0);
   846			if(i == D_AX || i == D_CX || i == D_DX || i == D_SP) {
   847				dump("regalloc-o", o);
   848				fatal("regalloc %R", i);
   849			}
   850		}
   851		reg[i]++;
   852		nodreg(n, t, i);
   853	}
   854	
   855	void
   856	regfree(Node *n)
   857	{
   858		int i;
   859		
   860		if(n->op == ONAME)
   861			return;
   862		if(n->op != OREGISTER && n->op != OINDREG)
   863			fatal("regfree: not a register");
   864		i = n->val.u.reg;
   865		if(i == D_SP)
   866			return;
   867		if(i < 0 || i >= sizeof(reg))
   868			fatal("regfree: reg out of range");
   869		if(reg[i] <= 0)
   870			fatal("regfree: reg not allocated");
   871		reg[i]--;
   872		if(reg[i] == 0 && (i == D_AX || i == D_CX || i == D_DX || i == D_SP))
   873			fatal("regfree %R", i);
   874	}
   875	
   876	/*
   877	 * initialize n to be register r of type t.
   878	 */
   879	void
   880	nodreg(Node *n, Type *t, int r)
   881	{
   882		if(t == T)
   883			fatal("nodreg: t nil");
   884	
   885		memset(n, 0, sizeof(*n));
   886		n->op = OREGISTER;
   887		n->addable = 1;
   888		ullmancalc(n);
   889		n->val.u.reg = r;
   890		n->type = t;
   891	}
   892	
   893	/*
   894	 * initialize n to be indirect of register r; n is type t.
   895	 */
   896	void
   897	nodindreg(Node *n, Type *t, int r)
   898	{
   899		nodreg(n, t, r);
   900		n->op = OINDREG;
   901	}
   902	
   903	Node*
   904	nodarg(Type *t, int fp)
   905	{
   906		Node *n;
   907		Type *first;
   908		Iter savet;
   909	
   910		// entire argument struct, not just one arg
   911		switch(t->etype) {
   912		default:
   913			fatal("nodarg %T", t);
   914	
   915		case TSTRUCT:
   916			if(!t->funarg)
   917				fatal("nodarg: TSTRUCT but not funarg");
   918			n = nod(ONAME, N, N);
   919			n->sym = lookup(".args");
   920			n->type = t;
   921			first = structfirst(&savet, &t);
   922			if(first == nil)
   923				fatal("nodarg: bad struct");
   924			if(first->width == BADWIDTH)
   925				fatal("nodarg: offset not computed for %T", t);
   926			n->xoffset = first->width;
   927			n->addable = 1;
   928			break;
   929	
   930		case TFIELD:
   931			n = nod(ONAME, N, N);
   932			n->type = t->type;
   933			n->sym = t->sym;
   934			if(t->width == BADWIDTH)
   935				fatal("nodarg: offset not computed for %T", t);
   936			n->xoffset = t->width;
   937			n->addable = 1;
   938			break;
   939		}
   940	
   941		switch(fp) {
   942		default:
   943			fatal("nodarg %T %d", t, fp);
   944	
   945		case 0:		// output arg
   946			n->op = OINDREG;
   947			n->val.u.reg = D_SP;
   948			break;
   949	
   950		case 1:		// input arg
   951			n->class = PPARAM;
   952			break;
   953		}
   954	
   955		n->typecheck = 1;
   956		return n;
   957	}
   958	
   959	/*
   960	 * generate
   961	 *	as $c, reg
   962	 */
   963	void
   964	gconreg(int as, vlong c, int reg)
   965	{
   966		Node n1, n2;
   967	
   968		nodconst(&n1, types[TINT64], c);
   969		nodreg(&n2, types[TINT64], reg);
   970		gins(as, &n1, &n2);
   971	}
   972	
   973	/*
   974	 * swap node contents
   975	 */
   976	void
   977	nswap(Node *a, Node *b)
   978	{
   979		Node t;
   980	
   981		t = *a;
   982		*a = *b;
   983		*b = t;
   984	}
   985	
   986	/*
   987	 * return constant i node.
   988	 * overwritten by next call, but useful in calls to gins.
   989	 */
   990	Node*
   991	ncon(uint32 i)
   992	{
   993		static Node n;
   994	
   995		if(n.type == T)
   996			nodconst(&n, types[TUINT32], 0);
   997		mpmovecfix(n.val.u.xval, i);
   998		return &n;
   999	}
  1000	
  1001	/*
  1002	 * Is this node a memory operand?
  1003	 */
  1004	int
  1005	ismem(Node *n)
  1006	{
  1007		switch(n->op) {
  1008		case OLEN:
  1009		case OCAP:
  1010		case OINDREG:
  1011		case ONAME:
  1012		case OPARAM:
  1013			return 1;
  1014		}
  1015		return 0;
  1016	}
  1017	
  1018	Node sclean[10];
  1019	int nsclean;
  1020	
  1021	/*
  1022	 * n is a 64-bit value.  fill in lo and hi to refer to its 32-bit halves.
  1023	 */
  1024	void
  1025	split64(Node *n, Node *lo, Node *hi)
  1026	{
  1027		Node n1;
  1028		int64 i;
  1029	
  1030		if(!is64(n->type))
  1031			fatal("split64 %T", n->type);
  1032	
  1033		sclean[nsclean].op = OEMPTY;
  1034		if(nsclean >= nelem(sclean))
  1035			fatal("split64 clean");
  1036		nsclean++;
  1037		switch(n->op) {
  1038		default:
  1039			if(!dotaddable(n, &n1)) {
  1040				igen(n, &n1, N);
  1041				sclean[nsclean-1] = n1;
  1042			}
  1043			n = &n1;
  1044			goto common;
  1045		case ONAME:
  1046			if(n->class == PPARAMREF) {
  1047				cgen(n->heapaddr, &n1);
  1048				sclean[nsclean-1] = n1;
  1049				// fall through.
  1050				n = &n1;
  1051			}
  1052			goto common;
  1053		case OINDREG:
  1054		common:
  1055			*lo = *n;
  1056			*hi = *n;
  1057			lo->type = types[TUINT32];
  1058			if(n->type->etype == TINT64)
  1059				hi->type = types[TINT32];
  1060			else
  1061				hi->type = types[TUINT32];
  1062			hi->xoffset += 4;
  1063			break;
  1064	
  1065		case OLITERAL:
  1066			convconst(&n1, n->type, &n->val);
  1067			i = mpgetfix(n1.val.u.xval);
  1068			nodconst(lo, types[TUINT32], (uint32)i);
  1069			i >>= 32;
  1070			if(n->type->etype == TINT64)
  1071				nodconst(hi, types[TINT32], (int32)i);
  1072			else
  1073				nodconst(hi, types[TUINT32], (uint32)i);
  1074			break;
  1075		}
  1076	}
  1077	
  1078	void
  1079	splitclean(void)
  1080	{
  1081		if(nsclean <= 0)
  1082			fatal("splitclean");
  1083		nsclean--;
  1084		if(sclean[nsclean].op != OEMPTY)
  1085			regfree(&sclean[nsclean]);
  1086	}
  1087	
  1088	/*
  1089	 * set up nodes representing fp constants
  1090	 */
  1091	Node zerof;
  1092	Node two64f;
  1093	Node two63f;
  1094	
  1095	void
  1096	bignodes(void)
  1097	{
  1098		static int did;
  1099	
  1100		if(did)
  1101			return;
  1102		did = 1;
  1103	
  1104		two64f = *ncon(0);
  1105		two64f.type = types[TFLOAT64];
  1106		two64f.val.ctype = CTFLT;
  1107		two64f.val.u.fval = mal(sizeof *two64f.val.u.fval);
  1108		mpmovecflt(two64f.val.u.fval, 18446744073709551616.);
  1109	
  1110		two63f = two64f;
  1111		two63f.val.u.fval = mal(sizeof *two63f.val.u.fval);
  1112		mpmovecflt(two63f.val.u.fval, 9223372036854775808.);
  1113	
  1114		zerof = two64f;
  1115		zerof.val.u.fval = mal(sizeof *zerof.val.u.fval);
  1116		mpmovecflt(zerof.val.u.fval, 0);
  1117	}
  1118	
  1119	void
  1120	memname(Node *n, Type *t)
  1121	{
  1122		tempname(n, t);
  1123		strcpy(namebuf, n->sym->name);
  1124		namebuf[0] = '.';	// keep optimizer from registerizing
  1125		n->sym = lookup(namebuf);
  1126	}
  1127	
  1128	void
  1129	gmove(Node *f, Node *t)
  1130	{
  1131		int a, ft, tt;
  1132		Type *cvt;
  1133		Node r1, r2, t1, t2, flo, fhi, tlo, thi, con, f0, f1, ax, dx, cx;
  1134		Prog *p1, *p2, *p3;
  1135	
  1136		if(debug['M'])
  1137			print("gmove %N -> %N\n", f, t);
  1138	
  1139		ft = simsimtype(f->type);
  1140		tt = simsimtype(t->type);
  1141		cvt = t->type;
  1142	
  1143		if(iscomplex[ft] || iscomplex[tt]) {
  1144			complexmove(f, t);
  1145			return;
  1146		}
  1147	
  1148		// cannot have two integer memory operands;
  1149		// except 64-bit, which always copies via registers anyway.
  1150		if(isint[ft] && isint[tt] && !is64(f->type) && !is64(t->type) && ismem(f) && ismem(t))
  1151			goto hard;
  1152	
  1153		// convert constant to desired type
  1154		if(f->op == OLITERAL) {
  1155			if(tt == TFLOAT32)
  1156				convconst(&con, types[TFLOAT64], &f->val);
  1157			else
  1158				convconst(&con, t->type, &f->val);
  1159			f = &con;
  1160			ft = simsimtype(con.type);
  1161	
  1162			// some constants can't move directly to memory.
  1163			if(ismem(t)) {
  1164				// float constants come from memory.
  1165				if(isfloat[tt])
  1166					goto hard;
  1167			}
  1168		}
  1169	
  1170		// value -> value copy, only one memory operand.
  1171		// figure out the instruction to use.
  1172		// break out of switch for one-instruction gins.
  1173		// goto rdst for "destination must be register".
  1174		// goto hard for "convert to cvt type first".
  1175		// otherwise handle and return.
  1176	
  1177		switch(CASE(ft, tt)) {
  1178		default:
  1179			goto fatal;
  1180	
  1181		/*
  1182		 * integer copy and truncate
  1183		 */
  1184		case CASE(TINT8, TINT8):	// same size
  1185		case CASE(TINT8, TUINT8):
  1186		case CASE(TUINT8, TINT8):
  1187		case CASE(TUINT8, TUINT8):
  1188			a = AMOVB;
  1189			break;
  1190	
  1191		case CASE(TINT16, TINT8):	// truncate
  1192		case CASE(TUINT16, TINT8):
  1193		case CASE(TINT32, TINT8):
  1194		case CASE(TUINT32, TINT8):
  1195		case CASE(TINT16, TUINT8):
  1196		case CASE(TUINT16, TUINT8):
  1197		case CASE(TINT32, TUINT8):
  1198		case CASE(TUINT32, TUINT8):
  1199			a = AMOVB;
  1200			goto rsrc;
  1201	
  1202		case CASE(TINT64, TINT8):	// truncate low word
  1203		case CASE(TUINT64, TINT8):
  1204		case CASE(TINT64, TUINT8):
  1205		case CASE(TUINT64, TUINT8):
  1206			split64(f, &flo, &fhi);
  1207			nodreg(&r1, t->type, D_AX);
  1208			gmove(&flo, &r1);
  1209			gins(AMOVB, &r1, t);
  1210			splitclean();
  1211			return;
  1212	
  1213		case CASE(TINT16, TINT16):	// same size
  1214		case CASE(TINT16, TUINT16):
  1215		case CASE(TUINT16, TINT16):
  1216		case CASE(TUINT16, TUINT16):
  1217			a = AMOVW;
  1218			break;
  1219	
  1220		case CASE(TINT32, TINT16):	// truncate
  1221		case CASE(TUINT32, TINT16):
  1222		case CASE(TINT32, TUINT16):
  1223		case CASE(TUINT32, TUINT16):
  1224			a = AMOVW;
  1225			goto rsrc;
  1226	
  1227		case CASE(TINT64, TINT16):	// truncate low word
  1228		case CASE(TUINT64, TINT16):
  1229		case CASE(TINT64, TUINT16):
  1230		case CASE(TUINT64, TUINT16):
  1231			split64(f, &flo, &fhi);
  1232			nodreg(&r1, t->type, D_AX);
  1233			gmove(&flo, &r1);
  1234			gins(AMOVW, &r1, t);
  1235			splitclean();
  1236			return;
  1237	
  1238		case CASE(TINT32, TINT32):	// same size
  1239		case CASE(TINT32, TUINT32):
  1240		case CASE(TUINT32, TINT32):
  1241		case CASE(TUINT32, TUINT32):
  1242			a = AMOVL;
  1243			break;
  1244	
  1245		case CASE(TINT64, TINT32):	// truncate
  1246		case CASE(TUINT64, TINT32):
  1247		case CASE(TINT64, TUINT32):
  1248		case CASE(TUINT64, TUINT32):
  1249			split64(f, &flo, &fhi);
  1250			nodreg(&r1, t->type, D_AX);
  1251			gmove(&flo, &r1);
  1252			gins(AMOVL, &r1, t);
  1253			splitclean();
  1254			return;
  1255	
  1256		case CASE(TINT64, TINT64):	// same size
  1257		case CASE(TINT64, TUINT64):
  1258		case CASE(TUINT64, TINT64):
  1259		case CASE(TUINT64, TUINT64):
  1260			split64(f, &flo, &fhi);
  1261			split64(t, &tlo, &thi);
  1262			if(f->op == OLITERAL) {
  1263				gins(AMOVL, &flo, &tlo);
  1264				gins(AMOVL, &fhi, &thi);
  1265			} else {
  1266				nodreg(&r1, t->type, D_AX);
  1267				nodreg(&r2, t->type, D_DX);
  1268				gins(AMOVL, &flo, &r1);
  1269				gins(AMOVL, &fhi, &r2);
  1270				gins(AMOVL, &r1, &tlo);
  1271				gins(AMOVL, &r2, &thi);
  1272			}
  1273			splitclean();
  1274			splitclean();
  1275			return;
  1276	
  1277		/*
  1278		 * integer up-conversions
  1279		 */
  1280		case CASE(TINT8, TINT16):	// sign extend int8
  1281		case CASE(TINT8, TUINT16):
  1282			a = AMOVBWSX;
  1283			goto rdst;
  1284		case CASE(TINT8, TINT32):
  1285		case CASE(TINT8, TUINT32):
  1286			a = AMOVBLSX;
  1287			goto rdst;
  1288		case CASE(TINT8, TINT64):	// convert via int32
  1289		case CASE(TINT8, TUINT64):
  1290			cvt = types[TINT32];
  1291			goto hard;
  1292	
  1293		case CASE(TUINT8, TINT16):	// zero extend uint8
  1294		case CASE(TUINT8, TUINT16):
  1295			a = AMOVBWZX;
  1296			goto rdst;
  1297		case CASE(TUINT8, TINT32):
  1298		case CASE(TUINT8, TUINT32):
  1299			a = AMOVBLZX;
  1300			goto rdst;
  1301		case CASE(TUINT8, TINT64):	// convert via uint32
  1302		case CASE(TUINT8, TUINT64):
  1303			cvt = types[TUINT32];
  1304			goto hard;
  1305	
  1306		case CASE(TINT16, TINT32):	// sign extend int16
  1307		case CASE(TINT16, TUINT32):
  1308			a = AMOVWLSX;
  1309			goto rdst;
  1310		case CASE(TINT16, TINT64):	// convert via int32
  1311		case CASE(TINT16, TUINT64):
  1312			cvt = types[TINT32];
  1313			goto hard;
  1314	
  1315		case CASE(TUINT16, TINT32):	// zero extend uint16
  1316		case CASE(TUINT16, TUINT32):
  1317			a = AMOVWLZX;
  1318			goto rdst;
  1319		case CASE(TUINT16, TINT64):	// convert via uint32
  1320		case CASE(TUINT16, TUINT64):
  1321			cvt = types[TUINT32];
  1322			goto hard;
  1323	
  1324		case CASE(TINT32, TINT64):	// sign extend int32
  1325		case CASE(TINT32, TUINT64):
  1326			split64(t, &tlo, &thi);
  1327			nodreg(&flo, tlo.type, D_AX);
  1328			nodreg(&fhi, thi.type, D_DX);
  1329			gmove(f, &flo);
  1330			gins(ACDQ, N, N);
  1331			gins(AMOVL, &flo, &tlo);
  1332			gins(AMOVL, &fhi, &thi);
  1333			splitclean();
  1334			return;
  1335	
  1336		case CASE(TUINT32, TINT64):	// zero extend uint32
  1337		case CASE(TUINT32, TUINT64):
  1338			split64(t, &tlo, &thi);
  1339			gmove(f, &tlo);
  1340			gins(AMOVL, ncon(0), &thi);
  1341			splitclean();
  1342			return;
  1343	
  1344		/*
  1345		* float to integer
  1346		*/
  1347		case CASE(TFLOAT32, TINT16):
  1348		case CASE(TFLOAT32, TINT32):
  1349		case CASE(TFLOAT32, TINT64):
  1350		case CASE(TFLOAT64, TINT16):
  1351		case CASE(TFLOAT64, TINT32):
  1352		case CASE(TFLOAT64, TINT64):
  1353			if(t->op == OREGISTER)
  1354				goto hardmem;
  1355			nodreg(&r1, types[ft], D_F0);
  1356			if(f->op != OREGISTER) {
  1357				if(ft == TFLOAT32)
  1358					gins(AFMOVF, f, &r1);
  1359				else
  1360					gins(AFMOVD, f, &r1);
  1361			}
  1362	
  1363			// set round to zero mode during conversion
  1364			memname(&t1, types[TUINT16]);
  1365			memname(&t2, types[TUINT16]);
  1366			gins(AFSTCW, N, &t1);
  1367			gins(AMOVW, ncon(0xf7f), &t2);
  1368			gins(AFLDCW, &t2, N);
  1369			if(tt == TINT16)
  1370				gins(AFMOVWP, &r1, t);
  1371			else if(tt == TINT32)
  1372				gins(AFMOVLP, &r1, t);
  1373			else
  1374				gins(AFMOVVP, &r1, t);
  1375			gins(AFLDCW, &t1, N);
  1376			return;
  1377	
  1378		case CASE(TFLOAT32, TINT8):
  1379		case CASE(TFLOAT32, TUINT16):
  1380		case CASE(TFLOAT32, TUINT8):
  1381		case CASE(TFLOAT64, TINT8):
  1382		case CASE(TFLOAT64, TUINT16):
  1383		case CASE(TFLOAT64, TUINT8):
  1384			// convert via int32.
  1385			tempname(&t1, types[TINT32]);
  1386			gmove(f, &t1);
  1387			switch(tt) {
  1388			default:
  1389				fatal("gmove %T", t);
  1390			case TINT8:
  1391				gins(ACMPL, &t1, ncon(-0x80));
  1392				p1 = gbranch(optoas(OLT, types[TINT32]), T);
  1393				gins(ACMPL, &t1, ncon(0x7f));
  1394				p2 = gbranch(optoas(OGT, types[TINT32]), T);
  1395				p3 = gbranch(AJMP, T);
  1396				patch(p1, pc);
  1397				patch(p2, pc);
  1398				gmove(ncon(-0x80), &t1);
  1399				patch(p3, pc);
  1400				gmove(&t1, t);
  1401				break;
  1402			case TUINT8:
  1403				gins(ATESTL, ncon(0xffffff00), &t1);
  1404				p1 = gbranch(AJEQ, T);
  1405				gins(AMOVL, ncon(0), &t1);
  1406				patch(p1, pc);
  1407				gmove(&t1, t);
  1408				break;
  1409			case TUINT16:
  1410				gins(ATESTL, ncon(0xffff0000), &t1);
  1411				p1 = gbranch(AJEQ, T);
  1412				gins(AMOVL, ncon(0), &t1);
  1413				patch(p1, pc);
  1414				gmove(&t1, t);
  1415				break;
  1416			}
  1417			return;
  1418	
  1419		case CASE(TFLOAT32, TUINT32):
  1420		case CASE(TFLOAT64, TUINT32):
  1421			// convert via int64.
  1422			tempname(&t1, types[TINT64]);
  1423			gmove(f, &t1);
  1424			split64(&t1, &tlo, &thi);
  1425			gins(ACMPL, &thi, ncon(0));
  1426			p1 = gbranch(AJEQ, T);
  1427			gins(AMOVL, ncon(0), &tlo);
  1428			patch(p1, pc);
  1429			gmove(&tlo, t);
  1430			splitclean();
  1431			return;
  1432	
  1433		case CASE(TFLOAT32, TUINT64):
  1434		case CASE(TFLOAT64, TUINT64):
  1435			bignodes();
  1436			nodreg(&f0, types[ft], D_F0);
  1437			nodreg(&f1, types[ft], D_F0 + 1);
  1438			nodreg(&ax, types[TUINT16], D_AX);
  1439	
  1440			gmove(f, &f0);
  1441	
  1442			// if 0 > v { answer = 0 }
  1443			gmove(&zerof, &f0);
  1444			gins(AFUCOMIP, &f0, &f1);
  1445			p1 = gbranch(optoas(OGT, types[tt]), T);
  1446			// if 1<<64 <= v { answer = 0 too }
  1447			gmove(&two64f, &f0);
  1448			gins(AFUCOMIP, &f0, &f1);
  1449			p2 = gbranch(optoas(OGT, types[tt]), T);
  1450			patch(p1, pc);
  1451			gins(AFMOVVP, &f0, t);	// don't care about t, but will pop the stack
  1452			split64(t, &tlo, &thi);
  1453			gins(AMOVL, ncon(0), &tlo);
  1454			gins(AMOVL, ncon(0), &thi);
  1455			splitclean();
  1456			p1 = gbranch(AJMP, T);
  1457			patch(p2, pc);
  1458	
  1459			// in range; algorithm is:
  1460			//	if small enough, use native float64 -> int64 conversion.
  1461			//	otherwise, subtract 2^63, convert, and add it back.
  1462	
  1463			// set round to zero mode during conversion
  1464			memname(&t1, types[TUINT16]);
  1465			memname(&t2, types[TUINT16]);
  1466			gins(AFSTCW, N, &t1);
  1467			gins(AMOVW, ncon(0xf7f), &t2);
  1468			gins(AFLDCW, &t2, N);
  1469	
  1470			// actual work
  1471			gmove(&two63f, &f0);
  1472			gins(AFUCOMIP, &f0, &f1);
  1473			p2 = gbranch(optoas(OLE, types[tt]), T);
  1474			gins(AFMOVVP, &f0, t);
  1475			p3 = gbranch(AJMP, T);
  1476			patch(p2, pc);
  1477			gmove(&two63f, &f0);
  1478			gins(AFSUBDP, &f0, &f1);
  1479			gins(AFMOVVP, &f0, t);
  1480			split64(t, &tlo, &thi);
  1481			gins(AXORL, ncon(0x80000000), &thi);	// + 2^63
  1482			patch(p3, pc);
  1483			splitclean();
  1484			// restore rounding mode
  1485			gins(AFLDCW, &t1, N);
  1486	
  1487			patch(p1, pc);
  1488			return;
  1489	
  1490		/*
  1491		 * integer to float
  1492		 */
  1493		case CASE(TINT16, TFLOAT32):
  1494		case CASE(TINT16, TFLOAT64):
  1495		case CASE(TINT32, TFLOAT32):
  1496		case CASE(TINT32, TFLOAT64):
  1497		case CASE(TINT64, TFLOAT32):
  1498		case CASE(TINT64, TFLOAT64):
  1499			if(t->op != OREGISTER)
  1500				goto hard;
  1501			if(f->op == OREGISTER) {
  1502				cvt = f->type;
  1503				goto hardmem;
  1504			}
  1505			switch(ft) {
  1506			case TINT16:
  1507				a = AFMOVW;
  1508				break;
  1509			case TINT32:
  1510				a = AFMOVL;
  1511				break;
  1512			default:
  1513				a = AFMOVV;
  1514				break;
  1515			}
  1516			break;
  1517	
  1518		case CASE(TINT8, TFLOAT32):
  1519		case CASE(TINT8, TFLOAT64):
  1520		case CASE(TUINT16, TFLOAT32):
  1521		case CASE(TUINT16, TFLOAT64):
  1522		case CASE(TUINT8, TFLOAT32):
  1523		case CASE(TUINT8, TFLOAT64):
  1524			// convert via int32 memory
  1525			cvt = types[TINT32];
  1526			goto hardmem;
  1527	
  1528		case CASE(TUINT32, TFLOAT32):
  1529		case CASE(TUINT32, TFLOAT64):
  1530			// convert via int64 memory
  1531			cvt = types[TINT64];
  1532			goto hardmem;
  1533	
  1534		case CASE(TUINT64, TFLOAT32):
  1535		case CASE(TUINT64, TFLOAT64):
  1536			// algorithm is:
  1537			//	if small enough, use native int64 -> uint64 conversion.
  1538			//	otherwise, halve (rounding to odd?), convert, and double.
  1539			nodreg(&ax, types[TUINT32], D_AX);
  1540			nodreg(&dx, types[TUINT32], D_DX);
  1541			nodreg(&cx, types[TUINT32], D_CX);
  1542			tempname(&t1, f->type);
  1543			split64(&t1, &tlo, &thi);
  1544			gmove(f, &t1);
  1545			gins(ACMPL, &thi, ncon(0));
  1546			p1 = gbranch(AJLT, T);
  1547			// native
  1548			t1.type = types[TINT64];
  1549			gmove(&t1, t);
  1550			p2 = gbranch(AJMP, T);
  1551			// simulated
  1552			patch(p1, pc);
  1553			gmove(&tlo, &ax);
  1554			gmove(&thi, &dx);
  1555			p1 = gins(ASHRL, ncon(1), &ax);
  1556			p1->from.index = D_DX;	// double-width shift DX -> AX
  1557			p1->from.scale = 0;
  1558			gins(ASETCC, N, &cx);
  1559			gins(AORB, &cx, &ax);
  1560			gins(ASHRL, ncon(1), &dx);
  1561			gmove(&dx, &thi);
  1562			gmove(&ax, &tlo);
  1563			nodreg(&r1, types[tt], D_F0);
  1564			nodreg(&r2, types[tt], D_F0 + 1);
  1565			gmove(&t1, &r1);	// t1.type is TINT64 now, set above
  1566			gins(AFMOVD, &r1, &r1);
  1567			gins(AFADDDP, &r1, &r2);
  1568			gmove(&r1, t);
  1569			patch(p2, pc);
  1570			splitclean();
  1571			return;
  1572	
  1573		/*
  1574		 * float to float
  1575		 */
  1576		case CASE(TFLOAT32, TFLOAT32):
  1577		case CASE(TFLOAT64, TFLOAT64):
  1578			// The way the code generator uses floating-point
  1579			// registers, a move from F0 to F0 is intended as a no-op.
  1580			// On the x86, it's not: it pushes a second copy of F0
  1581			// on the floating point stack.  So toss it away here.
  1582			// Also, F0 is the *only* register we ever evaluate
  1583			// into, so we should only see register/register as F0/F0.
  1584			if(ismem(f) && ismem(t))
  1585				goto hard;
  1586			if(f->op == OREGISTER && t->op == OREGISTER) {
  1587				if(f->val.u.reg != D_F0 || t->val.u.reg != D_F0)
  1588					goto fatal;
  1589				return;
  1590			}
  1591			a = AFMOVF;
  1592			if(ft == TFLOAT64)
  1593				a = AFMOVD;
  1594			if(ismem(t)) {
  1595				if(f->op != OREGISTER || f->val.u.reg != D_F0)
  1596					fatal("gmove %N", f);
  1597				a = AFMOVFP;
  1598				if(ft == TFLOAT64)
  1599					a = AFMOVDP;
  1600			}
  1601			break;
  1602	
  1603		case CASE(TFLOAT32, TFLOAT64):
  1604			if(ismem(f) && ismem(t))
  1605				goto hard;
  1606			if(f->op == OREGISTER && t->op == OREGISTER) {
  1607				if(f->val.u.reg != D_F0 || t->val.u.reg != D_F0)
  1608					goto fatal;
  1609				return;
  1610			}
  1611			if(f->op == OREGISTER)
  1612				gins(AFMOVDP, f, t);
  1613			else
  1614				gins(AFMOVF, f, t);
  1615			return;
  1616	
  1617		case CASE(TFLOAT64, TFLOAT32):
  1618			if(ismem(f) && ismem(t))
  1619				goto hard;
  1620			if(f->op == OREGISTER && t->op == OREGISTER) {
  1621				tempname(&r1, types[TFLOAT32]);
  1622				gins(AFMOVFP, f, &r1);
  1623				gins(AFMOVF, &r1, t);
  1624				return;
  1625			}
  1626			if(f->op == OREGISTER)
  1627				gins(AFMOVFP, f, t);
  1628			else
  1629				gins(AFMOVD, f, t);
  1630			return;
  1631		}
  1632	
  1633		gins(a, f, t);
  1634		return;
  1635	
  1636	rsrc:
  1637		// requires register source
  1638		regalloc(&r1, f->type, t);
  1639		gmove(f, &r1);
  1640		gins(a, &r1, t);
  1641		regfree(&r1);
  1642		return;
  1643	
  1644	rdst:
  1645		// requires register destination
  1646		regalloc(&r1, t->type, t);
  1647		gins(a, f, &r1);
  1648		gmove(&r1, t);
  1649		regfree(&r1);
  1650		return;
  1651	
  1652	hard:
  1653		// requires register intermediate
  1654		regalloc(&r1, cvt, t);
  1655		gmove(f, &r1);
  1656		gmove(&r1, t);
  1657		regfree(&r1);
  1658		return;
  1659	
  1660	hardmem:
  1661		// requires memory intermediate
  1662		tempname(&r1, cvt);
  1663		gmove(f, &r1);
  1664		gmove(&r1, t);
  1665		return;
  1666	
  1667	fatal:
  1668		// should not happen
  1669		fatal("gmove %N -> %N", f, t);
  1670	}
  1671	
  1672	int
  1673	samaddr(Node *f, Node *t)
  1674	{
  1675	
  1676		if(f->op != t->op)
  1677			return 0;
  1678	
  1679		switch(f->op) {
  1680		case OREGISTER:
  1681			if(f->val.u.reg != t->val.u.reg)
  1682				break;
  1683			return 1;
  1684		}
  1685		return 0;
  1686	}
  1687	/*
  1688	 * generate one instruction:
  1689	 *	as f, t
  1690	 */
  1691	Prog*
  1692	gins(int as, Node *f, Node *t)
  1693	{
  1694		Prog *p;
  1695		Addr af, at;
  1696		int w;
  1697	
  1698		if(as == AFMOVF && f && f->op == OREGISTER && t && t->op == OREGISTER)
  1699			fatal("gins MOVF reg, reg");
  1700	
  1701		switch(as) {
  1702		case AMOVB:
  1703		case AMOVW:
  1704		case AMOVL:
  1705			if(f != N && t != N && samaddr(f, t))
  1706				return nil;
  1707		}
  1708	
  1709		memset(&af, 0, sizeof af);
  1710		memset(&at, 0, sizeof at);
  1711		if(f != N)
  1712			naddr(f, &af, 1);
  1713		if(t != N)
  1714			naddr(t, &at, 1);
  1715		p = prog(as);
  1716		if(f != N)
  1717			p->from = af;
  1718		if(t != N)
  1719			p->to = at;
  1720		if(debug['g'])
  1721			print("%P\n", p);
  1722	
  1723		w = 0;
  1724		switch(as) {
  1725		case AMOVB:
  1726			w = 1;
  1727			break;
  1728		case AMOVW:
  1729			w = 2;
  1730			break;
  1731		case AMOVL:
  1732			w = 4;
  1733			break;
  1734		}
  1735	
  1736		if(1 && w != 0 && f != N && (af.width > w || at.width > w)) {
  1737			dump("bad width from:", f);
  1738			dump("bad width to:", t);
  1739			fatal("bad width: %P (%d, %d)\n", p, af.width, at.width);
  1740		}
  1741	
  1742		return p;
  1743	}
  1744	
  1745	static void
  1746	checkoffset(Addr *a, int canemitcode)
  1747	{
  1748		Prog *p;
  1749	
  1750		if(a->offset < unmappedzero)
  1751			return;
  1752		if(!canemitcode)
  1753			fatal("checkoffset %#x, cannot emit code", a->offset);
  1754	
  1755		// cannot rely on unmapped nil page at 0 to catch
  1756		// reference with large offset.  instead, emit explicit
  1757		// test of 0(reg).
  1758		p = gins(ATESTB, nodintconst(0), N);
  1759		p->to = *a;
  1760		p->to.offset = 0;
  1761	}
  1762	
  1763	/*
  1764	 * generate code to compute n;
  1765	 * make a refer to result.
  1766	 */
  1767	void
  1768	naddr(Node *n, Addr *a, int canemitcode)
  1769	{
  1770		a->scale = 0;
  1771		a->index = D_NONE;
  1772		a->type = D_NONE;
  1773		a->gotype = S;
  1774		a->node = N;
  1775		if(n == N)
  1776			return;
  1777	
  1778		switch(n->op) {
  1779		default:
  1780			fatal("naddr: bad %O %D", n->op, a);
  1781			break;
  1782	
  1783		case OREGISTER:
  1784			a->type = n->val.u.reg;
  1785			a->sym = S;
  1786			break;
  1787	
  1788		case OINDREG:
  1789			a->type = n->val.u.reg+D_INDIR;
  1790			a->sym = n->sym;
  1791			a->offset = n->xoffset;
  1792			break;
  1793	
  1794		case OPARAM:
  1795			// n->left is PHEAP ONAME for stack parameter.
  1796			// compute address of actual parameter on stack.
  1797			a->etype = n->left->type->etype;
  1798			a->width = n->left->type->width;
  1799			a->offset = n->xoffset;
  1800			a->sym = n->left->sym;
  1801			a->type = D_PARAM;
  1802			break;
  1803	
  1804		case ONAME:
  1805			a->etype = 0;
  1806			a->width = 0;
  1807			if(n->type != T) {
  1808				a->etype = simtype[n->type->etype];
  1809				a->width = n->type->width;
  1810				a->gotype = ngotype(n);
  1811			}
  1812			a->pun = n->pun;
  1813			a->offset = n->xoffset;
  1814			a->sym = n->sym;
  1815			if(a->sym == S)
  1816				a->sym = lookup(".noname");
  1817			if(n->method) {
  1818				if(n->type != T)
  1819				if(n->type->sym != S)
  1820				if(n->type->sym->pkg != nil)
  1821					a->sym = pkglookup(a->sym->name, n->type->sym->pkg);
  1822			}
  1823	
  1824			switch(n->class) {
  1825			default:
  1826				fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
  1827			case PEXTERN:
  1828				a->type = D_EXTERN;
  1829				break;
  1830			case PAUTO:
  1831				a->type = D_AUTO;
  1832				if (n->sym)
  1833					a->node = n->orig;
  1834				break;
  1835			case PPARAM:
  1836			case PPARAMOUT:
  1837				a->type = D_PARAM;
  1838				break;
  1839			case PFUNC:
  1840				a->index = D_EXTERN;
  1841				a->type = D_ADDR;
  1842				break;
  1843			}
  1844			break;
  1845	
  1846		case OLITERAL:
  1847			switch(n->val.ctype) {
  1848			default:
  1849				fatal("naddr: const %lT", n->type);
  1850				break;
  1851			case CTFLT:
  1852				a->type = D_FCONST;
  1853				a->dval = mpgetflt(n->val.u.fval);
  1854				break;
  1855			case CTINT:
  1856				a->sym = S;
  1857				a->type = D_CONST;
  1858				a->offset = mpgetfix(n->val.u.xval);
  1859				break;
  1860			case CTSTR:
  1861				datagostring(n->val.u.sval, a);
  1862				break;
  1863			case CTBOOL:
  1864				a->sym = S;
  1865				a->type = D_CONST;
  1866				a->offset = n->val.u.bval;
  1867				break;
  1868			case CTNIL:
  1869				a->sym = S;
  1870				a->type = D_CONST;
  1871				a->offset = 0;
  1872				break;
  1873			}
  1874			break;
  1875	
  1876		case OADDR:
  1877			naddr(n->left, a, canemitcode);
  1878			if(a->type >= D_INDIR) {
  1879				a->type -= D_INDIR;
  1880				break;
  1881			}
  1882			if(a->type == D_EXTERN || a->type == D_STATIC ||
  1883			   a->type == D_AUTO || a->type == D_PARAM)
  1884				if(a->index == D_NONE) {
  1885					a->index = a->type;
  1886					a->type = D_ADDR;
  1887					break;
  1888				}
  1889			fatal("naddr: OADDR\n");
  1890	
  1891		case OLEN:
  1892			// len of string or slice
  1893			naddr(n->left, a, canemitcode);
  1894			if(a->type == D_CONST && a->offset == 0)
  1895				break;	// len(nil)
  1896			a->etype = TUINT32;
  1897			a->offset += Array_nel;
  1898			a->width = 4;
  1899			if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
  1900				checkoffset(a, canemitcode);
  1901			break;
  1902	
  1903		case OCAP:
  1904			// cap of string or slice
  1905			naddr(n->left, a, canemitcode);
  1906			if(a->type == D_CONST && a->offset == 0)
  1907				break;	// cap(nil)
  1908			a->etype = TUINT32;
  1909			a->offset += Array_cap;
  1910			a->width = 4;
  1911			if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
  1912				checkoffset(a, canemitcode);
  1913			break;
  1914	
  1915	//	case OADD:
  1916	//		if(n->right->op == OLITERAL) {
  1917	//			v = n->right->vconst;
  1918	//			naddr(n->left, a, canemitcode);
  1919	//		} else
  1920	//		if(n->left->op == OLITERAL) {
  1921	//			v = n->left->vconst;
  1922	//			naddr(n->right, a, canemitcode);
  1923	//		} else
  1924	//			goto bad;
  1925	//		a->offset += v;
  1926	//		break;
  1927	
  1928		}
  1929	}
  1930	
  1931	int
  1932	dotaddable(Node *n, Node *n1)
  1933	{
  1934		int o, oary[10];
  1935		Node *nn;
  1936	
  1937		if(n->op != ODOT)
  1938			return 0;
  1939	
  1940		o = dotoffset(n, oary, &nn);
  1941		if(nn != N && nn->addable && o == 1 && oary[0] >= 0) {
  1942			*n1 = *nn;
  1943			n1->type = n->type;
  1944			n1->xoffset += oary[0];
  1945			return 1;
  1946		}
  1947		return 0;
  1948	}
  1949	
  1950	void
  1951	sudoclean(void)
  1952	{
  1953	}
  1954	
  1955	int
  1956	sudoaddable(int as, Node *n, Addr *a)
  1957	{
  1958		return 0;
  1959	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.