-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNanoDisasm.c
109 lines (102 loc) · 3.38 KB
/
NanoDisasm.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <stdio.h>
#include <stdlib.h>
#include "NanoCpu.h"
/*
* ===== Table of ALU operations =====
* Must match order of ALU_OP...
*/
char szAlu[16][5] =
{
/* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
"add", "sub", "adc", "sbc ", "rsub", "and", "or ", "xor",
"mul", "div", "asr", "lsr ", "aluc", "alud", "alue", "aluf"
};
/*
* ===== Table of Conditional Branch instructions =====
* Must match order of COND_BRA...
*/
char szBra[16][4] =
{
/* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
"beq", "bne", "bhi", "bls", "bhs", "blo", "bgt", "ble",
"bge", "blt", "bra", "rts", "jal", "bdx", "bex", "bfx"
};
const char szRegName[16][4] =
{
/* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "sp", "lr"
};
#ifdef _MSC_VER
#define SNPRINTF _snprintf
#else
#define SNPRINTF snprintf
#endif
/*
* ===== NanoDisAsm =====
* Disassemble one instruction. Note: prefixes are treated as
* separate instructions to mimic the behaviour of the hardware.
*/
int NanoDisAsm(char* line, size_t len, NANO_ADDR addr, NANO_INST opc)
{
int length;
int Rx, Ry;
/* Decode (register) fields */
Rx = OPC_RX(opc);
Ry = OPC_RY(opc);
switch (GET_OPC(opc))
{
case OPC_ADD_IMM:
length = SNPRINTF(line, len, "add %s,%s,#%-3u", szRegName[Rx], szRegName[Ry], OPC_IMM4(opc));
break;
case OPC_SUB_IMM:
length = SNPRINTF(line, len, "sub %s,%s,#%-3u", szRegName[Rx], szRegName[Ry], OPC_IMM4(opc));
break;
case OPC_ADC_IMM:
length = SNPRINTF(line, len, "adc %s,%s,#%-3u", szRegName[Rx], szRegName[Ry], OPC_IMM4(opc));
break;
case OPC_SBC_IMM:
length = SNPRINTF(line, len, "sbc %s,%s,#%-3u", szRegName[Rx], szRegName[Ry], OPC_IMM4(opc));
break;
case OPC_RSUB_IMM:
length = SNPRINTF(line, len, "rsub %s,%s,#%-3u", szRegName[Rx], szRegName[Ry], OPC_IMM4(opc));
break;
case OPC_AND_IMM:
length = SNPRINTF(line, len, "and %s,%s,#%-3u", szRegName[Rx], szRegName[Ry], OPC_IMM4(opc));
break;
case OPC_OR_IMM:
length = SNPRINTF(line, len, "or %s,%s,#%-3u", szRegName[Rx], szRegName[Ry], OPC_IMM4(opc));
break;
case OPC_XOR_IMM:
length = SNPRINTF(line, len, "xor %s,%s,#%-3u", szRegName[Rx], szRegName[Ry], OPC_IMM4(opc));
break;
case OPC_LB_OFF:
length = SNPRINTF(line, len, "lb %s,%u[%s]", szRegName[Rx], OPC_OFF4(opc), szRegName[Ry]);
break;
case OPC_SB_OFF:
length = SNPRINTF(line, len, "sb %s,%u[%s]", szRegName[Rx], OPC_OFF4(opc), szRegName[Ry]);
break;
case OPC_ALU_REG:
length = SNPRINTF(line, len, "%s %s,%s", szAlu[OPC_RZ(opc)], szRegName[Rx], szRegName[Ry]);
break;
case OPC_BRANCH:
length = SNPRINTF(line, len, "%-4s $" NANO_SZADDR, szBra[Rx], addr + 2 * SIGN_EXT(opc, 128) + 2);
break;
case OPC_MOV_IMM:
length = SNPRINTF(line, len, "mov %s,#%-3u", szRegName[Rx], OPC_IMM8(opc));
break;
case OPC_LW_OFF:
length = SNPRINTF(line, len, "lw %s,%u[%s]", szRegName[Rx], OPC_OFF4(opc)*2, szRegName[Ry]);
break;
case OPC_SW_OFF:
length = SNPRINTF(line, len, "sw %s,%u[%s]", szRegName[Rx], OPC_OFF4(opc)*2, szRegName[Ry]);
break;
case OPC_IMM:
length = SNPRINTF(line, len, "imm #%03x", OPC_IMM12(opc));
break;
default:
length = SNPRINTF(line, len, ".word $%04X", opc);
break;
}
return length;
}