1*74a4d8c2SCharles.Forsyth #include "gc.h"
2*74a4d8c2SCharles.Forsyth
3*74a4d8c2SCharles.Forsyth /*
4*74a4d8c2SCharles.Forsyth * code sequences for multiply by constant.
5*74a4d8c2SCharles.Forsyth * [a-l][0-3]
6*74a4d8c2SCharles.Forsyth * lsl $(A-'a'),r0,r1
7*74a4d8c2SCharles.Forsyth * [+][0-7]
8*74a4d8c2SCharles.Forsyth * add r0,r1,r2
9*74a4d8c2SCharles.Forsyth * [-][0-7]
10*74a4d8c2SCharles.Forsyth * sub r0,r1,r2
11*74a4d8c2SCharles.Forsyth */
12*74a4d8c2SCharles.Forsyth
13*74a4d8c2SCharles.Forsyth static int maxmulops = 3; /* max # of ops to replace mul with */
14*74a4d8c2SCharles.Forsyth static int multabp;
15*74a4d8c2SCharles.Forsyth static long mulval;
16*74a4d8c2SCharles.Forsyth static char* mulcp;
17*74a4d8c2SCharles.Forsyth static long valmax;
18*74a4d8c2SCharles.Forsyth static int shmax;
19*74a4d8c2SCharles.Forsyth
20*74a4d8c2SCharles.Forsyth static int docode(char *hp, char *cp, int r0, int r1);
21*74a4d8c2SCharles.Forsyth static int gen1(int len);
22*74a4d8c2SCharles.Forsyth static int gen2(int len, long r1);
23*74a4d8c2SCharles.Forsyth static int gen3(int len, long r0, long r1, int flag);
24*74a4d8c2SCharles.Forsyth enum
25*74a4d8c2SCharles.Forsyth {
26*74a4d8c2SCharles.Forsyth SR1 = 1<<0, /* r1 has been shifted */
27*74a4d8c2SCharles.Forsyth SR0 = 1<<1, /* r0 has been shifted */
28*74a4d8c2SCharles.Forsyth UR1 = 1<<2, /* r1 has not been used */
29*74a4d8c2SCharles.Forsyth UR0 = 1<<3, /* r0 has not been used */
30*74a4d8c2SCharles.Forsyth };
31*74a4d8c2SCharles.Forsyth
32*74a4d8c2SCharles.Forsyth Multab*
mulcon0(long v)33*74a4d8c2SCharles.Forsyth mulcon0(long v)
34*74a4d8c2SCharles.Forsyth {
35*74a4d8c2SCharles.Forsyth int a1, a2, g;
36*74a4d8c2SCharles.Forsyth Multab *m, *m1;
37*74a4d8c2SCharles.Forsyth char hint[10];
38*74a4d8c2SCharles.Forsyth
39*74a4d8c2SCharles.Forsyth if(v < 0)
40*74a4d8c2SCharles.Forsyth v = -v;
41*74a4d8c2SCharles.Forsyth
42*74a4d8c2SCharles.Forsyth /*
43*74a4d8c2SCharles.Forsyth * look in cache
44*74a4d8c2SCharles.Forsyth */
45*74a4d8c2SCharles.Forsyth m = multab;
46*74a4d8c2SCharles.Forsyth for(g=0; g<nelem(multab); g++) {
47*74a4d8c2SCharles.Forsyth if(m->val == v) {
48*74a4d8c2SCharles.Forsyth if(m->code[0] == 0)
49*74a4d8c2SCharles.Forsyth return 0;
50*74a4d8c2SCharles.Forsyth return m;
51*74a4d8c2SCharles.Forsyth }
52*74a4d8c2SCharles.Forsyth m++;
53*74a4d8c2SCharles.Forsyth }
54*74a4d8c2SCharles.Forsyth
55*74a4d8c2SCharles.Forsyth /*
56*74a4d8c2SCharles.Forsyth * select a spot in cache to overwrite
57*74a4d8c2SCharles.Forsyth */
58*74a4d8c2SCharles.Forsyth multabp++;
59*74a4d8c2SCharles.Forsyth if(multabp < 0 || multabp >= nelem(multab))
60*74a4d8c2SCharles.Forsyth multabp = 0;
61*74a4d8c2SCharles.Forsyth m = multab+multabp;
62*74a4d8c2SCharles.Forsyth m->val = v;
63*74a4d8c2SCharles.Forsyth mulval = v;
64*74a4d8c2SCharles.Forsyth
65*74a4d8c2SCharles.Forsyth /*
66*74a4d8c2SCharles.Forsyth * look in execption hint table
67*74a4d8c2SCharles.Forsyth */
68*74a4d8c2SCharles.Forsyth a1 = 0;
69*74a4d8c2SCharles.Forsyth a2 = hintabsize;
70*74a4d8c2SCharles.Forsyth for(;;) {
71*74a4d8c2SCharles.Forsyth if(a1 >= a2)
72*74a4d8c2SCharles.Forsyth goto no;
73*74a4d8c2SCharles.Forsyth g = (a2 + a1)/2;
74*74a4d8c2SCharles.Forsyth if(v < hintab[g].val) {
75*74a4d8c2SCharles.Forsyth a2 = g;
76*74a4d8c2SCharles.Forsyth continue;
77*74a4d8c2SCharles.Forsyth }
78*74a4d8c2SCharles.Forsyth if(v > hintab[g].val) {
79*74a4d8c2SCharles.Forsyth a1 = g+1;
80*74a4d8c2SCharles.Forsyth continue;
81*74a4d8c2SCharles.Forsyth }
82*74a4d8c2SCharles.Forsyth break;
83*74a4d8c2SCharles.Forsyth }
84*74a4d8c2SCharles.Forsyth
85*74a4d8c2SCharles.Forsyth if(docode(hintab[g].hint, m->code, 1, 0))
86*74a4d8c2SCharles.Forsyth return m;
87*74a4d8c2SCharles.Forsyth print("multiply table failure %ld\n", v);
88*74a4d8c2SCharles.Forsyth m->code[0] = 0;
89*74a4d8c2SCharles.Forsyth return 0;
90*74a4d8c2SCharles.Forsyth
91*74a4d8c2SCharles.Forsyth no:
92*74a4d8c2SCharles.Forsyth /*
93*74a4d8c2SCharles.Forsyth * try to search
94*74a4d8c2SCharles.Forsyth */
95*74a4d8c2SCharles.Forsyth hint[0] = 0;
96*74a4d8c2SCharles.Forsyth for(g=1; g<=maxmulops; g++) {
97*74a4d8c2SCharles.Forsyth if(g >= maxmulops && v >= 65535)
98*74a4d8c2SCharles.Forsyth break;
99*74a4d8c2SCharles.Forsyth mulcp = hint+g;
100*74a4d8c2SCharles.Forsyth *mulcp = 0;
101*74a4d8c2SCharles.Forsyth if(gen1(g)) {
102*74a4d8c2SCharles.Forsyth if(docode(hint, m->code, 1, 0))
103*74a4d8c2SCharles.Forsyth return m;
104*74a4d8c2SCharles.Forsyth print("multiply table failure %ld\n", v);
105*74a4d8c2SCharles.Forsyth break;
106*74a4d8c2SCharles.Forsyth }
107*74a4d8c2SCharles.Forsyth }
108*74a4d8c2SCharles.Forsyth
109*74a4d8c2SCharles.Forsyth /*
110*74a4d8c2SCharles.Forsyth * try a recur followed by a shift
111*74a4d8c2SCharles.Forsyth */
112*74a4d8c2SCharles.Forsyth g = 0;
113*74a4d8c2SCharles.Forsyth while(!(v & 1)) {
114*74a4d8c2SCharles.Forsyth g++;
115*74a4d8c2SCharles.Forsyth v >>= 1;
116*74a4d8c2SCharles.Forsyth }
117*74a4d8c2SCharles.Forsyth if(g) {
118*74a4d8c2SCharles.Forsyth m1 = mulcon0(v);
119*74a4d8c2SCharles.Forsyth if(m1) {
120*74a4d8c2SCharles.Forsyth strcpy(m->code, m1->code);
121*74a4d8c2SCharles.Forsyth sprint(strchr(m->code, 0), "%c0", g+'a');
122*74a4d8c2SCharles.Forsyth return m;
123*74a4d8c2SCharles.Forsyth }
124*74a4d8c2SCharles.Forsyth }
125*74a4d8c2SCharles.Forsyth m->code[0] = 0;
126*74a4d8c2SCharles.Forsyth return 0;
127*74a4d8c2SCharles.Forsyth }
128*74a4d8c2SCharles.Forsyth
129*74a4d8c2SCharles.Forsyth static int
docode(char * hp,char * cp,int r0,int r1)130*74a4d8c2SCharles.Forsyth docode(char *hp, char *cp, int r0, int r1)
131*74a4d8c2SCharles.Forsyth {
132*74a4d8c2SCharles.Forsyth int c, i;
133*74a4d8c2SCharles.Forsyth
134*74a4d8c2SCharles.Forsyth c = *hp++;
135*74a4d8c2SCharles.Forsyth *cp = c;
136*74a4d8c2SCharles.Forsyth cp += 2;
137*74a4d8c2SCharles.Forsyth switch(c) {
138*74a4d8c2SCharles.Forsyth default:
139*74a4d8c2SCharles.Forsyth c -= 'a';
140*74a4d8c2SCharles.Forsyth if(c < 1 || c >= 30)
141*74a4d8c2SCharles.Forsyth break;
142*74a4d8c2SCharles.Forsyth for(i=0; i<4; i++) {
143*74a4d8c2SCharles.Forsyth switch(i) {
144*74a4d8c2SCharles.Forsyth case 0:
145*74a4d8c2SCharles.Forsyth if(docode(hp, cp, r0<<c, r1))
146*74a4d8c2SCharles.Forsyth goto out;
147*74a4d8c2SCharles.Forsyth break;
148*74a4d8c2SCharles.Forsyth case 1:
149*74a4d8c2SCharles.Forsyth if(docode(hp, cp, r1<<c, r1))
150*74a4d8c2SCharles.Forsyth goto out;
151*74a4d8c2SCharles.Forsyth break;
152*74a4d8c2SCharles.Forsyth case 2:
153*74a4d8c2SCharles.Forsyth if(docode(hp, cp, r0, r0<<c))
154*74a4d8c2SCharles.Forsyth goto out;
155*74a4d8c2SCharles.Forsyth break;
156*74a4d8c2SCharles.Forsyth case 3:
157*74a4d8c2SCharles.Forsyth if(docode(hp, cp, r0, r1<<c))
158*74a4d8c2SCharles.Forsyth goto out;
159*74a4d8c2SCharles.Forsyth break;
160*74a4d8c2SCharles.Forsyth }
161*74a4d8c2SCharles.Forsyth }
162*74a4d8c2SCharles.Forsyth break;
163*74a4d8c2SCharles.Forsyth
164*74a4d8c2SCharles.Forsyth case '+':
165*74a4d8c2SCharles.Forsyth for(i=0; i<8; i++) {
166*74a4d8c2SCharles.Forsyth cp[-1] = i+'0';
167*74a4d8c2SCharles.Forsyth switch(i) {
168*74a4d8c2SCharles.Forsyth case 1:
169*74a4d8c2SCharles.Forsyth if(docode(hp, cp, r0+r1, r1))
170*74a4d8c2SCharles.Forsyth goto out;
171*74a4d8c2SCharles.Forsyth break;
172*74a4d8c2SCharles.Forsyth case 5:
173*74a4d8c2SCharles.Forsyth if(docode(hp, cp, r0, r0+r1))
174*74a4d8c2SCharles.Forsyth goto out;
175*74a4d8c2SCharles.Forsyth break;
176*74a4d8c2SCharles.Forsyth }
177*74a4d8c2SCharles.Forsyth }
178*74a4d8c2SCharles.Forsyth break;
179*74a4d8c2SCharles.Forsyth
180*74a4d8c2SCharles.Forsyth case '-':
181*74a4d8c2SCharles.Forsyth for(i=0; i<8; i++) {
182*74a4d8c2SCharles.Forsyth cp[-1] = i+'0';
183*74a4d8c2SCharles.Forsyth switch(i) {
184*74a4d8c2SCharles.Forsyth case 1:
185*74a4d8c2SCharles.Forsyth if(docode(hp, cp, r0-r1, r1))
186*74a4d8c2SCharles.Forsyth goto out;
187*74a4d8c2SCharles.Forsyth break;
188*74a4d8c2SCharles.Forsyth case 2:
189*74a4d8c2SCharles.Forsyth if(docode(hp, cp, r1-r0, r1))
190*74a4d8c2SCharles.Forsyth goto out;
191*74a4d8c2SCharles.Forsyth break;
192*74a4d8c2SCharles.Forsyth case 5:
193*74a4d8c2SCharles.Forsyth if(docode(hp, cp, r0, r0-r1))
194*74a4d8c2SCharles.Forsyth goto out;
195*74a4d8c2SCharles.Forsyth break;
196*74a4d8c2SCharles.Forsyth case 6:
197*74a4d8c2SCharles.Forsyth if(docode(hp, cp, r0, r1-r0))
198*74a4d8c2SCharles.Forsyth goto out;
199*74a4d8c2SCharles.Forsyth break;
200*74a4d8c2SCharles.Forsyth }
201*74a4d8c2SCharles.Forsyth }
202*74a4d8c2SCharles.Forsyth break;
203*74a4d8c2SCharles.Forsyth
204*74a4d8c2SCharles.Forsyth case 0:
205*74a4d8c2SCharles.Forsyth if(r0 == mulval)
206*74a4d8c2SCharles.Forsyth return 1;
207*74a4d8c2SCharles.Forsyth }
208*74a4d8c2SCharles.Forsyth return 0;
209*74a4d8c2SCharles.Forsyth
210*74a4d8c2SCharles.Forsyth out:
211*74a4d8c2SCharles.Forsyth cp[-1] = i+'0';
212*74a4d8c2SCharles.Forsyth return 1;
213*74a4d8c2SCharles.Forsyth }
214*74a4d8c2SCharles.Forsyth
215*74a4d8c2SCharles.Forsyth static int
gen1(int len)216*74a4d8c2SCharles.Forsyth gen1(int len)
217*74a4d8c2SCharles.Forsyth {
218*74a4d8c2SCharles.Forsyth int i;
219*74a4d8c2SCharles.Forsyth
220*74a4d8c2SCharles.Forsyth for(shmax=1; shmax<30; shmax++) {
221*74a4d8c2SCharles.Forsyth valmax = 1<<shmax;
222*74a4d8c2SCharles.Forsyth if(valmax >= mulval)
223*74a4d8c2SCharles.Forsyth break;
224*74a4d8c2SCharles.Forsyth }
225*74a4d8c2SCharles.Forsyth if(mulval == 1)
226*74a4d8c2SCharles.Forsyth return 1;
227*74a4d8c2SCharles.Forsyth
228*74a4d8c2SCharles.Forsyth len--;
229*74a4d8c2SCharles.Forsyth for(i=1; i<=shmax; i++)
230*74a4d8c2SCharles.Forsyth if(gen2(len, 1<<i)) {
231*74a4d8c2SCharles.Forsyth *--mulcp = 'a'+i;
232*74a4d8c2SCharles.Forsyth return 1;
233*74a4d8c2SCharles.Forsyth }
234*74a4d8c2SCharles.Forsyth return 0;
235*74a4d8c2SCharles.Forsyth }
236*74a4d8c2SCharles.Forsyth
237*74a4d8c2SCharles.Forsyth static int
gen2(int len,long r1)238*74a4d8c2SCharles.Forsyth gen2(int len, long r1)
239*74a4d8c2SCharles.Forsyth {
240*74a4d8c2SCharles.Forsyth int i;
241*74a4d8c2SCharles.Forsyth
242*74a4d8c2SCharles.Forsyth if(len <= 0) {
243*74a4d8c2SCharles.Forsyth if(r1 == mulval)
244*74a4d8c2SCharles.Forsyth return 1;
245*74a4d8c2SCharles.Forsyth return 0;
246*74a4d8c2SCharles.Forsyth }
247*74a4d8c2SCharles.Forsyth
248*74a4d8c2SCharles.Forsyth len--;
249*74a4d8c2SCharles.Forsyth if(len == 0)
250*74a4d8c2SCharles.Forsyth goto calcr0;
251*74a4d8c2SCharles.Forsyth
252*74a4d8c2SCharles.Forsyth if(gen3(len, r1, r1+1, UR1)) {
253*74a4d8c2SCharles.Forsyth i = '+';
254*74a4d8c2SCharles.Forsyth goto out;
255*74a4d8c2SCharles.Forsyth }
256*74a4d8c2SCharles.Forsyth if(gen3(len, r1-1, r1, UR0)) {
257*74a4d8c2SCharles.Forsyth i = '-';
258*74a4d8c2SCharles.Forsyth goto out;
259*74a4d8c2SCharles.Forsyth }
260*74a4d8c2SCharles.Forsyth if(gen3(len, 1, r1+1, UR1)) {
261*74a4d8c2SCharles.Forsyth i = '+';
262*74a4d8c2SCharles.Forsyth goto out;
263*74a4d8c2SCharles.Forsyth }
264*74a4d8c2SCharles.Forsyth if(gen3(len, 1, r1-1, UR1)) {
265*74a4d8c2SCharles.Forsyth i = '-';
266*74a4d8c2SCharles.Forsyth goto out;
267*74a4d8c2SCharles.Forsyth }
268*74a4d8c2SCharles.Forsyth
269*74a4d8c2SCharles.Forsyth return 0;
270*74a4d8c2SCharles.Forsyth
271*74a4d8c2SCharles.Forsyth calcr0:
272*74a4d8c2SCharles.Forsyth if(mulval == r1+1) {
273*74a4d8c2SCharles.Forsyth i = '+';
274*74a4d8c2SCharles.Forsyth goto out;
275*74a4d8c2SCharles.Forsyth }
276*74a4d8c2SCharles.Forsyth if(mulval == r1-1) {
277*74a4d8c2SCharles.Forsyth i = '-';
278*74a4d8c2SCharles.Forsyth goto out;
279*74a4d8c2SCharles.Forsyth }
280*74a4d8c2SCharles.Forsyth return 0;
281*74a4d8c2SCharles.Forsyth
282*74a4d8c2SCharles.Forsyth out:
283*74a4d8c2SCharles.Forsyth *--mulcp = i;
284*74a4d8c2SCharles.Forsyth return 1;
285*74a4d8c2SCharles.Forsyth }
286*74a4d8c2SCharles.Forsyth
287*74a4d8c2SCharles.Forsyth static int
gen3(int len,long r0,long r1,int flag)288*74a4d8c2SCharles.Forsyth gen3(int len, long r0, long r1, int flag)
289*74a4d8c2SCharles.Forsyth {
290*74a4d8c2SCharles.Forsyth int i, f1, f2;
291*74a4d8c2SCharles.Forsyth long x;
292*74a4d8c2SCharles.Forsyth
293*74a4d8c2SCharles.Forsyth if(r0 <= 0 ||
294*74a4d8c2SCharles.Forsyth r0 >= r1 ||
295*74a4d8c2SCharles.Forsyth r1 > valmax)
296*74a4d8c2SCharles.Forsyth return 0;
297*74a4d8c2SCharles.Forsyth
298*74a4d8c2SCharles.Forsyth len--;
299*74a4d8c2SCharles.Forsyth if(len == 0)
300*74a4d8c2SCharles.Forsyth goto calcr0;
301*74a4d8c2SCharles.Forsyth
302*74a4d8c2SCharles.Forsyth if(!(flag & UR1)) {
303*74a4d8c2SCharles.Forsyth f1 = UR1|SR1;
304*74a4d8c2SCharles.Forsyth for(i=1; i<=shmax; i++) {
305*74a4d8c2SCharles.Forsyth x = r0<<i;
306*74a4d8c2SCharles.Forsyth if(x > valmax)
307*74a4d8c2SCharles.Forsyth break;
308*74a4d8c2SCharles.Forsyth if(gen3(len, r0, x, f1)) {
309*74a4d8c2SCharles.Forsyth i += 'a';
310*74a4d8c2SCharles.Forsyth goto out;
311*74a4d8c2SCharles.Forsyth }
312*74a4d8c2SCharles.Forsyth }
313*74a4d8c2SCharles.Forsyth }
314*74a4d8c2SCharles.Forsyth
315*74a4d8c2SCharles.Forsyth if(!(flag & UR0)) {
316*74a4d8c2SCharles.Forsyth f1 = UR1|SR1;
317*74a4d8c2SCharles.Forsyth for(i=1; i<=shmax; i++) {
318*74a4d8c2SCharles.Forsyth x = r1<<i;
319*74a4d8c2SCharles.Forsyth if(x > valmax)
320*74a4d8c2SCharles.Forsyth break;
321*74a4d8c2SCharles.Forsyth if(gen3(len, r1, x, f1)) {
322*74a4d8c2SCharles.Forsyth i += 'a';
323*74a4d8c2SCharles.Forsyth goto out;
324*74a4d8c2SCharles.Forsyth }
325*74a4d8c2SCharles.Forsyth }
326*74a4d8c2SCharles.Forsyth }
327*74a4d8c2SCharles.Forsyth
328*74a4d8c2SCharles.Forsyth if(!(flag & SR1)) {
329*74a4d8c2SCharles.Forsyth f1 = UR1|SR1|(flag&UR0);
330*74a4d8c2SCharles.Forsyth for(i=1; i<=shmax; i++) {
331*74a4d8c2SCharles.Forsyth x = r1<<i;
332*74a4d8c2SCharles.Forsyth if(x > valmax)
333*74a4d8c2SCharles.Forsyth break;
334*74a4d8c2SCharles.Forsyth if(gen3(len, r0, x, f1)) {
335*74a4d8c2SCharles.Forsyth i += 'a';
336*74a4d8c2SCharles.Forsyth goto out;
337*74a4d8c2SCharles.Forsyth }
338*74a4d8c2SCharles.Forsyth }
339*74a4d8c2SCharles.Forsyth }
340*74a4d8c2SCharles.Forsyth
341*74a4d8c2SCharles.Forsyth if(!(flag & SR0)) {
342*74a4d8c2SCharles.Forsyth f1 = UR0|SR0|(flag&(SR1|UR1));
343*74a4d8c2SCharles.Forsyth
344*74a4d8c2SCharles.Forsyth f2 = UR1|SR1;
345*74a4d8c2SCharles.Forsyth if(flag & UR1)
346*74a4d8c2SCharles.Forsyth f2 |= UR0;
347*74a4d8c2SCharles.Forsyth if(flag & SR1)
348*74a4d8c2SCharles.Forsyth f2 |= SR0;
349*74a4d8c2SCharles.Forsyth
350*74a4d8c2SCharles.Forsyth for(i=1; i<=shmax; i++) {
351*74a4d8c2SCharles.Forsyth x = r0<<i;
352*74a4d8c2SCharles.Forsyth if(x > valmax)
353*74a4d8c2SCharles.Forsyth break;
354*74a4d8c2SCharles.Forsyth if(x > r1) {
355*74a4d8c2SCharles.Forsyth if(gen3(len, r1, x, f2)) {
356*74a4d8c2SCharles.Forsyth i += 'a';
357*74a4d8c2SCharles.Forsyth goto out;
358*74a4d8c2SCharles.Forsyth }
359*74a4d8c2SCharles.Forsyth } else
360*74a4d8c2SCharles.Forsyth if(gen3(len, x, r1, f1)) {
361*74a4d8c2SCharles.Forsyth i += 'a';
362*74a4d8c2SCharles.Forsyth goto out;
363*74a4d8c2SCharles.Forsyth }
364*74a4d8c2SCharles.Forsyth }
365*74a4d8c2SCharles.Forsyth }
366*74a4d8c2SCharles.Forsyth
367*74a4d8c2SCharles.Forsyth x = r1+r0;
368*74a4d8c2SCharles.Forsyth if(gen3(len, r0, x, UR1)) {
369*74a4d8c2SCharles.Forsyth i = '+';
370*74a4d8c2SCharles.Forsyth goto out;
371*74a4d8c2SCharles.Forsyth }
372*74a4d8c2SCharles.Forsyth
373*74a4d8c2SCharles.Forsyth if(gen3(len, r1, x, UR1)) {
374*74a4d8c2SCharles.Forsyth i = '+';
375*74a4d8c2SCharles.Forsyth goto out;
376*74a4d8c2SCharles.Forsyth }
377*74a4d8c2SCharles.Forsyth
378*74a4d8c2SCharles.Forsyth x = r1-r0;
379*74a4d8c2SCharles.Forsyth if(gen3(len, x, r1, UR0)) {
380*74a4d8c2SCharles.Forsyth i = '-';
381*74a4d8c2SCharles.Forsyth goto out;
382*74a4d8c2SCharles.Forsyth }
383*74a4d8c2SCharles.Forsyth
384*74a4d8c2SCharles.Forsyth if(x > r0) {
385*74a4d8c2SCharles.Forsyth if(gen3(len, r0, x, UR1)) {
386*74a4d8c2SCharles.Forsyth i = '-';
387*74a4d8c2SCharles.Forsyth goto out;
388*74a4d8c2SCharles.Forsyth }
389*74a4d8c2SCharles.Forsyth } else
390*74a4d8c2SCharles.Forsyth if(gen3(len, x, r0, UR0)) {
391*74a4d8c2SCharles.Forsyth i = '-';
392*74a4d8c2SCharles.Forsyth goto out;
393*74a4d8c2SCharles.Forsyth }
394*74a4d8c2SCharles.Forsyth
395*74a4d8c2SCharles.Forsyth return 0;
396*74a4d8c2SCharles.Forsyth
397*74a4d8c2SCharles.Forsyth calcr0:
398*74a4d8c2SCharles.Forsyth f1 = flag & (UR0|UR1);
399*74a4d8c2SCharles.Forsyth if(f1 == UR1) {
400*74a4d8c2SCharles.Forsyth for(i=1; i<=shmax; i++) {
401*74a4d8c2SCharles.Forsyth x = r1<<i;
402*74a4d8c2SCharles.Forsyth if(x >= mulval) {
403*74a4d8c2SCharles.Forsyth if(x == mulval) {
404*74a4d8c2SCharles.Forsyth i += 'a';
405*74a4d8c2SCharles.Forsyth goto out;
406*74a4d8c2SCharles.Forsyth }
407*74a4d8c2SCharles.Forsyth break;
408*74a4d8c2SCharles.Forsyth }
409*74a4d8c2SCharles.Forsyth }
410*74a4d8c2SCharles.Forsyth }
411*74a4d8c2SCharles.Forsyth
412*74a4d8c2SCharles.Forsyth if(mulval == r1+r0) {
413*74a4d8c2SCharles.Forsyth i = '+';
414*74a4d8c2SCharles.Forsyth goto out;
415*74a4d8c2SCharles.Forsyth }
416*74a4d8c2SCharles.Forsyth if(mulval == r1-r0) {
417*74a4d8c2SCharles.Forsyth i = '-';
418*74a4d8c2SCharles.Forsyth goto out;
419*74a4d8c2SCharles.Forsyth }
420*74a4d8c2SCharles.Forsyth
421*74a4d8c2SCharles.Forsyth return 0;
422*74a4d8c2SCharles.Forsyth
423*74a4d8c2SCharles.Forsyth out:
424*74a4d8c2SCharles.Forsyth *--mulcp = i;
425*74a4d8c2SCharles.Forsyth return 1;
426*74a4d8c2SCharles.Forsyth }
427*74a4d8c2SCharles.Forsyth
428*74a4d8c2SCharles.Forsyth /*
429*74a4d8c2SCharles.Forsyth * hint table has numbers that
430*74a4d8c2SCharles.Forsyth * the search algorithm fails on.
431*74a4d8c2SCharles.Forsyth * <1000:
432*74a4d8c2SCharles.Forsyth * all numbers
433*74a4d8c2SCharles.Forsyth * <5000:
434*74a4d8c2SCharles.Forsyth * ÷ by 5
435*74a4d8c2SCharles.Forsyth * <10000:
436*74a4d8c2SCharles.Forsyth * ÷ by 50
437*74a4d8c2SCharles.Forsyth * <65536:
438*74a4d8c2SCharles.Forsyth * ÷ by 250
439*74a4d8c2SCharles.Forsyth */
440*74a4d8c2SCharles.Forsyth Hintab hintab[] =
441*74a4d8c2SCharles.Forsyth {
442*74a4d8c2SCharles.Forsyth 683, "b++d+e+",
443*74a4d8c2SCharles.Forsyth 687, "b+e++e-",
444*74a4d8c2SCharles.Forsyth 691, "b++d+e+",
445*74a4d8c2SCharles.Forsyth 731, "b++d+e+",
446*74a4d8c2SCharles.Forsyth 811, "b++d+i+",
447*74a4d8c2SCharles.Forsyth 821, "b++e+e+",
448*74a4d8c2SCharles.Forsyth 843, "b+d++e+",
449*74a4d8c2SCharles.Forsyth 851, "b+f-+e-",
450*74a4d8c2SCharles.Forsyth 853, "b++e+e+",
451*74a4d8c2SCharles.Forsyth 877, "c++++g-",
452*74a4d8c2SCharles.Forsyth 933, "b+c++g-",
453*74a4d8c2SCharles.Forsyth 981, "c-+e-d+",
454*74a4d8c2SCharles.Forsyth 1375, "b+c+b+h-",
455*74a4d8c2SCharles.Forsyth 1675, "d+b++h+",
456*74a4d8c2SCharles.Forsyth 2425, "c++f-e+",
457*74a4d8c2SCharles.Forsyth 2675, "c+d++f-",
458*74a4d8c2SCharles.Forsyth 2750, "b+d-b+h-",
459*74a4d8c2SCharles.Forsyth 2775, "c-+g-e-",
460*74a4d8c2SCharles.Forsyth 3125, "b++e+g+",
461*74a4d8c2SCharles.Forsyth 3275, "b+c+g+e+",
462*74a4d8c2SCharles.Forsyth 3350, "c++++i+",
463*74a4d8c2SCharles.Forsyth 3475, "c-+e-f-",
464*74a4d8c2SCharles.Forsyth 3525, "c-+d+g-",
465*74a4d8c2SCharles.Forsyth 3625, "c-+e-j+",
466*74a4d8c2SCharles.Forsyth 3675, "b+d+d+e+",
467*74a4d8c2SCharles.Forsyth 3725, "b+d-+h+",
468*74a4d8c2SCharles.Forsyth 3925, "b+d+f-d-",
469*74a4d8c2SCharles.Forsyth 4275, "b+g++e+",
470*74a4d8c2SCharles.Forsyth 4325, "b+h-+d+",
471*74a4d8c2SCharles.Forsyth 4425, "b+b+g-j-",
472*74a4d8c2SCharles.Forsyth 4525, "b+d-d+f+",
473*74a4d8c2SCharles.Forsyth 4675, "c++d-g+",
474*74a4d8c2SCharles.Forsyth 4775, "b+d+b+g-",
475*74a4d8c2SCharles.Forsyth 4825, "c+c-+i-",
476*74a4d8c2SCharles.Forsyth 4850, "c++++i-",
477*74a4d8c2SCharles.Forsyth 4925, "b++e-g-",
478*74a4d8c2SCharles.Forsyth 4975, "c+f++e-",
479*74a4d8c2SCharles.Forsyth 5500, "b+g-c+d+",
480*74a4d8c2SCharles.Forsyth 6700, "d+b++i+",
481*74a4d8c2SCharles.Forsyth 9700, "d++++j-",
482*74a4d8c2SCharles.Forsyth 11000, "b+f-c-h-",
483*74a4d8c2SCharles.Forsyth 11750, "b+d+g+j-",
484*74a4d8c2SCharles.Forsyth 12500, "b+c+e-k+",
485*74a4d8c2SCharles.Forsyth 13250, "b+d+e-f+",
486*74a4d8c2SCharles.Forsyth 13750, "b+h-c-d+",
487*74a4d8c2SCharles.Forsyth 14250, "b+g-c+e-",
488*74a4d8c2SCharles.Forsyth 14500, "c+f+j-d-",
489*74a4d8c2SCharles.Forsyth 14750, "d-g--f+",
490*74a4d8c2SCharles.Forsyth 16750, "b+e-d-n+",
491*74a4d8c2SCharles.Forsyth 17750, "c+h-b+e+",
492*74a4d8c2SCharles.Forsyth 18250, "d+b+h-d+",
493*74a4d8c2SCharles.Forsyth 18750, "b+g-++f+",
494*74a4d8c2SCharles.Forsyth 19250, "b+e+b+h+",
495*74a4d8c2SCharles.Forsyth 19750, "b++h--f-",
496*74a4d8c2SCharles.Forsyth 20250, "b+e-l-c+",
497*74a4d8c2SCharles.Forsyth 20750, "c++bi+e-",
498*74a4d8c2SCharles.Forsyth 21250, "b+i+l+c+",
499*74a4d8c2SCharles.Forsyth 22000, "b+e+d-g-",
500*74a4d8c2SCharles.Forsyth 22250, "b+d-h+k-",
501*74a4d8c2SCharles.Forsyth 22750, "b+d-e-g+",
502*74a4d8c2SCharles.Forsyth 23250, "b+c+h+e-",
503*74a4d8c2SCharles.Forsyth 23500, "b+g-c-g-",
504*74a4d8c2SCharles.Forsyth 23750, "b+g-b+h-",
505*74a4d8c2SCharles.Forsyth 24250, "c++g+m-",
506*74a4d8c2SCharles.Forsyth 24750, "b+e+e+j-",
507*74a4d8c2SCharles.Forsyth 25000, "b++dh+g+",
508*74a4d8c2SCharles.Forsyth 25250, "b+e+d-g-",
509*74a4d8c2SCharles.Forsyth 25750, "b+e+b+j+",
510*74a4d8c2SCharles.Forsyth 26250, "b+h+c+e+",
511*74a4d8c2SCharles.Forsyth 26500, "b+h+c+g+",
512*74a4d8c2SCharles.Forsyth 26750, "b+d+e+g-",
513*74a4d8c2SCharles.Forsyth 27250, "b+e+e+f+",
514*74a4d8c2SCharles.Forsyth 27500, "c-i-c-d+",
515*74a4d8c2SCharles.Forsyth 27750, "b+bd++j+",
516*74a4d8c2SCharles.Forsyth 28250, "d-d-++i-",
517*74a4d8c2SCharles.Forsyth 28500, "c+c-h-e-",
518*74a4d8c2SCharles.Forsyth 29000, "b+g-d-f+",
519*74a4d8c2SCharles.Forsyth 29500, "c+h+++e-",
520*74a4d8c2SCharles.Forsyth 29750, "b+g+f-c+",
521*74a4d8c2SCharles.Forsyth 30250, "b+f-g-c+",
522*74a4d8c2SCharles.Forsyth 33500, "c-f-d-n+",
523*74a4d8c2SCharles.Forsyth 33750, "b+d-b+j-",
524*74a4d8c2SCharles.Forsyth 34250, "c+e+++i+",
525*74a4d8c2SCharles.Forsyth 35250, "e+b+d+k+",
526*74a4d8c2SCharles.Forsyth 35500, "c+e+d-g-",
527*74a4d8c2SCharles.Forsyth 35750, "c+i-++e+",
528*74a4d8c2SCharles.Forsyth 36250, "b+bh-d+e+",
529*74a4d8c2SCharles.Forsyth 36500, "c+c-h-e-",
530*74a4d8c2SCharles.Forsyth 36750, "d+e--i+",
531*74a4d8c2SCharles.Forsyth 37250, "b+g+g+b+",
532*74a4d8c2SCharles.Forsyth 37500, "b+h-b+f+",
533*74a4d8c2SCharles.Forsyth 37750, "c+be++j-",
534*74a4d8c2SCharles.Forsyth 38500, "b+e+b+i+",
535*74a4d8c2SCharles.Forsyth 38750, "d+i-b+d+",
536*74a4d8c2SCharles.Forsyth 39250, "b+g-l-+d+",
537*74a4d8c2SCharles.Forsyth 39500, "b+g-c+g-",
538*74a4d8c2SCharles.Forsyth 39750, "b+bh-c+f-",
539*74a4d8c2SCharles.Forsyth 40250, "b+bf+d+g-",
540*74a4d8c2SCharles.Forsyth 40500, "b+g-c+g+",
541*74a4d8c2SCharles.Forsyth 40750, "c+b+i-e+",
542*74a4d8c2SCharles.Forsyth 41250, "d++bf+h+",
543*74a4d8c2SCharles.Forsyth 41500, "b+j+c+d-",
544*74a4d8c2SCharles.Forsyth 41750, "c+f+b+h-",
545*74a4d8c2SCharles.Forsyth 42500, "c+h++g+",
546*74a4d8c2SCharles.Forsyth 42750, "b+g+d-f-",
547*74a4d8c2SCharles.Forsyth 43250, "b+l-e+d-",
548*74a4d8c2SCharles.Forsyth 43750, "c+bd+h+f-",
549*74a4d8c2SCharles.Forsyth 44000, "b+f+g-d-",
550*74a4d8c2SCharles.Forsyth 44250, "b+d-g--f+",
551*74a4d8c2SCharles.Forsyth 44500, "c+e+c+h+",
552*74a4d8c2SCharles.Forsyth 44750, "b+e+d-h-",
553*74a4d8c2SCharles.Forsyth 45250, "b++g+j-g+",
554*74a4d8c2SCharles.Forsyth 45500, "c+d+e-g+",
555*74a4d8c2SCharles.Forsyth 45750, "b+d-h-e-",
556*74a4d8c2SCharles.Forsyth 46250, "c+bd++j+",
557*74a4d8c2SCharles.Forsyth 46500, "b+d-c-j-",
558*74a4d8c2SCharles.Forsyth 46750, "e-e-b+g-",
559*74a4d8c2SCharles.Forsyth 47000, "b+c+d-j-",
560*74a4d8c2SCharles.Forsyth 47250, "b+e+e-g-",
561*74a4d8c2SCharles.Forsyth 47500, "b+g-c-h-",
562*74a4d8c2SCharles.Forsyth 47750, "b+f-c+h-",
563*74a4d8c2SCharles.Forsyth 48250, "d--h+n-",
564*74a4d8c2SCharles.Forsyth 48500, "b+c-g+m-",
565*74a4d8c2SCharles.Forsyth 48750, "b+e+e-g+",
566*74a4d8c2SCharles.Forsyth 49500, "c-f+e+j-",
567*74a4d8c2SCharles.Forsyth 49750, "c+c+g++f-",
568*74a4d8c2SCharles.Forsyth 50000, "b+e+e+k+",
569*74a4d8c2SCharles.Forsyth 50250, "b++i++g+",
570*74a4d8c2SCharles.Forsyth 50500, "c+g+f-i+",
571*74a4d8c2SCharles.Forsyth 50750, "b+e+d+k-",
572*74a4d8c2SCharles.Forsyth 51500, "b+i+c-f+",
573*74a4d8c2SCharles.Forsyth 51750, "b+bd+g-e-",
574*74a4d8c2SCharles.Forsyth 52250, "b+d+g-j+",
575*74a4d8c2SCharles.Forsyth 52500, "c+c+f+g+",
576*74a4d8c2SCharles.Forsyth 52750, "b+c+e+i+",
577*74a4d8c2SCharles.Forsyth 53000, "b+i+c+g+",
578*74a4d8c2SCharles.Forsyth 53500, "c+g+g-n+",
579*74a4d8c2SCharles.Forsyth 53750, "b+j+d-c+",
580*74a4d8c2SCharles.Forsyth 54250, "b+d-g-j-",
581*74a4d8c2SCharles.Forsyth 54500, "c-f+e+f+",
582*74a4d8c2SCharles.Forsyth 54750, "b+f-+c+g+",
583*74a4d8c2SCharles.Forsyth 55000, "b+g-d-g-",
584*74a4d8c2SCharles.Forsyth 55250, "b+e+e+g+",
585*74a4d8c2SCharles.Forsyth 55500, "b+cd++j+",
586*74a4d8c2SCharles.Forsyth 55750, "b+bh-d-f-",
587*74a4d8c2SCharles.Forsyth 56250, "c+d-b+j-",
588*74a4d8c2SCharles.Forsyth 56500, "c+d+c+i+",
589*74a4d8c2SCharles.Forsyth 56750, "b+e+d++h-",
590*74a4d8c2SCharles.Forsyth 57000, "b+d+g-f+",
591*74a4d8c2SCharles.Forsyth 57250, "b+f-m+d-",
592*74a4d8c2SCharles.Forsyth 57750, "b+i+c+e-",
593*74a4d8c2SCharles.Forsyth 58000, "b+e+d+h+",
594*74a4d8c2SCharles.Forsyth 58250, "c+b+g+g+",
595*74a4d8c2SCharles.Forsyth 58750, "d-e-j--e+",
596*74a4d8c2SCharles.Forsyth 59000, "d-i-+e+",
597*74a4d8c2SCharles.Forsyth 59250, "e--h-m+",
598*74a4d8c2SCharles.Forsyth 59500, "c+c-h+f-",
599*74a4d8c2SCharles.Forsyth 59750, "b+bh-e+i-",
600*74a4d8c2SCharles.Forsyth 60250, "b+bh-e-e-",
601*74a4d8c2SCharles.Forsyth 60500, "c+c-g-g-",
602*74a4d8c2SCharles.Forsyth 60750, "b+e-l-e-",
603*74a4d8c2SCharles.Forsyth 61250, "b+g-g-c+",
604*74a4d8c2SCharles.Forsyth 61750, "b+g-c+g+",
605*74a4d8c2SCharles.Forsyth 62250, "f--+c-i-",
606*74a4d8c2SCharles.Forsyth 62750, "e+f--+g+",
607*74a4d8c2SCharles.Forsyth 64750, "b+f+d+p-",
608*74a4d8c2SCharles.Forsyth };
609*74a4d8c2SCharles.Forsyth int hintabsize = nelem(hintab);
610