|
|
1.1 root 1: /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */
2:
3: #include <stdio.h>
4:
5: #include "generator.h"
6:
7: #include "def68k-iibs.h"
8:
9: /* forward references */
10:
11: void generate(FILE *output, int topnibble);
12: void generate_ea(FILE *o, t_iib *iib, t_type type, int update);
13: void generate_eaval(FILE *o, t_iib *iib, t_type type);
14: void generate_eastore(FILE *o, t_iib *iib, t_type type);
15: void generate_outdata(FILE *o, t_iib *iib, const char *init);
16: void generate_cc(FILE *o, t_iib *iib);
17: void generate_stdflag_n(FILE *o, t_iib *iib);
18: void generate_stdflag_z(FILE *o, t_iib *iib);
19: void generate_clrflag_v(FILE *o, t_iib *iib);
20: void generate_clrflag_c(FILE *o, t_iib *iib);
21: void generate_clrflag_n(FILE *o, t_iib *iib);
22: void generate_setflag_z(FILE *o, t_iib *iib);
23: void generate_subflag_c(FILE *o, t_iib *iib);
24: void generate_subflag_cx(FILE *o, t_iib *iib);
25: void generate_subxflag_cx(FILE *o, t_iib *iib);
26: void generate_subflag_v(FILE *o, t_iib *iib);
27: void generate_cmpaflag_c(FILE *o, t_iib *iib);
28: void generate_cmpaflag_v(FILE *o, t_iib *iib);
29: void generate_addflag_cx(FILE *o, t_iib *iib);
30: void generate_addflag_v(FILE *o, t_iib *iib);
31: void generate_addxflag_cx(FILE *o, t_iib *iib);
32: void generate_stdxflag_z(FILE *o, t_iib *iib);
33: void generate_negflag_cx(FILE *o, t_iib *iib);
34: void generate_negflag_v(FILE *o, t_iib *iib);
35: void generate_negxflag_cx(FILE *o, t_iib *iib);
36: void generate_negxflag_v(FILE *o, t_iib *iib);
37: void generate_bits(FILE *o, t_iib *iib);
38:
39: /* defines */
40:
41: #define HEADER "/*****************************************************************************/\n/* Generator - Sega Genesis emulation - (c) James Ponder 1997-2001 */\n/*****************************************************************************/\n/* */\n/* cpu68k-%x.c */\n/* */\n/*****************************************************************************/\n\n"
42:
43: #define OUT(x) fputs(x,output);
44: #define FNAME_GEN68K_CPU_OUT "cpu68k-%x.c"
45:
46: /* program entry routine */
47:
48: int main(int argc, char *argv[])
49: {
50: FILE *output;
51: int i;
52: char tmp[256];
53:
54: printf("Writing C files... ");
55: fflush(stdout);
56:
57: for (i = 0; i < 16; i++) {
58:
59: printf("%d. ", i);
60: fflush(stdout);
61:
62: /* make filename */
63: sprintf(tmp, FNAME_GEN68K_CPU_OUT, i);
64:
65: /* open output file */
66: if ((output = fopen(tmp, "w")) == NULL) {
67: perror("fopen output");
68: exit(1);
69: }
70:
71: /* output header */
72: fprintf(output, HEADER, i);
73: fprintf(output, "#include \"generator.h\"\n");
74: fprintf(output, "#include \"cpu68k.h\"\n");
75: fprintf(output, "#include \"mem68k.h\"\n");
76: fprintf(output, "#include \"reg68k.h\"\n\n");
77: fprintf(output, "#include \"cpu68k-inline.h\"\n\n");
78: fprintf(output, "#include <stdio.h>\n\n");
79:
80: generate(output, i);
81:
82: /* close output */
83: if (fclose(output)) {
84: perror("fclose output");
85: exit(1);
86: }
87:
88: }
89:
90: printf("done.\n");
91: fflush(stdout);
92:
93: /* normal program termination */
94: return(0);
95: }
96:
97: void generate(FILE *output, int topnibble)
98: {
99: t_iib *iib;
100: int i, flags, pcinc;
101: int DEBUG_BRANCH = 0;
102: int DEBUG_SR = 0;
103: int DEBUG_RTE = 0;
104:
105: for (i = 0; i < iibs_num; i++) {
106: iib = &iibs[i];
107:
108: if ((iib->mask & 0xF000) != 0xF000) {
109: fprintf(stderr, "error: Strange mask %x\n", iib->mask);
110: exit(1);
111: }
112: if (((iib->bits & 0xF000)>>12) != topnibble) {
113: continue;
114: }
115:
116: for (flags = 0; flags < 2; flags++) {
117:
118: if (flags == 1 && iib->flags.set == 0) {
119: /* there is no non-flags version, functable will already go
120: straight to the normal version anyway, so lets just skip it */
121: continue;
122: }
123:
124: fprintf(output, "void cpu_op_%i%s(t_ipc *ipc) /* %s */ {\n",
125: i, flags ? "b" : "a", mnemonic_table[iib->mnemonic].name);
126: fprintf(output, " /* mask %0.4x, bits %0.4x, mnemonic %d, priv %d, ",
127: iib->mask, iib->bits, iib->mnemonic, iib->flags.priv);
128: fprintf(output, "endblk %d, imm_notzero %d, used %d",
129: iib->flags.endblk, iib->flags.imm_notzero, iib->flags.used);
130: fprintf(output, " set %d, size %d, stype %d, dtype %d, sbitpos %d, ",
131: iib->flags.set, iib->size, iib->stype, iib->dtype, iib->sbitpos);
132: fprintf(output, "dbitpos %d, immvalue %d */\n", iib->dbitpos,
133: iib->immvalue);
134:
135: pcinc = 1;
136:
137: switch(iib->mnemonic) {
138:
139: case i_OR:
140: case i_AND:
141: case i_EOR:
142: generate_ea(output, iib, tp_src, 1);
143: generate_eaval(output, iib, tp_src);
144: generate_ea(output, iib, tp_dst, 1);
145: generate_eaval(output, iib, tp_dst);
146: generate_outdata(output, iib, "dstdata");
147: OUT("\n");
148: switch(iib->mnemonic) {
149: case i_OR:
150: OUT(" outdata|= srcdata;\n");
151: break;
152: case i_AND:
153: OUT(" outdata&= srcdata;\n");
154: break;
155: case i_EOR:
156: OUT(" outdata^= srcdata;\n");
157: break;
158: default:
159: OUT("ERROR\n");
160: break;
161: }
162: generate_eastore(output, iib, tp_dst);
163: if (flags)
164: OUT("\n");
165: if (flags && iib->flags.set & IIB_FLAG_N)
166: generate_stdflag_n(output, iib);
167: if (flags && iib->flags.set & IIB_FLAG_Z)
168: generate_stdflag_z(output, iib);
169: if (flags && iib->flags.set & IIB_FLAG_V)
170: generate_clrflag_v(output, iib);
171: if (flags && iib->flags.set & IIB_FLAG_C)
172: generate_clrflag_c(output, iib);
173: break;
174:
175: case i_ORSR:
176: case i_ANDSR:
177: case i_EORSR:
178: generate_ea(output, iib, tp_src, 1);
179: generate_eaval(output, iib, tp_src);
180: OUT(" unsigned int sr = reg68k_sr.sr_struct.s;\n");
181: OUT("\n");
182: if (DEBUG_SR)
183: fputs(" printf(\"SR: %08X %04X\\n\", PC, reg68k_sr.sr_int);\n",
184: output);
185: if (iib->size == sz_word) {
186: OUT(" if (!SFLAG)\n");
187: fprintf(output, " reg68k_internal_vector(V_PRIVILEGE, PC+%d);\n",
188: (iib->wordlen)*2);
189: OUT("\n");
190: }
191: switch(iib->mnemonic) {
192: case i_ORSR:
193: OUT(" SR|= srcdata;\n");
194: break;
195: case i_ANDSR:
196: if (iib->size == sz_byte) {
197: OUT(" SR = (SR & 0xFF00) | (SR & srcdata);\n");
198: } else {
199: OUT(" SR&= srcdata;\n");
200: }
201: break;
202: case i_EORSR:
203: OUT(" SR^= srcdata;\n");
204: break;
205: default:
206: OUT("ERROR\n");
207: break;
208: }
209: OUT(" if (sr != (uint8)reg68k_sr.sr_struct.s) {\n");
210: OUT(" /* mode change, swap SP and A7 */\n");
211: OUT(" ADDRREG(7)^= SP; SP^= ADDRREG(7); ADDRREG(7)^= SP;\n");
212: OUT(" }\n");
213: if (DEBUG_SR)
214: fputs(" printf(\"SR: %08X %04X\\n\", PC, reg68k_sr.sr_int);\n",
215: output);
216: break;
217:
218: case i_SUB:
219: generate_ea(output, iib, tp_src, 1);
220: generate_eaval(output, iib, tp_src);
221: generate_ea(output, iib, tp_dst, 1);
222: generate_eaval(output, iib, tp_dst);
223: switch (iib->size) {
224: case sz_byte:
225: generate_outdata(output, iib, "(sint8)dstdata - (sint8)srcdata");
226: break;
227: case sz_word:
228: generate_outdata(output, iib, "(sint16)dstdata - (sint16)srcdata");
229: break;
230: case sz_long:
231: generate_outdata(output, iib, "(sint32)dstdata - (sint32)srcdata");
232: break;
233: default:
234: OUT("ERROR size\n");
235: break;
236: }
237: OUT("\n");
238: generate_eastore(output, iib, tp_dst);
239: if (flags)
240: OUT("\n");
241: if (flags && iib->flags.set & IIB_FLAG_V)
242: generate_subflag_v(output, iib);
243: if (flags && ((iib->flags.set & IIB_FLAG_C) ||
244: (iib->flags.set & IIB_FLAG_X)))
245: generate_subflag_cx(output, iib);
246: if (flags && iib->flags.set & IIB_FLAG_N)
247: generate_stdflag_n(output, iib);
248: if (flags && iib->flags.set & IIB_FLAG_Z)
249: generate_stdflag_z(output, iib);
250: break;
251:
252: case i_SUBA:
253: if (iib->dtype != dt_Areg)
254: OUT("Error\n");
255: generate_ea(output, iib, tp_src, 1);
256: generate_eaval(output, iib, tp_src);
257: generate_ea(output, iib, tp_dst, 1);
258: OUT(" uint32 dstdata = ADDRREG(dstreg);\n");
259: switch (iib->size) {
260: case sz_byte:
261: OUT(" uint32 outdata = (sint32)dstdata - (sint8)srcdata;\n");
262: break;
263: case sz_word:
264: OUT(" uint32 outdata = (sint32)dstdata - (sint16)srcdata;\n");
265: break;
266: case sz_long:
267: OUT(" uint32 outdata = (sint32)dstdata - (sint32)srcdata;\n");
268: break;
269: default:
270: OUT("ERROR size\n");
271: break;
272: }
273: OUT("\n");
274: OUT(" ADDRREG(dstreg) = outdata;\n");
275: break;
276:
277: case i_SUBX:
278: generate_ea(output, iib, tp_src, 1);
279: generate_eaval(output, iib, tp_src);
280: generate_ea(output, iib, tp_dst, 1);
281: generate_eaval(output, iib, tp_dst);
282: switch (iib->size) {
283: case sz_byte:
284: generate_outdata(output, iib, "(sint8)dstdata - (sint8)srcdata "
285: "- XFLAG");
286: break;
287: case sz_word:
288: generate_outdata(output, iib, "(sint16)dstdata - (sint16)srcdata"
289: "- XFLAG");
290: break;
291: case sz_long:
292: generate_outdata(output, iib, "(sint32)dstdata - (sint32)srcdata"
293: "- XFLAG");
294: break;
295: default:
296: OUT("ERROR size\n");
297: break;
298: }
299: OUT("\n");
300: generate_eastore(output, iib, tp_dst);
301: if (flags)
302: OUT("\n");
303: if (flags && iib->flags.set & IIB_FLAG_V)
304: generate_subflag_v(output, iib);
305: if (flags && ((iib->flags.set & IIB_FLAG_C) ||
306: (iib->flags.set & IIB_FLAG_X)))
307: generate_subxflag_cx(output, iib);
308: if (flags && iib->flags.set & IIB_FLAG_N)
309: generate_stdflag_n(output, iib);
310: if (flags && iib->flags.set & IIB_FLAG_Z)
311: generate_stdxflag_z(output, iib);
312: break;
313:
314: case i_ADD:
315: generate_ea(output, iib, tp_src, 1);
316: generate_eaval(output, iib, tp_src);
317: generate_ea(output, iib, tp_dst, 1);
318: generate_eaval(output, iib, tp_dst);
319: switch (iib->size) {
320: case sz_byte:
321: generate_outdata(output, iib, "(sint8)dstdata + (sint8)srcdata");
322: break;
323: case sz_word:
324: generate_outdata(output, iib, "(sint16)dstdata + (sint16)srcdata");
325: break;
326: case sz_long:
327: generate_outdata(output, iib, "(sint32)dstdata + (sint32)srcdata");
328: break;
329: default:
330: OUT("ERROR size\n");
331: break;
332: }
333: OUT("\n");
334: generate_eastore(output, iib, tp_dst);
335: if (flags)
336: OUT("\n");
337: if (flags && iib->flags.set & IIB_FLAG_V)
338: generate_addflag_v(output, iib);
339: if (flags && ((iib->flags.set & IIB_FLAG_C) ||
340: (iib->flags.set & IIB_FLAG_X)))
341: generate_addflag_cx(output, iib);
342: if (flags && iib->flags.set & IIB_FLAG_N)
343: generate_stdflag_n(output, iib);
344: if (flags && iib->flags.set & IIB_FLAG_Z)
345: generate_stdflag_z(output, iib);
346: break;
347:
348: case i_ADDA:
349: if (iib->dtype != dt_Areg)
350: OUT("Error\n");
351: generate_ea(output, iib, tp_src, 1);
352: generate_eaval(output, iib, tp_src);
353: generate_ea(output, iib, tp_dst, 1);
354: OUT(" uint32 dstdata = ADDRREG(dstreg);\n");
355: switch (iib->size) {
356: case sz_byte:
357: OUT(" uint32 outdata = (sint32)dstdata + (sint8)srcdata;\n");
358: break;
359: case sz_word:
360: OUT(" uint32 outdata = (sint32)dstdata + (sint16)srcdata;\n");
361: break;
362: case sz_long:
363: OUT(" uint32 outdata = (sint32)dstdata + (sint32)srcdata;\n");
364: break;
365: default:
366: OUT("ERROR size\n");
367: break;
368: }
369: OUT("\n");
370: OUT(" ADDRREG(dstreg) = outdata;\n");
371: break;
372:
373: case i_ADDX:
374: generate_ea(output, iib, tp_src, 1);
375: generate_eaval(output, iib, tp_src);
376: generate_ea(output, iib, tp_dst, 1);
377: generate_eaval(output, iib, tp_dst);
378: switch (iib->size) {
379: case sz_byte:
380: generate_outdata(output, iib, "(sint8)dstdata + (sint8)srcdata "
381: "+ XFLAG");
382: break;
383: case sz_word:
384: generate_outdata(output, iib, "(sint16)dstdata + (sint16)srcdata"
385: "+ XFLAG");
386: break;
387: case sz_long:
388: generate_outdata(output, iib, "(sint32)dstdata + (sint32)srcdata"
389: "+ XFLAG");
390: break;
391: default:
392: OUT("ERROR size\n");
393: break;
394: }
395: OUT("\n");
396: generate_eastore(output, iib, tp_dst);
397: if (flags)
398: OUT("\n");
399: if (flags && iib->flags.set & IIB_FLAG_V)
400: generate_addflag_v(output, iib);
401: if (flags && ((iib->flags.set & IIB_FLAG_C) ||
402: (iib->flags.set & IIB_FLAG_X)))
403: generate_addxflag_cx(output, iib);
404: if (flags && iib->flags.set & IIB_FLAG_N)
405: generate_stdflag_n(output, iib);
406: if (flags && iib->flags.set & IIB_FLAG_Z)
407: generate_stdxflag_z(output, iib);
408: break;
409:
410: case i_MULU:
411: generate_ea(output, iib, tp_src, 1);
412: generate_eaval(output, iib, tp_src);
413: generate_ea(output, iib, tp_dst, 1);
414: generate_eaval(output, iib, tp_dst);
415: OUT("\n");
416: OUT(" uint32 outdata = (uint32)srcdata * (uint32)dstdata;\n");
417: if (iib->dtype != dt_Dreg)
418: OUT("ERROR dtype\n");
419: OUT(" DATAREG(dstreg) = outdata;\n");
420: if (flags)
421: OUT("\n");
422: if (flags && iib->flags.set & IIB_FLAG_N)
423: OUT(" NFLAG = ((sint32)outdata) < 0;\n");
424: if (flags && iib->flags.set & IIB_FLAG_Z)
425: generate_stdflag_z(output, iib);
426: if (flags && iib->flags.set & IIB_FLAG_V)
427: generate_clrflag_v(output, iib);
428: if (flags && iib->flags.set & IIB_FLAG_C)
429: generate_clrflag_c(output, iib);
430: break;
431:
432: case i_MULS:
433: generate_ea(output, iib, tp_src, 1);
434: generate_eaval(output, iib, tp_src);
435: generate_ea(output, iib, tp_dst, 1);
436: generate_eaval(output, iib, tp_dst);
437: OUT("\n");
438: OUT(" uint32 outdata = (sint32)(sint16)srcdata * "
439: "(sint32)(sint16)dstdata;\n");
440: if (iib->dtype != dt_Dreg)
441: OUT("ERROR dtype\n");
442: OUT(" DATAREG(dstreg) = outdata;\n");
443: if (flags)
444: OUT("\n");
445: if (flags && iib->flags.set & IIB_FLAG_N)
446: OUT(" NFLAG = ((sint32)outdata) < 0;\n");
447: if (flags && iib->flags.set & IIB_FLAG_Z)
448: generate_stdflag_z(output, iib);
449: if (flags && iib->flags.set & IIB_FLAG_V)
450: generate_clrflag_v(output, iib);
451: if (flags && iib->flags.set & IIB_FLAG_C)
452: generate_clrflag_c(output, iib);
453: break;
454:
455: case i_CMP:
456: generate_ea(output, iib, tp_src, 1);
457: generate_eaval(output, iib, tp_src);
458: generate_ea(output, iib, tp_dst, 1);
459: generate_eaval(output, iib, tp_dst);
460: switch (iib->size) {
461: case sz_byte:
462: generate_outdata(output, iib, "(sint8)dstdata - (sint8)srcdata");
463: break;
464: case sz_word:
465: generate_outdata(output, iib, "(sint16)dstdata - (sint16)srcdata");
466: break;
467: case sz_long:
468: generate_outdata(output, iib, "(sint32)dstdata - (sint32)srcdata");
469: break;
470: default:
471: OUT("ERROR size\n");
472: break;
473: }
474: if (flags)
475: OUT("\n");
476: if (flags && iib->flags.set & IIB_FLAG_V)
477: generate_subflag_v(output, iib);
478: if (flags && iib->flags.set & IIB_FLAG_C)
479: generate_subflag_c(output, iib);
480: if (flags && iib->flags.set & IIB_FLAG_N)
481: generate_stdflag_n(output, iib);
482: if (flags && iib->flags.set & IIB_FLAG_Z)
483: generate_stdflag_z(output, iib);
484: break;
485:
486: case i_CMPA:
487: if (iib->dtype != dt_Areg || iib->size != sz_word)
488: OUT("Error\n");
489: generate_ea(output, iib, tp_src, 1);
490: generate_eaval(output, iib, tp_src);
491: iib->size = sz_long;
492: generate_ea(output, iib, tp_dst, 1);
493: generate_eaval(output, iib, tp_dst);
494: OUT(" uint32 outdata = (sint32)dstdata - (sint32)(sint16)srcdata;\n");
495: if (flags)
496: OUT("\n");
497: if (flags && iib->flags.set & IIB_FLAG_V)
498: generate_cmpaflag_v(output, iib);
499: if (flags && iib->flags.set & IIB_FLAG_C)
500: generate_cmpaflag_c(output, iib);
501: if (flags && iib->flags.set & IIB_FLAG_N)
502: generate_stdflag_n(output, iib);
503: if (flags && iib->flags.set & IIB_FLAG_Z)
504: generate_stdflag_z(output, iib);
505: iib->size = sz_word;
506: break;
507:
508: case i_BTST:
509: case i_BCHG:
510: case i_BCLR:
511: case i_BSET:
512: generate_ea(output, iib, tp_src, 1);
513: generate_eaval(output, iib, tp_src);
514: generate_ea(output, iib, tp_dst, 1);
515: generate_eaval(output, iib, tp_dst);
516: switch (iib->size) {
517: case sz_byte:
518: OUT(" uint32 bitpos = 1<<(srcdata & 7);");
519: break;
520: case sz_long:
521: OUT(" uint32 bitpos = 1<<(srcdata & 31);");
522: break;
523: default:
524: OUT("ERROR size\n");
525: break;
526: }
527: OUT("\n");
528: switch(iib->mnemonic) {
529: case i_BTST:
530: break;
531: case i_BCHG:
532: generate_outdata(output, iib, "dstdata ^ bitpos");
533: generate_eastore(output, iib, tp_dst);
534: break;
535: case i_BCLR:
536: generate_outdata(output, iib, "dstdata & ~bitpos");
537: generate_eastore(output, iib, tp_dst);
538: break;
539: case i_BSET:
540: generate_outdata(output, iib, "dstdata | bitpos");
541: generate_eastore(output, iib, tp_dst);
542: break;
543: default:
544: OUT("ERROR\n");
545: break;
546: }
547: OUT("\n");
548: OUT(" ZFLAG = !(dstdata & bitpos);\n");
549: break;
550:
551: case i_MOVE:
552: generate_ea(output, iib, tp_src, 1);
553: generate_eaval(output, iib, tp_src);
554: generate_ea(output, iib, tp_dst, 1);
555: generate_outdata(output, iib, "srcdata");
556: OUT("\n");
557: generate_eastore(output, iib, tp_dst);
558: if (flags)
559: OUT("\n");
560: if (flags && iib->flags.set & IIB_FLAG_V)
561: generate_clrflag_v(output, iib);
562: if (flags && iib->flags.set & IIB_FLAG_C)
563: generate_clrflag_c(output, iib);
564: if (flags && iib->flags.set & IIB_FLAG_N)
565: generate_stdflag_n(output, iib);
566: if (flags && iib->flags.set & IIB_FLAG_Z)
567: generate_stdflag_z(output, iib);
568: break;
569:
570: case i_MOVEA:
571: generate_ea(output, iib, tp_src, 1);
572: generate_eaval(output, iib, tp_src);
573: generate_ea(output, iib, tp_dst, 1);
574: if (iib->dtype != dt_Areg || iib->size != sz_word)
575: OUT("Error\n");
576: OUT("\n");
577: OUT(" ADDRREG(dstreg) = (sint32)(sint16)srcdata;\n");
578: break;
579:
580: case i_MOVEPMR:
581: generate_ea(output, iib, tp_src, 1);
582: generate_ea(output, iib, tp_dst, 1);
583: generate_eaval(output, iib, tp_dst);
584: switch(iib->size) {
585: case sz_word:
586: generate_outdata(output, iib, "(fetchbyte(srcaddr) << 8) + "
587: "fetchbyte(srcaddr+2)");
588: break;
589: case sz_long:
590: generate_outdata(output, iib, "(fetchbyte(srcaddr) << 24) | "
591: "(fetchbyte(srcaddr+2) << 16) | "
592: "\n (fetchbyte(srcaddr+4) << 8) | "
593: "fetchbyte(srcaddr+6)");
594: break;
595: default:
596: OUT("ERROR size\n");
597: break;
598: }
599: OUT("\n");
600: generate_eastore(output, iib, tp_dst);
601: break;
602:
603: case i_MOVEPRM:
604: generate_ea(output, iib, tp_src, 1);
605: generate_eaval(output, iib, tp_src);
606: generate_ea(output, iib, tp_dst, 1);
607: OUT("\n");
608: switch(iib->size) {
609: case sz_word:
610: OUT(" storebyte(dstaddr, (srcdata >> 8) & 0xFF);\n");
611: OUT(" storebyte(dstaddr+2, srcdata & 0xFF);\n");
612: break;
613: case sz_long:
614: OUT(" storebyte(dstaddr, (srcdata >> 24) & 0xFF);\n");
615: OUT(" storebyte(dstaddr+2, (srcdata >> 16) & 0xFF);\n");
616: OUT(" storebyte(dstaddr+4, (srcdata >> 8) & 0xFF);\n");
617: OUT(" storebyte(dstaddr+6, srcdata & 0xFF);\n");
618: break;
619: default:
620: OUT("ERROR size\n");
621: break;
622: }
623: break;
624:
625: case i_MOVEFSR:
626: generate_ea(output, iib, tp_src, 1);
627: generate_outdata(output, iib, NULL);
628: OUT("\n");
629: OUT(" outdata = SR;\n");
630: generate_eastore(output, iib, tp_src);
631: break;
632:
633: case i_MOVETSR:
634: generate_ea(output, iib, tp_src, 1);
635: generate_eaval(output, iib, tp_src);
636: OUT(" unsigned int sr = reg68k_sr.sr_struct.s;\n");
637: OUT("\n");
638: if (DEBUG_SR)
639: fputs(" printf(\"SR: %08X %04X\\n\", PC, reg68k_sr.sr_int);\n",
640: output);
641: switch (iib->size) {
642: case sz_byte:
643: OUT(" SR = (SR & ~0xFF) | srcdata;\n");
644: break;
645: case sz_word:
646: OUT(" if (!SFLAG)\n");
647: fprintf(output, " reg68k_internal_vector(V_PRIVILEGE, PC+%d);\n",
648: (iib->wordlen)*2);
649: OUT("\n");
650: OUT(" SR = srcdata;\n");
651: break;
652: default:
653: OUT("ERROR size\n");
654: break;
655: }
656: OUT(" if (sr != (uint8)reg68k_sr.sr_struct.s) {\n");
657: OUT(" /* mode change, swap SP and A7 */\n");
658: OUT(" ADDRREG(7)^= SP; SP^= ADDRREG(7); ADDRREG(7)^= SP;\n");
659: OUT(" }\n");
660: if (DEBUG_SR)
661: fputs(" printf(\"SR: %08X %04X\\n\", PC, reg68k_sr.sr_int);\n",
662: output);
663: break;
664:
665: case i_MOVEMRM:
666: generate_ea(output, iib, tp_src, 1);
667: generate_eaval(output, iib, tp_src);
668: generate_ea(output, iib, tp_dst, 0);
669: if (iib->dtype == dt_Adec) {
670: OUT(" uint8 datamask = (srcdata & 0xFF00) >> 8;\n");
671: OUT(" uint8 addrmask = srcdata & 0xFF;");
672: OUT("\n");
673: switch(iib->size) {
674: case sz_word:
675: OUT(" while (addrmask) {\n");
676: OUT(" dstaddr-= 2;\n");
677: OUT(" storeword(dstaddr, ADDRREG((7-movem_bit[addrmask])));\n");
678: OUT(" addrmask&= ~(1<<movem_bit[addrmask]);\n");
679: OUT(" }\n");
680: OUT(" while (datamask) {\n");
681: OUT(" dstaddr-= 2;\n");
682: OUT(" storeword(dstaddr, DATAREG((7-movem_bit[datamask])));\n");
683: OUT(" datamask&= ~(1<<movem_bit[datamask]);\n");
684: OUT(" }\n");
685: break;
686: case sz_long:
687: OUT(" while (addrmask) {\n");
688: OUT(" dstaddr-= 4;\n");
689: OUT(" storelong(dstaddr, ADDRREG((7-movem_bit[addrmask])));\n");
690: OUT(" addrmask&= ~(1<<movem_bit[addrmask]);\n");
691: OUT(" }\n");
692: OUT(" while (datamask) {\n");
693: OUT(" dstaddr-= 4;\n");
694: OUT(" storelong(dstaddr, ");
695: OUT("DATAREG((7-movem_bit[datamask])));\n");
696: OUT(" datamask&= ~(1<<movem_bit[datamask]);\n");
697: OUT(" }\n");
698: break;
699: default:
700: OUT("ERROR\n");
701: break;
702: }
703: OUT(" ADDRREG(dstreg) = dstaddr;");
704: } else {
705: OUT(" uint8 addrmask = (srcdata & 0xFF00) >> 8;\n");
706: OUT(" uint8 datamask = srcdata & 0xFF;");
707: OUT("\n");
708: switch(iib->size) {
709: case sz_word:
710: OUT(" while (datamask) {\n");
711: OUT(" storeword(dstaddr, DATAREG(movem_bit[datamask]));\n");
712: OUT(" datamask&= ~(1<<movem_bit[datamask]);\n");
713: OUT(" dstaddr+= 2;\n");
714: OUT(" }\n");
715: OUT(" while (addrmask) {\n");
716: OUT(" storeword(dstaddr, ADDRREG(movem_bit[addrmask]));\n");
717: OUT(" addrmask&= ~(1<<movem_bit[addrmask]);\n");
718: OUT(" dstaddr+= 2;\n");
719: OUT(" }\n");
720: break;
721: case sz_long:
722: OUT(" while (datamask) {\n");
723: OUT(" storelong(dstaddr, DATAREG(movem_bit[datamask]));\n");
724: OUT(" datamask&= ~(1<<movem_bit[datamask]);\n");
725: OUT(" dstaddr+= 4;\n");
726: OUT(" }\n");
727: OUT(" while (addrmask) {\n");
728: OUT(" storelong(dstaddr, ADDRREG(movem_bit[addrmask]));\n");
729: OUT(" addrmask&= ~(1<<movem_bit[addrmask]);\n");
730: OUT(" dstaddr+= 4;\n");
731: OUT(" }\n");
732: break;
733: default:
734: OUT("ERROR\n");
735: break;
736: }
737: if (iib->dtype == dt_Ainc) {
738: /* not supported */
739: OUT("ERROR\n");
740: }
741: }
742: break;
743:
744: case i_MOVEMMR:
745: generate_ea(output, iib, tp_src, 1);
746: generate_eaval(output, iib, tp_src);
747: generate_ea(output, iib, tp_dst, 0);
748: OUT(" uint8 addrmask = (srcdata & 0xFF00) >> 8;\n");
749: OUT(" uint8 datamask = srcdata & 0xFF;");
750: OUT("\n");
751: switch(iib->size) {
752: case sz_word:
753: OUT(" while (datamask) {\n");
754: OUT(" DATAREG(movem_bit[datamask]) = ");
755: OUT("(sint32)(sint16)fetchword(dstaddr);\n");
756: OUT(" datamask&= ~(1<<movem_bit[datamask]);\n");
757: OUT(" dstaddr+= 2;\n");
758: OUT(" }\n");
759: OUT(" while (addrmask) {\n");
760: OUT(" ADDRREG(movem_bit[addrmask]) = ");
761: OUT("(sint32)(sint16)fetchword(dstaddr);\n");
762: OUT(" addrmask&= ~(1<<movem_bit[addrmask]);\n");
763: OUT(" dstaddr+= 2;\n");
764: OUT(" }\n");
765: break;
766: case sz_long:
767: OUT(" while (datamask) {\n");
768: OUT(" DATAREG(movem_bit[datamask]) = fetchlong(dstaddr);\n");
769: OUT(" datamask&= ~(1<<movem_bit[datamask]);\n");
770: OUT(" dstaddr+= 4;\n");
771: OUT(" }\n");
772: OUT(" while (addrmask) {\n");
773: OUT(" ADDRREG(movem_bit[addrmask]) = fetchlong(dstaddr);\n");
774: OUT(" addrmask&= ~(1<<movem_bit[addrmask]);\n");
775: OUT(" dstaddr+= 4;\n");
776: OUT(" }\n");
777: break;
778: default:
779: OUT("ERROR\n");
780: break;
781: }
782: if (iib->dtype == dt_Ainc) {
783: OUT(" ADDRREG(dstreg) = dstaddr;\n");
784: } else if (iib->dtype == dt_Adec) {
785: /* not supported */
786: OUT("ERROR\n");
787: }
788: break;
789:
790: case i_MOVETUSP:
791: generate_ea(output, iib, tp_src, 1);
792: generate_eaval(output, iib, tp_src);
793: OUT("\n");
794: OUT(" if (!SFLAG)\n");
795: fprintf(output, " reg68k_internal_vector(V_PRIVILEGE, PC+%d);\n",
796: (iib->wordlen)*2);
797: OUT("\n");
798: OUT(" SP = srcdata;\n");
799: break;
800:
801: case i_MOVEFUSP:
802: generate_ea(output, iib, tp_src, 1);
803: OUT(" uint32 outdata;\n");
804: OUT("\n");
805: OUT(" if (!SFLAG)\n");
806: fprintf(output, " reg68k_internal_vector(V_PRIVILEGE, PC+%d);\n",
807: (iib->wordlen)*2);
808: OUT("\n");
809: OUT(" outdata = SP;\n");
810: generate_eastore(output, iib, tp_src);
811: break;
812:
813: case i_NEG:
814: generate_ea(output, iib, tp_src, 1);
815: generate_eaval(output, iib, tp_src);
816: switch (iib->size) {
817: case sz_byte:
818: generate_outdata(output, iib, "0 - (sint8)srcdata");
819: break;
820: case sz_word:
821: generate_outdata(output, iib, "0 - (sint16)srcdata");
822: break;
823: case sz_long:
824: generate_outdata(output, iib, "0 - (sint32)srcdata");
825: break;
826: default:
827: OUT("ERROR size\n");
828: break;
829: }
830: OUT("\n");
831: generate_eastore(output, iib, tp_src);
832: if (flags)
833: OUT("\n");
834: if (flags && iib->flags.set & IIB_FLAG_V)
835: generate_negflag_v(output, iib);
836: if (flags && ((iib->flags.set & IIB_FLAG_C) ||
837: (iib->flags.set & IIB_FLAG_X)))
838: generate_negflag_cx(output, iib);
839: if (flags && iib->flags.set & IIB_FLAG_N)
840: generate_stdflag_n(output, iib);
841: if (flags && iib->flags.set & IIB_FLAG_Z)
842: generate_stdflag_z(output, iib);
843: break;
844:
845: case i_NEGX:
846: generate_ea(output, iib, tp_src, 1);
847: generate_eaval(output, iib, tp_src);
848: switch (iib->size) {
849: case sz_byte:
850: generate_outdata(output, iib, "0 - (sint8)srcdata - XFLAG");
851: break;
852: case sz_word:
853: generate_outdata(output, iib, "0 - (sint16)srcdata - XFLAG");
854: break;
855: case sz_long:
856: generate_outdata(output, iib, "0 - (sint32)srcdata - XFLAG");
857: break;
858: default:
859: OUT("ERROR size\n");
860: break;
861: }
862: OUT("\n");
863: generate_eastore(output, iib, tp_src);
864: if (flags)
865: OUT("\n");
866: if (flags && iib->flags.set & IIB_FLAG_V)
867: generate_negxflag_v(output, iib);
868: if (flags && ((iib->flags.set & IIB_FLAG_C) ||
869: (iib->flags.set & IIB_FLAG_X)))
870: generate_negxflag_cx(output, iib);
871: if (flags && iib->flags.set & IIB_FLAG_N)
872: generate_stdflag_n(output, iib);
873: if (flags && iib->flags.set & IIB_FLAG_Z)
874: generate_stdxflag_z(output, iib);
875: break;
876:
877: case i_CLR:
878: generate_ea(output, iib, tp_src, 1);
879: generate_eaval(output, iib, tp_src); /* read before write */
880: generate_outdata(output, iib, "0");
881: OUT("\n");
882: generate_eastore(output, iib, tp_src);
883: if (flags)
884: OUT("\n");
885: if (flags && iib->flags.set & IIB_FLAG_V)
886: generate_clrflag_v(output, iib);
887: if (flags && iib->flags.set & IIB_FLAG_C)
888: generate_clrflag_c(output, iib);
889: if (flags && iib->flags.set & IIB_FLAG_N)
890: generate_clrflag_n(output, iib);
891: if (flags && iib->flags.set & IIB_FLAG_Z)
892: generate_setflag_z(output, iib);
893: break;
894:
895: case i_NOT:
896: generate_ea(output, iib, tp_src, 1);
897: generate_eaval(output, iib, tp_src); /* read before write */
898: generate_outdata(output, iib, "~srcdata");
899: OUT("\n");
900: generate_eastore(output, iib, tp_src);
901: if (flags)
902: OUT("\n");
903: if (flags && iib->flags.set & IIB_FLAG_V)
904: generate_clrflag_v(output, iib);
905: if (flags && iib->flags.set & IIB_FLAG_C)
906: generate_clrflag_c(output, iib);
907: if (flags && iib->flags.set & IIB_FLAG_N)
908: generate_stdflag_n(output, iib);
909: if (flags && iib->flags.set & IIB_FLAG_Z)
910: generate_stdflag_z(output, iib);
911: break;
912:
913: case i_ABCD:
914: generate_ea(output, iib, tp_src, 1);
915: generate_eaval(output, iib, tp_src);
916: generate_ea(output, iib, tp_dst, 1);
917: generate_eaval(output, iib, tp_dst);
918: generate_outdata(output, iib, NULL);
919: OUT("\n");
920: OUT(" uint8 outdata_low = (dstdata & 0xF) + (srcdata & 0xF) ");
921: OUT("+ XFLAG;\n");
922: OUT(" uint8 outdata_high = (dstdata>>4) + (srcdata>>4);\n");
923: OUT("\n");
924: OUT(" if (outdata_low > 9) {\n");
925: OUT(" outdata_low-=10; outdata_high++;\n");
926: OUT(" }\n");
927: OUT(" if (outdata_high > 9) {\n");
928: OUT(" outdata_high-=10;\n");
929: if (flags && iib->flags.set & IIB_FLAG_C)
930: OUT(" CFLAG = 1;\n");
931: if (flags && iib->flags.set & IIB_FLAG_X)
932: OUT(" XFLAG = 1;\n");
933: OUT(" } else {\n");
934: if (flags && iib->flags.set & IIB_FLAG_C)
935: OUT(" CFLAG = 0;\n");
936: if (flags && iib->flags.set & IIB_FLAG_X)
937: OUT(" XFLAG = 0;\n");
938: OUT(" }\n");
939: OUT(" outdata = outdata_low | (outdata_high << 4);\n");
940: if (flags && iib->flags.set & IIB_FLAG_Z)
941: OUT(" if (outdata) ZFLAG = 0;\n");
942: generate_eastore(output, iib, tp_dst);
943: break;
944:
945: case i_SBCD:
946: generate_ea(output, iib, tp_src, 1);
947: generate_eaval(output, iib, tp_src);
948: generate_ea(output, iib, tp_dst, 1);
949: generate_eaval(output, iib, tp_dst);
950: generate_outdata(output, iib, NULL);
951: OUT("\n");
952: OUT(" sint8 outdata_low = (sint8)(dstdata & 0xF) -");
953: OUT("(sint8)(srcdata & 0xF) - XFLAG;\n");
954: OUT(" sint8 outdata_high = (sint8)(dstdata>>4) - ");
955: OUT("(sint8)(srcdata>>4);\n");
956: OUT("\n");
957: OUT(" if (outdata_low < 0) {\n");
958: OUT(" outdata_low+=10; outdata_high--;\n");
959: OUT(" }\n");
960: OUT(" if (outdata_high < 0) {\n");
961: OUT(" outdata_high+=10;\n");
962: if (flags && iib->flags.set & IIB_FLAG_C)
963: OUT(" CFLAG = 1;\n");
964: if (flags && iib->flags.set & IIB_FLAG_X)
965: OUT(" XFLAG = 1;\n");
966: OUT(" } else {\n");
967: if (flags && iib->flags.set & IIB_FLAG_C)
968: OUT(" CFLAG = 0;\n");
969: if (flags && iib->flags.set & IIB_FLAG_X)
970: OUT(" XFLAG = 0;\n");
971: OUT(" }\n");
972: OUT(" outdata = (uint8)outdata_low | ");
973: OUT("((uint8)outdata_high << 4);\n");
974: if (flags && iib->flags.set & IIB_FLAG_Z)
975: OUT(" if (outdata) ZFLAG = 0;\n");
976: generate_eastore(output, iib, tp_dst);
977: break;
978:
979: case i_NBCD:
980: generate_ea(output, iib, tp_src, 1);
981: generate_eaval(output, iib, tp_src);
982: generate_outdata(output, iib, NULL);
983: OUT("\n");
984: OUT(" sint8 outdata_low = 0 - (sint8)(srcdata & 0xF) - XFLAG;\n");
985: OUT(" sint8 outdata_high = 0 - (sint8)(srcdata>>4);\n");
986: OUT("\n");
987: OUT(" if ((sint8)outdata_low < 0) {\n");
988: OUT(" outdata_low+=10; outdata_high--;\n");
989: OUT(" }\n");
990: OUT(" if ((sint8)outdata_high < 0) {\n");
991: OUT(" outdata_high+=10;\n");
992: if (flags && iib->flags.set & IIB_FLAG_C)
993: OUT(" CFLAG = 1;\n");
994: if (flags && iib->flags.set & IIB_FLAG_X)
995: OUT(" XFLAG = 1;\n");
996: OUT(" } else {\n");
997: if (flags && iib->flags.set & IIB_FLAG_C)
998: OUT(" CFLAG = 0;\n");
999: if (flags && iib->flags.set & IIB_FLAG_X)
1000: OUT(" XFLAG = 0;\n");
1001: OUT(" }\n");
1002: OUT(" outdata = (uint8)outdata_low |");
1003: OUT("((uint8)outdata_high << 4);\n");
1004: if (flags && iib->flags.set & IIB_FLAG_Z)
1005: OUT(" if (outdata) ZFLAG = 0;\n");
1006: generate_eastore(output, iib, tp_src);
1007: break;
1008:
1009: case i_SWAP:
1010: generate_ea(output, iib, tp_src, 1);
1011: generate_eaval(output, iib, tp_src);
1012: generate_outdata(output, iib, "(srcdata>>16) | (srcdata<<16)");
1013: OUT("\n");
1014: generate_eastore(output, iib, tp_src);
1015: if (flags)
1016: OUT("\n");
1017: if (flags && iib->flags.set & IIB_FLAG_V)
1018: generate_clrflag_v(output, iib);
1019: if (flags && iib->flags.set & IIB_FLAG_C)
1020: generate_clrflag_c(output, iib);
1021: if (flags && iib->flags.set & IIB_FLAG_N)
1022: generate_stdflag_n(output, iib);
1023: if (flags && iib->flags.set & IIB_FLAG_Z)
1024: generate_stdflag_z(output, iib);
1025: break;
1026:
1027: case i_PEA:
1028: generate_ea(output, iib, tp_src, 1);
1029: OUT("\n");
1030: OUT(" ADDRREG(7)-= 4;\n");
1031: OUT(" storelong(ADDRREG(7), srcaddr);\n");
1032: break;
1033:
1034: case i_LEA:
1035: generate_ea(output, iib, tp_src, 1);
1036: generate_ea(output, iib, tp_dst, 1);
1037: generate_outdata(output, iib, "srcaddr");
1038: OUT("\n");
1039: generate_eastore(output, iib, tp_dst);
1040: break;
1041:
1042: case i_EXT:
1043: generate_ea(output, iib, tp_src, 1);
1044: generate_eaval(output, iib, tp_src);
1045: OUT("\n");
1046: switch(iib->size) {
1047: case sz_word:
1048: generate_outdata(output, iib, "(sint16)(sint8)(srcdata)");
1049: break;
1050: case sz_long:
1051: generate_outdata(output, iib, "(sint32)(sint16)(srcdata)");
1052: break;
1053: default:
1054: fprintf(output, "ERROR size\n");
1055: break;
1056: }
1057: generate_eastore(output, iib, tp_src);
1058: if (flags)
1059: OUT("\n");
1060: if (flags && iib->flags.set & IIB_FLAG_V)
1061: generate_clrflag_v(output, iib);
1062: if (flags && iib->flags.set & IIB_FLAG_C)
1063: generate_clrflag_c(output, iib);
1064: if (flags && iib->flags.set & IIB_FLAG_N)
1065: generate_stdflag_n(output, iib);
1066: if (flags && iib->flags.set & IIB_FLAG_Z)
1067: generate_stdflag_z(output, iib);
1068: break;
1069:
1070: case i_EXG:
1071: generate_ea(output, iib, tp_src, 1);
1072: generate_eaval(output, iib, tp_src);
1073: generate_ea(output, iib, tp_dst, 1);
1074: generate_eaval(output, iib, tp_dst);
1075: OUT("\n");
1076: switch (iib->dtype) {
1077: case dt_Dreg:
1078: OUT(" DATAREG(dstreg) = srcdata;\n");
1079: break;
1080: case dt_Areg:
1081: OUT(" ADDRREG(dstreg) = srcdata;\n");
1082: break;
1083: default:
1084: OUT("ERROR size\n");
1085: break;
1086: }
1087: switch (iib->stype) {
1088: case dt_Dreg:
1089: OUT(" DATAREG(srcreg) = dstdata;\n");
1090: break;
1091: case dt_Areg:
1092: OUT(" ADDRREG(srcreg) = dstdata;\n");
1093: break;
1094: default:
1095: OUT("ERROR size\n");
1096: break;
1097: }
1098: break;
1099:
1100: case i_TST:
1101: generate_ea(output, iib, tp_src, 1);
1102: generate_eaval(output, iib, tp_src);
1103: generate_outdata(output, iib, "srcdata");
1104: if (flags)
1105: OUT("\n");
1106: if (flags && iib->flags.set & IIB_FLAG_V)
1107: generate_clrflag_v(output, iib);
1108: if (flags && iib->flags.set & IIB_FLAG_C)
1109: generate_clrflag_c(output, iib);
1110: if (flags && iib->flags.set & IIB_FLAG_N)
1111: generate_stdflag_n(output, iib);
1112: if (flags && iib->flags.set & IIB_FLAG_Z)
1113: generate_stdflag_z(output, iib);
1114: break;
1115:
1116: case i_TAS:
1117: generate_ea(output, iib, tp_src, 1);
1118: generate_eaval(output, iib, tp_src);
1119: generate_outdata(output, iib, "srcdata");
1120: if (flags)
1121: OUT("\n");
1122: if (flags && iib->flags.set & IIB_FLAG_V)
1123: generate_clrflag_v(output, iib);
1124: if (flags && iib->flags.set & IIB_FLAG_C)
1125: generate_clrflag_c(output, iib);
1126: if (flags && iib->flags.set & IIB_FLAG_N)
1127: generate_stdflag_n(output, iib);
1128: if (flags && iib->flags.set & IIB_FLAG_Z)
1129: generate_stdflag_z(output, iib);
1130: switch(iib->size) {
1131: case sz_byte:
1132: OUT(" outdata|= 1<<7;\n");
1133: break;
1134: case sz_word:
1135: OUT(" outdata|= 1<<15;\n");
1136: break;
1137: case sz_long:
1138: OUT(" outdata|= 1<<31;\n");
1139: break;
1140: default:
1141: OUT("ERROR size\n");
1142: break;
1143: }
1144: generate_eastore(output, iib, tp_src);
1145: break;
1146:
1147: case i_CHK:
1148: generate_ea(output, iib, tp_src, 1);
1149: generate_eaval(output, iib, tp_src);
1150: generate_ea(output, iib, tp_dst, 1);
1151: generate_eaval(output, iib, tp_dst);
1152: fprintf(output, "\n");
1153: if (iib->size != sz_word)
1154: OUT("ERROR size\n");
1155: fprintf(output, " if ((sint16)srcdata < 0) {\n");
1156: if (flags)
1157: OUT(" NFLAG = 1;\n");
1158: fprintf(output, " reg68k_internal_vector(V_CHK, PC+%d);\n",
1159: (iib->wordlen)*2);
1160: OUT(" } else if (dstdata > srcdata) {\n");
1161: if (flags)
1162: OUT(" NFLAG = 0;\n");
1163: fprintf(output, " reg68k_internal_vector(V_CHK, PC+%d);\n",
1164: (iib->wordlen)*2);
1165: OUT(" }\n");
1166: break;
1167:
1168: case i_TRAPV:
1169: OUT(" if (VFLAG) {\n");
1170: fprintf(output, " reg68k_internal_vector(V_TRAPV, PC+%d);\n",
1171: (iib->wordlen)*2);
1172: OUT(" }\n");
1173: break;
1174:
1175: case i_TRAP:
1176: generate_ea(output, iib, tp_src, 1);
1177: generate_eaval(output, iib, tp_src);
1178: OUT("\n");
1179: fprintf(output, " reg68k_internal_vector(V_TRAP+srcdata, PC+%d);\n",
1180: (iib->wordlen)*2);
1181: pcinc = 0;
1182: break;
1183:
1184: case i_RESET:
1185: OUT(" printf(\"RESET @ %x\\n\", PC);\n");
1186: OUT(" exit(1);\n");
1187: break;
1188:
1189: case i_NOP:
1190: /* NOP */
1191: break;
1192:
1193: case i_STOP:
1194: generate_ea(output, iib, tp_src, 1);
1195: generate_eaval(output, iib, tp_src);
1196: OUT("\n");
1197: OUT(" if (regs.stop)\n");
1198: OUT(" return;\n");
1199: OUT(" if (!(SFLAG && (srcdata & 1<<13))) {\n");
1200: fprintf(output, " reg68k_internal_vector(V_PRIVILEGE, PC+%d);\n",
1201: (iib->wordlen)*2);
1202: fprintf(output, " PC+= %d;\n", (iib->wordlen)*2);
1203: OUT(" } else {\n");
1204: OUT(" SR = srcdata;\n");
1205: OUT(" STOP = 1;\n");
1206: OUT(" }\n");
1207: pcinc = 0;
1208: break;
1209:
1210: case i_LINK:
1211: generate_ea(output, iib, tp_src, 1);
1212: generate_eaval(output, iib, tp_src);
1213: generate_ea(output, iib, tp_dst, 1);
1214: generate_eaval(output, iib, tp_dst);
1215: if (iib->stype != dt_ImmW)
1216: OUT("ERROR stype\n");
1217: OUT("\n");
1218: OUT(" ADDRREG(7)-= 4;\n");
1219: OUT(" storelong(ADDRREG(7), dstdata);\n");
1220: OUT(" ADDRREG(dstreg) = ADDRREG(7);\n");
1221: OUT(" ADDRREG(7)+= (sint16)srcdata;\n");
1222: break;
1223:
1224: case i_UNLK:
1225: generate_ea(output, iib, tp_src, 1);
1226: generate_eaval(output, iib, tp_src);
1227: OUT("\n");
1228: OUT(" ADDRREG(srcreg) = fetchlong(srcdata);\n");
1229: OUT(" ADDRREG(7) = srcdata+4;\n");
1230: break;
1231:
1232: case i_RTE:
1233: if (DEBUG_RTE)
1234: fputs(" printf(\"RTE: 0x%X\\n\", PC);\n", output);
1235: if (DEBUG_SR)
1236: fputs(" printf(\"SR: %08X %04X\\n\", PC, reg68k_sr.sr_int);\n",
1237: output);
1238: OUT(" if (!SFLAG)\n");
1239: fprintf(output, " reg68k_internal_vector(V_PRIVILEGE, PC+%d);\n",
1240: (iib->wordlen)*2);
1241: OUT("\n");
1242: OUT(" SR = fetchword(ADDRREG(7));\n");
1243: OUT(" PC = fetchlong(ADDRREG(7)+2);\n");
1244: OUT(" ADDRREG(7)+= 6;\n");
1245: OUT(" if (!reg68k_sr.sr_struct.s) {\n");
1246: OUT(" /* mode change, swap SP and A7 */\n");
1247: OUT(" ADDRREG(7)^= SP; SP^= ADDRREG(7); ADDRREG(7)^= SP;\n");
1248: OUT(" }\n");
1249: if (DEBUG_RTE)
1250: fputs(" printf(\"RTE: ->0x%X\\n\", PC);\n", output);
1251: if (DEBUG_SR)
1252: fputs(" printf(\"SR: %08X %04X\\n\", PC, reg68k_sr.sr_int);\n",
1253: output);
1254: pcinc = 0;
1255: break;
1256:
1257: case i_RTS:
1258: if (DEBUG_BRANCH)
1259: fputs(" printf(\"RTS: 0x%X\\n\", PC);", output);
1260: OUT(" PC = fetchlong(ADDRREG(7));\n");
1261: OUT(" ADDRREG(7)+= 4;\n");
1262: if (DEBUG_BRANCH)
1263: fputs(" printf(\"RTS: ->0x%X\\n\", PC);", output);
1264: pcinc = 0;
1265: break;
1266:
1267: case i_RTR:
1268: if (DEBUG_BRANCH)
1269: fputs(" printf(\"RTR: 0x%X\\n\", PC);\n", output);
1270: if (DEBUG_SR)
1271: fputs(" printf(\"SR: %08X %04X\\n\", PC, reg68k_sr.sr_int);\n",
1272: output);
1273: OUT(" SR = (SR & ~0xFF) | (fetchword(ADDRREG(7)) & 0xFF);\n");
1274: OUT(" PC = fetchlong(ADDRREG(7)+2);\n");
1275: OUT(" ADDRREG(7)+= 6;\n");
1276: if (DEBUG_BRANCH)
1277: fputs(" printf(\"RTR: ->0x%X\\n\", PC);\n", output);
1278: if (DEBUG_SR)
1279: fputs(" printf(\"SR: %08X %04X\\n\", PC, reg68k_sr.sr_int);\n",
1280: output);
1281: pcinc = 0;
1282: break;
1283:
1284: case i_JSR:
1285: generate_ea(output, iib, tp_src, 1);
1286: OUT("\n");
1287: if (DEBUG_BRANCH)
1288: fputs(" printf(\"JSR: 0x%X\\n\", PC);\n", output);
1289: OUT(" ADDRREG(7)-= 4;\n");
1290: fprintf(output, " storelong(ADDRREG(7), PC+%d);\n", (iib->wordlen)*2);
1291: OUT(" PC = srcaddr;\n");
1292: if (DEBUG_BRANCH)
1293: fputs(" printf(\"JSR: ->0x%X\\n\", PC);", output);
1294: pcinc = 0;
1295: break;
1296:
1297: case i_JMP:
1298: generate_ea(output, iib, tp_src, 1);
1299: OUT("\n");
1300: if (DEBUG_BRANCH)
1301: fputs(" printf(\"JMP: 0x%X\\n\", PC);", output);
1302: OUT(" PC = srcaddr;\n");
1303: if (DEBUG_BRANCH)
1304: fputs(" printf(\"JMP: ->0x%X\\n\", PC);\n", output);
1305: pcinc = 0;
1306: break;
1307:
1308: case i_Scc:
1309: generate_ea(output, iib, tp_src, 1);
1310: generate_cc(output, iib);
1311: generate_outdata(output, iib, "cc ? (uint8)(-1) : 0");
1312: OUT("\n");
1313: generate_eastore(output, iib, tp_src);
1314: break;
1315:
1316: case i_SF:
1317: generate_ea(output, iib, tp_src, 1);
1318: generate_outdata(output, iib, "0");
1319: OUT("\n");
1320: generate_eastore(output, iib, tp_src);
1321: break;
1322:
1323: case i_DBcc:
1324: /* special case where ipc holds the already PC-relative value */
1325: fprintf(output, " uint32 srcdata = ipc->src;\n");
1326: generate_ea(output, iib, tp_dst, 1);
1327: generate_eaval(output, iib, tp_dst);
1328: generate_cc(output, iib);
1329: fprintf(output, "\n");
1330: if (iib->size != sz_word) {
1331: OUT("ERROR size\n");
1332: }
1333: OUT(" if (!cc) {\n");
1334: OUT(" dstdata-= 1;\n");
1335: OUT(" DATAREG(dstreg) = (DATAREG(dstreg) & ~0xFFFF)\n");
1336: OUT("| (dstdata & 0xFFFF);\n");
1337: OUT(" if ((sint16)dstdata != -1)\n");
1338: OUT(" PC = srcdata;\n");
1339: OUT(" else\n");
1340: fprintf(output, " PC+= %d;\n", (iib->wordlen)*2);
1341: OUT(" } else\n");
1342: fprintf(output, " PC+= %d;\n", (iib->wordlen)*2);
1343: pcinc = 0;
1344: break;
1345:
1346: case i_DBRA:
1347: /* special case where ipc holds the already PC-relative value */
1348: fprintf(output, " uint32 srcdata = ipc->src;\n");
1349: generate_ea(output, iib, tp_dst, 1);
1350: generate_eaval(output, iib, tp_dst);
1351: OUT("\n");
1352: if (iib->size != sz_word) {
1353: OUT("ERROR size\n");
1354: }
1355: OUT(" dstdata-= 1;\n");
1356: OUT(" DATAREG(dstreg) = (DATAREG(dstreg) & ~0xFFFF) | ");
1357: OUT("(dstdata & 0xFFFF);\n");
1358: OUT(" if ((sint16)dstdata != -1)\n");
1359: OUT(" PC = srcdata;\n");
1360: OUT(" else\n");
1361: fprintf(output, " PC+= %d;\n", (iib->wordlen)*2);
1362: pcinc = 0;
1363: break;
1364:
1365: case i_Bcc:
1366: /* special case where ipc holds the already PC-relative value */
1367: OUT(" uint32 srcdata = ipc->src;\n");
1368: generate_cc(output, iib);
1369: OUT("\n");
1370: if (DEBUG_BRANCH)
1371: fputs(" printf(\"Bcc: 0x%X\\n\", PC);\n", output);
1372: OUT(" if (cc)\n");
1373: OUT(" PC = srcdata;\n");
1374: OUT(" else\n");
1375: fprintf(output, " PC+= %d;\n", (iib->wordlen)*2);
1376: if (DEBUG_BRANCH)
1377: fputs(" printf(\"Bcc: ->0x%X\\n\", PC);\n", output);
1378: pcinc = 0;
1379: break;
1380:
1381: case i_BSR:
1382: /* special case where ipc holds the already PC-relative value */
1383: OUT(" uint32 srcdata = ipc->src;\n");
1384: OUT("\n");
1385: if (DEBUG_BRANCH)
1386: fputs(" printf(\"BSR: 0x%X\\n\", PC);\n", output);
1387: OUT(" ADDRREG(7)-= 4;\n");
1388: fprintf(output, " storelong(ADDRREG(7), PC+%d);\n", (iib->wordlen)*2);
1389: OUT(" PC = srcdata;\n");
1390: if (DEBUG_BRANCH)
1391: fputs(" printf(\"BSR: ->0x%X\\n\", PC);\n", output);
1392: pcinc = 0;
1393: break;
1394:
1395: case i_DIVU:
1396: /* DIVx is the only instruction that has different sizes for the
1397: source and destination! */
1398: if (iib->dtype != dt_Dreg)
1399: OUT("ERROR dtype\n");
1400: generate_ea(output, iib, tp_src, 1);
1401: generate_eaval(output, iib, tp_src); /* 16bit EA */
1402: generate_ea(output, iib, tp_dst, 1); /* 32bit Dn */
1403: OUT(" uint32 dstdata = DATAREG(dstreg);\n");
1404: OUT(" uint32 quotient;\n");
1405: OUT("\n");
1406: OUT(" if (srcdata == 0) {\n");
1407: fprintf(output, " reg68k_internal_vector(V_ZERO, PC+%d);\n",
1408: (iib->wordlen)*2);
1409: OUT(" return;\n");
1410: OUT(" }\n");
1411: OUT(" quotient = dstdata / srcdata;\n");
1412: OUT(" if ((quotient & 0xffff0000) == 0) {\n");
1413: OUT(" DATAREG(dstreg) = quotient | ");
1414: OUT("(((uint16)(dstdata % srcdata))<<16);\n");
1415: if (flags && iib->flags.set & IIB_FLAG_V)
1416: OUT(" VFLAG = 0;\n");
1417: if (flags && iib->flags.set & IIB_FLAG_N)
1418: OUT(" NFLAG = ((sint16)quotient) < 0;\n");
1419: if (flags && iib->flags.set & IIB_FLAG_Z)
1420: OUT(" ZFLAG = !((uint16)quotient);\n");
1421: if (flags && (iib->flags.set & IIB_FLAG_V ||
1422: iib->flags.set & IIB_FLAG_N)) {
1423: OUT(" } else {\n");
1424: if (flags && iib->flags.set & IIB_FLAG_V)
1425: OUT(" VFLAG = 1;\n");
1426: if (flags && iib->flags.set & IIB_FLAG_N)
1427: OUT(" NFLAG = 1;\n");
1428: }
1429: OUT(" }\n");
1430: if (flags && iib->flags.set & IIB_FLAG_C)
1431: OUT(" CFLAG = 0;\n");
1432: break;
1433:
1434: case i_DIVS:
1435: /* DIVx is the only instruction that has different sizes for the
1436: source and destination! */
1437: if (iib->dtype != dt_Dreg)
1438: OUT("ERROR dtype\n");
1439: generate_ea(output, iib, tp_src, 1);
1440: generate_eaval(output, iib, tp_src); /* 16bit EA */
1441: generate_ea(output, iib, tp_dst, 1); /* 32bit Dn */
1442: OUT(" sint32 dstdata = DATAREG(dstreg);\n");
1443: OUT(" sint32 quotient;\n");
1444: OUT(" sint16 remainder;\n");
1445: OUT("\n");
1446: OUT(" if (srcdata == 0) {\n");
1447: fprintf(output, " reg68k_internal_vector(V_ZERO, PC+%d);\n",
1448: (iib->wordlen)*2);
1449: OUT(" return;\n");
1450: OUT(" }\n");
1451: OUT(" quotient = dstdata / (sint16)srcdata;\n");
1452: OUT(" remainder = dstdata % (sint16)srcdata;\n");
1453: OUT(" if (((quotient & 0xffff8000) == 0) ||\n");
1454: OUT(" ((quotient & 0xffff8000) == 0xffff8000)) {\n");
1455: OUT(" if ((quotient < 0) != (remainder < 0))\n");
1456: OUT(" remainder = -remainder;\n");
1457: OUT(" DATAREG(dstreg) = ((uint16)quotient) | ");
1458: OUT("(((uint16)(remainder))<<16);\n");
1459: if (flags && iib->flags.set & IIB_FLAG_V)
1460: OUT(" VFLAG = 0;\n");
1461: if (flags && iib->flags.set & IIB_FLAG_N)
1462: OUT(" NFLAG = ((sint16)quotient) < 0;\n");
1463: if (flags && iib->flags.set & IIB_FLAG_Z)
1464: OUT(" ZFLAG = !((uint16)quotient);\n");
1465: if (flags && (iib->flags.set & IIB_FLAG_V ||
1466: iib->flags.set & IIB_FLAG_N)) {
1467: OUT(" } else {\n");
1468: if (flags && iib->flags.set & IIB_FLAG_V)
1469: OUT(" VFLAG = 1;\n");
1470: if (flags && iib->flags.set & IIB_FLAG_N)
1471: OUT(" NFLAG = 1;\n");
1472: }
1473: OUT(" }\n");
1474: if (flags && iib->flags.set & IIB_FLAG_C)
1475: OUT(" CFLAG = 0;\n");
1476: break;
1477:
1478: case i_ASR:
1479: generate_ea(output, iib, tp_src, 1);
1480: generate_eaval(output, iib, tp_src);
1481: generate_ea(output, iib, tp_dst, 1);
1482: generate_eaval(output, iib, tp_dst);
1483: generate_bits(output, iib);
1484: OUT(" uint8 count = srcdata & 63;\n");
1485: switch (iib->size) {
1486: case sz_byte:
1487: generate_outdata(output, iib, "((sint8)dstdata) >> "
1488: "(count > 7 ? 7 : count)");
1489: break;
1490: case sz_word:
1491: generate_outdata(output, iib, "((sint16)dstdata) >> "
1492: "(count > 15 ? 15 : count)");
1493: break;
1494: case sz_long:
1495: generate_outdata(output, iib, "((sint32)dstdata) >> "
1496: "(count > 31 ? 31 : count)");
1497: break;
1498: default:
1499: OUT("ERROR size\n");
1500: break;
1501: }
1502: OUT("\n");
1503: generate_eastore(output, iib, tp_dst);
1504: if (flags) {
1505: OUT("\n");
1506: OUT(" if (!srcdata)\n");
1507: if (iib->flags.set & IIB_FLAG_C)
1508: OUT(" CFLAG = 0;\n");
1509: OUT(" else if (srcdata >= bits) {\n");
1510: if (iib->flags.set & IIB_FLAG_C)
1511: OUT(" CFLAG = dstdata>>(bits-1);\n");
1512: if (iib->flags.set & IIB_FLAG_X)
1513: OUT(" XFLAG = dstdata>>(bits-1);\n");
1514: OUT(" } else {\n");
1515: if (iib->flags.set & IIB_FLAG_C)
1516: OUT(" CFLAG = dstdata>>(count-1) & 1;\n");
1517: if (iib->flags.set & IIB_FLAG_X)
1518: OUT(" XFLAG = dstdata>>(count-1) & 1;\n");
1519: OUT(" }\n");
1520: if (iib->flags.set & IIB_FLAG_V)
1521: generate_clrflag_v(output, iib);
1522: if (iib->flags.set & IIB_FLAG_N)
1523: generate_stdflag_n(output, iib);
1524: if (iib->flags.set & IIB_FLAG_Z)
1525: generate_stdflag_z(output, iib);
1526: }
1527: break;
1528:
1529: case i_LSR:
1530: generate_ea(output, iib, tp_src, 1);
1531: generate_eaval(output, iib, tp_src);
1532: generate_ea(output, iib, tp_dst, 1);
1533: generate_eaval(output, iib, tp_dst);
1534: generate_bits(output, iib);
1535: OUT(" uint8 count = srcdata & 63;\n");
1536: generate_outdata(output, iib,
1537: "dstdata >> (count > (bits-1) ? (bits-1) : count)");
1538: OUT("\n");
1539: generate_eastore(output, iib, tp_dst);
1540: if (flags) {
1541: OUT("\n");
1542: OUT(" if (!count)\n");
1543: if (iib->flags.set & IIB_FLAG_C)
1544: OUT(" CFLAG = 0;\n");
1545: OUT(" else if (count >= bits) {\n");
1546: if (iib->flags.set & IIB_FLAG_C)
1547: OUT(" CFLAG = (count == bits) ? dstdata>>(bits-1) : 0;\n");
1548: if (iib->flags.set & IIB_FLAG_X)
1549: OUT(" XFLAG = (count == bits) ? dstdata>>(bits-1) : 0;\n");
1550: OUT(" } else {\n");
1551: if (iib->flags.set & IIB_FLAG_C)
1552: OUT(" CFLAG = dstdata>>(count-1) & 1;\n");
1553: if (iib->flags.set & IIB_FLAG_X)
1554: OUT(" XFLAG = dstdata>>(count-1) & 1;\n");
1555: OUT(" }\n");
1556: if (iib->flags.set & IIB_FLAG_V)
1557: generate_clrflag_v(output, iib);
1558: if (iib->flags.set & IIB_FLAG_N)
1559: generate_stdflag_n(output, iib);
1560: if (iib->flags.set & IIB_FLAG_Z)
1561: generate_stdflag_z(output, iib);
1562: }
1563: break;
1564:
1565: case i_ASL:
1566: generate_ea(output, iib, tp_src, 1);
1567: generate_eaval(output, iib, tp_src);
1568: generate_ea(output, iib, tp_dst, 1);
1569: generate_eaval(output, iib, tp_dst);
1570: generate_bits(output, iib);
1571: OUT(" uint8 count = srcdata & 63;\n");
1572: generate_outdata(output, iib,
1573: "count >= bits ? 0 : (dstdata << count)");
1574: OUT("\n");
1575: generate_eastore(output, iib, tp_dst);
1576: if (flags) {
1577: OUT("\n");
1578: OUT(" if (!count)\n");
1579: if (iib->flags.set & IIB_FLAG_C)
1580: OUT(" CFLAG = 0;\n");
1581: OUT(" else if (count >= bits) {\n");
1582: if (iib->flags.set & IIB_FLAG_C)
1583: OUT(" CFLAG = (count == bits) ? dstdata & 1 : 0;\n");
1584: if (iib->flags.set & IIB_FLAG_X)
1585: OUT(" XFLAG = (count == bits) ? dstdata & 1 : 0;\n");
1586: if (iib->flags.set & IIB_FLAG_V)
1587: OUT(" VFLAG = !dstdata;\n");
1588: OUT(" } else {\n");
1589: if (iib->flags.set & IIB_FLAG_C)
1590: OUT(" CFLAG = dstdata>>(bits-count) & 1;\n");
1591: if (iib->flags.set & IIB_FLAG_X)
1592: OUT(" XFLAG = dstdata>>(bits-count) & 1;\n");
1593: if (iib->flags.set & IIB_FLAG_V) {
1594: OUT(" {\n");
1595: switch (iib->size) {
1596: case sz_byte:
1597: OUT(" uint8 mask = 0xff << (7-count);\n")
1598: break;
1599: case sz_word:
1600: OUT(" uint16 mask = 0xffff << (15-count);\n");
1601: break;
1602: case sz_long:
1603: OUT(" uint32 mask = 0xffffffff <<(31-count);\n");
1604: break;
1605: default:
1606: OUT("ERROR size\n");
1607: break;
1608: }
1609: OUT(" VFLAG = ((dstdata & mask) != mask) && ");
1610: OUT("((dstdata & mask) != 0);\n");
1611: OUT(" }\n");
1612: OUT(" }\n");
1613: }
1614: if (iib->flags.set & IIB_FLAG_N)
1615: generate_stdflag_n(output, iib);
1616: if (iib->flags.set & IIB_FLAG_Z)
1617: generate_stdflag_z(output, iib);
1618: }
1619: break;
1620:
1621: case i_LSL:
1622: generate_ea(output, iib, tp_src, 1);
1623: generate_eaval(output, iib, tp_src);
1624: generate_ea(output, iib, tp_dst, 1);
1625: generate_eaval(output, iib, tp_dst);
1626: generate_bits(output, iib);
1627: OUT(" uint8 count = srcdata & 63;\n");
1628: generate_outdata(output, iib,
1629: "count >= bits ? 0 : (dstdata << count)");
1630: OUT("\n");
1631: generate_eastore(output, iib, tp_dst);
1632: if (flags) {
1633: OUT("\n");
1634: OUT(" if (!count)\n");
1635: if (iib->flags.set & IIB_FLAG_C)
1636: OUT(" CFLAG = 0;\n");
1637: OUT(" else if (count >= bits) {\n");
1638: if (iib->flags.set & IIB_FLAG_C)
1639: OUT(" CFLAG = (count == bits) ? dstdata & 1 : 0;\n");
1640: if (iib->flags.set & IIB_FLAG_X)
1641: OUT(" XFLAG = (count == bits) ? dstdata & 1 : 0;\n");
1642: OUT(" } else {\n");
1643: if (iib->flags.set & IIB_FLAG_C)
1644: OUT(" CFLAG = dstdata>>(bits-count) & 1;\n");
1645: if (iib->flags.set & IIB_FLAG_X)
1646: OUT(" XFLAG = dstdata>>(bits-count) & 1;\n");
1647: OUT(" }\n");
1648: if (iib->flags.set & IIB_FLAG_V)
1649: generate_clrflag_v(output, iib);
1650: if (iib->flags.set & IIB_FLAG_N)
1651: generate_stdflag_n(output, iib);
1652: if (iib->flags.set & IIB_FLAG_Z)
1653: generate_stdflag_z(output, iib);
1654: }
1655: break;
1656:
1657: /* 64 */
1658:
1659: case i_ROXR:
1660: case i_ROXL:
1661: generate_ea(output, iib, tp_src, 1);
1662: generate_eaval(output, iib, tp_src);
1663: generate_ea(output, iib, tp_dst, 1);
1664: generate_eaval(output, iib, tp_dst);
1665: generate_bits(output, iib);
1666: OUT(" uint8 loop = srcdata & 63;\n");
1667: OUT(" uint8 cflag = CFLAG;\n");
1668: OUT(" uint8 xflag = XFLAG;\n");
1669: generate_outdata(output, iib, "dstdata");
1670: OUT("\n");
1671: if (iib->mnemonic == i_ROXR) {
1672: OUT(" while(loop) {\n");
1673: OUT(" cflag = outdata & 1;\n");
1674: OUT(" outdata>>= 1;\n");
1675: OUT(" if (xflag)\n");
1676: OUT(" outdata |= 1<<(bits-1);\n");
1677: OUT(" xflag = cflag;\n");
1678: OUT(" loop--;\n");
1679: OUT(" }\n");
1680: } else {
1681: OUT(" while(loop) {\n");
1682: OUT(" cflag = outdata & 1<<(bits-1) ? 1 : 0;\n");
1683: OUT(" outdata<<= 1;\n");
1684: OUT(" outdata |= xflag;\n");
1685: OUT(" xflag = cflag;\n");
1686: OUT(" loop--;\n");
1687: OUT(" }\n");
1688: }
1689: generate_eastore(output, iib, tp_dst);
1690: if (flags)
1691: OUT("\n");
1692: if (flags && iib->flags.set & IIB_FLAG_X)
1693: OUT(" XFLAG = xflag;\n");
1694: if (flags && iib->flags.set & IIB_FLAG_C)
1695: OUT(" CFLAG = xflag;\n");
1696: if (flags && iib->flags.set & IIB_FLAG_N)
1697: generate_stdflag_n(output, iib);
1698: if (flags && iib->flags.set & IIB_FLAG_Z)
1699: generate_stdflag_z(output, iib);
1700: if (flags && iib->flags.set & IIB_FLAG_V)
1701: generate_clrflag_v(output, iib);
1702: break;
1703:
1704: case i_ROR:
1705: case i_ROL:
1706: generate_ea(output, iib, tp_src, 1);
1707: generate_eaval(output, iib, tp_src);
1708: generate_ea(output, iib, tp_dst, 1);
1709: generate_eaval(output, iib, tp_dst);
1710: generate_bits(output, iib);
1711: OUT(" uint8 loop = srcdata & 63;\n");
1712: OUT(" uint8 cflag = 0;\n");
1713: generate_outdata(output, iib, "dstdata");
1714: OUT("\n");
1715: if (iib->mnemonic == i_ROR) {
1716: OUT(" while(loop) {\n");
1717: OUT(" cflag = outdata & 1;\n");
1718: OUT(" outdata>>= 1;\n");
1719: OUT(" if (cflag)\n");
1720: OUT(" outdata |= 1<<(bits-1);\n");
1721: OUT(" loop--;\n");
1722: OUT(" }\n");
1723: } else {
1724: OUT(" while(loop) {\n");
1725: OUT(" cflag = outdata & 1<<(bits-1) ? 1 : 0;\n");
1726: OUT(" outdata<<= 1;\n");
1727: OUT(" if (cflag)\n");
1728: OUT(" outdata |= 1;\n");
1729: OUT(" loop--;\n");
1730: OUT(" }\n");
1731: }
1732: generate_eastore(output, iib, tp_dst);
1733: if (flags)
1734: OUT("\n");
1735: if (flags && iib->flags.set & IIB_FLAG_C)
1736: OUT(" CFLAG = cflag;\n");
1737: if (flags && iib->flags.set & IIB_FLAG_N)
1738: generate_stdflag_n(output, iib);
1739: if (flags && iib->flags.set & IIB_FLAG_Z)
1740: generate_stdflag_z(output, iib);
1741: if (flags && iib->flags.set & IIB_FLAG_V)
1742: generate_clrflag_v(output, iib);
1743: break;
1744:
1745: case i_LINE10:
1746: OUT("\n");
1747: fprintf(output, " reg68k_internal_vector(V_LINE10, PC);\n");
1748: pcinc = 0;
1749: break;
1750:
1751: case i_LINE15:
1752: OUT("\n");
1753: fprintf(output, " reg68k_internal_vector(V_LINE15, PC);\n");
1754: pcinc = 0;
1755: break;
1756:
1757: case i_ILLG:
1758: OUT(" printf(\"Illegal instruction @ %x\\n\", PC);\n");
1759: OUT(" exit(1);\n");
1760: break;
1761:
1762: } /* switch */
1763:
1764: if (pcinc) {
1765: fprintf(output, " PC+= %d;\n", (iib->wordlen)*2);
1766: }
1767:
1768: OUT("}\n\n");
1769: }
1770:
1771: }
1772: }
1773:
1774: void generate_ea(FILE *o, t_iib *iib, t_type type, int update)
1775: {
1776: t_datatype datatype = type ? iib->dtype : iib->stype;
1777:
1778: /* generate information about EA to be used in calculations */
1779:
1780: switch(datatype) {
1781: case dt_Dreg:
1782: case dt_Areg:
1783: case dt_Aind:
1784: case dt_Ainc:
1785: case dt_Adec:
1786: case dt_Adis:
1787: case dt_Aidx:
1788: if (type == tp_src)
1789: fprintf(o, " int srcreg = (ipc->opcode >> %d) & 7;\n", iib->sbitpos);
1790: else
1791: fprintf(o, " int dstreg = (ipc->opcode >> %d) & 7;\n", iib->dbitpos);
1792: break;
1793: default:
1794: break;
1795: }
1796:
1797: if (datatype == dt_Ainc && update) {
1798:
1799: /* Ainc and update */
1800:
1801: switch(iib->size) {
1802: case sz_byte:
1803: if (type == tp_src) {
1804: fprintf(o, " uint32 srcaddr = ADDRREG(srcreg);\n");
1805: fprintf(o, " uint32 srcaddr_tmp = (ADDRREG(srcreg)+= "
1806: "(srcreg == 7 ? 2 : 1), 0);\n");
1807: } else {
1808: fprintf(o, " uint32 dstaddr = ADDRREG(dstreg);\n");
1809: fprintf(o, " uint32 dstaddr_tmp = (ADDRREG(dstreg)+= "
1810: "(dstreg == 7 ? 2 : 1), 0);\n");
1811: }
1812: break;
1813: case sz_word:
1814: if (type == tp_src)
1815: fprintf(o, " uint32 srcaddr = (ADDRREG(srcreg)+=2, "
1816: "ADDRREG(srcreg)-2);\n");
1817: else
1818: fprintf(o, " uint32 dstaddr = (ADDRREG(dstreg)+=2, "
1819: "ADDRREG(dstreg)-2);\n");
1820: break;
1821: case sz_long:
1822: if (type == tp_src)
1823: fprintf(o, " uint32 srcaddr = (ADDRREG(srcreg)+=4, "
1824: "ADDRREG(srcreg)-4);\n");
1825: else
1826: fprintf(o, " uint32 dstaddr = (ADDRREG(dstreg)+=4, "
1827: "ADDRREG(dstreg)-4);\n");
1828: break;
1829: default:
1830: fprintf(o, "ERROR size\n");
1831: break;
1832: }
1833:
1834: } else if (datatype == dt_Adec && update) {
1835:
1836: /* Adec and update */
1837:
1838: switch(iib->size) {
1839: case sz_byte:
1840: if (type == tp_src) {
1841: fprintf(o, " uint32 srcaddr = (ADDRREG(srcreg)-= "
1842: "(srcreg == 7 ? 2 : 1));\n");
1843: } else {
1844: fprintf(o, " uint32 dstaddr = (ADDRREG(dstreg)-= "
1845: "(dstreg == 7 ? 2 : 1));\n");
1846: }
1847: break;
1848: case sz_word:
1849: if (type == tp_src)
1850: fprintf(o, " uint32 srcaddr = ADDRREG(srcreg)-=2;\n");
1851: else
1852: fprintf(o, " uint32 dstaddr = ADDRREG(dstreg)-=2;\n");
1853: break;
1854: case sz_long:
1855: if (type == tp_src)
1856: fprintf(o, " uint32 srcaddr = ADDRREG(srcreg)-=4;\n");
1857: else
1858: fprintf(o, " uint32 dstaddr = ADDRREG(dstreg)-=4;\n");
1859: break;
1860: default:
1861: fprintf(o, "ERROR size\n");
1862: break;
1863: }
1864:
1865: } else {
1866:
1867: /* no update required */
1868:
1869: switch(datatype) {
1870: case dt_Dreg:
1871: case dt_Areg:
1872: break;
1873: case dt_Aind:
1874: case dt_Adec:
1875: case dt_Ainc:
1876: if (type == tp_src)
1877: fprintf(o, " uint32 srcaddr = ADDRREG(srcreg);\n");
1878: else
1879: fprintf(o, " uint32 dstaddr = ADDRREG(dstreg);\n");
1880: break;
1881: case dt_Adis:
1882: if (type == tp_src)
1883: fprintf(o, " uint32 srcaddr = (sint32)ADDRREG(srcreg) + "
1884: "(sint32)(sint16)ipc->src;\n");
1885: else
1886: fprintf(o, " uint32 dstaddr = (sint32)ADDRREG(dstreg) + "
1887: "(sint32)(sint16)ipc->dst;\n");
1888: break;
1889: case dt_Aidx:
1890: if (type == tp_src) {
1891: fprintf(o, " uint32 srcaddr = (sint32)ADDRREG(srcreg) + "
1892: "idxval_src(ipc);\n");
1893: } else {
1894: fprintf(o, " uint32 dstaddr = (sint32)ADDRREG(dstreg) + "
1895: "idxval_dst(ipc);\n");
1896: }
1897: break;
1898: case dt_AbsW:
1899: case dt_AbsL:
1900: case dt_Pdis:
1901: if (type == tp_src)
1902: fprintf(o, " uint32 srcaddr = ipc->src;\n");
1903: else
1904: fprintf(o, " uint32 dstaddr = ipc->dst;\n");
1905: break;
1906: case dt_Pidx:
1907: if (type == tp_src) {
1908: fprintf(o, " uint32 srcaddr = idxval_src(ipc);\n");
1909: } else {
1910: fprintf(o, " uint32 dstaddr = idxval_dst(ipc);\n");
1911: }
1912: break;
1913: case dt_ImmB:
1914: case dt_ImmW:
1915: case dt_ImmL:
1916: case dt_ImmS:
1917: case dt_Imm3:
1918: case dt_Imm4:
1919: case dt_Imm8:
1920: case dt_Imm8s:
1921: /* no address - it is immediate */
1922: break;
1923: default:
1924: fprintf(o, "ERROR\n");
1925: break;
1926: }
1927: }
1928: }
1929:
1930: void generate_eaval(FILE *o, t_iib *iib, t_type type)
1931: {
1932: t_datatype datatype = type ? iib->dtype : iib->stype;
1933:
1934: /* get value in EA */
1935:
1936: switch(datatype) {
1937: case dt_Dreg:
1938: switch(iib->size) {
1939: case sz_byte:
1940: if (type == tp_src)
1941: fprintf(o, " uint8 srcdata = DATAREG(srcreg);\n");
1942: else
1943: fprintf(o, " uint8 dstdata = DATAREG(dstreg);\n");
1944: break;
1945: case sz_word:
1946: if (type == tp_src)
1947: fprintf(o, " uint16 srcdata = DATAREG(srcreg);\n");
1948: else
1949: fprintf(o, " uint16 dstdata = DATAREG(dstreg);\n");
1950: break;
1951: case sz_long:
1952: if (type == tp_src)
1953: fprintf(o, " uint32 srcdata = DATAREG(srcreg);\n");
1954: else
1955: fprintf(o, " uint32 dstdata = DATAREG(dstreg);\n");
1956: break;
1957: default:
1958: fprintf(o, "ERROR size\n");
1959: break;
1960: }
1961: break;
1962: case dt_Areg:
1963: switch(iib->size) {
1964: case sz_byte:
1965: if (type == tp_src)
1966: fprintf(o, " uint8 srcdata = ADDRREG(srcreg);\n");
1967: else
1968: fprintf(o, " uint8 dstdata = ADDRREG(dstreg);\n");
1969: break;
1970: case sz_word:
1971: if (type == tp_src)
1972: fprintf(o, " uint16 srcdata = ADDRREG(srcreg);\n");
1973: else
1974: fprintf(o, " uint16 dstdata = ADDRREG(dstreg);\n");
1975: break;
1976: case sz_long:
1977: if (type == tp_src)
1978: fprintf(o, " uint32 srcdata = ADDRREG(srcreg);\n");
1979: else
1980: fprintf(o, " uint32 dstdata = ADDRREG(dstreg);\n");
1981: break;
1982: default:
1983: fprintf(o, "ERROR size\n");
1984: break;
1985: }
1986: break;
1987: case dt_Aind:
1988: case dt_Adec:
1989: case dt_Ainc:
1990: case dt_Adis:
1991: case dt_Aidx:
1992: case dt_AbsW:
1993: case dt_AbsL:
1994: case dt_Pdis:
1995: case dt_Pidx:
1996: switch(iib->size) {
1997: case sz_byte:
1998: if (type == tp_src)
1999: fprintf(o, " uint8 srcdata = fetchbyte(srcaddr);\n");
2000: else
2001: fprintf(o, " uint8 dstdata = fetchbyte(dstaddr);\n");
2002: break;
2003: case sz_word:
2004: if (type == tp_src)
2005: fprintf(o, " uint16 srcdata = fetchword(srcaddr);\n");
2006: else
2007: fprintf(o, " uint16 dstdata = fetchword(dstaddr);\n");
2008: break;
2009: case sz_long:
2010: if (type == tp_src)
2011: fprintf(o, " uint32 srcdata = fetchlong(srcaddr);\n");
2012: else
2013: fprintf(o, " uint32 dstdata = fetchlong(dstaddr);\n");
2014: break;
2015: default:
2016: fprintf(o, "ERROR size\n");
2017: break;
2018: }
2019: break;
2020: case dt_ImmB:
2021: if (type == tp_src)
2022: fprintf(o, " uint8 srcdata = ipc->src;\n");
2023: else
2024: fprintf(o, " uint8 dstdata = ipc->dst;\n");
2025: break;
2026: case dt_ImmW:
2027: if (type == tp_src)
2028: fprintf(o, " uint16 srcdata = ipc->src;\n");
2029: else
2030: fprintf(o, " uint16 dstdata = ipc->dst;\n");
2031: break;
2032: case dt_ImmL:
2033: if (type == tp_src)
2034: fprintf(o, " uint32 srcdata = ipc->src;\n");
2035: else
2036: fprintf(o, " uint32 dstdata = ipc->dst;\n");
2037: break;
2038: case dt_ImmS:
2039: if (type == tp_src)
2040: fprintf(o, " unsigned int srcdata = %d;\n", iib->immvalue);
2041: else
2042: fprintf(o, " unsigned int dstdata = %d;\n", iib->immvalue);
2043: break;
2044: case dt_Imm3:
2045: case dt_Imm4:
2046: case dt_Imm8:
2047: if (type == tp_src)
2048: fprintf(o, " unsigned int srcdata = ipc->src;\n");
2049: else
2050: fprintf(o, " unsigned int dstdata = ipc->dst;\n");
2051: break;
2052: case dt_Imm8s:
2053: if (type == tp_src)
2054: fprintf(o, " signed int srcdata = ipc->src;\n");
2055: else
2056: fprintf(o, " signed int dstdata = ipc->dst;\n");
2057: break;
2058: default:
2059: fprintf(o, "ERROR\n");
2060: }
2061: }
2062:
2063: void generate_eastore(FILE *o, t_iib *iib, t_type type)
2064: {
2065: /* get value in EA */
2066:
2067: switch(type == tp_dst ? iib->dtype : iib->stype) {
2068: case dt_Dreg:
2069: switch (iib->size) {
2070: case sz_byte:
2071: if (type == tp_src)
2072: fprintf(o, " DATAREG(srcreg) = (DATAREG(srcreg) & ~0xff) | "
2073: "outdata;\n");
2074: else
2075: fprintf(o, " DATAREG(dstreg) = (DATAREG(dstreg) & ~0xff) | "
2076: "outdata;\n");
2077: break;
2078: case sz_word:
2079: if (type == tp_src)
2080: fprintf(o, " DATAREG(srcreg) = (DATAREG(srcreg) & ~0xffff) | "
2081: "outdata;\n");
2082: else
2083: fprintf(o, " DATAREG(dstreg) = (DATAREG(dstreg) & ~0xffff) | "
2084: "outdata;\n");
2085: break;
2086: case sz_long:
2087: if (type == tp_src)
2088: fprintf(o, " DATAREG(srcreg) = outdata;\n");
2089: else
2090: fprintf(o, " DATAREG(dstreg) = outdata;\n");
2091: break;
2092: default:
2093: fprintf(o, "ERROR size\n");
2094: break;
2095: }
2096: break;
2097: case dt_Areg:
2098: switch(iib->size) {
2099: case sz_byte:
2100: if (type == tp_src)
2101: fprintf(o, " ADDRREG(srcreg) = (ADDRREG(srcreg) & ~0xff) | "
2102: "outdata;\n");
2103: else
2104: fprintf(o, " ADDRREG(dstreg) = (ADDRREG(dstreg) & ~0xff) | "
2105: "outdata;\n");
2106: break;
2107: case sz_word:
2108: if (type == tp_src)
2109: fprintf(o, " ADDRREG(srcreg) = (ADDRREG(srcreg) & ~0xffff) | "
2110: "outdata;\n");
2111: else
2112: fprintf(o, " ADDRREG(dstreg) = (ADDRREG(dstreg) & ~0xffff) | "
2113: "outdata;\n");
2114: break;
2115: case sz_long:
2116: if (type == tp_src)
2117: fprintf(o, " ADDRREG(srcreg) = outdata;\n");
2118: else
2119: fprintf(o, " ADDRREG(dstreg) = outdata;\n");
2120: break;
2121: default:
2122: fprintf(o, "ERROR size\n");
2123: break;
2124: }
2125: break;
2126: case dt_Aind:
2127: case dt_Ainc:
2128: case dt_Adec:
2129: case dt_Adis:
2130: case dt_Aidx:
2131: case dt_AbsW:
2132: case dt_AbsL:
2133: case dt_Pdis:
2134: case dt_Pidx:
2135: switch(iib->size) {
2136: case sz_byte:
2137: if (type == tp_src)
2138: fprintf(o, " storebyte(srcaddr, outdata);\n");
2139: else
2140: fprintf(o, " storebyte(dstaddr, outdata);\n");
2141: break;
2142: case sz_word:
2143: if (type == tp_src)
2144: fprintf(o, " storeword(srcaddr, outdata);\n");
2145: else
2146: fprintf(o, " storeword(dstaddr, outdata);\n");
2147: break;
2148: case sz_long:
2149: if (type == tp_src)
2150: fprintf(o, " storelong(srcaddr, outdata);\n");
2151: else
2152: fprintf(o, " storelong(dstaddr, outdata);\n");
2153: break;
2154: default:
2155: fprintf(o, "ERROR size\n");
2156: }
2157: break;
2158: default:
2159: fprintf(o, "ERROR type\n");
2160: }
2161: }
2162:
2163: void generate_outdata(FILE *o, t_iib *iib, const char *init)
2164: {
2165: switch(iib->size) {
2166: case sz_byte:
2167: fprintf(o, " uint8 ");
2168: break;
2169: case sz_word:
2170: fprintf(o, " uint16 ");
2171: break;
2172: case sz_long:
2173: fprintf(o, " uint32 ");
2174: break;
2175: default:
2176: fprintf(o, "ERROR size\n");
2177: break;
2178: }
2179: fprintf(o, "outdata%s%s;\n", (init && init[0]) ? " = " : "",
2180: init ? init : "");
2181: }
2182:
2183: void generate_cc(FILE *o, t_iib *iib)
2184: {
2185: switch(iib->cc) {
2186: case 0: /* T */
2187: fprintf(o, " uint8 cc = 1;\n");
2188: break;
2189: case 1: /* F */
2190: fprintf(o, " uint8 cc = 0;\n");
2191: break;
2192: case 2: /* HI */
2193: fprintf(o, " uint8 cc = !(CFLAG || ZFLAG);\n");
2194: break;
2195: case 3: /* LS */
2196: fprintf(o, " uint8 cc = CFLAG || ZFLAG;\n");
2197: break;
2198: case 4: /* CC */
2199: fprintf(o, " uint8 cc = !CFLAG;\n");
2200: break;
2201: case 5: /* CS */
2202: fprintf(o, " uint8 cc = CFLAG;\n");
2203: break;
2204: case 6: /* NE */
2205: fprintf(o, " uint8 cc = !ZFLAG;\n");
2206: break;
2207: case 7: /* EQ */
2208: fprintf(o, " uint8 cc = ZFLAG;\n");
2209: break;
2210: case 8: /* VC */
2211: fprintf(o, " uint8 cc = !VFLAG;\n");
2212: break;
2213: case 9: /* VS */
2214: fprintf(o, " uint8 cc = VFLAG;\n");
2215: break;
2216: case 10: /* PL */
2217: fprintf(o, " uint8 cc = !NFLAG;\n");
2218: break;
2219: case 11: /* MI */
2220: fprintf(o, " uint8 cc = NFLAG;\n");
2221: break;
2222: case 12: /* GE */
2223: fprintf(o, " uint8 cc = (NFLAG == VFLAG);\n");
2224: break;
2225: case 13: /* LT */
2226: fprintf(o, " uint8 cc = (NFLAG != VFLAG);\n");
2227: break;
2228: case 14: /* GT */
2229: fprintf(o, " uint8 cc = !ZFLAG && (NFLAG == VFLAG);\n");
2230: break;
2231: case 15: /* LE */
2232: fprintf(o, " uint8 cc = ZFLAG || (NFLAG != VFLAG);\n");
2233: break;
2234: default:
2235: fprintf(o, "ERROR cc\n");
2236: break;
2237: }
2238: }
2239:
2240: void generate_stdflag_n(FILE *o, t_iib *iib)
2241: {
2242: switch(iib->size) {
2243: case sz_byte:
2244: fprintf(o, " NFLAG = ((sint8)outdata) < 0;\n");
2245: break;
2246: case sz_word:
2247: fprintf(o, " NFLAG = ((sint16)outdata) < 0;\n");
2248: break;
2249: case sz_long:
2250: fprintf(o, " NFLAG = ((sint32)outdata) < 0;\n");
2251: break;
2252: default:
2253: fprintf(o, "ERROR size\n");
2254: break;
2255: }
2256: }
2257:
2258: void generate_stdflag_z(FILE *o, t_iib *iib)
2259: {
2260: fprintf(o, " ZFLAG = !outdata;\n");
2261: }
2262:
2263: void generate_clrflag_v(FILE *o, t_iib *iib)
2264: {
2265: fprintf(o, " VFLAG = 0;\n");
2266: }
2267:
2268: void generate_clrflag_c(FILE *o, t_iib *iib)
2269: {
2270: fprintf(o, " CFLAG = 0;\n");
2271: }
2272:
2273: void generate_clrflag_n(FILE *o, t_iib *iib)
2274: {
2275: fprintf(o, " NFLAG = 0;\n");
2276: }
2277:
2278: void generate_setflag_z(FILE *o, t_iib *iib)
2279: {
2280: fprintf(o, " ZFLAG = 1;\n");
2281: }
2282:
2283: void generate_subflag_c(FILE *o, t_iib *iib)
2284: {
2285: /* C = (Sm && !Dm) || (Rm && !Dm) || (Sm && Rm)
2286: carry is performed as if both source and destination are unsigned,
2287: so this is simply if the source is greater than the destination - I
2288: have proven this to be the case using a truth table and the above
2289: motorola definition */
2290: fprintf(o, " CFLAG = srcdata > dstdata;\n");
2291: }
2292:
2293: void generate_subflag_cx(FILE *o, t_iib *iib)
2294: {
2295: /* C = (Sm && !Dm) || (Rm && !Dm) || (Sm && Rm)
2296: carry is performed as if both source and destination are unsigned,
2297: so this is simply if the source is greater than the destination - I
2298: have proven this to be the case using a truth table and the above
2299: motorola definition */
2300: fprintf(o, " XFLAG = CFLAG = srcdata > dstdata;\n");
2301: }
2302:
2303: void generate_subxflag_cx(FILE *o, t_iib *iib)
2304: {
2305: /* V = (Sm && !Dm) || (Rm && (!Dm || Sm)) */
2306: fprintf(o, " {\n");
2307: switch(iib->size) {
2308: case sz_byte:
2309: fprintf(o, " int Sm = (sint8)srcdata < 0;\n");
2310: fprintf(o, " int Dm = (sint8)dstdata < 0;\n");
2311: fprintf(o, " int Rm = (sint8)outdata < 0;\n");
2312: break;
2313: case sz_word:
2314: fprintf(o, " int Sm = (sint16)srcdata < 0;\n");
2315: fprintf(o, " int Dm = (sint16)dstdata < 0;\n");
2316: fprintf(o, " int Rm = (sint16)outdata < 0;\n");
2317: break;
2318: case sz_long:
2319: fprintf(o, " int Sm = (sint32)srcdata < 0;\n");
2320: fprintf(o, " int Dm = (sint32)dstdata < 0;\n");
2321: fprintf(o, " int Rm = (sint32)outdata < 0;\n");
2322: break;
2323: default:
2324: fprintf(o, "ERROR size\n");
2325: break;
2326: }
2327: fprintf(o, " XFLAG = CFLAG = (Sm && !Dm) || (Rm && (!Dm || Sm));\n");
2328: fprintf(o, " }\n");
2329: }
2330:
2331: void generate_cmpaflag_c(FILE *o, t_iib *iib)
2332: {
2333: /* see generate_subflag_c - this is just the same but with a sign extend
2334: on the source */
2335: fprintf(o, " CFLAG = (uint32)(sint32)(sint16)srcdata > dstdata;\n");
2336: }
2337:
2338: void generate_subflag_v(FILE *o, t_iib *iib)
2339: {
2340: /* V = (!Sm && Dm && !Rm) || (Sm && !Dm && Rm)
2341: overflow is performed as if both source and destination are signed,
2342: the only two condtions are if we've added too much to a +ve number
2343: or we've subtracted too much from a -ve number - I have proven the
2344: this to be the case using a truth table and the above motorola
2345: definition */
2346: /* the technique to implement the above formula is to make sure the sign
2347: of Sm != the sign of Dm, and the sign of Dm != the sign of Rm. */
2348: switch(iib->size) {
2349: case sz_byte:
2350: fprintf(o, " VFLAG = (((sint8)srcdata < 0) != ((sint8)dstdata < 0)) ");
2351: fprintf(o, "&&\n (((sint8)dstdata < 0) != ((sint8)outdata < 0));\n");
2352: break;
2353: case sz_word:
2354: fprintf(o, " VFLAG = (((sint16)srcdata < 0) != ((sint16)dstdata < 0)) ");
2355: fprintf(o, "&&\n (((sint16)dstdata < 0) != ((sint16)outdata < 0));\n");
2356: break;
2357: case sz_long:
2358: fprintf(o, " VFLAG = (((sint32)srcdata < 0) != ((sint32)dstdata < 0)) ");
2359: fprintf(o, "&&\n (((sint32)dstdata < 0) != ((sint32)outdata < 0));\n");
2360: break;
2361: default:
2362: fprintf(o, "ERROR size\n");
2363: break;
2364: }
2365: }
2366:
2367: void generate_cmpaflag_v(FILE *o, t_iib *iib)
2368: {
2369: /* see generate_subflag_v - this is just the sz_long version with a sign
2370: extend on the source */
2371: fprintf(o, " VFLAG = (((sint32)(sint16)srcdata < 0) != ");
2372: fprintf(o, "((sint32)dstdata < 0)) ");
2373: fprintf(o, "&&\n (((sint32)dstdata < 0) != ((sint32)outdata < 0));\n");
2374: }
2375:
2376: void generate_stdxflag_z(FILE *o, t_iib *iib)
2377: {
2378: fprintf(o, " if (outdata) ZFLAG = 0;\n");
2379: }
2380:
2381: void generate_addflag_cx(FILE *o, t_iib *iib)
2382: {
2383: /* C = (Sm && Dm) || (!Rm && Dm) || (Sm && !Rm)
2384: carry is performed as if both source and destination are unsigned,
2385: so this is simply if the source is bigger than how much can be added
2386: to the destination without wrapping - this is of course just the bit
2387: inverse of the destination. */
2388: /* 0xFFFF - dstdata is obviously just ~dstdata, but try and get the
2389: compiler to do that without producing a warning, go on... */
2390: switch (iib->size) {
2391: case sz_byte:
2392: fprintf(o, " XFLAG = CFLAG = srcdata > (0xFFu - (uint8)dstdata);\n");
2393: break;
2394: case sz_word:
2395: fprintf(o, " XFLAG = CFLAG = srcdata > (0xFFFFu - (uint16)dstdata);\n");
2396: break;
2397: case sz_long:
2398: fprintf(o, " XFLAG = CFLAG = srcdata > (uint32)~(uint32)dstdata;\n");
2399: break;
2400: default:
2401: fprintf(o, "ERROR size\n");
2402: break;
2403: }
2404: /* gcc doesn't like a one's compliment of an unsigned - take out the
2405: casts in the above and it will warn you incorrectly */
2406: }
2407:
2408: void generate_addxflag_cx(FILE *o, t_iib *iib)
2409: {
2410: /* V = (Sm && Dm) || (!Rm && (Dm || Sm)) */
2411: fprintf(o, " {\n");
2412: switch(iib->size) {
2413: case sz_byte:
2414: fprintf(o, " int Sm = (sint8)srcdata < 0;\n");
2415: fprintf(o, " int Dm = (sint8)dstdata < 0;\n");
2416: fprintf(o, " int Rm = (sint8)outdata < 0;\n");
2417: break;
2418: case sz_word:
2419: fprintf(o, " int Sm = (sint16)srcdata < 0;\n");
2420: fprintf(o, " int Dm = (sint16)dstdata < 0;\n");
2421: fprintf(o, " int Rm = (sint16)outdata < 0;\n");
2422: break;
2423: case sz_long:
2424: fprintf(o, " int Sm = (sint32)srcdata < 0;\n");
2425: fprintf(o, " int Dm = (sint32)dstdata < 0;\n");
2426: fprintf(o, " int Rm = (sint32)outdata < 0;\n");
2427: break;
2428: default:
2429: fprintf(o, "ERROR size\n");
2430: break;
2431: }
2432: fprintf(o, " XFLAG = CFLAG = (Sm && Dm) || (!Rm && (Dm || Sm));\n");
2433: fprintf(o, " }\n");
2434: }
2435:
2436: void generate_addflag_v(FILE *o, t_iib *iib)
2437: {
2438: /* V = (Sm && Dm && !Rm) || (!Sm && !Dm && Rm)
2439: overflow is performed as if both source and destination are signed,
2440: the only two condtions are if we've added too much to a +ve number
2441: or we've subtracted too much from a -ve number */
2442: /* the technique to implement the above formula is to make sure the sign
2443: of Sm == the sign of Dm, and the sign of Dm != the sign of Rm. */
2444: switch(iib->size) {
2445: case sz_byte:
2446: fprintf(o, " VFLAG = (((sint8)srcdata < 0) == ((sint8)dstdata < 0)) ");
2447: fprintf(o, "&&\n (((sint8)dstdata < 0) != ((sint8)outdata < 0));\n");
2448: break;
2449: case sz_word:
2450: fprintf(o, " VFLAG = (((sint16)srcdata < 0) == ((sint16)dstdata < 0)) ");
2451: fprintf(o, "&&\n (((sint16)dstdata < 0) != ((sint16)outdata < 0));\n");
2452: break;
2453: case sz_long:
2454: fprintf(o, " VFLAG = (((sint32)srcdata < 0) == ((sint32)dstdata < 0)) ");
2455: fprintf(o, "&&\n (((sint32)dstdata < 0) != ((sint32)outdata < 0));\n");
2456: break;
2457: default:
2458: fprintf(o, "ERROR size\n");
2459: break;
2460: }
2461: }
2462:
2463: void generate_negflag_cx(FILE *o, t_iib *iib)
2464: {
2465: /* C = (Dm || Rm) */
2466: fprintf(o, " XFLAG = CFLAG = srcdata ? 1 : 0;\n");
2467: }
2468:
2469: void generate_negflag_v(FILE *o, t_iib *iib)
2470: {
2471: /* V = (Dm && Rm)
2472: which is the same as V = src == 1<<15 as the only case where both the
2473: data and the result are both negative is in the case of the extreme
2474: negative number (1<<15 in the case of 16 bit) since 0 - 1<<15 = 1<<15. */
2475: switch(iib->size) {
2476: case sz_byte:
2477: fprintf(o, " VFLAG = (srcdata == (1u<<7));\n");
2478: break;
2479: case sz_word:
2480: fprintf(o, " VFLAG = (srcdata == (1u<<15));\n");
2481: break;
2482: case sz_long:
2483: fprintf(o, " VFLAG = (srcdata == (1u<<31));\n");
2484: break;
2485: default:
2486: fprintf(o, "ERROR size\n");
2487: break;
2488: }
2489: }
2490:
2491: void generate_negxflag_cx(FILE *o, t_iib *iib)
2492: {
2493: /* C = (Dm || Rm)
2494: unlike NEG, NEGX is done properly */
2495: fprintf(o, " XFLAG = CFLAG ");
2496: switch(iib->size) {
2497: case sz_byte:
2498: fprintf(o, "= ((sint8)srcdata < 0) || ((sint8)outdata < 0);\n");
2499: break;
2500: case sz_word:
2501: fprintf(o, "= ((sint16)srcdata < 0) || ((sint16)outdata < 0);\n");
2502: break;
2503: case sz_long:
2504: fprintf(o, "= ((sint32)srcdata < 0) || ((sint32)outdata < 0);\n");
2505: break;
2506: default:
2507: fprintf(o, "ERROR size\n");
2508: break;
2509: }
2510: }
2511:
2512: void generate_negxflag_v(FILE *o, t_iib *iib)
2513: {
2514: /* V = (Dm && Rm)
2515: unlike NEG, NEGX is done properly */
2516: switch(iib->size) {
2517: case sz_byte:
2518: fprintf(o, " VFLAG = ((sint8)srcdata < 0) && ((sint8)outdata < 0);\n");
2519: break;
2520: case sz_word:
2521: fprintf(o, " VFLAG = ((sint16)srcdata < 0) && ((sint16)outdata < 0);\n");
2522: break;
2523: case sz_long:
2524: fprintf(o, " VFLAG = ((sint32)srcdata < 0) && ((sint32)outdata < 0);\n");
2525: break;
2526: default:
2527: fprintf(o, "ERROR size\n");
2528: break;
2529: }
2530: }
2531:
2532: void generate_bits(FILE *o, t_iib *iib)
2533: {
2534: switch (iib->size) {
2535: case sz_byte:
2536: fprintf(o, " uint8 bits = 8;\n");
2537: break;
2538: case sz_word:
2539: fprintf(o, " uint8 bits = 16;\n");
2540: break;
2541: case sz_long:
2542: fprintf(o, " uint8 bits = 32;\n");
2543: break;
2544: default:
2545: fprintf(o, "ERROR size\n");
2546: break;
2547: }
2548: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.