|
|
1.1 root 1:
2: #include <assert.h>
3: #include <stdio.h>
4: #include <stdlib.h>
5: #include <string.h>
6: #include <ctype.h>
7: #include <stdarg.h>
8: #include "dict.h"
1.1.1.2 ! root 9: #include "as68k.h"
! 10: #include "output.h"
! 11:
! 12: struct Compiler *comp;
1.1 root 13:
14: FILE *fin;
1.1.1.2 ! root 15: FILE *fout;
! 16:
1.1 root 17: char buf[4096];
18: Dict labels;
19: int dump_labels = 0;
20: int line_no = 0;
21: int last_op_addr;
1.1.1.2 ! root 22: int output_c = 0;
! 23:
! 24: const char *src_filename;
1.1 root 25:
26: /* to convert weird move sizes to standard sizes */
27: const int move_size[4] = { 1, 3, 2, 0 };
28: const char *Bcc_str[16] = {
29: "ra",NULL,"hi","ls","cc","cs","ne","eq",
30: "vc","vs","pl","mi","ge","lt","gt","le"
31: };
32: const char *DBcc_str[16] = {
33: "t","f","hi","ls","cc","cs","ne","eq",
34: "vc","vs","pl","mi","ge","lt","gt","le"
35: };
36:
1.1.1.2 ! root 37: /* enum SIZE */
! 38: const int size2len[] = { 8, 16, 32 };
! 39:
1.1 root 40: #define check(ch) do { \
41: if (*pos != (ch)) error ("Expected '%c'", ch); \
42: pos++; \
43: } while (0);
44: #define check_whitespace() do { \
45: if (!isspace (*pos)) error ("Line malformed."); \
46: while (isspace (*pos)) pos++; \
47: } while (0);
48:
1.1.1.2 ! root 49: int get_bitpos () { return (int)ftell (fout); }
1.1 root 50: #define set_bitpos(pos) (fseek (fout,pos,SEEK_SET))
51:
52: struct Fixup *fix_first = NULL;
53: struct Fixup *fix_last = NULL;
54: void add_fixup (int adr, int size, const char *label)
55: {
56: struct Fixup *fix = malloc (sizeof (struct Fixup));
57: fix->adr = adr;
58: fix->size = size;
59: fix->next = NULL;
60: fix->rel_to = (last_op_addr + 2) - BASE;
61: fix->line_no = line_no;
62: strcpy (fix->label, label);
63: if (fix_first == NULL) fix_first = fix;
64: if (fix_last == NULL) fix_last = fix;
65: else {
66: fix_last->next = fix;
67: fix_last = fix;
68: }
69: }
1.1.1.2 ! root 70: void add_fixup_rel_to (int adr, int size, const char *label, int rel_to)
! 71: {
! 72: struct Fixup *fix = malloc (sizeof (struct Fixup));
! 73: fix->adr = adr;
! 74: fix->size = size;
! 75: fix->next = NULL;
! 76: fix->rel_to = rel_to;
! 77: fix->line_no = line_no;
! 78: strcpy (fix->label, label);
! 79: if (fix_first == NULL) fix_first = fix;
! 80: if (fix_last == NULL) fix_last = fix;
! 81: else {
! 82: fix_last->next = fix;
! 83: fix_last = fix;
! 84: }
! 85: }
1.1 root 86:
87: void error (const char *format, ...)
88: {
89: va_list argptr;
90:
1.1.1.2 ! root 91: fprintf (stderr, "Error at line %d: ", line_no);
1.1 root 92: va_start (argptr, format);
1.1.1.2 ! root 93: vfprintf (stderr, format, argptr);
1.1 root 94: va_end (argptr);
1.1.1.2 ! root 95: fprintf (stderr, "\n");
1.1 root 96:
97: fclose (fout);
98: remove ("aout.prg");
99: exit (0);
100: }
1.1.1.2 ! root 101:
! 102: void bug_error (const char *format, ...)
! 103: {
! 104: va_list argptr;
! 105:
! 106: fprintf (stderr, "Internal compiler error (line %d of input): ", line_no);
! 107: va_start (argptr, format);
! 108: vfprintf (stderr, format, argptr);
! 109: va_end (argptr);
! 110: fprintf (stderr, "\n");
! 111:
! 112: fclose (fout);
! 113: remove ("aout.prg");
! 114: abort ();
! 115: }
! 116:
! 117: static void ea_set_immediate (ea_t *ea, int imm_val)
! 118: {
! 119: ea->mode = 7;
! 120: ea->reg = 4;
! 121: ea->imm.has_label = 0;
! 122: ea->imm.val = imm_val;
! 123: }
1.1 root 124:
125: void add_label (const char *name, int type, int val)
126: {
127: struct Label *lab = malloc (sizeof (struct Label));
128: if (dict_get (&labels, name)) error ("Label %s redefined.", name);
129: lab->val = val;
130: lab->type = type;
131: dict_set (&labels, name, lab);
132: }
133:
134: struct Label *get_label (const char *name)
135: {
136: struct Label *lab;
137: struct Node *n = dict_get (&labels, name);
138:
139: if (n == NULL) return NULL;
140: lab = n->obj;
141: lab->name = n->key;
142: return lab;
143: }
144:
145: void wr_byte(unsigned char x)
146: {
147: fputc (x, fout);
148: }
149:
150: void wr_short(short x)
151: {
152: wr_byte((unsigned char)((x>>8) & 0xff));
153: wr_byte((unsigned char)(x & 0xff));
154: }
155:
156: void wr_int(int x)
157: {
158: wr_byte((unsigned char)((x>>24) & 0xff));
159: wr_byte((unsigned char)((x>>16) & 0xff));
160: wr_byte((unsigned char)((x>>8) & 0xff));
161: wr_byte((unsigned char)(x & 0xff));
162: }
163:
164:
165: static inline int get_size (int ch)
166: {
167: switch (ch) {
168: case 'b': return BYTE;
169: case 'w': return WORD;
170: case 'l': return LONG;
171: default: error ("Invalid size '.%c'.", ch); return 0;
172: }
173: }
174:
175: char *rd_label (char *buf, char *lab_buf)
176: {
177: char snipped;
178: char *pos = buf;
179:
180: if (!isalpha (*buf)) error ("Label expected.");
181: /* label */
182: do {
183: pos++;
184: } while (isalnum (*pos) || (*pos == '_'));
185: /* snip */
186: snipped = *pos;
187: *pos = '\0';
188:
189: if (strlen (buf) > LAB_LEN-1) error ("Label too long.");
190: strncpy (lab_buf, buf, LAB_LEN);
191: lab_buf[LAB_LEN-1] = '\0';
192: *pos = snipped;
193: return pos;
194: }
195:
196:
197: void check_range (int *val, enum SIZE size)
198: {
199: switch (size) {
200: case BYTE: if ((*val < -128) || (*val > 255)) goto err;
201: if (*val > 127) *val -= 256;
202: break;
203: case WORD: if ((*val < -32768) || (*val > 65535)) goto err;
204: if (*val > 32767) *val -= 65536;
205: break;
206: default: break;
207: }
208: return;
209: err:
210: error ("Data too large.");
211: }
212:
213:
214: char *get_imm (char *buf, struct ImmVal *imm, int flags)
215: {
216: struct Label *lab;
217:
218: imm->has_label = 0;
219: while (isspace (*buf)) buf++;
220: if (flags & F_IMM) {
221: if (*buf != '#') goto err;
222: buf++;
223: }
224: if (*buf == '$') {
225: /* hex value */
226: buf++;
227: if (sscanf (&buf[0], "%x", &imm->val) != 1) goto err;
228: while (isxdigit (*buf)) buf++;
229: } else if (isdigit (*buf) || (*buf == '-')) {
230: /* dec value */
231: if (sscanf (&buf[0], "%d", &imm->val) != 1) goto err;
232: if (*buf == '-') buf++;
233: while (isdigit (*buf)) buf++;
234: } else if (isalpha (*buf)) {
235: /* label */
236: buf = rd_label (buf, imm->label);
237: lab = get_label (imm->label);
238: imm->val = 0;
239: if (lab) {
240: if (lab->type == L_CONST) imm->val = lab->val;
241: else imm->has_label = 1;
242: } else {
243: imm->has_label = 1;
244: }
245: if ((flags & F_NOLABELS) && (imm->has_label)) {
246: error ("Label not allowed.");
247: }
248: } else {
249: goto err;
250: }
251: return buf;
252: err:
253: error ("Malformed immediate value.");
254: return NULL;
255: }
256:
257: void check_end (const char *buf)
258: {
259: while (isspace (*buf)) buf++;
260: if (*buf) error ("Garbage at end of line.");
261: }
262:
263: void wr_ea (ea_t *ea)
264: {
265: if (ea->mode == 5) {
266: if (ea->imm.has_label) error ("Relative not allowed.");
267: wr_short (ea->imm.val);
268: return;
269: }
270: if (ea->mode == 6) {
271: if (ea->imm.has_label) error ("Relative not allowed.");
272: wr_short (ea->ext.ext);
273: return;
274: }
275: if (ea->mode == 7) {
276: /* $xxx.w */
277: if (ea->reg == 0) {
278: wr_short (ea->imm.val);
279: return;
280: }
281: /* $xxx.l */
282: else if (ea->reg == 1) {
283: if (ea->imm.has_label) goto abs_lab32;
284: wr_int (ea->imm.val);
285: return;
286: }
287: /* immediate */
288: else if (ea->reg == 4) {
289: if (ea->imm.has_label) {
290: if (ea->op_size != LONG)
291: error ("Relative not allowed.");
292: goto abs_lab32;
293: }
294: if (ea->op_size == LONG) {
295: wr_int (ea->imm.val);
296: } else if (ea->op_size == WORD) {
297: wr_short (ea->imm.val);
298: } else {
299: wr_short (ea->imm.val & 0xff);
300: }
301: return;
302: }
303: /* PC + offset */
304: else if (ea->reg == 2) {
305: if (ea->imm.has_label) goto rel_lab16;
306: error ("Absolute value not allowed.");
307: return;
308: }
309: /* PC + INDEX + OFFSET */
310: else if (ea->reg == 3) {
311: if (!ea->imm.has_label) error ("Absolute value not allowed.");
312: wr_short (ea->ext.ext);
313: add_fixup (get_bitpos()-1, BYTE, ea->imm.label);
314: return;
315: }
316: }
317: return;
318: rel_lab16:
319: /* resolve a relative 16-bit label (offset) */
320: wr_short (0);
321: add_fixup (get_bitpos()-2, WORD, ea->imm.label);
322: return;
323: abs_lab32:
324: /* resolve an absolute 32-bit label */
325: wr_int (0);
326: add_fixup (get_bitpos ()-4, LONG_FIXUP, ea->imm.label);
327: }
328:
329: char *get_reg (char *buf, int *reg_num, int flags)
330: {
331: int type;
332: while (isspace (*buf)) buf++;
333: if ((flags & F_AREG) && (buf[0] == 'a')) type = 8;
334: else if ((flags & F_DREG) && (buf[0] == 'd')) type = 0;
335: else goto err;
336: buf++;
337: if (sscanf (&buf[0], "%d", reg_num) != 1) goto err;
338:
339: *reg_num += type;
340: while (isdigit (*buf)) buf++;
341: return buf;
342: err:
343: error ("Expected a register.");
344: return NULL;
345: }
346:
347: char *get_ea (char *pos, ea_t *ea, int op_size, int flags)
348: {
349: int reg;
350: int size;
351: char *orig;
352: ea->imm.has_label = 0;
353: ea->op_size = op_size;
354: while (isspace (*pos)) pos++;
355: orig = pos;
356: if ((pos[0] == 'd') && isdigit (pos[1])) {
357: pos++;
358: if (sscanf (&pos[0], "%d", &ea->reg) != 1) goto poopdog;
359: ea->mode = 0;
360: if ((ea->reg < 0) || (ea->reg > 7)) goto poopdog;
361: while (isdigit (*pos)) pos++;
362: if (!(flags & F_DREG)) goto err;
363: return pos;
364: }
365: if ((pos[0] == 'a') && isdigit (pos[1])) {
366: pos++;
367: if (sscanf (&pos[0], "%d", &ea->reg) != 1) goto poopdog;
368: ea->mode = 1;
369: if ((ea->reg < 0) || (ea->reg > 7)) goto poopdog;
1.1.1.2 ! root 370: ea->reg += 8;
1.1 root 371: while (isdigit (*pos)) pos++;
372: if (!(flags & F_AREG)) goto err;
373: return pos;
374: }
375: poopdog:
376: pos = orig;
377: if ((*pos == '#') && (flags & F_IMM)) {
378: pos = get_imm (pos, &ea->imm, F_IMM);
379: check_range (&ea->imm.val, op_size);
380: ea->mode = 7;
381: ea->reg = 4;
382: return pos;
383: }
384: if ((flags & F_PRE) && (pos[0] == '-') && (pos[1] == '(')) {
385: pos += 2;
386: pos = get_reg (pos, &ea->reg, F_AREG);
387: check (')');
388: ea->mode = 0x4;
389: return pos;
390: }
391: if ((flags & (F_IND | F_POST)) && (pos[0] == '(')) {
392: check ('(');
393: pos = get_reg (pos, &ea->reg, F_AREG);
394: check (')');
395: if ((flags & F_POST) && (pos[0] == '+')) {
396: ea->mode = 3;
397: return ++pos;
398: } else if (flags & F_IND) {
399: ea->mode = 2;
400: return pos;
401: } else goto err;
402: }
403: if ((*pos == '$') || isdigit (*pos) || (*pos == '-') || isalpha (*pos)) {
404: if (isalpha (*pos)) {
405: pos = get_imm (pos, &ea->imm, 0);
406: } else if (*pos == '$') {
407: pos++;
408: if (sscanf (pos, "%x", &ea->imm.val) != 1) goto err;
409: while (isxdigit (*pos)) pos++;
410: } else {
411: if (sscanf (pos, "%d", &ea->imm.val) != 1) goto err;
412: if (*pos == '-') pos++;
413: while (isdigit (*pos)) pos++;
414: }
415: /* Immediate memory (not label) */
416: if ((*pos == '.') && (flags & (F_MEM_W | F_MEM_L))) {
417: pos++;
418: size = get_size (*pos);
419: pos++;
420: ea->mode = 0x7;
421: if (size == WORD) {
422: ea->reg = 0;
423: if ((ea->imm.val < 0) || (ea->imm.val > 65535)) error ("Immediate value too large.");
424: }
425: else if (size == LONG) ea->reg = 1;
426: else error ("Bad size.");
427: return pos;
428: }
429: while (isspace (*pos)) pos++;
430: if (((*pos == ',') || (*pos == '\0')) && (flags & F_MEM_L)) {
431: /* Immed memory with label */
432: ea->mode = 0x7;
433: ea->reg = 1;
434: return pos;
435: }
436: if (*pos != '(') goto err;
437: /* adr reg or pc indexed or offset */
438: pos++;
439: if ((pos[0] == 'p') && (pos[1] == 'c')) {
440: /* pc relative */
441: pos += 2;
442: if ((pos [0] == ')') && (flags & F_PC_OFFSET)) {
443: if ((ea->imm.val < -32768) || (ea->imm.val > 32767)) error ("Immediate value too large.");
444: ea->mode = 7;
445: ea->reg = 2;
446: return ++pos;
447: }
448: if (!(flags & F_PC_INDEX)) goto err;
449: check (',');
450: pos = get_reg (pos, ®, F_AREG | F_DREG);
451: ea->ext.ext = 0;
452: if (reg > 7) {
453: ea->ext._.reg = reg-8;
454: ea->ext._.d_or_a = 1;
455: } else {
456: ea->ext._.reg = reg;
457: ea->ext._.d_or_a = 0;
458: }
459: check ('.');
460: if (pos[0] == 'l') {
461: ea->ext._.size = 1;
462: } else if (pos[0] == 'w') {
463: ea->ext._.size = 0;
464: } else error ("Index register must have size.");
465: pos++;
466: check (')');
467: ea->mode = 7;
468: ea->reg = 3;
469: return pos;
470: } else {
471: /* adr with index/offset */
472: pos = get_reg (pos, &ea->reg, F_AREG);
473: if ((flags & F_OFFSET) && (pos[0] == ')')) {
474: /* with offset only */
475: if ((ea->imm.val < -32768) || (ea->imm.val > 32767)) error ("Immediate value too large.");
476: ea->mode = 5;
477: return ++pos;
478: }
479: if (!(flags & F_INDEX)) goto err;
480: check (',');
481: pos = get_reg (pos, ®, F_AREG | F_DREG);
482: if ((ea->imm.val < -128) || (ea->imm.val > 127)) error ("Immediate value too large.");
483: ea->ext.ext = 0;
484: ea->ext._.displacement = ea->imm.val;
485: if (reg > 7) {
486: ea->ext._.reg = reg-8;
487: ea->ext._.d_or_a = 1;
488: } else {
489: ea->ext._.reg = reg;
490: ea->ext._.d_or_a = 0;
491: }
492: check ('.');
493: if (pos[0] == 'l') {
494: ea->ext._.size = 1;
495: } else if (pos[0] == 'w') {
496: ea->ext._.size = 0;
497: } else error ("Index register must have size.");
498: pos++;
499: check (')');
500: ea->mode = 6;
501: return pos;
502: }
503: }
504: error ("Illegal effective address.");
505: err:
506: error ("Malformed effective address. Valid modes are: %s%s%s%s%s%s%s%s%s%s%s%s",
507: (flags & F_DREG ? "dreg " : ""),
508: (flags & F_AREG ? "areg " : ""),
509: (flags & F_IND ? "indirect " : ""),
510: (flags & F_POST ? "postincrement ": ""),
511: (flags & F_PRE ? "predecrement ": ""),
512: (flags & F_OFFSET ? "areg-offset ": ""),
513: (flags & F_OFFSET ? "areg-offset-index ": ""),
514: (flags & F_MEM_W ? "absolute.w ": ""),
515: (flags & F_MEM_L ? "absolute.l ": ""),
516: (flags & F_IMM ? "immediate ": ""),
517: (flags & F_PC_OFFSET ? "pc-relative ": ""),
518: (flags & F_PC_INDEX ? "pc-rel-index ": ""));
519: return NULL;
520: }
521:
522: int _reg_num (char *cunt)
523: {
524: int is_areg;
525: int num;
526:
527: if (cunt[0] == 'a') is_areg = 8;
528: else is_areg = 0;
529: cunt++;
530:
531: if (sscanf (cunt, "%d", &num) != 1) return -1;
532: num += is_areg;
533:
534: while (isdigit (*cunt)) cunt++;
535: if (isalpha (*cunt)) return -1;
536: return num;
537: }
538:
539: /* movem is a wanking cunt of doom */
540: /* this is such a sinful mess :-) */
541: char *parse_movem (char *pos, int size)
542: {
543: union Opcode op;
544: char *start = pos;
545: char lab1[LAB_LEN];
546: int lo, hi;
547: /* d0-7,a0-7 */
1.1.1.2 ! root 548: int Regs[16];
1.1 root 549: int dr = 0; /* reg to mem */
1.1.1.2 ! root 550: ea_t ea, ea2;
! 551: memset (Regs, 0, 16*sizeof(int));
1.1 root 552: try_again:
553: if ((pos[0] == 'a') || (pos[0] == 'd')) {
554: more_to_come:
555: pos = rd_label (pos, lab1);
556: lo = _reg_num (lab1);
557: if (lo == -1) {
558: mess:
559: /* mem to reg */
560: dr = 1;
561: pos = start;
562: pos = get_ea (pos, &ea, size, F_IND | F_POST | F_INDEX | F_OFFSET | F_MEM_W | F_MEM_L | F_PC_OFFSET | F_PC_INDEX);
563: if (pos[0] != ',') goto err;
564: pos++;
565: goto try_again;
566: }
567:
568: if (*pos == '-') {
569: /* range of fucking registers */
570: pos++;
571: if (sscanf (pos, "%d", &hi) != 1) goto err;
572: pos++;
573: if ((hi < 0) || (hi > 7)) goto err;
574: if (lo > 7) hi += 8;
575: } else {
576: hi = lo;
577: }
1.1.1.2 ! root 578: for (; lo<=hi; lo++) Regs[lo] = 1;
1.1 root 579: if (pos[0] == '/') {
580: pos++;
581: goto more_to_come;
582: }
583: } else {
584: goto mess;
585: }
586: if (!dr) {
587: /* reg to mem */
588: if (pos[0] != ',') goto err;
589: pos++;
590: pos = get_ea (pos, &ea, size, F_IND | F_PRE | F_INDEX | F_OFFSET | F_MEM_W | F_MEM_L);
591: }
592: op.code = 0x4880;
593: op.movem.sz = (size == WORD ? 0 : 1);
594: op.movem.dr = dr;
595: op.movem.dest_reg = ea.reg;
596: op.movem.dest_mode = ea.mode;
597: wr_short (op.code);
598:
599: hi = 0;
600: if (ea.mode == 0x4) {
601: /* predecrement mode */
602: for (lo=0; lo < 16; lo++) {
1.1.1.2 ! root 603: if (Regs[15-lo]) hi |= (1<<lo);
1.1 root 604: }
605: } else {
606: for (lo=0; lo < 16; lo++) {
1.1.1.2 ! root 607: if (Regs[lo]) hi |= (1<<lo);
1.1 root 608: }
609: }
610: wr_short (hi);
611: /* movem seems to count offsets relative to the
612: * register bitfield... */
613: last_op_addr += 2;
614: wr_ea (&ea);
1.1.1.2 ! root 615:
! 616: if (output_c) {
! 617: /* register mask in ea2->reg */
! 618: ea2.reg = hi;
! 619: comp->push_op2 (OP_MOVEM, &ea, &ea2, size, op.code);
! 620: }
! 621:
1.1 root 622: return pos;
623: err:
624: error ("your movem is all wanked up.");
625: return NULL;
626: }
627:
1.1.1.2 ! root 628: static char *do_dcx_labelled (char *pos, int size, struct ImmVal *imm)
! 629: {
! 630: struct Label *l;
! 631: char lab2[LAB_LEN];
! 632: int rel_to = 0;
! 633:
! 634: if (*pos == '-') {
! 635: /* form: LABEL1-LABEL2. LABEL2 must be resolvable NOW */
! 636: pos = rd_label (++pos, lab2);
! 637:
! 638: l = get_label (lab2);
! 639: if (l == NULL) error ("Error. dc.x LABEL1-LABEL2 must have resolvable LABEL2 on first pass.");
! 640:
! 641: rel_to = l->val;
! 642: }
! 643:
! 644: switch (size) {
! 645: case BYTE:
! 646: wr_byte (0);
! 647: add_fixup_rel_to (get_bitpos()-1, BYTE, imm->label, rel_to);
! 648: break;
! 649: case WORD:
! 650: wr_short (0);
! 651: add_fixup_rel_to (get_bitpos()-2, WORD, imm->label, rel_to);
! 652: break;
! 653: case LONG: default:
! 654: wr_int (0);
! 655: add_fixup_rel_to (get_bitpos()-4, LONG_FIXUP, imm->label, rel_to);
! 656: break;
! 657: }
! 658: return pos;
! 659: }
! 660:
! 661: int asm_pass1 (const char *bin_filename)
1.1 root 662: {
663: int i, reg, size;
664: union Opcode op;
665: struct ImmVal imm;
666: char lab1[LAB_LEN];
667: char *equ_lab;
668: char *pos;
669: ea_t ea;
670: ea_t ea2;
1.1.1.2 ! root 671: int coutput_label;
1.1 root 672:
673: wr_short (0x601a);
674: wr_int (0);
675: wr_int (0);
676: wr_int (0);
677: wr_int (0);
678: wr_int (0);
679: wr_int (0);
680: wr_short (0);
681:
682: dict_init (&labels);
683:
1.1.1.2 ! root 684: if (output_c) comp->begin (src_filename, bin_filename);
! 685:
1.1 root 686: while (fgets (buf, sizeof (buf), fin)) {
687: last_op_addr = get_bitpos ();
688: line_no++;
689: pos = &buf[0];
690: /* comments */
691: equ_lab = NULL;
692: while (isspace (*pos)) pos++;
693: if (*pos == '\0') continue;
694: if (*pos == '*') continue;
1.1.1.2 ! root 695: if (*pos == ':') {
! 696: /* empty label (": moveq...") signifies a valid
! 697: * computed jump target without a defined label.
! 698: * Helpful for optimising generated asm output. */
! 699: coutput_label = 1;
! 700: pos++;
! 701: check_whitespace ();
! 702: if (*pos == '\0') continue;
! 703: }
1.1 root 704: else if (isalpha (*pos)) {
705: equ_lab = pos;
706: pos = rd_label (pos, lab1);
707: if (*pos == ':') {
708: /* add label */
709: add_label (lab1, L_ADDR, get_bitpos () - BASE);
710: if (dump_labels) {
1.1.1.2 ! root 711: fprintf (stderr, "0x%x: %s\n", get_bitpos () - BASE, lab1);
! 712: }
! 713: if (output_c) {
! 714: comp->label (lab1);
1.1 root 715: }
1.1.1.2 ! root 716: coutput_label = 1;
1.1 root 717: equ_lab = NULL;
718: pos++;
719: check_whitespace ();
720: if (*pos == '\0') continue;
721: }
722: while (isspace (*pos)) pos++;
723: }
1.1.1.2 ! root 724:
1.1 root 725: /* EQU */
726: if (strncmp (pos, "equ", 3) == 0) {
727: pos += 3;
728: check_whitespace();
729: if (!equ_lab) error ("EQU without label.");
730: pos = get_imm (pos, &imm, F_NOLABELS);
731: add_label (lab1, L_CONST, imm.val);
1.1.1.2 ! root 732: coutput_label = 0;
1.1 root 733: continue;
734: }
735: if (equ_lab) {
736: pos = equ_lab;
737: equ_lab = NULL;
738: }
739:
740: /* DC.X */
741: if (strncmp (pos, "dc.", 3) == 0) {
742: size = get_size (pos[3]);
743: pos += 4;
744: check_whitespace();
1.1.1.2 ! root 745: coutput_label = 0;
1.1 root 746: if ((size == BYTE) && (*pos == '"')) {
747: thing:
748: pos++;
749: while (*pos != '"') {
750: wr_byte (*pos);
751: pos++;
752: }
753: /* double '""' escapes */
754: pos++;
755: if (*pos == '"') {
756: wr_byte ('"');
757: goto thing;
758: }
759: while (isspace (*pos)) pos++;
760: if (*pos != ',') {
761: check_end (pos);
762: continue;
763: }
764: pos++;
765: }
766: while (isdigit (*pos) || isalpha (*pos) || (*pos == '$')) {
767: pos = get_imm (pos, &imm, 0);
768: if (imm.has_label) {
1.1.1.2 ! root 769: pos = do_dcx_labelled (pos, size, &imm);
1.1 root 770: } else {
771: switch (size) {
772: case BYTE: wr_byte (imm.val); break;
773: case WORD: wr_short (imm.val); break;
774: case LONG: default: wr_int (imm.val); break;
775: }
776: }
777: while (isspace (*pos)) pos++;
778: if (*pos != ',') break;
779: pos++;
780: while (isspace (*pos)) pos++;
781: }
782: check_end (pos);
783: continue;
784: }
785: /* DS.X */
786: if (strncmp (pos, "ds.", 3) == 0) {
787: size = get_size (pos[3]);
788: pos += 4;
789: check_whitespace();
790: pos = get_imm (pos, &imm, F_NOLABELS);
791: check_end (pos);
792: for (i=0; i<imm.val; i++) {
793: if (size == BYTE) wr_byte (0);
794: else if (size == WORD) wr_short (0);
795: else wr_int (0);
796: }
797: continue;
798: }
1.1.1.2 ! root 799:
! 800: if (output_c) {
! 801: comp->addr_label (coutput_label);
! 802: }
! 803: coutput_label = 0;
! 804:
1.1 root 805: /* odd address checking */
806: if (last_op_addr & 0x1) error ("Odd address.");
807: /* ADDQ/SUBQ */
808: if ((strncmp (pos, "addq", 4)==0) ||
809: (strncmp (pos, "subq", 4)==0)) {
810: op.code = 0x5000;
811: op.addq.issub = (pos[0] == 's');
812: pos += 4;
813: check ('.');
814: size = get_size (pos[0]);
815: pos++;
816: check_whitespace();
817: pos = get_imm (pos, &imm, F_NOLABELS | F_IMM);
818: if ((imm.val < 1) || (imm.val > 8)) error ("Immediate value too large.");
819: check (',');
820: pos = get_ea (pos, &ea, LONG, F_DREG | F_AREG | F_IND | F_POST | F_PRE | F_INDEX | F_OFFSET | F_MEM_W | F_MEM_L);
821: if ((size == BYTE) && (ea.mode == 1)) error ("Bad size for address reg direct.");
822: check_end (pos);
823: op.addq.dest_reg = ea.reg;
824: op.addq.dest_mode = ea.mode;
825: op.addq.size = size;
1.1.1.2 ! root 826: op.addq.data = (imm.val == 8 ? 0 : imm.val);
1.1 root 827: wr_short (op.code);
828: wr_ea (&ea);
1.1.1.2 ! root 829:
! 830: if (output_c) {
! 831: ea.op_size = size;
! 832: ea2.op_size = size;
! 833: ea_set_immediate (&ea2, imm.val);
! 834:
! 835: if (ea.mode == 1) {
! 836: /* to areg is special: no condition codes set */
! 837: if (op.addq.issub) {
! 838: comp->push_op (OP_SUBA, &ea2, &ea, size);
! 839: } else {
! 840: comp->push_op (OP_ADDA, &ea2, &ea, size);
! 841: }
! 842: } else {
! 843: if (op.addq.issub) {
! 844: comp->push_op (OP_SUB, &ea2, &ea, size);
! 845: } else {
! 846: comp->push_op (OP_ADD, &ea2, &ea, size);
! 847: }
! 848: }
! 849: }
1.1 root 850: continue;
851: }
852: /* NOP */
853: if (strncmp (pos, "nop", 3) == 0) {
854: pos += 3;
855: check_end (pos);
856: wr_short (0x4e71);
857: continue;
858: }
859: /* NOT/NEGX/NEG */
860: if (strncmp (pos, "not", 3) == 0) {
861: pos += 3;
862: check ('.');
863: size = get_size (pos[0]);
864: pos++;
865: check_whitespace();
866: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG);
867: check_end (pos);
868: op.code = 0x4600;
869: op.type1.size = size;
870: op.type1.ea_reg = ea.reg;
871: op.type1.ea_mode = ea.mode;
872: wr_short (op.code);
873: wr_ea (&ea);
1.1.1.2 ! root 874:
! 875: if (output_c) {
! 876: comp->push_op (OP_NOT, &ea, NULL, size);
! 877: }
1.1 root 878: continue;
879: }
880: if (strncmp (pos, "negx", 4) == 0) {
881: pos += 4;
882: check ('.');
883: size = get_size (pos[0]);
884: pos++;
885: check_whitespace();
886: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG);
887: check_end (pos);
888: op.code = 0x4000;
889: op.type1.size = size;
890: op.type1.ea_reg = ea.reg;
891: op.type1.ea_mode = ea.mode;
892: wr_short (op.code);
893: wr_ea (&ea);
1.1.1.2 ! root 894:
! 895: if (output_c) {
! 896: comp->push_op (OP_NEGX, &ea, NULL, size);
! 897: }
1.1 root 898: continue;
899: }
900: if (strncmp (pos, "neg", 3) == 0) {
901: pos += 3;
902: check ('.');
903: size = get_size (pos[0]);
904: pos++;
905: check_whitespace();
906: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG);
907: check_end (pos);
908: op.code = 0x4400;
909: op.type1.size = size;
910: op.type1.ea_reg = ea.reg;
911: op.type1.ea_mode = ea.mode;
912: wr_short (op.code);
913: wr_ea (&ea);
1.1.1.2 ! root 914:
! 915: if (output_c) {
! 916: comp->push_op (OP_NEG, &ea, NULL, size);
! 917: }
1.1 root 918: continue;
919: }
920: /* DIVS/DIVU */
1.1.1.2 ! root 921: if ((strncmp (pos, "divs", 3) == 0) ||
! 922: (strncmp (pos, "divu", 3) == 0)) {
! 923: int _signed = 0;
1.1 root 924: pos += 3;
1.1.1.2 ! root 925: if (pos[0] == 's') { op.code = 0x81c0; _signed = 1; }
1.1 root 926: else op.code = 0x80c0;
927: pos++;
928: check_whitespace();
929: pos = get_ea (pos, &ea, WORD, F_ALL_NOAREG);
930: check (',');
1.1.1.2 ! root 931: pos = get_ea (pos, &ea2, WORD, F_DREG);
1.1 root 932: check_end (pos);
1.1.1.2 ! root 933: op.type2.reg = ea2.reg;
1.1 root 934: op.type2.ea_mode = ea.mode;
935: op.type2.ea_reg = ea.reg;
936: wr_short (op.code);
937: wr_ea (&ea);
1.1.1.2 ! root 938:
! 939: if (output_c) {
! 940: if (_signed) {
! 941: comp->push_op (OP_DIVS, &ea, &ea2, WORD);
! 942: } else {
! 943: comp->push_op (OP_DIVU, &ea, &ea2, WORD);
! 944: }
! 945: }
1.1 root 946: continue;
947: }
948: /* MULS/MULU */
949: if (strncmp (pos, "mul", 3) == 0) {
950: pos += 3;
1.1.1.2 ! root 951: int _signed = 0;
! 952: if (pos[0] == 's') { op.code = 0xc1c0; _signed = 1; }
1.1 root 953: else op.code = 0xc0c0;
954: pos++;
955: check_whitespace();
956: pos = get_ea (pos, &ea, WORD, F_ALL_NOAREG);
957: check (',');
1.1.1.2 ! root 958: pos = get_ea (pos, &ea2, WORD, F_DREG);
1.1 root 959: check_end (pos);
1.1.1.2 ! root 960: op.type2.reg = ea2.reg;
1.1 root 961: op.type2.ea_mode = ea.mode;
962: op.type2.ea_reg = ea.reg;
963: wr_short (op.code);
964: wr_ea (&ea);
1.1.1.2 ! root 965:
! 966: if (output_c) {
! 967: if (_signed) {
! 968: comp->push_op (OP_MULS, &ea, &ea2, WORD);
! 969: } else {
! 970: comp->push_op (OP_MULU, &ea, &ea2, WORD);
! 971: }
! 972: }
1.1 root 973: continue;
974: }
975: /* ADDI/SUBI */
976: if ((strncmp (pos, "addi", 4) == 0) ||
977: (strncmp (pos, "subi", 4) == 0)) {
1.1.1.2 ! root 978: int sub = 0;
! 979: if (pos[0] == 'a') {
! 980: op.code = 0x0600;
! 981: } else {
! 982: op.code = 0x0400;
! 983: sub = 1;
! 984: }
1.1 root 985: pos += 4;
986: check ('.');
987: size = get_size (pos[0]);
988: pos++;
989: check_whitespace();
990: pos = get_ea (pos, &ea2, size, F_IMM);
991: check (',');
992: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG);
993: check_end (pos);
994: op.type1.size = size;
995: op.type1.ea_reg = ea.reg;
996: op.type1.ea_mode = ea.mode;
997: wr_short (op.code);
998: if (size == BYTE) {
999: wr_short (ea2.imm.val & 0xff);
1000: } else if (size == WORD) {
1001: wr_short (ea2.imm.val);
1002: } else {
1003: wr_int (ea2.imm.val);
1004: }
1005: wr_ea (&ea);
1.1.1.2 ! root 1006:
! 1007: if (output_c) {
! 1008: if (sub) {
! 1009: comp->push_op (OP_SUB, &ea2, &ea, size);
! 1010: } else {
! 1011: comp->push_op (OP_ADD, &ea2, &ea, size);
! 1012: }
! 1013: }
! 1014:
1.1 root 1015: continue;
1016: }
1017: /* ADDA/SUBA */
1018: if ((strncmp (pos, "adda", 4) == 0) ||
1019: (strncmp (pos, "suba", 4) == 0)) {
1.1.1.2 ! root 1020: int is_sub = 0;
1.1 root 1021: if (pos[0] == 'a') op.code = 0xd000;
1.1.1.2 ! root 1022: else { op.code = 0x9000; is_sub = 1; }
1.1 root 1023: pos += 4;
1024: check ('.');
1025: size = get_size (pos[0]);
1026: if (size == BYTE) error ("Crap size for adda.");
1027: pos++;
1028: check_whitespace();
1029: pos = get_ea (pos, &ea, size, F_ALL);
1030: check (',');
1.1.1.2 ! root 1031: pos = get_ea (pos, &ea2, size, F_AREG);
1.1 root 1032: check_end (pos);
1.1.1.2 ! root 1033: op.type2.reg = ea2.reg;
! 1034: op.type2.op_mode = (size == WORD ? 3 : 7);
1.1 root 1035: op.type2.ea_reg = ea.reg;
1036: op.type2.ea_mode = ea.mode;
1037: wr_short (op.code);
1038: wr_ea (&ea);
1.1.1.2 ! root 1039:
! 1040: if (output_c) {
! 1041: if (is_sub) {
! 1042: comp->push_op (OP_SUBA, &ea, &ea2, size);
! 1043: } else {
! 1044: comp->push_op (OP_ADDA, &ea, &ea2, size);
! 1045: }
! 1046: }
1.1 root 1047: continue;
1048: }
1049: /* ADDX/SUBX */
1050: if ((strncmp (pos, "addx", 4) == 0) ||
1051: (strncmp (pos, "subx", 4) == 0)) {
1.1.1.2 ! root 1052: int _type = pos[0];
1.1 root 1053: if (pos[0] == 'a') op.code = 0xd100;
1054: else op.code = 0x9100;
1055: pos += 4;
1056: check ('.');
1057: size = get_size (pos[0]);
1058: op.addx.size = size;
1059: pos++;
1060: check_whitespace();
1061: pos = get_ea (pos, &ea, size, F_DREG | F_PRE);
1062: if (ea.mode == 0) {
1063: /* Dn,Dn mode */
1064: check (',');
1065: op.addx.src_reg = ea.reg;
1066: op.addx.rm = 0;
1067: pos = get_reg (pos, &i, F_DREG);
1068: check_end (pos);
1069: op.addx.dest_reg = i;
1070: wr_short (op.code);
1.1.1.2 ! root 1071:
! 1072: if (output_c) {
! 1073: ea2.mode = 0; ea2.reg = i; ea2.op_size = size;
! 1074:
! 1075: if (_type == 'a') comp->push_op (OP_ADDX, &ea, &ea2, size);
! 1076: else comp->push_op (OP_SUBX, &ea, &ea2, size);
! 1077: }
1.1 root 1078: } else {
1079: /* -(An),-(An) mode */
1080: check (',');
1081: op.addx.src_reg = ea.reg;
1082: op.addx.rm = 1;
1.1.1.2 ! root 1083: pos = get_ea (pos, &ea2, size, F_PRE);
! 1084: op.addx.dest_reg = ea2.reg;
1.1 root 1085: wr_short (op.code);
1.1.1.2 ! root 1086:
! 1087: if (output_c) {
! 1088: if (_type == 'a') comp->push_op (OP_ADDX, &ea, &ea2, size);
! 1089: else comp->push_op (OP_SUBX, &ea, &ea2, size);
! 1090: }
1.1 root 1091: }
1092: check_end (pos);
1093: continue;
1094: }
1095: /* ADD/SUB */
1096: if ((strncmp (pos, "add", 3) == 0) ||
1097: (strncmp (pos, "sub", 3) == 0)) {
1.1.1.2 ! root 1098: int sub = 0;
1.1 root 1099: if (pos[0] == 'a') op.code = 0xd000;
1.1.1.2 ! root 1100: else {
! 1101: op.code = 0x9000;
! 1102: sub = 1;
! 1103: }
1.1 root 1104: pos += 3;
1105: check ('.');
1106: size = get_size (pos[0]);
1107: pos++;
1108: check_whitespace();
1109: pos = get_ea (pos, &ea, size, F_ALL);
1110: check (',');
1111: pos = get_ea (pos, &ea2, size, F_DREG | F_IND | F_POST | F_PRE | F_OFFSET | F_INDEX | F_MEM_W | F_MEM_L);
1112: if (ea2.mode == 0) {
1113: /* data reg dest */
1114: op.type2.reg = ea2.reg;
1115: op.type2.op_mode = size;
1116: op.type2.ea_reg = ea.reg;
1117: op.type2.ea_mode = ea.mode;
1118: wr_short (op.code);
1119: wr_ea (&ea);
1120: } else {
1121: /* ea dest */
1122: if (ea.mode != 0) error ("One operand must be a data register.");
1123: op.type2.reg = ea.reg;
1124: op.type2.op_mode = size+4;
1125: op.type2.ea_reg = ea2.reg;
1126: op.type2.ea_mode = ea2.mode;
1127: wr_short (op.code);
1128: wr_ea (&ea2);
1129: }
1130: check_end (pos);
1.1.1.2 ! root 1131:
! 1132: if (output_c) {
! 1133: ea.op_size = size;
! 1134: ea2.op_size = size;
! 1135:
! 1136: if (sub) {
! 1137: comp->push_op (OP_SUB, &ea, &ea2, size);
! 1138: } else {
! 1139: comp->push_op (OP_ADD, &ea, &ea2, size);
! 1140: }
! 1141: }
1.1 root 1142: continue;
1143: }
1144: /* BCHG/BCLR/BSET/BTST */
1145: if ((strncmp (pos, "bchg", 4)==0) ||
1146: (strncmp (pos, "bclr", 4)==0) ||
1147: (strncmp (pos, "bset", 4)==0) ||
1148: (strncmp (pos, "btst", 4)==0)) {
1149: int type;
1150: switch (pos[2]) {
1151: /* bchg */
1152: case 'h': type = 0; break;
1153: /* bclr */
1154: case 'l': type = 1; break;
1155: /* bset */
1156: case 'e': type = 2; break;
1157: /* btst */
1158: default: case 's': type = 3; break;
1159: }
1160: pos += 4;
1161: check_whitespace();
1162: pos = get_ea (pos, &ea, BYTE, F_IMM | F_DREG);
1163: if (ea.mode == 0) {
1164: /* Dn,<ea> mode */
1165: switch (type) {
1166: case 0: op.code = 0x0140; break;
1167: case 1: op.code = 0x0180; break;
1168: case 2: op.code = 0x01c0; break;
1169: case 3: op.code = 0x0100; break;
1170: }
1171: op.type2.reg = ea.reg;
1172: check (',');
1.1.1.2 ! root 1173: pos = get_ea (pos, &ea2, size, F_NOIMM_NOPC_NOAREG);
! 1174: op.type2.ea_reg = ea2.reg;
! 1175: op.type2.ea_mode = ea2.mode;
1.1 root 1176: wr_short (op.code);
1.1.1.2 ! root 1177: wr_ea (&ea2);
1.1 root 1178: } else {
1179: /* IMM,<ea> mode */
1180: check_range (&ea.imm.val, BYTE);
1181: imm.val = ea.imm.val;
1182: switch (type) {
1183: case 0: op.code = 0x0840; break;
1184: case 1: op.code = 0x0880; break;
1185: case 2: op.code = 0x08c0; break;
1186: case 3: op.code = 0x0800; break;
1187: }
1188: check (',');
1189: if (type == 3) {
1.1.1.2 ! root 1190: pos = get_ea (pos, &ea2, size, F_DREG | F_IND | F_POST | F_PRE | F_OFFSET | F_INDEX | F_MEM_W | F_MEM_L | F_PC_OFFSET | F_PC_INDEX);
1.1 root 1191: } else {
1.1.1.2 ! root 1192: pos = get_ea (pos, &ea2, size, F_NOIMM_NOPC_NOAREG);
1.1 root 1193: }
1.1.1.2 ! root 1194: op.type2.ea_mode = ea2.mode;
! 1195: op.type2.ea_reg = ea2.reg;
1.1 root 1196: wr_short (op.code);
1197: wr_short (imm.val & 0xff);
1.1.1.2 ! root 1198: wr_ea (&ea2);
1.1 root 1199: }
1200: check_end (pos);
1.1.1.2 ! root 1201:
! 1202: if (output_c) {
! 1203: if (ea2.mode == 0) {
! 1204: size = LONG;
! 1205: } else {
! 1206: size = BYTE;
! 1207: }
! 1208: ea2.op_size = ea.op_size = size;
! 1209: switch (type) {
! 1210: /* bchg */
! 1211: case 0: comp->push_op (OP_BCHG, &ea, &ea2, size); break;
! 1212: /* bclr */
! 1213: case 1: comp->push_op (OP_BCLR, &ea, &ea2, size); break;
! 1214: /* bset */
! 1215: case 2: comp->push_op (OP_BSET, &ea, &ea2, size); break;
! 1216: /* btst */
! 1217: default: case 3:
! 1218: comp->push_op (OP_BTST, &ea, &ea2, size); break;
! 1219: }
! 1220: }
1.1 root 1221: continue;
1222: }
1223: /* ASx/LSx/ROx ROXx */
1224: if ((strncmp (pos, "ls", 2) == 0) ||
1225: (strncmp (pos, "as", 2) == 0) ||
1226: (strncmp (pos, "ro", 2) == 0)) {
1227: char dir;
1228: int type;
1229: dir = pos[2];
1230: if (pos[0] == 'a') type = 0;
1231: else if (pos[0] == 'l') type = 1;
1232: else if (pos[0] == 'r') {
1233: if (pos[2] == 'x') {
1234: type = 2;
1235: dir = pos[3];
1236: }
1237: else type = 3;
1238: } else {
1239: goto blork;
1240: }
1241: if ((dir != 'l') && (dir != 'r')) goto blork;
1242: dir = (dir == 'l' ? 1 : 0);
1243: while (isalpha (*pos)) pos++;
1244: check ('.');
1245: size = get_size (pos[0]);
1246: pos++;
1247: check_whitespace();
1248: pos = get_ea (pos, &ea, size, F_DREG | F_IND | F_POST | F_PRE | F_OFFSET | F_INDEX | F_MEM_W | F_MEM_L | F_IMM);
1.1.1.2 ! root 1249:
1.1 root 1250: if (ea.mode == 0) {
1251: /* data reg type */
1252: check (',');
1253: pos = get_reg (pos, ®, F_DREG);
1254: check_end (pos);
1255: if (type == 1) op.code = 0xe008;
1256: else if (type == 0) op.code = 0xe000;
1257: else if (type == 2) op.code = 0xe010;
1258: else op.code = 0xe018;
1259: op.ASx.count_reg = ea.reg;
1260: op.ASx.dr = dir;
1261: op.ASx.size = size;
1262: op.ASx.ir = 1;
1263: op.ASx.reg = reg;
1264: wr_short (op.code);
1.1.1.2 ! root 1265:
! 1266: if (output_c) {
! 1267: ea.op_size = size;
! 1268: ea2.op_size = size;
! 1269: ea2.mode = 0; ea2.reg = reg;
! 1270:
! 1271: if (type == 0) {
! 1272: if (dir) comp->push_op (OP_ASL, &ea, &ea2, size);
! 1273: else comp->push_op (OP_ASR, &ea, &ea2, size);
! 1274: } else if (type == 1) {
! 1275: if (dir) comp->push_op (OP_LSL, &ea, &ea2, size);
! 1276: else comp->push_op (OP_LSR, &ea, &ea2, size);
! 1277: } else if (type == 2) {
! 1278: if (dir) comp->push_op (OP_ROXL, &ea, &ea2, size);
! 1279: else comp->push_op (OP_ROXR, &ea, &ea2, size);
! 1280: } else if (type == 3) {
! 1281: if (dir) comp->push_op (OP_ROL, &ea, &ea2, size);
! 1282: else comp->push_op (OP_ROR, &ea, &ea2, size);
! 1283: } else {
! 1284: error ("C code not generated (work unfinished).");
! 1285: }
! 1286: }
1.1 root 1287: continue;
1288: } else if ((ea.mode == 7) && (ea.reg == 4)) {
1289: /* imm,Dn type */
1290: check (',');
1291: pos = get_reg (pos, ®, F_DREG);
1292: check_end (pos);
1293: if (type == 1) op.code = 0xe008;
1294: else if (type == 0) op.code = 0xe000;
1295: else if (type == 2) op.code = 0xe010;
1296: else op.code = 0xe018;
1297: if ((ea.imm.val < 1) || (ea.imm.val > 8)) error ("Bad immediate value.");
1.1.1.2 ! root 1298: op.ASx.count_reg = (ea.imm.val == 8 ? 0 : ea.imm.val);
1.1 root 1299: op.ASx.dr = dir;
1300: op.ASx.size = size;
1301: op.ASx.ir = 0;
1302: op.ASx.reg = reg;
1303: wr_short (op.code);
1.1.1.2 ! root 1304:
! 1305: if (output_c) {
! 1306: ea.op_size = size;
! 1307: ea2.op_size = size;
! 1308: ea2.mode = 0; ea2.reg = reg;
! 1309:
! 1310: if (type == 0) {
! 1311: if (dir) comp->push_op (OP_ASL, &ea, &ea2, size);
! 1312: else comp->push_op (OP_ASR, &ea, &ea2, size);
! 1313: } else if (type == 1) {
! 1314: if (dir) comp->push_op (OP_LSL, &ea, &ea2, size);
! 1315: else comp->push_op (OP_LSR, &ea, &ea2, size);
! 1316: } else if (type == 2) {
! 1317: if (dir) comp->push_op (OP_ROXL, &ea, &ea2, size);
! 1318: else comp->push_op (OP_ROXR, &ea, &ea2, size);
! 1319: } else if (type == 3) {
! 1320: if (dir) comp->push_op (OP_ROL, &ea, &ea2, size);
! 1321: else comp->push_op (OP_ROR, &ea, &ea2, size);
! 1322: } else {
! 1323: error ("C code not generated (work unfinished).");
! 1324: }
! 1325: }
1.1 root 1326: continue;
1327: } else {
1328: /* ea mode */
1329: if (size != WORD) error ("Illegal size.");
1330: check_end (pos);
1331: if (type == 1) op.code = 0xe2c0;
1332: else if (type == 0) op.code = 0xe0c0;
1333: else if (type == 2) op.code = 0xe4c0;
1334: else op.code = 0xe6c0;
1335: op.ASx.dr = dir;
1336: op.type1.ea_reg = ea.reg;
1337: op.type1.ea_mode = ea.mode;
1338: wr_short (op.code);
1339: wr_ea (&ea);
1.1.1.2 ! root 1340:
! 1341: if (output_c) {
! 1342: ea.op_size = size;
! 1343: ea2.op_size = size;
! 1344: ea_set_immediate (&ea2, 1);
! 1345: if (type == 0) {
! 1346: if (dir) comp->push_op (OP_ASL, &ea2, &ea, size);
! 1347: else comp->push_op (OP_ASR, &ea2, &ea, size);
! 1348: } else if (type == 1) {
! 1349: if (dir) comp->push_op (OP_LSL, &ea2, &ea, size);
! 1350: else comp->push_op (OP_LSR, &ea2, &ea, size);
! 1351: } else if (type == 2) {
! 1352: if (dir) comp->push_op (OP_ROXL, &ea2, &ea, size);
! 1353: else comp->push_op (OP_ROXR, &ea2, &ea, size);
! 1354: } else if (type == 3) {
! 1355: if (dir) comp->push_op (OP_ROL, &ea2, &ea, size);
! 1356: else comp->push_op (OP_ROR, &ea2, &ea, size);
! 1357: } else {
! 1358: error ("C code not generated (work unfinished).");
! 1359: }
! 1360: }
1.1 root 1361: continue;
1362: }
1363: continue;
1364: }
1365: blork:
1366: /* ANDI/EORI/ORI */
1367: if ((strncmp (pos, "andi", 4) == 0) ||
1368: (strncmp (pos, "eori", 4) == 0) ||
1369: (strncmp (pos, "ori", 3) == 0)) {
1.1.1.2 ! root 1370: int _type = pos[0];
1.1 root 1371: if (pos[0] == 'a') {
1372: op.code = 0x0200;
1373: } else if (pos[0] == 'e') {
1374: op.code = 0x0a00;
1375: } else {
1376: op.code = 0x0000;
1377: }
1378: while (isalpha (*pos)) pos++;
1379: check ('.');
1380: size = get_size (pos[0]);
1381: pos++;
1382: check_whitespace();
1383: pos = get_imm (pos, &imm, F_NOLABELS | F_IMM);
1384: check_range (&imm.val, size);
1385: check (',');
1386: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG);
1387: check_end (pos);
1388: op.type1.ea_reg = ea.reg;
1389: op.type1.ea_mode = ea.mode;
1390: op.type1.size = size;
1391: wr_short (op.code);
1392: if (size == BYTE) {
1393: wr_short (imm.val & 0xff);
1394: } else if (size == WORD) {
1395: wr_short (imm.val);
1396: } else {
1397: wr_int (imm.val);
1398: }
1399: wr_ea (&ea);
1.1.1.2 ! root 1400:
! 1401: if (output_c) {
! 1402: ea2.op_size = size;
! 1403: ea_set_immediate (&ea2, imm.val);
! 1404:
! 1405: if (_type == 'e') {
! 1406: comp->push_op (OP_XOR, &ea2, &ea, size);
! 1407: } else if (_type == 'o') {
! 1408: comp->push_op (OP_OR, &ea2, &ea, size);
! 1409: } else if (_type == 'a') {
! 1410: comp->push_op (OP_AND, &ea2, &ea, size);
! 1411: }
! 1412: }
1.1 root 1413: continue;
1414: }
1415: /* AND/OR */
1416: if ((strncmp (pos, "and", 3) == 0) ||
1417: (strncmp (pos, "or", 2) == 0)) {
1.1.1.2 ! root 1418: int _type = pos[0];
1.1 root 1419: if (pos[0] == 'a') op.code = 0xc000;
1420: else op.code = 0x8000;
1421: while (isalpha (*pos)) pos++;
1422: check ('.');
1423: size = get_size (pos[0]);
1424: pos++;
1425: check_whitespace();
1426: pos = get_ea (pos, &ea, size, F_ALL_NOAREG);
1427: check (',');
1428: pos = get_ea (pos, &ea2, size, F_NOIMM_NOPC_NOAREG);
1429: check_end (pos);
1430: if (ea2.mode == 0) {
1431: /* data reg dest */
1432: op.type2.reg = ea2.reg;
1433: op.type2.op_mode = size;
1434: op.type2.ea_reg = ea.reg;
1435: op.type2.ea_mode = ea.mode;
1436: wr_short (op.code);
1437: wr_ea (&ea);
1438: } else {
1439: /* ea dest */
1440: if (ea.mode != 0) error ("One operand must be a data register.");
1441: op.type2.reg = ea.reg;
1442: op.type2.op_mode = size+4;
1443: op.type2.ea_reg = ea2.reg;
1444: op.type2.ea_mode = ea2.mode;
1445: wr_short (op.code);
1446: wr_ea (&ea2);
1447: }
1.1.1.2 ! root 1448:
! 1449: if (output_c) {
! 1450: if (_type == 'a')
! 1451: comp->push_op (OP_AND, &ea, &ea2, size);
! 1452: else
! 1453: comp->push_op (OP_OR, &ea, &ea2, size);
! 1454: }
1.1 root 1455: continue;
1456: }
1457: /* EOR */
1458: if (strncmp (pos, "eor", 3) == 0) {
1459: op.code = 0xb000;
1460: pos += 3;
1461: check ('.');
1462: size = get_size (pos[0]);
1463: pos++;
1464: check_whitespace();
1465: pos = get_reg (pos, ®, F_DREG);
1466: check (',');
1467: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG);
1468: check_end (pos);
1469: op.type2.reg = reg;
1.1.1.2 ! root 1470: op.type2.op_mode = size + 4;
1.1 root 1471: op.type2.ea_reg = ea.reg;
1472: op.type2.ea_mode = ea.mode;
1473: wr_short (op.code);
1474: wr_ea (&ea);
1.1.1.2 ! root 1475:
! 1476: if (output_c) {
! 1477: ea2.mode = 0; ea2.reg = reg;
! 1478: ea2.op_size = size;
! 1479: comp->push_op (OP_XOR, &ea2, &ea, size);
! 1480: }
1.1 root 1481: continue;
1482: }
1483: /* SWAP */
1484: if (strncmp (pos, "swap", 4) == 0) {
1485: pos += 4;
1.1.1.2 ! root 1486: pos = get_ea (pos, &ea, LONG, F_DREG);
1.1 root 1487: op.code = 0x4840;
1.1.1.2 ! root 1488: op.type2.ea_reg = ea.reg;
1.1 root 1489: check_end (pos);
1490: wr_short (op.code);
1.1.1.2 ! root 1491:
! 1492: if (output_c) {
! 1493: comp->push_op (OP_SWAP, &ea, NULL, 0);
! 1494: }
1.1 root 1495: continue;
1496: }
1497: /* BSR */
1498: if (strncmp (pos, "bsr", 3) == 0) {
1499: pos += 3;
1500: check ('.');
1501: size = pos[0];
1502: pos++;
1503: check_whitespace();
1.1.1.2 ! root 1504: pos = get_ea (pos, &ea, LONG, F_MEM_L);
! 1505: if (ea.imm.has_label == 0) error ("BSR desires a label.");
1.1 root 1506: check_end (pos);
1507: op.code = 0x6100;
1508: wr_short (op.code);
1509: if (size == 's') {
1.1.1.2 ! root 1510: add_fixup (get_bitpos()-1, BYTE, ea.imm.label);
1.1 root 1511: } else if (size == 'w') {
1512: wr_short (0);
1.1.1.2 ! root 1513: add_fixup (get_bitpos()-2, WORD, ea.imm.label);
1.1 root 1514: } else {
1515: error ("Invalid size '.%c'.", size);
1516: }
1.1.1.2 ! root 1517: if (output_c) {
! 1518: comp->push_op (OP_JSR, &ea, NULL, 0);
! 1519: }
1.1 root 1520: continue;
1521: }
1522: /* Bcc.S */
1523: if (pos[0] == 'b') {
1524: for (i=0; i<16; i++) {
1525: if (Bcc_str [i] == NULL) continue;
1526: if (strncmp (&pos[1], Bcc_str[i], 2)==0) break;
1527: }
1528: if (i==16) goto fuckit;
1529: pos += 3;
1530: check ('.');
1531: size = pos[0];
1532: pos++;
1533: check_whitespace();
1.1.1.2 ! root 1534: pos = get_ea (pos, &ea, LONG, F_MEM_L);
! 1535: if (ea.imm.has_label == 0) error ("BSR desires a label.");
1.1 root 1536: check_end (pos);
1537: op.code = 0x6000 | (i<<8);
1538: wr_short (op.code);
1539: if (size == 's') {
1.1.1.2 ! root 1540: add_fixup (get_bitpos()-1, BYTE, ea.imm.label);
1.1 root 1541: } else if (size == 'w') {
1542: wr_short (0);
1.1.1.2 ! root 1543: add_fixup (get_bitpos()-2, WORD, ea.imm.label);
1.1 root 1544: } else {
1545: error ("Invalid size '.%c'.", size);
1546: }
1.1.1.2 ! root 1547: if (output_c) {
! 1548: comp->push_op2 (OP_BCC, &ea, NULL, 0, op.code);
! 1549: }
1.1 root 1550: continue;
1551: }
1552: /* DBcc */
1553: if ((pos[0] == 'd') && (pos[1] == 'b')) {
1554: pos = rd_label (&pos[2], lab1);
1555: for (i=0; i<16; i++) {
1556: if (strncmp (lab1, DBcc_str[i], 2)==0) break;
1557: }
1558: if (i==16) {
1559: if (strncmp (lab1, "ra", 2)==0) {
1560: i = 1;
1561: } else {
1562: goto fuckit;
1563: }
1564: }
1565: while (isalpha (*pos)) pos++;
1566: check_whitespace();
1.1.1.2 ! root 1567: pos = get_ea (pos, &ea, WORD, F_DREG);
1.1 root 1568: check (',');
1.1.1.2 ! root 1569: pos = get_ea (pos, &ea2, LONG, F_MEM_L);
! 1570: if (ea2.imm.has_label == 0) error ("DBcc desires a label.");
1.1 root 1571: check_end (pos);
1572: op.code = 0x50c8;
1.1.1.2 ! root 1573: op.DBcc.reg = ea.reg;
1.1 root 1574: op.DBcc.cond = i;
1575: wr_short (op.code);
1576: wr_short (0);
1.1.1.2 ! root 1577: add_fixup (get_bitpos()-2, WORD, ea2.imm.label);
! 1578:
! 1579: if (output_c) {
! 1580: comp->push_op2 (OP_DBCC, &ea, &ea2, 0, op.code);
! 1581: }
1.1 root 1582: continue;
1583: }
1584: fuckit:
1585: /* CLR */
1586: if (strncmp (pos, "clr", 3) == 0) {
1587: pos += 3;
1588: check ('.');
1589: size = get_size (pos[0]);
1590: pos++;
1591: check_whitespace();
1592: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG);
1593: check_end (pos);
1594: op.code = 0x4200;
1595: op.type1.size = size;
1596: op.type1.ea_reg = ea.reg;
1597: op.type1.ea_mode = ea.mode;
1598: wr_short (op.code);
1599: wr_ea (&ea);
1.1.1.2 ! root 1600:
! 1601: if (output_c) {
! 1602: ea.op_size = size;
! 1603: comp->push_op (OP_CLR, &ea, NULL, size);
! 1604: }
1.1 root 1605: continue;
1606: }
1607: /* CMPI */
1608: if (strncmp (pos, "cmpi", 4) == 0) {
1609: pos += 4;
1610: check ('.');
1611: size = get_size (*pos);
1612: pos++;
1613: check_whitespace();
1614: pos = get_imm (pos, &imm, F_NOLABELS | F_IMM);
1615: check_range (&imm.val, size);
1616: check (',');
1617: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG);
1618: check_end (pos);
1619: op.code = 0x0c00;
1620: op.type1.ea_reg = ea.reg;
1621: op.type1.ea_mode = ea.mode;
1622: op.type1.size = size;
1623: wr_short (op.code);
1624: if (size == BYTE) {
1625: wr_short (imm.val & 0xff);
1626: } else if (size == WORD) {
1627: wr_short (imm.val);
1628: } else {
1629: wr_int (imm.val);
1630: }
1631: wr_ea (&ea);
1.1.1.2 ! root 1632:
! 1633: if (output_c) {
! 1634: ea.op_size = size;
! 1635: ea2.op_size = size;
! 1636: ea_set_immediate (&ea2, imm.val);
! 1637:
! 1638: comp->push_op (OP_CMP, &ea2, &ea, size);
! 1639: }
1.1 root 1640: continue;
1641: }
1642: /* CMPA */
1643: if (strncmp (pos, "cmpa", 4) == 0) {
1644: pos += 4;
1645: check ('.');
1646: size = get_size (*pos);
1647: pos++;
1648: if (size == BYTE) error ("Size must be word or long.");
1649: check_whitespace();
1650: pos = get_ea (pos, &ea, size, F_ALL);
1651: check (',');
1652: pos = get_reg (pos, &i, F_AREG);
1653: check_end (pos);
1654:
1655: op.code = 0xb000;
1656: op.type2.reg = i;
1657: op.type2.op_mode = (size == WORD ? 3 : 7);
1658: op.type2.ea_mode = ea.mode;
1659: op.type2.ea_reg = ea.reg;
1660: wr_short (op.code);
1661: wr_ea (&ea);
1.1.1.2 ! root 1662:
! 1663: if (output_c) {
! 1664: ea.op_size = size;
! 1665: ea2.op_size = size;
! 1666: ea2.mode = 1; ea2.reg = i;
! 1667:
! 1668: comp->push_op (OP_CMPA, &ea, &ea2, size);
! 1669: }
1.1 root 1670: continue;
1671: }
1672: /* CMPM */
1673: if (strncmp (pos, "cmpm", 4) == 0) {
1674: pos += 4;
1675: check ('.');
1676: size = get_size (*pos);
1677: pos++;
1678: check_whitespace ();
1679: pos = get_ea (pos, &ea, size, F_POST);
1680: op.code = 0xb108;
1681: op.cmpm.src_reg = ea.reg;
1682: op.cmpm.size = size;
1683: check (',');
1684: pos = get_ea (pos, &ea, size, F_POST);
1685: op.cmpm.dest_reg = ea.reg;
1686: wr_short (op.code);
1.1.1.2 ! root 1687:
! 1688: if (output_c) {
! 1689: error ("C code not generated (work unfinished).");
! 1690: }
1.1 root 1691: continue;
1692: }
1693: /* CMP */
1694: if (strncmp (pos, "cmp", 3) == 0) {
1695: pos += 3;
1696: check ('.');
1697: size = get_size (*pos);
1698: pos++;
1699: check_whitespace();
1700: pos = get_ea (pos, &ea, size, F_ALL);
1701: check (',');
1702: if ((size == BYTE) && (ea.mode == 0x1))
1703: error ("Bad size for address register gropery.");
1704: pos = get_reg (pos, &i, F_DREG);
1705: check_end (pos);
1706:
1707: op.code = 0xb000;
1708: op.type2.reg = i;
1709: op.type2.op_mode = size;
1710: op.type2.ea_mode = ea.mode;
1711: op.type2.ea_reg = ea.reg;
1712: wr_short (op.code);
1713: wr_ea (&ea);
1.1.1.2 ! root 1714:
! 1715: if (output_c) {
! 1716: ea.op_size = size;
! 1717: ea2.op_size = size;
! 1718: ea2.mode = 0; ea2.reg = i;
! 1719:
! 1720: comp->push_op (OP_CMP, &ea, &ea2, size);
! 1721: }
1.1 root 1722: continue;
1723: }
1724: /* EXG */
1725: if (strncmp (pos, "exg", 3) == 0) {
1726: pos += 3;
1727: op.code = 0xc100;
1728: check_whitespace();
1.1.1.2 ! root 1729: pos = get_ea (pos, &ea, LONG, F_DREG | F_AREG);
1.1 root 1730: check (',');
1.1.1.2 ! root 1731: op.exg.src_reg = ea.reg;
! 1732: if (ea.reg > 7) {
1.1 root 1733: /* Ax,Ay mode */
1734: op.exg.op_mode = 0x9;
1.1.1.2 ! root 1735: pos = get_ea (pos, &ea2, LONG, F_AREG);
! 1736: op.exg.dest_reg = ea2.reg;
1.1 root 1737: } else {
1738: /* Dx,Xn mode */
1.1.1.2 ! root 1739: pos = get_ea (pos, &ea2, LONG, F_AREG | F_DREG);
! 1740: if (ea2.reg > 7) {
1.1 root 1741: op.exg.op_mode = 0x11;
1742: } else {
1743: op.exg.op_mode = 0x8;
1744: }
1.1.1.2 ! root 1745: op.exg.dest_reg = ea2.reg;
1.1 root 1746: }
1747: check_end (pos);
1748: wr_short (op.code);
1.1.1.2 ! root 1749:
! 1750: if (output_c) {
! 1751: comp->push_op (OP_EXG, &ea, &ea2, LONG);
! 1752: }
1.1 root 1753: continue;
1754: }
1755: /* EXT */
1756: if (strncmp (pos, "ext", 3) == 0) {
1757: pos += 3;
1758: check ('.');
1759: size = get_size (pos[0]);
1760: pos++;
1761: check_whitespace();
1762: if (size == BYTE) error ("Ext dislikes bytes.");
1.1.1.2 ! root 1763: pos = get_ea (pos, &ea, size, F_DREG);
1.1 root 1764: check_end (pos);
1765: op.code = 0x4800;
1.1.1.2 ! root 1766: op.type2.ea_reg = ea.reg;
1.1 root 1767: op.type2.op_mode = size+1;
1768: wr_short (op.code);
1.1.1.2 ! root 1769:
! 1770: if (output_c) {
! 1771: comp->push_op (OP_EXT, &ea, NULL, size);
! 1772: }
1.1 root 1773: continue;
1774: }
1775:
1776:
1777: /* MOVEM */
1778: if (strncmp (pos, "movem.", 6)==0) {
1779: pos += 6;
1780: size = get_size (pos[0]);
1781: pos++;
1782: if (size == BYTE) error ("Movem dislikes bytes.");
1783: check_whitespace();
1784: /* register to memory */
1785: pos = parse_movem (pos, size);
1786: check_end (pos);
1.1.1.2 ! root 1787:
1.1 root 1788: continue;
1789: }
1790: /* RTE */
1791: if (strncmp (pos, "rte", 3) == 0) {
1792: check_end (&pos[3]);
1793: wr_short (0x4e73);
1.1.1.2 ! root 1794:
! 1795: if (output_c) {
! 1796: comp->push_op_basic (OP_RTE);
! 1797: }
1.1 root 1798: continue;
1799: }
1800: /* RTS */
1801: if (strncmp (pos, "rts", 3) == 0) {
1802: check_end (&pos[3]);
1803: wr_short (0x4e75);
1.1.1.2 ! root 1804:
! 1805: if (output_c) {
! 1806: comp->push_op_basic (OP_RTS);
! 1807: }
1.1 root 1808: continue;
1809: }
1810: /* ILLEGAL */
1811: if (strncmp (pos, "illegal", 7) == 0) {
1812: check_end (&pos[7]);
1813: wr_short (0x4afc);
1.1.1.2 ! root 1814:
! 1815: if (output_c) {
! 1816: comp->push_op_basic (OP_ILLEGAL);
! 1817: }
1.1 root 1818: continue;
1819: }
1820: /* HOSTCALL -- Not 68000 */
1821: if (strncmp (pos, "hcall", 5) == 0) {
1822: pos += 5;
1823: check_whitespace();
1824: pos = get_imm (pos, &imm, F_IMM | F_NOLABELS);
1825: check_end (pos);
1826: check_range (&imm.val, WORD);
1827: wr_short (0x000b);
1828: wr_short (imm.val);
1.1.1.2 ! root 1829:
! 1830: if (output_c) {
! 1831: ea.imm.val = imm.val;
! 1832: comp->push_op (OP_HCALL, &ea, NULL, 0);
! 1833: }
1.1 root 1834: continue;
1835: }
1836: /* RESET */
1837: if (strncmp (pos, "reset", 5) == 0) {
1838: check_end (&pos[5]);
1839: wr_short (0x4e70);
1.1.1.2 ! root 1840:
! 1841: if (output_c) {
! 1842: error ("C code not generated (work unfinished).");
! 1843: }
1.1 root 1844: continue;
1845: }
1846: /* TRAP */
1847: if (strncmp (pos, "trap", 4) == 0) {
1848: /* TRAPV */
1849: if (pos[4] == 'v') {
1850: check_end (&pos[5]);
1851: wr_short (0x4e76);
1.1.1.2 ! root 1852:
! 1853: if (output_c) {
! 1854: error ("C code not generated (work unfinished).");
! 1855: }
1.1 root 1856: continue;
1857: }
1858: pos += 4;
1859: check_whitespace();
1860: pos = get_imm (pos, &imm, F_IMM | F_NOLABELS);
1861: check_end (pos);
1862: if ((imm.val < 0) || (imm.val > 15)) {
1863: error ("Trap vector out of range.");
1864: }
1865: wr_short (0x4e40 | imm.val);
1.1.1.2 ! root 1866:
! 1867: if (output_c) {
! 1868: error ("C code not generated (work unfinished).");
! 1869: }
1.1 root 1870: continue;
1871: }
1872: /* LINK */
1873: if (strncmp (pos, "link", 4) == 0) {
1874: pos += 4;
1875: check_whitespace();
1876: pos = get_reg (pos, ®, F_AREG);
1877: check (',');
1878: pos = get_imm (pos, &imm, F_IMM | F_NOLABELS);
1879: check_end (pos);
1880: check_range (&imm.val, WORD);
1881: op.code = 0x4e50;
1882: op.type1.ea_reg = reg;
1883: wr_short (op.code);
1884: wr_short (imm.val);
1.1.1.2 ! root 1885:
! 1886: if (output_c) {
! 1887: ea.mode = 1; ea.reg = reg;
! 1888: ea2.imm.val = imm.val;
! 1889: comp->push_op (OP_LINK, &ea, &ea2, 0);
! 1890: }
1.1 root 1891: continue;
1892: }
1893: /* UNLK */
1894: if (strncmp (pos, "unlk", 4) == 0) {
1895: pos += 4;
1896: check_whitespace();
1897: pos = get_reg (pos, ®, F_AREG);
1898: check_end (pos);
1899: op.code = 0x4e58;
1900: op.type1.ea_reg = reg;
1901: wr_short (op.code);
1.1.1.2 ! root 1902:
! 1903: if (output_c) {
! 1904: ea.mode = 1; ea.reg = reg;
! 1905: comp->push_op (OP_UNLK, &ea, NULL, 0);
! 1906: }
1.1 root 1907: continue;
1908: }
1909: /* MOVEQ */
1910: if (strncmp (pos, "moveq", 5) == 0){
1911: pos += 5;
1912: check_whitespace();
1913: pos = get_imm (pos, &imm, F_NOLABELS | F_IMM);
1914: check_range (&imm.val, BYTE);
1915: check (',');
1916: pos = get_ea (pos, &ea, LONG, F_DREG);
1917: check_end (pos);
1918: op.code = 0x7000;
1919: op.moveq.reg = ea.reg;
1920: op.moveq.data = imm.val;
1921: wr_short (op.code);
1.1.1.2 ! root 1922:
! 1923: if (output_c) {
! 1924: ea_set_immediate (&ea2, imm.val);
! 1925: comp->push_op (OP_MOVE, &ea2, &ea, LONG);
! 1926: }
1.1 root 1927: continue;
1928: }
1929: /* MOVEA */
1930: if (strncmp (pos, "movea.", 6) == 0) {
1931: pos += 6;
1932: size = get_size (pos[0]);
1933: pos++;
1934: check_whitespace();
1935: pos = get_ea (pos, &ea, size, F_ALL);
1936: check (',');
1937: pos = get_reg (pos, &i, F_AREG);
1938: check_end (pos);
1939: is_movea:
1940: if (size == BYTE) error ("Illegal size.");
1941: op.code = 0;
1.1.1.2 ! root 1942: op.move.size = move_size [size];
1.1 root 1943: op.move.dest_reg = i;
1944: op.move.dest_mode = 1;
1945: op.move.src_reg = ea.reg;
1946: op.move.src_mode = ea.mode;
1947: wr_short (op.code);
1948: wr_ea (&ea);
1.1.1.2 ! root 1949:
! 1950: if (output_c) {
! 1951: ea2.mode = 1; ea2.reg = i;
! 1952: comp->push_op (OP_MOVEA, &ea, &ea2, size);
! 1953: }
1.1 root 1954: continue;
1955: }
1956: /* MOVE */
1957: if (strncmp (pos, "move.", 5) == 0) {
1958: pos += 5;
1959: size = get_size (pos[0]);
1960: pos++;
1961: check_whitespace();
1962: pos = get_ea (pos, &ea, size, F_ALL);
1963: check (',');
1964: pos = get_ea (pos, &ea2, size, F_AREG | F_DREG | F_IND | F_PRE | F_POST | F_INDEX | F_OFFSET | F_MEM_W | F_MEM_L);
1965: check_end (pos);
1966:
1967: if ((ea.mode == 7) && (ea.reg == 1) && (ea.imm.has_label)) {
1968: if (strcmp (ea.imm.label, "sr")==0) {
1969: /* move from sr */
1970: if (size != WORD) error ("Illegal size.");
1971: op.code = 0x40c0;
1972: op.type1.ea_reg = ea2.reg;
1973: op.type1.ea_mode = ea2.mode;
1974: wr_short (op.code);
1975: wr_ea (&ea2);
1.1.1.2 ! root 1976:
! 1977: if (output_c) {
! 1978: error ("C code not generated (work unfinished).");
! 1979: }
1.1 root 1980: continue;
1981: }
1982: }
1983: if (ea2.mode == 1) {
1984: i = ea2.reg;
1985: goto is_movea;
1986: }
1987: if ((ea2.mode == 7) && (ea2.reg == 1) && (ea2.imm.has_label)) {
1988: if (strcmp (ea2.imm.label, "sr")==0) {
1989: /* move to status reg */
1990: if (size != WORD) error ("Illegal size.");
1991: op.code = 0x46c0;
1992: op.type1.ea_reg = ea.reg;
1993: op.type1.ea_mode = ea.mode;
1994: wr_short (op.code);
1995: wr_ea (&ea);
1.1.1.2 ! root 1996:
! 1997: if (output_c) {
! 1998: error ("C code not generated (work unfinished).");
! 1999: }
1.1 root 2000: continue;
2001: }
2002: }
2003: op.code = 0;
1.1.1.2 ! root 2004: op.move.size = move_size [size];
1.1 root 2005: op.move.dest_reg = ea2.reg;
2006: op.move.dest_mode = ea2.mode;
2007: op.move.src_reg = ea.reg;
2008: op.move.src_mode = ea.mode;
2009: wr_short (op.code);
2010: wr_ea (&ea);
2011: wr_ea (&ea2);
1.1.1.2 ! root 2012:
! 2013: if (output_c) {
! 2014: comp->push_op (OP_MOVE, &ea, &ea2, size);
! 2015: }
1.1 root 2016: continue;
2017: }
2018: /* TST */
2019: if (strncmp (pos, "tst.", 4) == 0) {
2020: pos += 4;
2021: size = get_size (pos[0]);
2022: pos++;
2023: check_whitespace();
2024: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG);
2025: check_end (pos);
2026: op.code = 0x4a00;
2027: op.type1.size = size;
2028: op.type1.ea_reg = ea.reg;
2029: op.type1.ea_mode = ea.mode;
2030: wr_short (op.code);
2031: wr_ea (&ea);
1.1.1.2 ! root 2032:
! 2033: if (output_c) {
! 2034: ea.op_size = size;
! 2035: comp->push_op (OP_TST, &ea, NULL, size);
! 2036: }
1.1 root 2037: continue;
2038: }
2039: /* PEA */
2040: if (strncmp (pos, "pea", 3) == 0) {
2041: pos += 3;
2042: check_whitespace();
2043: pos = get_ea (pos, &ea, LONG, F_IND | F_OFFSET | F_INDEX | F_MEM_W | F_MEM_L | F_PC_OFFSET | F_PC_INDEX);
2044: check_end (pos);
2045: op.code = 0x4840;
2046: op.type2.ea_reg = ea.reg;
2047: op.type2.ea_mode = ea.mode;
2048: wr_short (op.code);
2049: wr_ea (&ea);
1.1.1.2 ! root 2050:
! 2051: if (output_c) {
! 2052: ea.op_size = LONG;
! 2053: comp->push_op (OP_PEA, &ea, NULL, LONG);
! 2054: }
1.1 root 2055: continue;
2056: }
2057: /* LEA */
2058: if (strncmp (pos, "lea", 3) == 0) {
2059: pos += 3;
2060: check_whitespace();
2061: pos = get_ea (pos, &ea, LONG, F_IND | F_OFFSET | F_INDEX | F_MEM_W | F_MEM_L | F_PC_OFFSET | F_PC_INDEX);
2062: check (',');
1.1.1.2 ! root 2063: pos = get_ea (pos, &ea2, LONG, F_AREG);
1.1 root 2064: check_end (pos);
2065: op.code = 0x41e0;
2066: op.type2.ea_reg = ea.reg;
2067: op.type2.ea_mode = ea.mode;
1.1.1.2 ! root 2068: op.type2.reg = ea2.reg;
1.1 root 2069: wr_short (op.code);
2070: wr_ea (&ea);
1.1.1.2 ! root 2071:
! 2072: if (output_c) {
! 2073: ea.op_size = LONG;
! 2074: comp->push_op (OP_LEA, &ea, &ea2, LONG);
! 2075: }
1.1 root 2076: continue;
2077: }
2078:
2079: /* JSR */
2080: if (strncmp (pos, "jsr", 3) == 0) {
2081: pos += 3;
2082: check_whitespace();
2083: pos = get_ea (pos, &ea, LONG, F_IND | F_OFFSET |
2084: F_INDEX | F_MEM_W | F_MEM_L | F_PC_OFFSET | F_PC_INDEX);
2085: check_end (pos);
2086: op.code = 0x4e80;
2087: op.type1.ea_reg = ea.reg;
2088: op.type1.ea_mode = ea.mode;
2089: wr_short (op.code);
2090: wr_ea (&ea);
1.1.1.2 ! root 2091:
! 2092: if (output_c) {
! 2093: comp->push_op (OP_JSR, &ea, NULL, 0);
! 2094: }
1.1 root 2095: continue;
2096: }
2097: /* JMP */
2098: if (strncmp (pos, "jmp", 3) == 0) {
2099: pos += 3;
2100: check_whitespace();
2101: pos = get_ea (pos, &ea, LONG, F_IND | F_OFFSET |
2102: F_INDEX | F_MEM_W | F_MEM_L | F_PC_OFFSET | F_PC_INDEX);
2103: check_end (pos);
2104: op.code = 0x4ec0;
2105: op.type1.ea_reg = ea.reg;
2106: op.type1.ea_mode = ea.mode;
2107: wr_short (op.code);
2108: wr_ea (&ea);
1.1.1.2 ! root 2109:
! 2110: if (output_c) {
! 2111: comp->push_op (OP_JMP, &ea, NULL, 0);
! 2112: }
! 2113: continue;
! 2114: }
! 2115: /* TAS */
! 2116: if (strncmp (pos, "tas", 3) == 0) {
! 2117: pos += 3;
! 2118: check_whitespace ();
! 2119: pos = get_ea (pos, &ea, BYTE, F_NOIMM_NOPC_NOAREG);
! 2120: check_end (pos);
! 2121: op.code = 0x4ac0;
! 2122: op.type1.ea_reg = ea.reg;
! 2123: op.type1.ea_mode = ea.mode;
! 2124: wr_short (op.code);
! 2125: wr_ea (&ea);
! 2126:
! 2127: if (output_c) {
! 2128: error ("C code not generated (work unfinished).");
! 2129: }
1.1 root 2130: continue;
2131: }
2132: /* Scc */
2133: if (pos[0] == 's') {
2134: pos = rd_label (&pos[1], lab1);
2135: for (i=0; i<16; i++) {
2136: if (strncmp (lab1, DBcc_str[i], 2)==0) break;
2137: }
2138: if (i==16) goto fuckit2;
2139: while (isalpha (*pos)) pos++;
2140: check_whitespace();
2141: pos = get_ea (pos, &ea, BYTE, F_NOIMM_NOPC_NOAREG);
2142: check_end (pos);
2143: op.code = 0x50c0;
2144: op.DBcc.cond = i;
2145: op.type1.ea_reg = ea.reg;
2146: op.type1.ea_mode = ea.mode;
2147: wr_short (op.code);
2148: wr_ea (&ea);
1.1.1.2 ! root 2149:
! 2150: if (output_c) {
! 2151: comp->push_op2 (OP_SCC, &ea, NULL, BYTE, op.code);
! 2152: }
1.1 root 2153: continue;
2154: }
2155: fuckit2:
2156: error ("Unknown opcode %s.", pos);
2157: }
2158: /* write text section length */
2159: size = get_bitpos () - BASE;
2160: set_bitpos (2);
2161: wr_int (size);
2162: /* empty reloc table for the moment */
2163: set_bitpos (size + BASE);
2164: wr_int (0);
1.1.1.2 ! root 2165:
! 2166: if (output_c) comp->end (src_filename);
! 2167:
1.1 root 2168: return size + BASE;
2169: }
2170:
2171: int asm_pass2 (int fixup_pos)
2172: {
2173: struct Label *lab;
2174: struct Fixup *fix;
2175: int last_adr = BASE;
2176: int _first = 1;
2177: int dist;
2178: int num_relocs = 0;
2179:
2180: fix = fix_first;
2181:
1.1.1.2 ! root 2182: for (; fix!=NULL; fix = fix->next) {
! 2183: if (fix->size == C_ADDR) continue;
! 2184: if (fix->size == C_FUNC) continue;
! 2185:
1.1 root 2186: line_no = fix->line_no;
2187: lab = get_label (fix->label);
2188: if (!lab) {
2189: error ("Undefined label '%s'.", fix->label);
2190: }
2191: if (lab->type == L_CONST) {
2192: error ("Illegal absolute value.");
2193: }
2194: set_bitpos (fix->adr);
2195: if (fix->size == BYTE) {
2196: dist = lab->val - fix->rel_to;
2197: if ((dist < -128) || (dist > 127)) {
2198: error ("Offset too big (%d).", dist);
2199: }
2200: wr_byte (dist);
2201: } else if (fix->size == WORD) {
2202: dist = lab->val - fix->rel_to;
2203: if ((dist < -32768) || (dist > 32767)) {
2204: error ("Offset too big (%d).", dist);
2205: }
2206: wr_short (dist);
2207: } else if (fix->size >= LONG) {
2208: num_relocs++;
2209: wr_int (lab->val);
2210: set_bitpos (fixup_pos);
2211: if (_first) {
2212: wr_int (fix->adr - BASE);
2213: last_adr = fix->adr;
2214: fixup_pos+=4;
2215: _first = 0;
2216: } else {
2217: dist = fix->adr - last_adr;
2218: while (dist > 254) {
2219: wr_byte (1);
2220: dist -= 254;
2221: fixup_pos++;
2222: }
2223: wr_byte (dist);
2224: last_adr = fix->adr;
2225: fixup_pos++;
2226: }
2227: } else {error ("Unknown size in fixup tab.");}
2228: }
2229: set_bitpos (fixup_pos);
2230: if (_first) wr_int (0);
2231: else wr_byte (0);
2232:
2233: return num_relocs;
2234: }
2235:
2236: int main (int argc, char **argv)
2237: {
1.1.1.2 ! root 2238: int arg, size, num;
! 2239: char bin_filename[128];
1.1 root 2240: if (argc == 1) {
1.1.1.2 ! root 2241: fprintf (stderr, "Usage: ./as68k [--dump-labels] [--output-c | --output-i386] file.s\n");
1.1 root 2242: exit (0);
2243: }
2244:
1.1.1.2 ! root 2245: for (arg=1; arg<argc-1; arg++) {
! 2246:
! 2247: if (strcmp (argv[arg], "--dump-labels") == 0) {
! 2248: dump_labels = 1;
! 2249: }
! 2250: else if (strcmp (argv[arg], "--output-c") == 0) {
! 2251: comp = &compiler[COMPILE_C];
! 2252: output_c = 1;
! 2253: }
! 2254: else if (strcmp (argv[arg], "--output-i386") == 0) {
! 2255: comp = &compiler[COMPILE_i386];
! 2256: output_c = 1;
! 2257: }
! 2258: else {
! 2259: fprintf (stderr, "Unknown option: '%s'\n", argv[arg]);
! 2260: }
1.1 root 2261: }
1.1.1.2 ! root 2262:
! 2263: src_filename = argv[arg];
! 2264: if ((fin = fopen (src_filename, "r"))==NULL) {
! 2265: printf ("Error. Cannot open %s.\n", src_filename);
1.1 root 2266: exit (0);
2267: }
2268:
1.1.1.2 ! root 2269: snprintf (bin_filename, sizeof (bin_filename), "%s.bin", src_filename);
! 2270: fout = fopen (bin_filename, "wb");
1.1 root 2271:
1.1.1.2 ! root 2272: fprintf (stderr, "Pass 1\n");
! 2273: size = asm_pass1 (bin_filename);
! 2274: fprintf (stderr, "Pass 2\n");
1.1 root 2275: num = asm_pass2 (size);
2276: fseek (fout, 0, SEEK_END);
2277: size = ftell (fout);
2278:
1.1.1.2 ! root 2279: /* on the ST 0x12 in executable is reserved. we put total
! 2280: * size here because we are silly people */
! 2281: set_bitpos (0x12);
! 2282: wr_int (size);
! 2283:
! 2284: fprintf (stderr, "Done! %d bytes and %d relocations.\n", size, num);
! 2285:
1.1 root 2286: return 0;
2287: }
2288:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.