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