|
|
1.1 ! root 1: #include "gencode.h" ! 2: char *jeq = "jeql"; ! 3: char *jne = "jneq"; ! 4: char *jgt = "jgtr"; ! 5: char *jge = "jgeq"; ! 6: char *jlt = "jlss"; ! 7: char *jle = "jleq"; ! 8: char *jugt = "jgtru"; ! 9: char *juge = "jgequ"; ! 10: char *jult = "jlssu"; ! 11: char *jule = "jlequ"; ! 12: mnod *gimmemnod(); ! 13: ! 14: char prbuf[10*1024]; ! 15: extern int bothdebug, nosharp; ! 16: #define NBUF 256 /* must fit in an unsigned char */ ! 17: char bufs[NBUF][BUF], *buf; ! 18: char *bufend = (char *)bufs + sizeof(bufs); ! 19: pr(fmt, list) ! 20: char *fmt; long list; ! 21: { char *n; ! 22: char *sprintxl(); ! 23: nosharp = !bothdebug; ! 24: prptr = sprintxl(n=prptr, fmt, &list); ! 25: if(prptr > prbuf + sizeof(prbuf)) ! 26: cerror("prbuf overflow"); ! 27: nosharp = 0; ! 28: } ! 29: ! 30: outpr() ! 31: { ! 32: *prptr = 0; ! 33: printbuf(prbuf, prptr-prbuf); ! 34: } ! 35: ! 36: ret ! 37: checksize(p, s, regmask) ! 38: mnod *p; ! 39: ret s; ! 40: { ret t; ! 41: if(p->type != Tdouble) ! 42: return(s); ! 43: regmask |= s.regmask; ! 44: t = allocreg(p, regmask); ! 45: return(t); ! 46: } ! 47: ! 48: gimmetemp(n) ! 49: { ! 50: return(freetemp(n)/8 - maxboff/SZCHAR); ! 51: } ! 52: ! 53: commutes(op) ! 54: { ! 55: switch(op) { ! 56: default: ! 57: cerror("unexpected op in commutes"); ! 58: case Plus: case Mul: case Or: case Xor: case And: ! 59: return(1); ! 60: case Minus: case Div: case Mod: ! 61: return(0); ! 62: } ! 63: } ! 64: ! 65: strshift(s, n) ! 66: char *s; ! 67: { int i, j; ! 68: i = strlen(s); ! 69: if(n > 0) ! 70: for(j = i; j >= 0; j--) ! 71: s[j + n] = s[j]; ! 72: else ! 73: for(j = -n; j <= i; j++) ! 74: s[j + n] = s[j]; ! 75: } ! 76: ! 77: ret ! 78: tostack() ! 79: { ret s; ! 80: sprintx(buf, "-(sp)"); ! 81: done(s, 0, 0); ! 82: } ! 83: ! 84: char * ! 85: genjbc(n) ! 86: { ! 87: if(n == EQ) ! 88: return("jbc"); ! 89: if(n == NE) ! 90: return("jbs"); ! 91: cerror("impossible jmp mask type"); ! 92: return("jweird"); ! 93: } ! 94: ! 95: char * ! 96: genjmp(n) ! 97: { ! 98: switch(n) { ! 99: default: cerror("impossible jmp type"); return("jweird"); ! 100: case EQ: return(jeq); ! 101: case NE: return(jne); ! 102: case GT: return(jgt); ! 103: case GE: return(jge); ! 104: case LT: return(jlt); ! 105: case LE: return(jle); ! 106: case UGT: return(jugt); ! 107: case UGE: return(juge); ! 108: case ULT: return(jult); ! 109: case ULE: return(jule); ! 110: } ! 111: } ! 112: ! 113: pow2(n) ! 114: { int i; ! 115: if(n & (n-1)) ! 116: return(-1); ! 117: for(i = 0; i < 32; i++) /* good old vax */ ! 118: if(n & (1 << i)) ! 119: return(i); ! 120: return(-1); /* can't happen */ ! 121: } ! 122: ! 123: ret ! 124: indirit(s) ! 125: ret s; ! 126: { ! 127: if(s.flag & ISREG) { ! 128: strcat(str(s), ")"); ! 129: strshift(str(s), 1); ! 130: str(s)[0] = '('; ! 131: return(s); ! 132: } ! 133: if(s.flag & CANINDIR) { ! 134: strshift(str(s), 1); ! 135: str(s)[0] = '*'; ! 136: return(s); ! 137: } ! 138: if(str(s)[0] == '(') { /* (r3)[r11] */ ! 139: strshift(str(s), 1); ! 140: str(s)[0] = '*'; ! 141: return(s); ! 142: } ! 143: if(str(s)[0] == '$') { /* an icon for structure returns */ ! 144: strshift(str(s), -1); ! 145: return(s); ! 146: } ! 147: debugpr("# FAIL "); ! 148: s.flag = FAIL; ! 149: return(s); ! 150: } ! 151: ! 152: ret /* unseal the seals for Stasg */ ! 153: addrsimp(a, b) ! 154: ret a, b; ! 155: { extern char *index(); ! 156: char *p; ! 157: if(str(b)[0] == '(') { /* posit register */ ! 158: reg: ! 159: strshift(str(b), -1); ! 160: *index(str(b), ')') = 0; ! 161: return(b); ! 162: } ! 163: if(str(a)[0] == '(') { /* posit register */ ! 164: b = a; ! 165: goto reg; ! 166: } ! 167: if(str(b)[0] == '_') { /* posit name of struct */ ! 168: name: ! 169: pr("#\tmoval\t%s,r0\n", str(b)); ! 170: b.regmask = 1; ! 171: b.flag = ISREG|SCRATCH; ! 172: strcpy(str(b), "r0"); /* arrrrrgh */ ! 173: return(b); ! 174: } ! 175: if(str(a)[0] == '_') { ! 176: b = a; ! 177: goto name; ! 178: } ! 179: if(str(b)[0] == '*') { ! 180: unstar: ! 181: p = index(str(b), '+'); ! 182: if(!p) ! 183: p = index(str(b), '-'); ! 184: if(p && (*(p+1) == 0 || *(p+1) == '(')) ! 185: goto bad; ! 186: strshift(str(b), -1); ! 187: return(b); ! 188: } ! 189: if(str(a)[0] == '*') { ! 190: b = a; ! 191: goto unstar; ! 192: } ! 193: if(str(b)[0] == 'L') { ! 194: label: ! 195: strshift(str(b), 1); ! 196: str(b)[0] = '&'; ! 197: return(b); ! 198: } ! 199: if(str(a)[0] == 'L') { ! 200: b = a; ! 201: goto label; ! 202: } ! 203: bad: ! 204: cerror("(addrsimp) rewrite struct asg"); ! 205: } ! 206: ! 207: ret ! 208: simpler(a, b) /* returns b (as dest) preferentially */ ! 209: ret a, b; ! 210: { ! 211: if(b.flag & ISREG) ! 212: return(b); ! 213: if(a.flag & ISREG) ! 214: return(a); ! 215: if(b.flag & SCRATCH) ! 216: return(b); ! 217: if(a.flag & SCRATCH) ! 218: return(a); ! 219: if(!(b.flag & INDEX)) ! 220: return(b); ! 221: if(!(a.flag & INDEX)) ! 222: return(a); ! 223: /* disallow *p++ = *q++ but not p[i]=q[i]*/ ! 224: if(!index(str(b), '-') && !index(str(b), '+')) ! 225: return(b); ! 226: if(!index(str(a), '-') && !index(str(a), '+')) ! 227: return(a); ! 228: b.flag |= USED; ! 229: return(b); ! 230: } ! 231: ! 232: hasqnode(p) ! 233: mnod *p; ! 234: { ! 235: if(p->op == Asg && p->left->op == Qnode) { ! 236: return(1); ! 237: } ! 238: if(1) { ! 239: return(0); ! 240: } ! 241: switch(p->op) { ! 242: default: ! 243: cerror("hasqnode\n"); ! 244: case Andeq: case And: case Cmp: case Comop: case Decr: ! 245: case Diveq: case Div: case Xoreq: case Xor: ! 246: case Incr: case Lseq: case Ls: case Minuseq: case Minus: ! 247: case Modeq: case Mod: case Muleq: case Mul: case Oreq: ! 248: case Or: case Pluseq: case Plus: case Rseq: case Rs: ! 249: case Asg: case Cm: ! 250: case Call: case Stcall: ! 251: case Stasg: ! 252: return(hasqnode(p->left) || hasqnode(p->right)); ! 253: case Compl: case Conv: case Genbr: case Genlab: ! 254: case Genubr: case Star: case Addr: case Ucall: ! 255: case Uminus: case Ustcall: case Init: case Funarg: ! 256: case Fld:case Starg: ! 257: return(hasqnode(p->left)); ! 258: case Auto: case Reg: case Name: case Param: case Icon: ! 259: case Snode: case Rnode: ! 260: return(0); ! 261: case Qnode: ! 262: return(1); ! 263: } ! 264: } ! 265: ! 266: mnod * ! 267: copytree(p) ! 268: NODE *p; ! 269: { mnod *a, *b, *c; ! 270: c = gimmemnod(); ! 271: switch(p->in.op) { ! 272: case ASG AND: case AND: case CMP: case COMOP: case DECR: ! 273: case ASG DIV: case DIV: case ASG ER: case ER: ! 274: case INCR: case ASG LS: case LS: case ASG MINUS: case MINUS: ! 275: case ASG MOD: case MOD: case ASG MUL: case MUL: case ASG OR: ! 276: case OR: case ASG PLUS: case PLUS: case ASG RS: case RS: ! 277: case ASSIGN: case CM: ! 278: a = copytree(p->in.left); ! 279: b = copytree(p->in.right); ! 280: c->left = a; ! 281: c->right = b; ! 282: break; ! 283: case CALL: case STCALL: ! 284: a = copytree(p->in.left); ! 285: b = copytree(p->in.right); ! 286: c->argsize = p->stn.argsize; ! 287: c->left = a; ! 288: c->right = b; ! 289: break; ! 290: case STASG: ! 291: a = copytree(p->in.left); ! 292: b = copytree(p->in.right); ! 293: c->stsize = p->stn.stsize; ! 294: c->left = a; ! 295: c->right = b; ! 296: break; ! 297: case COMPL: case CONV: case GENBR: case GENLAB: ! 298: case GENUBR: case STAR: case UNARY AND: case UNARY CALL: ! 299: case UNARY MINUS: case UNARY STCALL: case INIT: case FUNARG: ! 300: a = copytree(p->in.left); ! 301: c->label = p->bn.label; /* should be separated out */ ! 302: c->lop = p->bn.lop; ! 303: c->left = a; ! 304: break; ! 305: case FLD:case STARG: ! 306: a = copytree(p->in.left); ! 307: c->left = a; ! 308: c->rval = p->tn.rval; ! 309: c->stsize = p->stn.stsize; ! 310: break; ! 311: case VAUTO: case REG: case NAME: case VPARAM: case ICON: ! 312: case SNODE: case RNODE: case QNODE: ! 313: c->name = p->tn.name; ! 314: c->lval = p->tn.lval; ! 315: c->rval = p->tn.rval; ! 316: break; ! 317: } ! 318: switch(p->in.op) { ! 319: default: ! 320: cerror("unk op in copytree"); ! 321: case ASG AND: c->op = Andeq; break; ! 322: case AND: c->op = And; break; ! 323: case CMP: c->op = Cmp; break; ! 324: case COMOP: c->op = Comop; break; ! 325: case DECR: c->op = Decr; break; ! 326: case ASG DIV: c->op = Diveq; break; ! 327: case DIV: c->op = Div; break; ! 328: case ASG ER: c->op = Xoreq; break; ! 329: case ER: c->op = Xor; break; ! 330: case INCR: c->op = Incr; break; ! 331: case ASG LS: c->op = Lseq; break; ! 332: case LS: c->op = Ls; break; ! 333: case ASG MINUS: c->op = Minuseq; break; ! 334: case MINUS: c->op = Minus; break; ! 335: case ASG MOD: c->op = Modeq; break; ! 336: case MOD: c->op = Mod; break; ! 337: case ASG MUL: c->op = Muleq; break; ! 338: case MUL: c->op = Mul; break; ! 339: case ASG OR: c->op = Oreq; break; ! 340: case OR: c->op = Or; break; ! 341: case ASG PLUS: c->op = Pluseq; break; ! 342: case PLUS: c->op = Plus; break; ! 343: case ASG RS: c->op = Rseq; break; ! 344: case RS: c->op = Rs; break; ! 345: case ASSIGN: c->op = Asg; break; ! 346: case CM: c->op = Cm; break; ! 347: case CALL: c->op = Call; break; ! 348: case STCALL: c->op = Stcall; break; ! 349: case STASG: c->op = Stasg; break; ! 350: case COMPL: c->op = Compl; break; ! 351: case CONV: c->op = Conv; break; ! 352: case GENBR: c->op = Genbr; break; ! 353: case GENLAB: c->op = Genlab; break; ! 354: case GENUBR: c->op = Genubr; break; ! 355: case STAR: c->op = Star; break; ! 356: case UNARY AND: c->op = Addr; break; ! 357: case UNARY CALL: c->op = Ucall; break; ! 358: case UNARY MINUS: c->op = Uminus; break; ! 359: case UNARY STCALL: c->op = Ustcall; break; ! 360: case INIT: c->op = Init; break; ! 361: case FUNARG: c->op = Funarg; break; ! 362: case FLD: c->op = Fld; break; ! 363: case STARG: c->op = Starg; break; ! 364: case VAUTO: c->op = Auto; break; ! 365: case REG: c->op = Reg; break; ! 366: case NAME: c->op = Name; break; ! 367: case VPARAM: c->op = Param; break; ! 368: case ICON: c->op = Icon; break; ! 369: case SNODE: c->op = Snode; break; ! 370: case QNODE: c->op = Qnode; break; ! 371: case RNODE: c->op = Rnode; break; ! 372: } ! 373: switch(p->in.type) { ! 374: default: ! 375: cerror("incomprehensible type"); ! 376: case TCHAR: c->type = Tchar; break; ! 377: case TUCHAR: c->type = Tuchar; break; ! 378: case TSHORT: c->type = Tshort; break; ! 379: case TUSHORT: c->type = Tushort; break; ! 380: case TINT: c->type = Tint; break; ! 381: case TUNSIGNED: c->type = Tuint; break; ! 382: case TLONG: c->type = Tlong; break; ! 383: case TULONG: c->type = Tulong; break; ! 384: case TPOINT: c->type = Tpoint; break; ! 385: case TFLOAT: c->type = Tfloat; break; ! 386: case TDOUBLE: c->type = Tdouble; break; ! 387: case TSTRUCT: c->type = Tstruct; break; ! 388: case TVOID: c->type = Tvoid; break; ! 389: } ! 390: } ! 391: ! 392: /* does p contain an asgop or Incr (or could it be evaluated twice) */ ! 393: sideffects(p) ! 394: mnod *p; ! 395: { ! 396: switch(p->op) { ! 397: case Andeq: case Decr: case Diveq: case Xoreq: case Incr: ! 398: case Lseq: case Minuseq:case Modeq: case Muleq: case Oreq: ! 399: case Pluseq: case Rseq: case Call: case Stcall: case Ucall: ! 400: return(1); ! 401: case And: case Cmp: case Comop: case Div: case Xor: ! 402: case Ls: case Minus: case Mod: case Mul: ! 403: case Or: case Plus: case Rs: case Asg: case Cm: case Stasg: ! 404: return(sideffects(p->left) || sideffects(p->right)); ! 405: case Compl: case Conv: case Genbr: case Genlab: ! 406: case Genubr: case Star: case Addr: ! 407: case Uminus: case Ustcall: case Init: case Funarg: ! 408: case Fld: case Starg: ! 409: return(sideffects(p->left)); ! 410: case Auto: case Reg: case Name: case Param: case Icon: ! 411: case Snode: case Rnode: case Qnode: ! 412: return(0); ! 413: default: ! 414: cerror("unk mnod in sideffects"); ! 415: } ! 416: } ! 417: /* to make up for pointless 9th edition name change */ ! 418: char * ! 419: index(s, c) ! 420: char *s; ! 421: { ! 422: return(strchr(s, c)); ! 423: } ! 424: ! 425: char * ! 426: rindex(s, c) ! 427: { ! 428: return(strrchr(s, c)); ! 429: } ! 430: ! 431: overr() ! 432: { ! 433: cerror("expression too complicated"); ! 434: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.