|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)quicken.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 "as.h" ! 10: #include "c2.h" ! 11: ! 12: extern struct ins_bkt *moveq, *subql, *addql; ! 13: #ifdef TRACKSP ! 14: int spoffset = 0; /* track a6-a7 distance */ ! 15: #define SPUNK 999999; /* sp unknown here */ ! 16: #endif TRACKSP ! 17: ! 18: void ! 19: quicken() ! 20: { ! 21: register NODE *n; ! 22: register struct oper *o; ! 23: register long v; ! 24: register struct ins_bkt *ip; ! 25: register int regno; ! 26: ! 27: for (n=first.forw; n!=&first; n=n->forw){ ! 28: switch (n->op){ ! 29: case OP_MOVE: ! 30: if (n->instr==moveq || (o=n->ref[0])->type_o!=T_IMMED || o->sym_o!=NULL) continue; ! 31: v = o->value_o; ! 32: o = n->ref[1]; ! 33: if (!datareg_addr(o))continue; ! 34: regno = o->value_o; ! 35: if ( dreg(regno) && v >= -128 && v<= 127) { ! 36: n->instr = moveq; ! 37: } else if (freg( regno ) ){ ! 38: if (use_fmovecr( n )) ! 39: meter.nusecr++; ! 40: break; ! 41: } ! 42: continue; ! 43: case OP_ADD: ! 44: ip = addql; ! 45: goto xsub; ! 46: case OP_SUB: ! 47: ip = subql; ! 48: xsub: ! 49: if ( n->subop==SUBOP_B ) ip-=2; ! 50: else if (n->subop==SUBOP_W) ip-=1; ! 51: if (n->instr==ip || (o=n->ref[0])->type_o!=T_IMMED || o->sym_o!=NULL) continue; ! 52: v = o->value_o; ! 53: if ( v>=1 && v<=8) ! 54: n->instr = ip; ! 55: else if ( v<=-1 && v>= -8){ ! 56: o->value_o = -v; ! 57: if (n->op==OP_ADD){ ! 58: n->op=OP_SUB; ! 59: ip = subql; ! 60: } else { ! 61: n->op=OP_ADD; ! 62: ip = addql; ! 63: } ! 64: goto xsub; ! 65: } ! 66: continue; ! 67: } ! 68: } ! 69: } ! 70: ! 71: #ifdef TRACKSP ! 72: void ! 73: track_sp( n ) ! 74: NODE *n; ! 75: { ! 76: /* try to keep track of distance from a6 to a7 */ ! 77: /* keep global variable spoffset up-to-date */ ! 78: ! 79: register struct oper *o; ! 80: int i; ! 81: ! 82: switch (n->op){ ! 83: case OP_LINK: ! 84: if ((o=n->ref[1])->type_o==T_IMMED) ! 85: spoffset = - o->value_o; ! 86: else ! 87: spoffset = SPUNK; ! 88: break; ! 89: case OP_UNLK: ! 90: spoffset = 0; break; ! 91: case OP_LEA: ! 92: if (istmp(o=n->ref[0])) ! 93: spoffset += o->value_o; ! 94: else ! 95: spoffset = SPUNK; ! 96: break; ! 97: case OP_PEA: ! 98: spoffset -= 4; break; ! 99: case OP_ADD: ! 100: if ((o=n->ref[0])->type_o==T_IMMED) ! 101: spoffset += o->value_o; ! 102: else ! 103: spoffset = SPUNK; ! 104: break; ! 105: case OP_SUB: ! 106: if ((o=n->ref[0])->type_o==T_IMMED) ! 107: spoffset -= o->value_o; ! 108: else ! 109: spoffset = SPUNK; ! 110: break; ! 111: default: ! 112: for (i=0; i<n->nref; i++){ ! 113: o = n->ref[i]; ! 114: if (o->type_o == T_REG && o->value_o == SPREG) ! 115: spoffset = SPUNK; ! 116: else if (o->type_o == T_POSTINC) ! 117: spoffset += BYTESIZE(n->subop); ! 118: else if (o->type_o == T_PREDEC) ! 119: spoffset -= BYTESIZE(n->subop); ! 120: } ! 121: } ! 122: } ! 123: #endif TRACKSP ! 124: ! 125: /* ! 126: * list of floating-point constants in the 68881 constant ROM. ! 127: * Note that the ROM supports more constants, and they are ! 128: * actually documented; but they aren't representable in IEEE ! 129: * double precision. ! 130: */ ! 131: struct romlist { ! 132: int address; ! 133: double value; ! 134: } romlist[] = { ! 135: 0xf, 0.0, ! 136: 0x32, 1.0, ! 137: 0x33, 1.0e1, ! 138: 0x34, 1.0e2, ! 139: 0x35, 1.0e4, ! 140: 0x36, 1.0e8, ! 141: 0x37, 1.0e16, ! 142: 0x38, 1.0e32, ! 143: 0x39, 1.0e64, ! 144: 0x3a, 1.0e128, ! 145: 0x3b, 1.0e256, ! 146: -1, 0.0 ! 147: }; ! 148: ! 149: /* ! 150: * determine if the fmove instruction n can be replaced by a fmovecr ! 151: * instruction. If so, then make the substitution. ! 152: */ ! 153: static int ! 154: use_fmovecr( n ) ! 155: NODE *n; ! 156: { ! 157: register struct oper *o; ! 158: register struct romlist *rp; ! 159: register double v; ! 160: ! 161: o = n->ref[0]; ! 162: if (o->flags_o&O_FLOAT) { ! 163: v = o->fval_o; ! 164: } else { ! 165: /* integer conversion */ ! 166: v = (double)o->value_o; ! 167: } ! 168: rp = romlist; ! 169: while ( rp->address >= 0 && rp->value != v ) ! 170: rp++; ! 171: if ( rp->address < 0 ) return 0; /* sorry */ ! 172: o->value_o = rp->address; ! 173: o->flags_o = 0; ! 174: cannibalize( n, "fmovecr" ); ! 175: return 1; ! 176: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.