|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)bound.c 1.1 86/02/03 Copyr 1985 Sun Micro"; ! 3: #endif ! 4: ! 5: /* ! 6: * Copyright (c) 1985 by Sun Microsystems, Inc. ! 7: */ ! 8: ! 9: #include "cpass2.h" ! 10: #include "ctype.h" ! 11: ! 12: int failsafe; /* very disgusting: see offstar() for use */ ! 13: ! 14: # define SAFETY( a, reg, b ) \ ! 15: {if ((reg & MUSTDO) && find_mustdo( a , reg )) {rewrite_rall( b, 1 );} } ! 16: # define isareg(r) (rstatus[r]&SAREG) ! 17: # define iscnode(p) (p->in.op==REG && iscreg(p->tn.rval)) ! 18: ! 19: # define max(x,y) ((x)<(y)?(y):(x)) ! 20: # define min(x,y) ((x)<(y)?(x):(y)) ! 21: ! 22: ! 23: static char *unsigned_branches[2] = { "jcs", "jls"}; ! 24: static char *signed_branches[2] = { "jlt", "jle"}; ! 25: ! 26: trapv(type) ! 27: { ! 28: if (chk_ovfl){ ! 29: if (!ISPTR(type) && !ISUNSIGNED(type)){ ! 30: print_str( " trapv\n" ); ! 31: } ! 32: } ! 33: } ! 34: ! 35: ! 36: #ifdef NOTDEF ! 37: chksize(p) ! 38: NODE *p; ! 39: { ! 40: /* check size of result after a multiply instruction */ ! 41: int chklab = getlab(); ! 42: int oklab; ! 43: int type = p->in.type; ! 44: int lb, ub; ! 45: char *regname = rnames[p->in.left->tn.rval]; ! 46: if (chk_ovfl){ ! 47: if (use68020){ ! 48: switch(type){ ! 49: case CHAR: ! 50: printf("\t.data\nL%d:\t.long\t-0x80,0x7f\n\t.text\n", chklab); ! 51: break; ! 52: case UCHAR: ! 53: printf("\t.data\nL%d:\t.long\t0,0xff\n\t.text\n", chklab); ! 54: break; ! 55: case SHORT: ! 56: printf("\t.data\nL%d:\t.long\t-0x8000,0x7fff\n\t.text\n", chklab); ! 57: break; ! 58: case USHORT: ! 59: printf("\t.data\nL%d:\t.long\t0,0xffff\n\t.text\n", chklab); ! 60: break; ! 61: default: ! 62: trapv( type ); ! 63: return; ! 64: } ! 65: printf(" chk2l L%d,%s\n", chklab, regname); ! 66: return; ! 67: }else { ! 68: oklab = getlab(); ! 69: switch(type){ ! 70: case CHAR: ! 71: lb = -128; ub = 127; ! 72: break; ! 73: case SHORT: ! 74: lb = -32768; ub = 32767; ! 75: signed: ! 76: printf(" cmpl #%#x,%s\n", lb, regname); ! 77: break; ! 78: case UCHAR: ! 79: ub = 255; ! 80: break; ! 81: case USHORT: ! 82: ub = 0xffff; ! 83: break; ! 84: default: ! 85: trapv( type ); ! 86: return; ! 87: } ! 88: printf(" jlt L%d\n", chklab); ! 89: printf(" cmpl #%#x,%s\n", ub, regname); ! 90: printf(" jle L%d\n", oklab); ! 91: printf("L%d: chk #-1,%s\n", chklab, regname); ! 92: printf("L%d:\n", oklab); ! 93: } ! 94: } ! 95: } ! 96: #endif ! 97: ! 98: /* generate a copy of p ; p should be simple */ ! 99: ! 100: static char * ! 101: rcopy(p) ! 102: NODE *p; ! 103: { ! 104: NODE *temp; ! 105: int r; ! 106: ! 107: if (busy[D0] && busy[D1]) ! 108: return(NULL); ! 109: temp = tcopy(p); ! 110: order(temp, INTAREG); ! 111: r = temp->tn.rval; ! 112: reclaim(temp, RNULL, FOREFF); ! 113: return(rnames[r]); ! 114: } ! 115: ! 116: bound_test( p, cookie ) ! 117: register NODE *p; ! 118: { ! 119: register NODE *expr, *lb, *ub; ! 120: register t = p->in.type; ! 121: NODE *bounds = p->in.right; ! 122: int chklab, oklab; ! 123: char *size; ! 124: char **branch; ! 125: NODE *copy; ! 126: char *regname; ! 127: ! 128: expr = p->in.left; ! 129: lb = bounds->in.left; ! 130: ub = bounds->in.right; ! 131: if (!chk_ovfl){ ! 132: order( expr, cookie ); ! 133: return; ! 134: } ! 135: regname = rnames[expr->tn.rval]; ! 136: /* ! 137: * see if we can use the chk or chkl instructions. ! 138: * For nonzero lower bounds, try to generate a copy and ! 139: * subtract the lower bound. In array subscripting the ! 140: * lower bound must be subtracted anyway; c2 may be able ! 141: * to identify this as a cse. ! 142: */ ! 143: if (lb->in.op == ICON && lb->in.name[0] == '\0' && ! 144: ub->in.op == ICON && ub->in.name[0] == '\0' ){ ! 145: /* constant bounds */ ! 146: switch(t){ ! 147: case CHAR: ! 148: printf(" extw %s\n", regname ); ! 149: p->in.type = expr->in.type = SHORT; ! 150: goto use_chkw; ! 151: case UCHAR: ! 152: printf(" andw #0xff,%s\n", regname ); ! 153: p->in.type = expr->in.type = SHORT; ! 154: /* FALL THROUGH */ ! 155: case SHORT: ! 156: use_chkw: ! 157: if (lb->tn.lval) { ! 158: char *regcopy = rcopy(expr); ! 159: if (regcopy == NULL) goto long_case; ! 160: regname = regcopy; ! 161: printf(" subw #0x%x,%s\n", lb->tn.lval, regname); ! 162: } ! 163: if (ub->tn.lval - lb->tn.lval < 0x8000) { ! 164: printf(" chk #0x%x,%s\n", ub->tn.lval-lb->tn.lval, ! 165: regname); ! 166: } else { ! 167: printf(" cmpw #0x%x,%s\n", ub->tn.lval-lb->tn.lval, ! 168: regname); ! 169: oklab = getlab(); ! 170: printf(" jls L%d\n", oklab); ! 171: printf(" chk #-1,%s\n", regname); ! 172: printf("L%d:\n", oklab); ! 173: } ! 174: break; ! 175: case USHORT: ! 176: if (ub->tn.lval <= 0x7fff) goto use_chkw; ! 177: printf(" andl #0xffff,%s\n", regname); ! 178: p->in.type = expr->in.type = INT; ! 179: /* FALL THROUGH */ ! 180: default: ! 181: if (lb->tn.lval == -32768 && ub->tn.lval == 32767) { ! 182: /* common case, can be done without long literals */ ! 183: char *regcopy = rcopy(expr); ! 184: if (regcopy == NULL) goto long_case; ! 185: regname = regcopy; ! 186: printf(" extl %s\n", regname); ! 187: expand(p, cookie, " cmpl AL,"); ! 188: printf("%s\n", regname); ! 189: oklab = getlab(); ! 190: printf(" jeq L%d\n", oklab); ! 191: printf(" chk #-1,%s\n", regname); ! 192: printf("L%d:\n", oklab); ! 193: break; ! 194: } ! 195: if (lb->tn.lval) { ! 196: char *regcopy = rcopy(expr); ! 197: if (regcopy == NULL) goto long_case; ! 198: regname = regcopy; ! 199: printf(" subl #0x%x,%s\n", lb->tn.lval, regname); ! 200: } ! 201: if (use68020 && (unsigned)(ub->tn.lval-lb->tn.lval) < 0x80000000) { ! 202: printf(" chkl #0x%x,%s\n", ub->tn.lval-lb->tn.lval, ! 203: regname); ! 204: } else { ! 205: printf(" cmpl #0x%x,%s\n", ub->tn.lval-lb->tn.lval, ! 206: regname); ! 207: oklab = getlab(); ! 208: printf(" jls L%d\n", oklab); ! 209: printf(" chk #-1,%s\n", regname); ! 210: printf("L%d:\n", oklab); ! 211: } ! 212: break; ! 213: } ! 214: return; ! 215: long_case: ! 216: if (use68020) { ! 217: /* use chk2l */ ! 218: switch(t){ ! 219: case CHAR: ! 220: case UCHAR: ! 221: size = "byte"; break; ! 222: case SHORT: ! 223: case USHORT: ! 224: size = "word"; break; ! 225: default: ! 226: size = "long"; break; ! 227: } ! 228: chklab = getlab(); ! 229: printf(" .data\nL%d: .%s %d,%d\n .text\n", ! 230: chklab, size, lb->tn.lval, ub->tn.lval); ! 231: printf(" chk2%c L%d,%s\n", size[0], chklab, regname); ! 232: return; ! 233: } ! 234: } ! 235: /* can't use any chk instructions -- do cmp & branch */ ! 236: branch = unsigned_branches; ! 237: if (ISUNSIGNED(t) || ISPTR(t)) ! 238: branch = unsigned_branches; ! 239: else ! 240: branch = signed_branches; ! 241: chklab = getlab(); ! 242: oklab = getlab(); ! 243: if (adjacent(lb, ub)) { ! 244: /* ! 245: * bounds are in adjacent memory operands ! 246: */ ! 247: if (SUTEST(lb->in.su)) ! 248: order(lb, SOREG); ! 249: p->in.right = lb; ! 250: if (use68020) { ! 251: expand( p, FORCC, " chk2ZB AR,AL\n"); ! 252: p->in.right = bounds; ! 253: reclaim( lb, RNULL, FOREFF ); ! 254: reclaim( ub, RNULL, FOREFF ); ! 255: return; ! 256: } else { ! 257: expand( p, FORCC, " cmpZB AR,AL\n"); ! 258: printf(" %s L%d\n", branch[0], chklab); ! 259: expand( p, FORCC, " cmpZB UR,AL\n"); ! 260: printf(" %s L%d\n", branch[1], oklab); ! 261: reclaim( lb, RNULL, FOREFF ); ! 262: reclaim( ub, RNULL, FOREFF ); ! 263: /* finish up below */ ! 264: } ! 265: } else { ! 266: /* ! 267: * lower bound ! 268: */ ! 269: if (SUTEST(lb->in.su)) { ! 270: order( lb, INTAREG|INTEMP|SOREG ); ! 271: } ! 272: p->in.right = lb; ! 273: expand( p, FORCC, " cmpZB AR,AL\n"); ! 274: printf(" %s L%d\n", branch[0], chklab); ! 275: reclaim( lb, RNULL, FOREFF ); ! 276: /* ! 277: * upper bound ! 278: */ ! 279: if (SUTEST(ub->in.su)) { ! 280: order( ub, INTAREG|INTEMP|SOREG ); ! 281: } ! 282: p->in.right = ub; ! 283: expand( p, FORCC, " cmpZB AR,AL\n"); ! 284: printf(" %s L%d\n", branch[1], oklab); ! 285: reclaim( ub, RNULL, FOREFF ); ! 286: } ! 287: ! 288: printf("L%d: chk #-1,%s\n", chklab, regname); ! 289: printf("L%d:\n", oklab); ! 290: p->in.right = bounds; ! 291: ! 292: } ! 293: ! 294: ! 295: #define true 1 ! 296: #define false 0 ! 297: ! 298: /* ! 299: * are operands p and q adjacent ! 300: * (in the sense assumed by upput() and adrput())? ! 301: */ ! 302: int ! 303: adjacent(p,q) ! 304: register NODE *p,*q; ! 305: { ! 306: register NODE *lp, *lq; ! 307: register o; ! 308: int result; ! 309: CONSZ temp; ! 310: ! 311: o = p->in.op; ! 312: if (o != q->in.op) ! 313: return false; ! 314: switch(o) { ! 315: case NAME: ! 316: case OREG: ! 317: p->tn.lval+= SZINT/SZCHAR; ! 318: result = equal(p,q); ! 319: p->tn.lval-= SZINT/SZCHAR; ! 320: return result; ! 321: case UNARY MUL: ! 322: lp = p->in.left; ! 323: lq = q->in.left; ! 324: if (lp->in.op == PLUS && lq->in.op == PLUS) { ! 325: lp = lp->in.right; ! 326: lq = lq->in.right; ! 327: if (lp->in.op == ICON && lq->in.op == ICON) { ! 328: if (lp->tn.lval+SZINT/SZCHAR == lq->tn.lval) { ! 329: lp->tn.lval += SZINT/SZCHAR; ! 330: result = equal(p,q); ! 331: lp->tn.lval -= SZINT/SZCHAR; ! 332: return result; ! 333: } ! 334: } ! 335: } ! 336: break; ! 337: } ! 338: return false; ! 339: } ! 340: ! 341: /* ! 342: * equal(p,q) : returns 1 if expressions p and q are equivalent, ! 343: * in the sense that they always return the same value given ! 344: * the same initial values of their operands. Note that if ! 345: * either p or q contains operators producing side-effects, ! 346: * equal(p,q) = 0. ! 347: */ ! 348: ! 349: int ! 350: equal(p,q) ! 351: register NODE *p,*q; ! 352: { ! 353: register char *pn,*qn; ! 354: register o; ! 355: ! 356: if (p == q) ! 357: return true; ! 358: if (p == NIL || q == NIL) ! 359: return false; ! 360: o = p->in.op; ! 361: if (o != q->in.op) ! 362: return false; ! 363: if (p->in.type != q->in.type) ! 364: return false; ! 365: switch(optype(o)) { ! 366: case UTYPE: ! 367: if (callop(o)) ! 368: return false; ! 369: return equal(p->in.left, q->in.left); ! 370: case BITYPE: ! 371: if (callop(o) || asgop(o)) ! 372: return false; ! 373: if (equal(p->in.left, q->in.left)) ! 374: return equal(p->in.right, q->in.right); ! 375: return false; ! 376: default: ! 377: /* leaf nodes */ ! 378: switch (o) { ! 379: case ICON: ! 380: case OREG: ! 381: case NAME: ! 382: pn = p->tn.name; ! 383: qn = q->tn.name; ! 384: if (pn != NULL && qn != NULL) { ! 385: if ( *pn == *qn ! 386: && (*pn == '\0' || strcmp(pn,qn) == 0) ) { ! 387: return (p->tn.lval == q->tn.lval); ! 388: } ! 389: ! 390: } else if (pn == qn) { /* == NULL */ ! 391: return ( p->tn.lval == q->tn.lval ); ! 392: } ! 393: return false; ! 394: case REG: ! 395: return(p->tn.rval == q->tn.rval); ! 396: case FCON: ! 397: return(p->fpn.dval == q->fpn.dval); ! 398: } ! 399: } ! 400: return false; ! 401: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.