|
|
1.1 root 1: //
2: // nono
1.1.1.2 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #include "m88100disasm.h"
1.1.1.9 root 8: #include "debugger_memory.h"
9: #include "m88100.h"
1.1.1.2 root 10: #include "m88100acc.h"
1.1 root 11:
12: #define OP_DEF(name) void __CONCAT(m88100disasm::op_,name)()
13: #define OP_FUNC(name) __CONCAT(op_,name)()
14:
1.1.1.8 root 15: // 別ニーモニックを使うなら true にする (外部から指定する)
16: /*static*/ bool m88100disasm::use_altname;
17:
1.1 root 18: // コンストラクタ
1.1.1.9 root 19: m88100disasm::m88100disasm()
1.1 root 20: {
21: }
22:
23: // デストラクタ
24: m88100disasm::~m88100disasm()
25: {
26: }
27:
28: // 逆アセンブルを実行
29: bool
1.1.1.9 root 30: m88100disasm::Exec(DebuggerMemoryStream *mem_)
1.1 root 31: {
1.1.1.9 root 32: ExecInit(mem_);
1.1 root 33:
34: opX = 0;
35: name.clear();
36: arg0.clear();
37: arg1.clear();
38: arg2.clear();
1.1.1.7 root 39: altname.clear();
40: altarg0.clear();
41: altarg1.clear();
42: altarg2.clear();
1.1 root 43:
1.1.1.10! root 44: xip = mem->laddr.Addr();
1.1 root 45:
1.1.1.9 root 46: opX = mem->Read(4);
47: uint32 op12 = M88100::op32_to_12(opX);
1.1 root 48: switch (op12) {
49: #include "m88100switch.inc"
50: default:
1.1.1.2 root 51: name = "illegal";
52: break;
53: //OP_FUNC(illegal);
1.1 root 54: }
55:
56: // 出力文字列(ダンプ)
57: dump = string_format("%08x ", opX);
58:
59: // 出力文字列(命令)
60: text = name;
61: if (!arg0.empty() || !arg1.empty() || !arg2.empty()) {
62: // オペランドがどれかでもあればインデントする
63: int len = text.length();
64: if (len < 8) {
65: text += std::string(8 - len, ' ');
66: } else {
67: text += ' ';
68: }
69:
70: // arg0,1,2 の空でないやつを追加
71: std::string args;
1.1.1.9 root 72: int argc = 0;
1.1 root 73: if (!arg0.empty()) {
74: args += arg0;
1.1.1.9 root 75: argc++;
1.1 root 76: }
77: if (!arg1.empty()) {
1.1.1.9 root 78: if (argc != 0) {
1.1 root 79: args += ",";
1.1.1.9 root 80: while (args.length() < argc * 4)
1.1 root 81: args += " ";
82: }
83: args += arg1;
1.1.1.9 root 84: argc++;
1.1 root 85: }
86: if (!arg2.empty()) {
1.1.1.9 root 87: if (argc != 0) {
1.1 root 88: args += ",";
1.1.1.9 root 89: while (args.length() < argc * 4)
1.1 root 90: args += " ";
91: }
92: args += arg2;
93: }
94:
95: text += args;
96: }
97:
1.1.1.7 root 98: // 出力文字列(別名)
99: if (use_altname && !altname.empty()) {
100: if (altarg1.empty() && !altarg2.empty()) {
101: altarg1 = altarg2;
102: altarg2.clear();
103: }
104: // {mov rn, rn} -> {nop} は無条件に置換できるのでここでやる
105: if (altname == "mov" && altarg0 == altarg1 && altarg2.empty()) {
106: altname = "nop";
107: altarg0.clear();
108: altarg1.clear();
109: }
110:
111: alttext += "{" + altname;
112:
113: if (!altarg0.empty() || !altarg1.empty() || !altarg2.empty()) {
114: // オペランドがあればインデントする
115: int len = alttext.length();
116: if (len < 8) {
117: alttext += std::string(8 - len, ' ');
118: } else {
119: alttext += ' ';
120: }
121:
122: // altarg0,1,2 の空でないやつを追加
123: std::string altargs;
1.1.1.9 root 124: int altargc = 0;
1.1.1.7 root 125: if (!altarg0.empty()) {
126: altargs += altarg0;
1.1.1.9 root 127: altargc++;
1.1.1.7 root 128: }
129: if (!altarg1.empty()) {
1.1.1.9 root 130: if (altargc != 0) {
1.1.1.7 root 131: altargs += ',';
1.1.1.9 root 132: while (altargs.length() < altargc * 4)
1.1.1.7 root 133: altargs += ' ';
134: }
135: altargs += altarg1;
1.1.1.9 root 136: altargc++;
1.1.1.7 root 137: }
138: if (!altarg2.empty()) {
1.1.1.9 root 139: if (altargc != 0) {
1.1.1.7 root 140: altargs += ',';
1.1.1.9 root 141: while (altargs.length() < altargc * 4)
1.1.1.7 root 142: altargs += ' ';
143: }
144: altargs += altarg2;
145: }
146:
147: alttext += altargs;
148: }
149: alttext += '}';
150: }
151:
1.1 root 152: // 出力バイナリ列
153: // bin は vector<uint8>。
154: bin.push_back( opX >> 24);
155: bin.push_back((opX >> 16) & 0xff);
156: bin.push_back((opX >> 8) & 0xff);
157: bin.push_back( opX & 0xff);
158:
159: return true;
160: }
161:
162: // フィールド部品
1.1.1.7 root 163: #define DD ((opX >> 21) & 0x1f)
164: #define S1 ((opX >> 16) & 0x1f)
165: #define S2 ( opX & 0x1f)
1.1 root 166: #define B5 ((opX >> 21) & 0x1f)
167: #define M5 ((opX >> 21) & 0x1f)
168: #define W5 ((opX >> 5) & 0x1f)
169: #define O5 ((opX ) & 0x1f)
1.1.1.7 root 170: #define CIO ((opX >> 8) & 0x03)
171: #define IMM16 (opX & 0x0000ffffU)
1.1 root 172: #define VEC9 (opX & 0x000001ffU)
173: #define D16 (((int32)(int16)opX) << 2)
174: #define D26 (((int32)(opX << 6)) >> 4)
175:
176: std::string
177: m88100disasm::rd()
178: {
1.1.1.10! root 179: return string_format("r%u", (opX >> 21) & 0x1f);
1.1 root 180: }
181:
182: std::string
183: m88100disasm::rs1()
184: {
1.1.1.10! root 185: return string_format("r%u", (opX >> 16) & 0x1f);
1.1 root 186: }
187:
188: std::string
189: m88100disasm::rs2()
190: {
1.1.1.10! root 191: return string_format("r%u", (opX ) & 0x1f);
1.1 root 192: }
193:
194: std::string
195: m88100disasm::imm16()
196: {
197: return string_format("#0x%04x", (opX & 0x0000ffff));
198: }
199:
200: std::string
201: m88100disasm::d16()
202: {
203: return string_format("0x%08x", xip + D16);
204: }
205:
1.1.1.6 root 206: std::string
207: m88100disasm::d26()
208: {
209: return string_format("0x%08x", xip + D26);
210: }
211:
1.1 root 212: // 制御レジスタ名
213: std::string
214: m88100disasm::crs()
215: {
1.1.1.2 root 216: // CRS フィールドは 6 bit。ただし CR20 までしか存在しない
1.1 root 217: uint32 cr = (opX >> 5) & 0x3f;
218: static const char *crnames[] = {
219: "pid", "psr", "epsr", "ssbr", // cr0..3
220: "sxip", "snip", "sfip", "vbr", // cr4..7
221: "dmt0", "dmd0", "dma0", // cr8..10
222: "dmt1", "dmd1", "dma1", // cr11..13
223: "dmt2", "dmd2", "dma2", // cr14..16
1.1.1.2 root 224: "sr0", "sr1", "sr2", "sr3", // cr17..20
1.1 root 225: };
226:
227: if (cr < countof(crnames)) {
228: return std::string(crnames[cr]);
229: } else {
1.1.1.10! root 230: return string_format("cr%u", cr); // こうなのか?
1.1 root 231: }
232: }
233:
234: // FPU 制御レジスタ名
235: std::string
236: m88100disasm::fcrs()
237: {
238: uint32 cr = (opX >> 5) & 0x3f;
239: static const char *fcrnames[] = {
240: "fpecr", // fcr0
241: "fphs1", // fcr1
242: "fpls1", // fcr2
243: "fphs2", // fcr3
244: "fpls2", // fcr4
245: "fppt", // fcr5
246: "fprh", // fcr6
247: "fprl", // fcr7
248: "fpit", // fcr8
249: };
250: if (cr < countof(fcrnames)) {
251: return std::string(fcrnames[cr]);
252: } else if (cr == 62) {
253: return "fpsr";
254: } else if (cr == 63) {
255: return "fpcr";
256: } else {
1.1.1.10! root 257: return string_format("fcr%u", cr);
1.1 root 258: }
259: }
260:
261: #define TD (5)
262: #define T1 (9)
263: #define T2 (7)
264:
265: // FPU サイズサフィックス t は TD、T1、T2
266: std::string
267: m88100disasm::fsize(uint32 t)
268: {
269: uint32 sz = (opX >> t) & 3;
270: return sz == 1 ? "d" : "s";
271: }
272:
273: // FPU サイズサフィックス (全部入り)
274: std::string
275: m88100disasm::fsize()
276: {
277: return fsize(TD) + fsize(T1) + fsize(T2);
278: }
279:
280: // "Width<Offset>"
281: std::string
282: m88100disasm::wo5()
283: {
284: uint32 w5 = W5 ?: 32;
285: uint32 o5 = O5;
1.1.1.10! root 286: return string_format("%u<%u>", w5, o5);
1.1 root 287: }
288:
1.1.1.9 root 289: // "Width<Offset>" 形式をビットマスク形式(数値)にして返す
290: uint32
291: m88100disasm::wo5mask()
292: {
293: uint32 w5 = W5 ?: 32;
294: uint32 o5 = O5;
295:
296: uint64 mask = (1ULL << w5) - 1;
297: mask <<= o5;
298: return (uint32)mask;
299: }
300:
1.1 root 301: // キャリーサフィックス
302: std::string
303: m88100disasm::cio()
304: {
305: uint32 c = (opX >> 8) & 3;
306: static const char *carrystr[] = {
307: "",
308: ".co",
1.1.1.2 root 309: ".ci",
1.1 root 310: ".cio",
311: };
312: return std::string(carrystr[c]);
313: }
314:
315: std::string
316: m88100disasm::b5()
317: {
1.1.1.10! root 318: return string_format("#%u", B5);
1.1 root 319: }
320:
321: std::string
322: m88100disasm::m5()
323: {
324: uint32 m = M5;
325: switch (m) {
326: case 0x02: return "eq0";
327: case 0x0d: return "ne0";
328: case 0x01: return "gt0";
329: case 0x0c: return "lt0";
330: case 0x03: return "ge0";
331: case 0x0e: return "le0";
332: default:
333: break;
334: }
1.1.1.10! root 335: return string_format("#%u", m);
1.1.1.9 root 336: }
337:
338: // M5(,rS1) に対する代替ニーモニックを返す。empty なら代替ニーモニックなし。
339: // 条件が 0(always false) でも .n かどうかがあるので nop とかにはしない。
340: // 15(always true) は無条件 br{,.n} だがこれは戻り値 "true" を呼び出し側が
341: // 比較して処理すること。
342: // 6 と 9 は使いみちがないので empty を返す。
343: // reserved なビットが立っていても動作には影響はないが、ニーモニックとしては
344: // 不正なものとして表示するためここでは empty を返す。
345: std::string
346: m88100disasm::alt_m5()
347: {
348: // 0000 false
349: // 0001 gt0 r > 0 (float)r > +0
350: // 0010 eq0 r == 0 (float)r == +0
351: // 0011 ge0 r >= 0 (float)r >= +0
352: // 0100 (float)r < -0
353: // 0101 (float)r != 0
354: // 0110 #6
355: // 0111 r != 0x80000000 (float)r != -0
356: // 1000 r == 0x80000000 (float)r == -0
357: // 1001 #9
358: // 1010 (float)r == 0
359: // 1011 (float)r >= -0
360: // 1100 lt0 r < 0 (float)r < +0
361: // 1101 ne0 r != 0 (float)r != +0
362: // 1110 le0 r <= 0 (float)r <= +0
363: // 1111 true
364:
365: uint32 m = M5;
366: if (S1 == 0) {
367: if (m < 0x10) {
368: // r0 相手なら、下から 2bit 目が立っていれば true、
369: // そうでなければ false の二択。
370: if ((m & 0x02)) {
371: return "true";
372: } else {
373: return "false";
374: }
375: }
376: } else {
377: char rs[8];
378: strlcpy(rs, rs1().c_str(), sizeof(rs));
379: switch (m) {
380: case 0:
381: return "false";
382: case 1:
383: return string_format("(%s>0|(float)%s>+0)", rs, rs);
384: case 2:
385: return string_format("(%s==0|(float)%s==+0)", rs, rs);
386: case 3:
387: return string_format("(%s>=0|(float)%s>=+0)", rs, rs);
388: case 4:
389: return string_format("((float)%s<-0)", rs);
390: case 5:
391: return string_format("((float)%s!=0)", rs);
392: case 7:
393: return string_format("(%s!=0x80000000)", rs);
394: case 8:
395: return string_format("(%s==0x80000000)", rs);
396: case 0xa:
397: return string_format("((float)%s==0)", rs);
398: case 0xb:
399: return string_format("((float)%s>=-0)", rs);
400: case 0xc:
401: return string_format("(%s<0|(float)%s<+0)", rs, rs);
402: case 0xd:
403: return string_format("(%s!=0|(float)%s!=+0)", rs, rs);
404: case 0xe:
405: return string_format("(%s<=0|(float)%s<=+0)", rs, rs);
406:
407: case 0xf: // always true
408: return "true";
409:
410: case 6:
411: case 9:
412: default: // reserved
413: break;
414: }
415: }
416:
417: return "";
1.1 root 418: }
419:
420: std::string
421: m88100disasm::vec9()
422: {
423: return string_format("#0x%03x", VEC9);
424: }
425:
426: // エミュレータ的未実装 (最終的にはなくなる)
427: void
428: m88100disasm::op_unimpl()
429: {
430: name = "unimplemented";
431: }
432:
1.1.1.6 root 433: // ld_imm, st_imm, xmem_imm の共通部
434: // namebase にはサイズプレフィックスを含む。
435: void
436: m88100disasm::ops_ldst_imm(const std::string& namebase)
1.1 root 437: {
1.1.1.6 root 438: name = namebase;
1.1 root 439: arg0 = rd();
440: arg1 = rs1();
441: arg2 = imm16();
1.1.1.7 root 442:
443: altname = namebase;
444: altarg0 = rd();
445: if (IMM16 == 0) {
446: altarg1 = rs1();
447: } else {
448: altarg1 = rs1() + "," + imm16();
449: }
450: // 3文字目が 'a' になるのは lda しかない
451: if (namebase[2] != 'a') {
452: altarg1 = "(" + altarg1 + ")";
453: }
1.1 root 454: }
455:
1.1.1.6 root 456: // 000000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
457: OP_DEF(xmem_bu_imm)
458: {
459: ops_ldst_imm("xmem.bu");
460: }
461:
1.1 root 462: // 000001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
463: OP_DEF(xmem_w_imm)
464: {
1.1.1.6 root 465: ops_ldst_imm("xmem");
1.1 root 466: }
467:
468: // 000010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
469: OP_DEF(ld_hu_imm)
470: {
1.1.1.6 root 471: ops_ldst_imm("ld.hu");
1.1 root 472: }
473:
474: // 000011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
475: OP_DEF(ld_bu_imm)
476: {
1.1.1.6 root 477: ops_ldst_imm("ld.bu");
1.1 root 478: }
479:
480: // 000100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
481: OP_DEF(ld_d_imm)
482: {
1.1.1.6 root 483: ops_ldst_imm("ld.d");
1.1 root 484: }
485:
486: // 000101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
487: OP_DEF(ld_w_imm)
488: {
1.1.1.6 root 489: ops_ldst_imm("ld");
1.1 root 490: }
491:
492: // 000110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
493: OP_DEF(ld_h_imm)
494: {
1.1.1.6 root 495: ops_ldst_imm("ld.h");
1.1 root 496: }
497:
498: // 000111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
499: OP_DEF(ld_b_imm)
500: {
1.1.1.6 root 501: ops_ldst_imm("ld.b");
1.1 root 502: }
503:
504: // 001000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
505: OP_DEF(st_d_imm)
506: {
1.1.1.6 root 507: ops_ldst_imm("st.d");
1.1 root 508: }
509:
510: // 001001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
511: OP_DEF(st_w_imm)
512: {
1.1.1.6 root 513: ops_ldst_imm("st");
1.1 root 514: }
515:
516: // 001010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
517: OP_DEF(st_h_imm)
518: {
1.1.1.6 root 519: ops_ldst_imm("st.h");
1.1 root 520: }
521:
522: // 001011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
523: OP_DEF(st_b_imm)
524: {
1.1.1.6 root 525: ops_ldst_imm("st.b");
1.1 root 526: }
527:
528: // 001100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
529: OP_DEF(lda_d_imm)
530: {
1.1.1.6 root 531: ops_ldst_imm("lda.d");
1.1 root 532: }
533:
534: // 001101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
535: OP_DEF(lda_w_imm)
536: {
1.1.1.6 root 537: ops_ldst_imm("lda");
1.1 root 538: }
539:
540: // 001110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
541: OP_DEF(lda_h_imm)
542: {
1.1.1.6 root 543: ops_ldst_imm("lda.h");
1.1 root 544: }
545:
546: // 001111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
547: OP_DEF(lda_b_imm)
548: {
1.1.1.6 root 549: ops_ldst_imm("lda.b");
1.1 root 550: }
551:
552: // 010000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
553: OP_DEF(and_imm)
554: {
555: name = "and";
556: arg0 = rd();
557: arg1 = rs1();
558: arg2 = imm16();
1.1.1.7 root 559:
560: // rd s1 imm
561: // ----------
562: // r0 * * nop
563: // rd r0 #imm clr rd
564: // rd rd #imm and rd, #ffff'imm
565: // rd s1 #imm and rd, s1, #ffff'imm
566:
567: if (DD == 0) {
568: altname = "nop";
569: } else if (S1 == 0) {
570: altname = "clr";
571: altarg0 = rd();
572: } else {
573: altname = "and";
574: altarg0 = rd();
575: if (DD != S1) {
576: altarg1 = rs1();
577: }
578: altarg2 = string_format("#0xffff%04x", IMM16);
579: }
1.1 root 580: }
581:
582: // 010001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
583: OP_DEF(and_u_imm)
584: {
585: name = "and.u";
586: arg0 = rd();
587: arg1 = rs1();
588: arg2 = imm16();
1.1.1.7 root 589:
590: // rd s1 imm
591: // ----------
592: // r0 * * nop
593: // rd r0 #imm clr rd
594: // rd rd #imm and rd, #imm'ffff
595: // rd s1 #imm and rd, s1, #imm'ffff
596:
597: if (DD == 0) {
598: altname = "nop";
599: } else if (S1 == 0) {
600: altname = "clr";
601: altarg0 = rd();
602: } else {
603: altname = "and";
604: altarg0 = rd();
605: if (DD != S1) {
606: altarg1 = rs1();
607: }
608: altarg2 = imm16() + "ffff";
609: }
1.1 root 610: }
611:
612: // 010010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
613: OP_DEF(mask_imm)
614: {
615: name = "mask";
616: arg0 = rd();
617: arg1 = rs1();
618: arg2 = imm16();
1.1.1.7 root 619:
620: // rd s1 imm
621: // ----------
622: // r0 * * nop
623: // rd r0 #imm clr rd
624: // rd rd #imm and rd, #0000'imm
625: // rd s1 #imm and rd, s1, #0000'imm
626:
627: if (DD == 0) {
628: altname = "nop";
629: } else if (S1 == 0) {
630: altname = "clr";
631: altarg0 = rd();
632: } else {
633: altname = "and";
634: altarg0 = rd();
635: if (DD != S1) {
636: altarg1 = rs1();
637: }
638: altarg2 = string_format("#0x0000%04x", IMM16);
639: }
1.1 root 640: }
641:
642: // 010011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
643: OP_DEF(mask_u_imm)
644: {
645: name = "mask.u";
646: arg0 = rd();
647: arg1 = rs1();
648: arg2 = imm16();
1.1.1.7 root 649:
650: // rd s1 imm
651: // ----------
652: // r0 * * nop
653: // rd r0 #imm clr rd
654: // rd rd #imm and rd, #imm'0000
655: // rd s1 #imm and rd, s1, #imm'0000
656:
657: if (DD == 0) {
658: altname = "nop";
659: } else if (S1 == 0) {
660: altname = "clr";
661: altarg0 = rd();
662: } else {
663: altname = "and";
664: altarg0 = rd();
665: if (DD != S1) {
666: altarg1 = rs1();
667: }
668: altarg2 = imm16() + "0000";
669: }
1.1 root 670: }
671:
672: // 010100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
673: OP_DEF(xor_imm)
674: {
675: name = "xor";
676: arg0 = rd();
677: arg1 = rs1();
678: arg2 = imm16();
1.1.1.7 root 679:
680: // rd s1 imm
681: // ----------
682: // r0 * * nop
683: // rd r0 #imm mov rd, #imm
684: // rd rd #imm xor rd, #imm
685: // rd s1 #imm xor rd, s1, #imm
686:
687: if (DD == 0) {
688: altname = "nop";
689: } else if (S1 == 0) {
690: altname = "mov";
691: altarg0 = rd();
692: altarg1 = imm16();
693: } else {
694: altname = "xor";
695: altarg0 = rd();
696: if (DD != S1) {
697: altarg1 = rs1();
698: }
699: altarg2 = imm16();
700: }
1.1 root 701: }
702:
703: // 010101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
704: OP_DEF(xor_u_imm)
705: {
706: name = "xor.u";
707: arg0 = rd();
708: arg1 = rs1();
709: arg2 = imm16();
1.1.1.7 root 710:
711: // rd s1 imm
712: // ----------
713: // r0 * * nop
714: // rd r0 #imm mov rd, #imm'0000
715: // rd rd #imm xor rd, #imm'0000
716: // rd s1 #imm xor rd, s1, #imm'0000
717:
718: if (DD == 0) {
719: altname = "nop";
720: } else if (S1 == 0) {
721: altname = "mov";
722: altarg0 = rd();
723: altarg1 = imm16() + "0000";
724: } else {
725: altname = "xor";
726: altarg0 = rd();
727: if (DD != S1) {
728: altarg1 = rs1();
729: }
730: altarg2 = imm16() + "0000";
731: }
1.1 root 732: }
733:
734: // 010110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
735: OP_DEF(or_imm)
736: {
737: name = "or";
738: arg0 = rd();
739: arg1 = rs1();
740: arg2 = imm16();
1.1.1.7 root 741:
742: // rd s1 imm
743: // ----------
744: // r0 * * nop
745: // rd r0 #imm mov rd, #imm
746: // rd rd #imm or rd, #imm
747: // rd s1 #imm or rd, s1, #imm
748:
749: if (DD == 0) {
750: altname = "nop";
751: } else if (S1 == 0) {
752: altname = "mov";
753: altarg0 = rd();
754: altarg1 = imm16();
755: } else {
756: altname = "or";
757: altarg0 = rd();
758: if (DD != S1) {
759: altarg1 = rs1();
760: }
761: altarg2 = imm16();
762: }
1.1 root 763: }
764:
765: // 010111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
766: OP_DEF(or_u_imm)
767: {
768: name = "or.u";
769: arg0 = rd();
770: arg1 = rs1();
771: arg2 = imm16();
1.1.1.7 root 772:
773: // rd s1 imm
774: // ----------
775: // r0 * * nop
776: // rd r0 #imm mov rd, #imm'0000
777: // rd rd #imm or rd, #imm'0000
778: // rd s1 #imm or rd, s1, #imm'0000
779:
780: if (DD == 0) {
781: altname = "nop";
782: } else if (S1 == 0) {
783: altname = "mov";
784: altarg0 = rd();
785: altarg1 = imm16() + "0000";
786: } else {
787: altname = "or";
788: altarg0 = rd();
789: if (DD != S1) {
790: altarg1 = rs1();
791: }
792: altarg2 = imm16() + "0000";
793: }
1.1 root 794: }
795:
796: // 011000_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
797: OP_DEF(addu_imm)
798: {
799: name = "addu";
800: arg0 = rd();
801: arg1 = rs1();
802: arg2 = imm16();
1.1.1.7 root 803:
804: // rd s1 imm
805: // ----------
806: // r0 * * nop
807: // rd r0 #imm mov rd, #0000'imm
808: // rd rd #imm addu rd, #0000'imm
809: // rd s1 #imm addu rd, s1, #0000'imm
810:
811: if (DD == 0) {
812: altname = "nop";
813: } else if (S1 == 0) {
814: altname = "mov";
815: altarg0 = rd();
816: altarg1 = string_format("#0x0000%04x", IMM16);
817: } else {
818: altname = "addu";
819: altarg0 = rd();
820: if (DD != S1) {
821: altarg1 = rs1();
822: }
823: altarg2 = string_format("#0x0000%04x", IMM16);
824: }
1.1 root 825: }
826:
827: // 011001_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
828: OP_DEF(subu_imm)
829: {
830: name = "subu";
831: arg0 = rd();
832: arg1 = rs1();
833: arg2 = imm16();
1.1.1.7 root 834:
835: // rd s1 imm
836: // ----------
837: // r0 * * nop
838: // rd r0 #imm mov rd, #-imm
839: // rd rd #imm subu rd, #0000'imm
840: // rd s1 #imm subu rd, s1, #0000'imm
841:
842: if (DD == 0) {
843: altname = "nop";
844: } else if (S1 == 0) {
845: altname = "mov";
846: altarg0 = rd();
847: altarg1 = string_format("#0x%08x", -(int32)(uint32)IMM16);
848: } else {
849: altname = "subu";
850: altarg0 = rd();
851: if (DD != S1) {
852: altarg1 = rs1();
853: }
854: altarg2 = string_format("#0x0000%04x", IMM16);
855: }
1.1 root 856: }
857:
858: // 011010_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
859: OP_DEF(divu_imm)
860: {
861: name = "divu";
862: arg0 = rd();
863: arg1 = rs1();
864: arg2 = imm16();
1.1.1.7 root 865:
866: // 例外発生の可能性があるので r0 を含んでいたとしても別名にしない
867: altname = "divu";
868: altarg0 = rd();
869: if (DD != S1) {
870: altarg1 = rs1();
871: }
872: altarg2 = string_format("#0x0000%04x", IMM16);
1.1 root 873: }
874:
875: // 011011_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
876: OP_DEF(mul_imm)
877: {
878: name = "mul";
879: arg0 = rd();
880: arg1 = rs1();
881: arg2 = imm16();
1.1.1.7 root 882:
883: // 例外発生の可能性があるので r0 を含んでいたとしても別名にしない
884: altname = "mul";
885: altarg0 = rd();
886: if (DD != S1) {
887: altarg1 = rs1();
888: }
889: altarg2 = string_format("#0x0000%04x", IMM16);
1.1 root 890: }
891:
892: // 011100_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
893: OP_DEF(add_imm)
894: {
895: name = "add";
896: arg0 = rd();
897: arg1 = rs1();
898: arg2 = imm16();
1.1.1.7 root 899:
900: // 例外発生の可能性があるので r0 を含んでいたとしても別名にしない
901: altname = "adds";
902: altarg0 = rd();
903: if (DD != S1) {
904: altarg1 = rs1();
905: }
906: altarg2 = string_format("#0x0000%04x", IMM16);
1.1 root 907: }
908:
909: // 011101_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
910: OP_DEF(sub_imm)
911: {
912: name = "sub";
913: arg0 = rd();
914: arg1 = rs1();
915: arg2 = imm16();
1.1.1.7 root 916:
917: // 例外発生の可能性があるので r0 を含んでいたとしても別名にしない
918: altname = "subs";
919: altarg0 = rd();
920: if (DD != S1) {
921: altarg1 = rs1();
922: }
923: altarg2 = string_format("#0x0000%04x", IMM16);
1.1 root 924: }
925:
926: // 011110_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
927: OP_DEF(div_imm)
928: {
929: name = "div";
930: arg0 = rd();
931: arg1 = rs1();
932: arg2 = imm16();
1.1.1.7 root 933:
934: // 例外発生の可能性があるので r0 を含んでいたとしても別名にしない
935: altname = "div";
936: altarg0 = rd();
937: if (DD != S1) {
938: altarg1 = rs1();
939: }
940: altarg2 = string_format("#0x0000%04x", IMM16);
1.1 root 941: }
942:
943: // 011111_DDDDDSSSSS_nnnnnn_nnnnnnnnnn
944: OP_DEF(cmp_imm)
945: {
946: name = "cmp";
947: arg0 = rd();
948: arg1 = rs1();
949: arg2 = imm16();
1.1.1.7 root 950:
951: if (DD == 0) {
952: altname = "nop";
953: } else {
954: altname = "cmp";
955: altarg0 = rd();
956: altarg1 = rs1();
957: altarg2 = string_format("#0x0000%04x", IMM16);
958: }
1.1 root 959: }
960:
961: // 100000_DDDDDzzzzz_01000n_nnnnnzzzzz
962: OP_DEF(ldcr)
963: {
964: name = "ldcr";
965: arg0 = rd();
966: arg1 = crs();
967: }
968:
969: // 100000_DDDDDzzzzz_01001n_nnnnnzzzzz
970: OP_DEF(fldcr)
971: {
972: name = "fldcr";
973: arg0 = rd();
974: arg1 = fcrs();
975: }
976:
977: // 100000_zzzzzSSSSS_10000n_nnnnnsssss
978: OP_DEF(stcr)
979: {
980: uint32 s1 = (opX >> 16) & 0x1f;
981: uint32 s2 = (opX ) & 0x1f;
982: if (s1 == s2) {
983: name = "stcr";
984: arg1 = rs1();
985: arg2 = crs();
986: } else {
987: // どうすべ
988: OP_FUNC(unimpl);
989: }
990: }
991:
992: // 100000_zzzzzSSSSS_10001n_nnnnnsssss
993: OP_DEF(fstcr)
994: {
995: uint32 s1 = (opX >> 16) & 0x1f;
996: uint32 s2 = (opX ) & 0x1f;
997: if (s1 == s2) {
998: name = "fstcr";
999: arg1 = rs1();
1000: arg2 = fcrs();
1001: } else {
1002: // どうすべ
1003: OP_FUNC(unimpl);
1004: }
1005: }
1006:
1007: // 100000_DDDDDSSSSS_11000n_nnnnnsssss
1008: OP_DEF(xcr)
1009: {
1010: uint32 s1 = (opX >> 16) & 0x1f;
1011: uint32 s2 = (opX ) & 0x1f;
1012: if (s1 == s2) {
1013: name = "xcr";
1014: arg0 = rd();
1015: arg1 = rs1();
1.1.1.2 root 1016: arg2 = crs();
1.1 root 1017: } else {
1018: // どうすべ
1019: OP_FUNC(unimpl);
1020: }
1021: }
1022:
1023: // 100000_DDDDDSSSSS_11001n_nnnnnsssss
1024: OP_DEF(fxcr)
1025: {
1026: uint32 s1 = (opX >> 16) & 0x1f;
1027: uint32 s2 = (opX ) & 0x1f;
1028: if (s1 == s2) {
1029: name = "fxcr";
1030: arg0 = rd();
1031: arg1 = rs1();
1032: arg2 = fcrs();
1033: } else {
1034: // どうすべ
1035: OP_FUNC(unimpl);
1036: }
1037: }
1038:
1039: // 100001_DDDDDSSSSS_00000n_nnnnnsssss
1040: OP_DEF(fmul)
1041: {
1042: name = "fmul." + fsize();
1043: arg0 = rd();
1044: arg1 = rs1();
1045: arg2 = rs2();
1046: }
1047:
1048: // 100001_DDDDD00000_001000_000nnsssss
1049: OP_DEF(flt)
1050: {
1051: name = "flt." + fsize(TD) + "s";
1052: arg0 = rd();
1053: arg2 = rs2();
1054: }
1055:
1056: // 100001_DDDDDSSSSS_00101n_nnnnnsssss
1057: OP_DEF(fadd)
1058: {
1059: name = "fadd." + fsize();
1060: arg0 = rd();
1061: arg1 = rs1();
1062: arg2 = rs2();
1063: }
1064:
1065: // 100001_DDDDDSSSSS_00110n_nnnnnsssss
1066: OP_DEF(fsub)
1067: {
1068: name = "fsub." + fsize();
1069: arg0 = rd();
1070: arg1 = rs1();
1071: arg2 = rs2();
1072: }
1073:
1074: // 100001_DDDDDSSSSS_00111n_nnnnnsssss
1075: OP_DEF(fcmp)
1076: {
1077: name = "fcmp.s" + fsize(T1) + fsize(T2);
1078: arg0 = rd();
1079: arg1 = rs1();
1080: arg2 = rs2();
1081: }
1082:
1083: // 100001_DDDDD00000_010010_0nn00sssss
1084: OP_DEF(int)
1085: {
1086: name = "int.s" + fsize(T2);
1087: arg0 = rd();
1088: arg1 = rs2();
1089: }
1090:
1091: // 100001_DDDDD00000_010100_0nn00sssss
1092: OP_DEF(nint)
1093: {
1094: name = "nint.s" + fsize(T2);
1095: arg0 = rd();
1096: arg1 = rs2();
1097: }
1098:
1099: // 100001_DDDDD00000_010110_0nn00sssss
1100: OP_DEF(trnc)
1101: {
1102: name = "trnc.s" + fsize(T2);
1103: arg0 = rd();
1104: arg2 = rs2();
1105: }
1106:
1107: // 100001_DDDDDSSSSS_01110n_nnnnnsssss
1108: OP_DEF(fdiv)
1109: {
1110: name = "fdiv." + fsize();
1111: arg0 = rd();
1112: arg1 = rs1();
1113: arg2 = rs2();
1114: }
1115:
1116: // 110000_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
1117: OP_DEF(br)
1118: {
1119: name = "br";
1.1.1.6 root 1120: arg0 = d26();
1.1 root 1121: }
1122:
1123: // 110001_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
1124: OP_DEF(br_n)
1125: {
1126: name = "br.n";
1.1.1.6 root 1127: arg0 = d26();
1.1 root 1128: }
1129:
1130: // 110010_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
1131: OP_DEF(bsr)
1132: {
1133: name = "bsr";
1.1.1.6 root 1134: arg0 = d26();
1.1 root 1135: }
1136:
1137: // 110011_nnnnnnnnnn_nnnnnn_nnnnnnnnnn
1138: OP_DEF(bsr_n)
1139: {
1140: name = "bsr.n";
1.1.1.6 root 1141: arg0 = d26();
1.1 root 1142: }
1143:
1144: // bb の共通部
1145: void
1146: m88100disasm::ops_bb(std::string namebase)
1147: {
1148: name = namebase;
1149: arg0 = b5();
1150: arg1 = rs1();
1151: arg2 = d16();
1152: }
1153:
1154: // 110100_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
1155: OP_DEF(bb0)
1156: {
1157: ops_bb("bb0");
1158: }
1159:
1160: // 110101_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
1161: OP_DEF(bb0_n)
1162: {
1163: ops_bb("bb0.n");
1164: }
1165:
1166: // 110110_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
1167: OP_DEF(bb1)
1168: {
1169: ops_bb("bb1");
1170: }
1171:
1172: // 110111_nnnnnSSSSS_nnnnnn_nnnnnnnnnn
1173: OP_DEF(bb1_n)
1174: {
1175: ops_bb("bb1.n");
1176: }
1177:
1178: void
1.1.1.9 root 1179: m88100disasm::ops_bcnd(std::string n)
1.1 root 1180: {
1.1.1.9 root 1181: name = "bcnd" + n;
1.1 root 1182: arg0 = m5();
1183: arg1 = rs1();
1184: arg2 = d16();
1.1.1.9 root 1185:
1186: const std::string cond = alt_m5();
1187: if (cond.empty()) {
1188: // 空なら表現できないやつなので代替表現もなし
1189: return;
1190: } else if (cond == "true") {
1191: // 無条件分岐
1192: altname = "br" + n;
1193: altarg0 = arg2;
1194: } else {
1195: // 条件分岐
1196: altname = "br" + n;
1197: altarg0 = cond;
1198: altarg1 = arg2;
1199: }
1.1 root 1200: }
1201:
1202: // 111010_MMMMMSSSSS_nnnnnn_nnnnnnnnnn
1203: OP_DEF(bcnd)
1204: {
1.1.1.9 root 1205: ops_bcnd("");
1.1 root 1206: }
1207:
1208: // 111011_MMMMMSSSSS_nnnnnn_nnnnnnnnnn
1209: OP_DEF(bcnd_n)
1210: {
1.1.1.9 root 1211: ops_bcnd(".n");
1.1 root 1212: }
1213:
1214: // 111100_DDDDDSSSSS_100000_wwwwwooooo
1215: OP_DEF(clr_1)
1216: {
1217: name = "clr";
1218: arg0 = rd();
1219: arg1 = rs1();
1220: arg2 = wo5();
1.1.1.7 root 1221:
1222: if (DD == 0) {
1223: altname = "nop";
1224: } else {
1.1.1.9 root 1225: altname = "and";
1.1.1.7 root 1226: altarg0 = rd();
1227: altarg1 = rs1();
1.1.1.9 root 1228: altarg2 = string_format("0x%08x", ~wo5mask());
1.1.1.7 root 1229: }
1.1 root 1230: }
1231:
1232: // 111100_DDDDDSSSSS_100010_wwwwwooooo
1233: OP_DEF(set_1)
1234: {
1235: name = "set";
1236: arg0 = rd();
1237: arg1 = rs1();
1238: arg2 = wo5();
1.1.1.7 root 1239:
1240: if (DD == 0) {
1241: altname = "nop";
1242: } else {
1.1.1.9 root 1243: altname = "or";
1.1.1.7 root 1244: altarg0 = rd();
1245: altarg1 = rs1();
1.1.1.9 root 1246: altarg2 = string_format("0x%08x", wo5mask());
1.1.1.7 root 1247: }
1.1 root 1248: }
1249:
1250: // 111100_DDDDDSSSSS_100100_wwwwwooooo
1251: OP_DEF(ext_1)
1252: {
1253: name = "ext";
1254: arg0 = rd();
1255: arg1 = rs1();
1256: arg2 = wo5();
1.1.1.7 root 1257:
1258: // rd s1 imm
1259: // ----------
1260: // r0 * * nop
1261: // rd r0 w:o clr rd
1262: // rd rd 32:o asr rd, #o
1263: // rd s1 32:o asr rd, s1, #o
1264: // rd rd w:o bfexts rd, w:o
1265: // rd s1 w:o bfexts rd, s1, w:o
1266:
1267: if (DD == 0) {
1268: altname = "nop";
1269: } else if (S1 == 0) {
1270: altname = "clr";
1271: altarg0 = rd();
1272: } else if (W5 == 0 || W5 + O5 >= 32) {
1273: // W5 + O5 >= 32 なら単純なシフトに相当
1274: altname = "asr";
1275: altarg0 = rd();
1276: if (DD != S1) {
1277: altarg1 = rs1();
1278: }
1.1.1.10! root 1279: altarg2 = string_format("#%u", O5);
1.1.1.7 root 1280: } else {
1281: altname = "bfexts";
1282: altarg0 = rd();
1283: if (DD != S1) {
1284: altarg1 = rs1();
1285: }
1286: altarg2 = wo5();
1287: }
1.1 root 1288: }
1289:
1290: // 111100_DDDDDSSSSS_100110_wwwwwooooo
1291: OP_DEF(extu_1)
1292: {
1293: name = "extu";
1294: arg0 = rd();
1295: arg1 = rs1();
1296: arg2 = wo5();
1.1.1.7 root 1297:
1298: // rd s1 imm
1299: // ----------
1300: // r0 * * nop
1301: // rd r0 w:o clr rd
1302: // rd rd 32:o lsr rd, #o
1303: // rd s1 32:o lsr rd, s1, #o
1304: // rd rd w:o bfextu rd, w:o
1305: // rd s1 w:o bfextu rd, s1, w:o
1306:
1307: if (DD == 0) {
1308: altname = "nop";
1309: } else if (S1 == 0) {
1310: altname = "clr";
1311: altarg0 = rd();
1312: } else if (W5 == 0 || W5 + O5 >= 32) {
1313: // W5 + O5 >= 32 なら単純なシフトに相当
1314: altname = "lsr";
1315: altarg0 = rd();
1316: if (DD != S1) {
1317: altarg1 = rs1();
1318: }
1.1.1.10! root 1319: altarg2 = string_format("#%u", O5);
1.1.1.7 root 1320: } else {
1321: altname = "bfextu";
1322: altarg0 = rd();
1323: if (DD != S1) {
1324: altarg1 = rs1();
1325: }
1326: altarg2 = wo5();
1327: }
1.1 root 1328: }
1329:
1330: // 111100_DDDDDSSSSS_101000_wwwwwooooo
1331: OP_DEF(mak_1)
1332: {
1333: name = "mak";
1334: arg0 = rd();
1335: arg1 = rs1();
1336: arg2 = wo5();
1.1.1.7 root 1337:
1338: // rd s1 imm
1339: // ----------
1340: // r0 * * nop
1341: // rd r0 w:o clr rd
1342: // rd rd 32:o lsl rd, #o
1343: // rd s1 32:o lsl rd, s1, #o
1344: // rd rd w:o bfmak rd, w:o
1345: // rd s1 w:o bfmak rd, s1, w:o
1346:
1347: if (DD == 0) {
1348: altname = "nop";
1349: } else if (S1 == 0) {
1350: altname = "clr";
1351: altarg0 = rd();
1352: } else if (W5 == 0 || W5 + O5 >= 32) {
1353: // W5 + O5 >= 32 なら単純なシフトに相当
1354: altname = "lsl";
1355: altarg0 = rd();
1356: if (DD != S1) {
1357: altarg1 = rs1();
1358: }
1.1.1.10! root 1359: altarg2 = string_format("#%u", O5);
1.1.1.7 root 1360: } else {
1361: // XXX 名前から動作が想像しづらいのがつらいのだが、とりあえず後回し
1362: altname = "bfmak";
1363: altarg0 = rd();
1364: if (DD != S1) {
1365: altarg1 = rs1();
1366: }
1367: altarg2 = wo5();
1368: }
1.1 root 1369: }
1370:
1371: // 111100_DDDDDSSSSS_101010_zzzzzooooo
1372: OP_DEF(rot_1)
1373: {
1374: name = "rot";
1375: arg0 = rd();
1376: arg1 = rs1();
1.1.1.10! root 1377: arg2 = string_format("<%u>", O5);
1.1.1.7 root 1378:
1379: // rd s1 offset
1380: // ----------
1381: // r0 * * nop
1382: // rd rd #0 nop
1383: // rd r0 * clr rd
1384: // rd rd 1-16 ror rd, #1-16
1385: // rd s1 1-16 ror rd, s1, #1-16
1386: // rd rd 17-31 rol rd, #1-15
1387: // rd s1 17-31 rol rd, s1, #1-15
1388:
1389: if (DD == 0) {
1390: altname = "nop";
1391: } else if (S1 == 0) {
1392: altname = "clr";
1393: altarg0 = rd();
1394: } else if (O5 == 0) {
1395: if (DD == S1) {
1396: altname = "nop";
1397: } else {
1398: altname = "clr";
1399: altarg0 = rd();
1400: }
1401: } else {
1402: // どう表記するのがいいかは状況によるかも知れないが
1403: // 1-16ビット(右)ローテートなら ror #0-16、
1404: // 17-31ビット(右)ローテートなら rol #1-15 としてみる
1405: auto offset = O5;
1406: if (offset > 16) {
1407: altname = "rol";
1408: offset = 32 - offset;
1409: } else {
1410: altname = "ror";
1411: }
1412: altarg0 = rd();
1413: if (DD != S1) {
1414: altarg1 = rs1();
1415: }
1.1.1.10! root 1416: altarg2 = string_format("#%u", offset);
1.1.1.7 root 1417: }
1.1 root 1418: }
1419:
1420: void
1421: m88100disasm::ops_tb(std::string namebase)
1422: {
1423: name = namebase;
1424: arg0 = b5();
1425: arg1 = rs1();
1426: arg2 = vec9();
1427: }
1428:
1429: // 111100_bbbbbSSSSS_110100_0vvvvvvvvv
1430: OP_DEF(tb0)
1431: {
1432: ops_tb("tb0");
1433: }
1434:
1435: // 111100_bbbbbSSSSS_110110_0vvvvvvvvv
1436: OP_DEF(tb1)
1437: {
1.1.1.7 root 1438: ops_tb("tb1");
1439:
1440: if (S1 == 0) {
1.1.1.2 root 1441: // tb1 *,r0,* はパイプライン同期を目的として使われる。
1442: // この形式はトラップは発生しない。
1443: if (VEC9 < 128) {
1.1.1.7 root 1444: altname = "ssync";
1.1.1.2 root 1445: } else {
1.1.1.7 root 1446: altname = "usync";
1.1.1.2 root 1447: }
1448: }
1.1 root 1449: }
1450:
1451: // 111100_MMMMMSSSSS_111010_0vvvvvvvvv
1452: OP_DEF(tcnd)
1453: {
1454: name = "tcnd";
1455: arg0 = m5();
1456: arg1 = rs1();
1457: arg2 = vec9();
1458: }
1459:
1460: // ld_reg, st_reg, xmem_reg の共通部
1.1.1.7 root 1461: // size は ".bu" などドットを含むサイズプレフィックス。
1.1 root 1462: void
1.1.1.7 root 1463: m88100disasm::ops_ldst_reg(const std::string& namebase, std::string size)
1.1 root 1464: {
1465: uint32 u = (opX >> 8) & 1;
1466: uint32 scaled = (opX >> 9) & 1;
1467:
1.1.1.7 root 1468: name = namebase + size;
1.1 root 1469: if (u) {
1470: name += ".usr";
1471: }
1472: arg0 = rd();
1473: arg1 = rs1();
1474: if (scaled == 0) {
1475: arg2 = rs2();
1476: } else {
1477: arg1 += "[" + rs2() + "]";
1478: }
1.1.1.7 root 1479:
1480: // 別名
1481: // ld.bu.usr はサフィックスの使い方が節操なさすぎるし
1482: // ld と ld.usr はわりと違う命令なので、違う命令のように見せる。
1483: altname = namebase;
1484: if (u) {
1485: altname += "usr";
1486: }
1487: altname += size;
1488: altarg0 = rd();
1489:
1490: // メモリアクセスはは括弧を付けて表す。
1491: // lda はメモリアクセスではないので括弧なしのまま。
1492: //
1493: // rs1 rs2 scaled
1494: // --------------
1495: // r* r0 * ld rd, (r*)
1496: // r0 s2 no ld rd, (s2)
1497: // s1 s2 no ld rd, (s1,s2)
1498: // r0 s2 yes ld rd, (r0[s2])
1499: // s1 s2 yes ld rd, (s1[s2])
1500: if (S2 == 0) {
1501: altarg1 = rs1();
1502: } else {
1503: if (scaled == 0) {
1504: if (S1 == 0) {
1505: altarg1 = rs2();
1506: } else {
1507: altarg1 = rs1() + "," + rs2();
1508: }
1509: } else {
1510: altarg1 = rs1() + "[" + rs2() + "]";
1511: }
1512: }
1513: // 3文字目が 'a' になるのは lda しかない
1514: if (namebase[2] != 'a') {
1515: altarg1 = "(" + altarg1 + ")";
1516: }
1.1 root 1517: }
1518:
1519: // 111101_DDDDDSSSSS_000000_xU000sssss
1520: OP_DEF(xmem_bu)
1521: {
1.1.1.7 root 1522: ops_ldst_reg("xmem", ".bu");
1.1 root 1523: }
1524:
1525: // 111101_DDDDDSSSSS_000001_xU000sssss
1526: OP_DEF(xmem_w)
1527: {
1.1.1.7 root 1528: ops_ldst_reg("xmem", "");
1.1 root 1529: }
1530:
1531: // 111101_DDDDDSSSSS_000010_xU000sssss
1532: OP_DEF(ld_hu)
1533: {
1.1.1.7 root 1534: ops_ldst_reg("ld", ".hu");
1.1 root 1535: }
1536:
1537: // 111101_DDDDDSSSSS_000011_xU000sssss
1538: OP_DEF(ld_bu)
1539: {
1.1.1.7 root 1540: ops_ldst_reg("ld", ".bu");
1.1 root 1541: }
1542:
1543: // 111101_DDDDDSSSSS_000100_xU000sssss
1544: OP_DEF(ld_d)
1545: {
1.1.1.7 root 1546: ops_ldst_reg("ld", ".d");
1.1 root 1547: }
1548:
1549: // 111101_DDDDDSSSSS_000101_xU000sssss
1550: OP_DEF(ld_w)
1551: {
1.1.1.7 root 1552: ops_ldst_reg("ld", "");
1.1 root 1553: }
1554:
1555: // 111101_DDDDDSSSSS_000110_xU000sssss
1556: OP_DEF(ld_h)
1557: {
1.1.1.7 root 1558: ops_ldst_reg("ld", ".h");
1.1 root 1559: }
1560:
1561: // 111101_DDDDDSSSSS_000111_xU000sssss
1562: OP_DEF(ld_b)
1563: {
1.1.1.7 root 1564: ops_ldst_reg("ld", ".b");
1.1 root 1565: }
1566:
1567: // 111101_DDDDDSSSSS_001000_xU000sssss
1568: OP_DEF(st_d)
1569: {
1.1.1.7 root 1570: ops_ldst_reg("st", ".d");
1.1 root 1571: }
1572:
1573: // 111101_DDDDDSSSSS_001001_xU000sssss
1574: OP_DEF(st_w)
1575: {
1.1.1.7 root 1576: ops_ldst_reg("st", "");
1.1 root 1577: }
1578:
1579: // 111101_DDDDDSSSSS_001010_xU000sssss
1580: OP_DEF(st_h)
1581: {
1.1.1.7 root 1582: ops_ldst_reg("st", ".h");
1.1 root 1583: }
1584:
1585: // 111101_DDDDDSSSSS_001011_xU000sssss
1586: OP_DEF(st_b)
1587: {
1.1.1.7 root 1588: ops_ldst_reg("st", ".b");
1.1 root 1589: }
1590:
1591: // 111101_DDDDDSSSSS_001100_xU000sssss
1592: OP_DEF(lda_d)
1593: {
1594: // XXX bit8 が 1 だとどうなるのか
1.1.1.7 root 1595: ops_ldst_reg("lda", ".d");
1.1 root 1596: }
1597:
1598: // 111101_DDDDDSSSSS_001101_xU000sssss
1599: OP_DEF(lda_w)
1600: {
1601: // XXX bit8 が 1 だとどうなるのか
1.1.1.7 root 1602: ops_ldst_reg("lda", "");
1.1 root 1603: }
1604:
1605: // 111101_DDDDDSSSSS_001110_xU000sssss
1606: OP_DEF(lda_h)
1607: {
1608: // XXX bit8 が 1 だとどうなるのか
1.1.1.7 root 1609: ops_ldst_reg("lda", ".h");
1.1 root 1610: }
1611:
1612: // 111101_DDDDDSSSSS_001111_xU000sssss
1613: OP_DEF(lda_b)
1614: {
1615: // XXX bit8 が 1 だとどうなるのか
1.1.1.7 root 1616: ops_ldst_reg("lda", ".b");
1.1 root 1617: }
1618:
1619: // 111101_DDDDDSSSSS_010000_00000sssss
1620: OP_DEF(and)
1621: {
1622: name = "and";
1623: arg0 = rd();
1624: arg1 = rs1();
1625: arg2 = rs2();
1.1.1.7 root 1626:
1627: // rd s1 s2
1628: // ----------
1629: // r0 * * nop
1630: // rd r0 * clr rd
1631: // rd * r0 clr rd
1632: // rd rd rd nop
1633: // rd s1 s1 mov rd, s1
1634: // rd rd s2 and rd, s2
1635: // rd s1 s2 and rd, s1, s2
1636:
1637: if (DD == 0) {
1638: altname = "nop";
1639: } else if (S1 == 0 || S2 == 0) {
1640: altname = "clr";
1641: altarg0 = rd();
1642: } else if (S1 == S2) {
1643: altname = "mov";
1644: altarg0 = rd();
1645: altarg1 = rs1();
1646: } else {
1647: altname = "and";
1648: altarg0 = rd();
1649: if (DD != S1) {
1650: altarg1 = rs1();
1651: }
1652: if (DD != S2) {
1653: altarg2 = rs2();
1654: }
1655: }
1.1 root 1656: }
1657:
1658: // 111101_DDDDDSSSSS_010001_00000sssss
1659: OP_DEF(and_c)
1660: {
1661: name = "and.c";
1662: arg0 = rd();
1663: arg1 = rs1();
1664: arg2 = rs2();
1.1.1.7 root 1665:
1666: // rd s1 s2
1667: // ----------
1668: // r0 * * nop
1669: // rd r0 * clr rd
1670: // rd s1 r0 mov rd, s1
1671: // rd rd r0 nop
1672: // rd s1 s1 clr rd
1673: // rd s1 s2 and rd, s1, ~s2
1674:
1675: if (DD == 0) {
1676: altname = "nop";
1677: } else if (S1 == 0) {
1678: altname = "clr";
1679: altarg0 = rd();
1680: } else if (S2 == 0) {
1681: altname = "mov";
1682: altarg0 = rd();
1683: altarg1 = rs1();
1684: } else if (S1 == S2) {
1685: altname = "clr";
1686: altarg0 = rd();
1687: } else {
1688: altname = "and";
1689: altarg0 = rd();
1690: if (DD != S1) {
1691: altarg1 = rs1();
1692: }
1693: altarg2 = "~" + rs2();
1694: }
1.1 root 1695: }
1696:
1697: // 111101_DDDDDSSSSS_010100_00000sssss
1698: OP_DEF(xor)
1699: {
1700: name = "xor";
1701: arg0 = rd();
1702: arg1 = rs1();
1703: arg2 = rs2();
1.1.1.7 root 1704:
1705: // rd s1 s2
1706: // ----------
1707: // r0 * * nop
1708: // rd s1 s1 clr rd
1709: // rd r0 s2 mov rd, s2
1710: // rd s1 r0 mov rd, s1
1711: // rd s1 s2 xor rd, s1, s2
1712:
1713: if (DD == 0) {
1714: altname = "nop";
1715: } else if (S1 == S2) {
1716: altname = "clr";
1717: altarg0 = rd();
1718: } else if (S1 == 0) {
1719: altname = "mov";
1720: altarg0 = rd();
1721: altarg1 = rs2();
1722: } else if (S2 == 0) {
1723: altname = "mov";
1724: altarg0 = rd();
1725: altarg1 = rs1();
1726: } else {
1727: altname = "xor";
1728: altarg0 = rd();
1729: if (DD != S1) {
1730: altarg1 = rs1();
1731: }
1732: if (DD != S2) {
1733: altarg2 = rs2();
1734: }
1735: }
1.1 root 1736: }
1737:
1738: // 111101_DDDDDSSSSS_010101_00000sssss
1739: OP_DEF(xor_c)
1740: {
1741: name = "xor.c";
1742: arg0 = rd();
1743: arg1 = rs1();
1744: arg2 = rs2();
1.1.1.7 root 1745:
1746: // rd s1 s2
1747: // ----------
1748: // r0 * * nop
1749: // rd s1 s1 mov rd, #0xffffffff
1750: // rd r0 s2 not rd, s2
1751: // rd s1 r0 not rd, s1
1752: // rd s1 s2 xor rd, s1, ~s2
1753:
1754: if (DD == 0) {
1755: altname = "nop";
1756: } else if (S1 == S2) {
1757: altname = "mov";
1758: altarg0 = rd();
1759: altarg1 = "#0xffffffff";
1760: } else if (S1 == 0) {
1761: altname = "not";
1762: altarg0 = rd();
1763: if (DD != S2) {
1764: altarg1 = rs2();
1765: }
1766: } else if (S2 == 0) {
1767: altname = "not";
1768: altarg0 = rd();
1769: if (DD != S1) {
1770: altarg1 = rs1();
1771: }
1772: } else {
1773: altname = "xor";
1774: altarg0 = rd();
1775: if (DD != S1) {
1776: altarg1 = rs1();
1777: }
1778: altarg2 = "~" + rs2();
1779: }
1.1 root 1780: }
1781:
1782: // 111101_DDDDDSSSSS_010110_00000sssss
1783: OP_DEF(or)
1784: {
1.1.1.7 root 1785: name = "or";
1786: arg0 = rd();
1787: arg1 = rs1();
1788: arg2 = rs2();
1789:
1790: // rd s1 s2
1791: // ----------
1792: // r0 * * nop
1793: // rd r0 r0 clr rd
1794: // rd s1 s1 mov rd, s1
1795: // rd s1 r0 mov rd, s1
1796: // rd r0 s2 mov rd, s2
1797: // rd s1 s2 or rd, s1, s2
1798:
1799: if (DD == 0) {
1800: altname = "nop";
1801: } else if (S1 == 0 && S2 == 0) {
1802: altname = "clr";
1803: altarg0 = rd();
1804: } else if (S1 == S2 || S2 == 0) {
1805: altname = "mov";
1806: altarg0 = rd();
1807: altarg1 = rs1();
1808: } else if (S1 == 0) {
1809: altname = "mov";
1810: altarg0 = rd();
1811: altarg1 = rs2();
1.1.1.2 root 1812: } else {
1.1.1.7 root 1813: altname = "or";
1814: altarg0 = rd();
1815: if (DD != S1) {
1816: altarg1 = rs1();
1817: }
1818: if (DD != S2) {
1819: altarg2 = rs2();
1820: }
1.1.1.2 root 1821: }
1.1 root 1822: }
1823:
1824: // 111101_DDDDDSSSSS_010111_00000sssss
1825: OP_DEF(or_c)
1826: {
1827: name = "or.c";
1828: arg0 = rd();
1829: arg1 = rs1();
1830: arg2 = rs2();
1.1.1.7 root 1831:
1832: // rd s1 s2
1833: // ----------
1834: // r0 * * nop
1835: // rd s1 r0 mov rd, #0xffffffff
1836: // rd s1 s1 mov rd, #0xffffffff
1837: // rd r0 s2 not rd, s2
1838: // rd s1 s2 or rd, s1, ~s2
1839:
1840: if (DD == 0) {
1841: altname = "nop";
1842: } else if (S2 == 0 || S1 == S2) {
1843: altname = "mov";
1844: altarg0 = rd();
1845: altarg1 = "#0xffffffff";
1846: } else if (S1 == 0) {
1847: altname = "not";
1848: altarg0 = rd();
1849: if (DD != S2) {
1850: altarg1 = rs2();
1851: }
1852: } else {
1853: altname = "or";
1854: altarg0 = rd();
1855: if (DD != S1) {
1856: altarg1 = rs1();
1857: }
1858: altarg2 = "~" + rs2();
1859: }
1.1 root 1860: }
1861:
1862: // 111101_DDDDDSSSSS_011000_nn000sssss
1863: OP_DEF(addu)
1864: {
1865: name = "addu" + cio();
1866: arg0 = rd();
1867: arg1 = rs1();
1868: arg2 = rs2();
1.1.1.7 root 1869:
1870: if (CIO == 0) {
1871: // addu 無印の場合
1872: //
1873: // rd s1 s2
1874: // ----------
1875: // r0 * * nop
1876: // rd r0 r0 clr rd
1877: // rd s1 r0 mov rd, s1
1878: // rd r0 s2 mov rd, s2
1879: // rd s1 s2 add rd, s1, s2
1880:
1881: if (DD == 0) {
1882: altname = "nop";
1883: } else if (S1 == 0 && S2 == 0) {
1884: altname = "clr";
1885: altarg0 = rd();
1886: } else if (S1 == 0 || S2 == 0) {
1887: altname = "mov";
1888: altarg0 = rd();
1889: if (S1 == 0) {
1890: altarg1 = rs2();
1891: }
1892: if (S2 == 0) {
1893: altarg1 = rs1();
1894: }
1895: } else if (DD == S1 && DD == S2) {
1896: altname = "addu";
1897: altarg0 = rd();
1898: altarg1 = rs2();
1899: } else {
1900: altname = "addu";
1901: altarg0 = rd();
1902: if (DD != S1) {
1903: altarg1 = rs1();
1904: }
1905: if (DD != S2) {
1906: altarg2 = rs2();
1907: }
1908: }
1909: } else {
1910: // addu キャリー込み .ci/co/cio のほうは 2 オペランドへの省略のみ。
1911: // XXX addu の2項は交換可なので addu r1, r2, r1 は addu r1, r2 と
1912: // 省略できていいがそれには未対応。
1913: altname = "addu" + cio();
1914: altarg0 = rd();
1915: if (DD != S1) {
1916: altarg1 = rs1();
1917: }
1918: altarg2 = rs2();
1919: }
1.1 root 1920: }
1921:
1922: // 111101_DDDDDSSSSS_011001_nn000sssss
1923: OP_DEF(subu)
1924: {
1925: name = "subu" + cio();
1926: arg0 = rd();
1927: arg1 = rs1();
1928: arg2 = rs2();
1.1.1.7 root 1929:
1930: if (CIO == 0) {
1931: // subu 無印の場合
1932: //
1933: // rd s1 s2
1934: // ----------
1935: // r0 * * nop
1936: // rd s1 s1 clr rd
1937: // rd s1 r0 mov rd, s1
1938: // rd s1 s2 subu rd, s1, s2
1939:
1940: if (DD == 0) {
1941: altname = "nop";
1942: } else if (S1 == S2) {
1943: altname = "clr";
1944: altarg0 = rd();
1945: } else if (S2 == 0) {
1946: altname = "mov";
1947: altarg0 = rd();
1948: altarg1 = rs1();
1949: } else {
1950: altname = "subu";
1951: altarg0 = rd();
1952: if (DD != S1) {
1953: altarg1 = rs1();
1954: }
1955: altarg2 = rs2();
1956: }
1957: } else {
1958: // subu キャリー込み .ci/co/cio のほうは 2 オペランドへの省略のみ。
1959: altname = "subu" + cio();
1960: altarg0 = rd();
1961: if (DD != S1) {
1962: altarg1 = rs1();
1963: }
1964: altarg2 = rs2();
1965: }
1.1 root 1966: }
1967:
1968: // 111101_DDDDDSSSSS_011010_zz000sssss
1969: OP_DEF(divu)
1970: {
1971: name = "divu";
1972: arg0 = rd();
1973: arg1 = rs1();
1974: arg2 = rs2();
1.1.1.7 root 1975:
1976: // 例外が起きる可能性があるので 2オペランドへの省略のみ
1977: altname = "divu";
1978: altarg0 = rd();
1979: if (DD != S1) {
1980: altarg1 = rs1();
1981: }
1982: altarg2 = rs2();
1.1 root 1983: }
1984:
1985: // 111101_DDDDDSSSSS_011011_zz000sssss
1986: OP_DEF(mul)
1987: {
1988: name = "mul";
1989: arg0 = rd();
1990: arg1 = rs1();
1991: arg2 = rs2();
1.1.1.7 root 1992:
1993: // 例外が起きる可能性があるので 2オペランドへの省略のみ
1994: altname = "mul";
1995: altarg0 = rd();
1996: if (DD != S1) {
1997: altarg1 = rs1();
1998: }
1999: altarg2 = rs2();
1.1 root 2000: }
2001:
2002: // 111101_DDDDDSSSSS_011100_nn000sssss
2003: OP_DEF(add)
2004: {
2005: name = "add" + cio();
2006: arg0 = rd();
2007: arg1 = rs1();
2008: arg2 = rs2();
1.1.1.7 root 2009:
2010: if (CIO == 0) {
2011: // add 無印は符号付きなので、より明示的な adds を使う。
2012: // 符号付き加算ではオーバーフローが起きる可能性があるため、
2013: // rD が r0 であってもただちに nop とはならない。
2014: // 一方 r0 を加算する場合は何も起きないので圧縮表記したい。
2015:
2016: // rd s1 s2
2017: // ----------
2018: // rd r0 r0 clr rd
2019: // r0 r0 rd nop
2020: // rd r0 rd nop
2021: // rd r0 s2 mov rd, s2
2022: // rd rd r0 nop
2023: // rd s1 r0 mov rd, s1
2024: // rd s1 s2 adds rd, s1, s2
2025:
2026: if (S1 == 0 && S2 == 0) {
2027: if (DD == 0) {
2028: altname = "nop";
2029: } else {
2030: altname = "clr";
2031: altarg0 = rd();
2032: }
2033: } else if (S1 == 0) {
2034: if (DD == 0) {
2035: altname = "nop";
2036: } else {
2037: altname = "mov";
2038: altarg0 = rd();
2039: altarg1 = rs2();
2040: }
2041: } else if (S2 == 0) {
2042: if (DD == 0) {
2043: altname = "nop";
2044: } else {
2045: altname = "mov";
2046: altarg0 = rd();
2047: altarg1 = rs1();
2048: }
2049: } else {
2050: altname = "adds";
2051: altarg0 = rd();
2052: if (DD != S1) {
2053: altarg1 = rs1();
2054: }
2055: altarg2 = rs2();
2056: }
2057: } else {
2058: // adds キャリー込み .ci/co/cio のほうは 2 オペランドへの省略のみ。
2059: altname = "adds" + cio();
2060: altarg0 = rd();
2061: if (DD != S1) {
2062: altarg1 = rs1();
2063: }
2064: altarg2 = rs2();
2065: }
1.1 root 2066: }
2067:
2068: // 111101_DDDDDSSSSS_011101_nn000sssss
2069: OP_DEF(sub)
2070: {
2071: name = "sub" + cio();
2072: arg0 = rd();
2073: arg1 = rs1();
2074: arg2 = rs2();
1.1.1.7 root 2075:
2076: if (CIO == 0) {
2077: // sub 無印は符号付きなので、より明示的な subs を使う。
2078: // 符号付き減算ではオーバーフローが起きる可能性があるため、
2079: // rD が r0 であってもただちに nop とはならない。
2080: // 一方 r0 を減算する場合は何も起きないので圧縮表記したい。
2081:
2082: // rd s1 s2
2083: // ----------
2084: // rd rd r0 nop
2085: // rd r0 r0 clr rd
2086: // rd s1 r0 mov rd, s1
2087: // rd s1 s2 subs rd, s1, s2
2088:
2089: if (S1 == 0 && S2 == 0) {
2090: if (DD == 0) {
2091: altname = "nop";
2092: } else {
2093: altname = "clr";
2094: altarg0 = rd();
2095: }
2096: } else if (S2 == 0) {
2097: if (DD == 0) {
2098: altname = "nop";
2099: } else {
2100: altname = "mov";
2101: altarg0 = rd();
2102: altarg1 = rs1();
2103: }
2104: } else {
2105: altname = "subs";
2106: altarg0 = rd();
2107: if (DD != S1) {
2108: altarg1 = rs1();
2109: }
2110: altarg2 = rs2();
2111: }
2112: } else {
2113: // subs キャリー込み .ci/co/cio のほうは 2 オペランドへの省略のみ。
2114: altname = "subs" + cio();
2115: altarg0 = rd();
2116: if (DD != S1) {
2117: altarg1 = rs1();
2118: }
2119: altarg2 = rs2();
2120: }
1.1 root 2121: }
2122:
2123: // 111101_DDDDDSSSSS_011110_zz000sssss
2124: OP_DEF(div)
2125: {
2126: name = "div";
2127: arg0 = rd();
2128: arg1 = rs1();
2129: arg2 = rs2();
1.1.1.7 root 2130:
2131: // 例外が起きる可能性があるので 2オペランドへの省略のみ
2132: altname = "div";
2133: altarg0 = rd();
2134: if (DD != S1) {
2135: altarg1 = rs1();
2136: }
2137: altarg2 = rs2();
1.1 root 2138: }
2139:
2140: // 111101_DDDDDSSSSS_011111_zz000sssss
2141: OP_DEF(cmp)
2142: {
2143: name = "cmp";
2144: arg0 = rd();
2145: arg1 = rs1();
2146: arg2 = rs2();
1.1.1.7 root 2147:
2148: // cmp r0,*,* 以外は別表記を用意する必要ない
2149: if (DD == 0) {
2150: altname = "nop";
2151: }
1.1 root 2152: }
2153:
2154: // 111101_DDDDDSSSSS_100000_00000sssss
2155: OP_DEF(clr_2)
2156: {
2157: name = "clr";
2158: arg0 = rd();
2159: arg1 = rs1();
2160: arg2 = rs2();
1.1.1.7 root 2161:
2162: // rd s1 s2
2163: // ----------
2164: // r0 * * nop
2165: // rd r0 s2 clr rd
2166: // rd s1 r0 mov rd, s1
2167: // rd rd s2 bfclr rd, s2
2168: // rd s1 s2 bfclr rd, s1, s2
2169:
2170: if (DD == 0) {
2171: altname = "nop";
2172: } else if (S1 == 0) {
2173: altname = "clr";
2174: altarg0 = rd();
2175: } else if (S2 == 0) {
2176: altname = "mov";
2177: altarg0 = rd();
2178: altarg1 = rs1();
2179: } else {
2180: altname = "bfclr";
2181: altarg0 = rd();
2182: if (DD != S1) {
2183: altarg1 = rs1();
2184: }
2185: altarg2 = rs2();
2186: }
1.1 root 2187: }
2188:
2189: // 111101_DDDDDSSSSS_100010_00000sssss
2190: OP_DEF(set_2)
2191: {
2192: name = "set";
2193: arg0 = rd();
2194: arg1 = rs1();
2195: arg2 = rs2();
1.1.1.7 root 2196:
2197: // rd s1 s2
2198: // ----------
2199: // r0 * * nop
2200: // rd s1 r0 mov rd, #0xffffffff
2201: // rd rd s2 bfset rd, s2
2202: // rd s1 s2 bfset rd, s1, s2
2203:
2204: if (DD == 0) {
2205: altname = "nop";
2206: } else if (S2 == 0) {
2207: altname = "mov";
2208: altarg0 = rd();
2209: altarg1 = "#0xffffffff";
2210: } else {
2211: altname = "bfset";
2212: altarg0 = rd();
2213: if (DD != S1) {
2214: altarg1 = rs1();
2215: }
2216: altarg2 = rs2();
2217: }
1.1 root 2218: }
2219:
2220: // 111101_DDDDDSSSSS_100100_00000sssss
2221: OP_DEF(ext_2)
2222: {
2223: name = "ext";
2224: arg0 = rd();
2225: arg1 = rs1();
2226: arg2 = rs2();
1.1.1.7 root 2227:
2228: // rd s1 s2
2229: // ----------
2230: // r0 * * nop
2231: // rd s1 r0 mov rd, s1
2232: // rd rd s2 bfexts rd, s2
2233: // rd s1 s2 bfexts rd, s1, s2
2234:
2235: if (DD == 0) {
2236: altname = "nop";
2237: } else if (S2 == 0) {
2238: altname = "mov";
2239: altarg0 = rd();
2240: altarg1 = rs1();
2241: } else {
2242: altname = "bfexts";
2243: altarg0 = rd();
2244: if (DD != S1) {
2245: altarg1 = rs1();
2246: }
2247: altarg2 = rs2();
2248: }
1.1 root 2249: }
2250:
2251: // 111101_DDDDDSSSSS_100110_00000sssss
2252: OP_DEF(extu_2)
2253: {
2254: name = "extu";
2255: arg0 = rd();
2256: arg1 = rs1();
2257: arg2 = rs2();
1.1.1.7 root 2258:
2259: // rd s1 s2
2260: // ----------
2261: // r0 * * nop
2262: // rd s1 r0 mov rd, s1
2263: // rd rd s2 bfextu rd, s2
2264: // rd s1 s2 bfextu rd, s1, s2
2265:
2266: if (DD == 0) {
2267: altname = "nop";
2268: } else if (S2 == 0) {
2269: altname = "mov";
2270: altarg0 = rd();
2271: altarg1 = rs1();
2272: } else {
2273: altname = "bfextu";
2274: altarg0 = rd();
2275: if (DD != S1) {
2276: altarg1 = rs1();
2277: }
2278: altarg2 = rs2();
2279: }
1.1 root 2280: }
2281:
2282: // 111101_DDDDDSSSSS_101000_00000sssss
2283: OP_DEF(mak_2)
2284: {
2285: name = "mak";
2286: arg0 = rd();
2287: arg1 = rs1();
2288: arg2 = rs2();
1.1.1.7 root 2289:
2290: // rd s1 s2
2291: // ----------
2292: // r0 * * nop
2293: // rd r0 s2 clr rd
2294: // rd s1 r0 mov rd, s1
2295: // rd s1 s2 bfmak rd, s1, s2
2296:
2297: if (DD == 0) {
2298: altname = "nop";
2299: } else if (S1 == 0) {
2300: altname = "clr";
2301: altarg0 = rd();
2302: } else if (S2 == 0) {
2303: altname = "mov";
2304: altarg0 = rd();
2305: altarg1 = rs1();
2306: } else {
2307: altname = "bfmak";
2308: altarg0 = rd();
2309: if (DD != S1) {
2310: altarg1 = rs1();
2311: }
2312: altarg2 = rs2();
2313: }
1.1 root 2314: }
2315:
2316: // 111101_DDDDDSSSSS_101010_00000sssss
2317: OP_DEF(rot_2)
2318: {
2319: name = "rot";
2320: arg0 = rd();
2321: arg1 = rs1();
2322: arg2 = rs2();
1.1.1.7 root 2323:
2324: // rd s1 s2
2325: // ----------
2326: // r0 * * nop
2327: // rd r0 s2 clr rd
2328: // rd s1 r0 mov rd, s1
2329: // rd s1 s2 ror rd, s1, s2
2330:
2331: if (DD == 0) {
2332: altname = "nop";
2333: } else if (S1 == 0) {
2334: altname = "clr";
2335: altarg0 = rd();
2336: } else if (S2 == 0) {
2337: altname = "mov";
2338: altarg0 = rd();
2339: altarg1 = rs1();
2340: } else {
2341: altname = "ror";
2342: altarg0 = rd();
2343: if (DD != S1) {
2344: altarg1 = rs1();
2345: }
2346: altarg2 = rs2();
2347: }
1.1 root 2348: }
2349:
2350: // 111101_zzzzzzzzzz_110000_00000sssss
2351: OP_DEF(jmp)
2352: {
2353: name = "jmp";
2354: arg0 = rs2();
2355: }
2356:
2357: // 111101_zzzzzzzzzz_110001_00000sssss
2358: OP_DEF(jmp_n)
2359: {
2360: name = "jmp.n";
2361: arg0 = rs2();
2362: }
2363:
2364: // 111101_zzzzzzzzzz_110010_00000sssss
2365: OP_DEF(jsr)
2366: {
2367: name = "jsr";
2368: arg0 = rs2();
2369: }
2370:
2371: // 111101_zzzzzzzzzz_110011_00000sssss
2372: OP_DEF(jsr_n)
2373: {
2374: name = "jsr.n";
2375: arg0 = rs2();
2376: }
2377:
1.1.1.2 root 2378: // 111101_DDDDDzzzzz_111010_00000sssss
2379: OP_DEF(ff1)
2380: {
2381: name = "ff1";
2382: arg0 = rd();
2383: arg1 = rs2();
1.1.1.7 root 2384:
2385: // rd s2
2386: // ------
2387: // r0 * nop
2388: // rd r0 mov rd, #32
2389: // rd s2 ff1 rd, s2
2390:
2391: if (DD == 0) {
2392: altname = "nop";
2393: } else if (S2 == 0) {
2394: altname = "mov";
2395: altarg0 = rd();
2396: altarg1 = "#32";
2397: } else {
2398: altname = "ff1";
2399: altarg0 = rd();
2400: altarg1 = rs2();
2401: }
1.1.1.2 root 2402: }
2403:
2404: // 111101_DDDDDzzzzz_111011_00000sssss
2405: OP_DEF(ff0)
2406: {
2407: name = "ff0";
2408: arg0 = rd();
2409: arg1 = rs2();
1.1.1.7 root 2410:
2411: // rd s2
2412: // ------
2413: // r0 * nop
2414: // rd r0 clr rd
2415: // rd s2 ff0 rd, s2
2416:
2417: if (DD == 0) {
2418: altname = "nop";
2419: } else if (S2 == 0) {
2420: altname = "clr";
2421: altarg0 = rd();
2422: } else {
2423: altname = "ff0";
2424: altarg0 = rd();
2425: altarg1 = rs2();
2426: }
1.1.1.2 root 2427: }
2428:
1.1 root 2429: // 111101_zzzzzzzzzz_111111_0000000000
2430: OP_DEF(rte)
2431: {
2432: name = "rte";
2433: }
2434:
2435: // 111101_zzzzzSSSSS_111110_00000SSSSS
2436: OP_DEF(tbnd_1)
2437: {
2438: name = "tbnd";
2439: arg1 = rs1();
2440: arg2 = rs2();
2441: }
2442:
2443: // 111110_zzzzzSSSSS_nnnnnn_nnnnnnnnnn
2444: OP_DEF(tbnd_2)
2445: {
2446: name = "tbnd";
2447: arg1 = rs1();
2448: arg2 = imm16();
2449: }
2450:
1.1.1.7 root 2451: // 111111_DDDDDSSSSS_000001_00nnnnnnnn
2452: OP_DEF(doscall)
1.1 root 2453: {
1.1.1.7 root 2454: name = "doscall";
2455: arg0 = rd();
2456: arg1 = rs1();
2457: arg2 = string_format("#0x%02x", (opX & 0xff));
1.1 root 2458: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.