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