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