|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Generator for planar to chunky conversions
5: *
6: * Copyright 1997 Bernd Schmidt
7: */
8:
9:
10: #include <stdio.h>
11:
12: #include "sysconfig.h"
13: #include "sysdeps.h"
14:
15: #include "custom.h"
16:
17: static char *gen_ind (char *a, int b)
18: {
19: char buf[200];
20: sprintf (buf, "%d(%s)", b, a);
21: return strdup (buf);
22: }
23:
24: static char *gen_indx (char *a, int b, char *c, int d)
25: {
26: char buf[200];
27: sprintf (buf, "%d(%s,%s,%d)", b, a, c, d);
28: return strdup (buf);
29: }
30:
31: static char *gen_indsx (char *a, char *sym, int b, char *c, int d)
32: {
33: char buf[200];
34: sprintf (buf, "%s+%d(%s,%s,%d)", sym, b, a, c, d);
35: return strdup (buf);
36: }
37:
38: #define reg(a) "%" a
39: #define ind(a,b) #b"("a")"
40: #define imm(a) "$"#a
41: #define sym(a) #a
42: #define indx(a,b,c,d) #b"("a","c","#d")"
43: #define indsx(a,s,b,c,d) s"+"#b"("a","c","#d")"
44:
45: static int labelno = 0;
46:
47: static int get_label (void)
48: {
49: return labelno++;
50: }
51: static void declare_label (int nr)
52: {
53: printf (".L%d:\n", nr);
54: }
55: static int new_label (void)
56: {
57: int nr = get_label ();
58: declare_label (nr);
59: return nr;
60: }
61: static void gen_label (int nr) { printf (".L%d", nr); }
62: static void jnz (int nr) { printf ("\tjnz "); gen_label (nr); printf ("\n"); }
63: static void jnc (int nr) { printf ("\tjnc "); gen_label (nr); printf ("\n"); }
64: static void jc (int nr) { printf ("\tjc "); gen_label (nr); printf ("\n"); }
65: static void jmp (int nr) { printf ("\tjmp "); gen_label (nr); printf ("\n"); }
66: static void movl (char *src, char *dst) { printf ("\tmovl %s,%s\n", src, dst); }
67: static void movw (char *src, char *dst) { printf ("\tmovl %s,%s\n", src, dst); }
68: static void movb (char *src, char *dst) { printf ("\tmovl %s,%s\n", src, dst); }
69: static void movzbl (char *src, char *dst) { printf ("\tmovzbl %s,%s\n", src, dst); }
70: static void leal (char *src, char *dst) { printf ("\tleal %s,%s\n", src, dst); }
71: static void addl (char *src, char *dst) { printf ("\taddl %s,%s\n", src, dst); }
72: static void subl (char *src, char *dst) { printf ("\tsubl %s,%s\n", src, dst); }
73: static void cmpl (char *src, char *dst) { printf ("\tcmpl %s,%s\n", src, dst); }
74: static void andl (unsigned long mask, char *dst) { printf ("\tandl $0x%0lx,%s\n", mask, dst); }
75: static void orl (char *src, char *dst) { printf ("\torl %s,%s\n", src, dst); }
76: static void imull (unsigned long val, char *dst) { printf ("\timull $0x%08lx,%s\n", val, dst); }
77: static void decl (char *dst) { printf ("\tdecl %s\n", dst); }
78: static void incl (char *dst) { printf ("\tincl %s\n", dst); }
79: static void bswapl (char *dst) { printf ("\tbswapl %s\n", dst); }
80: static void shrl (int count, char *dst) { printf ("\tshrl $%d,%s\n", count, dst); }
81: static void shll (int count, char *dst) { printf ("\tshll $%d,%s\n", count, dst); }
82: static void pushl (char *src) { printf ("\tpushl %s\n", src); }
83: static void popl (char *dst) { printf ("\tpopl %s\n", dst); }
84: static void ret (void) { printf ("\tret\n"); }
85: static void align (int a) { printf ("\t.align %d\n", 1 << a); }
86: static void shiftleftl (int count, char *dst)
87: {
88: if (count == 0)
89: return;
90: if (count < 0)
91: shrl (-count, dst);
92: else {
93: char *indb0;
94: switch (count) {
95: case 1:
96: addl (dst, dst);
97: break;
98: case 2: case 3:
99: indb0 = gen_indx ("", 0, dst, 1 << count);
100: leal (indb0, dst);
101: free (indb0);
102: break;
103: default:
104: shll (count, dst);
105: }
106: }
107: }
108:
109: static void declare_fn (char *name)
110: {
111: printf ("\t.globl %s\n", name);
112: printf ("\t.type %s,@function\n", name);
113: align (5);
114: printf ("%s:\n", name);
115: }
116:
117: #define esi reg("esi")
118: #define edi reg("edi")
119: #define ebp reg("ebp")
120: #define esp reg("esp")
121: #define eax reg("eax")
122: #define ebx reg("ebx")
123: #define ecx reg("ecx")
124: #define edx reg("edx")
125:
126: /* Modes:
127: * 0: normal
128: * 1: only generate every second plane, set memory
129: * 2: only generate every second plane, starting at second plane, or to memory
130: */
131:
132: /* Normal code: one pixel per bit */
133: static void gen_x86_set_hires_h_toobad_k6_too_slow_someone_try_this_with_a_ppro (int pl, int mode)
134: {
135: int plmul = mode == 0 ? 1 : 2;
136: int ploff = mode == 2 ? 1 : 0;
137: int i;
138: int loop;
139: char buf[40];
140: char *indb0;
141:
142: sprintf (buf, "set_hires_h_%d_%d", pl, mode);
143: declare_fn (buf);
144:
145: pushl (ebp);
146: pushl (esi);
147: pushl (edi);
148: pushl (ebx);
149:
150: if (pl == 0) {
151: movl (ind (esp, 20), ebp);
152: movl (ind (esp, 24), esi);
153: }
154: movl (imm (0), edi);
155:
156: loop = get_label ();
157: jmp (loop);
158: align (5);
159: declare_label (loop);
160:
161: if (pl > 0)
162: movl (ind (esp, 24), esi);
163: if (mode == 2) {
164: if (pl > 0)
165: movl (ind (esp, 20), ebp);
166: movl (indx (ebp, 0, edi, 8), ecx);
167: movl (indx (ebp, 4, edi, 8), ebx);
168: }
169: for (i = 0; i <= pl; i+=2) {
170: int realpl = i * plmul + ploff;
171: char *data1 = (i == 0 && mode != 2 ? ecx : edx);
172: char *data2 = (i == 0 && mode != 2 ? ebx : eax);
173:
174: if (i < pl) {
175: indb0 = gen_indx (esi, (realpl + plmul)*MAX_WORDS_PER_LINE*2, edi, 1);
176: movzbl (indb0, ebp);
177: free (indb0);
178: imull (0x08040201, ebp);
179: }
180:
181: indb0 = gen_indx (esi, realpl*MAX_WORDS_PER_LINE*2, edi, 1);
182: movzbl (indb0, data2);
183: free (indb0);
184:
185: if (i == pl || i == pl - 1)
186: incl (edi);
187: imull (0x08040201, data2);
188: if (i < pl) {
189: movl (ebp, esi);
190: andl (0x08080808, ebp);
191: shiftleftl (realpl + plmul - 7, esi);
192: }
193: movl (data2, data1);
194: andl (0x08080808, data2);
195: shiftleftl (realpl - 7, data1);
196: if (i < pl) {
197: andl (0x01010101 << (realpl + plmul), esi);
198: }
199: andl (0x01010101 << realpl, data1);
200: shiftleftl (realpl - 3, data2);
201: if (i < pl) {
202: shiftleftl (realpl + plmul - 3, ebp);
203: }
204: if (i < pl) {
205: orl (esi, ecx);
206: movl (ind (esp, 24), esi);
207: orl (ebp, ebx);
208: }
209: if (i > 0 || mode == 2) {
210: orl (edx, ecx);
211: orl (eax, ebx);
212: }
213: }
214: if (pl > 0)
215: movl (ind (esp, 20), ebp);
216: cmpl (ind (esp, 28), edi);
217: movl (ecx, indx (ebp, -8, edi, 8));
218: movl (ebx, indx (ebp, -4, edi, 8));
219: jc (loop);
220:
221: popl (reg ("ebx"));
222: popl (reg ("edi"));
223: popl (reg ("esi"));
224: popl (reg ("ebp"));
225: ret ();
226: printf ("\n\n");
227: }
228:
229: static void gen_x86_set_hires_h (int pl, int mode)
230: {
231: int plmul = mode == 0 ? 1 : 2;
232: int ploff = mode == 2 ? 1 : 0;
233: int i;
234: int loop;
235: char buf[40];
236: char *indb0;
237:
238: sprintf (buf, "set_hires_h_%d_%d", pl, mode);
239: declare_fn (buf);
240:
241: pushl (ebp);
242: pushl (esi);
243: pushl (edi);
244: pushl (ebx);
245:
246: if (pl == 0) {
247: movl (ind (esp, 20), ebp);
248: movl (ind (esp, 24), esi);
249: }
250: movl (imm (0), edi);
251:
252: loop = get_label ();
253: jmp (loop);
254: align (5);
255: declare_label (loop);
256:
257: if (pl > 0)
258: movl (ind (esp, 24), esi);
259: if (mode == 2) {
260: if (pl > 0)
261: movl (ind (esp, 20), ebp);
262: movl (indx (ebp, 0, edi, 8), ecx);
263: movl (indx (ebp, 4, edi, 8), ebx);
264: }
265: for (i = 0; i <= pl; i+=2) {
266: int realpl = i * plmul + ploff;
267: char *data1 = (i == 0 && mode != 2 ? ecx : edx);
268: char *data2 = (i == 0 && mode != 2 ? ebx : eax);
269:
270: if (i < pl) {
271: indb0 = gen_indx (esi, (realpl + plmul)*MAX_WORDS_PER_LINE*2, edi, 1);
272: movzbl (indb0, ebp);
273: free (indb0);
274: }
275: indb0 = gen_indx (esi, realpl*MAX_WORDS_PER_LINE*2, edi, 1);
276: movzbl (indb0, data2);
277: free (indb0);
278: if (i < pl) {
279: indb0 = gen_indsx ("", sym (hirestab_h), 0, ebp, 8);
280: movl (indb0, esi);
281: free (indb0);
282: indb0 = gen_indsx ("", sym (hirestab_h), 4, ebp, 8);
283: movl (indb0, ebp);
284: free (indb0);
285: }
286: if (i == pl || i == pl - 1)
287: incl (edi);
288: indb0 = gen_indsx ("", sym (hirestab_h), 0, data2, 8);
289: movl (indb0, data1);
290: free (indb0);
291: indb0 = gen_indsx ("", sym (hirestab_h), 4, data2, 8);
292: movl (indb0, data2);
293: free (indb0);
294: switch (realpl) {
295: case 0:
296: if (i < pl) {
297: addl (esi, esi);
298: addl (ebp, ebp);
299: if (plmul == 2) {
300: addl (esi, esi);
301: addl (ebp, ebp);
302: }
303: }
304: break;
305: case 1:
306: if (i < pl) {
307: indb0 = gen_indx ("", 0, esi, 4*plmul);
308: leal (indb0, esi);
309: free (indb0);
310: indb0 = gen_indx ("", 0, ebp, 4*plmul);
311: leal (indb0, ebp);
312: free (indb0);
313: }
314: addl (data1, data1);
315: addl (data2, data2);
316: break;
317: case 2:
318: if (i < pl) {
319: if (plmul == 1)
320: leal (indx ("", 0, esi, 8), esi);
321: else
322: shll (4, esi);
323: }
324: addl (data1, data1);
325: addl (data2, data2);
326: if (i < pl) {
327: if (plmul == 1)
328: leal (indx ("", 0, ebp, 8), ebp);
329: else
330: shll (4, ebp);
331: }
332: addl (data1, data1);
333: addl (data2, data2);
334: break;
335: case 3:
336: if (i < pl)
337: shll (3 + plmul, esi);
338: indb0 = gen_indx ("", 0, data1, 8);
339: leal (indb0, data1);
340: free (indb0);
341: if (i < pl)
342: shll (3 + plmul, ebp);
343: indb0 = gen_indx ("", 0, data2, 8);
344: leal (indb0, data2);
345: free (indb0);
346: break;
347: case 4: case 5: case 6: case 7:
348: shll (realpl, data1);
349: shll (realpl, data2);
350: if (i < pl) {
351: shll (realpl+plmul, esi);
352: shll (realpl+plmul, ebp);
353: }
354: break;
355: }
356:
357: if (i < pl) {
358: orl (esi, ecx);
359: orl (ebp, ebx);
360: if (i + 2 <= pl)
361: movl (ind (esp, 24), esi);
362: }
363: if (i + 2 > pl && pl > 0)
364: movl (ind (esp, 20), ebp);
365: if (i > 0 || mode == 2) {
366: orl (data1, ecx);
367: orl (data2, ebx);
368: }
369: }
370:
371: cmpl (ind (esp, 28), edi);
372: movl (ecx, indx (ebp, -8, edi, 8));
373: movl (ebx, indx (ebp, -4, edi, 8));
374: jc (loop);
375:
376: popl (reg ("ebx"));
377: popl (reg ("edi"));
378: popl (reg ("esi"));
379: popl (reg ("ebp"));
380: ret ();
381: printf ("\n\n");
382: }
383:
384: /* Squeeze: every second bit does not generate a pixel
385: Not optimized, this mode isn't useful. */
386: static void gen_x86_set_hires_l (int pl, int mode)
387: {
388: int plmul = mode == 0 ? 1 : 2;
389: int ploff = mode == 2 ? 1 : 0;
390: int i;
391: int loop;
392: char buf[40];
393:
394: sprintf (buf, "set_hires_l_%d_%d", pl, mode);
395: declare_fn (buf);
396:
397: pushl (ebp);
398: pushl (esi);
399: pushl (edi);
400: pushl (ebx);
401:
402: movl (ind (esp, 20), ebp);
403: movl (ind (esp, 24), esi);
404: movl (imm (0), edi);
405:
406: align (5);
407: loop = new_label ();
408:
409: if (mode == 2) {
410: movl (indx (ebp, 0, edi, 1), ecx);
411: }
412:
413: for (i = 0; i <= pl; i++) {
414: int realpl = i * plmul + ploff;
415: char *data1 = (i == 0 && mode != 2 ? ecx : edx);
416: char *indb0;
417:
418: indb0 = gen_indx (esi, realpl*MAX_WORDS_PER_LINE*2, edi, 1);
419: movzbl (indb0, data1);
420: free (indb0);
421:
422: indb0 = gen_indsx ("", sym (hirestab_l), 0, data1, 4);
423: movl (indb0, data1);
424: free (indb0);
425: if (i == pl)
426: incl (edi);
427: shiftleftl (realpl, data1);
428: if (i > 0 || mode == 2) {
429: orl (data1, ecx);
430: }
431: }
432: cmpl (ind (esp, 28), edi);
433: movl (ecx, indx (ebp, -4, edi, 4));
434: jc (loop);
435:
436: popl (reg ("ebx"));
437: popl (reg ("edi"));
438: popl (reg ("esi"));
439: popl (reg ("ebp"));
440: ret ();
441: printf ("\n\n");
442: }
443:
444: /* Stretch: two pixels per bit */
445: static void gen_x86_set_lores_h (int pl, int mode)
446: {
447: int plmul = mode == 0 ? 1 : 2;
448: int ploff = mode == 2 ? 1 : 0;
449: int i, j;
450: int loop;
451: char buf[40];
452:
453: sprintf (buf, "set_lores_h_%d_%d", pl, mode);
454: declare_fn (buf);
455:
456: pushl (ebp);
457: pushl (esi);
458: pushl (edi);
459: pushl (ebx);
460:
461: movl (ind (esp, 20), ebp);
462: movl (ind (esp, 24), esi);
463: movl (imm (0), edi);
464:
465: align (5);
466: loop = new_label ();
467:
468: for (j = 0; j < 2; j++) {
469: if (mode == 2) {
470: movl (j ? ind (ebp, 8) : ind (ebp, 0), ecx);
471: movl (j ? ind (ebp, 12) : ind (ebp, 4), ebx);
472: }
473:
474: for (i = 0; i <= pl; i++) {
475: int realpl = i * plmul + ploff;
476: char *data1 = (i == 0 && mode != 2 ? ecx : edx);
477: char *data2 = (i == 0 && mode != 2 ? ebx : eax);
478: char *indb0;
479:
480: indb0 = gen_indx (esi, realpl*MAX_WORDS_PER_LINE*2, edi, 1);
481: movzbl (indb0, data2);
482: free (indb0);
483: addl (data2, data2);
484: indb0 = gen_indsx ("", sym (lorestab_h), 0 + j*8, data2, 8);
485: movl (indb0, data1);
486: free (indb0);
487: indb0 = gen_indsx ("", sym (lorestab_h), 4 + j*8, data2, 8);
488: movl (indb0, data2);
489: free (indb0);
490: shiftleftl (realpl, data1);
491: shiftleftl (realpl, data2);
492: if (i > 0 || mode == 2) {
493: orl (data1, ecx);
494: orl (data2, ebx);
495: }
496: }
497: movl (ecx, j ? ind (ebp, 8) : ind (ebp, 0));
498: movl (ebx, j ? ind (ebp, 12) : ind (ebp, 4));
499: }
500: incl (edi);
501: cmpl (ind (esp, 28), edi);
502: leal (ind (ebp, 16), ebp);
503: jc (loop);
504:
505: popl (reg ("ebx"));
506: popl (reg ("edi"));
507: popl (reg ("esi"));
508: popl (reg ("ebp"));
509: ret ();
510: printf ("\n\n");
511: }
512:
513:
514: /* Normal code: one pixel per bit */
515: static void gen_c_set_hires_h (int pl, int mode, int header)
516: {
517: int plmul = mode == 0 ? 1 : 2;
518: int ploff = mode == 2 ? 1 : 0;
519: int i;
520:
521: if (header)
522: printf("extern ");
523: printf ("void set_hires_h_%d_%d (uae_u32 *app, uae_u8 *ptr, int len)", pl, mode);
524: if (header) {
525: printf (";\n");
526: return;
527: }
528:
529: printf ("\n\{\n\tint i;\n\tfor (i = 0; i < len; i++) {\n\t\tuae_u32 v1, v2;\n");
530:
531: if (mode == 2) {
532: printf ("\t\tv1 = app[i*2 + 0]; v2 = app[i*2 + 1];\n");
533: }
534:
535: for (i = 0; i <= pl; i++) {
536: int realpl = i * plmul + ploff;
537: char *asgn = (i == 0 && mode != 2 ? "=" : "|=");
538:
539: printf ("\t\t{\n");
540: printf ("\t\t\tunsigned int data = *(ptr + i + %d);\n", MAX_WORDS_PER_LINE*2*realpl);
541:
542: printf ("\t\t\tv1 %s hirestab_h[data][0] << %d;\n", asgn, realpl);
543: printf ("\t\t\tv2 %s hirestab_h[data][1] << %d;\n", asgn, realpl);
544: printf ("\t\t}\n");
545: }
546: printf ("\t\tapp[i*2 + 0] = v1;\n");
547: printf ("\t\tapp[i*2 + 1] = v2;\n");
548: printf ("\t}\n");
549: printf ("}\n\n");
550: }
551:
552: /* Squeeze: every second bit does not generate a pixel
553: Not optimized, this mode isn't useful. */
554: static void gen_c_set_hires_l (int pl, int mode, int header)
555: {
556: int plmul = mode == 0 ? 1 : 2;
557: int ploff = mode == 2 ? 1 : 0;
558: int i;
559: int loop;
560:
561: if (header)
562: printf("extern ");
563: printf ("void set_hires_l_%d_%d (uae_u32 *app, uae_u8 *ptr, int len)", pl, mode);
564: if (header) {
565: printf (";\n");
566: return;
567: }
568:
569: printf ("\n\{\n\tint i;\n\tfor (i = 0; i < len; i++) {\n\t\tuae_u32 v1;\n");
570:
571: if (mode == 2) {
572: printf ("\t\tv1 = app[i];\n");
573: }
574:
575: for (i = 0; i <= pl; i++) {
576: int realpl = i * plmul + ploff;
577: char *asgn = (i == 0 && mode != 2 ? "=" : "|=");
578:
579: printf ("\t\t{\n");
580: printf ("\t\t\tunsigned int data = *(ptr + i + %d);\n", MAX_WORDS_PER_LINE*2*realpl);
581:
582: printf ("\t\t\tv1 %s hirestab_l[data][0] << %d;\n", asgn, realpl);
583: printf ("\t\t}\n");
584: }
585: printf ("\t\tapp[i] = v1;\n");
586: printf ("\t}\n");
587: printf ("}\n\n");
588: }
589:
590: /* Stretch: two pixels per bit */
591: static void gen_c_set_lores_h (int pl, int mode, int header)
592: {
593: int plmul = mode == 0 ? 1 : 2;
594: int ploff = mode == 2 ? 1 : 0;
595: int i, j;
596:
597: if (header)
598: printf("extern ");
599: printf ("void set_lores_h_%d_%d (uae_u32 *app, uae_u8 *ptr, int len)", pl, mode);
600: if (header) {
601: printf (";\n");
602: return;
603: }
604:
605: printf ("\n\{\n\tint i;\n\tfor (i = 0; i < len; i++) {\n\t\tuae_u32 v1, v2, v3, v4;\n");
606:
607: if (mode == 2) {
608: printf ("\t\tv1 = app[i*4 + 0]; v2 = app[i*4 + 1]; v3 = app[i*4 + 2]; v4 = app[i*4 + 3];\n");
609: }
610:
611: for (i = 0; i <= pl; i++) {
612: int realpl = i * plmul + ploff;
613: char *asgn = (i == 0 && mode != 2 ? "=" : "|=");
614:
615: printf ("\t\t{\n");
616: printf ("\t\t\tunsigned int data = *(ptr + i + %d);\n", MAX_WORDS_PER_LINE*2*realpl);
617:
618: printf ("\t\t\tv1 %s lorestab_h[data][0] << %d;\n", asgn, realpl);
619: printf ("\t\t\tv2 %s lorestab_h[data][1] << %d;\n", asgn, realpl);
620: printf ("\t\t\tv3 %s lorestab_h[data][2] << %d;\n", asgn, realpl);
621: printf ("\t\t\tv4 %s lorestab_h[data][3] << %d;\n", asgn, realpl);
622: printf ("\t\t}\n");
623: }
624: printf ("\t\tapp[i*4 + 0] = v1;\n");
625: printf ("\t\tapp[i*4 + 1] = v2;\n");
626: printf ("\t\tapp[i*4 + 2] = v3;\n");
627: printf ("\t\tapp[i*4 + 3] = v4;\n");
628: printf ("\t}\n");
629: printf ("}\n\n");
630: }
631:
632: int main(int argc, char **argv)
633: {
634: int pl;
635: int outmode;
636:
637: if (argc != 2)
638: return 1;
639: if (strcmp (argv[1], "C") == 0)
640: outmode = 0;
641: else if (strcmp (argv[1], "H") == 0)
642: outmode = 1;
643: else if (strcmp (argv[1], "x86") == 0)
644: outmode = 2;
645: else
646: return 1;
647:
648: switch (outmode) {
649: case 0:
650: printf ("#include \"sysconfig.h\"\n");
651: printf ("#include \"sysdeps.h\"\n");
652: printf ("#include \"custom.h\"\n");
653: printf ("#include \"p2c.h\"\n");
654: break;
655: case 1:
656: printf ("#define MAX_WORDS_PER_LINE %d\n", MAX_WORDS_PER_LINE);
657: break;
658: case 2:
659: printf ("#define MAX_WORDS_PER_LINE %d\n", MAX_WORDS_PER_LINE);
660: printf (".text\n");
661: break;
662: }
663: for (pl = 0; pl < 8; pl++) {
664: int j;
665: for (j = 0; j < (pl < 4 ? 3 : 1); j++) {
666: switch (outmode) {
667: case 0: case 1:
668: gen_c_set_hires_h (pl, j, outmode);
669: gen_c_set_hires_l (pl, j, outmode);
670: gen_c_set_lores_h (pl, j, outmode);
671: break;
672: case 2:
673: gen_x86_set_hires_h (pl, j);
674: gen_x86_set_hires_l (pl, j);
675: gen_x86_set_lores_h (pl, j);
676: break;
677: }
678: }
679: }
680:
681: return 0;
682: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.