|
|
1.1 ! root 1: /* @(#) local2.c : 1.6 3/14/84 */ ! 2: /* local2.c - machine dependent grunge for back end ! 3: * ! 4: * Bellmac32 ! 5: * R. J. Mascitti ! 6: */ ! 7: ! 8: # include "mfile2.h" ! 9: # define istnode(p) (p->in.op==REG && istreg(p->tn.rval)) ! 10: # define STHRESH 6 /* max # of words to unroll copy loop */ ! 11: ! 12: static int strcall; /* have we made a call to a structure function? */ ! 13: ! 14: ! 15: ! 16: lineid(l, fn) /* identify line l and file fn */ ! 17: int l; ! 18: char *fn; ! 19: { ! 20: printf("# line %d, file %s\n", l, fn); ! 21: } ! 22: ! 23: ! 24: eobl2() /* end of function stuff */ ! 25: { ! 26: strcall = 0; ! 27: eobl2dbg(); /* very end debug code */ ! 28: } ! 29: ! 30: ! 31: char *rnames[]= ! 32: { ! 33: "%r0", ! 34: "%r1", ! 35: "%r2", ! 36: "%r3", ! 37: "%r4", ! 38: "%r5", ! 39: "%r6", ! 40: "%r7", ! 41: "%r8" ! 42: }; ! 43: ! 44: static char * ccbranches[] = ! 45: { ! 46: "je", ! 47: "jne", ! 48: "jle", ! 49: "jl", ! 50: "jge", ! 51: "jg", ! 52: "jleu", ! 53: "jlu", ! 54: "jgeu", ! 55: "jgu" ! 56: }; ! 57: ! 58: static char * arithjump[] = ! 59: { ! 60: "jz", ! 61: "jnz", ! 62: "jnpos", ! 63: "jneg", ! 64: "jnneg", ! 65: "jpos", ! 66: "jnpos", ! 67: "jneg", ! 68: "jnneg", ! 69: "jpos" ! 70: }; ! 71: ! 72: static int cmpflag = 0; /* have we done a cmp? */ ! 73: ! 74: zzzcode(pnode, ppc, q) /* hard stuff escaped from templates */ ! 75: NODE *pnode; ! 76: char **ppc; ! 77: OPTAB *q; /* not used in m32 zzzcode */ ! 78: { ! 79: int stlab, i; ! 80: OPTAB *q; ! 81: NODE *pl, *pr; ! 82: ! 83: switch (*++(*ppc)) ! 84: { ! 85: ! 86: case 'H': ! 87: /* put out word relative bit shift for insv and extv ! 88: /* instruction. Similar to case 'H' case in expand(), ! 89: /* but no difference for different types ! 90: */ ! 91: { ! 92: extern int fldsz, fldshf; ! 93: ! 94: pl = getlr( pnode, *++(*ppc) ); ! 95: if (pl->tn.op != FLD ) cerror( "bad FLD for ZH" ); ! 96: fldsz = UPKFSZ(pl->tn.rval); ! 97: fldshf = SZINT - fldsz - UPKFOFF(pl->tn.rval); ! 98: printf( "%d", fldshf ); ! 99: } ! 100: break; ! 101: ! 102: ! 103: case 'D': /* output address of second half of double */ ! 104: dbladrput( pl = getlr(pnode,*++(*ppc)) ); ! 105: break; ! 106: ! 107: ! 108: case 'B': ! 109: bycode(pnode->in.left->tn.lval, 0); ! 110: break; ! 111: ! 112: case 'b': ! 113: ++cmpflag; ! 114: break; ! 115: ! 116: case 'C': ! 117: printf("%s\t.L%d\n", ! 118: cmpflag ? ccbranches[pnode->bn.lop - EQ] : ! 119: arithjump[pnode->bn.lop - EQ], pnode->bn.label); ! 120: cmpflag = 0; ! 121: break; ! 122: ! 123: case 'c': /* # of word-length args */ ! 124: printf("%d", pnode->stn.argsize / SZINT); ! 125: break; ! 126: ! 127: case 'h': /* deal with the BM32's weird treatment ! 128: of half-word compares */ ! 129: /* If a 16 bit positive constant is used, it will ! 130: not be sign extended, but the othe operand will */ ! 131: { ! 132: register NODE *r, *l; ! 133: int lchg = 0, rchg = 0; ! 134: l = pnode ->in.left; ! 135: if ((l->tn.op == ICON) && ! 136: ((l->tn.type == TUSHORT) || ! 137: (l->tn.type == TSHORT)) && ! 138: (l->tn.lval > 0x7fff)) { ! 139: lchg = 1; ! 140: } ! 141: r = pnode->in.right; ! 142: if ((r->tn.op == ICON) && ! 143: ((r->tn.type == TUSHORT) || ! 144: (r->tn.type == TSHORT)) && ! 145: (r->tn.lval > 0x7fff)) { ! 146: rchg = 1; ! 147: } ! 148: if ((!rchg && !lchg) || (rchg && lchg)) { ! 149: expand(pnode, FORCC, "cmph AL,AR", q); ! 150: } else if (rchg) { ! 151: expand(pnode, FORCC, ! 152: "movzhw AL,A1\n cmpw A1,AR", q); ! 153: } else { ! 154: expand(pnode, FORCC, ! 155: "movzhw AR,A1\n cmpw AL,A1", q); ! 156: } ! 157: break; ! 158: } ! 159: ! 160: case 'S': /* STASG */ ! 161: q = ophead[STASG]; ! 162: if (istnode(pnode->in.left)) ! 163: pl = pnode->in.left; ! 164: else ! 165: { ! 166: pl = &resc[1]; ! 167: if (pnode->in.left->in.op == UNARY AND) ! 168: expand(pnode, FOREFF, " movaw A(LL),A2\n", q); ! 169: else ! 170: expand(pnode, FOREFF, " movw AL,A2\n", q); ! 171: } ! 172: if (istnode(pnode->in.right)) ! 173: pr = pnode->in.right; ! 174: else ! 175: { ! 176: pr = &resc[0]; ! 177: if (pnode->in.right->in.op == UNARY AND) ! 178: expand(pnode, FOREFF, " movaw A(RL),A1\n", q); ! 179: else ! 180: expand(pnode, FOREFF, " movw AR,A1\n", q); ! 181: } ! 182: if ((i = pnode->stn.stsize / SZINT) <= STHRESH) ! 183: while (i--) ! 184: printf("\tmovw\t%d(%s),%d(%s)\n", i << 2, ! 185: rnames[pr->tn.rval], i << 2, ! 186: rnames[pl->tn.rval]); ! 187: else ! 188: { ! 189: int lastlab = getlab(); ! 190: ! 191: printf(" movw &%d,", i); ! 192: expand(pnode, FOREFF, "A3\n.\\L", q); ! 193: printf("%d:\tmovw\t0(%s),0(%s)\n\taddw2\t&4,%s\n\taddw2\t&4,%s\n", ! 194: lastlab, rnames[pr->tn.rval], rnames[pl->tn.rval], ! 195: rnames[pr->tn.rval], rnames[pl->tn.rval]); ! 196: expand(pnode,FOREFF, "\tsubw2\t&1,A3\n\tjpos\t.\\L", q); ! 197: printf("%d\n", lastlab); ! 198: } ! 199: break; ! 200: ! 201: case 's': /* STARG */ ! 202: q = ophead[STARG]; ! 203: if (istnode(pnode->in.left)) ! 204: pl = pnode->in.left; ! 205: else ! 206: { ! 207: pl = &resc[0]; ! 208: if (pnode->in.left->in.op == UNARY AND) ! 209: expand(pnode, FOREFF, " movaw A(LL),A1\n", q); ! 210: else ! 211: expand(pnode, FOREFF, " movw AL,A1\n", q); ! 212: } ! 213: printf(" addw2 &%d,%%sp\n movaw -%d(%%sp),", ! 214: pnode->stn.stsize / SZCHAR, pnode->stn.stsize / SZCHAR); ! 215: expand(pnode, FOREFF, "A2\n", q); ! 216: if ((i = pnode->stn.stsize / SZINT) <= STHRESH) ! 217: while (i--) ! 218: { ! 219: printf(" movw %d(%s),%d(", i << 2, ! 220: rnames[pl->tn.rval], i << 2); ! 221: expand(pnode, FOREFF, "A2)\n", q); ! 222: } ! 223: else ! 224: { ! 225: int lastlab = getlab(); ! 226: ! 227: printf(" movw &%d,", i); ! 228: expand(pnode, FOREFF, "A3\n.\\L", q); ! 229: printf("%d:\tmovw\t0(%s),0(", lastlab, ! 230: rnames[pl->tn.rval]); ! 231: expand(pnode, FOREFF, "A2)\n\taddw2\t&4,", q); ! 232: printf("%s\n\taddw2\t&4,", rnames[pl->tn.rval]); ! 233: expand(pnode, FOREFF, ! 234: "A2\n\tsubw2\t&1,A3\n\tjpos\t.\\L", q); ! 235: printf("%d\n", lastlab); ! 236: } ! 237: break; ! 238: ! 239: default: ! 240: cerror("botched Z macro %c", **ppc); ! 241: /*NOTREACHED*/ ! 242: } ! 243: } ! 244: ! 245: ! 246: staradr(p) /* dereference p */ ! 247: NODE *p; ! 248: { ! 249: NODE *pp; ! 250: ! 251: pp = talloc(); ! 252: pp->tn.op = STAR; ! 253: pp->in.left = p; ! 254: upput(pp); ! 255: pp->tn.op = FREE; ! 256: } ! 257: ! 258: conput(p) /* name for a known */ ! 259: register NODE *p; ! 260: { ! 261: switch(p->in.op) ! 262: { ! 263: case ICON: ! 264: acon(p); ! 265: break; ! 266: case REG: ! 267: fputs(rnames[p->tn.rval], stdout); ! 268: break; ! 269: default: ! 270: cerror("confused node in conput"); ! 271: /*NOTREACHED*/ ! 272: } ! 273: } ! 274: ! 275: insput(p) /* we don't have any */ ! 276: NODE *p; ! 277: { ! 278: cerror("insput"); ! 279: } ! 280: ! 281: upput(p) /* generate address incl. indirect, offset */ ! 282: NODE *p; ! 283: { ! 284: register NODE *r, *l, *pp; ! 285: ! 286: sideff = 0; ! 287: if (p->in.op == STAR) ! 288: pp = p->in.left; ! 289: else ! 290: pp = p; ! 291: again: ! 292: switch (pp->tn.op) ! 293: { ! 294: case NAME: ! 295: case TEMP: ! 296: case VAUTO: ! 297: case VPARAM: ! 298: if (p->in.op == STAR) ! 299: putchar('*'); ! 300: adrput(pp); ! 301: break; ! 302: ! 303: case REG: ! 304: if (p->in.op == STAR) ! 305: { ! 306: fputs("0(", stdout); ! 307: conput(pp); ! 308: putchar(')'); ! 309: } ! 310: else ! 311: conput(pp); ! 312: break; ! 313: ! 314: case ICON: ! 315: if (p->in.op == STAR) ! 316: putchar('*'); ! 317: acon(pp); ! 318: break; ! 319: ! 320: case STAR: ! 321: putchar('*'); ! 322: p = pp; ! 323: pp = pp->in.left; ! 324: goto again; ! 325: ! 326: case PLUS: ! 327: case MINUS: ! 328: case INCR: ! 329: case DECR: ! 330: if (p->in.op == STAR && pp->in.left->in.op != REG) ! 331: putchar('*'); ! 332: if (pp->in.op == MINUS) ! 333: putchar('-'); ! 334: acon(pp->in.right); ! 335: putchar('('); ! 336: conput(pp->in.left); ! 337: putchar(')'); ! 338: break; ! 339: ! 340: default: ! 341: cerror("upput: confused addressing mode matched"); ! 342: /*NOTREACHED*/ ! 343: } ! 344: } ! 345: ! 346: adrput(p) /* output address from p */ ! 347: NODE *p; ! 348: { ! 349: sideff = 0; ! 350: while (p->in.op == FLD || p->in.op == CONV) ! 351: p = p->in.left; ! 352: switch (p->in.op) ! 353: { ! 354: case ICON: /* value of the constant */ ! 355: putchar('&'); ! 356: case NAME: ! 357: acon(p); ! 358: break; ! 359: case REG: ! 360: conput(p); ! 361: break; ! 362: case STAR: ! 363: upput(p); ! 364: break; ! 365: case TEMP: ! 366: printf("%d(%%fp)", p->tn.lval + maxboff / SZCHAR); ! 367: break; ! 368: case VAUTO: ! 369: printf("%d(%%fp)", p->tn.lval); ! 370: break; ! 371: case VPARAM: ! 372: printf("%d(%%ap)", p->tn.lval); ! 373: break; ! 374: default: ! 375: cerror("adrput: illegal address"); ! 376: break; ! 377: } ! 378: } ! 379: ! 380: ! 381: ! 382: ! 383: dbladrput(p) ! 384: NODE *p; ! 385: /* output address of word after p. used for double moves */ ! 386: { ! 387: while (p->in.op == FLD || p->in.op == CONV) ! 388: p = p->in.left; ! 389: switch (p->in.op) ! 390: { ! 391: case NAME: ! 392: printf("%s+%ld", p->in.name, p->tn.lval + 4); ! 393: break; ! 394: case REG: ! 395: fputs(rnames[p->tn.rval + 1],stdout); ! 396: break; ! 397: case TEMP: ! 398: printf("%d(%%fp)", (p->tn.lval+maxboff/SZCHAR)+4); ! 399: break; ! 400: case VAUTO: ! 401: printf("%d(%%fp)", p->tn.lval + 4); ! 402: break; ! 403: case VPARAM: ! 404: printf("%d(%%ap)", p->tn.lval + 4); ! 405: break; ! 406: default: ! 407: cerror("dbladrput: illegal double address substitution"); ! 408: /*NOTREACHED*/ ! 409: } ! 410: } ! 411: ! 412: ! 413: ! 414: ! 415: acon(p) /* print out a constant */ ! 416: register NODE *p; ! 417: { ! 418: ! 419: if (p->in.name == (char *) 0) /* constant only */ ! 420: { ! 421: if (p->in.op == ICON && ! 422: (p->in.type == TCHAR || p->in.type == TUCHAR)) ! 423: p->tn.lval &= 0xff; ! 424: printf("%ld", p->tn.lval); ! 425: } ! 426: else if (p->tn.lval == 0) /* name only */ ! 427: printf("%s", p->in.name); ! 428: else /* name + offset */ ! 429: printf ("%s+%ld", p->in.name, p->tn.lval); ! 430: } ! 431: ! 432: ! 433: ! 434: special(sc,p) ! 435: NODE *p; ! 436: { ! 437: cerror("special shape used"); ! 438: return (INFINITY); ! 439: } ! 440:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.