src/arm/decoder-inlines.h (view raw)
1#ifndef ARM_DECODER_INLINES_H
2#define ARM_DECODER_INLINES_H
3
4#include "decoder.h"
5
6#include "arm.h"
7
8#include <stdio.h>
9#include <string.h>
10
11#define ADVANCE(AMOUNT) \
12 if (AMOUNT > blen) { \
13 buffer[blen - 1] = '\0'; \
14 return total; \
15 } \
16 total += AMOUNT; \
17 buffer += AMOUNT; \
18 blen -= AMOUNT;
19
20#define LOAD_CYCLES \
21 info->iCycles = 1; \
22 info->nDataCycles = 1;
23
24#define STORE_CYCLES \
25 info->sInstructionCycles = 0; \
26 info->nInstructionCycles = 1; \
27 info->nDataCycles = 1;
28
29static int _decodeRegister(int reg, char* buffer, int blen);
30static int _decodeRegisterList(int list, char* buffer, int blen);
31static int _decodePCRelative(uint32_t address, uint32_t pc, char* buffer, int blen);
32static int _decodeMemory(struct ARMMemoryAccess memory, int pc, char* buffer, int blen);
33
34static const char* _armConditions[] = {
35 "eq",
36 "ne",
37 "cs",
38 "cc",
39 "mi",
40 "pl",
41 "vs",
42 "vc",
43 "hi",
44 "ls",
45 "ge",
46 "lt",
47 "gt",
48 "le",
49 "al",
50 "nv"
51};
52
53static int _decodeRegister(int reg, char* buffer, int blen) {
54 switch (reg) {
55 case ARM_SP:
56 strncpy(buffer, "sp", blen - 1);
57 return 2;
58 case ARM_LR:
59 strncpy(buffer, "lr", blen - 1);
60 return 2;
61 case ARM_PC:
62 strncpy(buffer, "pc", blen - 1);
63 return 2;
64 default:
65 return snprintf(buffer, blen - 1, "r%i", reg);
66 }
67}
68
69static int _decodeRegisterList(int list, char* buffer, int blen) {
70 if (blen <= 0) {
71 return 0;
72 }
73 int total = 0;
74 strncpy(buffer, "{", blen - 1);
75 ADVANCE(1);
76 int i;
77 int start = -1;
78 int end = -1;
79 int written;
80 for (i = 0; i <= ARM_PC; ++i) {
81 if (list & 1) {
82 if (start < 0) {
83 start = i;
84 end = i;
85 } else if (end + 1 == i) {
86 end = i;
87 } else {
88 if (end > start) {
89 written = _decodeRegister(start, buffer, blen);
90 ADVANCE(written);
91 strncpy(buffer, "-", blen - 1);
92 ADVANCE(1);
93 }
94 written = _decodeRegister(end, buffer, blen);
95 ADVANCE(written);
96 strncpy(buffer, ",", blen - 1);
97 ADVANCE(1);
98 start = i;
99 end = i;
100 }
101 }
102 list >>= 1;
103 }
104 if (start >= 0) {
105 if (end > start) {
106 written = _decodeRegister(start, buffer, blen);
107 ADVANCE(written);
108 strncpy(buffer, "-", blen - 1);
109 ADVANCE(1);
110 }
111 written = _decodeRegister(end, buffer, blen);
112 ADVANCE(written);
113 }
114 strncpy(buffer, "}", blen - 1);
115 ADVANCE(1);
116 return total;
117}
118
119static int _decodePCRelative(uint32_t address, uint32_t pc, char* buffer, int blen) {
120 return snprintf(buffer, blen - 1, "$%08X", address + pc);
121}
122
123static int _decodeMemory(struct ARMMemoryAccess memory, int pc, char* buffer, int blen) {
124 if (blen <= 1) {
125 return 0;
126 }
127 int total = 0;
128 strncpy(buffer, "[", blen - 1);
129 ADVANCE(1);
130 int written;
131 if (memory.format & ARM_MEMORY_REGISTER_BASE) {
132 if (memory.baseReg == ARM_PC && memory.format & ARM_MEMORY_IMMEDIATE_OFFSET) {
133 written = _decodePCRelative(memory.offset.immediate, pc, buffer, blen);
134 ADVANCE(written);
135 } else {
136 written = _decodeRegister(memory.baseReg, buffer, blen);
137 ADVANCE(written);
138 if (memory.format & (ARM_MEMORY_REGISTER_OFFSET | ARM_MEMORY_IMMEDIATE_OFFSET) && !(memory.format & ARM_MEMORY_POST_INCREMENT)) {
139 strncpy(buffer, ", ", blen - 1);
140 ADVANCE(2);
141 }
142 }
143 }
144 if (memory.format & ARM_MEMORY_POST_INCREMENT) {
145 strncpy(buffer, "], ", blen - 1);
146 ADVANCE(3);
147 }
148 if (memory.format & ARM_MEMORY_IMMEDIATE_OFFSET && memory.baseReg != ARM_PC) {
149 if (memory.format & ARM_MEMORY_OFFSET_SUBTRACT) {
150 written = snprintf(buffer, blen - 1, "#-%i", memory.offset.immediate);
151 ADVANCE(written);
152 } else {
153 written = snprintf(buffer, blen - 1, "#%i", memory.offset.immediate);
154 ADVANCE(written);
155 }
156 } else if (memory.format & ARM_MEMORY_REGISTER_OFFSET) {
157 if (memory.format & ARM_MEMORY_OFFSET_SUBTRACT) {
158 strncpy(buffer, "-", blen - 1);
159 ADVANCE(1);
160 }
161 written = _decodeRegister(memory.offset.reg, buffer, blen);
162 ADVANCE(written);
163 }
164 // TODO: shifted registers
165
166 if (!(memory.format & ARM_MEMORY_POST_INCREMENT)) {
167 strncpy(buffer, "]", blen - 1);
168 ADVANCE(1);
169 }
170 if (memory.format & ARM_MEMORY_PRE_INCREMENT) {
171 strncpy(buffer, "!", blen - 1);
172 ADVANCE(1);
173 }
174 return total;
175}
176
177#endif