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