|
|
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:
1.1.1.3 root 54: (void)argc;
55: (void)argv;
56:
1.1 root 57: printf("Writing C files... ");
58: fflush(stdout);
59:
60: for (i = 0; i < 16; i++) {
61:
62: printf("%d. ", i);
63: fflush(stdout);
64:
65: /* make filename */
66: sprintf(tmp, FNAME_GEN68K_CPU_OUT, i);
67:
68: /* open output file */
69: if ((output = fopen(tmp, "w")) == NULL) {
70: perror("fopen output");
71: exit(1);
72: }
73:
74: /* output header */
75: fprintf(output, HEADER, i);
76: fprintf(output, "#include \"cpu68k-inline.h\"\n\n");
77:
78: generate(output, i);
79:
80: /* close output */
81: if (fclose(output)) {
82: perror("fclose output");
83: exit(1);
84: }
85:
86: }
87:
88: printf("done.\n");
89: fflush(stdout);
90:
91: /* normal program termination */
92: return(0);
93: }
94:
95: void generate(FILE *output, int topnibble)
96: {
97: t_iib *iib;
98: int i, flags, pcinc;
99: int DEBUG_BRANCH = 0;
100: int DEBUG_SR = 0;
101: int DEBUG_RTE = 0;
102:
103: for (i = 0; i < iibs_num; i++) {
104: iib = &iibs[i];
105:
106: if ((iib->mask & 0xF000) != 0xF000) {
107: fprintf(stderr, "error: Strange mask %x\n", iib->mask);
108: exit(1);
109: }
110: if (((iib->bits & 0xF000)>>12) != topnibble) {
111: continue;
112: }
113:
114: for (flags = 0; flags < 2; flags++) {
115:
116: if (flags == 1 && iib->flags.set == 0) {
117: /* there is no non-flags version, functable will already go
118: straight to the normal version anyway, so lets just skip it */
119: continue;
120: }
121:
122: fprintf(output, "void cpu_op_%i%s(t_ipc *ipc) /* %s */ {\n",
123: i, flags ? "b" : "a", mnemonic_table[iib->mnemonic].name);
1.1.1.3 root 124: fprintf(output, " /* mask %04x, bits %04x, mnemonic %d, priv %d, ",
1.1 root 125: iib->mask, iib->bits, iib->mnemonic, iib->flags.priv);
126: fprintf(output, "endblk %d, imm_notzero %d, used %d",
127: iib->flags.endblk, iib->flags.imm_notzero, iib->flags.used);
128: fprintf(output, " set %d, size %d, stype %d, dtype %d, sbitpos %d, ",
129: iib->flags.set, iib->size, iib->stype, iib->dtype, iib->sbitpos);
130: fprintf(output, "dbitpos %d, immvalue %d */\n", iib->dbitpos,
131: iib->immvalue);
132:
133: pcinc = 1;
134:
135: switch(iib->mnemonic) {
136:
137: case i_OR:
138: case i_AND:
139: case i_EOR:
140: generate_ea(output, iib, tp_src, 1);
141: generate_eaval(output, iib, tp_src);
142: generate_ea(output, iib, tp_dst, 1);
143: generate_eaval(output, iib, tp_dst);
144: generate_outdata(output, iib, "dstdata");
145: OUT("\n");
146: switch(iib->mnemonic) {
147: case i_OR:
148: OUT(" outdata|= srcdata;\n");
149: break;
150: case i_AND:
151: OUT(" outdata&= srcdata;\n");
152: break;
153: case i_EOR:
154: OUT(" outdata^= srcdata;\n");
155: break;
156: default:
157: OUT("ERROR\n");
158: break;
159: }
160: generate_eastore(output, iib, tp_dst);
161: if (flags)
162: OUT("\n");
163: if (flags && iib->flags.set & IIB_FLAG_N)
164: generate_stdflag_n(output, iib);
165: if (flags && iib->flags.set & IIB_FLAG_Z)
166: generate_stdflag_z(output, iib);
167: if (flags && iib->flags.set & IIB_FLAG_V)
168: generate_clrflag_v(output, iib);
169: if (flags && iib->flags.set & IIB_FLAG_C)
170: generate_clrflag_c(output, iib);
171: break;
172:
173: case i_ORSR:
174: case i_ANDSR:
175: case i_EORSR:
176: generate_ea(output, iib, tp_src, 1);
177: generate_eaval(output, iib, tp_src);
178: OUT(" unsigned int sr = reg68k_sr.sr_struct.s;\n");
179: OUT("\n");
180: if (DEBUG_SR)
181: fputs(" printf(\"SR: %08X %04X\\n\", PC, reg68k_sr.sr_int);\n",
182: output);
183: if (iib->size == sz_word) {
184: OUT(" if (!SFLAG)\n");
185: fprintf(output, " reg68k_internal_vector(V_PRIVILEGE, PC+%d);\n",
186: (iib->wordlen)*2);
187: OUT("\n");
188: }
189: switch(iib->mnemonic) {
190: case i_ORSR:
191: OUT(" SR|= srcdata;\n");
192: break;
193: case i_ANDSR:
194: if (iib->size == sz_byte) {
195: OUT(" SR = (SR & 0xFF00) | (SR & srcdata);\n");
196: } else {
197: OUT(" SR&= srcdata;\n");
198: }
199: break;
200: case i_EORSR:
201: OUT(" SR^= srcdata;\n");
202: break;
203: default:
204: OUT("ERROR\n");
205: break;
206: }
207: OUT(" if (sr != (uint8)reg68k_sr.sr_struct.s) {\n");
208: OUT(" /* mode change, swap SP and A7 */\n");
209: OUT(" ADDRREG(7)^= SP; SP^= ADDRREG(7); ADDRREG(7)^= SP;\n");
210: OUT(" }\n");
211: if (DEBUG_SR)
212: fputs(" printf(\"SR: %08X %04X\\n\", PC, reg68k_sr.sr_int);\n",
213: output);
214: break;
215:
216: case i_SUB:
217: generate_ea(output, iib, tp_src, 1);
218: generate_eaval(output, iib, tp_src);
219: generate_ea(output, iib, tp_dst, 1);
220: generate_eaval(output, iib, tp_dst);
221: switch (iib->size) {
222: case sz_byte:
223: generate_outdata(output, iib, "(sint8)dstdata - (sint8)srcdata");
224: break;
225: case sz_word:
226: generate_outdata(output, iib, "(sint16)dstdata - (sint16)srcdata");
227: break;
228: case sz_long:
229: generate_outdata(output, iib, "(sint32)dstdata - (sint32)srcdata");
230: break;
231: default:
232: OUT("ERROR size\n");
233: break;
234: }
235: OUT("\n");
236: generate_eastore(output, iib, tp_dst);
237: if (flags)
238: OUT("\n");
239: if (flags && iib->flags.set & IIB_FLAG_V)
240: generate_subflag_v(output, iib);
241: if (flags && ((iib->flags.set & IIB_FLAG_C) ||
242: (iib->flags.set & IIB_FLAG_X)))
243: generate_subflag_cx(output, iib);
244: if (flags && iib->flags.set & IIB_FLAG_N)
245: generate_stdflag_n(output, iib);
246: if (flags && iib->flags.set & IIB_FLAG_Z)
247: generate_stdflag_z(output, iib);
248: break;
249:
250: case i_SUBA:
251: if (iib->dtype != dt_Areg)
252: OUT("Error\n");
253: generate_ea(output, iib, tp_src, 1);
254: generate_eaval(output, iib, tp_src);
255: generate_ea(output, iib, tp_dst, 1);
256: OUT(" uint32 dstdata = ADDRREG(dstreg);\n");
257: switch (iib->size) {
258: case sz_byte:
259: OUT(" uint32 outdata = (sint32)dstdata - (sint8)srcdata;\n");
260: break;
261: case sz_word:
262: OUT(" uint32 outdata = (sint32)dstdata - (sint16)srcdata;\n");
263: break;
264: case sz_long:
265: OUT(" uint32 outdata = (sint32)dstdata - (sint32)srcdata;\n");
266: break;
267: default:
268: OUT("ERROR size\n");
269: break;
270: }
271: OUT("\n");
272: OUT(" ADDRREG(dstreg) = outdata;\n");
273: break;
274:
275: case i_SUBX:
276: generate_ea(output, iib, tp_src, 1);
277: generate_eaval(output, iib, tp_src);
278: generate_ea(output, iib, tp_dst, 1);
279: generate_eaval(output, iib, tp_dst);
280: switch (iib->size) {
281: case sz_byte:
282: generate_outdata(output, iib, "(sint8)dstdata - (sint8)srcdata "
283: "- XFLAG");
284: break;
285: case sz_word:
286: generate_outdata(output, iib, "(sint16)dstdata - (sint16)srcdata"
287: "- XFLAG");
288: break;
289: case sz_long:
290: generate_outdata(output, iib, "(sint32)dstdata - (sint32)srcdata"
291: "- XFLAG");
292: break;
293: default:
294: OUT("ERROR size\n");
295: break;
296: }
297: OUT("\n");
298: generate_eastore(output, iib, tp_dst);
299: if (flags)
300: OUT("\n");
301: if (flags && iib->flags.set & IIB_FLAG_V)
302: generate_subflag_v(output, iib);
303: if (flags && ((iib->flags.set & IIB_FLAG_C) ||
304: (iib->flags.set & IIB_FLAG_X)))
305: generate_subxflag_cx(output, iib);
306: if (flags && iib->flags.set & IIB_FLAG_N)
307: generate_stdflag_n(output, iib);
308: if (flags && iib->flags.set & IIB_FLAG_Z)
309: generate_stdxflag_z(output, iib);
310: break;
311:
312: case i_ADD:
313: generate_ea(output, iib, tp_src, 1);
314: generate_eaval(output, iib, tp_src);
315: generate_ea(output, iib, tp_dst, 1);
316: generate_eaval(output, iib, tp_dst);
317: switch (iib->size) {
318: case sz_byte:
319: generate_outdata(output, iib, "(sint8)dstdata + (sint8)srcdata");
320: break;
321: case sz_word:
322: generate_outdata(output, iib, "(sint16)dstdata + (sint16)srcdata");
323: break;
324: case sz_long:
325: generate_outdata(output, iib, "(sint32)dstdata + (sint32)srcdata");
326: break;
327: default:
328: OUT("ERROR size\n");
329: break;
330: }
331: OUT("\n");
332: generate_eastore(output, iib, tp_dst);
333: if (flags)
334: OUT("\n");
335: if (flags && iib->flags.set & IIB_FLAG_V)
336: generate_addflag_v(output, iib);
337: if (flags && ((iib->flags.set & IIB_FLAG_C) ||
338: (iib->flags.set & IIB_FLAG_X)))
339: generate_addflag_cx(output, iib);
340: if (flags && iib->flags.set & IIB_FLAG_N)
341: generate_stdflag_n(output, iib);
342: if (flags && iib->flags.set & IIB_FLAG_Z)
343: generate_stdflag_z(output, iib);
344: break;
345:
346: case i_ADDA:
347: if (iib->dtype != dt_Areg)
348: OUT("Error\n");
349: generate_ea(output, iib, tp_src, 1);
350: generate_eaval(output, iib, tp_src);
351: generate_ea(output, iib, tp_dst, 1);
352: OUT(" uint32 dstdata = ADDRREG(dstreg);\n");
353: switch (iib->size) {
354: case sz_byte:
355: OUT(" uint32 outdata = (sint32)dstdata + (sint8)srcdata;\n");
356: break;
357: case sz_word:
358: OUT(" uint32 outdata = (sint32)dstdata + (sint16)srcdata;\n");
359: break;
360: case sz_long:
361: OUT(" uint32 outdata = (sint32)dstdata + (sint32)srcdata;\n");
362: break;
363: default:
364: OUT("ERROR size\n");
365: break;
366: }
367: OUT("\n");
368: OUT(" ADDRREG(dstreg) = outdata;\n");
369: break;
370:
371: case i_ADDX:
372: generate_ea(output, iib, tp_src, 1);
373: generate_eaval(output, iib, tp_src);
374: generate_ea(output, iib, tp_dst, 1);
375: generate_eaval(output, iib, tp_dst);
376: switch (iib->size) {
377: case sz_byte:
378: generate_outdata(output, iib, "(sint8)dstdata + (sint8)srcdata "
379: "+ XFLAG");
380: break;
381: case sz_word:
382: generate_outdata(output, iib, "(sint16)dstdata + (sint16)srcdata"
383: "+ XFLAG");
384: break;
385: case sz_long:
386: generate_outdata(output, iib, "(sint32)dstdata + (sint32)srcdata"
387: "+ XFLAG");
388: break;
389: default:
390: OUT("ERROR size\n");
391: break;
392: }
393: OUT("\n");
394: generate_eastore(output, iib, tp_dst);
395: if (flags)
396: OUT("\n");
397: if (flags && iib->flags.set & IIB_FLAG_V)
398: generate_addflag_v(output, iib);
399: if (flags && ((iib->flags.set & IIB_FLAG_C) ||
400: (iib->flags.set & IIB_FLAG_X)))
401: generate_addxflag_cx(output, iib);
402: if (flags && iib->flags.set & IIB_FLAG_N)
403: generate_stdflag_n(output, iib);
404: if (flags && iib->flags.set & IIB_FLAG_Z)
405: generate_stdxflag_z(output, iib);
406: break;
407:
408: case i_MULU:
409: generate_ea(output, iib, tp_src, 1);
410: generate_eaval(output, iib, tp_src);
411: generate_ea(output, iib, tp_dst, 1);
412: generate_eaval(output, iib, tp_dst);
413: OUT("\n");
414: OUT(" uint32 outdata = (uint32)srcdata * (uint32)dstdata;\n");
415: if (iib->dtype != dt_Dreg)
416: OUT("ERROR dtype\n");
417: OUT(" DATAREG(dstreg) = outdata;\n");
418: if (flags)
419: OUT("\n");
420: if (flags && iib->flags.set & IIB_FLAG_N)
421: OUT(" NFLAG = ((sint32)outdata) < 0;\n");
422: if (flags && iib->flags.set & IIB_FLAG_Z)
423: generate_stdflag_z(output, iib);
424: if (flags && iib->flags.set & IIB_FLAG_V)
425: generate_clrflag_v(output, iib);
426: if (flags && iib->flags.set & IIB_FLAG_C)
427: generate_clrflag_c(output, iib);
428: break;
429:
430: case i_MULS:
431: generate_ea(output, iib, tp_src, 1);
432: generate_eaval(output, iib, tp_src);
433: generate_ea(output, iib, tp_dst, 1);
434: generate_eaval(output, iib, tp_dst);
435: OUT("\n");
436: OUT(" uint32 outdata = (sint32)(sint16)srcdata * "
437: "(sint32)(sint16)dstdata;\n");
438: if (iib->dtype != dt_Dreg)
439: OUT("ERROR dtype\n");
440: OUT(" DATAREG(dstreg) = outdata;\n");
441: if (flags)
442: OUT("\n");
443: if (flags && iib->flags.set & IIB_FLAG_N)
444: OUT(" NFLAG = ((sint32)outdata) < 0;\n");
445: if (flags && iib->flags.set & IIB_FLAG_Z)
446: generate_stdflag_z(output, iib);
447: if (flags && iib->flags.set & IIB_FLAG_V)
448: generate_clrflag_v(output, iib);
449: if (flags && iib->flags.set & IIB_FLAG_C)
450: generate_clrflag_c(output, iib);
451: break;
452:
453: case i_CMP:
454: generate_ea(output, iib, tp_src, 1);
455: generate_eaval(output, iib, tp_src);
456: generate_ea(output, iib, tp_dst, 1);
457: generate_eaval(output, iib, tp_dst);
458: switch (iib->size) {
459: case sz_byte:
460: generate_outdata(output, iib, "(sint8)dstdata - (sint8)srcdata");
461: break;
462: case sz_word:
463: generate_outdata(output, iib, "(sint16)dstdata - (sint16)srcdata");
464: break;
465: case sz_long:
466: generate_outdata(output, iib, "(sint32)dstdata - (sint32)srcdata");
467: break;
468: default:
469: OUT("ERROR size\n");
470: break;
471: }
472: if (flags)
473: OUT("\n");
474: if (flags && iib->flags.set & IIB_FLAG_V)
475: generate_subflag_v(output, iib);
476: if (flags && iib->flags.set & IIB_FLAG_C)
477: generate_subflag_c(output, iib);
478: if (flags && iib->flags.set & IIB_FLAG_N)
479: generate_stdflag_n(output, iib);
480: if (flags && iib->flags.set & IIB_FLAG_Z)
481: generate_stdflag_z(output, iib);
482: break;
483:
484: case i_CMPA:
485: if (iib->dtype != dt_Areg || iib->size != sz_word)
486: OUT("Error\n");
487: generate_ea(output, iib, tp_src, 1);
488: generate_eaval(output, iib, tp_src);
489: iib->size = sz_long;
490: generate_ea(output, iib, tp_dst, 1);
491: generate_eaval(output, iib, tp_dst);
492: OUT(" uint32 outdata = (sint32)dstdata - (sint32)(sint16)srcdata;\n");
493: if (flags)
494: OUT("\n");
495: if (flags && iib->flags.set & IIB_FLAG_V)
496: generate_cmpaflag_v(output, iib);
497: if (flags && iib->flags.set & IIB_FLAG_C)
498: generate_cmpaflag_c(output, iib);
499: if (flags && iib->flags.set & IIB_FLAG_N)
500: generate_stdflag_n(output, iib);
501: if (flags && iib->flags.set & IIB_FLAG_Z)
502: generate_stdflag_z(output, iib);
503: iib->size = sz_word;
504: break;
505:
506: case i_BTST:
507: case i_BCHG:
508: case i_BCLR:
509: case i_BSET:
510: generate_ea(output, iib, tp_src, 1);
511: generate_eaval(output, iib, tp_src);
512: generate_ea(output, iib, tp_dst, 1);
513: generate_eaval(output, iib, tp_dst);
514: switch (iib->size) {
515: case sz_byte:
516: OUT(" uint32 bitpos = 1<<(srcdata & 7);");
517: break;
518: case sz_long:
519: OUT(" uint32 bitpos = 1<<(srcdata & 31);");
520: break;
521: default:
522: OUT("ERROR size\n");
523: break;
524: }
525: OUT("\n");
526: switch(iib->mnemonic) {
527: case i_BTST:
528: break;
529: case i_BCHG:
530: generate_outdata(output, iib, "dstdata ^ bitpos");
531: generate_eastore(output, iib, tp_dst);
532: break;
533: case i_BCLR:
534: generate_outdata(output, iib, "dstdata & ~bitpos");
535: generate_eastore(output, iib, tp_dst);
536: break;
537: case i_BSET:
538: generate_outdata(output, iib, "dstdata | bitpos");
539: generate_eastore(output, iib, tp_dst);
540: break;
541: default:
542: OUT("ERROR\n");
543: break;
544: }
545: OUT("\n");
546: OUT(" ZFLAG = !(dstdata & bitpos);\n");
547: break;
548:
549: case i_MOVE:
550: generate_ea(output, iib, tp_src, 1);
551: generate_eaval(output, iib, tp_src);
552: generate_ea(output, iib, tp_dst, 1);
553: generate_outdata(output, iib, "srcdata");
554: OUT("\n");
555: generate_eastore(output, iib, tp_dst);
556: if (flags)
557: OUT("\n");
558: if (flags && iib->flags.set & IIB_FLAG_V)
559: generate_clrflag_v(output, iib);
560: if (flags && iib->flags.set & IIB_FLAG_C)
561: generate_clrflag_c(output, iib);
562: if (flags && iib->flags.set & IIB_FLAG_N)
563: generate_stdflag_n(output, iib);
564: if (flags && iib->flags.set & IIB_FLAG_Z)
565: generate_stdflag_z(output, iib);
566: break;
567:
568: case i_MOVEA:
569: generate_ea(output, iib, tp_src, 1);
570: generate_eaval(output, iib, tp_src);
571: generate_ea(output, iib, tp_dst, 1);
572: if (iib->dtype != dt_Areg || iib->size != sz_word)
573: OUT("Error\n");
574: OUT("\n");
575: OUT(" ADDRREG(dstreg) = (sint32)(sint16)srcdata;\n");
576: break;
577:
578: case i_MOVEPMR:
579: generate_ea(output, iib, tp_src, 1);
580: generate_ea(output, iib, tp_dst, 1);
581: generate_eaval(output, iib, tp_dst);
582: switch(iib->size) {
583: case sz_word:
584: generate_outdata(output, iib, "(fetchbyte(srcaddr) << 8) + "
585: "fetchbyte(srcaddr+2)");
586: break;
587: case sz_long:
588: generate_outdata(output, iib, "(fetchbyte(srcaddr) << 24) | "
589: "(fetchbyte(srcaddr+2) << 16) | "
590: "\n (fetchbyte(srcaddr+4) << 8) | "
591: "fetchbyte(srcaddr+6)");
592: break;
593: default:
594: OUT("ERROR size\n");
595: break;
596: }
597: OUT("\n");
598: generate_eastore(output, iib, tp_dst);
599: break;
600:
601: case i_MOVEPRM:
602: generate_ea(output, iib, tp_src, 1);
603: generate_eaval(output, iib, tp_src);
604: generate_ea(output, iib, tp_dst, 1);
605: OUT("\n");
606: switch(iib->size) {
607: case sz_word:
608: OUT(" storebyte(dstaddr, (srcdata >> 8) & 0xFF);\n");
609: OUT(" storebyte(dstaddr+2, srcdata & 0xFF);\n");
610: break;
611: case sz_long:
612: OUT(" storebyte(dstaddr, (srcdata >> 24) & 0xFF);\n");
613: OUT(" storebyte(dstaddr+2, (srcdata >> 16) & 0xFF);\n");
614: OUT(" storebyte(dstaddr+4, (srcdata >> 8) & 0xFF);\n");
615: OUT(" storebyte(dstaddr+6, srcdata & 0xFF);\n");
616: break;
617: default:
618: OUT("ERROR size\n");
619: break;
620: }
621: break;
622:
623: case i_MOVEFSR:
624: generate_ea(output, iib, tp_src, 1);
625: generate_outdata(output, iib, NULL);
626: OUT("\n");
627: OUT(" outdata = SR;\n");
628: generate_eastore(output, iib, tp_src);
629: break;
630:
631: case i_MOVETSR:
632: generate_ea(output, iib, tp_src, 1);
633: generate_eaval(output, iib, tp_src);
634: OUT(" unsigned int sr = reg68k_sr.sr_struct.s;\n");
635: OUT("\n");
636: if (DEBUG_SR)
637: fputs(" printf(\"SR: %08X %04X\\n\", PC, reg68k_sr.sr_int);\n",
638: output);
639: switch (iib->size) {
640: case sz_byte:
641: OUT(" SR = (SR & ~0xFF) | srcdata;\n");
642: break;
643: case sz_word:
644: OUT(" if (!SFLAG)\n");
645: fprintf(output, " reg68k_internal_vector(V_PRIVILEGE, PC+%d);\n",
646: (iib->wordlen)*2);
647: OUT("\n");
648: OUT(" SR = srcdata;\n");
649: break;
650: default:
651: OUT("ERROR size\n");
652: break;
653: }
654: OUT(" if (sr != (uint8)reg68k_sr.sr_struct.s) {\n");
655: OUT(" /* mode change, swap SP and A7 */\n");
656: OUT(" ADDRREG(7)^= SP; SP^= ADDRREG(7); ADDRREG(7)^= SP;\n");
657: OUT(" }\n");
658: if (DEBUG_SR)
659: fputs(" printf(\"SR: %08X %04X\\n\", PC, reg68k_sr.sr_int);\n",
660: output);
661: break;
662:
663: case i_MOVEMRM:
664: generate_ea(output, iib, tp_src, 1);
665: generate_eaval(output, iib, tp_src);
666: generate_ea(output, iib, tp_dst, 0);
667: if (iib->dtype == dt_Adec) {
668: OUT(" uint8 datamask = (srcdata & 0xFF00) >> 8;\n");
669: OUT(" uint8 addrmask = srcdata & 0xFF;");
670: OUT("\n");
671: switch(iib->size) {
672: case sz_word:
673: OUT(" while (addrmask) {\n");
674: OUT(" dstaddr-= 2;\n");
675: OUT(" storeword(dstaddr, ADDRREG((7-movem_bit[addrmask])));\n");
676: OUT(" addrmask&= ~(1<<movem_bit[addrmask]);\n");
677: OUT(" }\n");
678: OUT(" while (datamask) {\n");
679: OUT(" dstaddr-= 2;\n");
680: OUT(" storeword(dstaddr, DATAREG((7-movem_bit[datamask])));\n");
681: OUT(" datamask&= ~(1<<movem_bit[datamask]);\n");
682: OUT(" }\n");
683: break;
684: case sz_long:
685: OUT(" while (addrmask) {\n");
686: OUT(" dstaddr-= 4;\n");
687: OUT(" storelong(dstaddr, ADDRREG((7-movem_bit[addrmask])));\n");
688: OUT(" addrmask&= ~(1<<movem_bit[addrmask]);\n");
689: OUT(" }\n");
690: OUT(" while (datamask) {\n");
691: OUT(" dstaddr-= 4;\n");
692: OUT(" storelong(dstaddr, ");
693: OUT("DATAREG((7-movem_bit[datamask])));\n");
694: OUT(" datamask&= ~(1<<movem_bit[datamask]);\n");
695: OUT(" }\n");
696: break;
697: default:
698: OUT("ERROR\n");
699: break;
700: }
701: OUT(" ADDRREG(dstreg) = dstaddr;");
702: } else {
703: OUT(" uint8 addrmask = (srcdata & 0xFF00) >> 8;\n");
704: OUT(" uint8 datamask = srcdata & 0xFF;");
705: OUT("\n");
706: switch(iib->size) {
707: case sz_word:
708: OUT(" while (datamask) {\n");
709: OUT(" storeword(dstaddr, DATAREG(movem_bit[datamask]));\n");
710: OUT(" datamask&= ~(1<<movem_bit[datamask]);\n");
711: OUT(" dstaddr+= 2;\n");
712: OUT(" }\n");
713: OUT(" while (addrmask) {\n");
714: OUT(" storeword(dstaddr, ADDRREG(movem_bit[addrmask]));\n");
715: OUT(" addrmask&= ~(1<<movem_bit[addrmask]);\n");
716: OUT(" dstaddr+= 2;\n");
717: OUT(" }\n");
718: break;
719: case sz_long:
720: OUT(" while (datamask) {\n");
721: OUT(" storelong(dstaddr, DATAREG(movem_bit[datamask]));\n");
722: OUT(" datamask&= ~(1<<movem_bit[datamask]);\n");
723: OUT(" dstaddr+= 4;\n");
724: OUT(" }\n");
725: OUT(" while (addrmask) {\n");
726: OUT(" storelong(dstaddr, ADDRREG(movem_bit[addrmask]));\n");
727: OUT(" addrmask&= ~(1<<movem_bit[addrmask]);\n");
728: OUT(" dstaddr+= 4;\n");
729: OUT(" }\n");
730: break;
731: default:
732: OUT("ERROR\n");
733: break;
734: }
735: if (iib->dtype == dt_Ainc) {
736: /* not supported */
737: OUT("ERROR\n");
738: }
739: }
740: break;
741:
742: case i_MOVEMMR:
743: generate_ea(output, iib, tp_src, 1);
744: generate_eaval(output, iib, tp_src);
745: generate_ea(output, iib, tp_dst, 0);
746: OUT(" uint8 addrmask = (srcdata & 0xFF00) >> 8;\n");
747: OUT(" uint8 datamask = srcdata & 0xFF;");
748: OUT("\n");
749: switch(iib->size) {
750: case sz_word:
751: OUT(" while (datamask) {\n");
752: OUT(" DATAREG(movem_bit[datamask]) = ");
753: OUT("(sint32)(sint16)fetchword(dstaddr);\n");
754: OUT(" datamask&= ~(1<<movem_bit[datamask]);\n");
755: OUT(" dstaddr+= 2;\n");
756: OUT(" }\n");
757: OUT(" while (addrmask) {\n");
758: OUT(" ADDRREG(movem_bit[addrmask]) = ");
759: OUT("(sint32)(sint16)fetchword(dstaddr);\n");
760: OUT(" addrmask&= ~(1<<movem_bit[addrmask]);\n");
761: OUT(" dstaddr+= 2;\n");
762: OUT(" }\n");
763: break;
764: case sz_long:
765: OUT(" while (datamask) {\n");
766: OUT(" DATAREG(movem_bit[datamask]) = fetchlong(dstaddr);\n");
767: OUT(" datamask&= ~(1<<movem_bit[datamask]);\n");
768: OUT(" dstaddr+= 4;\n");
769: OUT(" }\n");
770: OUT(" while (addrmask) {\n");
771: OUT(" ADDRREG(movem_bit[addrmask]) = fetchlong(dstaddr);\n");
772: OUT(" addrmask&= ~(1<<movem_bit[addrmask]);\n");
773: OUT(" dstaddr+= 4;\n");
774: OUT(" }\n");
775: break;
776: default:
777: OUT("ERROR\n");
778: break;
779: }
780: if (iib->dtype == dt_Ainc) {
781: OUT(" ADDRREG(dstreg) = dstaddr;\n");
782: } else if (iib->dtype == dt_Adec) {
783: /* not supported */
784: OUT("ERROR\n");
785: }
786: break;
787:
788: case i_MOVETUSP:
789: generate_ea(output, iib, tp_src, 1);
790: generate_eaval(output, iib, tp_src);
791: OUT("\n");
792: OUT(" if (!SFLAG)\n");
793: fprintf(output, " reg68k_internal_vector(V_PRIVILEGE, PC+%d);\n",
794: (iib->wordlen)*2);
795: OUT("\n");
796: OUT(" SP = srcdata;\n");
797: break;
798:
799: case i_MOVEFUSP:
800: generate_ea(output, iib, tp_src, 1);
801: OUT(" uint32 outdata;\n");
802: OUT("\n");
803: OUT(" if (!SFLAG)\n");
804: fprintf(output, " reg68k_internal_vector(V_PRIVILEGE, PC+%d);\n",
805: (iib->wordlen)*2);
806: OUT("\n");
807: OUT(" outdata = SP;\n");
808: generate_eastore(output, iib, tp_src);
809: break;
810:
811: case i_NEG:
812: generate_ea(output, iib, tp_src, 1);
813: generate_eaval(output, iib, tp_src);
814: switch (iib->size) {
815: case sz_byte:
816: generate_outdata(output, iib, "0 - (sint8)srcdata");
817: break;
818: case sz_word:
819: generate_outdata(output, iib, "0 - (sint16)srcdata");
820: break;
821: case sz_long:
822: generate_outdata(output, iib, "0 - (sint32)srcdata");
823: break;
824: default:
825: OUT("ERROR size\n");
826: break;
827: }
828: OUT("\n");
829: generate_eastore(output, iib, tp_src);
830: if (flags)
831: OUT("\n");
832: if (flags && iib->flags.set & IIB_FLAG_V)
833: generate_negflag_v(output, iib);
834: if (flags && ((iib->flags.set & IIB_FLAG_C) ||
835: (iib->flags.set & IIB_FLAG_X)))
836: generate_negflag_cx(output, iib);
837: if (flags && iib->flags.set & IIB_FLAG_N)
838: generate_stdflag_n(output, iib);
839: if (flags && iib->flags.set & IIB_FLAG_Z)
840: generate_stdflag_z(output, iib);
841: break;
842:
843: case i_NEGX:
844: generate_ea(output, iib, tp_src, 1);
845: generate_eaval(output, iib, tp_src);
846: switch (iib->size) {
847: case sz_byte:
848: generate_outdata(output, iib, "0 - (sint8)srcdata - XFLAG");
849: break;
850: case sz_word:
851: generate_outdata(output, iib, "0 - (sint16)srcdata - XFLAG");
852: break;
853: case sz_long:
854: generate_outdata(output, iib, "0 - (sint32)srcdata - XFLAG");
855: break;
856: default:
857: OUT("ERROR size\n");
858: break;
859: }
860: OUT("\n");
861: generate_eastore(output, iib, tp_src);
862: if (flags)
863: OUT("\n");
864: if (flags && iib->flags.set & IIB_FLAG_V)
865: generate_negxflag_v(output, iib);
866: if (flags && ((iib->flags.set & IIB_FLAG_C) ||
867: (iib->flags.set & IIB_FLAG_X)))
868: generate_negxflag_cx(output, iib);
869: if (flags && iib->flags.set & IIB_FLAG_N)
870: generate_stdflag_n(output, iib);
871: if (flags && iib->flags.set & IIB_FLAG_Z)
872: generate_stdxflag_z(output, iib);
873: break;
874:
875: case i_CLR:
876: generate_ea(output, iib, tp_src, 1);
877: generate_eaval(output, iib, tp_src); /* read before write */
878: generate_outdata(output, iib, "0");
879: OUT("\n");
880: generate_eastore(output, iib, tp_src);
881: if (flags)
882: OUT("\n");
883: if (flags && iib->flags.set & IIB_FLAG_V)
884: generate_clrflag_v(output, iib);
885: if (flags && iib->flags.set & IIB_FLAG_C)
886: generate_clrflag_c(output, iib);
887: if (flags && iib->flags.set & IIB_FLAG_N)
888: generate_clrflag_n(output, iib);
889: if (flags && iib->flags.set & IIB_FLAG_Z)
890: generate_setflag_z(output, iib);
891: break;
892:
893: case i_NOT:
894: generate_ea(output, iib, tp_src, 1);
895: generate_eaval(output, iib, tp_src); /* read before write */
896: generate_outdata(output, iib, "~srcdata");
897: OUT("\n");
898: generate_eastore(output, iib, tp_src);
899: if (flags)
900: OUT("\n");
901: if (flags && iib->flags.set & IIB_FLAG_V)
902: generate_clrflag_v(output, iib);
903: if (flags && iib->flags.set & IIB_FLAG_C)
904: generate_clrflag_c(output, iib);
905: if (flags && iib->flags.set & IIB_FLAG_N)
906: generate_stdflag_n(output, iib);
907: if (flags && iib->flags.set & IIB_FLAG_Z)
908: generate_stdflag_z(output, iib);
909: break;
910:
911: case i_ABCD:
912: generate_ea(output, iib, tp_src, 1);
913: generate_eaval(output, iib, tp_src);
914: generate_ea(output, iib, tp_dst, 1);
915: generate_eaval(output, iib, tp_dst);
916: generate_outdata(output, iib, NULL);
917: OUT("\n");
918: OUT(" uint8 outdata_low = (dstdata & 0xF) + (srcdata & 0xF) ");
919: OUT("+ XFLAG;\n");
1.1.1.4 ! root 920: OUT(" uint16 precalc = dstdata + srcdata + XFLAG;\n");
! 921: OUT(" uint16 outdata_tmp = precalc;\n");
! 922: OUT("\n");
! 923: OUT(" if (outdata_low > 0x09)\n");
! 924: OUT(" outdata_tmp+= 0x06;\n");
! 925: OUT(" if (outdata_tmp > 0x90) {\n");
! 926: OUT(" outdata_tmp+= 0x60;\n");
1.1 root 927: if (flags && iib->flags.set & IIB_FLAG_C)
928: OUT(" CFLAG = 1;\n");
929: if (flags && iib->flags.set & IIB_FLAG_X)
930: OUT(" XFLAG = 1;\n");
931: OUT(" } else {\n");
932: if (flags && iib->flags.set & IIB_FLAG_C)
933: OUT(" CFLAG = 0;\n");
934: if (flags && iib->flags.set & IIB_FLAG_X)
935: OUT(" XFLAG = 0;\n");
936: OUT(" }\n");
1.1.1.4 ! root 937: OUT(" outdata = outdata_tmp;\n");
1.1 root 938: if (flags && iib->flags.set & IIB_FLAG_Z)
939: OUT(" if (outdata) ZFLAG = 0;\n");
1.1.1.4 ! root 940: if (flags && iib->flags.set & IIB_FLAG_N)
! 941: generate_stdflag_n(output, iib);
! 942: if (flags && iib->flags.set & IIB_FLAG_V)
! 943: OUT(" VFLAG = ((precalc & 1<<7) == 0) && (outdata & 1<<7);\n");
1.1 root 944: generate_eastore(output, iib, tp_dst);
945: break;
946:
947: case i_SBCD:
948: generate_ea(output, iib, tp_src, 1);
949: generate_eaval(output, iib, tp_src);
950: generate_ea(output, iib, tp_dst, 1);
951: generate_eaval(output, iib, tp_dst);
952: generate_outdata(output, iib, NULL);
953: OUT("\n");
1.1.1.4 ! root 954: OUT(" sint8 outdata_low = (dstdata & 0xF) - (srcdata & 0xF) ");
! 955: OUT("- XFLAG;\n");
! 956: OUT(" sint16 precalc = dstdata - srcdata - XFLAG;\n");
! 957: OUT(" sint16 outdata_tmp = precalc;\n");
! 958: OUT("\n");
! 959: OUT(" if (outdata_low < 0)\n");
! 960: OUT(" outdata_tmp-= 0x06;\n");
! 961: OUT(" if (outdata_tmp < 0) {\n");
! 962: OUT(" outdata_tmp-= 0x60;\n");
1.1 root 963: if (flags && iib->flags.set & IIB_FLAG_C)
964: OUT(" CFLAG = 1;\n");
965: if (flags && iib->flags.set & IIB_FLAG_X)
966: OUT(" XFLAG = 1;\n");
967: OUT(" } else {\n");
968: if (flags && iib->flags.set & IIB_FLAG_C)
969: OUT(" CFLAG = 0;\n");
970: if (flags && iib->flags.set & IIB_FLAG_X)
971: OUT(" XFLAG = 0;\n");
972: OUT(" }\n");
1.1.1.4 ! root 973: OUT(" outdata = outdata_tmp;\n");
1.1 root 974: if (flags && iib->flags.set & IIB_FLAG_Z)
975: OUT(" if (outdata) ZFLAG = 0;\n");
1.1.1.4 ! root 976: if (flags && iib->flags.set & IIB_FLAG_N)
! 977: generate_stdflag_n(output, iib);
! 978: if (flags && iib->flags.set & IIB_FLAG_V)
! 979: OUT(" VFLAG = (precalc & 1<<7) && ((outdata & 1<<7) == 0);\n");
1.1 root 980: generate_eastore(output, iib, tp_dst);
981: break;
982:
983: case i_NBCD:
984: generate_ea(output, iib, tp_src, 1);
985: generate_eaval(output, iib, tp_src);
986: generate_outdata(output, iib, NULL);
987: OUT("\n");
1.1.1.4 ! root 988: OUT(" sint8 outdata_low = - (srcdata & 0xF) - XFLAG;\n");
! 989: OUT(" sint16 precalc = - srcdata - XFLAG;\n");
! 990: OUT(" sint16 outdata_tmp = precalc;\n");
! 991: OUT("\n");
! 992: OUT(" if (outdata_low < 0)\n");
! 993: OUT(" outdata_tmp-= 0x06;\n");
! 994: OUT(" if (outdata_tmp < 0) {\n");
! 995: OUT(" outdata_tmp-= 0x60;\n");
1.1 root 996: if (flags && iib->flags.set & IIB_FLAG_C)
997: OUT(" CFLAG = 1;\n");
998: if (flags && iib->flags.set & IIB_FLAG_X)
999: OUT(" XFLAG = 1;\n");
1000: OUT(" } else {\n");
1001: if (flags && iib->flags.set & IIB_FLAG_C)
1002: OUT(" CFLAG = 0;\n");
1003: if (flags && iib->flags.set & IIB_FLAG_X)
1004: OUT(" XFLAG = 0;\n");
1005: OUT(" }\n");
1.1.1.4 ! root 1006: OUT(" outdata = outdata_tmp;\n");
1.1 root 1007: if (flags && iib->flags.set & IIB_FLAG_Z)
1008: OUT(" if (outdata) ZFLAG = 0;\n");
1.1.1.4 ! root 1009: if (flags && iib->flags.set & IIB_FLAG_N)
! 1010: generate_stdflag_n(output, iib);
! 1011: if (flags && iib->flags.set & IIB_FLAG_V)
! 1012: OUT(" VFLAG = (precalc & 1<<7) && ((outdata & 1<<7) == 0);\n");
1.1 root 1013: generate_eastore(output, iib, tp_src);
1014: break;
1015:
1016: case i_SWAP:
1017: generate_ea(output, iib, tp_src, 1);
1018: generate_eaval(output, iib, tp_src);
1019: generate_outdata(output, iib, "(srcdata>>16) | (srcdata<<16)");
1020: OUT("\n");
1021: generate_eastore(output, iib, tp_src);
1022: if (flags)
1023: OUT("\n");
1024: if (flags && iib->flags.set & IIB_FLAG_V)
1025: generate_clrflag_v(output, iib);
1026: if (flags && iib->flags.set & IIB_FLAG_C)
1027: generate_clrflag_c(output, iib);
1028: if (flags && iib->flags.set & IIB_FLAG_N)
1029: generate_stdflag_n(output, iib);
1030: if (flags && iib->flags.set & IIB_FLAG_Z)
1031: generate_stdflag_z(output, iib);
1032: break;
1033:
1034: case i_PEA:
1035: generate_ea(output, iib, tp_src, 1);
1036: OUT("\n");
1037: OUT(" ADDRREG(7)-= 4;\n");
1038: OUT(" storelong(ADDRREG(7), srcaddr);\n");
1039: break;
1040:
1041: case i_LEA:
1042: generate_ea(output, iib, tp_src, 1);
1043: generate_ea(output, iib, tp_dst, 1);
1044: generate_outdata(output, iib, "srcaddr");
1045: OUT("\n");
1046: generate_eastore(output, iib, tp_dst);
1047: break;
1048:
1049: case i_EXT:
1050: generate_ea(output, iib, tp_src, 1);
1051: generate_eaval(output, iib, tp_src);
1052: OUT("\n");
1053: switch(iib->size) {
1054: case sz_word:
1055: generate_outdata(output, iib, "(sint16)(sint8)(srcdata)");
1056: break;
1057: case sz_long:
1058: generate_outdata(output, iib, "(sint32)(sint16)(srcdata)");
1059: break;
1060: default:
1061: fprintf(output, "ERROR size\n");
1062: break;
1063: }
1064: generate_eastore(output, iib, tp_src);
1065: if (flags)
1066: OUT("\n");
1067: if (flags && iib->flags.set & IIB_FLAG_V)
1068: generate_clrflag_v(output, iib);
1069: if (flags && iib->flags.set & IIB_FLAG_C)
1070: generate_clrflag_c(output, iib);
1071: if (flags && iib->flags.set & IIB_FLAG_N)
1072: generate_stdflag_n(output, iib);
1073: if (flags && iib->flags.set & IIB_FLAG_Z)
1074: generate_stdflag_z(output, iib);
1075: break;
1076:
1077: case i_EXG:
1078: generate_ea(output, iib, tp_src, 1);
1079: generate_eaval(output, iib, tp_src);
1080: generate_ea(output, iib, tp_dst, 1);
1081: generate_eaval(output, iib, tp_dst);
1082: OUT("\n");
1083: switch (iib->dtype) {
1084: case dt_Dreg:
1085: OUT(" DATAREG(dstreg) = srcdata;\n");
1086: break;
1087: case dt_Areg:
1088: OUT(" ADDRREG(dstreg) = srcdata;\n");
1089: break;
1090: default:
1091: OUT("ERROR size\n");
1092: break;
1093: }
1094: switch (iib->stype) {
1095: case dt_Dreg:
1096: OUT(" DATAREG(srcreg) = dstdata;\n");
1097: break;
1098: case dt_Areg:
1099: OUT(" ADDRREG(srcreg) = dstdata;\n");
1100: break;
1101: default:
1102: OUT("ERROR size\n");
1103: break;
1104: }
1105: break;
1106:
1107: case i_TST:
1108: generate_ea(output, iib, tp_src, 1);
1109: generate_eaval(output, iib, tp_src);
1110: generate_outdata(output, iib, "srcdata");
1111: if (flags)
1112: OUT("\n");
1113: if (flags && iib->flags.set & IIB_FLAG_V)
1114: generate_clrflag_v(output, iib);
1115: if (flags && iib->flags.set & IIB_FLAG_C)
1116: generate_clrflag_c(output, iib);
1117: if (flags && iib->flags.set & IIB_FLAG_N)
1118: generate_stdflag_n(output, iib);
1119: if (flags && iib->flags.set & IIB_FLAG_Z)
1120: generate_stdflag_z(output, iib);
1121: break;
1122:
1123: case i_TAS:
1124: generate_ea(output, iib, tp_src, 1);
1125: generate_eaval(output, iib, tp_src);
1126: generate_outdata(output, iib, "srcdata");
1127: if (flags)
1128: OUT("\n");
1129: if (flags && iib->flags.set & IIB_FLAG_V)
1130: generate_clrflag_v(output, iib);
1131: if (flags && iib->flags.set & IIB_FLAG_C)
1132: generate_clrflag_c(output, iib);
1133: if (flags && iib->flags.set & IIB_FLAG_N)
1134: generate_stdflag_n(output, iib);
1135: if (flags && iib->flags.set & IIB_FLAG_Z)
1136: generate_stdflag_z(output, iib);
1.1.1.4 ! root 1137: #ifndef BROKEN_TAS
1.1 root 1138: switch(iib->size) {
1139: case sz_byte:
1140: OUT(" outdata|= 1<<7;\n");
1141: break;
1142: case sz_word:
1143: OUT(" outdata|= 1<<15;\n");
1144: break;
1145: case sz_long:
1146: OUT(" outdata|= 1<<31;\n");
1147: break;
1148: default:
1149: OUT("ERROR size\n");
1150: break;
1151: }
1152: generate_eastore(output, iib, tp_src);
1.1.1.4 ! root 1153: #endif
1.1 root 1154: break;
1155:
1156: case i_CHK:
1157: generate_ea(output, iib, tp_src, 1);
1158: generate_eaval(output, iib, tp_src);
1159: generate_ea(output, iib, tp_dst, 1);
1160: generate_eaval(output, iib, tp_dst);
1161: fprintf(output, "\n");
1162: if (iib->size != sz_word)
1163: OUT("ERROR size\n");
1164: fprintf(output, " if ((sint16)srcdata < 0) {\n");
1165: if (flags)
1166: OUT(" NFLAG = 1;\n");
1167: fprintf(output, " reg68k_internal_vector(V_CHK, PC+%d);\n",
1168: (iib->wordlen)*2);
1169: OUT(" } else if (dstdata > srcdata) {\n");
1170: if (flags)
1171: OUT(" NFLAG = 0;\n");
1172: fprintf(output, " reg68k_internal_vector(V_CHK, PC+%d);\n",
1173: (iib->wordlen)*2);
1174: OUT(" }\n");
1175: break;
1176:
1177: case i_TRAPV:
1178: OUT(" if (VFLAG) {\n");
1179: fprintf(output, " reg68k_internal_vector(V_TRAPV, PC+%d);\n",
1180: (iib->wordlen)*2);
1181: OUT(" }\n");
1182: break;
1183:
1184: case i_TRAP:
1185: generate_ea(output, iib, tp_src, 1);
1186: generate_eaval(output, iib, tp_src);
1187: OUT("\n");
1188: fprintf(output, " reg68k_internal_vector(V_TRAP+srcdata, PC+%d);\n",
1189: (iib->wordlen)*2);
1190: pcinc = 0;
1191: break;
1192:
1193: case i_RESET:
1194: OUT(" printf(\"RESET @ %x\\n\", PC);\n");
1195: OUT(" exit(1);\n");
1196: break;
1197:
1198: case i_NOP:
1199: /* NOP */
1200: break;
1201:
1202: case i_STOP:
1203: generate_ea(output, iib, tp_src, 1);
1204: generate_eaval(output, iib, tp_src);
1205: OUT("\n");
1206: OUT(" if (regs.stop)\n");
1207: OUT(" return;\n");
1208: OUT(" if (!(SFLAG && (srcdata & 1<<13))) {\n");
1209: fprintf(output, " reg68k_internal_vector(V_PRIVILEGE, PC+%d);\n",
1210: (iib->wordlen)*2);
1211: fprintf(output, " PC+= %d;\n", (iib->wordlen)*2);
1212: OUT(" } else {\n");
1213: OUT(" SR = srcdata;\n");
1214: OUT(" STOP = 1;\n");
1215: OUT(" }\n");
1216: pcinc = 0;
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_internal_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_internal_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_internal_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_internal_vector(V_LINE10, PC);\n");
1757: pcinc = 0;
1758: break;
1759:
1760: case i_LINE15:
1761: OUT("\n");
1762: fprintf(output, " reg68k_internal_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) | "
1.1.1.4 ! root 2082: "outdata;\n");
1.1 root 2083: else
1.1.1.4 ! root 2084: fprintf(o, " DATAREG(dstreg) = (DATAREG(dstreg) & ~0xff) | "
! 2085: "outdata;\n");
1.1 root 2086: break;
2087: case sz_word:
2088: if (type == tp_src)
1.1.1.4 ! root 2089: fprintf(o, " DATAREG(srcreg) = (DATAREG(srcreg) & ~0xffff) | "
! 2090: "outdata;\n");
1.1 root 2091: else
1.1.1.4 ! root 2092: fprintf(o, " DATAREG(dstreg) = (DATAREG(dstreg) & ~0xffff) | "
! 2093: "outdata;\n");
1.1 root 2094: break;
2095: case sz_long:
2096: if (type == tp_src)
1.1.1.4 ! root 2097: fprintf(o, " DATAREG(srcreg) = outdata;\n");
1.1 root 2098: else
1.1.1.4 ! root 2099: fprintf(o, " DATAREG(dstreg) = outdata;\n");
1.1 root 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)
1.1.1.4 ! root 2110: fprintf(o, " ADDRREG(srcreg) = (ADDRREG(srcreg) & ~0xff) | "
! 2111: "outdata;\n");
1.1 root 2112: else
1.1.1.4 ! root 2113: fprintf(o, " ADDRREG(dstreg) = (ADDRREG(dstreg) & ~0xff) | "
! 2114: "outdata;\n");
1.1 root 2115: break;
2116: case sz_word:
2117: if (type == tp_src)
1.1.1.4 ! root 2118: fprintf(o, " ADDRREG(srcreg) = (ADDRREG(srcreg) & ~0xffff) | "
! 2119: "outdata;\n");
1.1 root 2120: else
1.1.1.4 ! root 2121: fprintf(o, " ADDRREG(dstreg) = (ADDRREG(dstreg) & ~0xffff) | "
! 2122: "outdata;\n");
1.1 root 2123: break;
2124: case sz_long:
2125: if (type == tp_src)
1.1.1.4 ! root 2126: fprintf(o, " ADDRREG(srcreg) = outdata;\n");
1.1 root 2127: else
1.1.1.4 ! root 2128: fprintf(o, " ADDRREG(dstreg) = outdata;\n");
1.1 root 2129: break;
2130: default:
2131: fprintf(o, "ERROR size\n");
2132: break;
2133: }
2134: break;
1.1.1.4 ! root 2135: case dt_Adec:
! 2136: switch(iib->size) {
! 2137: case sz_byte:
! 2138: if (type == tp_src)
! 2139: fprintf(o, " storebyte(srcaddr, outdata);\n");
! 2140: else
! 2141: fprintf(o, " storebyte(dstaddr, outdata);\n");
! 2142: break;
! 2143: case sz_word:
! 2144: if (type == tp_src)
! 2145: fprintf(o, " storeword(srcaddr, outdata);\n");
! 2146: else
! 2147: fprintf(o, " storeword(dstaddr, outdata);\n");
! 2148: break;
! 2149: case sz_long:
! 2150: fprintf(o, " /* pre-decrement long store must write low 16 bits\n"
! 2151: " in -2 first, then upper 16 bits in -4 second */\n");
! 2152: if (type == tp_src) {
! 2153: fprintf(o, " storeword(srcaddr + 2, (uint16)outdata);\n");
! 2154: fprintf(o, " storeword(srcaddr, (uint16)(outdata >> 16));\n");
! 2155: } else {
! 2156: fprintf(o, " storeword(dstaddr + 2, (uint16)outdata);\n");
! 2157: fprintf(o, " storeword(dstaddr, (uint16)(outdata >> 16));\n");
! 2158: }
! 2159: break;
! 2160: default:
! 2161: fprintf(o, "ERROR size\n");
! 2162: }
! 2163: break;
1.1 root 2164: case dt_Aind:
2165: case dt_Ainc:
2166: case dt_Adis:
2167: case dt_Aidx:
2168: case dt_AbsW:
2169: case dt_AbsL:
2170: case dt_Pdis:
2171: case dt_Pidx:
2172: switch(iib->size) {
2173: case sz_byte:
2174: if (type == tp_src)
1.1.1.4 ! root 2175: fprintf(o, " storebyte(srcaddr, outdata);\n");
1.1 root 2176: else
1.1.1.4 ! root 2177: fprintf(o, " storebyte(dstaddr, outdata);\n");
1.1 root 2178: break;
2179: case sz_word:
2180: if (type == tp_src)
1.1.1.4 ! root 2181: fprintf(o, " storeword(srcaddr, outdata);\n");
1.1 root 2182: else
1.1.1.4 ! root 2183: fprintf(o, " storeword(dstaddr, outdata);\n");
1.1 root 2184: break;
2185: case sz_long:
2186: if (type == tp_src)
1.1.1.4 ! root 2187: fprintf(o, " storelong(srcaddr, outdata);\n");
1.1 root 2188: else
1.1.1.4 ! root 2189: fprintf(o, " storelong(dstaddr, outdata);\n");
1.1 root 2190: break;
2191: default:
2192: fprintf(o, "ERROR size\n");
2193: }
2194: break;
2195: default:
2196: fprintf(o, "ERROR type\n");
2197: }
2198: }
2199:
2200: void generate_outdata(FILE *o, t_iib *iib, const char *init)
2201: {
2202: switch(iib->size) {
2203: case sz_byte:
2204: fprintf(o, " uint8 ");
2205: break;
2206: case sz_word:
2207: fprintf(o, " uint16 ");
2208: break;
2209: case sz_long:
2210: fprintf(o, " uint32 ");
2211: break;
2212: default:
2213: fprintf(o, "ERROR size\n");
2214: break;
2215: }
2216: fprintf(o, "outdata%s%s;\n", (init && init[0]) ? " = " : "",
2217: init ? init : "");
2218: }
2219:
2220: void generate_cc(FILE *o, t_iib *iib)
2221: {
2222: switch(iib->cc) {
2223: case 0: /* T */
2224: fprintf(o, " uint8 cc = 1;\n");
2225: break;
2226: case 1: /* F */
2227: fprintf(o, " uint8 cc = 0;\n");
2228: break;
2229: case 2: /* HI */
2230: fprintf(o, " uint8 cc = !(CFLAG || ZFLAG);\n");
2231: break;
2232: case 3: /* LS */
2233: fprintf(o, " uint8 cc = CFLAG || ZFLAG;\n");
2234: break;
2235: case 4: /* CC */
2236: fprintf(o, " uint8 cc = !CFLAG;\n");
2237: break;
2238: case 5: /* CS */
2239: fprintf(o, " uint8 cc = CFLAG;\n");
2240: break;
2241: case 6: /* NE */
2242: fprintf(o, " uint8 cc = !ZFLAG;\n");
2243: break;
2244: case 7: /* EQ */
2245: fprintf(o, " uint8 cc = ZFLAG;\n");
2246: break;
2247: case 8: /* VC */
2248: fprintf(o, " uint8 cc = !VFLAG;\n");
2249: break;
2250: case 9: /* VS */
2251: fprintf(o, " uint8 cc = VFLAG;\n");
2252: break;
2253: case 10: /* PL */
2254: fprintf(o, " uint8 cc = !NFLAG;\n");
2255: break;
2256: case 11: /* MI */
2257: fprintf(o, " uint8 cc = NFLAG;\n");
2258: break;
2259: case 12: /* GE */
2260: fprintf(o, " uint8 cc = (NFLAG == VFLAG);\n");
2261: break;
2262: case 13: /* LT */
2263: fprintf(o, " uint8 cc = (NFLAG != VFLAG);\n");
2264: break;
2265: case 14: /* GT */
2266: fprintf(o, " uint8 cc = !ZFLAG && (NFLAG == VFLAG);\n");
2267: break;
2268: case 15: /* LE */
2269: fprintf(o, " uint8 cc = ZFLAG || (NFLAG != VFLAG);\n");
2270: break;
2271: default:
2272: fprintf(o, "ERROR cc\n");
2273: break;
2274: }
2275: }
2276:
2277: void generate_stdflag_n(FILE *o, t_iib *iib)
2278: {
2279: switch(iib->size) {
2280: case sz_byte:
2281: fprintf(o, " NFLAG = ((sint8)outdata) < 0;\n");
2282: break;
2283: case sz_word:
2284: fprintf(o, " NFLAG = ((sint16)outdata) < 0;\n");
2285: break;
2286: case sz_long:
2287: fprintf(o, " NFLAG = ((sint32)outdata) < 0;\n");
2288: break;
2289: default:
2290: fprintf(o, "ERROR size\n");
2291: break;
2292: }
2293: }
2294:
2295: void generate_stdflag_z(FILE *o, t_iib *iib)
2296: {
1.1.1.3 root 2297: (void)iib;
1.1 root 2298: fprintf(o, " ZFLAG = !outdata;\n");
2299: }
2300:
2301: void generate_clrflag_v(FILE *o, t_iib *iib)
2302: {
1.1.1.3 root 2303: (void)iib;
1.1 root 2304: fprintf(o, " VFLAG = 0;\n");
2305: }
2306:
2307: void generate_clrflag_c(FILE *o, t_iib *iib)
2308: {
1.1.1.3 root 2309: (void)iib;
1.1 root 2310: fprintf(o, " CFLAG = 0;\n");
2311: }
2312:
2313: void generate_clrflag_n(FILE *o, t_iib *iib)
2314: {
1.1.1.3 root 2315: (void)iib;
1.1 root 2316: fprintf(o, " NFLAG = 0;\n");
2317: }
2318:
2319: void generate_setflag_z(FILE *o, t_iib *iib)
2320: {
1.1.1.3 root 2321: (void)iib;
1.1 root 2322: fprintf(o, " ZFLAG = 1;\n");
2323: }
2324:
2325: void generate_subflag_c(FILE *o, t_iib *iib)
2326: {
2327: /* C = (Sm && !Dm) || (Rm && !Dm) || (Sm && Rm)
2328: carry is performed as if both source and destination are unsigned,
2329: so this is simply if the source is greater than the destination - I
2330: have proven this to be the case using a truth table and the above
2331: motorola definition */
1.1.1.3 root 2332: (void)iib;
1.1 root 2333: fprintf(o, " CFLAG = srcdata > dstdata;\n");
2334: }
2335:
2336: void generate_subflag_cx(FILE *o, t_iib *iib)
2337: {
2338: /* C = (Sm && !Dm) || (Rm && !Dm) || (Sm && Rm)
2339: carry is performed as if both source and destination are unsigned,
2340: so this is simply if the source is greater than the destination - I
2341: have proven this to be the case using a truth table and the above
2342: motorola definition */
1.1.1.3 root 2343: (void)iib;
1.1 root 2344: fprintf(o, " XFLAG = CFLAG = srcdata > dstdata;\n");
2345: }
2346:
2347: void generate_subxflag_cx(FILE *o, t_iib *iib)
2348: {
2349: /* V = (Sm && !Dm) || (Rm && (!Dm || Sm)) */
2350: fprintf(o, " {\n");
2351: switch(iib->size) {
2352: case sz_byte:
2353: fprintf(o, " int Sm = (sint8)srcdata < 0;\n");
2354: fprintf(o, " int Dm = (sint8)dstdata < 0;\n");
2355: fprintf(o, " int Rm = (sint8)outdata < 0;\n");
2356: break;
2357: case sz_word:
2358: fprintf(o, " int Sm = (sint16)srcdata < 0;\n");
2359: fprintf(o, " int Dm = (sint16)dstdata < 0;\n");
2360: fprintf(o, " int Rm = (sint16)outdata < 0;\n");
2361: break;
2362: case sz_long:
2363: fprintf(o, " int Sm = (sint32)srcdata < 0;\n");
2364: fprintf(o, " int Dm = (sint32)dstdata < 0;\n");
2365: fprintf(o, " int Rm = (sint32)outdata < 0;\n");
2366: break;
2367: default:
2368: fprintf(o, "ERROR size\n");
2369: break;
2370: }
2371: fprintf(o, " XFLAG = CFLAG = (Sm && !Dm) || (Rm && (!Dm || Sm));\n");
2372: fprintf(o, " }\n");
2373: }
2374:
2375: void generate_cmpaflag_c(FILE *o, t_iib *iib)
2376: {
2377: /* see generate_subflag_c - this is just the same but with a sign extend
2378: on the source */
1.1.1.3 root 2379: (void)iib;
1.1 root 2380: fprintf(o, " CFLAG = (uint32)(sint32)(sint16)srcdata > dstdata;\n");
2381: }
2382:
2383: void generate_subflag_v(FILE *o, t_iib *iib)
2384: {
2385: /* V = (!Sm && Dm && !Rm) || (Sm && !Dm && Rm)
2386: overflow is performed as if both source and destination are signed,
2387: the only two condtions are if we've added too much to a +ve number
2388: or we've subtracted too much from a -ve number - I have proven the
2389: this to be the case using a truth table and the above motorola
2390: definition */
2391: /* the technique to implement the above formula is to make sure the sign
2392: of Sm != the sign of Dm, and the sign of Dm != the sign of Rm. */
2393: switch(iib->size) {
2394: case sz_byte:
2395: fprintf(o, " VFLAG = (((sint8)srcdata < 0) != ((sint8)dstdata < 0)) ");
2396: fprintf(o, "&&\n (((sint8)dstdata < 0) != ((sint8)outdata < 0));\n");
2397: break;
2398: case sz_word:
2399: fprintf(o, " VFLAG = (((sint16)srcdata < 0) != ((sint16)dstdata < 0)) ");
2400: fprintf(o, "&&\n (((sint16)dstdata < 0) != ((sint16)outdata < 0));\n");
2401: break;
2402: case sz_long:
2403: fprintf(o, " VFLAG = (((sint32)srcdata < 0) != ((sint32)dstdata < 0)) ");
2404: fprintf(o, "&&\n (((sint32)dstdata < 0) != ((sint32)outdata < 0));\n");
2405: break;
2406: default:
2407: fprintf(o, "ERROR size\n");
2408: break;
2409: }
2410: }
2411:
2412: void generate_cmpaflag_v(FILE *o, t_iib *iib)
2413: {
2414: /* see generate_subflag_v - this is just the sz_long version with a sign
2415: extend on the source */
1.1.1.3 root 2416: (void)iib;
1.1 root 2417: fprintf(o, " VFLAG = (((sint32)(sint16)srcdata < 0) != ");
2418: fprintf(o, "((sint32)dstdata < 0)) ");
2419: fprintf(o, "&&\n (((sint32)dstdata < 0) != ((sint32)outdata < 0));\n");
2420: }
2421:
2422: void generate_stdxflag_z(FILE *o, t_iib *iib)
2423: {
1.1.1.3 root 2424: (void)iib;
1.1 root 2425: fprintf(o, " if (outdata) ZFLAG = 0;\n");
2426: }
2427:
2428: void generate_addflag_cx(FILE *o, t_iib *iib)
2429: {
2430: /* C = (Sm && Dm) || (!Rm && Dm) || (Sm && !Rm)
2431: carry is performed as if both source and destination are unsigned,
2432: so this is simply if the source is bigger than how much can be added
2433: to the destination without wrapping - this is of course just the bit
2434: inverse of the destination. */
2435: /* 0xFFFF - dstdata is obviously just ~dstdata, but try and get the
2436: compiler to do that without producing a warning, go on... */
2437: switch (iib->size) {
2438: case sz_byte:
2439: fprintf(o, " XFLAG = CFLAG = srcdata > (0xFFu - (uint8)dstdata);\n");
2440: break;
2441: case sz_word:
2442: fprintf(o, " XFLAG = CFLAG = srcdata > (0xFFFFu - (uint16)dstdata);\n");
2443: break;
2444: case sz_long:
2445: fprintf(o, " XFLAG = CFLAG = srcdata > (uint32)~(uint32)dstdata;\n");
2446: break;
2447: default:
2448: fprintf(o, "ERROR size\n");
2449: break;
2450: }
2451: /* gcc doesn't like a one's compliment of an unsigned - take out the
2452: casts in the above and it will warn you incorrectly */
2453: }
2454:
2455: void generate_addxflag_cx(FILE *o, t_iib *iib)
2456: {
2457: /* V = (Sm && Dm) || (!Rm && (Dm || Sm)) */
2458: fprintf(o, " {\n");
2459: switch(iib->size) {
2460: case sz_byte:
2461: fprintf(o, " int Sm = (sint8)srcdata < 0;\n");
2462: fprintf(o, " int Dm = (sint8)dstdata < 0;\n");
2463: fprintf(o, " int Rm = (sint8)outdata < 0;\n");
2464: break;
2465: case sz_word:
2466: fprintf(o, " int Sm = (sint16)srcdata < 0;\n");
2467: fprintf(o, " int Dm = (sint16)dstdata < 0;\n");
2468: fprintf(o, " int Rm = (sint16)outdata < 0;\n");
2469: break;
2470: case sz_long:
2471: fprintf(o, " int Sm = (sint32)srcdata < 0;\n");
2472: fprintf(o, " int Dm = (sint32)dstdata < 0;\n");
2473: fprintf(o, " int Rm = (sint32)outdata < 0;\n");
2474: break;
2475: default:
2476: fprintf(o, "ERROR size\n");
2477: break;
2478: }
2479: fprintf(o, " XFLAG = CFLAG = (Sm && Dm) || (!Rm && (Dm || Sm));\n");
2480: fprintf(o, " }\n");
2481: }
2482:
2483: void generate_addflag_v(FILE *o, t_iib *iib)
2484: {
2485: /* V = (Sm && Dm && !Rm) || (!Sm && !Dm && Rm)
2486: overflow is performed as if both source and destination are signed,
2487: the only two condtions are if we've added too much to a +ve number
2488: or we've subtracted too much from a -ve number */
2489: /* the technique to implement the above formula is to make sure the sign
2490: of Sm == the sign of Dm, and the sign of Dm != the sign of Rm. */
2491: switch(iib->size) {
2492: case sz_byte:
2493: fprintf(o, " VFLAG = (((sint8)srcdata < 0) == ((sint8)dstdata < 0)) ");
2494: fprintf(o, "&&\n (((sint8)dstdata < 0) != ((sint8)outdata < 0));\n");
2495: break;
2496: case sz_word:
2497: fprintf(o, " VFLAG = (((sint16)srcdata < 0) == ((sint16)dstdata < 0)) ");
2498: fprintf(o, "&&\n (((sint16)dstdata < 0) != ((sint16)outdata < 0));\n");
2499: break;
2500: case sz_long:
2501: fprintf(o, " VFLAG = (((sint32)srcdata < 0) == ((sint32)dstdata < 0)) ");
2502: fprintf(o, "&&\n (((sint32)dstdata < 0) != ((sint32)outdata < 0));\n");
2503: break;
2504: default:
2505: fprintf(o, "ERROR size\n");
2506: break;
2507: }
2508: }
2509:
2510: void generate_negflag_cx(FILE *o, t_iib *iib)
2511: {
1.1.1.3 root 2512: (void)iib;
1.1 root 2513: /* C = (Dm || Rm) */
2514: fprintf(o, " XFLAG = CFLAG = srcdata ? 1 : 0;\n");
2515: }
2516:
2517: void generate_negflag_v(FILE *o, t_iib *iib)
2518: {
2519: /* V = (Dm && Rm)
2520: which is the same as V = src == 1<<15 as the only case where both the
2521: data and the result are both negative is in the case of the extreme
2522: negative number (1<<15 in the case of 16 bit) since 0 - 1<<15 = 1<<15. */
2523: switch(iib->size) {
2524: case sz_byte:
2525: fprintf(o, " VFLAG = (srcdata == (1u<<7));\n");
2526: break;
2527: case sz_word:
2528: fprintf(o, " VFLAG = (srcdata == (1u<<15));\n");
2529: break;
2530: case sz_long:
2531: fprintf(o, " VFLAG = (srcdata == (1u<<31));\n");
2532: break;
2533: default:
2534: fprintf(o, "ERROR size\n");
2535: break;
2536: }
2537: }
2538:
2539: void generate_negxflag_cx(FILE *o, t_iib *iib)
2540: {
2541: /* C = (Dm || Rm)
2542: unlike NEG, NEGX is done properly */
2543: fprintf(o, " XFLAG = CFLAG ");
2544: switch(iib->size) {
2545: case sz_byte:
2546: fprintf(o, "= ((sint8)srcdata < 0) || ((sint8)outdata < 0);\n");
2547: break;
2548: case sz_word:
2549: fprintf(o, "= ((sint16)srcdata < 0) || ((sint16)outdata < 0);\n");
2550: break;
2551: case sz_long:
2552: fprintf(o, "= ((sint32)srcdata < 0) || ((sint32)outdata < 0);\n");
2553: break;
2554: default:
2555: fprintf(o, "ERROR size\n");
2556: break;
2557: }
2558: }
2559:
2560: void generate_negxflag_v(FILE *o, t_iib *iib)
2561: {
2562: /* V = (Dm && Rm)
2563: unlike NEG, NEGX is done properly */
2564: switch(iib->size) {
2565: case sz_byte:
2566: fprintf(o, " VFLAG = ((sint8)srcdata < 0) && ((sint8)outdata < 0);\n");
2567: break;
2568: case sz_word:
2569: fprintf(o, " VFLAG = ((sint16)srcdata < 0) && ((sint16)outdata < 0);\n");
2570: break;
2571: case sz_long:
2572: fprintf(o, " VFLAG = ((sint32)srcdata < 0) && ((sint32)outdata < 0);\n");
2573: break;
2574: default:
2575: fprintf(o, "ERROR size\n");
2576: break;
2577: }
2578: }
2579:
2580: void generate_bits(FILE *o, t_iib *iib)
2581: {
2582: switch (iib->size) {
2583: case sz_byte:
2584: fprintf(o, " uint8 bits = 8;\n");
2585: break;
2586: case sz_word:
2587: fprintf(o, " uint8 bits = 16;\n");
2588: break;
2589: case sz_long:
2590: fprintf(o, " uint8 bits = 32;\n");
2591: break;
2592: default:
2593: fprintf(o, "ERROR size\n");
2594: break;
2595: }
2596: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.