12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024 |
- #include "cc.h"
- Node*
- new(int t, Node *l, Node *r)
- {
- Node *n;
- n = alloc(sizeof(*n));
- n->op = t;
- n->left = l;
- n->right = r;
- if(l && t != OGOTO)
- n->lineno = l->lineno;
- else if(r)
- n->lineno = r->lineno;
- else
- n->lineno = lineno;
- newflag = 1;
- return n;
- }
- Node*
- new1(int o, Node *l, Node *r)
- {
- Node *n;
- n = new(o, l, r);
- n->lineno = nearln;
- return n;
- }
- void
- prtree(Node *n, char *s)
- {
- print(" == %s ==\n", s);
- prtree1(n, 0, 0);
- print("\n");
- }
- void
- prtree1(Node *n, int d, int f)
- {
- int i;
- if(f)
- for(i=0; i<d; i++)
- print(" ");
- if(n == Z) {
- print("Z\n");
- return;
- }
- if(n->op == OLIST) {
- prtree1(n->left, d, 0);
- prtree1(n->right, d, 1);
- return;
- }
- d++;
- print("%O", n->op);
- i = 3;
- switch(n->op)
- {
- case ONAME:
- print(" \"%F\"", n);
- print(" %ld", n->xoffset);
- i = 0;
- break;
- case OINDREG:
- print(" %ld(R%d)", n->xoffset, n->reg);
- i = 0;
- break;
- case OREGISTER:
- if(n->xoffset)
- print(" %ld+R%d", n->xoffset, n->reg);
- else
- print(" R%d", n->reg);
- i = 0;
- break;
- case OSTRING:
- print(" \"%s\"", n->cstring);
- i = 0;
- break;
- case OLSTRING:
- print(" \"%S\"", n->rstring);
- i = 0;
- break;
- case ODOT:
- case OELEM:
- print(" \"%F\"", n);
- break;
- case OCONST:
- if(typefd[n->type->etype])
- print(" \"%.8e\"", n->fconst);
- else
- print(" \"%lld\"", n->vconst);
- i = 0;
- break;
- }
- if(n->addable != 0)
- print(" <%d>", n->addable);
- if(n->type != T)
- print(" %T", n->type);
- if(n->complex != 0)
- print(" (%d)", n->complex);
- print(" %L\n", n->lineno);
- if(i & 2)
- prtree1(n->left, d, 1);
- if(i & 1)
- prtree1(n->right, d, 1);
- }
- Type*
- typ(int et, Type *d)
- {
- Type *t;
- t = alloc(sizeof(*t));
- t->etype = et;
- t->link = d;
- t->down = T;
- t->sym = S;
- t->width = ewidth[et];
- t->offset = 0;
- t->shift = 0;
- t->nbits = 0;
- t->garb = 0;
- return t;
- }
- Type*
- copytyp(Type *t)
- {
- Type *nt;
- nt = typ(TXXX, T);
- *nt = *t;
- return nt;
- }
- Type*
- garbt(Type *t, long b)
- {
- Type *t1;
- if(b & BGARB) {
- t1 = copytyp(t);
- t1->garb = simpleg(b);
- return t1;
- }
- return t;
- }
- int
- simpleg(long b)
- {
- b &= BGARB;
- switch(b) {
- case BCONSTNT:
- return GCONSTNT;
- case BVOLATILE:
- return GVOLATILE;
- case BVOLATILE|BCONSTNT:
- return GCONSTNT|GVOLATILE;
- }
- return GXXX;
- }
- int
- simplec(long b)
- {
- b &= BCLASS;
- switch(b) {
- case 0:
- case BREGISTER:
- return CXXX;
- case BAUTO:
- case BAUTO|BREGISTER:
- return CAUTO;
- case BEXTERN:
- return CEXTERN;
- case BEXTERN|BREGISTER:
- return CEXREG;
- case BSTATIC:
- return CSTATIC;
- case BTYPEDEF:
- return CTYPEDEF;
- case BTYPESTR:
- return CTYPESTR;
- }
- diag(Z, "illegal combination of classes %Q", b);
- return CXXX;
- }
- Type*
- simplet(long b)
- {
- b &= ~BCLASS & ~BGARB;
- switch(b) {
- case BCHAR:
- case BCHAR|BSIGNED:
- return types[TCHAR];
- case BCHAR|BUNSIGNED:
- return types[TUCHAR];
- case BSHORT:
- case BSHORT|BINT:
- case BSHORT|BSIGNED:
- case BSHORT|BINT|BSIGNED:
- return types[TSHORT];
- case BUNSIGNED|BSHORT:
- case BUNSIGNED|BSHORT|BINT:
- return types[TUSHORT];
- case 0:
- case BINT:
- case BINT|BSIGNED:
- case BSIGNED:
- return types[TINT];
- case BUNSIGNED:
- case BUNSIGNED|BINT:
- return types[TUINT];
- case BLONG:
- case BLONG|BINT:
- case BLONG|BSIGNED:
- case BLONG|BINT|BSIGNED:
- return types[TLONG];
- case BUNSIGNED|BLONG:
- case BUNSIGNED|BLONG|BINT:
- return types[TULONG];
- case BVLONG|BLONG:
- case BVLONG|BLONG|BINT:
- case BVLONG|BLONG|BSIGNED:
- case BVLONG|BLONG|BINT|BSIGNED:
- return types[TVLONG];
- case BVLONG|BLONG|BUNSIGNED:
- case BVLONG|BLONG|BINT|BUNSIGNED:
- return types[TUVLONG];
- case BFLOAT:
- return types[TFLOAT];
- case BDOUBLE:
- case BDOUBLE|BLONG:
- case BFLOAT|BLONG:
- return types[TDOUBLE];
- case BVOID:
- return types[TVOID];
- }
- diag(Z, "illegal combination of types %Q", b);
- return types[TINT];
- }
- int
- stcompat(Node *n, Type *t1, Type *t2, long ttab[])
- {
- int i;
- ulong b;
- i = 0;
- if(t2 != T)
- i = t2->etype;
- b = 1L << i;
- i = 0;
- if(t1 != T)
- i = t1->etype;
- if(b & ttab[i]) {
- if(ttab == tasign)
- if(b == BSTRUCT || b == BUNION)
- if(!sametype(t1, t2))
- return 1;
- if(n->op != OCAST)
- if(b == BIND && i == TIND)
- if(!sametype(t1, t2))
- return 1;
- return 0;
- }
- return 1;
- }
- int
- tcompat(Node *n, Type *t1, Type *t2, long ttab[])
- {
- if(stcompat(n, t1, t2, ttab)) {
- if(t1 == T)
- diag(n, "incompatible type: \"%T\" for op \"%O\"",
- t2, n->op);
- else
- diag(n, "incompatible types: \"%T\" and \"%T\" for op \"%O\"",
- t1, t2, n->op);
- return 1;
- }
- return 0;
- }
- void
- makedot(Node *n, Type *t, long o)
- {
- Node *n1, *n2;
- if(t->nbits) {
- n1 = new(OXXX, Z, Z);
- *n1 = *n;
- n->op = OBIT;
- n->left = n1;
- n->right = Z;
- n->type = t;
- n->addable = n1->left->addable;
- n = n1;
- }
- n->addable = n->left->addable;
- if(n->addable == 0) {
- n1 = new1(OCONST, Z, Z);
- n1->vconst = o;
- n1->type = types[TLONG];
- n->right = n1;
- n->type = t;
- return;
- }
- n->left->type = t;
- if(o == 0) {
- *n = *n->left;
- return;
- }
- n->type = t;
- n1 = new1(OCONST, Z, Z);
- n1->vconst = o;
- t = typ(TIND, t);
- t->width = types[TIND]->width;
- n1->type = t;
- n2 = new1(OADDR, n->left, Z);
- n2->type = t;
- n1 = new1(OADD, n1, n2);
- n1->type = t;
- n->op = OIND;
- n->left = n1;
- n->right = Z;
- }
- Type*
- dotsearch(Sym *s, Type *t, Node *n, long *off)
- {
- Type *t1, *xt, *rt;
- xt = T;
- /*
- * look it up by name
- */
- for(t1 = t; t1 != T; t1 = t1->down)
- if(t1->sym == s) {
- if(xt != T)
- goto ambig;
- xt = t1;
- }
- /*
- * look it up by type
- */
- if(s->class == CTYPEDEF || s->class == CTYPESTR)
- for(t1 = t; t1 != T; t1 = t1->down)
- if(t1->sym == S && typesu[t1->etype])
- if(sametype(s->type, t1)) {
- if(xt != T)
- goto ambig;
- xt = t1;
- }
- if(xt != T) {
- *off = xt->offset;
- return xt;
- }
- /*
- * look it up in unnamed substructures
- */
- for(t1 = t; t1 != T; t1 = t1->down)
- if(t1->sym == S && typesu[t1->etype]){
- rt = dotsearch(s, t1->link, n, off);
- if(rt != T) {
- if(xt != T)
- goto ambig;
- xt = rt;
- *off += t1->offset;
- }
- }
- return xt;
- ambig:
- diag(n, "ambiguous structure element: %s", s->name);
- return xt;
- }
- long
- dotoffset(Type *st, Type *lt, Node *n)
- {
- Type *t;
- Sym *g;
- long o, o1;
- o = -1;
- /*
- * first try matching at the top level
- * for matching tag names
- */
- g = st->tag;
- if(g != S)
- for(t=lt->link; t!=T; t=t->down)
- if(t->sym == S)
- if(g == t->tag) {
- if(o >= 0)
- goto ambig;
- o = t->offset;
- }
- if(o >= 0)
- return o;
- /*
- * second try matching at the top level
- * for similar types
- */
- for(t=lt->link; t!=T; t=t->down)
- if(t->sym == S)
- if(sametype(st, t)) {
- if(o >= 0)
- goto ambig;
- o = t->offset;
- }
- if(o >= 0)
- return o;
- /*
- * last try matching sub-levels
- */
- for(t=lt->link; t!=T; t=t->down)
- if(t->sym == S)
- if(typesu[t->etype]) {
- o1 = dotoffset(st, t, n);
- if(o1 >= 0) {
- if(o >= 0)
- goto ambig;
- o = o1 + t->offset;
- }
- }
- return o;
- ambig:
- diag(n, "ambiguous unnamed structure element");
- return o;
- }
- /*
- * look into tree for floating point constant expressions
- */
- int
- allfloat(Node *n, int flag)
- {
- if(n != Z) {
- if(n->type->etype != TDOUBLE)
- return 1;
- switch(n->op) {
- case OCONST:
- if(flag)
- n->type = types[TFLOAT];
- return 1;
- case OADD: /* no need to get more exotic than this */
- case OSUB:
- case OMUL:
- case ODIV:
- if(!allfloat(n->right, flag))
- break;
- case OCAST:
- if(!allfloat(n->left, flag))
- break;
- if(flag)
- n->type = types[TFLOAT];
- return 1;
- }
- }
- return 0;
- }
- void
- constas(Node *n, Type *il, Type *ir)
- {
- Type *l, *r;
- l = il;
- r = ir;
- if(l == T)
- return;
- if(l->garb & GCONSTNT) {
- warn(n, "assignment to a constant type (%T)", il);
- return;
- }
- if(r == T)
- return;
- for(;;) {
- if(l->etype != TIND || r->etype != TIND)
- break;
- l = l->link;
- r = r->link;
- if(l == T || r == T)
- break;
- if(r->garb & GCONSTNT)
- if(!(l->garb & GCONSTNT)) {
- warn(n, "assignment of a constant pointer type (%T)", ir);
- break;
- }
- }
- }
- void
- typeext1(Type *st, Node *l)
- {
- if(st->etype == TFLOAT && allfloat(l, 0))
- allfloat(l, 1);
- }
- void
- typeext(Type *st, Node *l)
- {
- Type *lt;
- Node *n1, *n2;
- long o;
- lt = l->type;
- if(lt == T)
- return;
- if(st->etype == TIND && vconst(l) == 0) {
- l->type = st;
- l->vconst = 0;
- return;
- }
- typeext1(st, l);
- /*
- * extension of C
- * if assign of struct containing unnamed sub-struct
- * to type of sub-struct, insert the DOT.
- * if assign of *struct containing unnamed substruct
- * to type of *sub-struct, insert the add-offset
- */
- if(typesu[st->etype] && typesu[lt->etype]) {
- o = dotoffset(st, lt, l);
- if(o >= 0) {
- n1 = new1(OXXX, Z, Z);
- *n1 = *l;
- l->op = ODOT;
- l->left = n1;
- l->right = Z;
- makedot(l, st, o);
- }
- return;
- }
- if(st->etype == TIND && typesu[st->link->etype])
- if(lt->etype == TIND && typesu[lt->link->etype]) {
- o = dotoffset(st->link, lt->link, l);
- if(o >= 0) {
- l->type = st;
- if(o == 0)
- return;
- n1 = new1(OXXX, Z, Z);
- *n1 = *l;
- n2 = new1(OCONST, Z, Z);
- n2->vconst = o;
- n2->type = st;
- l->op = OADD;
- l->left = n1;
- l->right = n2;
- }
- return;
- }
- }
- /*
- * a cast that generates no code
- * (same size move)
- */
- int
- nocast(Type *t1, Type *t2)
- {
- int i, b;
- if(t1->nbits)
- return 0;
- i = 0;
- if(t2 != T)
- i = t2->etype;
- b = 1<<i;
- i = 0;
- if(t1 != T)
- i = t1->etype;
- if(b & ncast[i])
- return 1;
- return 0;
- }
- /*
- * a cast that has a noop semantic
- * (small to large, convert)
- */
- int
- nilcast(Type *t1, Type *t2)
- {
- int et1, et2;
- if(t1 == T)
- return 0;
- if(t1->nbits)
- return 0;
- if(t2 == T)
- return 0;
- et1 = t1->etype;
- et2 = t2->etype;
- if(et1 == et2)
- return 1;
- if(typefd[et1] && typefd[et2]) {
- if(ewidth[et1] < ewidth[et2])
- return 1;
- return 0;
- }
- if(typechlp[et1] && typechlp[et2]) {
- if(ewidth[et1] < ewidth[et2])
- return 1;
- return 0;
- }
- return 0;
- }
- /*
- * "the usual arithmetic conversions are performed"
- */
- void
- arith(Node *n, int f)
- {
- Type *t1, *t2;
- int i, j, k;
- Node *n1;
- long w;
- t1 = n->left->type;
- if(n->right == Z)
- t2 = t1;
- else
- t2 = n->right->type;
- i = TXXX;
- if(t1 != T)
- i = t1->etype;
- j = TXXX;
- if(t2 != T)
- j = t2->etype;
- k = tab[i][j];
- if(k == TIND) {
- if(i == TIND)
- n->type = t1;
- else
- if(j == TIND)
- n->type = t2;
- } else {
- /* convert up to at least int */
- if(f == 1)
- while(k < TINT)
- k += 2;
- n->type = types[k];
- }
- if(n->op == OSUB)
- if(i == TIND && j == TIND) {
- w = n->right->type->link->width;
- if(w < 1 || n->left->type->link == T || n->left->type->link->width < 1)
- goto bad;
- n->type = types[ewidth[TIND] <= ewidth[TLONG]? TLONG: TVLONG];
- if(1 && ewidth[TIND] > ewidth[TLONG]){
- n1 = new1(OXXX, Z, Z);
- *n1 = *n;
- n->op = OCAST;
- n->left = n1;
- n->right = Z;
- n->type = types[TLONG];
- }
- if(w > 1) {
- n1 = new1(OXXX, Z, Z);
- *n1 = *n;
- n->op = ODIV;
- n->left = n1;
- n1 = new1(OCONST, Z, Z);
- n1->vconst = w;
- n1->type = n->type;
- n->right = n1;
- w = vlog(n1);
- if(w >= 0) {
- n->op = OASHR;
- n1->vconst = w;
- }
- }
- return;
- }
- if(!sametype(n->type, n->left->type)) {
- n->left = new1(OCAST, n->left, Z);
- n->left->type = n->type;
- if(n->type->etype == TIND) {
- w = n->type->link->width;
- if(w < 1) {
- snap(n->type->link);
- w = n->type->link->width;
- if(w < 1)
- goto bad;
- }
- if(w > 1) {
- n1 = new1(OCONST, Z, Z);
- n1->vconst = w;
- n1->type = n->type;
- n->left = new1(OMUL, n->left, n1);
- n->left->type = n->type;
- }
- }
- }
- if(n->right != Z)
- if(!sametype(n->type, n->right->type)) {
- n->right = new1(OCAST, n->right, Z);
- n->right->type = n->type;
- if(n->type->etype == TIND) {
- w = n->type->link->width;
- if(w < 1) {
- snap(n->type->link);
- w = n->type->link->width;
- if(w < 1)
- goto bad;
- }
- if(w != 1) {
- n1 = new1(OCONST, Z, Z);
- n1->vconst = w;
- n1->type = n->type;
- n->right = new1(OMUL, n->right, n1);
- n->right->type = n->type;
- }
- }
- }
- return;
- bad:
- diag(n, "pointer addition not fully declared: %T", n->type->link);
- }
- /*
- * try to rewrite shift & mask
- */
- void
- simplifyshift(Node *n)
- {
- ulong c3;
- int o, s1, s2, c1, c2;
- if(!typechlp[n->type->etype])
- return;
- switch(n->op) {
- default:
- return;
- case OASHL:
- s1 = 0;
- break;
- case OLSHR:
- s1 = 1;
- break;
- case OASHR:
- s1 = 2;
- break;
- }
- if(n->right->op != OCONST)
- return;
- if(n->left->op != OAND)
- return;
- if(n->left->right->op != OCONST)
- return;
- switch(n->left->left->op) {
- default:
- return;
- case OASHL:
- s2 = 0;
- break;
- case OLSHR:
- s2 = 1;
- break;
- case OASHR:
- s2 = 2;
- break;
- }
- if(n->left->left->right->op != OCONST)
- return;
- c1 = n->right->vconst;
- c2 = n->left->left->right->vconst;
- c3 = n->left->right->vconst;
- /*
- if(debug['h'])
- print("%.3o %ld %ld %d #%.lux\n",
- (s1<<3)|s2, c1, c2, topbit(c3), c3);
- */
- o = n->op;
- switch((s1<<3)|s2) {
- case 000: /* (((e <<u c2) & c3) <<u c1) */
- c3 >>= c2;
- c1 += c2;
- if(c1 >= 32)
- break;
- goto rewrite1;
- case 002: /* (((e >>s c2) & c3) <<u c1) */
- if(topbit(c3) >= (32-c2))
- break;
- case 001: /* (((e >>u c2) & c3) <<u c1) */
- if(c1 > c2) {
- c3 <<= c2;
- c1 -= c2;
- o = OASHL;
- goto rewrite1;
- }
- c3 <<= c1;
- if(c1 == c2)
- goto rewrite0;
- c1 = c2-c1;
- o = OLSHR;
- goto rewrite2;
- case 022: /* (((e >>s c2) & c3) >>s c1) */
- if(c2 <= 0)
- break;
- case 012: /* (((e >>s c2) & c3) >>u c1) */
- if(topbit(c3) >= (32-c2))
- break;
- goto s11;
- case 021: /* (((e >>u c2) & c3) >>s c1) */
- if(topbit(c3) >= 31 && c2 <= 0)
- break;
- goto s11;
- case 011: /* (((e >>u c2) & c3) >>u c1) */
- s11:
- c3 <<= c2;
- c1 += c2;
- if(c1 >= 32)
- break;
- o = OLSHR;
- goto rewrite1;
- case 020: /* (((e <<u c2) & c3) >>s c1) */
- if(topbit(c3) >= 31)
- break;
- case 010: /* (((e <<u c2) & c3) >>u c1) */
- c3 >>= c1;
- if(c1 == c2)
- goto rewrite0;
- if(c1 > c2) {
- c1 -= c2;
- goto rewrite2;
- }
- c1 = c2 - c1;
- o = OASHL;
- goto rewrite2;
- }
- return;
- rewrite0: /* get rid of both shifts */
- if(debug['<'])prtree(n, "rewrite0");
- *n = *n->left;
- n->left = n->left->left;
- n->right->vconst = c3;
- return;
- rewrite1: /* get rid of lower shift */
- if(debug['<'])prtree(n, "rewrite1");
- n->left->left = n->left->left->left;
- n->left->right->vconst = c3;
- n->right->vconst = c1;
- n->op = o;
- return;
- rewrite2: /* get rid of upper shift */
- if(debug['<'])prtree(n, "rewrite2");
- *n = *n->left;
- n->right->vconst = c3;
- n->left->right->vconst = c1;
- n->left->op = o;
- }
- int
- side(Node *n)
- {
- loop:
- if(n != Z)
- switch(n->op) {
- case OCAST:
- case ONOT:
- case OADDR:
- case OIND:
- n = n->left;
- goto loop;
- case OCOND:
- if(side(n->left))
- break;
- n = n->right;
- case OEQ:
- case ONE:
- case OLT:
- case OGE:
- case OGT:
- case OLE:
- case OADD:
- case OSUB:
- case OMUL:
- case OLMUL:
- case ODIV:
- case OLDIV:
- case OLSHR:
- case OASHL:
- case OASHR:
- case OAND:
- case OOR:
- case OXOR:
- case OMOD:
- case OLMOD:
- case OANDAND:
- case OOROR:
- case OCOMMA:
- case ODOT:
- if(side(n->left))
- break;
- n = n->right;
- goto loop;
- case OSIGN:
- case OSIZE:
- case OCONST:
- case OSTRING:
- case OLSTRING:
- case ONAME:
- return 0;
- }
- return 1;
- }
- int
- vconst(Node *n)
- {
- int i;
- if(n == Z)
- goto no;
- if(n->op != OCONST)
- goto no;
- if(n->type == T)
- goto no;
- switch(n->type->etype)
- {
- case TFLOAT:
- case TDOUBLE:
- i = 100;
- if(n->fconst > i || n->fconst < -i)
- goto no;
- i = n->fconst;
- if(i != n->fconst)
- goto no;
- return i;
- case TVLONG:
- case TUVLONG:
- i = n->vconst;
- if(i != n->vconst)
- goto no;
- return i;
- case TCHAR:
- case TUCHAR:
- case TSHORT:
- case TUSHORT:
- case TINT:
- case TUINT:
- case TLONG:
- case TULONG:
- case TIND:
- i = n->vconst;
- if(i != n->vconst)
- goto no;
- return i;
- }
- no:
- return -159; /* first uninteresting constant */
- }
- /*
- * return log(n) if n is a power of 2 constant
- */
- int
- log2(uvlong v)
- {
- int s, i;
- uvlong m;
- s = 0;
- m = MASK(8*sizeof(uvlong));
- for(i=32; i; i>>=1) {
- m >>= i;
- if(!(v & m)) {
- v >>= i;
- s += i;
- }
- }
- if(v == 1)
- return s;
- return -1;
- }
- int
- vlog(Node *n)
- {
- if(n->op != OCONST)
- goto bad;
- if(typefd[n->type->etype])
- goto bad;
- return log2(n->vconst);
- bad:
- return -1;
- }
- int
- topbit(ulong v)
- {
- int i;
- for(i = -1; v; i++)
- v >>= 1;
- return i;
- }
- /*
- * try to cast a constant down
- * rather than cast a variable up
- * example:
- * if(c == 'a')
- */
- void
- relcon(Node *l, Node *r)
- {
- vlong v;
- if(l->op != OCONST)
- return;
- if(r->op != OCAST)
- return;
- if(!nilcast(r->left->type, r->type))
- return;
- switch(r->type->etype) {
- default:
- return;
- case TCHAR:
- case TUCHAR:
- case TSHORT:
- case TUSHORT:
- v = convvtox(l->vconst, r->type->etype);
- if(v != l->vconst)
- return;
- break;
- }
- l->type = r->left->type;
- *r = *r->left;
- }
- int
- relindex(int o)
- {
- switch(o) {
- default:
- diag(Z, "bad in relindex: %O", o);
- case OEQ: return 0;
- case ONE: return 1;
- case OLE: return 2;
- case OLS: return 3;
- case OLT: return 4;
- case OLO: return 5;
- case OGE: return 6;
- case OHS: return 7;
- case OGT: return 8;
- case OHI: return 9;
- }
- }
- Node*
- invert(Node *n)
- {
- Node *i;
- if(n == Z || n->op != OLIST)
- return n;
- i = n;
- for(n = n->left; n != Z; n = n->left) {
- if(n->op != OLIST)
- break;
- i->left = n->right;
- n->right = i;
- i = n;
- }
- i->left = n;
- return i;
- }
- int
- bitno(long b)
- {
- int i;
- for(i=0; i<32; i++)
- if(b & (1L<<i))
- return i;
- diag(Z, "bad in bitno");
- return 0;
- }
- long
- typebitor(long a, long b)
- {
- long c;
- c = a | b;
- if(a & b)
- if((a & b) == BLONG)
- c |= BVLONG; /* long long => vlong */
- else
- warn(Z, "once is enough: %Q", a & b);
- return c;
- }
- void
- diag(Node *n, char *fmt, ...)
- {
- char buf[STRINGSZ];
- va_list arg;
- va_start(arg, fmt);
- vseprint(buf, buf+sizeof(buf), fmt, arg);
- va_end(arg);
- Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf);
- if(debug['X']){
- Bflush(&diagbuf);
- abort();
- }
- if(n != Z)
- if(debug['v'])
- prtree(n, "diagnostic");
- nerrors++;
- if(nerrors > 10) {
- Bprint(&diagbuf, "too many errors\n");
- errorexit();
- }
- }
- void
- warn(Node *n, char *fmt, ...)
- {
- char buf[STRINGSZ];
- va_list arg;
- if(debug['w']) {
- Bprint(&diagbuf, "warning: ");
- va_start(arg, fmt);
- vseprint(buf, buf+sizeof(buf), fmt, arg);
- va_end(arg);
- Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf);
- if(n != Z)
- if(debug['v'])
- prtree(n, "warning");
- }
- }
- void
- yyerror(char *fmt, ...)
- {
- char buf[STRINGSZ];
- va_list arg;
- /*
- * hack to intercept message from yaccpar
- */
- if(strcmp(fmt, "syntax error") == 0) {
- yyerror("syntax error, last name: %s", symb);
- return;
- }
- va_start(arg, fmt);
- vseprint(buf, buf+sizeof(buf), fmt, arg);
- va_end(arg);
- Bprint(&diagbuf, "%L %s\n", lineno, buf);
- nerrors++;
- if(nerrors > 10) {
- Bprint(&diagbuf, "too many errors\n");
- errorexit();
- }
- }
- void
- fatal(Node *n, char *fmt, ...)
- {
- char buf[STRINGSZ];
- va_list arg;
- va_start(arg, fmt);
- vseprint(buf, buf+sizeof(buf), fmt, arg);
- va_end(arg);
- Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf);
- if(debug['X']){
- Bflush(&diagbuf);
- abort();
- }
- if(n != Z)
- if(debug['v'])
- prtree(n, "diagnostic");
- nerrors++;
- errorexit();
- }
- ulong thash1 = 0x2edab8c9;
- ulong thash2 = 0x1dc74fb8;
- ulong thash3 = 0x1f241331;
- ulong thash[NALLTYPES];
- Init thashinit[] =
- {
- TXXX, 0x17527bbd, 0,
- TCHAR, 0x5cedd32b, 0,
- TUCHAR, 0x552c4454, 0,
- TSHORT, 0x63040b4b, 0,
- TUSHORT, 0x32a45878, 0,
- TINT, 0x4151d5bd, 0,
- TUINT, 0x5ae707d6, 0,
- TLONG, 0x5ef20f47, 0,
- TULONG, 0x36d8eb8f, 0,
- TVLONG, 0x6e5e9590, 0,
- TUVLONG, 0x75910105, 0,
- TFLOAT, 0x25fd7af1, 0,
- TDOUBLE, 0x7c40a1b2, 0,
- TIND, 0x1b832357, 0,
- TFUNC, 0x6babc9cb, 0,
- TARRAY, 0x7c50986d, 0,
- TVOID, 0x44112eff, 0,
- TSTRUCT, 0x7c2da3bf, 0,
- TUNION, 0x3eb25e98, 0,
- TENUM, 0x44b54f61, 0,
- TFILE, 0x19242ac3, 0,
- TOLD, 0x22b15988, 0,
- TDOT, 0x0204f6b3, 0,
- -1, 0, 0,
- };
- char* bnames[NALIGN];
- Init bnamesinit[] =
- {
- Axxx, 0, "Axxx",
- Ael1, 0, "el1",
- Ael2, 0, "el2",
- Asu2, 0, "su2",
- Aarg0, 0, "arg0",
- Aarg1, 0, "arg1",
- Aarg2, 0, "arg2",
- Aaut3, 0, "aut3",
- -1, 0, 0,
- };
- char* tnames[NALLTYPES];
- Init tnamesinit[] =
- {
- TXXX, 0, "TXXX",
- TCHAR, 0, "CHAR",
- TUCHAR, 0, "UCHAR",
- TSHORT, 0, "SHORT",
- TUSHORT, 0, "USHORT",
- TINT, 0, "INT",
- TUINT, 0, "UINT",
- TLONG, 0, "LONG",
- TULONG, 0, "ULONG",
- TVLONG, 0, "VLONG",
- TUVLONG, 0, "UVLONG",
- TFLOAT, 0, "FLOAT",
- TDOUBLE, 0, "DOUBLE",
- TIND, 0, "IND",
- TFUNC, 0, "FUNC",
- TARRAY, 0, "ARRAY",
- TVOID, 0, "VOID",
- TSTRUCT, 0, "STRUCT",
- TUNION, 0, "UNION",
- TENUM, 0, "ENUM",
- TFILE, 0, "FILE",
- TOLD, 0, "OLD",
- TDOT, 0, "DOT",
- -1, 0, 0,
- };
- char* gnames[NGTYPES];
- Init gnamesinit[] =
- {
- GXXX, 0, "GXXX",
- GCONSTNT, 0, "CONST",
- GVOLATILE, 0, "VOLATILE",
- GVOLATILE|GCONSTNT, 0, "CONST-VOLATILE",
- -1, 0, 0,
- };
- char* qnames[NALLTYPES];
- Init qnamesinit[] =
- {
- TXXX, 0, "TXXX",
- TCHAR, 0, "CHAR",
- TUCHAR, 0, "UCHAR",
- TSHORT, 0, "SHORT",
- TUSHORT, 0, "USHORT",
- TINT, 0, "INT",
- TUINT, 0, "UINT",
- TLONG, 0, "LONG",
- TULONG, 0, "ULONG",
- TVLONG, 0, "VLONG",
- TUVLONG, 0, "UVLONG",
- TFLOAT, 0, "FLOAT",
- TDOUBLE, 0, "DOUBLE",
- TIND, 0, "IND",
- TFUNC, 0, "FUNC",
- TARRAY, 0, "ARRAY",
- TVOID, 0, "VOID",
- TSTRUCT, 0, "STRUCT",
- TUNION, 0, "UNION",
- TENUM, 0, "ENUM",
- TAUTO, 0, "AUTO",
- TEXTERN, 0, "EXTERN",
- TSTATIC, 0, "STATIC",
- TTYPEDEF, 0, "TYPEDEF",
- TTYPESTR, 0, "TYPESTR",
- TREGISTER, 0, "REGISTER",
- TCONSTNT, 0, "CONSTNT",
- TVOLATILE, 0, "VOLATILE",
- TUNSIGNED, 0, "UNSIGNED",
- TSIGNED, 0, "SIGNED",
- TDOT, 0, "DOT",
- TFILE, 0, "FILE",
- TOLD, 0, "OLD",
- -1, 0, 0,
- };
- char* cnames[NCTYPES];
- Init cnamesinit[] =
- {
- CXXX, 0, "CXXX",
- CAUTO, 0, "AUTO",
- CEXTERN, 0, "EXTERN",
- CGLOBL, 0, "GLOBL",
- CSTATIC, 0, "STATIC",
- CLOCAL, 0, "LOCAL",
- CTYPEDEF, 0, "TYPEDEF",
- CTYPESTR, 0, "TYPESTR",
- CPARAM, 0, "PARAM",
- CSELEM, 0, "SELEM",
- CLABEL, 0, "LABEL",
- CEXREG, 0, "EXREG",
- -1, 0, 0,
- };
- char* onames[OEND+1];
- Init onamesinit[] =
- {
- OXXX, 0, "OXXX",
- OADD, 0, "ADD",
- OADDR, 0, "ADDR",
- OAND, 0, "AND",
- OANDAND, 0, "ANDAND",
- OARRAY, 0, "ARRAY",
- OAS, 0, "AS",
- OASI, 0, "ASI",
- OASADD, 0, "ASADD",
- OASAND, 0, "ASAND",
- OASASHL, 0, "ASASHL",
- OASASHR, 0, "ASASHR",
- OASDIV, 0, "ASDIV",
- OASHL, 0, "ASHL",
- OASHR, 0, "ASHR",
- OASLDIV, 0, "ASLDIV",
- OASLMOD, 0, "ASLMOD",
- OASLMUL, 0, "ASLMUL",
- OASLSHR, 0, "ASLSHR",
- OASMOD, 0, "ASMOD",
- OASMUL, 0, "ASMUL",
- OASOR, 0, "ASOR",
- OASSUB, 0, "ASSUB",
- OASXOR, 0, "ASXOR",
- OBIT, 0, "BIT",
- OBREAK, 0, "BREAK",
- OCASE, 0, "CASE",
- OCAST, 0, "CAST",
- OCOMMA, 0, "COMMA",
- OCOND, 0, "COND",
- OCONST, 0, "CONST",
- OCONTINUE, 0, "CONTINUE",
- ODIV, 0, "DIV",
- ODOT, 0, "DOT",
- ODOTDOT, 0, "DOTDOT",
- ODWHILE, 0, "DWHILE",
- OENUM, 0, "ENUM",
- OEQ, 0, "EQ",
- OFOR, 0, "FOR",
- OFUNC, 0, "FUNC",
- OGE, 0, "GE",
- OGOTO, 0, "GOTO",
- OGT, 0, "GT",
- OHI, 0, "HI",
- OHS, 0, "HS",
- OIF, 0, "IF",
- OIND, 0, "IND",
- OINDREG, 0, "INDREG",
- OINIT, 0, "INIT",
- OLABEL, 0, "LABEL",
- OLDIV, 0, "LDIV",
- OLE, 0, "LE",
- OLIST, 0, "LIST",
- OLMOD, 0, "LMOD",
- OLMUL, 0, "LMUL",
- OLO, 0, "LO",
- OLS, 0, "LS",
- OLSHR, 0, "LSHR",
- OLT, 0, "LT",
- OMOD, 0, "MOD",
- OMUL, 0, "MUL",
- ONAME, 0, "NAME",
- ONE, 0, "NE",
- ONOT, 0, "NOT",
- OOR, 0, "OR",
- OOROR, 0, "OROR",
- OPOSTDEC, 0, "POSTDEC",
- OPOSTINC, 0, "POSTINC",
- OPREDEC, 0, "PREDEC",
- OPREINC, 0, "PREINC",
- OPROTO, 0, "PROTO",
- OREGISTER, 0, "REGISTER",
- ORETURN, 0, "RETURN",
- OSET, 0, "SET",
- OSIGN, 0, "SIGN",
- OSIZE, 0, "SIZE",
- OSTRING, 0, "STRING",
- OLSTRING, 0, "LSTRING",
- OSTRUCT, 0, "STRUCT",
- OSUB, 0, "SUB",
- OSWITCH, 0, "SWITCH",
- OUNION, 0, "UNION",
- OUSED, 0, "USED",
- OWHILE, 0, "WHILE",
- OXOR, 0, "XOR",
- OPOS, 0, "POS",
- ONEG, 0, "NEG",
- OCOM, 0, "COM",
- OELEM, 0, "ELEM",
- OTST, 0, "TST",
- OINDEX, 0, "INDEX",
- OFAS, 0, "FAS",
- OREGPAIR, 0, "REGPAIR",
- OEND, 0, "END",
- -1, 0, 0,
- };
- /* OEQ, ONE, OLE, OLS, OLT, OLO, OGE, OHS, OGT, OHI */
- char comrel[12] =
- {
- ONE, OEQ, OGT, OHI, OGE, OHS, OLT, OLO, OLE, OLS,
- };
- char invrel[12] =
- {
- OEQ, ONE, OGE, OHS, OGT, OHI, OLE, OLS, OLT, OLO,
- };
- char logrel[12] =
- {
- OEQ, ONE, OLS, OLS, OLO, OLO, OHS, OHS, OHI, OHI,
- };
- char typei[NTYPE];
- int typeiinit[] =
- {
- TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TVLONG, TUVLONG, -1,
- };
- char typeu[NTYPE];
- int typeuinit[] =
- {
- TUCHAR, TUSHORT, TUINT, TULONG, TUVLONG, TIND, -1,
- };
- char typesuv[NTYPE];
- int typesuvinit[] =
- {
- TVLONG, TUVLONG, TSTRUCT, TUNION, -1,
- };
- char typeilp[NTYPE];
- int typeilpinit[] =
- {
- TINT, TUINT, TLONG, TULONG, TIND, -1
- };
- char typechl[NTYPE];
- char typechlv[NTYPE];
- char typechlvp[NTYPE];
- int typechlinit[] =
- {
- TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, -1,
- };
- char typechlp[NTYPE];
- int typechlpinit[] =
- {
- TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TIND, -1,
- };
- char typechlpfd[NTYPE];
- int typechlpfdinit[] =
- {
- TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TFLOAT, TDOUBLE, TIND, -1,
- };
- char typec[NTYPE];
- int typecinit[] =
- {
- TCHAR, TUCHAR, -1
- };
- char typeh[NTYPE];
- int typehinit[] =
- {
- TSHORT, TUSHORT, -1,
- };
- char typeil[NTYPE];
- int typeilinit[] =
- {
- TINT, TUINT, TLONG, TULONG, -1,
- };
- char typev[NTYPE];
- int typevinit[] =
- {
- TVLONG, TUVLONG, -1,
- };
- char typefd[NTYPE];
- int typefdinit[] =
- {
- TFLOAT, TDOUBLE, -1,
- };
- char typeaf[NTYPE];
- int typeafinit[] =
- {
- TFUNC, TARRAY, -1,
- };
- char typesu[NTYPE];
- int typesuinit[] =
- {
- TSTRUCT, TUNION, -1,
- };
- long tasign[NTYPE];
- Init tasigninit[] =
- {
- TCHAR, BNUMBER, 0,
- TUCHAR, BNUMBER, 0,
- TSHORT, BNUMBER, 0,
- TUSHORT, BNUMBER, 0,
- TINT, BNUMBER, 0,
- TUINT, BNUMBER, 0,
- TLONG, BNUMBER, 0,
- TULONG, BNUMBER, 0,
- TVLONG, BNUMBER, 0,
- TUVLONG, BNUMBER, 0,
- TFLOAT, BNUMBER, 0,
- TDOUBLE, BNUMBER, 0,
- TIND, BIND, 0,
- TSTRUCT, BSTRUCT, 0,
- TUNION, BUNION, 0,
- -1, 0, 0,
- };
- long tasadd[NTYPE];
- Init tasaddinit[] =
- {
- TCHAR, BNUMBER, 0,
- TUCHAR, BNUMBER, 0,
- TSHORT, BNUMBER, 0,
- TUSHORT, BNUMBER, 0,
- TINT, BNUMBER, 0,
- TUINT, BNUMBER, 0,
- TLONG, BNUMBER, 0,
- TULONG, BNUMBER, 0,
- TVLONG, BNUMBER, 0,
- TUVLONG, BNUMBER, 0,
- TFLOAT, BNUMBER, 0,
- TDOUBLE, BNUMBER, 0,
- TIND, BINTEGER, 0,
- -1, 0, 0,
- };
- long tcast[NTYPE];
- Init tcastinit[] =
- {
- TCHAR, BNUMBER|BIND|BVOID, 0,
- TUCHAR, BNUMBER|BIND|BVOID, 0,
- TSHORT, BNUMBER|BIND|BVOID, 0,
- TUSHORT, BNUMBER|BIND|BVOID, 0,
- TINT, BNUMBER|BIND|BVOID, 0,
- TUINT, BNUMBER|BIND|BVOID, 0,
- TLONG, BNUMBER|BIND|BVOID, 0,
- TULONG, BNUMBER|BIND|BVOID, 0,
- TVLONG, BNUMBER|BIND|BVOID, 0,
- TUVLONG, BNUMBER|BIND|BVOID, 0,
- TFLOAT, BNUMBER|BVOID, 0,
- TDOUBLE, BNUMBER|BVOID, 0,
- TIND, BINTEGER|BIND|BVOID, 0,
- TVOID, BVOID, 0,
- TSTRUCT, BSTRUCT|BVOID, 0,
- TUNION, BUNION|BVOID, 0,
- -1, 0, 0,
- };
- long tadd[NTYPE];
- Init taddinit[] =
- {
- TCHAR, BNUMBER|BIND, 0,
- TUCHAR, BNUMBER|BIND, 0,
- TSHORT, BNUMBER|BIND, 0,
- TUSHORT, BNUMBER|BIND, 0,
- TINT, BNUMBER|BIND, 0,
- TUINT, BNUMBER|BIND, 0,
- TLONG, BNUMBER|BIND, 0,
- TULONG, BNUMBER|BIND, 0,
- TVLONG, BNUMBER|BIND, 0,
- TUVLONG, BNUMBER|BIND, 0,
- TFLOAT, BNUMBER, 0,
- TDOUBLE, BNUMBER, 0,
- TIND, BINTEGER, 0,
- -1, 0, 0,
- };
- long tsub[NTYPE];
- Init tsubinit[] =
- {
- TCHAR, BNUMBER, 0,
- TUCHAR, BNUMBER, 0,
- TSHORT, BNUMBER, 0,
- TUSHORT, BNUMBER, 0,
- TINT, BNUMBER, 0,
- TUINT, BNUMBER, 0,
- TLONG, BNUMBER, 0,
- TULONG, BNUMBER, 0,
- TVLONG, BNUMBER, 0,
- TUVLONG, BNUMBER, 0,
- TFLOAT, BNUMBER, 0,
- TDOUBLE, BNUMBER, 0,
- TIND, BINTEGER|BIND, 0,
- -1, 0, 0,
- };
- long tmul[NTYPE];
- Init tmulinit[] =
- {
- TCHAR, BNUMBER, 0,
- TUCHAR, BNUMBER, 0,
- TSHORT, BNUMBER, 0,
- TUSHORT, BNUMBER, 0,
- TINT, BNUMBER, 0,
- TUINT, BNUMBER, 0,
- TLONG, BNUMBER, 0,
- TULONG, BNUMBER, 0,
- TVLONG, BNUMBER, 0,
- TUVLONG, BNUMBER, 0,
- TFLOAT, BNUMBER, 0,
- TDOUBLE, BNUMBER, 0,
- -1, 0, 0,
- };
- long tand[NTYPE];
- Init tandinit[] =
- {
- TCHAR, BINTEGER, 0,
- TUCHAR, BINTEGER, 0,
- TSHORT, BINTEGER, 0,
- TUSHORT, BINTEGER, 0,
- TINT, BNUMBER, 0,
- TUINT, BNUMBER, 0,
- TLONG, BINTEGER, 0,
- TULONG, BINTEGER, 0,
- TVLONG, BINTEGER, 0,
- TUVLONG, BINTEGER, 0,
- -1, 0, 0,
- };
- long trel[NTYPE];
- Init trelinit[] =
- {
- TCHAR, BNUMBER, 0,
- TUCHAR, BNUMBER, 0,
- TSHORT, BNUMBER, 0,
- TUSHORT, BNUMBER, 0,
- TINT, BNUMBER, 0,
- TUINT, BNUMBER, 0,
- TLONG, BNUMBER, 0,
- TULONG, BNUMBER, 0,
- TVLONG, BNUMBER, 0,
- TUVLONG, BNUMBER, 0,
- TFLOAT, BNUMBER, 0,
- TDOUBLE, BNUMBER, 0,
- TIND, BIND, 0,
- -1, 0, 0,
- };
- long tfunct[1] =
- {
- BFUNC,
- };
- long tindir[1] =
- {
- BIND,
- };
- long tdot[1] =
- {
- BSTRUCT|BUNION,
- };
- long tnot[1] =
- {
- BNUMBER|BIND,
- };
- long targ[1] =
- {
- BNUMBER|BIND|BSTRUCT|BUNION,
- };
- char tab[NTYPE][NTYPE] =
- {
- /*TXXX*/ { 0,
- },
- /*TCHAR*/ { 0, TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG,
- TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
- },
- /*TUCHAR*/ { 0, TUCHAR, TUCHAR, TUSHORT, TUSHORT, TUINT, TUINT, TULONG,
- TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
- },
- /*TSHORT*/ { 0, TSHORT, TUSHORT, TSHORT, TUSHORT, TINT, TUINT, TLONG,
- TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
- },
- /*TUSHORT*/ { 0, TUSHORT, TUSHORT, TUSHORT, TUSHORT, TUINT, TUINT, TULONG,
- TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
- },
- /*TINT*/ { 0, TINT, TUINT, TINT, TUINT, TINT, TUINT, TLONG,
- TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
- },
- /*TUINT*/ { 0, TUINT, TUINT, TUINT, TUINT, TUINT, TUINT, TULONG,
- TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
- },
- /*TLONG*/ { 0, TLONG, TULONG, TLONG, TULONG, TLONG, TULONG, TLONG,
- TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
- },
- /*TULONG*/ { 0, TULONG, TULONG, TULONG, TULONG, TULONG, TULONG, TULONG,
- TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
- },
- /*TVLONG*/ { 0, TVLONG, TUVLONG, TVLONG, TUVLONG, TVLONG, TUVLONG, TVLONG,
- TUVLONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
- },
- /*TUVLONG*/ { 0, TUVLONG, TUVLONG, TUVLONG, TUVLONG, TUVLONG, TUVLONG, TUVLONG,
- TUVLONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND,
- },
- /*TFLOAT*/ { 0, TFLOAT, TFLOAT, TFLOAT, TFLOAT, TFLOAT, TFLOAT, TFLOAT,
- TFLOAT, TFLOAT, TFLOAT, TFLOAT, TDOUBLE, TIND,
- },
- /*TDOUBLE*/ { 0, TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE,
- TDOUBLE, TDOUBLE, TDOUBLE, TFLOAT, TDOUBLE, TIND,
- },
- /*TIND*/ { 0, TIND, TIND, TIND, TIND, TIND, TIND, TIND,
- TIND, TIND, TIND, TIND, TIND, TIND,
- },
- };
- void
- urk(char *name, int max, int i)
- {
- if(i >= max) {
- fprint(2, "bad tinit: %s %d>=%d\n", name, i, max);
- exits("init");
- }
- }
- void
- tinit(void)
- {
- int *ip;
- Init *p;
- for(p=thashinit; p->code >= 0; p++) {
- urk("thash", nelem(thash), p->code);
- thash[p->code] = p->value;
- }
- for(p=bnamesinit; p->code >= 0; p++) {
- urk("bnames", nelem(bnames), p->code);
- bnames[p->code] = p->s;
- }
- for(p=tnamesinit; p->code >= 0; p++) {
- urk("tnames", nelem(tnames), p->code);
- tnames[p->code] = p->s;
- }
- for(p=gnamesinit; p->code >= 0; p++) {
- urk("gnames", nelem(gnames), p->code);
- gnames[p->code] = p->s;
- }
- for(p=qnamesinit; p->code >= 0; p++) {
- urk("qnames", nelem(qnames), p->code);
- qnames[p->code] = p->s;
- }
- for(p=cnamesinit; p->code >= 0; p++) {
- urk("cnames", nelem(cnames), p->code);
- cnames[p->code] = p->s;
- }
- for(p=onamesinit; p->code >= 0; p++) {
- urk("onames", nelem(onames), p->code);
- onames[p->code] = p->s;
- }
- for(ip=typeiinit; *ip>=0; ip++) {
- urk("typei", nelem(typei), *ip);
- typei[*ip] = 1;
- }
- for(ip=typeuinit; *ip>=0; ip++) {
- urk("typeu", nelem(typeu), *ip);
- typeu[*ip] = 1;
- }
- for(ip=typesuvinit; *ip>=0; ip++) {
- urk("typesuv", nelem(typesuv), *ip);
- typesuv[*ip] = 1;
- }
- for(ip=typeilpinit; *ip>=0; ip++) {
- urk("typeilp", nelem(typeilp), *ip);
- typeilp[*ip] = 1;
- }
- for(ip=typechlinit; *ip>=0; ip++) {
- urk("typechl", nelem(typechl), *ip);
- typechl[*ip] = 1;
- typechlv[*ip] = 1;
- typechlvp[*ip] = 1;
- }
- for(ip=typechlpinit; *ip>=0; ip++) {
- urk("typechlp", nelem(typechlp), *ip);
- typechlp[*ip] = 1;
- typechlvp[*ip] = 1;
- }
- for(ip=typechlpfdinit; *ip>=0; ip++) {
- urk("typechlpfd", nelem(typechlpfd), *ip);
- typechlpfd[*ip] = 1;
- }
- for(ip=typecinit; *ip>=0; ip++) {
- urk("typec", nelem(typec), *ip);
- typec[*ip] = 1;
- }
- for(ip=typehinit; *ip>=0; ip++) {
- urk("typeh", nelem(typeh), *ip);
- typeh[*ip] = 1;
- }
- for(ip=typeilinit; *ip>=0; ip++) {
- urk("typeil", nelem(typeil), *ip);
- typeil[*ip] = 1;
- }
- for(ip=typevinit; *ip>=0; ip++) {
- urk("typev", nelem(typev), *ip);
- typev[*ip] = 1;
- typechlv[*ip] = 1;
- typechlvp[*ip] = 1;
- }
- for(ip=typefdinit; *ip>=0; ip++) {
- urk("typefd", nelem(typefd), *ip);
- typefd[*ip] = 1;
- }
- for(ip=typeafinit; *ip>=0; ip++) {
- urk("typeaf", nelem(typeaf), *ip);
- typeaf[*ip] = 1;
- }
- for(ip=typesuinit; *ip >= 0; ip++) {
- urk("typesu", nelem(typesu), *ip);
- typesu[*ip] = 1;
- }
- for(p=tasigninit; p->code >= 0; p++) {
- urk("tasign", nelem(tasign), p->code);
- tasign[p->code] = p->value;
- }
- for(p=tasaddinit; p->code >= 0; p++) {
- urk("tasadd", nelem(tasadd), p->code);
- tasadd[p->code] = p->value;
- }
- for(p=tcastinit; p->code >= 0; p++) {
- urk("tcast", nelem(tcast), p->code);
- tcast[p->code] = p->value;
- }
- for(p=taddinit; p->code >= 0; p++) {
- urk("tadd", nelem(tadd), p->code);
- tadd[p->code] = p->value;
- }
- for(p=tsubinit; p->code >= 0; p++) {
- urk("tsub", nelem(tsub), p->code);
- tsub[p->code] = p->value;
- }
- for(p=tmulinit; p->code >= 0; p++) {
- urk("tmul", nelem(tmul), p->code);
- tmul[p->code] = p->value;
- }
- for(p=tandinit; p->code >= 0; p++) {
- urk("tand", nelem(tand), p->code);
- tand[p->code] = p->value;
- }
- for(p=trelinit; p->code >= 0; p++) {
- urk("trel", nelem(trel), p->code);
- trel[p->code] = p->value;
- }
-
- /* 32-bit defaults */
- typeword = typechlp;
- typecmplx = typesuv;
- }
- /*
- * return 1 if it is impossible to jump into the middle of n.
- */
- static int
- deadhead(Node *n, int caseok)
- {
- loop:
- if(n == Z)
- return 1;
- switch(n->op) {
- case OLIST:
- if(!deadhead(n->left, caseok))
- return 0;
- rloop:
- n = n->right;
- goto loop;
- case ORETURN:
- break;
- case OLABEL:
- return 0;
- case OGOTO:
- break;
- case OCASE:
- if(!caseok)
- return 0;
- goto rloop;
- case OSWITCH:
- return deadhead(n->right, 1);
- case OWHILE:
- case ODWHILE:
- goto rloop;
- case OFOR:
- goto rloop;
- case OCONTINUE:
- break;
- case OBREAK:
- break;
- case OIF:
- return deadhead(n->right->left, caseok) && deadhead(n->right->right, caseok);
- case OSET:
- case OUSED:
- break;
- }
- return 1;
- }
- int
- deadheads(Node *c)
- {
- return deadhead(c->left, 0) && deadhead(c->right, 0);
- }
- int
- mixedasop(Type *l, Type *r)
- {
- return !typefd[l->etype] && typefd[r->etype];
- }
|