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