The Go Programming Language

Text file src/cmd/5l/span.c

     1	// Inferno utils/5l/span.c
     2	// http://code.google.com/p/inferno-os/source/browse/utils/5l/span.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	// Instruction layout.
    32	
    33	#include	"l.h"
    34	#include	"../ld/lib.h"
    35	
    36	static struct {
    37		uint32	start;
    38		uint32	size;
    39		uint32	extra;
    40	} pool;
    41	
    42	int	checkpool(Prog*, int);
    43	int 	flushpool(Prog*, int, int);
    44	
    45	int
    46	isbranch(Prog *p)
    47	{
    48		int as = p->as;
    49		return (as >= ABEQ && as <= ABLE) || as == AB || as == ABL || as == ABX;
    50	}
    51	
    52	static int
    53	scan(Prog *op, Prog *p, int c)
    54	{
    55		Prog *q;
    56	
    57		for(q = op->link; q != p && q != P; q = q->link){
    58			q->pc = c;
    59			c += oplook(q)->size;
    60			nocache(q);
    61		}
    62		return c;
    63	}
    64	
    65	/* size of a case statement including jump table */
    66	static int32
    67	casesz(Prog *p)
    68	{
    69		int jt = 0;
    70		int32 n = 0;
    71		Optab *o;
    72	
    73		for( ; p != P; p = p->link){
    74			if(p->as == ABCASE)
    75				jt = 1;
    76			else if(jt)
    77				break;
    78			o = oplook(p);
    79			n += o->size;
    80		}
    81		return n;
    82	}
    83	
    84	void
    85	span(void)
    86	{
    87		Prog *p, *op;
    88		Optab *o;
    89		int m, bflag, i, v;
    90		int32 c, otxt, out[6];
    91		Section *sect;
    92		uchar *bp;
    93	
    94		if(debug['v'])
    95			Bprint(&bso, "%5.2f span\n", cputime());
    96		Bflush(&bso);
    97	
    98		bflag = 0;
    99		c = INITTEXT;
   100		otxt = c;
   101		for(cursym = textp; cursym != nil; cursym = cursym->next) {
   102			p = cursym->text;
   103			p->pc = c;
   104			cursym->value = c;
   105	
   106			autosize = p->to.offset + 4;
   107			if(p->from.sym != S)
   108				p->from.sym->value = c;
   109			/* need passes to resolve branches */
   110			if(c-otxt >= 1L<<17)
   111				bflag = 1;
   112			otxt = c;
   113	
   114			for(op = p, p = p->link; p != P; op = p, p = p->link) {
   115				curp = p;
   116				p->pc = c;
   117				o = oplook(p);
   118				m = o->size;
   119				// must check literal pool here in case p generates many instructions
   120				if(blitrl){
   121					if(checkpool(op, p->as == ACASE ? casesz(p) : m))
   122						c = p->pc = scan(op, p, c);
   123				}
   124				if(m == 0) {
   125					diag("zero-width instruction\n%P", p);
   126					continue;
   127				}
   128				switch(o->flag & (LFROM|LTO|LPOOL)) {
   129				case LFROM:
   130					addpool(p, &p->from);
   131					break;
   132				case LTO:
   133					addpool(p, &p->to);
   134					break;
   135				case LPOOL:
   136					if ((p->scond&C_SCOND) == 14)
   137						flushpool(p, 0, 0);
   138					break;
   139				}
   140				if(p->as==AMOVW && p->to.type==D_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == 14)
   141					flushpool(p, 0, 0);
   142				c += m;
   143			}
   144			if(blitrl){
   145				if(checkpool(op, 0))
   146					c = scan(op, P, c);
   147			}
   148			cursym->size = c - cursym->value;
   149		}
   150	
   151		/*
   152		 * if any procedure is large enough to
   153		 * generate a large SBRA branch, then
   154		 * generate extra passes putting branches
   155		 * around jmps to fix. this is rare.
   156		 */
   157		while(bflag) {
   158			if(debug['v'])
   159				Bprint(&bso, "%5.2f span1\n", cputime());
   160			bflag = 0;
   161			c = INITTEXT;
   162			for(cursym = textp; cursym != nil; cursym = cursym->next) {
   163				cursym->value = c;
   164				for(p = cursym->text; p != P; p = p->link) {
   165					curp = p;
   166					p->pc = c;
   167					o = oplook(p);
   168	/* very large branches
   169					if(o->type == 6 && p->cond) {
   170						otxt = p->cond->pc - c;
   171						if(otxt < 0)
   172							otxt = -otxt;
   173						if(otxt >= (1L<<17) - 10) {
   174							q = prg();
   175							q->link = p->link;
   176							p->link = q;
   177							q->as = AB;
   178							q->to.type = D_BRANCH;
   179							q->cond = p->cond;
   180							p->cond = q;
   181							q = prg();
   182							q->link = p->link;
   183							p->link = q;
   184							q->as = AB;
   185							q->to.type = D_BRANCH;
   186							q->cond = q->link->link;
   187							bflag = 1;
   188						}
   189					}
   190	 */
   191					m = o->size;
   192					if(m == 0) {
   193						if(p->as == ATEXT) {
   194							autosize = p->to.offset + 4;
   195							if(p->from.sym != S)
   196								p->from.sym->value = c;
   197							continue;
   198						}
   199						diag("zero-width instruction\n%P", p);
   200						continue;
   201					}
   202					c += m;
   203				}
   204				cursym->size = c - cursym->value;
   205			}
   206		}
   207	
   208		c = rnd(c, 8);
   209		
   210		/*
   211		 * lay out the code.  all the pc-relative code references,
   212		 * even cross-function, are resolved now;
   213		 * only data references need to be relocated.
   214		 * with more work we could leave cross-function
   215		 * code references to be relocated too, and then
   216		 * perhaps we'd be able to parallelize the span loop above.
   217		 */
   218		for(cursym = textp; cursym != nil; cursym = cursym->next) {
   219			p = cursym->text;
   220			autosize = p->to.offset + 4;
   221			symgrow(cursym, cursym->size);
   222		
   223			bp = cursym->p;
   224			for(p = p->link; p != P; p = p->link) {
   225				pc = p->pc;
   226				curp = p;
   227				o = oplook(p);
   228				asmout(p, o, out);
   229				for(i=0; i<o->size/4; i++) {
   230					v = out[i];
   231					*bp++ = v;
   232					*bp++ = v>>8;
   233					*bp++ = v>>16;
   234					*bp++ = v>>24;
   235				}
   236			}
   237		}
   238		sect = addsection(&segtext, ".text", 05);
   239		sect->vaddr = INITTEXT;
   240		sect->len = c - INITTEXT;
   241	}
   242	
   243	/*
   244	 * when the first reference to the literal pool threatens
   245	 * to go out of range of a 12-bit PC-relative offset,
   246	 * drop the pool now, and branch round it.
   247	 * this happens only in extended basic blocks that exceed 4k.
   248	 */
   249	int
   250	checkpool(Prog *p, int sz)
   251	{
   252		if(pool.size >= 0xffc || immaddr((p->pc+sz+4)+4+pool.size - pool.start+8) == 0)
   253			return flushpool(p, 1, 0);
   254		else if(p->link == P)
   255			return flushpool(p, 2, 0);
   256		return 0;
   257	}
   258	
   259	int
   260	flushpool(Prog *p, int skip, int force)
   261	{
   262		Prog *q;
   263	
   264		if(blitrl) {
   265			if(skip){
   266				if(0 && skip==1)print("note: flush literal pool at %ux: len=%ud ref=%ux\n", p->pc+4, pool.size, pool.start);
   267				q = prg();
   268				q->as = AB;
   269				q->to.type = D_BRANCH;
   270				q->cond = p->link;
   271				q->link = blitrl;
   272				blitrl = q;
   273			}
   274			else if(!force && (p->pc+pool.size-pool.start < 2048))
   275				return 0;
   276			elitrl->link = p->link;
   277			p->link = blitrl;
   278			blitrl = 0;	/* BUG: should refer back to values until out-of-range */
   279			elitrl = 0;
   280			pool.size = 0;
   281			pool.start = 0;
   282			pool.extra = 0;
   283			return 1;
   284		}
   285		return 0;
   286	}
   287	
   288	void
   289	addpool(Prog *p, Adr *a)
   290	{
   291		Prog *q, t;
   292		int c;
   293	
   294		c = aclass(a);
   295	
   296		t = zprg;
   297		t.as = AWORD;
   298	
   299		switch(c) {
   300		default:
   301			t.to = *a;
   302			break;
   303	
   304		case	C_SROREG:
   305		case C_LOREG:
   306		case C_ROREG:
   307		case C_FOREG:
   308		case C_SOREG:
   309		case C_HOREG:
   310		case C_FAUTO:
   311		case C_SAUTO:
   312		case C_LAUTO:
   313		case C_LACON:
   314			t.to.type = D_CONST;
   315			t.to.offset = instoffset;
   316			break;
   317		}
   318	
   319		for(q = blitrl; q != P; q = q->link)	/* could hash on t.t0.offset */
   320			if(memcmp(&q->to, &t.to, sizeof(t.to)) == 0) {
   321				p->cond = q;
   322				return;
   323			}
   324	
   325		q = prg();
   326		*q = t;
   327		q->pc = pool.size;
   328	
   329		if(blitrl == P) {
   330			blitrl = q;
   331			pool.start = p->pc;
   332			q->align = 4;
   333		} else
   334			elitrl->link = q;
   335		elitrl = q;
   336		pool.size += 4;
   337	
   338		p->cond = q;
   339	}
   340	
   341	void
   342	xdefine(char *p, int t, int32 v)
   343	{
   344		Sym *s;
   345	
   346		s = lookup(p, 0);
   347		s->type = t;
   348		s->value = v;
   349		s->reachable = 1;
   350		s->special = 1;
   351	}
   352	
   353	int32
   354	regoff(Adr *a)
   355	{
   356	
   357		instoffset = 0;
   358		aclass(a);
   359		return instoffset;
   360	}
   361	
   362	int32
   363	immrot(uint32 v)
   364	{
   365		int i;
   366	
   367		for(i=0; i<16; i++) {
   368			if((v & ~0xff) == 0)
   369				return (i<<8) | v | (1<<25);
   370			v = (v<<2) | (v>>30);
   371		}
   372		return 0;
   373	}
   374	
   375	int32
   376	immaddr(int32 v)
   377	{
   378		if(v >= 0 && v <= 0xfff)
   379			return (v & 0xfff) |
   380				(1<<24) |	/* pre indexing */
   381				(1<<23);	/* pre indexing, up */
   382		if(v >= -0xfff && v < 0)
   383			return (-v & 0xfff) |
   384				(1<<24);	/* pre indexing */
   385		return 0;
   386	}
   387	
   388	int
   389	immfloat(int32 v)
   390	{
   391		return (v & 0xC03) == 0;	/* offset will fit in floating-point load/store */
   392	}
   393	
   394	int
   395	immhalf(int32 v)
   396	{
   397		if(v >= 0 && v <= 0xff)
   398			return v|
   399				(1<<24)|	/* pre indexing */
   400				(1<<23);	/* pre indexing, up */
   401		if(v >= -0xff && v < 0)
   402			return (-v & 0xff)|
   403				(1<<24);	/* pre indexing */
   404		return 0;
   405	}
   406	
   407	int32
   408	symaddr(Sym *s)
   409	{
   410		int32 v;
   411	
   412		v = s->value;
   413		switch(s->type) {
   414		default:
   415			diag("unexpected type %d in symaddr(%s)", s->type, s->name);
   416			return 0;
   417		
   418		case STEXT:
   419		case SELFROSECT:
   420		case SRODATA:
   421		case SDATA:
   422		case SBSS:
   423		case SCONST:
   424			break;
   425		}
   426		return v;
   427	}
   428	
   429	int
   430	aclass(Adr *a)
   431	{
   432		Sym *s;
   433		int t;
   434	
   435		switch(a->type) {
   436		case D_NONE:
   437			return C_NONE;
   438	
   439		case D_REG:
   440			return C_REG;
   441	
   442		case D_REGREG:
   443			return C_REGREG;
   444	
   445		case D_SHIFT:
   446			return C_SHIFT;
   447	
   448		case D_FREG:
   449			return C_FREG;
   450	
   451		case D_FPCR:
   452			return C_FCR;
   453	
   454		case D_OREG:
   455			switch(a->name) {
   456			case D_EXTERN:
   457			case D_STATIC:
   458				if(a->sym == 0 || a->sym->name == 0) {
   459					print("null sym external\n");
   460					print("%D\n", a);
   461					return C_GOK;
   462				}
   463				instoffset = 0;	// s.b. unused but just in case
   464				return C_ADDR;
   465	
   466			case D_AUTO:
   467				instoffset = autosize + a->offset;
   468				t = immaddr(instoffset);
   469				if(t){
   470					if(immhalf(instoffset))
   471						return immfloat(t) ? C_HFAUTO : C_HAUTO;
   472					if(immfloat(t))
   473						return C_FAUTO;
   474					return C_SAUTO;
   475				}
   476				return C_LAUTO;
   477	
   478			case D_PARAM:
   479				instoffset = autosize + a->offset + 4L;
   480				t = immaddr(instoffset);
   481				if(t){
   482					if(immhalf(instoffset))
   483						return immfloat(t) ? C_HFAUTO : C_HAUTO;
   484					if(immfloat(t))
   485						return C_FAUTO;
   486					return C_SAUTO;
   487				}
   488				return C_LAUTO;
   489			case D_NONE:
   490				instoffset = a->offset;
   491				t = immaddr(instoffset);
   492				if(t) {
   493					if(immhalf(instoffset))		 /* n.b. that it will also satisfy immrot */
   494						return immfloat(t) ? C_HFOREG : C_HOREG;
   495					if(immfloat(t))
   496						return C_FOREG; /* n.b. that it will also satisfy immrot */
   497					t = immrot(instoffset);
   498					if(t)
   499						return C_SROREG;
   500					if(immhalf(instoffset))
   501						return C_HOREG;
   502					return C_SOREG;
   503				}
   504				t = immrot(instoffset);
   505				if(t)
   506					return C_ROREG;
   507				return C_LOREG;
   508			}
   509			return C_GOK;
   510	
   511		case D_PSR:
   512			return C_PSR;
   513	
   514		case D_OCONST:
   515			switch(a->name) {
   516			case D_EXTERN:
   517			case D_STATIC:
   518				instoffset = 0;	// s.b. unused but just in case
   519				return C_ADDR;
   520			}
   521			return C_GOK;
   522	
   523		case D_FCONST:
   524			if(chipzero(&a->ieee) >= 0)
   525				return C_ZFCON;
   526			if(chipfloat(&a->ieee) >= 0)
   527				return C_SFCON;
   528			return C_LFCON;
   529	
   530		case D_CONST:
   531		case D_CONST2:
   532			switch(a->name) {
   533	
   534			case D_NONE:
   535				instoffset = a->offset;
   536				if(a->reg != NREG)
   537					goto aconsize;
   538	
   539				t = immrot(instoffset);
   540				if(t)
   541					return C_RCON;
   542				t = immrot(~instoffset);
   543				if(t)
   544					return C_NCON;
   545				return C_LCON;
   546	
   547			case D_EXTERN:
   548			case D_STATIC:
   549				s = a->sym;
   550				if(s == S)
   551					break;
   552				instoffset = 0;	// s.b. unused but just in case
   553				return C_LCON;
   554	
   555			case D_AUTO:
   556				instoffset = autosize + a->offset;
   557				goto aconsize;
   558	
   559			case D_PARAM:
   560				instoffset = autosize + a->offset + 4L;
   561			aconsize:
   562				t = immrot(instoffset);
   563				if(t)
   564					return C_RACON;
   565				return C_LACON;
   566			}
   567			return C_GOK;
   568	
   569		case D_BRANCH:
   570			return C_SBRA;
   571		}
   572		return C_GOK;
   573	}
   574	
   575	Optab*
   576	oplook(Prog *p)
   577	{
   578		int a1, a2, a3, r;
   579		char *c1, *c3;
   580		Optab *o, *e;
   581	
   582		a1 = p->optab;
   583		if(a1)
   584			return optab+(a1-1);
   585		a1 = p->from.class;
   586		if(a1 == 0) {
   587			a1 = aclass(&p->from) + 1;
   588			p->from.class = a1;
   589		}
   590		a1--;
   591		a3 = p->to.class;
   592		if(a3 == 0) {
   593			a3 = aclass(&p->to) + 1;
   594			p->to.class = a3;
   595		}
   596		a3--;
   597		a2 = C_NONE;
   598		if(p->reg != NREG)
   599			a2 = C_REG;
   600		r = p->as;
   601		o = oprange[r].start;
   602		if(o == 0) {
   603			a1 = opcross[repop[r]][a1][a2][a3];
   604			if(a1) {
   605				p->optab = a1+1;
   606				return optab+a1;
   607			}
   608			o = oprange[r].stop; /* just generate an error */
   609		}
   610		if(debug['O']) {
   611			print("oplook %A %O %O %O\n",
   612				(int)p->as, a1, a2, a3);
   613			print("		%d %d\n", p->from.type, p->to.type);
   614		}
   615		e = oprange[r].stop;
   616		c1 = xcmp[a1];
   617		c3 = xcmp[a3];
   618		for(; o<e; o++)
   619			if(o->a2 == a2)
   620			if(c1[o->a1])
   621			if(c3[o->a3]) {
   622				p->optab = (o-optab)+1;
   623				return o;
   624			}
   625		diag("illegal combination %A %O %O %O, %d %d",
   626			p->as, a1, a2, a3, p->from.type, p->to.type);
   627		prasm(p);
   628		if(o == 0)
   629			o = optab;
   630		return o;
   631	}
   632	
   633	int
   634	cmp(int a, int b)
   635	{
   636	
   637		if(a == b)
   638			return 1;
   639		switch(a) {
   640		case C_LCON:
   641			if(b == C_RCON || b == C_NCON)
   642				return 1;
   643			break;
   644		case C_LACON:
   645			if(b == C_RACON)
   646				return 1;
   647			break;
   648		case C_LFCON:
   649			if(b == C_ZFCON || b == C_SFCON)
   650				return 1;
   651			break;
   652	
   653		case C_HFAUTO:
   654			return b == C_HAUTO || b == C_FAUTO;
   655		case C_FAUTO:
   656		case C_HAUTO:
   657			return b == C_HFAUTO;
   658		case C_SAUTO:
   659			return cmp(C_HFAUTO, b);
   660		case C_LAUTO:
   661			return cmp(C_SAUTO, b);
   662	
   663		case C_HFOREG:
   664			return b == C_HOREG || b == C_FOREG;
   665		case C_FOREG:
   666		case C_HOREG:
   667			return b == C_HFOREG;
   668		case C_SROREG:
   669			return cmp(C_SOREG, b) || cmp(C_ROREG, b);
   670		case C_SOREG:
   671		case C_ROREG:
   672			return b == C_SROREG || cmp(C_HFOREG, b);
   673		case C_LOREG:
   674			return cmp(C_SROREG, b);
   675	
   676		case C_LBRA:
   677			if(b == C_SBRA)
   678				return 1;
   679			break;
   680	
   681		case C_HREG:
   682			return cmp(C_SP, b) || cmp(C_PC, b);
   683	
   684		}
   685		return 0;
   686	}
   687	
   688	int
   689	ocmp(const void *a1, const void *a2)
   690	{
   691		Optab *p1, *p2;
   692		int n;
   693	
   694		p1 = (Optab*)a1;
   695		p2 = (Optab*)a2;
   696		n = p1->as - p2->as;
   697		if(n)
   698			return n;
   699		n = p1->a1 - p2->a1;
   700		if(n)
   701			return n;
   702		n = p1->a2 - p2->a2;
   703		if(n)
   704			return n;
   705		n = p1->a3 - p2->a3;
   706		if(n)
   707			return n;
   708		return 0;
   709	}
   710	
   711	void
   712	buildop(void)
   713	{
   714		int i, n, r;
   715	
   716		for(i=0; i<C_GOK; i++)
   717			for(n=0; n<C_GOK; n++)
   718				xcmp[i][n] = cmp(n, i);
   719		for(n=0; optab[n].as != AXXX; n++)
   720			;
   721		qsort(optab, n, sizeof(optab[0]), ocmp);
   722		for(i=0; i<n; i++) {
   723			r = optab[i].as;
   724			oprange[r].start = optab+i;
   725			while(optab[i].as == r)
   726				i++;
   727			oprange[r].stop = optab+i;
   728			i--;
   729	
   730			switch(r)
   731			{
   732			default:
   733				diag("unknown op in build: %A", r);
   734				errorexit();
   735			case AADD:
   736				oprange[AAND] = oprange[r];
   737				oprange[AEOR] = oprange[r];
   738				oprange[ASUB] = oprange[r];
   739				oprange[ARSB] = oprange[r];
   740				oprange[AADC] = oprange[r];
   741				oprange[ASBC] = oprange[r];
   742				oprange[ARSC] = oprange[r];
   743				oprange[AORR] = oprange[r];
   744				oprange[ABIC] = oprange[r];
   745				break;
   746			case ACMP:
   747				oprange[ATEQ] = oprange[r];
   748				oprange[ACMN] = oprange[r];
   749				break;
   750			case AMVN:
   751				break;
   752			case ABEQ:
   753				oprange[ABNE] = oprange[r];
   754				oprange[ABCS] = oprange[r];
   755				oprange[ABHS] = oprange[r];
   756				oprange[ABCC] = oprange[r];
   757				oprange[ABLO] = oprange[r];
   758				oprange[ABMI] = oprange[r];
   759				oprange[ABPL] = oprange[r];
   760				oprange[ABVS] = oprange[r];
   761				oprange[ABVC] = oprange[r];
   762				oprange[ABHI] = oprange[r];
   763				oprange[ABLS] = oprange[r];
   764				oprange[ABGE] = oprange[r];
   765				oprange[ABLT] = oprange[r];
   766				oprange[ABGT] = oprange[r];
   767				oprange[ABLE] = oprange[r];
   768				break;
   769			case ASLL:
   770				oprange[ASRL] = oprange[r];
   771				oprange[ASRA] = oprange[r];
   772				break;
   773			case AMUL:
   774				oprange[AMULU] = oprange[r];
   775				break;
   776			case ADIV:
   777				oprange[AMOD] = oprange[r];
   778				oprange[AMODU] = oprange[r];
   779				oprange[ADIVU] = oprange[r];
   780				break;
   781			case AMOVW:
   782			case AMOVB:
   783			case AMOVBU:
   784			case AMOVH:
   785			case AMOVHU:
   786				break;
   787			case ASWPW:
   788				oprange[ASWPBU] = oprange[r];
   789				break;
   790			case AB:
   791			case ABL:
   792			case ABX:
   793			case ABXRET:
   794			case ASWI:
   795			case AWORD:
   796			case AMOVM:
   797			case ARFE:
   798			case ATEXT:
   799			case ACASE:
   800			case ABCASE:
   801				break;
   802			case AADDF:
   803				oprange[AADDD] = oprange[r];
   804				oprange[ASUBF] = oprange[r];
   805				oprange[ASUBD] = oprange[r];
   806				oprange[AMULF] = oprange[r];
   807				oprange[AMULD] = oprange[r];
   808				oprange[ADIVF] = oprange[r];
   809				oprange[ADIVD] = oprange[r];
   810				oprange[ASQRTF] = oprange[r];
   811				oprange[ASQRTD] = oprange[r];
   812				oprange[AMOVFD] = oprange[r];
   813				oprange[AMOVDF] = oprange[r];
   814				break;
   815	
   816			case ACMPF:
   817				oprange[ACMPD] = oprange[r];
   818				break;
   819	
   820			case AMOVF:
   821				oprange[AMOVD] = oprange[r];
   822				break;
   823	
   824			case AMOVFW:
   825				oprange[AMOVDW] = oprange[r];
   826				break;
   827	
   828			case AMOVWF:
   829				oprange[AMOVWD] = oprange[r];
   830				break;
   831	
   832			case AMULL:
   833				oprange[AMULA] = oprange[r];
   834				oprange[AMULAL] = oprange[r];
   835				oprange[AMULLU] = oprange[r];
   836				oprange[AMULALU] = oprange[r];
   837				break;
   838	
   839			case ALDREX:
   840			case ASTREX:
   841			case ALDREXD:
   842			case ASTREXD:
   843			case ATST:
   844				break;
   845			}
   846		}
   847	}
   848	
   849	/*
   850	void
   851	buildrep(int x, int as)
   852	{
   853		Opcross *p;
   854		Optab *e, *s, *o;
   855		int a1, a2, a3, n;
   856	
   857		if(C_NONE != 0 || C_REG != 1 || C_GOK >= 32 || x >= nelem(opcross)) {
   858			diag("assumptions fail in buildrep");
   859			errorexit();
   860		}
   861		repop[as] = x;
   862		p = (opcross + x);
   863		s = oprange[as].start;
   864		e = oprange[as].stop;
   865		for(o=e-1; o>=s; o--) {
   866			n = o-optab;
   867			for(a2=0; a2<2; a2++) {
   868				if(a2) {
   869					if(o->a2 == C_NONE)
   870						continue;
   871				} else
   872					if(o->a2 != C_NONE)
   873						continue;
   874				for(a1=0; a1<32; a1++) {
   875					if(!xcmp[a1][o->a1])
   876						continue;
   877					for(a3=0; a3<32; a3++)
   878						if(xcmp[a3][o->a3])
   879							(*p)[a1][a2][a3] = n;
   880				}
   881			}
   882		}
   883		oprange[as].start = 0;
   884	}
   885	*/

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