|
|
1.1 root 1:
2: #include <assert.h>
3: #include <stdio.h>
4: #include <stdlib.h>
5: #include <string.h>
6: #include <ctype.h>
7: #include <stdarg.h>
8: #include "dict.h"
9: #include "as68k.h"
10: #include "output.h"
11:
12: //#define DUMP_LOADS_OF_CRAP
13:
14: static op_t pending;
15: static char pending_func_name[LAB_LEN];
16: static enum M68K_OPS next_op_type;
17:
18: #define GEN_CALL 0
19: #define GEN_BODY 1
20: static int gen_mode;
21: static int return_target;
22:
23: /* which flags an M68K_OP thingy may set */
24: #define fN (1<<0)
25: #define fZ (1<<1)
26: #define fV (1<<2)
27: #define fC (1<<3)
28: #define fX (1<<4)
29: #define fNZVCX (fN | fZ | fV | fC | fX)
30: #define fNZVC (fN | fZ | fV | fC)
31: #define _fSafe 0
32: /* _fSafe are ones i haven't got round to doing yet. */
33:
34: static int sets_flags[OP_MAX+1] = {
35: _fSafe, /* OP_NONE */
36: 0, // OP_JMP
37: fZ, // OP_BCHG
38: fZ, // OP_BCLR
39: fZ, // OP_BSET
40: fZ, // OP_BTST
41: fNZVC, // OP_MULS
42: fNZVC, // OP_MULU,
43: fNZVC, // OP_AND
44: fNZVC, // OP_OR
45: fNZVC, // OP_XOR
46: fNZVC, // OP_NOT
47: fNZVCX, // OP_NEGX
48: fNZVCX, // OP_NEG
49: fNZVC, // OP_DIVU
50: fNZVC, // OP_DIVS
51: fNZVCX, // OP_ASL,
52: fNZVCX, // OP_LSL
53: fNZVCX, // OP_ROXR
54: fNZVCX, // OP_ROXL
55: fNZVC, // OP_ROL
56: fNZVC, // OP_ROR
57: fNZVCX, // OP_ASR
58: fNZVCX, // OP_LSR,
59: 0, // OP_MOVEM
60: fNZVCX, // OP_SUBX
61: fNZVCX, // OP_ADDX
62: fNZVCX, // OP_ADD
63: fNZVC, // OP_CMPA
64: fNZVC, // OP_CMP
65: fNZVCX, // OP_SUB,
66: _fSafe, // OP_ADDA
67: _fSafe, // OP_SUBA
68: fNZVC, // OP_SWAP
69: _fSafe, // OP_JSR
70: 0, // OP_BCC
71: 0, // OP_DBCC
72: fNZVC, // OP_CLR,
73: 0, // OP_EXG
74: fNZVC, // OP_EXT
75: 0, // OP_RTE
76: 0, // OP_RTS
77: 0, // OP_ILLEGAL
78: 0, // OP_HCALL
79: 0, // OP_LINK,
80: 0, // OP_UNLK
81: fNZVC, // OP_MOVE
82: _fSafe, // OP_MOVEA
83: fNZVC, // OP_TST
84: 0, // OP_PEA
85: 0, // OP_LEA
86: 0, // OP_SCC
87: _fSafe, // OP_MAX.....
88: };
89:
90: /* does the flag need to be set? if the next instruction will
91: * set the flag then no. */
92: #define ifZ if(!(sets_flags[next_op_type] & fZ))
93: #define ifN if(!(sets_flags[next_op_type] & fN))
94: #define ifV if(!(sets_flags[next_op_type] & fV))
95: #define ifC if(!(sets_flags[next_op_type] & fC))
96: //#define ifCX if((!(sets_flags[next_op_type] & fC)) && (!(sets_flags[next_op_type] & fX)))
97: //#define ifX if(!(sets_flags[next_op_type] & fX))
98: #define ifVoN if((!(sets_flags[next_op_type] & fV)) || (!(sets_flags[next_op_type] & fN)))
99:
100: FILE *f_temp;
101: FILE *c_out;
102: FILE *c_out2; /* writing functions here */
103:
104: /* useless stats */
105: static int num_funcs;
106:
107: #define SWAP_COUT { f_temp = c_out; c_out = c_out2; c_out2 = f_temp; }
108:
109: static void output_op (op_t *op, op_t *next);
110:
111: static void cout (const char *format, ...)
112: {
113: va_list argptr;
114:
115: va_start (argptr, format);
116: vfprintf (c_out, format, argptr);
117: va_end (argptr);
118: }
119: static void cln (const char *format, ...)
120: {
121: va_list argptr;
122:
123: fputc ('\t', c_out);
124: va_start (argptr, format);
125: vfprintf (c_out, format, argptr);
126: va_end (argptr);
127: fputc ('\n', c_out);
128: }
129: /* C code generation shit */
130: const char *c_usizes[] = { "u8", "u16", "u32" };
131: const char *c_ssizes[] = { "s8", "s16", "s32" };
132: const char *mem_read_funcs[] = { "rdbyte", "rdword", "rdlong" };
133: const char *mem_write_funcs[] = { "wrbyte", "wrword", "wrlong" };
134:
135: void c_label (const char *lab)
136: {
137: cout ("__N%s:\n", lab);
138: add_fixup (0, C_ADDR, lab);
139: }
140:
141: void c_addr_label (int labelled)
142: {
143: if (labelled || return_target || (get_bitpos () == 0x1c)) {
144: cout ("\tcase (0x%x):\n", get_bitpos ());
145: }
146: cln ("#ifdef M68K_DEBUG");
147: cln (" line_no = %d;", line_no);
148: #ifdef DUMP_LOADS_OF_CRAP
149: cln (" DumpRegsChanged ();");
150: #endif /* DUMP_LOADS_OF_CRAP */
151: cln ("#endif");
152: }
153:
154: void c_begin (const char *src_filename, const char *bin_filename)
155: {
156: char buf[128];
157: snprintf (buf, sizeof (buf), ".%s.c", src_filename);
158: if ((c_out = fopen (buf, "w"))==NULL) {
159: fprintf (stderr, "Error: Cannot open %s for writing.\n", buf);
160: exit (-1);
161: }
162: snprintf (buf, sizeof (buf), ".%s.fn.c", src_filename);
163: if ((c_out2 = fopen (buf, "w"))==NULL) {
164: fprintf (stderr, "Error: Cannot open %s for writing.\n", buf);
165: exit (-1);
166: }
167:
168: cout ("void Init680x0 () {\n");
169: cln ("STRam = &m68kram[0];");
170: cln ("load_binfile (\"%s\");", bin_filename);
171: cout ("}\n");
172:
173: cout ("void Start680x0 ()\n{\n");
174: cout ("\ts32 i, jdest = 0x1c;\n");
175: cout ("\tRegs[15]._u32 = MEM_SIZE;\n\n");
176: cout ("jumptable:\n\tswitch (jdest) {\n");
177: }
178:
179: void c_end (const char *src_filename)
180: {
181: /* some more crap needs to be added to the top */
182: char c, buf[128];
183: FILE *f;
184: struct Fixup *fix;
185: struct Label *lab;
186:
187: /* remember to do last pending instruction */
188: next_op_type = OP_NONE;
189: if (pending.optype) {
190: gen_mode = GEN_BODY;
191: output_op (&pending, NULL);
192: gen_mode = GEN_CALL;
193: }
194:
195: fclose (c_out);
196: fclose (c_out2);
197:
198: snprintf (buf, sizeof (buf), "%s.c", src_filename);
199: if ((c_out = fopen (buf, "w"))==NULL) {
200: fprintf (stderr, "Error: Cannot open %s for writing.\n", buf);
201: exit (-1);
202: }
203:
204: /* _host.c contains much necessary boilerplate code. include it */
205: cout ("#include \"_host.c\"\n");
206:
207: /* call prototype turds */
208: cout ("#ifdef PART1\n");
209: fix = fix_first;
210: for (; fix != NULL; fix = fix->next) {
211: if (fix->size == C_FUNC) {
212: cout ("extern void %s ();\n", fix->label);
213: continue;
214: }
215: }
216: cout ("#endif /* PART1 */\n");
217: /* address 'fixups' */
218: fix = fix_first;
219: for (; fix != NULL; fix = fix->next) {
220: if (fix->size != C_ADDR) continue;
221:
222: lab = get_label (fix->label);
223: if (!lab) {
224: /* ignore. let pass2 throw the error. */
225: continue;
226: }
227: cout ("#define __D%s (0x%x)\n", lab->name, lab->val+BASE);
228: }
229:
230: /* the code we made */
231: snprintf (buf, sizeof (buf), ".%s.fn.c", src_filename);
232: if ((f = fopen (buf, "r"))==NULL) {
233: fprintf (stderr, "Error: Cannot open %s for writing.\n", buf);
234: exit (-1);
235: }
236: cout ("#ifdef PART2\n");
237: while ((c = fgetc (f)) != EOF) fputc (c, c_out);
238: fclose (f);
239: remove (buf);
240: cout ("#endif /* PART2 */\n");
241:
242: snprintf (buf, sizeof (buf), ".%s.c", src_filename);
243: if ((f = fopen (buf, "r"))==NULL) {
244: fprintf (stderr, "Error: Cannot open %s for writing.\n", buf);
245: exit (-1);
246: }
247: cout ("#ifdef PART1\n");
248: while ((c = fgetc (f)) != EOF) fputc (c, c_out);
249: fclose (f);
250: remove (buf);
251:
252: /* and then computed jump table */
253: cln ("goto end_;");
254: cout ("\t\tdefault: \n");
255: cln ("#ifdef M68K_DEBUG");
256: cln (" printf (\"Bad jump target at line %%d: $%%x (rdest=$%%x).\\n\", line_no, jdest, rdest);");
257: cln ("#else");
258: cln (" printf (\"Bad jump target: $%%x (rdest=$%%x).\\n\", jdest, rdest);");
259: cln ("#endif");
260: cln ("abort ();");
261: cout (" }\n\n");
262:
263: cout ("handle_exception:\n");
264: cln ("for (i=0; i<32; i++) {");
265: cln (" if (exceptions_pending & ((1<<i))) {");
266: cln (" jdest = exception_handlers[i];");
267: cln (" if (!--exceptions_pending_nums[i]) {");
268: cln (" exceptions_pending ^= 1<<i;");
269: cln (" }");
270: /* save flags */
271: cln (" bN=N; bnZ=nZ; bV=V; bC=C; bX=X;");
272: cln (" goto jumptable;");
273: cln (" }");
274: cln ("}");
275: cln ("/* shouldn't get here... */");
276: cln ("jdest = rdest;");
277: cln ("goto jumptable;\n");
278:
279: cout ("end_:\treturn;\n}\n");
280: cout ("#endif /* PART1 */\n");
281:
282: fclose (c_out);
283:
284: printf ("%d functions generated.\n", num_funcs);
285: }
286:
287: static int is_immediate (ea_t *ea)
288: {
289: return ((ea->mode == 7) && (ea->reg == 4));
290: }
291:
292: static void c_postea (ea_t *ea)
293: {
294: int inc;
295:
296: inc = 1<<ea->op_size;
297: if ((ea->reg == 15) && (inc == 1)) inc = 2;
298:
299: switch (ea->mode) {
300: /* areg postinc */
301: case 3: cln ("Regs[%d]._s32 += %d;", ea->reg, inc); break;
302: /* areg predec */
303: case 4: cln ("Regs[%d]._s32 -= %d;", ea->reg, inc); break;
304: default: break;
305: }
306: }
307: static void c_ea_get_address (ea_t *ea, char *buf)
308: {
309: int inc;
310: switch (ea->mode) {
311: /* dreg, areg */
312: case 0: case 1: assert (0);
313: /* areg indirect, postinc */
314: case 2: case 3:
315: sprintf (buf, "(Regs[%d]._s32)", ea->reg); break;
316: /* areg predec */
317: case 4:
318: inc = 1<<ea->op_size;
319: /* stack pointer always by 2 */
320: if ((ea->reg == 15) && (inc == 1)) inc = 2;
321:
322: sprintf (buf, "(Regs[%d]._s32-%d)", ea->reg, inc);
323: break;
324: /* areg offset */
325: case 5:
326: sprintf (buf, "(Regs[%d]._s32%+d)", ea->reg, ea->imm.val);
327: break;
328: /* areg offset + reg */
329: case 6:
330: sprintf (buf, "(Regs[%d]._s32+((%s)Regs[%d]._s32)%+d)", ea->reg, (ea->ext._.size ? "s32" : "s16"), ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), ea->ext._.displacement);
331: break;
332: /* yes */
333: case 7:
334: /* $xxx.w */
335: if (ea->reg == 0) {
336: sprintf (buf, "(%d)", ea->imm.val);
337: }
338: /* $xxx.l */
339: else if (ea->reg == 1) {
340: if (ea->imm.has_label) {
341: sprintf (buf, "(__D%s)", ea->imm.label);
342: } else {
343: sprintf (buf, "(%d)", ea->imm.val);
344: }
345: }
346: /* immediate */
347: else if (ea->reg == 4) {
348: assert (0);
349: }
350: /* PC + offset */
351: else if (ea->reg == 2) {
352: if (ea->imm.has_label)
353: sprintf (buf, "__D%s", ea->imm.label);
354: else
355: error ("Absolute value not allowed.");
356: }
357: /* PC + INDEX + OFFSET */
358: else if (ea->reg == 3) {
359: if (!ea->imm.has_label) error ("Absolute value not allowed.");
360: sprintf (buf, "(__D%s + Regs[%d]._%s)",
361: ea->imm.label,
362: ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0),
363: (ea->ext._.size ? "s32" : "s16"));
364: }
365: break;
366: default:
367: assert (0);
368: }
369: }
370: static void c_readea (ea_t *ea, char *buf)
371: {
372: int inc;
373: switch (ea->mode) {
374: /* dreg, areg */
375: case 0:
376: case 1:
377: sprintf (buf, "Regs[%d]._%s", ea->reg, c_ssizes[ea->op_size]);
378: break;
379: /* areg indirect */
380: case 2:
381: sprintf (buf, "%s(Regs[%d]._s32)", mem_read_funcs[ea->op_size], ea->reg);
382: break;
383: /* areg postinc */
384: case 3:
385: sprintf (buf, "%s(Regs[%d]._s32)", mem_read_funcs[ea->op_size], ea->reg);
386: break;
387: /* areg predec */
388: case 4:
389: inc = 1<<ea->op_size;
390: /* stack pointer always by 2 */
391: if ((ea->reg == 15) && (inc == 1)) inc = 2;
392:
393: sprintf (buf, "%s(Regs[%d]._s32-%d)", mem_read_funcs[ea->op_size], ea->reg, inc);
394: break;
395: /* areg offset */
396: case 5:
397: sprintf (buf, "%s(Regs[%d]._s32%+d)", mem_read_funcs[ea->op_size], ea->reg, ea->imm.val);
398: break;
399: /* areg offset + reg */
400: case 6:
401: sprintf (buf, "%s(Regs[%d]._s32+((%s)Regs[%d]._s32)%+d)", mem_read_funcs[ea->op_size], ea->reg, (ea->ext._.size ? "s32" : "s16"), ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), ea->ext._.displacement);
402: break;
403: /* yes */
404: case 7:
405: /* $xxx.w */
406: if (ea->reg == 0) {
407: sprintf (buf, "%s(%d)", mem_read_funcs[ea->op_size], ea->imm.val);
408: }
409: /* $xxx.l */
410: else if (ea->reg == 1) {
411: if (ea->imm.has_label) {
412: sprintf (buf, "%s(__D%s)", mem_read_funcs[ea->op_size], ea->imm.label);
413: } else {
414: sprintf (buf, "%s(%d)", mem_read_funcs[ea->op_size], ea->imm.val);
415: }
416: }
417: /* immediate */
418: else if (ea->reg == 4) {
419: if (ea->imm.has_label) {
420: sprintf (buf, "__D%s", ea->imm.label);
421: } else {
422: sprintf (buf, "%d", ea->imm.val);
423: }
424: }
425: /* PC + offset */
426: else if (ea->reg == 2) {
427: if (ea->imm.has_label)
428: sprintf (buf, "%s(__D%s)", mem_read_funcs[ea->op_size], ea->imm.label);
429: else
430: error ("Absolute value not allowed.");
431: }
432: /* PC + INDEX + OFFSET */
433: else if (ea->reg == 3) {
434: if (!ea->imm.has_label) error ("Absolute value not allowed.");
435: sprintf (buf, "%s(__D%s + Regs[%d]._%s)",
436: mem_read_funcs[ea->op_size],
437: ea->imm.label,
438: ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0),
439: (ea->ext._.size ? "s32" : "s16"));
440: }
441: break;
442: default:
443: error ("nasty error in c_readea()");
444: }
445: }
446: static void c_writeea (ea_t *ea, int size, const char *val)
447: {
448: int inc;
449: switch (ea->mode) {
450: /* dreg, areg */
451: case 0: case 1:
452: cln ("Regs[%d]._%s = %s;", ea->reg, (size==BYTE ? "s8" : (size==WORD ? "s16" : "s32")), val);
453: break;
454: /* areg indirect */
455: case 2:
456: cln ("%s(Regs[%d]._s32, %s);", mem_write_funcs[size], ea->reg, val);
457: break;
458: /* areg postinc */
459: case 3:
460: cln ("%s(Regs[%d]._s32, %s);", mem_write_funcs[size], ea->reg, val);
461: break;
462: /* areg predec */
463: case 4:
464: inc = 1<<size;
465: /* stack pointer always by 2 */
466: if ((ea->reg == 15) && (inc == 1)) inc = 2;
467:
468: cln ("%s(Regs[%d]._s32-%d, %s);", mem_write_funcs[size], ea->reg, inc, val);
469: break;
470: /* areg offset */
471: case 5:
472: cln ("%s(Regs[%d]._s32%+d, %s);", mem_write_funcs[size], ea->reg, ea->imm.val, val);
473: break;
474: /* areg offset + reg */
475: case 6:
476: cln ("%s(Regs[%d]._s32+(Regs[%d]._%s)%+d, %s);", mem_write_funcs[size], ea->reg, ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), (ea->ext._.size ? "s32" : "s16"), ea->ext._.displacement, val);
477: break;
478: /* yes */
479: case 7:
480: /* $xxx.w */
481: if (ea->reg == 0) {
482: cln ("%s(%d, %s);", mem_write_funcs[size], ea->imm.val, val);
483: }
484: /* $xxx.l */
485: else if (ea->reg == 1) {
486: if (ea->imm.has_label) {
487: cln ("%s(__D%s, %s);", mem_write_funcs[size], ea->imm.label, val);
488: } else {
489: cln ("%s(%d, %s);", mem_write_funcs[size], ea->imm.val, val);
490: }
491: }
492: /* immediate */
493: else if (ea->reg == 4) {
494: if (ea->imm.has_label) {
495: cln ("%s(__D%s, %s);", mem_write_funcs[size], ea->imm.label, val);
496: } else {
497: cln ("%s(%d, %s);", mem_write_funcs[size], ea->imm.val, val);
498: }
499: }
500: /* PC + offset */
501: else if (ea->reg == 2) {
502: if (ea->imm.has_label)
503: cln ("%s(__D%s, %s);", mem_write_funcs[size], ea->imm.label, val);
504: else
505: error ("Absolute value not allowed.");
506: }
507: /* PC + INDEX + OFFSET */
508: else if (ea->reg == 3) {
509: if (!ea->imm.has_label) error ("Absolute value not allowed.");
510: cln ("%s(__D%s + Regs[%d]._%s, %s);", mem_write_funcs[size], ea->imm.label, ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), (ea->ext._.size ? "s32" : "s16"), val);
511: }
512: else {
513: error ("wtf in c_writeea ()");
514: }
515: break;
516: default:
517: error ("nasty error in c_writeea()");
518: }
519: }
520:
521: static void c_eval_cond (int cond)
522: {
523: switch (cond) {
524: /* ra */
525: case 0: cout ("1"); break;
526: /* f */
527: case 1: cout ("0"); break;
528: /* hi */
529: case 2: cout ("((!C) && nZ)"); break;
530: /* ls */
531: case 3: cout ("(C || (!nZ))"); break;
532: /* cc */
533: case 4: cout ("(!C)"); break;
534: /* cs */
535: case 5: cout ("C"); break;
536: /* ne */
537: case 6: cout ("nZ"); break;
538: /* eq */
539: case 7: cout ("(!nZ)"); break;
540: /* vc */
541: case 8: cout ("(!V)"); break;
542: /* vs */
543: case 9: cout ("V"); break;
544: /* pl */
545: case 10: cout ("(!N)"); break;
546: /* mi */
547: case 11: cout ("N"); break;
548: /* ge */
549: case 12: cout ("(!(N ^ V))"); break;
550: /* lt */
551: case 13: cout ("(!(N ^ (!V)))"); break;
552: /* gt */
553: case 14: cout ("(nZ && (!(N ^ V)))"); break;
554: /* le */
555: case 15: cout ("((!nZ) || (!(N ^ (!V))))"); break;
556: }
557: }
558:
559: static void make_funcname (char *buf, int len)
560: {
561: snprintf (buf, len, "__F%x", get_bitpos ());
562: }
563:
564: static void c_fnbegin ()
565: {
566: add_fixup (0, C_FUNC, pending_func_name);
567: SWAP_COUT;
568: num_funcs++;
569: cout ("void %s ()\n", pending_func_name);
570: cout ("{\n");
571: }
572:
573: static void c_fnend ()
574: {
575: cout ("}\n");
576: SWAP_COUT;
577: }
578:
579: #define c_fncall() \
580: {if (gen_mode == GEN_CALL) { \
581: make_funcname (pending_func_name, sizeof (pending_func_name)); \
582: cln ("%s ();", pending_func_name); \
583: return; \
584: }}
585:
586: /* Check for pending exceptions also */
587: void c_jump_e (ea_t *ea)
588: {
589: char buf[256];
590: if (gen_mode != GEN_CALL) return;
591: c_ea_get_address (ea, buf);
592: cln ("{");
593: cln ("if ((exceptions_pending) && (rdest == 0)) {");
594:
595: if (((ea->mode == 7) && (ea->reg == 1)) ||
596: ((ea->mode == 7) && (ea->reg == 2))) {
597: cln (" rdest = __D%s;", ea->imm.label);
598: } else {
599: cln (" rdest = %s;", buf);
600: }
601: c_postea (ea);
602: cln (" goto handle_exception;", buf);
603: cln ("} else {");
604:
605: if (((ea->mode == 7) && (ea->reg == 1)) ||
606: ((ea->mode == 7) && (ea->reg == 2))) {
607: cln (" goto __N%s;", ea->imm.label);
608: } else {
609: cln (" jdest = %s;", buf);
610: c_postea (ea);
611: cln (" goto jumptable;");
612: }
613: cln ("}}");
614: }
615:
616: void c_jump (ea_t *ea)
617: {
618: char buf[256];
619: if (gen_mode != GEN_CALL) return;
620: c_ea_get_address (ea, buf);
621:
622: cln ("{");
623: if (((ea->mode == 7) && (ea->reg == 1)) ||
624: ((ea->mode == 7) && (ea->reg == 2))) {
625: cln (" goto __N%s;", ea->imm.label);
626: } else {
627: cln (" jdest = %s;", buf);
628: c_postea (ea);
629: cln (" goto jumptable;");
630: }
631: cln ("}");
632: }
633:
634: void c_func_bchg (ea_t *src, ea_t *dest, int size)
635: {
636: int len;
637: const char *sz;
638: char buf[256];
639: c_fncall ();
640:
641: c_fnbegin ();
642: sz = c_usizes[size];
643: if (size == BYTE) len = 8;
644: else if (size == WORD) len = 16;
645: else len = 32;
646:
647: c_readea (src, buf);
648: cln ("%s src = %s;", sz, buf);
649: c_readea (dest, buf);
650: cln ("%s dest = %s;", sz, buf);
651: cln ("src &= %d;", len-1);
652: cln ("dest ^= (1 << src);");
653: ifZ { cln ("nZ = !(((%s)dest & (1 << src)) >> src);", sz); }
654: c_writeea (dest, size, "dest");
655: c_postea (src);
656: c_postea (dest);
657: c_fnend ();
658: }
659:
660: void c_func_bclr (ea_t *src, ea_t *dest, int size)
661: {
662: int len;
663: const char *sz;
664: char buf[256];
665:
666: c_fncall ();
667:
668: c_fnbegin ();
669: sz = c_usizes[size];
670: if (size == BYTE) len = 8;
671: else if (size == WORD) len = 16;
672: else len = 32;
673:
674: c_readea (src, buf);
675: cln ("%s src = %s;", sz, buf);
676: c_readea (dest, buf);
677: cln ("%s dest = %s;", sz, buf);
678: cln ("src &= %d;", len-1);
679: ifZ { cln ("nZ = !(1 ^ ((dest >> src) & 1));"); }
680: cln ("dest &= ~(1 << src);");
681: c_writeea (dest, size, "dest");
682: c_postea (src);
683: c_postea (dest);
684: c_fnend ();
685: }
686:
687: void c_func_bset (ea_t *src, ea_t *dest, int size)
688: {
689: int len;
690: const char *sz;
691: char buf[256];
692:
693: c_fncall ();
694:
695: c_fnbegin ();
696: sz = c_usizes[size];
697: if (size == BYTE) len = 8;
698: else if (size == WORD) len = 16;
699: else len = 32;
700:
701: c_readea (src, buf);
702: cln ("%s src = %s;", sz, buf);
703: c_readea (dest, buf);
704: cln ("%s dest = %s;", sz, buf);
705: cln ("src &= %d;", len-1);
706: ifZ { cln ("nZ = !(1 ^ ((dest >> src) & 1));"); }
707: cln ("dest |= (1 << src);");
708: c_writeea (dest, size, "dest");
709: c_postea (src);
710: c_postea (dest);
711: c_fnend ();
712: }
713:
714: void c_func_btst (ea_t *src, ea_t *dest, int size)
715: {
716: int len;
717: const char *sz;
718: char buf[256];
719:
720: c_fncall ();
721:
722: c_fnbegin ();
723: sz = c_usizes[size];
724: if (size == BYTE) len = 8;
725: else if (size == WORD) len = 16;
726: else len = 32;
727:
728: c_readea (src, buf);
729: cln ("%s src = %s;", sz, buf);
730: c_readea (dest, buf);
731: cln ("%s dest = %s;", sz, buf);
732: cln ("src &= %d;", len-1);
733: ifZ { cln ("nZ = !(1 ^ ((dest >> src) & 1));"); }
734: c_postea (src);
735: c_postea (dest);
736: c_fnend ();
737: }
738:
739: void c_func_muls (ea_t *src, ea_t *dest)
740: {
741: char buf[256];
742: c_fncall ();
743:
744: c_fnbegin ();
745: c_readea (src, buf);
746: cln ("s16 src = %s;", buf);
747: c_readea (dest, buf);
748: cln ("s32 dest = (s16)%s;", buf);
749: cln ("dest *= (s32)src;");
750: ifZ { cln ("nZ = dest;"); }
751: ifN { cln ("N = ((s32)dest) < 0;"); }
752: ifC { cln ("C = 0;"); }
753: ifV { cln ("V = 0;"); }
754: c_writeea (dest, LONG, "dest");
755: c_postea (dest);
756: c_postea (src);
757: c_fnend ();
758: }
759: void c_func_mulu (ea_t *src, ea_t *dest)
760: {
761: char buf[256];
762: c_fncall ();
763:
764: c_fnbegin ();
765: c_readea (src, buf);
766: cln ("u16 src = %s;", buf);
767: c_readea (dest, buf);
768: cln ("u32 dest = (u16)%s;", buf);
769: cln ("dest *= (u32)src;");
770: ifZ { cln ("nZ = dest;"); }
771: ifN { cln ("N = ((s32)dest) < 0;"); }
772: ifC { cln ("C = 0;"); }
773: ifV { cln ("V = 0;"); }
774: c_writeea (dest, LONG, "dest");
775: c_postea (dest);
776: c_postea (src);
777: c_fnend ();
778: }
779:
780: void c_func_logop (ea_t *src, ea_t *dest, int size, char op)
781: {
782: const char *sz;
783: char buf[256];
784: sz = c_ssizes[size];
785:
786: c_fncall ();
787:
788: c_fnbegin ();
789: c_readea (src, buf);
790: cln ("%s src = %s;", sz, buf);
791: c_readea (dest, buf);
792: cln ("%s dest = %s;", sz, buf);
793: cln ("dest %c= src;", op);
794: ifC { cln ("C = 0;"); }
795: ifV { cln ("V = 0;"); }
796: ifZ { cln ("nZ = dest;"); }
797: ifN { cln ("N = (dest < 0);"); }
798: c_writeea (dest, size, "dest");
799: c_postea (src);
800: c_postea (dest);
801: c_fnend ();
802: }
803:
804: void c_func_not (ea_t *ea, int size)
805: {
806: char buf[256];
807: c_fncall ();
808:
809: c_fnbegin ();
810: c_readea (ea, buf);
811: cln ("%s val = %s;", c_usizes[size], buf);
812: cln ("val = ~val;");
813: ifN { cln ("N = ((%s)val) < 0;", c_ssizes[size]); }
814: ifZ { cln ("nZ = val;"); }
815: ifV { cln ("V = 0;"); }
816: ifC { cln ("C = 0;"); }
817: c_writeea (ea, size, "val");
818: c_postea (ea);
819: c_fnend ();
820: }
821:
822: void c_func_negx (ea_t *ea, int size)
823: {
824: char buf[256];
825: c_fncall ();
826:
827: c_fnbegin ();
828: c_readea (ea, buf);
829: /* XXX is nZ flag correct here? */
830: cln ("%s src = %s;", c_ssizes[size], buf);
831: cln ("u32 dest = (0 - src) - (X ? 1 : 0);");
832: cln ("int flgs, flgn;");
833: cln ("flgs = ((%s)src) < 0;", c_ssizes[size]);
834: cln ("flgn = ((%s)dest) < 0;", c_ssizes[size]);
835: ifZ { cln ("nZ = !((!nZ) & (((%s)(dest)) == 0));", c_ssizes[size]); }
836: ifV { cln ("V = (flgs & flgn);"); }
837: cln ("X = flgs ^ ((flgs ^ flgn) & (flgn));");
838: ifC { cln ("C = X;"); }
839: ifN { cln ("N = ((%s)dest) < 0;", c_ssizes[size]); }
840: c_writeea (ea, size, "dest");
841: c_postea (ea);
842: c_fnend ();
843: }
844: void c_func_neg (ea_t *ea, int size)
845: {
846: char buf[256];
847: c_fncall ();
848:
849: c_fnbegin ();
850: c_readea (ea, buf);
851: cln ("%s src = %s;", c_ssizes[size], buf);
852: cln ("%s dest = ((%s)0) - ((%s)src);", c_usizes[size], c_ssizes[size], c_ssizes[size]);
853: cln ("int flgs, flgn;");
854: cln ("flgs = ((%s)src) < 0;", c_ssizes[size]);
855: cln ("flgn = ((%s)dest) < 0;", c_ssizes[size]);
856: ifZ { cln ("nZ = dest;"); }
857: ifV { cln ("V = (flgs & flgn);"); }
858: cln ("X = (dest != 0);");
859: ifC { cln ("C = X;"); }
860: ifN { cln ("N = (flgn != 0);"); }
861: c_writeea (ea, size, "dest");
862: c_postea (ea);
863: c_fnend ();
864: }
865:
866: void c_func_divu (ea_t *ea, int reg)
867: {
868: char buf[256];
869: c_fncall ();
870:
871: c_fnbegin ();
872: c_readea (ea, buf);
873: cln ("s16 src = %s;\n", buf);
874: cln ("s32 dest = Regs[%d]._s32;", reg);
875: cln ("if (src == 0) {");
876: ifV { cln (" V = 0;"); }
877: cln (" assert (src != 0);");
878: cln ("} else {");
879: cln (" u32 newv = (u32)dest / (u32)(u16)src;");
880: cln (" u32 rem = (u32)dest % (u32)(u16)src;");
881: cln (" if (newv > 0xffff) {");
882: ifV { cln (" V = 1;"); }
883: ifN { cln (" N = 1;"); }
884: ifC { cln (" C = 0;"); }
885: cln (" } else {");
886: ifC { cln (" C = 0;"); }
887: ifV { cln (" V = 0;"); }
888: ifZ { cln (" nZ = newv;"); }
889: ifN { cln (" N = (newv < 0);"); }
890: cln (" Regs[%d]._u32 = (newv & 0xffff) | ((u32)rem << 16);", reg);
891: cln ("}}");
892: c_postea (ea);
893: c_fnend ();
894: }
895:
896: void c_func_divs (ea_t *ea, int reg)
897: {
898: char buf[256];
899: c_fncall ();
900:
901: c_fnbegin ();
902: c_readea (ea, buf);
903: cln ("s16 src = %s;\n", buf);
904: cln ("s32 dest = Regs[%d]._s32;", reg);
905: cln ("if (src == 0) {");
906: ifV { cln (" V = 0;"); }
907: cln (" assert (src != 0);");
908: cln ("} else {");
909: cln (" s32 newv = (s32)dest / (s32)(s16)src;");
910: cln (" u16 rem = (s32)dest % (s32)(s16)src;");
911: cln (" if ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) {");
912: ifV { cln (" V = 1;"); }
913: ifN { cln (" N = 1;"); }
914: ifC { cln (" C = 0;"); }
915: cln (" } else {");
916: ifC { cln (" C = 0;"); }
917: ifV { cln (" V = 0;"); }
918: ifZ { cln (" nZ = newv;"); }
919: ifN { cln (" N = (newv < 0);"); }
920: cln (" Regs[%d]._u32 = (newv & 0xffff) | ((u32)rem << 16);", reg);
921: cln ("}}");
922: c_postea (ea);
923: c_fnend ();
924: }
925:
926: /* src is the shift */
927: void c_func_asl (ea_t *src, ea_t *dest, int size)
928: {
929: char buf[256];
930: unsigned int mask;
931: int shift, len;
932:
933: c_fncall ();
934:
935: c_fnbegin ();
936: if (size == BYTE) {
937: mask = 0xff;
938: len = 8;
939: } else if (size == WORD) {
940: mask = 0xffff;
941: len = 16;
942: } else {
943: mask = 0xffffffff;
944: len = 32;
945: }
946:
947: c_readea (dest, buf);
948: cln ("u32 val = %s;\n", buf);
949:
950: if (is_immediate (src)) {
951: /* mostly for the sake of -O0 compiles... */
952: shift = src->imm.val;
953:
954: if (shift >= len) {
955: ifV cln ("V = (val != 0);");
956: cln ("X = %s;", (shift == len ? "val & 1" : "0"));
957: ifC cln ("C = X;");
958: cln ("val = 0;");
959: } else {
960: ifV cln ("u32 mask = (0x%x << (%d - %d)) & 0x%x;", mask, len-1, shift, mask);
961: ifV cln ("V = (val & mask) != mask && (val & mask) != 0;");
962: cln ("val <<= %d;", shift-1);
963: cln ("X = (val & 0x%x);", 1<<(len-1));
964: ifC cln ("C = (val & 0x%x);", 1<<(len-1));
965: cln ("val <<= 1;");
966: }
967: } else {
968: c_readea (src, buf);
969: cln ("s32 src = %s & 63;", buf);
970: cln ("if (src >= %d) {", len);
971: ifV cln (" V = (val != 0);");
972: cln (" X = (src == %d ? val & 1 : 0);", len);
973: ifC cln ("C = X;");
974: cln (" val = 0;");
975: cln ("} else if (src == 0) {");
976: ifC cln (" C = 0;");
977: ifV cln (" V = 0;");
978: cln ("} else {");
979: ifV cln (" u32 mask = (0x%x << (%d - src)) & 0x%x;", mask, len-1, mask);
980: ifV cln (" V = (val & mask) != mask && (val & mask) != 0;");
981: cln (" val <<= src-1;");
982: cln (" X = (val & 0x%x);", 1<<(len-1));
983: ifC cln (" C = (val & 0x%x);", 1<<(len-1));
984: cln (" val <<= 1;");
985: //cln (" val &= 0x%x;", mask);
986: cln ("}");
987: }
988: ifZ cln ("nZ = ((%s)(val)) != 0;", c_ssizes[size]);
989: ifN cln ("N = ((%s)(val)) < 0;", c_ssizes[size]);
990:
991: c_writeea (dest, size, "val");
992: c_postea (dest);
993: c_postea (src);
994: c_fnend ();
995: }
996:
997: void c_func_lsl (ea_t *src, ea_t *dest, int size)
998: {
999: char buf[256];
1000: unsigned int mask;
1001: int shift, len;
1002:
1003: c_fncall ();
1004:
1005: c_fnbegin ();
1006: if (size == BYTE) {
1007: mask = 0xff;
1008: len = 8;
1009: } else if (size == WORD) {
1010: mask = 0xffff;
1011: len = 16;
1012: } else {
1013: mask = 0xffffffff;
1014: len = 32;
1015: }
1016:
1017: c_readea (dest, buf);
1018: cln ("u32 val = (%s)%s;\n", c_usizes[size], buf);
1019:
1020: if (is_immediate (src)) {
1021: shift = src->imm.val;
1022:
1023: if (shift >= len) {
1024: cln ("X = %s;", (shift == len ? "val & 1" : "0"));
1025: ifC cln ("C = X;");
1026: cln ("val = 0;");
1027: } else {
1028: cln ("val <<= %d;", shift-1);
1029: cln ("X = (val & 0x%x);", 1<<(len-1));
1030: ifC cln ("C = X;");
1031: cln ("val <<= 1;");
1032: cln ("val &= 0x%x;", mask);
1033: }
1034: } else {
1035: c_readea (src, buf);
1036: cln ("s32 shift = %s & 63;", buf);
1037: cln ("if (shift >= %d) {", len);
1038: cln (" X = (shift == %d ? val & 1 : 0);", len);
1039: ifC cln (" C = X;");
1040: cln (" val = 0;");
1041: cln ("} else if (shift == 0) {");
1042: ifC cln (" C = 0;");
1043: cln ("} else {");
1044: cln (" val <<= shift-1;");
1045: cln (" X = (val & 0x%x);", 1<<(len-1));
1046: ifC cln (" C = X;");
1047: cln (" val <<= 1;");
1048: cln (" val &= 0x%x;", mask);
1049: cln ("}");
1050: }
1051:
1052: ifZ cln ("nZ = ((%s)(val)) != 0;", c_ssizes[size]);
1053: ifN cln ("N = ((%s)(val)) < 0;", c_ssizes[size]);
1054: ifV cln ("V = 0;");
1055:
1056: c_writeea (dest, size, "val");
1057: c_postea (dest);
1058: c_postea (src);
1059: c_fnend ();
1060: }
1061:
1062: void c_func_roxr (ea_t *src, ea_t *dest, int size)
1063: {
1064: char buf[256];
1065: unsigned int mask;
1066: int len;
1067:
1068: c_fncall ();
1069:
1070: c_fnbegin ();
1071: if (size == BYTE) {
1072: mask = 0xff;
1073: len = 8;
1074: } else if (size == WORD) {
1075: mask = 0xffff;
1076: len = 16;
1077: } else {
1078: mask = 0xffffffff;
1079: len = 32;
1080: }
1081:
1082: c_readea (dest, buf);
1083: cln ("u32 carry;");
1084: cln ("u32 val = (%s)%s;\n", c_usizes[size], buf);
1085:
1086: c_readea (src, buf);
1087: cln ("s32 cnt = (%s & 63) - 1;", buf);
1088:
1089: cln ("u32 hival = (val << 1) | (X ? 1 : 0);");
1090: cln ("hival <<= (%d - cnt);", len-1);
1091: cln ("val >>= cnt;");
1092: cln ("carry = val & 1;");
1093: cln ("val >>= 1;");
1094: cln ("val |= hival;");
1095: cln ("X = carry;");
1096: cln ("val &= 0x%x;", mask);
1097: ifC cln ("C = X;");
1098: ifZ cln ("nZ = val;");
1099: ifN cln ("N = ((%s)val) < 0;", c_ssizes[size]);
1100: ifV cln ("V = 0;");
1101:
1102: c_writeea (dest, size, "val");
1103: c_postea (dest);
1104: c_postea (src);
1105: c_fnend ();
1106: }
1107: void c_func_roxl (ea_t *src, ea_t *dest, int size)
1108: {
1109: char buf[256];
1110: unsigned int mask;
1111: int len;
1112:
1113: c_fncall ();
1114:
1115: c_fnbegin ();
1116: if (size == BYTE) {
1117: mask = 0xff;
1118: len = 8;
1119: } else if (size == WORD) {
1120: mask = 0xffff;
1121: len = 16;
1122: } else {
1123: mask = 0xffffffff;
1124: len = 32;
1125: }
1126:
1127: c_readea (dest, buf);
1128: cln ("u32 val = (%s)%s;\n", c_usizes[size], buf);
1129:
1130: c_readea (src, buf);
1131: cln ("s32 cnt = (%s & 63) - 1;", buf);
1132:
1133: cln ("u32 loval = val >> (%d - cnt);", len-1);
1134: cln ("u32 carry = loval & 1;");
1135: cln ("val = (((val << 1) | (X ? 1 : 0)) << cnt) | (loval >> 1);");
1136: cln ("X = carry;");
1137: cln ("val &= 0x%x;", mask);
1138: ifC cln ("C = X;");
1139: ifZ cln ("nZ = val;");
1140: ifN cln ("N = ((%s)val) < 0;", c_ssizes[size]);
1141: ifV cln ("V = 0;");
1142:
1143: c_writeea (dest, size, "val");
1144: c_postea (dest);
1145: c_postea (src);
1146: c_fnend ();
1147: }
1148: void c_func_rol (ea_t *src, ea_t *dest, int size)
1149: {
1150: char buf[256];
1151: unsigned int mask;
1152: int len;
1153:
1154: c_fncall ();
1155:
1156: c_fnbegin ();
1157: if (size == BYTE) {
1158: mask = 0xff;
1159: len = 8;
1160: } else if (size == WORD) {
1161: mask = 0xffff;
1162: len = 16;
1163: } else {
1164: mask = 0xffffffff;
1165: len = 32;
1166: }
1167:
1168: c_readea (dest, buf);
1169: cln ("u32 val = (%s)%s;\n", c_usizes[size], buf);
1170:
1171: c_readea (src, buf);
1172: cln ("s32 cnt = %s & 63;", buf);
1173:
1174: cln ("u32 loval;");
1175: cln ("cnt &= %d;", len-1);
1176: cln ("loval = val >> (%d - cnt);", len);
1177: cln ("val <<= cnt;");
1178: cln ("val |= loval;");
1179: cln ("val &= 0x%x;", mask);
1180: ifC cln ("C = val & 1;");
1181: ifZ cln ("nZ = val;");
1182: ifN cln ("N = ((%s)val) < 0;", c_ssizes[size]);
1183: ifV cln ("V = 0;");
1184:
1185: c_writeea (dest, size, "val");
1186: c_postea (dest);
1187: c_postea (src);
1188: c_fnend ();
1189: }
1190:
1191: void c_func_ror (ea_t *src, ea_t *dest, int size)
1192: {
1193: char buf[256];
1194: unsigned int mask;
1195: int len;
1196:
1197: c_fncall ();
1198:
1199: c_fnbegin ();
1200: if (size == BYTE) {
1201: mask = 0xff;
1202: len = 8;
1203: } else if (size == WORD) {
1204: mask = 0xffff;
1205: len = 16;
1206: } else {
1207: mask = 0xffffffff;
1208: len = 32;
1209: }
1210:
1211: c_readea (dest, buf);
1212: cln ("u32 val = (%s)%s;\n", c_usizes[size], buf);
1213:
1214: c_readea (src, buf);
1215: cln ("s32 cnt = %s & 63;", buf);
1216:
1217: cln ("u32 hival;");
1218: cln ("cnt &= %d;", len-1);
1219: cln ("hival = val << (%d - cnt);", len);
1220: cln ("val >>= cnt;");
1221: cln ("val |= hival;");
1222: cln ("val &= 0x%x;", mask);
1223: ifC cln ("C = (val & 0x%x) >> %d;", 1<<(len-1), len-1);
1224: ifZ cln ("nZ = val;");
1225: ifN cln ("N = ((%s)val) < 0;", c_ssizes[size]);
1226: ifV cln ("V = 0;");
1227:
1228: c_writeea (dest, size, "val");
1229: c_postea (dest);
1230: c_postea (src);
1231: c_fnend ();
1232: }
1233:
1234: void c_func_asr (ea_t *src, ea_t *dest, int size)
1235: {
1236: char buf[256];
1237: unsigned int mask;
1238: int shift, len;
1239:
1240: c_fncall ();
1241:
1242: c_fnbegin ();
1243: if (size == BYTE) {
1244: mask = 0xff;
1245: len = 8;
1246: } else if (size == WORD) {
1247: mask = 0xffff;
1248: len = 16;
1249: } else {
1250: mask = 0xffffffff;
1251: len = 32;
1252: }
1253:
1254: c_readea (dest, buf);
1255: cln ("u32 val = (%s)%s;\n", c_usizes[size], buf);
1256: cln ("u32 sign = (0x%x & val) >> %d;", 1<<(len-1), len-1);
1257:
1258: if (is_immediate (src)) {
1259: shift = src->imm.val;
1260:
1261: if (shift >= len) {
1262: cln ("val = 0x%x & (u32)-sign;", mask);
1263: cln ("X = sign;");
1264: ifC cln ("C = X;");
1265: } else {
1266: cln ("val >>= %d;", shift-1);
1267: cln ("X = val & 1;");
1268: ifC cln ("C = X;");
1269: cln ("val >>= 1;");
1270: cln ("val |= (0x%x << %d) & (u32)-sign;", mask, len - shift);
1271: }
1272: } else {
1273: c_readea (src, buf);
1274: cln ("s32 src = %s & 63;", buf);
1275:
1276: cln ("if (src >= %d) {", len);
1277: cln (" val = 0x%x & (u32)-sign;", mask);
1278: cln (" X = sign;");
1279: ifC cln (" C = X;");
1280: cln ("} else if (src == 0) {");
1281: ifC cln (" C = 0;");
1282: cln ("} else {");
1283: cln (" val >>= src - 1;");
1284: cln (" X = val & 1;");
1285: ifC cln (" C = X;");
1286: cln (" val >>= 1;");
1287: cln (" val |= (0x%x << (%d - src)) & (u32)-sign;", mask, len);
1288: //cln (" val &= 0x%x;", mask);
1289: cln ("}");
1290: }
1291: ifZ cln ("nZ = ((%s)(val)) != 0;", c_ssizes[size]);
1292: ifN cln ("N = ((%s)(val)) < 0;", c_ssizes[size]);
1293: ifV cln ("V = 0;");
1294:
1295: c_writeea (dest, size, "val");
1296: c_postea (dest);
1297: c_postea (src);
1298: c_fnend ();
1299: }
1300: void c_func_lsr (ea_t *src, ea_t *dest, int size)
1301: {
1302: char buf[256];
1303: unsigned int mask;
1304: int shift, len;
1305:
1306: c_fncall ();
1307:
1308: c_fnbegin ();
1309: if (size == BYTE) {
1310: mask = 0xff;
1311: len = 8;
1312: } else if (size == WORD) {
1313: mask = 0xffff;
1314: len = 16;
1315: } else {
1316: mask = 0xffffffff;
1317: len = 32;
1318: }
1319:
1320: c_readea (dest, buf);
1321: cln ("u32 val = (%s)%s;\n", c_usizes[size], buf);
1322:
1323: if (is_immediate (src)) {
1324: shift = src->imm.val;
1325:
1326: if (shift >= len) {
1327: cln ("val = 0;");
1328: cln ("X = %d && (val >> %d);", (shift == len), len-1);
1329: ifC cln ("C = X;");
1330: } else {
1331: cln ("val >>= %d;", shift-1);
1332: cln ("X = val & 1;");
1333: ifC cln ("C = X;");
1334: cln ("val >>= 1;");
1335: }
1336: } else {
1337: c_readea (src, buf);
1338: cln ("u32 shift = %s & 63;", buf);
1339:
1340: cln ("if (shift >= %d) {", len);
1341: cln (" val = 0;");
1342: cln (" X = (shift == %d) && (val >> %d);", len, len-1);
1343: ifC cln (" C = X;");
1344: cln ("} else if (shift == 0) {");
1345: ifC cln (" C = 0;");
1346: cln ("} else {");
1347: cln (" val >>= shift - 1;");
1348: cln (" X = val & 1;");
1349: ifC cln (" C = X;");
1350: cln (" val >>= 1;");
1351: cln ("}");
1352: }
1353:
1354: ifZ cln ("nZ = ((%s)(val)) != 0;", c_ssizes[size]);
1355: ifN cln ("N = ((%s)(val)) < 0;", c_ssizes[size]);
1356: ifV cln ("V = 0;");
1357:
1358: c_writeea (dest, size, "val");
1359: c_postea (dest);
1360: c_postea (src);
1361: c_fnend ();
1362: }
1363:
1364: void c_func_movem (ea_t *ea, int sz, int dr, int reg_mask)
1365: {
1366: int i, offset;
1367: char buf[256];
1368: const char *read_func;
1369: const char *write_func;
1370:
1371: c_fncall ();
1372:
1373: c_fnbegin ();
1374:
1375: sz++;
1376: read_func = mem_read_funcs[sz];
1377: write_func = mem_write_funcs[sz];
1378:
1379: c_ea_get_address (ea, buf);
1380:
1381: if (dr == 0) {
1382: /* reg to memory */
1383: cln ("s32 dest = %s;", buf);
1384:
1385: if (ea->mode == 4) {
1386: /* pre-decrement mode */
1387: offset = 0;
1388: for (i=0; i<16; i++) {
1389: if (reg_mask & (1<<i)) {
1390: cln ("%s (dest, Regs[%d]._%s);", write_func, 15-i, c_usizes[sz]);
1391: cln ("dest -= %d;", 1<<sz);
1392: offset += 1<<sz;
1393: }
1394: }
1395: cln ("Regs[%d]._s32 -= %d;", ea->reg, offset);
1396: } else {
1397: for (i=0; i<16; i++) {
1398: if (reg_mask & (1<<i)) {
1399: cln ("%s (dest, Regs[%d]._%s);", write_func, i, c_usizes[sz]);
1400: cln ("dest += %d;", 1<<sz);
1401: }
1402: }
1403: }
1404: } else {
1405: /* mem to reg */
1406: cln ("s32 src = %s;", buf);
1407:
1408: offset = 0;
1409: for (i=0; i<16; i++) {
1410: if (reg_mask & (1<<i)) {
1411: cln ("Regs[%d]._s32 = %s (src);", i, read_func);
1412: cln ("src += %d;", 1<<sz);
1413: offset += 1<<sz;
1414: }
1415: }
1416: /* post-inc mode */
1417: if (ea->mode == 3)
1418: cln ("Regs[%d]._s32 += %d;", ea->reg, offset);
1419: }
1420: c_fnend ();
1421: }
1422:
1423: void c_func_subx (ea_t *src, ea_t *dest, int size)
1424: {
1425: char buf[256];
1426: const char *sz = c_ssizes[size];
1427: c_fncall ();
1428:
1429: c_fnbegin ();
1430: /* XXX nZ correct? */
1431: c_readea (dest, buf);
1432: cln ("int flgs, flgo, flgn;");
1433: cln ("%s dest = %s;", sz, buf);
1434:
1435: c_readea (src, buf);
1436: cln ("%s src = %s;", sz, buf);
1437:
1438: cln ("s32 newv = dest - src - (X ? 1 : 0);");
1439:
1440: cln ("flgs = src < 0;", sz);
1441: cln ("flgo = dest < 0;", sz);
1442: cln ("flgn = ((%s)newv) < 0;", sz);
1443: ifV cln ("V = (flgs ^ flgo) & (flgo ^ flgn);");
1444: cln ("X = (flgs ^ ((flgs ^ flgn) & (flgo ^ flgn)));");
1445: ifC cln ("C = X;");
1446: ifZ cln ("nZ = !((!nZ) & (((%s)(newv)) == 0));", sz);
1447: ifN cln ("N = ((%s)newv) < 0;", sz);
1448: c_writeea (dest, size, "newv");
1449: c_postea (dest);
1450: c_postea (src);
1451: c_fnend ();
1452: }
1453:
1454: void c_func_addx (ea_t *src, ea_t *dest, int size)
1455: {
1456: char buf[256];
1457: const char *sz = c_ssizes[size];
1458: c_fncall ();
1459:
1460: c_fnbegin ();
1461: /* XXX nZ correct? */
1462: c_readea (dest, buf);
1463: cln ("int flgs, flgo, flgn;");
1464: cln ("%s dest = %s;", sz, buf);
1465:
1466: c_readea (src, buf);
1467: cln ("%s src = %s;", sz, buf);
1468:
1469: cln ("s32 newv = dest + src + (X ? 1 : 0);");
1470:
1471: cln ("flgs = src < 0;", sz);
1472: cln ("flgo = dest < 0;", sz);
1473: cln ("flgn = ((%s)newv) < 0;", sz);
1474: ifV cln ("V = (flgs ^ flgn) & (flgo ^ flgn);");
1475: cln ("X = (flgs ^ ((flgs ^ flgo) & (flgo ^ flgn)));");
1476: ifC cln ("C = X;");
1477: ifZ cln ("nZ = !((!nZ) & (((%s)(newv)) == 0));", sz);
1478: ifN cln ("N = ((%s)newv) < 0;", sz);
1479: c_writeea (dest, size, "newv");
1480: c_postea (dest);
1481: c_postea (src);
1482: c_fnend ();
1483: }
1484:
1485: void c_func_add (ea_t *src, ea_t *dest, int size)
1486: {
1487: char buf[256];
1488: const char *sz = c_ssizes[size];
1489: const char *usz = c_usizes[size];
1490:
1491: c_fncall ();
1492:
1493: c_fnbegin ();
1494: c_readea (dest, buf);
1495: cln ("s32 dest = %s;\n", buf);
1496:
1497: c_readea (src, buf);
1498: cln ("s32 src = %s;\n", buf);
1499:
1500: cln ("s32 val = (%s)dest + (%s)src;", sz, sz);
1501:
1502: ifV cln ("s32 flgs = ((%s)src) < 0;", sz);
1503: ifV cln ("s32 flgo = ((%s)dest) < 0;", sz);
1504: ifVoN cln ("s32 flgn = ((%s)val) < 0;", sz);
1505: ifZ cln ("nZ = val;");
1506: ifV cln ("V = (flgs ^ flgn) & (flgo ^ flgn);");
1507: cln ("X = ((%s)(~src)) < ((%s)dest);", usz, usz);
1508: ifC cln ("C = X;");
1509: ifN cln ("N = (flgn != 0);");
1510: c_writeea (dest, size, "val");
1511: c_postea (dest);
1512: c_postea (src);
1513: c_fnend ();
1514: }
1515:
1516: void c_func_cmpa (ea_t *src, ea_t *dest, int size)
1517: {
1518: char buf[256];
1519: const char *sz = c_ssizes[size];
1520: c_fncall ();
1521:
1522: c_fnbegin ();
1523:
1524: cln ("s32 dest = Regs[%d]._s32;\n", dest->reg);
1525:
1526: c_readea (src, buf);
1527: cln ("%s src = %s;\n", sz, buf);
1528:
1529: cln ("s32 val = (s32)dest - (s32)src;");
1530: ifV cln ("s32 flgs = ((s32)src) < 0;");
1531: ifV cln ("s32 flgo = ((s32)dest) < 0;");
1532: ifVoN cln ("s32 flgn = ((s32)val) < 0;");
1533: ifZ cln ("nZ = val;");
1534: ifV cln ("V = ((flgs != flgo) && (flgn != flgo));");
1535: ifC cln ("C = ((u32)src) > ((u32)dest);");
1536: ifN cln ("N = (flgn != 0);");
1537: c_postea (dest);
1538: c_postea (src);
1539: c_fnend ();
1540: }
1541:
1542: void c_func_cmp (ea_t *src, ea_t *dest, int size)
1543: {
1544: char buf[256];
1545: const char *sz = c_ssizes[size];
1546: const char *usz = c_usizes[size];
1547: c_fncall ();
1548:
1549: c_fnbegin ();
1550:
1551: c_readea (dest, buf);
1552: cln ("s32 dest = %s;\n", buf);
1553:
1554: c_readea (src, buf);
1555: cln ("s32 src = %s;\n", buf);
1556:
1557: cln ("s32 val = (%s)dest - (%s)src;", sz, sz);
1558:
1559: ifV cln ("s32 flgs = ((%s)src) < 0;", sz);
1560: ifV cln ("s32 flgo = ((%s)dest) < 0;", sz);
1561: ifVoN cln ("s32 flgn = ((%s)val) < 0;", sz);
1562: ifV cln ("V = ((flgs != flgo) && (flgn != flgo));");
1563: ifC cln ("C = ((%s)src) > ((%s)dest);", usz, usz);
1564: ifN cln ("N = (flgn != 0);");
1565: ifZ cln ("nZ = val;");
1566: c_postea (dest);
1567: c_postea (src);
1568: c_fnend ();
1569: }
1570:
1571: void c_func_sub (ea_t *src, ea_t *dest, int size)
1572: {
1573: char buf[256];
1574: const char *sz = c_ssizes[size];
1575: const char *usz = c_usizes[size];
1576:
1577: c_fncall ();
1578:
1579: c_fnbegin ();
1580: c_readea (dest, buf);
1581: cln ("s32 dest = %s;\n", buf);
1582:
1583: c_readea (src, buf);
1584: cln ("s32 src = %s;\n", buf);
1585:
1586: cln ("u32 newv = (%s)dest - (%s)src;", sz, sz);
1587:
1588: ifV cln ("s32 flgs = ((%s)src) < 0;", sz);
1589: ifV cln ("s32 flgo = ((%s)dest) < 0;", sz);
1590: ifVoN cln ("s32 flgn = ((%s)newv) < 0;", sz);
1591: ifZ cln ("nZ = newv;");
1592: ifV cln ("V = (flgs ^ flgo) & (flgn ^ flgo);");
1593: cln ("X = ((%s)src) > ((%s)dest);", usz, usz);
1594: ifC cln ("C = X;");
1595: ifN cln ("N = (flgn != 0);");
1596: c_writeea (dest, size, "newv");
1597: c_postea (dest);
1598: c_postea (src);
1599: c_fnend ();
1600: }
1601:
1602: void c_func_adda (ea_t *src, int dest_reg, int size)
1603: {
1604: char buf[256];
1605: if (gen_mode != GEN_CALL) return;
1606: c_readea (src, buf);
1607: cln ("Regs[%d]._u32 = Regs[%d]._s32 + (%s)%s;", dest_reg, dest_reg, c_ssizes[size], buf);
1608: c_postea (src);
1609: }
1610:
1611: void c_func_suba (ea_t *src, int dest_reg, int size)
1612: {
1613: char buf[256];
1614: if (gen_mode != GEN_CALL) return;
1615: c_readea (src, buf);
1616: cln ("Regs[%d]._u32 = Regs[%d]._s32 - (%s)%s;", dest_reg, dest_reg, c_ssizes[size], buf);
1617: c_postea (src);
1618: }
1619:
1620: void c_func_swap (int reg)
1621: {
1622: c_fncall ();
1623:
1624: c_fnbegin ();
1625: cln ("s32 temp = Regs[%d].word[0];", reg);
1626: cln ("Regs[%d].word[0] = Regs[%d].word[1];", reg, reg);
1627: cln ("Regs[%d].word[1] = temp;", reg);
1628: ifZ cln ("nZ = Regs[%d]._s32;", reg);
1629: ifN cln ("N = (Regs[%d]._s32 < 0);", reg);
1630: ifV cln ("V = 0;");
1631: ifC cln ("C = 0;");
1632: c_fnend ();
1633: }
1634:
1635: void c_func_jsr (ea_t *dest)
1636: {
1637: char buf[256];
1638: if (gen_mode != GEN_CALL) return;
1639: snprintf (buf, sizeof (buf), "%x", get_bitpos ());
1640: add_label (buf, C_ADDR, get_bitpos () - BASE);
1641: add_fixup (0, C_ADDR, buf);
1642:
1643: snprintf (buf, sizeof (buf), "__D%x", get_bitpos ());
1644: cln ("Regs[15]._s32 -= 4;");
1645: cln ("wrlong (Regs[15]._s32, %s);", buf);
1646:
1647: c_jump (dest);
1648: }
1649:
1650: void c_func_bcc (ea_t *dest, int cond)
1651: {
1652: if (gen_mode != GEN_CALL) return;
1653: if (cond == 0) {
1654: c_jump (dest);
1655: } else {
1656: cout ("\tif (");
1657: c_eval_cond (cond);
1658: cout (")\n");
1659: c_jump_e (dest);
1660: }
1661: }
1662:
1663: /* XXX note: this does not call c_jump and therefore does not
1664: * check for pending exceptions. an infinite DBcc loop will not
1665: * allow exceptions to occur.
1666: * does it matter? */
1667: void c_func_dbcc (const char *label, int cond, int reg)
1668: {
1669: if (gen_mode != GEN_CALL) return;
1670: if (cond == 0) {
1671: cln ("if (--Regs[%d]._s16 != -1) goto __N%s;\n", reg, label);
1672: } else {
1673: cout ("\tif ((!");
1674: c_eval_cond (cond);
1675: cout (") && (--Regs[%d]._s16 != -1)) goto __N%s;\n", reg, label);
1676: }
1677: }
1678:
1679: void c_func_clr (ea_t *dest)
1680: {
1681: c_fncall ();
1682:
1683: c_fnbegin ();
1684: c_writeea (dest, dest->op_size, "0");
1685: c_postea (dest);
1686: ifN cln ("N = 0;");
1687: ifZ cln ("nZ = 0;");
1688: ifV cln ("V = 0;");
1689: ifC cln ("C = 0;");
1690: c_fnend ();
1691: }
1692:
1693: void c_func_exg (int reg1, int reg2)
1694: {
1695: c_fncall ();
1696:
1697: c_fnbegin ();
1698: cln ("u32 temp = Regs[%d]._u32;", reg1);
1699: cln ("Regs[%d]._u32 = Regs[%d]._u32;", reg1, reg2);
1700: cln ("Regs[%d]._u32 = temp;", reg2);
1701: c_fnend ();
1702: }
1703:
1704: void c_func_ext (int reg, int size)
1705: {
1706: c_fncall ();
1707:
1708: c_fnbegin ();
1709: cln ("%s val = Regs[%d]._%s;", c_ssizes[size], reg, c_ssizes[size-1]);
1710: cln ("Regs[%d]._%s = val;", reg, c_ssizes[size]);
1711: ifZ cln ("nZ = val;");
1712: ifN cln ("N = (val < 0);");
1713: ifV cln ("V = 0;");
1714: ifC cln ("C = 0;");
1715: c_fnend ();
1716: }
1717:
1718: void c_func_rte ()
1719: {
1720: if (gen_mode != GEN_CALL) return;
1721: cln ("N=bN; nZ=bnZ; V=bV; C=bC; X=bX;");
1722: cln ("jdest = rdest;");
1723: cln ("rdest = 0;");
1724: cln ("goto jumptable;");
1725: }
1726:
1727: void c_func_rts ()
1728: {
1729: if (gen_mode != GEN_CALL) return;
1730: cln ("jdest = rdlong (Regs[15]._u32);");
1731: cln ("Regs[15]._s32 += 4;");
1732: cln ("goto jumptable;");
1733: }
1734:
1735: void c_func_illegal ()
1736: {
1737: if (gen_mode != GEN_CALL) return;
1738: cln ("printf (\"Illegal instruction at line %d.\\n\");", line_no);
1739: cln ("abort ();");
1740: }
1741:
1742: void c_func_hcall (int val)
1743: {
1744: if (gen_mode != GEN_CALL) return;
1745: cln ("(* hcalls[%d]) ();", val);
1746: }
1747:
1748: void c_func_link (int reg, int val)
1749: {
1750: c_fncall ();
1751:
1752: c_fnbegin ();
1753: cln ("Regs[15]._u32 -= 4;");
1754: cln ("wrlong (Regs[15]._u32, Regs[%d]._u32);", reg);
1755: cln ("Regs[%d]._u32 = Regs[15]._u32;", reg);
1756: cln ("Regs[15]._u32 += 0x%x;", val);
1757: c_fnend ();
1758: }
1759:
1760: void c_func_unlk (int reg)
1761: {
1762: c_fncall ();
1763:
1764: c_fnbegin ();
1765: cln ("Regs[15]._u32 = Regs[%d]._u32;", reg);
1766: cln ("Regs[%d]._u32 = rdlong (Regs[15]._u32);", reg);
1767: cln ("Regs[15]._u32 += 4;");
1768: c_fnend ();
1769: }
1770:
1771: void c_func_move (ea_t *src, ea_t *dest, int size)
1772: {
1773: char buf[256];
1774: c_fncall ();
1775:
1776: c_fnbegin ();
1777: c_readea (src, buf);
1778: cln ("s32 val = %s;", buf);
1779: c_writeea (dest, size, "val");
1780: c_postea (src);
1781: c_postea (dest);
1782: ifZ cln ("nZ = val;");
1783: ifN cln ("N = val < 0;");
1784: ifV cln ("V = 0;");
1785: ifC cln ("C = 0;");
1786: c_fnend ();
1787: }
1788:
1789: void c_func_movea (ea_t *src, int reg_dest)
1790: {
1791: char buf[256];
1792: if (gen_mode != GEN_CALL) return;
1793: assert (reg_dest > 7);
1794: c_readea (src, buf);
1795: cln ("Regs[%d]._s32 = %s;", reg_dest, buf);
1796: c_postea (src);
1797: }
1798:
1799: void c_func_tst (ea_t *ea)
1800: {
1801: char buf[256];
1802: c_fncall ();
1803:
1804: c_fnbegin ();
1805: c_readea (ea, buf);
1806: cln ("nZ = %s;", buf);
1807: c_postea (ea);
1808: ifN cln ("N = nZ < 0;");
1809: ifV cln ("V = 0;");
1810: ifC cln ("C = 0;");
1811: c_fnend ();
1812: }
1813:
1814: void c_func_pea (ea_t *ea)
1815: {
1816: char buf[256];
1817: if (gen_mode != GEN_CALL) return;
1818: c_ea_get_address (ea, buf);
1819:
1820: cln ("Regs[15]._u32 -= 4;");
1821: cln ("wrlong (Regs[15]._u32, %s);", buf);
1822: }
1823:
1824: void c_func_lea (ea_t *ea, int reg)
1825: {
1826: char buf[256];
1827: if (gen_mode != GEN_CALL) return;
1828: c_ea_get_address (ea, buf);
1829:
1830: cln ("Regs[%d]._u32 = %s;", reg, buf);
1831: }
1832:
1833: void c_func_scc (ea_t *dest, int cond)
1834: {
1835: c_fncall ();
1836:
1837: c_fnbegin ();
1838: cout ("\tif (");
1839: c_eval_cond (cond);
1840: cout (") {\n");
1841: c_writeea (dest, BYTE, "0xff");
1842: cln ("} else {");
1843: c_writeea (dest, BYTE, "0");
1844: cln ("}");
1845: c_postea (dest);
1846: c_fnend ();
1847: }
1848:
1849: static void output_op (op_t *op, op_t *next)
1850: {
1851: switch (op->optype) {
1852: case OP_MULS: c_func_muls (&op->src, &op->dest); break;
1853: case OP_MULU: c_func_mulu (&op->src, &op->dest); break;
1854: case OP_ADDA: c_func_adda (&op->src, op->dest.reg, op->size); break;
1855: case OP_SUBA: c_func_suba (&op->src, op->dest.reg, op->size); break;
1856: case OP_ADD: c_func_add (&op->src, &op->dest, op->size); break;
1857: case OP_SUB: c_func_sub (&op->src, &op->dest, op->size); break;
1858: case OP_NOT: c_func_not (&op->src, op->size); break;
1859: case OP_NEGX: c_func_negx (&op->src, op->size); break;
1860: case OP_NEG: c_func_neg (&op->src, op->size); break;
1861: case OP_DIVS: c_func_divs (&op->src, op->dest.reg); break;
1862: case OP_DIVU: c_func_divu (&op->src, op->dest.reg); break;
1863: case OP_ADDX: c_func_addx (&op->src, &op->dest, op->size); break;
1864: case OP_SUBX: c_func_subx (&op->src, &op->dest, op->size); break;
1865: case OP_BCHG: c_func_bchg (&op->src, &op->dest, op->size); break;
1866: case OP_BCLR: c_func_bclr (&op->src, &op->dest, op->size); break;
1867: case OP_BSET: c_func_bset (&op->src, &op->dest, op->size); break;
1868: case OP_BTST: c_func_btst (&op->src, &op->dest, op->size); break;
1869: case OP_ASL: c_func_asl (&op->src, &op->dest, op->size); break;
1870: case OP_ASR: c_func_asr (&op->src, &op->dest, op->size); break;
1871: case OP_LSL: c_func_lsl (&op->src, &op->dest, op->size); break;
1872: case OP_LSR: c_func_lsr (&op->src, &op->dest, op->size); break;
1873: case OP_ROL: c_func_rol (&op->src, &op->dest, op->size); break;
1874: case OP_ROR: c_func_ror (&op->src, &op->dest, op->size); break;
1875: case OP_ROXL: c_func_roxl (&op->src, &op->dest, op->size); break;
1876: case OP_ROXR: c_func_roxr (&op->src, &op->dest, op->size); break;
1877: case OP_OR: c_func_logop (&op->src, &op->dest, op->size, '|'); break;
1878: case OP_AND: c_func_logop (&op->src, &op->dest, op->size, '&'); break;
1879: case OP_XOR: c_func_logop (&op->src, &op->dest, op->size, '^'); break;
1880: case OP_SWAP: c_func_swap (op->src.reg); break;
1881: case OP_JSR: c_func_jsr (&op->src); break;
1882: case OP_BCC: c_func_bcc (&op->src, op->opcode.Bcc.cond); break;
1883: case OP_DBCC: c_func_dbcc (op->dest.imm.label, op->opcode.Bcc.cond, op->src.reg); break;
1884: case OP_CLR: c_func_clr (&op->src); break;
1885: case OP_CMP: c_func_cmp (&op->src, &op->dest, op->size); break;
1886: case OP_CMPA: c_func_cmpa (&op->src, &op->dest, op->size); break;
1887: case OP_EXG: c_func_exg (op->src.reg, op->dest.reg); break;
1888: case OP_EXT: c_func_ext (op->src.reg, op->size); break;
1889: case OP_MOVEM: c_func_movem (&op->src, op->opcode.movem.sz, op->opcode.movem.dr, op->dest.reg); break;
1890: case OP_RTE: c_func_rte (); break;
1891: case OP_RTS: c_func_rts (); break;
1892: case OP_ILLEGAL: c_func_illegal (); break;
1893: case OP_HCALL: c_func_hcall (op->src.imm.val); break;
1894: case OP_LINK: c_func_link (op->src.reg, op->dest.imm.val); break;
1895: case OP_UNLK: c_func_unlk (op->src.reg); break;
1896: case OP_MOVE: c_func_move (&op->src, &op->dest, op->size); break;
1897: case OP_MOVEA: c_func_movea (&op->src, op->dest.reg); break;
1898: case OP_TST: c_func_tst (&op->src); break;
1899: case OP_PEA: c_func_pea (&op->src); break;
1900: case OP_LEA: c_func_lea (&op->src, op->dest.reg); break;
1901: case OP_JMP: c_jump (&op->src); break;
1902: case OP_SCC: c_func_scc (&op->src, op->opcode.DBcc.cond); break;
1903:
1904: default:
1905: printf ("type %d\n", op->optype);
1906: assert (0);
1907: }
1908: }
1909:
1910: void c_push_op (enum M68K_OPS type, ea_t *src, ea_t *dest, int size)
1911: {
1912: c_push_op2 (type, src, dest, size, 0);
1913: }
1914: void c_push_op2 (enum M68K_OPS type, ea_t *src, ea_t *dest, int size, int opcode)
1915: {
1916: next_op_type = type;
1917:
1918: if (pending.optype) {
1919: gen_mode = GEN_BODY;
1920: output_op (&pending, NULL);
1921: gen_mode = GEN_CALL;
1922: }
1923:
1924: pending.size = size;
1925: pending.opcode.code = opcode;
1926: pending.optype = type;
1927:
1928: if (type == OP_JSR)
1929: return_target = 1;
1930: else
1931: return_target = 0;
1932:
1933: if (src) {
1934: pending.src = *src;
1935: }
1936: if (dest) {
1937: pending.dest = *dest;
1938: }
1939: output_op (&pending, NULL);
1940: }
1941: void c_push_op_basic (enum M68K_OPS type)
1942: {
1943: c_push_op2 (type, NULL, NULL, 0, 0);
1944: }
1945:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.