|
|
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.