rlm@1
|
1 #ifdef BKPT_SUPPORT
|
rlm@1
|
2 #define CONSOLE_OUTPUT(a, b) \
|
rlm@1
|
3 extern void (*dbgOutput)(char *, u32); \
|
rlm@1
|
4 if ((opcode == 0xe0000000) && (reg[0].I == 0xC0DED00D)) { \
|
rlm@1
|
5 dbgOutput((a), (b)); \
|
rlm@1
|
6 }
|
rlm@1
|
7 #else
|
rlm@1
|
8 #define CONSOLE_OUTPUT(a, b)
|
rlm@1
|
9 #endif
|
rlm@1
|
10
|
rlm@1
|
11 #define OP_AND \
|
rlm@1
|
12 reg[dest].I = reg[(opcode >> 16) & 15].I & value; \
|
rlm@1
|
13 CONSOLE_OUTPUT(NULL, reg[2].I);
|
rlm@1
|
14
|
rlm@1
|
15 #define OP_ANDS \
|
rlm@1
|
16 reg[dest].I = reg[(opcode >> 16) & 15].I & value; \
|
rlm@1
|
17 \
|
rlm@1
|
18 N_FLAG = (reg[dest].I & 0x80000000) ? true : false; \
|
rlm@1
|
19 Z_FLAG = (reg[dest].I) ? false : true; \
|
rlm@1
|
20 C_FLAG = C_OUT;
|
rlm@1
|
21
|
rlm@1
|
22 #define OP_EOR \
|
rlm@1
|
23 reg[dest].I = reg[(opcode >> 16) & 15].I ^ value;
|
rlm@1
|
24
|
rlm@1
|
25 #define OP_EORS \
|
rlm@1
|
26 reg[dest].I = reg[(opcode >> 16) & 15].I ^ value; \
|
rlm@1
|
27 \
|
rlm@1
|
28 N_FLAG = (reg[dest].I & 0x80000000) ? true : false; \
|
rlm@1
|
29 Z_FLAG = (reg[dest].I) ? false : true; \
|
rlm@1
|
30 C_FLAG = C_OUT;
|
rlm@1
|
31 #ifdef C_CORE
|
rlm@1
|
32 #define NEG(i) ((i) >> 31)
|
rlm@1
|
33 #define POS(i) ((~(i)) >> 31)
|
rlm@1
|
34 #define ADDCARRY(a, b, c) \
|
rlm@1
|
35 C_FLAG = ((NEG(a) & NEG(b)) | \
|
rlm@1
|
36 (NEG(a) & POS(c)) | \
|
rlm@1
|
37 (NEG(b) & POS(c))) ? true : false;
|
rlm@1
|
38 #define ADDOVERFLOW(a, b, c) \
|
rlm@1
|
39 V_FLAG = ((NEG(a) & NEG(b) & POS(c)) | \
|
rlm@1
|
40 (POS(a) & POS(b) & NEG(c))) ? true : false;
|
rlm@1
|
41 #define SUBCARRY(a, b, c) \
|
rlm@1
|
42 C_FLAG = ((NEG(a) & POS(b)) | \
|
rlm@1
|
43 (NEG(a) & POS(c)) | \
|
rlm@1
|
44 (POS(b) & POS(c))) ? true : false;
|
rlm@1
|
45 #define SUBOVERFLOW(a, b, c) \
|
rlm@1
|
46 V_FLAG = ((NEG(a) & POS(b) & POS(c)) | \
|
rlm@1
|
47 (POS(a) & NEG(b) & NEG(c))) ? true : false;
|
rlm@1
|
48 #define OP_SUB \
|
rlm@1
|
49 { \
|
rlm@1
|
50 reg[dest].I = reg[base].I - value; \
|
rlm@1
|
51 }
|
rlm@1
|
52 #define OP_SUBS \
|
rlm@1
|
53 { \
|
rlm@1
|
54 u32 lhs = reg[base].I; \
|
rlm@1
|
55 u32 rhs = value; \
|
rlm@1
|
56 u32 res = lhs - rhs; \
|
rlm@1
|
57 reg[dest].I = res; \
|
rlm@1
|
58 Z_FLAG = (res == 0) ? true : false; \
|
rlm@1
|
59 N_FLAG = NEG(res) ? true : false; \
|
rlm@1
|
60 SUBCARRY(lhs, rhs, res); \
|
rlm@1
|
61 SUBOVERFLOW(lhs, rhs, res); \
|
rlm@1
|
62 }
|
rlm@1
|
63 #define OP_RSB \
|
rlm@1
|
64 { \
|
rlm@1
|
65 reg[dest].I = value - reg[base].I; \
|
rlm@1
|
66 }
|
rlm@1
|
67 #define OP_RSBS \
|
rlm@1
|
68 { \
|
rlm@1
|
69 u32 lhs = reg[base].I; \
|
rlm@1
|
70 u32 rhs = value; \
|
rlm@1
|
71 u32 res = rhs - lhs; \
|
rlm@1
|
72 reg[dest].I = res; \
|
rlm@1
|
73 Z_FLAG = (res == 0) ? true : false; \
|
rlm@1
|
74 N_FLAG = NEG(res) ? true : false; \
|
rlm@1
|
75 SUBCARRY(rhs, lhs, res); \
|
rlm@1
|
76 SUBOVERFLOW(rhs, lhs, res); \
|
rlm@1
|
77 }
|
rlm@1
|
78 #define OP_ADD \
|
rlm@1
|
79 { \
|
rlm@1
|
80 reg[dest].I = reg[base].I + value; \
|
rlm@1
|
81 }
|
rlm@1
|
82 #define OP_ADDS \
|
rlm@1
|
83 { \
|
rlm@1
|
84 u32 lhs = reg[base].I; \
|
rlm@1
|
85 u32 rhs = value; \
|
rlm@1
|
86 u32 res = lhs + rhs; \
|
rlm@1
|
87 reg[dest].I = res; \
|
rlm@1
|
88 Z_FLAG = (res == 0) ? true : false; \
|
rlm@1
|
89 N_FLAG = NEG(res) ? true : false; \
|
rlm@1
|
90 ADDCARRY(lhs, rhs, res); \
|
rlm@1
|
91 ADDOVERFLOW(lhs, rhs, res); \
|
rlm@1
|
92 }
|
rlm@1
|
93 #define OP_ADC \
|
rlm@1
|
94 { \
|
rlm@1
|
95 reg[dest].I = reg[base].I + value + (u32)C_FLAG; \
|
rlm@1
|
96 }
|
rlm@1
|
97 #define OP_ADCS \
|
rlm@1
|
98 { \
|
rlm@1
|
99 u32 lhs = reg[base].I; \
|
rlm@1
|
100 u32 rhs = value; \
|
rlm@1
|
101 u32 res = lhs + rhs + (u32)C_FLAG; \
|
rlm@1
|
102 reg[dest].I = res; \
|
rlm@1
|
103 Z_FLAG = (res == 0) ? true : false; \
|
rlm@1
|
104 N_FLAG = NEG(res) ? true : false; \
|
rlm@1
|
105 ADDCARRY(lhs, rhs, res); \
|
rlm@1
|
106 ADDOVERFLOW(lhs, rhs, res); \
|
rlm@1
|
107 }
|
rlm@1
|
108 #define OP_SBC \
|
rlm@1
|
109 { \
|
rlm@1
|
110 reg[dest].I = reg[base].I - value - !((u32)C_FLAG); \
|
rlm@1
|
111 }
|
rlm@1
|
112 #define OP_SBCS \
|
rlm@1
|
113 { \
|
rlm@1
|
114 u32 lhs = reg[base].I; \
|
rlm@1
|
115 u32 rhs = value; \
|
rlm@1
|
116 u32 res = lhs - rhs - !((u32)C_FLAG); \
|
rlm@1
|
117 reg[dest].I = res; \
|
rlm@1
|
118 Z_FLAG = (res == 0) ? true : false; \
|
rlm@1
|
119 N_FLAG = NEG(res) ? true : false; \
|
rlm@1
|
120 SUBCARRY(lhs, rhs, res); \
|
rlm@1
|
121 SUBOVERFLOW(lhs, rhs, res); \
|
rlm@1
|
122 }
|
rlm@1
|
123 #define OP_RSC \
|
rlm@1
|
124 { \
|
rlm@1
|
125 reg[dest].I = value - reg[base].I - !((u32)C_FLAG); \
|
rlm@1
|
126 }
|
rlm@1
|
127 #define OP_RSCS \
|
rlm@1
|
128 { \
|
rlm@1
|
129 u32 lhs = reg[base].I; \
|
rlm@1
|
130 u32 rhs = value; \
|
rlm@1
|
131 u32 res = rhs - lhs - !((u32)C_FLAG); \
|
rlm@1
|
132 reg[dest].I = res; \
|
rlm@1
|
133 Z_FLAG = (res == 0) ? true : false; \
|
rlm@1
|
134 N_FLAG = NEG(res) ? true : false; \
|
rlm@1
|
135 SUBCARRY(rhs, lhs, res); \
|
rlm@1
|
136 SUBOVERFLOW(rhs, lhs, res); \
|
rlm@1
|
137 }
|
rlm@1
|
138 #define OP_CMP \
|
rlm@1
|
139 { \
|
rlm@1
|
140 u32 lhs = reg[base].I; \
|
rlm@1
|
141 u32 rhs = value; \
|
rlm@1
|
142 u32 res = lhs - rhs; \
|
rlm@1
|
143 Z_FLAG = (res == 0) ? true : false; \
|
rlm@1
|
144 N_FLAG = NEG(res) ? true : false; \
|
rlm@1
|
145 SUBCARRY(lhs, rhs, res); \
|
rlm@1
|
146 SUBOVERFLOW(lhs, rhs, res); \
|
rlm@1
|
147 }
|
rlm@1
|
148 #define OP_CMN \
|
rlm@1
|
149 { \
|
rlm@1
|
150 u32 lhs = reg[base].I; \
|
rlm@1
|
151 u32 rhs = value; \
|
rlm@1
|
152 u32 res = lhs + rhs; \
|
rlm@1
|
153 Z_FLAG = (res == 0) ? true : false; \
|
rlm@1
|
154 N_FLAG = NEG(res) ? true : false; \
|
rlm@1
|
155 ADDCARRY(lhs, rhs, res); \
|
rlm@1
|
156 ADDOVERFLOW(lhs, rhs, res); \
|
rlm@1
|
157 }
|
rlm@1
|
158
|
rlm@1
|
159 #define LOGICAL_LSL_REG \
|
rlm@1
|
160 { \
|
rlm@1
|
161 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
162 C_OUT = (v >> (32 - shift)) & 1 ? true : false; \
|
rlm@1
|
163 value = v << shift; \
|
rlm@1
|
164 }
|
rlm@1
|
165 #define LOGICAL_LSR_REG \
|
rlm@1
|
166 { \
|
rlm@1
|
167 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
168 C_OUT = (v >> (shift - 1)) & 1 ? true : false; \
|
rlm@1
|
169 value = v >> shift; \
|
rlm@1
|
170 }
|
rlm@1
|
171 #define LOGICAL_ASR_REG \
|
rlm@1
|
172 { \
|
rlm@1
|
173 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
174 C_OUT = ((s32)v >> (int)(shift - 1)) & 1 ? true : false; \
|
rlm@1
|
175 value = (s32)v >> (int)shift; \
|
rlm@1
|
176 }
|
rlm@1
|
177 #define LOGICAL_ROR_REG \
|
rlm@1
|
178 { \
|
rlm@1
|
179 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
180 C_OUT = (v >> (shift - 1)) & 1 ? true : false; \
|
rlm@1
|
181 value = ((v << (32 - shift)) | \
|
rlm@1
|
182 (v >> shift)); \
|
rlm@1
|
183 }
|
rlm@1
|
184 #define LOGICAL_RRX_REG \
|
rlm@1
|
185 { \
|
rlm@1
|
186 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
187 shift = (int)C_FLAG; \
|
rlm@1
|
188 C_OUT = (v & 1) ? true : false; \
|
rlm@1
|
189 value = ((v >> 1) | \
|
rlm@1
|
190 (shift << 31)); \
|
rlm@1
|
191 }
|
rlm@1
|
192 #define LOGICAL_ROR_IMM \
|
rlm@1
|
193 { \
|
rlm@1
|
194 u32 v = opcode & 0xff; \
|
rlm@1
|
195 C_OUT = (v >> (shift - 1)) & 1 ? true : false; \
|
rlm@1
|
196 value = ((v << (32 - shift)) | \
|
rlm@1
|
197 (v >> shift)); \
|
rlm@1
|
198 }
|
rlm@1
|
199 #define ARITHMETIC_LSL_REG \
|
rlm@1
|
200 { \
|
rlm@1
|
201 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
202 value = v << shift; \
|
rlm@1
|
203 }
|
rlm@1
|
204 #define ARITHMETIC_LSR_REG \
|
rlm@1
|
205 { \
|
rlm@1
|
206 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
207 value = v >> shift; \
|
rlm@1
|
208 }
|
rlm@1
|
209 #define ARITHMETIC_ASR_REG \
|
rlm@1
|
210 { \
|
rlm@1
|
211 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
212 value = (s32)v >> (int)shift; \
|
rlm@1
|
213 }
|
rlm@1
|
214 #define ARITHMETIC_ROR_REG \
|
rlm@1
|
215 { \
|
rlm@1
|
216 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
217 value = ((v << (32 - shift)) | \
|
rlm@1
|
218 (v >> shift)); \
|
rlm@1
|
219 }
|
rlm@1
|
220 #define ARITHMETIC_RRX_REG \
|
rlm@1
|
221 { \
|
rlm@1
|
222 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
223 shift = (int)C_FLAG; \
|
rlm@1
|
224 value = ((v >> 1) | \
|
rlm@1
|
225 (shift << 31)); \
|
rlm@1
|
226 }
|
rlm@1
|
227 #define ARITHMETIC_ROR_IMM \
|
rlm@1
|
228 { \
|
rlm@1
|
229 u32 v = opcode & 0xff; \
|
rlm@1
|
230 value = ((v << (32 - shift)) | \
|
rlm@1
|
231 (v >> shift)); \
|
rlm@1
|
232 }
|
rlm@1
|
233 #define ROR_IMM_MSR \
|
rlm@1
|
234 { \
|
rlm@1
|
235 u32 v = opcode & 0xff; \
|
rlm@1
|
236 value = ((v << (32 - shift)) | \
|
rlm@1
|
237 (v >> shift)); \
|
rlm@1
|
238 }
|
rlm@1
|
239 #define ROR_VALUE \
|
rlm@1
|
240 { \
|
rlm@1
|
241 value = ((value << (32 - shift)) | \
|
rlm@1
|
242 (value >> shift)); \
|
rlm@1
|
243 }
|
rlm@1
|
244 #define RCR_VALUE \
|
rlm@1
|
245 { \
|
rlm@1
|
246 shift = (int)C_FLAG; \
|
rlm@1
|
247 value = ((value >> 1) | \
|
rlm@1
|
248 (shift << 31)); \
|
rlm@1
|
249 }
|
rlm@1
|
250 #else
|
rlm@1
|
251 #ifdef __GNUC__
|
rlm@1
|
252 #ifdef __POWERPC__
|
rlm@1
|
253 #define OP_SUB \
|
rlm@1
|
254 { \
|
rlm@1
|
255 reg[dest].I = reg[base].I - value; \
|
rlm@1
|
256 }
|
rlm@1
|
257 #define OP_SUBS \
|
rlm@1
|
258 { \
|
rlm@1
|
259 register int Flags; \
|
rlm@1
|
260 register int Result; \
|
rlm@1
|
261 asm volatile ("subco. %0, %2, %3\n" \
|
rlm@1
|
262 "mcrxr cr1\n" \
|
rlm@1
|
263 "mfcr %1\n" \
|
rlm@1
|
264 : "=r" (Result), \
|
rlm@1
|
265 "=r" (Flags) \
|
rlm@1
|
266 : "r" (reg[base].I), \
|
rlm@1
|
267 "r" (value) \
|
rlm@1
|
268 ); \
|
rlm@1
|
269 reg[dest].I = Result; \
|
rlm@1
|
270 Z_FLAG = (Flags >> 29) & 1; \
|
rlm@1
|
271 N_FLAG = (Flags >> 31) & 1; \
|
rlm@1
|
272 C_FLAG = (Flags >> 25) & 1; \
|
rlm@1
|
273 V_FLAG = (Flags >> 26) & 1; \
|
rlm@1
|
274 }
|
rlm@1
|
275 #define OP_RSB \
|
rlm@1
|
276 { \
|
rlm@1
|
277 reg[dest].I = value - reg[base].I; \
|
rlm@1
|
278 }
|
rlm@1
|
279 #define OP_RSBS \
|
rlm@1
|
280 { \
|
rlm@1
|
281 register int Flags; \
|
rlm@1
|
282 register int Result; \
|
rlm@1
|
283 asm volatile ("subfco. %0, %2, %3\n" \
|
rlm@1
|
284 "mcrxr cr1\n" \
|
rlm@1
|
285 "mfcr %1\n" \
|
rlm@1
|
286 : "=r" (Result), \
|
rlm@1
|
287 "=r" (Flags) \
|
rlm@1
|
288 : "r" (reg[base].I), \
|
rlm@1
|
289 "r" (value) \
|
rlm@1
|
290 ); \
|
rlm@1
|
291 reg[dest].I = Result; \
|
rlm@1
|
292 Z_FLAG = (Flags >> 29) & 1; \
|
rlm@1
|
293 N_FLAG = (Flags >> 31) & 1; \
|
rlm@1
|
294 C_FLAG = (Flags >> 25) & 1; \
|
rlm@1
|
295 V_FLAG = (Flags >> 26) & 1; \
|
rlm@1
|
296 }
|
rlm@1
|
297 #define OP_ADD \
|
rlm@1
|
298 { \
|
rlm@1
|
299 reg[dest].I = reg[base].I + value; \
|
rlm@1
|
300 }
|
rlm@1
|
301
|
rlm@1
|
302 #define OP_ADDS \
|
rlm@1
|
303 { \
|
rlm@1
|
304 register int Flags; \
|
rlm@1
|
305 register int Result; \
|
rlm@1
|
306 asm volatile ("addco. %0, %2, %3\n" \
|
rlm@1
|
307 "mcrxr cr1\n" \
|
rlm@1
|
308 "mfcr %1\n" \
|
rlm@1
|
309 : "=r" (Result), \
|
rlm@1
|
310 "=r" (Flags) \
|
rlm@1
|
311 : "r" (reg[base].I), \
|
rlm@1
|
312 "r" (value) \
|
rlm@1
|
313 ); \
|
rlm@1
|
314 reg[dest].I = Result; \
|
rlm@1
|
315 Z_FLAG = (Flags >> 29) & 1; \
|
rlm@1
|
316 N_FLAG = (Flags >> 31) & 1; \
|
rlm@1
|
317 C_FLAG = (Flags >> 25) & 1; \
|
rlm@1
|
318 V_FLAG = (Flags >> 26) & 1; \
|
rlm@1
|
319 }
|
rlm@1
|
320 #define OP_ADC \
|
rlm@1
|
321 { \
|
rlm@1
|
322 reg[dest].I = reg[base].I + value + (u32)C_FLAG; \
|
rlm@1
|
323 }
|
rlm@1
|
324 #define OP_ADCS \
|
rlm@1
|
325 { \
|
rlm@1
|
326 register int Flags; \
|
rlm@1
|
327 register int Result; \
|
rlm@1
|
328 asm volatile ("mtspr xer, %4\n" \
|
rlm@1
|
329 "addeo. %0, %2, %3\n" \
|
rlm@1
|
330 "mcrxr cr1\n" \
|
rlm@1
|
331 "mfcr %1\n" \
|
rlm@1
|
332 : "=r" (Result), \
|
rlm@1
|
333 "=r" (Flags) \
|
rlm@1
|
334 : "r" (reg[base].I), \
|
rlm@1
|
335 "r" (value), \
|
rlm@1
|
336 "r" (C_FLAG << 29) \
|
rlm@1
|
337 ); \
|
rlm@1
|
338 reg[dest].I = Result; \
|
rlm@1
|
339 Z_FLAG = (Flags >> 29) & 1; \
|
rlm@1
|
340 N_FLAG = (Flags >> 31) & 1; \
|
rlm@1
|
341 C_FLAG = (Flags >> 25) & 1; \
|
rlm@1
|
342 V_FLAG = (Flags >> 26) & 1; \
|
rlm@1
|
343 }
|
rlm@1
|
344 #define OP_SBC \
|
rlm@1
|
345 { \
|
rlm@1
|
346 reg[dest].I = reg[base].I - value - (C_FLAG ^ 1); \
|
rlm@1
|
347 }
|
rlm@1
|
348 #define OP_SBCS \
|
rlm@1
|
349 { \
|
rlm@1
|
350 register int Flags; \
|
rlm@1
|
351 register int Result; \
|
rlm@1
|
352 asm volatile ("mtspr xer, %4\n" \
|
rlm@1
|
353 "subfeo. %0, %3, %2\n" \
|
rlm@1
|
354 "mcrxr cr1\n" \
|
rlm@1
|
355 "mfcr %1\n" \
|
rlm@1
|
356 : "=r" (Result), \
|
rlm@1
|
357 "=r" (Flags) \
|
rlm@1
|
358 : "r" (reg[base].I), \
|
rlm@1
|
359 "r" (value), \
|
rlm@1
|
360 "r" (C_FLAG << 29) \
|
rlm@1
|
361 ); \
|
rlm@1
|
362 reg[dest].I = Result; \
|
rlm@1
|
363 Z_FLAG = (Flags >> 29) & 1; \
|
rlm@1
|
364 N_FLAG = (Flags >> 31) & 1; \
|
rlm@1
|
365 C_FLAG = (Flags >> 25) & 1; \
|
rlm@1
|
366 V_FLAG = (Flags >> 26) & 1; \
|
rlm@1
|
367 }
|
rlm@1
|
368 #define OP_RSC \
|
rlm@1
|
369 { \
|
rlm@1
|
370 reg[dest].I = value - reg[base].I - (C_FLAG ^ 1); \
|
rlm@1
|
371 }
|
rlm@1
|
372 #define OP_RSCS \
|
rlm@1
|
373 { \
|
rlm@1
|
374 register int Flags; \
|
rlm@1
|
375 register int Result; \
|
rlm@1
|
376 asm volatile ("mtspr xer, %4\n" \
|
rlm@1
|
377 "subfeo. %0, %2, %3\n" \
|
rlm@1
|
378 "mcrxr cr1\n" \
|
rlm@1
|
379 "mfcr %1\n" \
|
rlm@1
|
380 : "=r" (Result), \
|
rlm@1
|
381 "=r" (Flags) \
|
rlm@1
|
382 : "r" (reg[base].I), \
|
rlm@1
|
383 "r" (value), \
|
rlm@1
|
384 "r" (C_FLAG << 29) \
|
rlm@1
|
385 ); \
|
rlm@1
|
386 reg[dest].I = Result; \
|
rlm@1
|
387 Z_FLAG = (Flags >> 29) & 1; \
|
rlm@1
|
388 N_FLAG = (Flags >> 31) & 1; \
|
rlm@1
|
389 C_FLAG = (Flags >> 25) & 1; \
|
rlm@1
|
390 V_FLAG = (Flags >> 26) & 1; \
|
rlm@1
|
391 }
|
rlm@1
|
392 #define OP_CMP \
|
rlm@1
|
393 { \
|
rlm@1
|
394 register int Flags; \
|
rlm@1
|
395 register int Result; \
|
rlm@1
|
396 asm volatile ("subco. %0, %2, %3\n" \
|
rlm@1
|
397 "mcrxr cr1\n" \
|
rlm@1
|
398 "mfcr %1\n" \
|
rlm@1
|
399 : "=r" (Result), \
|
rlm@1
|
400 "=r" (Flags) \
|
rlm@1
|
401 : "r" (reg[base].I), \
|
rlm@1
|
402 "r" (value) \
|
rlm@1
|
403 ); \
|
rlm@1
|
404 Z_FLAG = (Flags >> 29) & 1; \
|
rlm@1
|
405 N_FLAG = (Flags >> 31) & 1; \
|
rlm@1
|
406 C_FLAG = (Flags >> 25) & 1; \
|
rlm@1
|
407 V_FLAG = (Flags >> 26) & 1; \
|
rlm@1
|
408 }
|
rlm@1
|
409 #define OP_CMN \
|
rlm@1
|
410 { \
|
rlm@1
|
411 register int Flags; \
|
rlm@1
|
412 register int Result; \
|
rlm@1
|
413 asm volatile ("addco. %0, %2, %3\n" \
|
rlm@1
|
414 "mcrxr cr1\n" \
|
rlm@1
|
415 "mfcr %1\n" \
|
rlm@1
|
416 : "=r" (Result), \
|
rlm@1
|
417 "=r" (Flags) \
|
rlm@1
|
418 : "r" (reg[base].I), \
|
rlm@1
|
419 "r" (value) \
|
rlm@1
|
420 ); \
|
rlm@1
|
421 Z_FLAG = (Flags >> 29) & 1; \
|
rlm@1
|
422 N_FLAG = (Flags >> 31) & 1; \
|
rlm@1
|
423 C_FLAG = (Flags >> 25) & 1; \
|
rlm@1
|
424 V_FLAG = (Flags >> 26) & 1; \
|
rlm@1
|
425 }
|
rlm@1
|
426
|
rlm@1
|
427 #define LOGICAL_LSL_REG \
|
rlm@1
|
428 { \
|
rlm@1
|
429 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
430 C_OUT = (v >> (32 - shift)) & 1 ? true : false; \
|
rlm@1
|
431 value = v << shift; \
|
rlm@1
|
432 }
|
rlm@1
|
433 #define LOGICAL_LSR_REG \
|
rlm@1
|
434 { \
|
rlm@1
|
435 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
436 C_OUT = (v >> (shift - 1)) & 1 ? true : false; \
|
rlm@1
|
437 value = v >> shift; \
|
rlm@1
|
438 }
|
rlm@1
|
439 #define LOGICAL_ASR_REG \
|
rlm@1
|
440 { \
|
rlm@1
|
441 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
442 C_OUT = ((s32)v >> (int)(shift - 1)) & 1 ? true : false; \
|
rlm@1
|
443 value = (s32)v >> (int)shift; \
|
rlm@1
|
444 }
|
rlm@1
|
445 #define LOGICAL_ROR_REG \
|
rlm@1
|
446 { \
|
rlm@1
|
447 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
448 C_OUT = (v >> (shift - 1)) & 1 ? true : false; \
|
rlm@1
|
449 value = ((v << (32 - shift)) | \
|
rlm@1
|
450 (v >> shift)); \
|
rlm@1
|
451 }
|
rlm@1
|
452 #define LOGICAL_RRX_REG \
|
rlm@1
|
453 { \
|
rlm@1
|
454 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
455 shift = (int)C_FLAG; \
|
rlm@1
|
456 C_OUT = (v & 1) ? true : false; \
|
rlm@1
|
457 value = ((v >> 1) | \
|
rlm@1
|
458 (shift << 31)); \
|
rlm@1
|
459 }
|
rlm@1
|
460 #define LOGICAL_ROR_IMM \
|
rlm@1
|
461 { \
|
rlm@1
|
462 u32 v = opcode & 0xff; \
|
rlm@1
|
463 C_OUT = (v >> (shift - 1)) & 1 ? true : false; \
|
rlm@1
|
464 value = ((v << (32 - shift)) | \
|
rlm@1
|
465 (v >> shift)); \
|
rlm@1
|
466 }
|
rlm@1
|
467 #define ARITHMETIC_LSL_REG \
|
rlm@1
|
468 { \
|
rlm@1
|
469 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
470 value = v << shift; \
|
rlm@1
|
471 }
|
rlm@1
|
472 #define ARITHMETIC_LSR_REG \
|
rlm@1
|
473 { \
|
rlm@1
|
474 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
475 value = v >> shift; \
|
rlm@1
|
476 }
|
rlm@1
|
477 #define ARITHMETIC_ASR_REG \
|
rlm@1
|
478 { \
|
rlm@1
|
479 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
480 value = (s32)v >> (int)shift; \
|
rlm@1
|
481 }
|
rlm@1
|
482 #define ARITHMETIC_ROR_REG \
|
rlm@1
|
483 { \
|
rlm@1
|
484 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
485 value = ((v << (32 - shift)) | \
|
rlm@1
|
486 (v >> shift)); \
|
rlm@1
|
487 }
|
rlm@1
|
488 #define ARITHMETIC_RRX_REG \
|
rlm@1
|
489 { \
|
rlm@1
|
490 u32 v = reg[opcode & 0x0f].I; \
|
rlm@1
|
491 shift = (int)C_FLAG; \
|
rlm@1
|
492 value = ((v >> 1) | \
|
rlm@1
|
493 (shift << 31)); \
|
rlm@1
|
494 }
|
rlm@1
|
495 #define ARITHMETIC_ROR_IMM \
|
rlm@1
|
496 { \
|
rlm@1
|
497 u32 v = opcode & 0xff; \
|
rlm@1
|
498 value = ((v << (32 - shift)) | \
|
rlm@1
|
499 (v >> shift)); \
|
rlm@1
|
500 }
|
rlm@1
|
501 #define ROR_IMM_MSR \
|
rlm@1
|
502 { \
|
rlm@1
|
503 u32 v = opcode & 0xff; \
|
rlm@1
|
504 value = ((v << (32 - shift)) | \
|
rlm@1
|
505 (v >> shift)); \
|
rlm@1
|
506 }
|
rlm@1
|
507 #define ROR_VALUE \
|
rlm@1
|
508 { \
|
rlm@1
|
509 value = ((value << (32 - shift)) | \
|
rlm@1
|
510 (value >> shift)); \
|
rlm@1
|
511 }
|
rlm@1
|
512 #define RCR_VALUE \
|
rlm@1
|
513 { \
|
rlm@1
|
514 shift = (int)C_FLAG; \
|
rlm@1
|
515 value = ((value >> 1) | \
|
rlm@1
|
516 (shift << 31)); \
|
rlm@1
|
517 }
|
rlm@1
|
518 #else
|
rlm@1
|
519 #define OP_SUB \
|
rlm@1
|
520 asm ("sub %1, %%ebx;" \
|
rlm@1
|
521 : "=b" (reg[dest].I) \
|
rlm@1
|
522 : "r" (value), "b" (reg[base].I));
|
rlm@1
|
523
|
rlm@1
|
524 #define OP_SUBS \
|
rlm@1
|
525 asm ("sub %1, %%ebx;" \
|
rlm@1
|
526 "setsb N_FLAG;" \
|
rlm@1
|
527 "setzb Z_FLAG;" \
|
rlm@1
|
528 "setncb C_FLAG;" \
|
rlm@1
|
529 "setob V_FLAG;" \
|
rlm@1
|
530 : "=b" (reg[dest].I) \
|
rlm@1
|
531 : "r" (value), "b" (reg[base].I));
|
rlm@1
|
532
|
rlm@1
|
533 #define OP_RSB \
|
rlm@1
|
534 asm ("sub %1, %%ebx;" \
|
rlm@1
|
535 : "=b" (reg[dest].I) \
|
rlm@1
|
536 : "r" (reg[base].I), "b" (value));
|
rlm@1
|
537
|
rlm@1
|
538 #define OP_RSBS \
|
rlm@1
|
539 asm ("sub %1, %%ebx;" \
|
rlm@1
|
540 "setsb N_FLAG;" \
|
rlm@1
|
541 "setzb Z_FLAG;" \
|
rlm@1
|
542 "setncb C_FLAG;" \
|
rlm@1
|
543 "setob V_FLAG;" \
|
rlm@1
|
544 : "=b" (reg[dest].I) \
|
rlm@1
|
545 : "r" (reg[base].I), "b" (value));
|
rlm@1
|
546
|
rlm@1
|
547 #define OP_ADD \
|
rlm@1
|
548 asm ("add %1, %%ebx;" \
|
rlm@1
|
549 : "=b" (reg[dest].I) \
|
rlm@1
|
550 : "r" (value), "b" (reg[base].I));
|
rlm@1
|
551
|
rlm@1
|
552 #define OP_ADDS \
|
rlm@1
|
553 asm ("add %1, %%ebx;" \
|
rlm@1
|
554 "setsb N_FLAG;" \
|
rlm@1
|
555 "setzb Z_FLAG;" \
|
rlm@1
|
556 "setcb C_FLAG;" \
|
rlm@1
|
557 "setob V_FLAG;" \
|
rlm@1
|
558 : "=b" (reg[dest].I) \
|
rlm@1
|
559 : "r" (value), "b" (reg[base].I));
|
rlm@1
|
560
|
rlm@1
|
561 #define OP_ADC \
|
rlm@1
|
562 asm ("bt $0, C_FLAG;" \
|
rlm@1
|
563 "adc %1, %%ebx;" \
|
rlm@1
|
564 : "=b" (reg[dest].I) \
|
rlm@1
|
565 : "r" (value), "b" (reg[base].I));
|
rlm@1
|
566
|
rlm@1
|
567 #define OP_ADCS \
|
rlm@1
|
568 asm ("bt $0, C_FLAG;" \
|
rlm@1
|
569 "adc %1, %%ebx;" \
|
rlm@1
|
570 "setsb N_FLAG;" \
|
rlm@1
|
571 "setzb Z_FLAG;" \
|
rlm@1
|
572 "setcb C_FLAG;" \
|
rlm@1
|
573 "setob V_FLAG;" \
|
rlm@1
|
574 : "=b" (reg[dest].I) \
|
rlm@1
|
575 : "r" (value), "b" (reg[base].I));
|
rlm@1
|
576
|
rlm@1
|
577 #define OP_SBC \
|
rlm@1
|
578 asm ("bt $0, C_FLAG;" \
|
rlm@1
|
579 "cmc;" \
|
rlm@1
|
580 "sbb %1, %%ebx;" \
|
rlm@1
|
581 : "=b" (reg[dest].I) \
|
rlm@1
|
582 : "r" (value), "b" (reg[base].I));
|
rlm@1
|
583
|
rlm@1
|
584 #define OP_SBCS \
|
rlm@1
|
585 asm ("bt $0, C_FLAG;" \
|
rlm@1
|
586 "cmc;" \
|
rlm@1
|
587 "sbb %1, %%ebx;" \
|
rlm@1
|
588 "setsb N_FLAG;" \
|
rlm@1
|
589 "setzb Z_FLAG;" \
|
rlm@1
|
590 "setncb C_FLAG;" \
|
rlm@1
|
591 "setob V_FLAG;" \
|
rlm@1
|
592 : "=b" (reg[dest].I) \
|
rlm@1
|
593 : "r" (value), "b" (reg[base].I));
|
rlm@1
|
594 #define OP_RSC \
|
rlm@1
|
595 asm ("bt $0, C_FLAG;" \
|
rlm@1
|
596 "cmc;" \
|
rlm@1
|
597 "sbb %1, %%ebx;" \
|
rlm@1
|
598 : "=b" (reg[dest].I) \
|
rlm@1
|
599 : "r" (reg[base].I), "b" (value));
|
rlm@1
|
600
|
rlm@1
|
601 #define OP_RSCS \
|
rlm@1
|
602 asm ("bt $0, C_FLAG;" \
|
rlm@1
|
603 "cmc;" \
|
rlm@1
|
604 "sbb %1, %%ebx;" \
|
rlm@1
|
605 "setsb N_FLAG;" \
|
rlm@1
|
606 "setzb Z_FLAG;" \
|
rlm@1
|
607 "setncb C_FLAG;" \
|
rlm@1
|
608 "setob V_FLAG;" \
|
rlm@1
|
609 : "=b" (reg[dest].I) \
|
rlm@1
|
610 : "r" (reg[base].I), "b" (value));
|
rlm@1
|
611 #define OP_CMP \
|
rlm@1
|
612 asm ("sub %0, %1;" \
|
rlm@1
|
613 "setsb N_FLAG;" \
|
rlm@1
|
614 "setzb Z_FLAG;" \
|
rlm@1
|
615 "setncb C_FLAG;" \
|
rlm@1
|
616 "setob V_FLAG;" \
|
rlm@1
|
617 : \
|
rlm@1
|
618 : "r" (value), "r" (reg[base].I));
|
rlm@1
|
619
|
rlm@1
|
620 #define OP_CMN \
|
rlm@1
|
621 asm ("add %0, %1;" \
|
rlm@1
|
622 "setsb N_FLAG;" \
|
rlm@1
|
623 "setzb Z_FLAG;" \
|
rlm@1
|
624 "setcb C_FLAG;" \
|
rlm@1
|
625 "setob V_FLAG;" \
|
rlm@1
|
626 : \
|
rlm@1
|
627 : "r" (value), "r" (reg[base].I));
|
rlm@1
|
628 #define LOGICAL_LSL_REG \
|
rlm@1
|
629 asm ("shl %%cl, %%eax;" \
|
rlm@1
|
630 "setcb %%cl;" \
|
rlm@1
|
631 : "=a" (value), "=c" (C_OUT) \
|
rlm@1
|
632 : "a" (reg[opcode & 0x0f].I), "c" (shift));
|
rlm@1
|
633
|
rlm@1
|
634 #define LOGICAL_LSR_REG \
|
rlm@1
|
635 asm ("shr %%cl, %%eax;" \
|
rlm@1
|
636 "setcb %%cl;" \
|
rlm@1
|
637 : "=a" (value), "=c" (C_OUT) \
|
rlm@1
|
638 : "a" (reg[opcode & 0x0f].I), "c" (shift));
|
rlm@1
|
639
|
rlm@1
|
640 #define LOGICAL_ASR_REG \
|
rlm@1
|
641 asm ("sar %%cl, %%eax;" \
|
rlm@1
|
642 "setcb %%cl;" \
|
rlm@1
|
643 : "=a" (value), "=c" (C_OUT) \
|
rlm@1
|
644 : "a" (reg[opcode & 0x0f].I), "c" (shift));
|
rlm@1
|
645
|
rlm@1
|
646 #define LOGICAL_ROR_REG \
|
rlm@1
|
647 asm ("ror %%cl, %%eax;" \
|
rlm@1
|
648 "setcb %%cl;" \
|
rlm@1
|
649 : "=a" (value), "=c" (C_OUT) \
|
rlm@1
|
650 : "a" (reg[opcode & 0x0f].I), "c" (shift));
|
rlm@1
|
651
|
rlm@1
|
652 #define LOGICAL_RRX_REG \
|
rlm@1
|
653 asm ("bt $0, C_FLAG;" \
|
rlm@1
|
654 "rcr $1, %%eax;" \
|
rlm@1
|
655 "setcb %%cl;" \
|
rlm@1
|
656 : "=a" (value), "=c" (C_OUT) \
|
rlm@1
|
657 : "a" (reg[opcode & 0x0f].I));
|
rlm@1
|
658
|
rlm@1
|
659 #define LOGICAL_ROR_IMM \
|
rlm@1
|
660 asm ("ror %%cl, %%eax;" \
|
rlm@1
|
661 "setcb %%cl;" \
|
rlm@1
|
662 : "=a" (value), "=c" (C_OUT) \
|
rlm@1
|
663 : "a" (opcode & 0xff), "c" (shift));
|
rlm@1
|
664 #define ARITHMETIC_LSL_REG \
|
rlm@1
|
665 asm ("\
|
rlm@1
|
666 shl %%cl, %%eax;" \
|
rlm@1
|
667 : "=a" (value) \
|
rlm@1
|
668 : "a" (reg[opcode & 0x0f].I), "c" (shift));
|
rlm@1
|
669
|
rlm@1
|
670 #define ARITHMETIC_LSR_REG \
|
rlm@1
|
671 asm ("\
|
rlm@1
|
672 shr %%cl, %%eax;" \
|
rlm@1
|
673 : "=a" (value) \
|
rlm@1
|
674 : "a" (reg[opcode & 0x0f].I), "c" (shift));
|
rlm@1
|
675
|
rlm@1
|
676 #define ARITHMETIC_ASR_REG \
|
rlm@1
|
677 asm ("\
|
rlm@1
|
678 sar %%cl, %%eax;" \
|
rlm@1
|
679 : "=a" (value) \
|
rlm@1
|
680 : "a" (reg[opcode & 0x0f].I), "c" (shift));
|
rlm@1
|
681
|
rlm@1
|
682 #define ARITHMETIC_ROR_REG \
|
rlm@1
|
683 asm ("\
|
rlm@1
|
684 ror %%cl, %%eax;" \
|
rlm@1
|
685 : "=a" (value) \
|
rlm@1
|
686 : "a" (reg[opcode & 0x0f].I), "c" (shift));
|
rlm@1
|
687
|
rlm@1
|
688 #define ARITHMETIC_RRX_REG \
|
rlm@1
|
689 asm ("\
|
rlm@1
|
690 bt $0, C_FLAG;\
|
rlm@1
|
691 rcr $1, %%eax;" \
|
rlm@1
|
692 : "=a" (value) \
|
rlm@1
|
693 : "a" (reg[opcode & 0x0f].I));
|
rlm@1
|
694
|
rlm@1
|
695 #define ARITHMETIC_ROR_IMM \
|
rlm@1
|
696 asm ("\
|
rlm@1
|
697 ror %%cl, %%eax;" \
|
rlm@1
|
698 : "=a" (value) \
|
rlm@1
|
699 : "a" (opcode & 0xff), "c" (shift));
|
rlm@1
|
700 #define ROR_IMM_MSR \
|
rlm@1
|
701 asm ("ror %%cl, %%eax;" \
|
rlm@1
|
702 : "=a" (value) \
|
rlm@1
|
703 : "a" (opcode & 0xFF), "c" (shift));
|
rlm@1
|
704 #define ROR_VALUE \
|
rlm@1
|
705 asm ("ror %%cl, %0" \
|
rlm@1
|
706 : "=r" (value) \
|
rlm@1
|
707 : "r" (value), "c" (shift));
|
rlm@1
|
708 #define RCR_VALUE \
|
rlm@1
|
709 asm ("bt $0, C_FLAG;" \
|
rlm@1
|
710 "rcr $1, %0" \
|
rlm@1
|
711 : "=r" (value) \
|
rlm@1
|
712 : "r" (value));
|
rlm@1
|
713 #endif
|
rlm@1
|
714 #else
|
rlm@1
|
715 #define OP_SUB \
|
rlm@1
|
716 { \
|
rlm@1
|
717 __asm mov ebx, base \
|
rlm@1
|
718 __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \
|
rlm@1
|
719 __asm sub ebx, value \
|
rlm@1
|
720 __asm mov eax, dest \
|
rlm@1
|
721 __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \
|
rlm@1
|
722 }
|
rlm@1
|
723
|
rlm@1
|
724 #define OP_SUBS \
|
rlm@1
|
725 { \
|
rlm@1
|
726 __asm mov ebx, base \
|
rlm@1
|
727 __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \
|
rlm@1
|
728 __asm sub ebx, value \
|
rlm@1
|
729 __asm mov eax, dest \
|
rlm@1
|
730 __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \
|
rlm@1
|
731 __asm sets byte ptr N_FLAG \
|
rlm@1
|
732 __asm setz byte ptr Z_FLAG \
|
rlm@1
|
733 __asm setnc byte ptr C_FLAG \
|
rlm@1
|
734 __asm seto byte ptr V_FLAG \
|
rlm@1
|
735 }
|
rlm@1
|
736
|
rlm@1
|
737 #define OP_RSB \
|
rlm@1
|
738 { \
|
rlm@1
|
739 __asm mov ebx, base \
|
rlm@1
|
740 __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \
|
rlm@1
|
741 __asm mov eax, value \
|
rlm@1
|
742 __asm sub eax, ebx \
|
rlm@1
|
743 __asm mov ebx, dest \
|
rlm@1
|
744 __asm mov dword ptr [OFFSET reg + 4 * ebx], eax \
|
rlm@1
|
745 }
|
rlm@1
|
746
|
rlm@1
|
747 #define OP_RSBS \
|
rlm@1
|
748 { \
|
rlm@1
|
749 __asm mov ebx, base \
|
rlm@1
|
750 __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \
|
rlm@1
|
751 __asm mov eax, value \
|
rlm@1
|
752 __asm sub eax, ebx \
|
rlm@1
|
753 __asm mov ebx, dest \
|
rlm@1
|
754 __asm mov dword ptr [OFFSET reg + 4 * ebx], eax \
|
rlm@1
|
755 __asm sets byte ptr N_FLAG \
|
rlm@1
|
756 __asm setz byte ptr Z_FLAG \
|
rlm@1
|
757 __asm setnc byte ptr C_FLAG \
|
rlm@1
|
758 __asm seto byte ptr V_FLAG \
|
rlm@1
|
759 }
|
rlm@1
|
760
|
rlm@1
|
761 #define OP_ADD \
|
rlm@1
|
762 { \
|
rlm@1
|
763 __asm mov ebx, base \
|
rlm@1
|
764 __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \
|
rlm@1
|
765 __asm add ebx, value \
|
rlm@1
|
766 __asm mov eax, dest \
|
rlm@1
|
767 __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \
|
rlm@1
|
768 }
|
rlm@1
|
769
|
rlm@1
|
770 #define OP_ADDS \
|
rlm@1
|
771 { \
|
rlm@1
|
772 __asm mov ebx, base \
|
rlm@1
|
773 __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \
|
rlm@1
|
774 __asm add ebx, value \
|
rlm@1
|
775 __asm mov eax, dest \
|
rlm@1
|
776 __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \
|
rlm@1
|
777 __asm sets byte ptr N_FLAG \
|
rlm@1
|
778 __asm setz byte ptr Z_FLAG \
|
rlm@1
|
779 __asm setc byte ptr C_FLAG \
|
rlm@1
|
780 __asm seto byte ptr V_FLAG \
|
rlm@1
|
781 }
|
rlm@1
|
782
|
rlm@1
|
783 #define OP_ADC \
|
rlm@1
|
784 { \
|
rlm@1
|
785 __asm mov ebx, base \
|
rlm@1
|
786 __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \
|
rlm@1
|
787 __asm bt word ptr C_FLAG, 0 \
|
rlm@1
|
788 __asm adc ebx, value \
|
rlm@1
|
789 __asm mov eax, dest \
|
rlm@1
|
790 __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \
|
rlm@1
|
791 }
|
rlm@1
|
792
|
rlm@1
|
793 #define OP_ADCS \
|
rlm@1
|
794 { \
|
rlm@1
|
795 __asm mov ebx, base \
|
rlm@1
|
796 __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \
|
rlm@1
|
797 __asm bt word ptr C_FLAG, 0 \
|
rlm@1
|
798 __asm adc ebx, value \
|
rlm@1
|
799 __asm mov eax, dest \
|
rlm@1
|
800 __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \
|
rlm@1
|
801 __asm sets byte ptr N_FLAG \
|
rlm@1
|
802 __asm setz byte ptr Z_FLAG \
|
rlm@1
|
803 __asm setc byte ptr C_FLAG \
|
rlm@1
|
804 __asm seto byte ptr V_FLAG \
|
rlm@1
|
805 }
|
rlm@1
|
806
|
rlm@1
|
807 #define OP_SBC \
|
rlm@1
|
808 { \
|
rlm@1
|
809 __asm mov ebx, base \
|
rlm@1
|
810 __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \
|
rlm@1
|
811 __asm mov eax, value \
|
rlm@1
|
812 __asm bt word ptr C_FLAG, 0 \
|
rlm@1
|
813 __asm cmc \
|
rlm@1
|
814 __asm sbb ebx, eax \
|
rlm@1
|
815 __asm mov eax, dest \
|
rlm@1
|
816 __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \
|
rlm@1
|
817 }
|
rlm@1
|
818
|
rlm@1
|
819 #define OP_SBCS \
|
rlm@1
|
820 { \
|
rlm@1
|
821 __asm mov ebx, base \
|
rlm@1
|
822 __asm mov ebx, dword ptr [OFFSET reg + 4 * ebx] \
|
rlm@1
|
823 __asm mov eax, value \
|
rlm@1
|
824 __asm bt word ptr C_FLAG, 0 \
|
rlm@1
|
825 __asm cmc \
|
rlm@1
|
826 __asm sbb ebx, eax \
|
rlm@1
|
827 __asm mov eax, dest \
|
rlm@1
|
828 __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \
|
rlm@1
|
829 __asm sets byte ptr N_FLAG \
|
rlm@1
|
830 __asm setz byte ptr Z_FLAG \
|
rlm@1
|
831 __asm setnc byte ptr C_FLAG \
|
rlm@1
|
832 __asm seto byte ptr V_FLAG \
|
rlm@1
|
833 }
|
rlm@1
|
834 #define OP_RSC \
|
rlm@1
|
835 { \
|
rlm@1
|
836 __asm mov ebx, value \
|
rlm@1
|
837 __asm mov eax, base \
|
rlm@1
|
838 __asm mov eax, dword ptr[OFFSET reg + 4 * eax] \
|
rlm@1
|
839 __asm bt word ptr C_FLAG, 0 \
|
rlm@1
|
840 __asm cmc \
|
rlm@1
|
841 __asm sbb ebx, eax \
|
rlm@1
|
842 __asm mov eax, dest \
|
rlm@1
|
843 __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \
|
rlm@1
|
844 }
|
rlm@1
|
845
|
rlm@1
|
846 #define OP_RSCS \
|
rlm@1
|
847 { \
|
rlm@1
|
848 __asm mov ebx, value \
|
rlm@1
|
849 __asm mov eax, base \
|
rlm@1
|
850 __asm mov eax, dword ptr[OFFSET reg + 4 * eax] \
|
rlm@1
|
851 __asm bt word ptr C_FLAG, 0 \
|
rlm@1
|
852 __asm cmc \
|
rlm@1
|
853 __asm sbb ebx, eax \
|
rlm@1
|
854 __asm mov eax, dest \
|
rlm@1
|
855 __asm mov dword ptr [OFFSET reg + 4 * eax], ebx \
|
rlm@1
|
856 __asm sets byte ptr N_FLAG \
|
rlm@1
|
857 __asm setz byte ptr Z_FLAG \
|
rlm@1
|
858 __asm setnc byte ptr C_FLAG \
|
rlm@1
|
859 __asm seto byte ptr V_FLAG \
|
rlm@1
|
860 }
|
rlm@1
|
861 #define OP_CMP \
|
rlm@1
|
862 { \
|
rlm@1
|
863 __asm mov eax, base \
|
rlm@1
|
864 __asm mov ebx, dword ptr [OFFSET reg + 4 * eax] \
|
rlm@1
|
865 __asm sub ebx, value \
|
rlm@1
|
866 __asm sets byte ptr N_FLAG \
|
rlm@1
|
867 __asm setz byte ptr Z_FLAG \
|
rlm@1
|
868 __asm setnc byte ptr C_FLAG \
|
rlm@1
|
869 __asm seto byte ptr V_FLAG \
|
rlm@1
|
870 }
|
rlm@1
|
871
|
rlm@1
|
872 #define OP_CMN \
|
rlm@1
|
873 { \
|
rlm@1
|
874 __asm mov eax, base \
|
rlm@1
|
875 __asm mov ebx, dword ptr [OFFSET reg + 4 * eax] \
|
rlm@1
|
876 __asm add ebx, value \
|
rlm@1
|
877 __asm sets byte ptr N_FLAG \
|
rlm@1
|
878 __asm setz byte ptr Z_FLAG \
|
rlm@1
|
879 __asm setc byte ptr C_FLAG \
|
rlm@1
|
880 __asm seto byte ptr V_FLAG \
|
rlm@1
|
881 }
|
rlm@1
|
882 #define LOGICAL_LSL_REG \
|
rlm@1
|
883 __asm mov eax, opcode \
|
rlm@1
|
884 __asm and eax, 0x0f \
|
rlm@1
|
885 __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \
|
rlm@1
|
886 __asm mov cl, byte ptr shift \
|
rlm@1
|
887 __asm shl eax, cl \
|
rlm@1
|
888 __asm mov value, eax \
|
rlm@1
|
889 __asm setc byte ptr C_OUT
|
rlm@1
|
890
|
rlm@1
|
891 #define LOGICAL_LSR_REG \
|
rlm@1
|
892 __asm mov eax, opcode \
|
rlm@1
|
893 __asm and eax, 0x0f \
|
rlm@1
|
894 __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \
|
rlm@1
|
895 __asm mov cl, byte ptr shift \
|
rlm@1
|
896 __asm shr eax, cl \
|
rlm@1
|
897 __asm mov value, eax \
|
rlm@1
|
898 __asm setc byte ptr C_OUT
|
rlm@1
|
899
|
rlm@1
|
900 #define LOGICAL_ASR_REG \
|
rlm@1
|
901 __asm mov eax, opcode \
|
rlm@1
|
902 __asm and eax, 0x0f \
|
rlm@1
|
903 __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \
|
rlm@1
|
904 __asm mov cl, byte ptr shift \
|
rlm@1
|
905 __asm sar eax, cl \
|
rlm@1
|
906 __asm mov value, eax \
|
rlm@1
|
907 __asm setc byte ptr C_OUT
|
rlm@1
|
908
|
rlm@1
|
909 #define LOGICAL_ROR_REG \
|
rlm@1
|
910 __asm mov eax, opcode \
|
rlm@1
|
911 __asm and eax, 0x0F \
|
rlm@1
|
912 __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \
|
rlm@1
|
913 __asm mov cl, byte ptr shift \
|
rlm@1
|
914 __asm ror eax, cl \
|
rlm@1
|
915 __asm mov value, eax \
|
rlm@1
|
916 __asm setc byte ptr C_OUT
|
rlm@1
|
917
|
rlm@1
|
918 #define LOGICAL_RRX_REG \
|
rlm@1
|
919 __asm mov eax, opcode \
|
rlm@1
|
920 __asm and eax, 0x0F \
|
rlm@1
|
921 __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \
|
rlm@1
|
922 __asm bt word ptr C_OUT, 0 \
|
rlm@1
|
923 __asm rcr eax, 1 \
|
rlm@1
|
924 __asm mov value, eax \
|
rlm@1
|
925 __asm setc byte ptr C_OUT
|
rlm@1
|
926
|
rlm@1
|
927 #define LOGICAL_ROR_IMM \
|
rlm@1
|
928 __asm mov eax, opcode \
|
rlm@1
|
929 __asm and eax, 0xff \
|
rlm@1
|
930 __asm mov cl, byte ptr shift \
|
rlm@1
|
931 __asm ror eax, cl \
|
rlm@1
|
932 __asm mov value, eax \
|
rlm@1
|
933 __asm setc byte ptr C_OUT
|
rlm@1
|
934 #define ARITHMETIC_LSL_REG \
|
rlm@1
|
935 __asm mov eax, opcode \
|
rlm@1
|
936 __asm and eax, 0x0f \
|
rlm@1
|
937 __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \
|
rlm@1
|
938 __asm mov cl, byte ptr shift \
|
rlm@1
|
939 __asm shl eax, cl \
|
rlm@1
|
940 __asm mov value, eax
|
rlm@1
|
941
|
rlm@1
|
942 #define ARITHMETIC_LSR_REG \
|
rlm@1
|
943 __asm mov eax, opcode \
|
rlm@1
|
944 __asm and eax, 0x0f \
|
rlm@1
|
945 __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \
|
rlm@1
|
946 __asm mov cl, byte ptr shift \
|
rlm@1
|
947 __asm shr eax, cl \
|
rlm@1
|
948 __asm mov value, eax
|
rlm@1
|
949
|
rlm@1
|
950 #define ARITHMETIC_ASR_REG \
|
rlm@1
|
951 __asm mov eax, opcode \
|
rlm@1
|
952 __asm and eax, 0x0f \
|
rlm@1
|
953 __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \
|
rlm@1
|
954 __asm mov cl, byte ptr shift \
|
rlm@1
|
955 __asm sar eax, cl \
|
rlm@1
|
956 __asm mov value, eax
|
rlm@1
|
957
|
rlm@1
|
958 #define ARITHMETIC_ROR_REG \
|
rlm@1
|
959 __asm mov eax, opcode \
|
rlm@1
|
960 __asm and eax, 0x0F \
|
rlm@1
|
961 __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \
|
rlm@1
|
962 __asm mov cl, byte ptr shift \
|
rlm@1
|
963 __asm ror eax, cl \
|
rlm@1
|
964 __asm mov value, eax
|
rlm@1
|
965
|
rlm@1
|
966 #define ARITHMETIC_RRX_REG \
|
rlm@1
|
967 __asm mov eax, opcode \
|
rlm@1
|
968 __asm and eax, 0x0F \
|
rlm@1
|
969 __asm mov eax, dword ptr [OFFSET reg + 4 * eax] \
|
rlm@1
|
970 __asm bt word ptr C_FLAG, 0 \
|
rlm@1
|
971 __asm rcr eax, 1 \
|
rlm@1
|
972 __asm mov value, eax
|
rlm@1
|
973
|
rlm@1
|
974 #define ARITHMETIC_ROR_IMM \
|
rlm@1
|
975 __asm mov eax, opcode \
|
rlm@1
|
976 __asm and eax, 0xff \
|
rlm@1
|
977 __asm mov cl, byte ptr shift \
|
rlm@1
|
978 __asm ror eax, cl \
|
rlm@1
|
979 __asm mov value, eax
|
rlm@1
|
980 #define ROR_IMM_MSR \
|
rlm@1
|
981 { \
|
rlm@1
|
982 __asm mov eax, opcode \
|
rlm@1
|
983 __asm and eax, 0xff \
|
rlm@1
|
984 __asm mov cl, byte ptr shift \
|
rlm@1
|
985 __asm ror eax, CL \
|
rlm@1
|
986 __asm mov value, eax \
|
rlm@1
|
987 }
|
rlm@1
|
988 #define ROR_VALUE \
|
rlm@1
|
989 { \
|
rlm@1
|
990 __asm mov cl, byte ptr shift \
|
rlm@1
|
991 __asm ror dword ptr value, cl \
|
rlm@1
|
992 }
|
rlm@1
|
993 #define RCR_VALUE \
|
rlm@1
|
994 { \
|
rlm@1
|
995 __asm mov cl, byte ptr shift \
|
rlm@1
|
996 __asm bt word ptr C_FLAG, 0 \
|
rlm@1
|
997 __asm rcr dword ptr value, 1 \
|
rlm@1
|
998 }
|
rlm@1
|
999 #endif
|
rlm@1
|
1000 #endif
|
rlm@1
|
1001
|
rlm@1
|
1002 #define OP_TST \
|
rlm@1
|
1003 u32 res = reg[base].I & value; \
|
rlm@1
|
1004 N_FLAG = (res & 0x80000000) ? true : false; \
|
rlm@1
|
1005 Z_FLAG = (res) ? false : true; \
|
rlm@1
|
1006 C_FLAG = C_OUT;
|
rlm@1
|
1007
|
rlm@1
|
1008 #define OP_TEQ \
|
rlm@1
|
1009 u32 res = reg[base].I ^ value; \
|
rlm@1
|
1010 N_FLAG = (res & 0x80000000) ? true : false; \
|
rlm@1
|
1011 Z_FLAG = (res) ? false : true; \
|
rlm@1
|
1012 C_FLAG = C_OUT;
|
rlm@1
|
1013
|
rlm@1
|
1014 #define OP_ORR \
|
rlm@1
|
1015 reg[dest].I = reg[base].I | value;
|
rlm@1
|
1016
|
rlm@1
|
1017 #define OP_ORRS \
|
rlm@1
|
1018 reg[dest].I = reg[base].I | value; \
|
rlm@1
|
1019 N_FLAG = (reg[dest].I & 0x80000000) ? true : false; \
|
rlm@1
|
1020 Z_FLAG = (reg[dest].I) ? false : true; \
|
rlm@1
|
1021 C_FLAG = C_OUT;
|
rlm@1
|
1022
|
rlm@1
|
1023 #define OP_MOV \
|
rlm@1
|
1024 reg[dest].I = value;
|
rlm@1
|
1025
|
rlm@1
|
1026 #define OP_MOVS \
|
rlm@1
|
1027 reg[dest].I = value; \
|
rlm@1
|
1028 N_FLAG = (reg[dest].I & 0x80000000) ? true : false; \
|
rlm@1
|
1029 Z_FLAG = (reg[dest].I) ? false : true; \
|
rlm@1
|
1030 C_FLAG = C_OUT;
|
rlm@1
|
1031
|
rlm@1
|
1032 #define OP_BIC \
|
rlm@1
|
1033 reg[dest].I = reg[base].I & (~value);
|
rlm@1
|
1034
|
rlm@1
|
1035 #define OP_BICS \
|
rlm@1
|
1036 reg[dest].I = reg[base].I & (~value); \
|
rlm@1
|
1037 N_FLAG = (reg[dest].I & 0x80000000) ? true : false; \
|
rlm@1
|
1038 Z_FLAG = (reg[dest].I) ? false : true; \
|
rlm@1
|
1039 C_FLAG = C_OUT;
|
rlm@1
|
1040
|
rlm@1
|
1041 #define OP_MVN \
|
rlm@1
|
1042 reg[dest].I = ~value;
|
rlm@1
|
1043
|
rlm@1
|
1044 #define OP_MVNS \
|
rlm@1
|
1045 reg[dest].I = ~value; \
|
rlm@1
|
1046 N_FLAG = (reg[dest].I & 0x80000000) ? true : false; \
|
rlm@1
|
1047 Z_FLAG = (reg[dest].I) ? false : true; \
|
rlm@1
|
1048 C_FLAG = C_OUT;
|
rlm@1
|
1049
|
rlm@1
|
1050 #define CASE_16(BASE) \
|
rlm@1
|
1051 case BASE: \
|
rlm@1
|
1052 case BASE + 1: \
|
rlm@1
|
1053 case BASE + 2: \
|
rlm@1
|
1054 case BASE + 3: \
|
rlm@1
|
1055 case BASE + 4: \
|
rlm@1
|
1056 case BASE + 5: \
|
rlm@1
|
1057 case BASE + 6: \
|
rlm@1
|
1058 case BASE + 7: \
|
rlm@1
|
1059 case BASE + 8: \
|
rlm@1
|
1060 case BASE + 9: \
|
rlm@1
|
1061 case BASE + 10: \
|
rlm@1
|
1062 case BASE + 11: \
|
rlm@1
|
1063 case BASE + 12: \
|
rlm@1
|
1064 case BASE + 13: \
|
rlm@1
|
1065 case BASE + 14: \
|
rlm@1
|
1066 case BASE + 15:
|
rlm@1
|
1067
|
rlm@1
|
1068 #define CASE_256(BASE) \
|
rlm@1
|
1069 CASE_16(BASE) \
|
rlm@1
|
1070 CASE_16(BASE + 0x10) \
|
rlm@1
|
1071 CASE_16(BASE + 0x20) \
|
rlm@1
|
1072 CASE_16(BASE + 0x30) \
|
rlm@1
|
1073 CASE_16(BASE + 0x40) \
|
rlm@1
|
1074 CASE_16(BASE + 0x50) \
|
rlm@1
|
1075 CASE_16(BASE + 0x60) \
|
rlm@1
|
1076 CASE_16(BASE + 0x70) \
|
rlm@1
|
1077 CASE_16(BASE + 0x80) \
|
rlm@1
|
1078 CASE_16(BASE + 0x90) \
|
rlm@1
|
1079 CASE_16(BASE + 0xa0) \
|
rlm@1
|
1080 CASE_16(BASE + 0xb0) \
|
rlm@1
|
1081 CASE_16(BASE + 0xc0) \
|
rlm@1
|
1082 CASE_16(BASE + 0xd0) \
|
rlm@1
|
1083 CASE_16(BASE + 0xe0) \
|
rlm@1
|
1084 CASE_16(BASE + 0xf0)
|
rlm@1
|
1085
|
rlm@1
|
1086 #define LOGICAL_DATA_OPCODE(OPCODE, OPCODE2, BASE) \
|
rlm@1
|
1087 case BASE: \
|
rlm@1
|
1088 case BASE + 8: \
|
rlm@1
|
1089 { \
|
rlm@1
|
1090 /* OP Rd,Rb,Rm LSL # */ \
|
rlm@1
|
1091 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
1092 int shift = (opcode >> 7) & 0x1F; \
|
rlm@1
|
1093 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1094 bool C_OUT = C_FLAG; \
|
rlm@1
|
1095 u32 value; \
|
rlm@1
|
1096 \
|
rlm@1
|
1097 if (shift) { \
|
rlm@1
|
1098 LOGICAL_LSL_REG \
|
rlm@1
|
1099 } else { \
|
rlm@1
|
1100 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
1101 } \
|
rlm@1
|
1102 if (dest == 15) { \
|
rlm@1
|
1103 OPCODE2 \
|
rlm@1
|
1104 /* todo */ \
|
rlm@1
|
1105 if (opcode & 0x00100000) { \
|
rlm@1
|
1106 clockTicks++; \
|
rlm@1
|
1107 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1108 } \
|
rlm@1
|
1109 if (armState) { \
|
rlm@1
|
1110 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1111 armNextPC = reg[15].I; \
|
rlm@1
|
1112 reg[15].I += 4; \
|
rlm@1
|
1113 } else { \
|
rlm@1
|
1114 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1115 armNextPC = reg[15].I; \
|
rlm@1
|
1116 reg[15].I += 2; \
|
rlm@1
|
1117 } \
|
rlm@1
|
1118 } else { \
|
rlm@1
|
1119 OPCODE \
|
rlm@1
|
1120 } \
|
rlm@1
|
1121 } \
|
rlm@1
|
1122 break; \
|
rlm@1
|
1123 case BASE + 2: \
|
rlm@1
|
1124 case BASE + 10: \
|
rlm@1
|
1125 { \
|
rlm@1
|
1126 /* OP Rd,Rb,Rm LSR # */ \
|
rlm@1
|
1127 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
1128 int shift = (opcode >> 7) & 0x1F; \
|
rlm@1
|
1129 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1130 bool C_OUT = C_FLAG; \
|
rlm@1
|
1131 u32 value; \
|
rlm@1
|
1132 if (shift) { \
|
rlm@1
|
1133 LOGICAL_LSR_REG \
|
rlm@1
|
1134 } else { \
|
rlm@1
|
1135 value = 0; \
|
rlm@1
|
1136 C_OUT = (reg[opcode & 0x0F].I & 0x80000000) ? true : false; \
|
rlm@1
|
1137 } \
|
rlm@1
|
1138 \
|
rlm@1
|
1139 if (dest == 15) { \
|
rlm@1
|
1140 OPCODE2 \
|
rlm@1
|
1141 /* todo */ \
|
rlm@1
|
1142 if (opcode & 0x00100000) { \
|
rlm@1
|
1143 clockTicks++; \
|
rlm@1
|
1144 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1145 } \
|
rlm@1
|
1146 if (armState) { \
|
rlm@1
|
1147 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1148 armNextPC = reg[15].I; \
|
rlm@1
|
1149 reg[15].I += 4; \
|
rlm@1
|
1150 } else { \
|
rlm@1
|
1151 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1152 armNextPC = reg[15].I; \
|
rlm@1
|
1153 reg[15].I += 2; \
|
rlm@1
|
1154 } \
|
rlm@1
|
1155 } else { \
|
rlm@1
|
1156 OPCODE \
|
rlm@1
|
1157 } \
|
rlm@1
|
1158 } \
|
rlm@1
|
1159 break; \
|
rlm@1
|
1160 case BASE + 4: \
|
rlm@1
|
1161 case BASE + 12: \
|
rlm@1
|
1162 { \
|
rlm@1
|
1163 /* OP Rd,Rb,Rm ASR # */ \
|
rlm@1
|
1164 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
1165 int shift = (opcode >> 7) & 0x1F; \
|
rlm@1
|
1166 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1167 bool C_OUT = C_FLAG; \
|
rlm@1
|
1168 u32 value; \
|
rlm@1
|
1169 if (shift) { \
|
rlm@1
|
1170 LOGICAL_ASR_REG \
|
rlm@1
|
1171 } else { \
|
rlm@1
|
1172 if (reg[opcode & 0x0F].I & 0x80000000) { \
|
rlm@1
|
1173 value = 0xFFFFFFFF; \
|
rlm@1
|
1174 C_OUT = true; \
|
rlm@1
|
1175 } else { \
|
rlm@1
|
1176 value = 0; \
|
rlm@1
|
1177 C_OUT = false; \
|
rlm@1
|
1178 } \
|
rlm@1
|
1179 } \
|
rlm@1
|
1180 \
|
rlm@1
|
1181 if (dest == 15) { \
|
rlm@1
|
1182 OPCODE2 \
|
rlm@1
|
1183 /* todo */ \
|
rlm@1
|
1184 if (opcode & 0x00100000) { \
|
rlm@1
|
1185 clockTicks++; \
|
rlm@1
|
1186 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1187 } \
|
rlm@1
|
1188 if (armState) { \
|
rlm@1
|
1189 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1190 armNextPC = reg[15].I; \
|
rlm@1
|
1191 reg[15].I += 4; \
|
rlm@1
|
1192 } else { \
|
rlm@1
|
1193 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1194 armNextPC = reg[15].I; \
|
rlm@1
|
1195 reg[15].I += 2; \
|
rlm@1
|
1196 } \
|
rlm@1
|
1197 } else { \
|
rlm@1
|
1198 OPCODE \
|
rlm@1
|
1199 } \
|
rlm@1
|
1200 } \
|
rlm@1
|
1201 break; \
|
rlm@1
|
1202 case BASE + 6: \
|
rlm@1
|
1203 case BASE + 14: \
|
rlm@1
|
1204 { \
|
rlm@1
|
1205 /* OP Rd,Rb,Rm ROR # */ \
|
rlm@1
|
1206 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
1207 int shift = (opcode >> 7) & 0x1F; \
|
rlm@1
|
1208 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1209 bool C_OUT = C_FLAG; \
|
rlm@1
|
1210 u32 value; \
|
rlm@1
|
1211 if (shift) { \
|
rlm@1
|
1212 LOGICAL_ROR_REG \
|
rlm@1
|
1213 } else { \
|
rlm@1
|
1214 LOGICAL_RRX_REG \
|
rlm@1
|
1215 } \
|
rlm@1
|
1216 if (dest == 15) { \
|
rlm@1
|
1217 OPCODE2 \
|
rlm@1
|
1218 /* todo */ \
|
rlm@1
|
1219 if (opcode & 0x00100000) { \
|
rlm@1
|
1220 clockTicks++; \
|
rlm@1
|
1221 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1222 } \
|
rlm@1
|
1223 if (armState) { \
|
rlm@1
|
1224 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1225 armNextPC = reg[15].I; \
|
rlm@1
|
1226 reg[15].I += 4; \
|
rlm@1
|
1227 } else { \
|
rlm@1
|
1228 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1229 armNextPC = reg[15].I; \
|
rlm@1
|
1230 reg[15].I += 2; \
|
rlm@1
|
1231 } \
|
rlm@1
|
1232 } else { \
|
rlm@1
|
1233 OPCODE \
|
rlm@1
|
1234 } \
|
rlm@1
|
1235 } \
|
rlm@1
|
1236 break; \
|
rlm@1
|
1237 case BASE + 1: \
|
rlm@1
|
1238 { \
|
rlm@1
|
1239 /* OP Rd,Rb,Rm LSL Rs */ \
|
rlm@1
|
1240 clockTicks++; \
|
rlm@1
|
1241 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
1242 int shift = reg[(opcode >> 8) & 15].B.B0; \
|
rlm@1
|
1243 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1244 bool C_OUT = C_FLAG; \
|
rlm@1
|
1245 u32 value; \
|
rlm@1
|
1246 if (shift) { \
|
rlm@1
|
1247 if (shift == 32) { \
|
rlm@1
|
1248 value = 0; \
|
rlm@1
|
1249 C_OUT = (reg[opcode & 0x0F].I & 1 ? true : false); \
|
rlm@1
|
1250 } else if (shift < 32) { \
|
rlm@1
|
1251 LOGICAL_LSL_REG \
|
rlm@1
|
1252 } else { \
|
rlm@1
|
1253 value = 0; \
|
rlm@1
|
1254 C_OUT = false; \
|
rlm@1
|
1255 } \
|
rlm@1
|
1256 } else { \
|
rlm@1
|
1257 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
1258 } \
|
rlm@1
|
1259 if (dest == 15) { \
|
rlm@1
|
1260 OPCODE2 \
|
rlm@1
|
1261 /* todo */ \
|
rlm@1
|
1262 if (opcode & 0x00100000) { \
|
rlm@1
|
1263 clockTicks++; \
|
rlm@1
|
1264 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1265 } \
|
rlm@1
|
1266 if (armState) { \
|
rlm@1
|
1267 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1268 armNextPC = reg[15].I; \
|
rlm@1
|
1269 reg[15].I += 4; \
|
rlm@1
|
1270 } else { \
|
rlm@1
|
1271 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1272 armNextPC = reg[15].I; \
|
rlm@1
|
1273 reg[15].I += 2; \
|
rlm@1
|
1274 } \
|
rlm@1
|
1275 } else { \
|
rlm@1
|
1276 OPCODE \
|
rlm@1
|
1277 } \
|
rlm@1
|
1278 } \
|
rlm@1
|
1279 break; \
|
rlm@1
|
1280 case BASE + 3: \
|
rlm@1
|
1281 { \
|
rlm@1
|
1282 /* OP Rd,Rb,Rm LSR Rs */ \
|
rlm@1
|
1283 clockTicks++; \
|
rlm@1
|
1284 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
1285 int shift = reg[(opcode >> 8) & 15].B.B0; \
|
rlm@1
|
1286 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1287 bool C_OUT = C_FLAG; \
|
rlm@1
|
1288 u32 value; \
|
rlm@1
|
1289 if (shift) { \
|
rlm@1
|
1290 if (shift == 32) { \
|
rlm@1
|
1291 value = 0; \
|
rlm@1
|
1292 C_OUT = (reg[opcode & 0x0F].I & 0x80000000 ? true : false); \
|
rlm@1
|
1293 } else if (shift < 32) { \
|
rlm@1
|
1294 LOGICAL_LSR_REG \
|
rlm@1
|
1295 } else { \
|
rlm@1
|
1296 value = 0; \
|
rlm@1
|
1297 C_OUT = false; \
|
rlm@1
|
1298 } \
|
rlm@1
|
1299 } else { \
|
rlm@1
|
1300 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
1301 } \
|
rlm@1
|
1302 if (dest == 15) { \
|
rlm@1
|
1303 OPCODE2 \
|
rlm@1
|
1304 /* todo */ \
|
rlm@1
|
1305 if (opcode & 0x00100000) { \
|
rlm@1
|
1306 clockTicks++; \
|
rlm@1
|
1307 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1308 } \
|
rlm@1
|
1309 if (armState) { \
|
rlm@1
|
1310 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1311 armNextPC = reg[15].I; \
|
rlm@1
|
1312 reg[15].I += 4; \
|
rlm@1
|
1313 } else { \
|
rlm@1
|
1314 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1315 armNextPC = reg[15].I; \
|
rlm@1
|
1316 reg[15].I += 2; \
|
rlm@1
|
1317 } \
|
rlm@1
|
1318 } else { \
|
rlm@1
|
1319 OPCODE \
|
rlm@1
|
1320 } \
|
rlm@1
|
1321 } \
|
rlm@1
|
1322 break; \
|
rlm@1
|
1323 case BASE + 5: \
|
rlm@1
|
1324 { \
|
rlm@1
|
1325 /* OP Rd,Rb,Rm ASR Rs */ \
|
rlm@1
|
1326 clockTicks++; \
|
rlm@1
|
1327 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
1328 int shift = reg[(opcode >> 8) & 15].B.B0; \
|
rlm@1
|
1329 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1330 bool C_OUT = C_FLAG; \
|
rlm@1
|
1331 u32 value; \
|
rlm@1
|
1332 if (shift < 32) { \
|
rlm@1
|
1333 if (shift) { \
|
rlm@1
|
1334 LOGICAL_ASR_REG \
|
rlm@1
|
1335 } else { \
|
rlm@1
|
1336 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
1337 } \
|
rlm@1
|
1338 } else { \
|
rlm@1
|
1339 if (reg[opcode & 0x0F].I & 0x80000000) { \
|
rlm@1
|
1340 value = 0xFFFFFFFF; \
|
rlm@1
|
1341 C_OUT = true; \
|
rlm@1
|
1342 } else { \
|
rlm@1
|
1343 value = 0; \
|
rlm@1
|
1344 C_OUT = false; \
|
rlm@1
|
1345 } \
|
rlm@1
|
1346 } \
|
rlm@1
|
1347 if (dest == 15) { \
|
rlm@1
|
1348 OPCODE2 \
|
rlm@1
|
1349 /* todo */ \
|
rlm@1
|
1350 if (opcode & 0x00100000) { \
|
rlm@1
|
1351 clockTicks++; \
|
rlm@1
|
1352 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1353 } \
|
rlm@1
|
1354 if (armState) { \
|
rlm@1
|
1355 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1356 armNextPC = reg[15].I; \
|
rlm@1
|
1357 reg[15].I += 4; \
|
rlm@1
|
1358 } else { \
|
rlm@1
|
1359 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1360 armNextPC = reg[15].I; \
|
rlm@1
|
1361 reg[15].I += 2; \
|
rlm@1
|
1362 } \
|
rlm@1
|
1363 } else { \
|
rlm@1
|
1364 OPCODE \
|
rlm@1
|
1365 } \
|
rlm@1
|
1366 } \
|
rlm@1
|
1367 break; \
|
rlm@1
|
1368 case BASE + 7: \
|
rlm@1
|
1369 { \
|
rlm@1
|
1370 /* OP Rd,Rb,Rm ROR Rs */ \
|
rlm@1
|
1371 clockTicks++; \
|
rlm@1
|
1372 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
1373 int shift = reg[(opcode >> 8) & 15].B.B0; \
|
rlm@1
|
1374 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1375 bool C_OUT = C_FLAG; \
|
rlm@1
|
1376 u32 value; \
|
rlm@1
|
1377 if (shift) { \
|
rlm@1
|
1378 shift &= 0x1f; \
|
rlm@1
|
1379 if (shift) { \
|
rlm@1
|
1380 LOGICAL_ROR_REG \
|
rlm@1
|
1381 } else { \
|
rlm@1
|
1382 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
1383 C_OUT = (value & 0x80000000 ? true : false); \
|
rlm@1
|
1384 } \
|
rlm@1
|
1385 } else { \
|
rlm@1
|
1386 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
1387 C_OUT = (value & 0x80000000 ? true : false); \
|
rlm@1
|
1388 } \
|
rlm@1
|
1389 if (dest == 15) { \
|
rlm@1
|
1390 OPCODE2 \
|
rlm@1
|
1391 /* todo */ \
|
rlm@1
|
1392 if (opcode & 0x00100000) { \
|
rlm@1
|
1393 clockTicks++; \
|
rlm@1
|
1394 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1395 } \
|
rlm@1
|
1396 if (armState) { \
|
rlm@1
|
1397 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1398 armNextPC = reg[15].I; \
|
rlm@1
|
1399 reg[15].I += 4; \
|
rlm@1
|
1400 } else { \
|
rlm@1
|
1401 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1402 armNextPC = reg[15].I; \
|
rlm@1
|
1403 reg[15].I += 2; \
|
rlm@1
|
1404 } \
|
rlm@1
|
1405 } else { \
|
rlm@1
|
1406 OPCODE \
|
rlm@1
|
1407 } \
|
rlm@1
|
1408 } \
|
rlm@1
|
1409 break; \
|
rlm@1
|
1410 case BASE + 0x200: \
|
rlm@1
|
1411 case BASE + 0x201: \
|
rlm@1
|
1412 case BASE + 0x202: \
|
rlm@1
|
1413 case BASE + 0x203: \
|
rlm@1
|
1414 case BASE + 0x204: \
|
rlm@1
|
1415 case BASE + 0x205: \
|
rlm@1
|
1416 case BASE + 0x206: \
|
rlm@1
|
1417 case BASE + 0x207: \
|
rlm@1
|
1418 case BASE + 0x208: \
|
rlm@1
|
1419 case BASE + 0x209: \
|
rlm@1
|
1420 case BASE + 0x20a: \
|
rlm@1
|
1421 case BASE + 0x20b: \
|
rlm@1
|
1422 case BASE + 0x20c: \
|
rlm@1
|
1423 case BASE + 0x20d: \
|
rlm@1
|
1424 case BASE + 0x20e: \
|
rlm@1
|
1425 case BASE + 0x20f: \
|
rlm@1
|
1426 { \
|
rlm@1
|
1427 int shift = (opcode & 0xF00) >> 7; \
|
rlm@1
|
1428 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
1429 int dest = (opcode >> 12) & 0x0F; \
|
rlm@1
|
1430 bool C_OUT = C_FLAG; \
|
rlm@1
|
1431 u32 value; \
|
rlm@1
|
1432 if (shift) { \
|
rlm@1
|
1433 LOGICAL_ROR_IMM \
|
rlm@1
|
1434 } else { \
|
rlm@1
|
1435 value = opcode & 0xff; \
|
rlm@1
|
1436 } \
|
rlm@1
|
1437 if (dest == 15) { \
|
rlm@1
|
1438 OPCODE2 \
|
rlm@1
|
1439 /* todo */ \
|
rlm@1
|
1440 if (opcode & 0x00100000) { \
|
rlm@1
|
1441 clockTicks++; \
|
rlm@1
|
1442 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1443 } \
|
rlm@1
|
1444 if (armState) { \
|
rlm@1
|
1445 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1446 armNextPC = reg[15].I; \
|
rlm@1
|
1447 reg[15].I += 4; \
|
rlm@1
|
1448 } else { \
|
rlm@1
|
1449 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1450 armNextPC = reg[15].I; \
|
rlm@1
|
1451 reg[15].I += 2; \
|
rlm@1
|
1452 } \
|
rlm@1
|
1453 } else { \
|
rlm@1
|
1454 OPCODE \
|
rlm@1
|
1455 } \
|
rlm@1
|
1456 } \
|
rlm@1
|
1457 break;
|
rlm@1
|
1458
|
rlm@1
|
1459 #define LOGICAL_DATA_OPCODE_WITHOUT_base(OPCODE, OPCODE2, BASE) \
|
rlm@1
|
1460 case BASE: \
|
rlm@1
|
1461 case BASE + 8: \
|
rlm@1
|
1462 { \
|
rlm@1
|
1463 /* OP Rd,Rb,Rm LSL # */ \
|
rlm@1
|
1464 int shift = (opcode >> 7) & 0x1F; \
|
rlm@1
|
1465 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1466 bool C_OUT = C_FLAG; \
|
rlm@1
|
1467 u32 value; \
|
rlm@1
|
1468 \
|
rlm@1
|
1469 if (shift) { \
|
rlm@1
|
1470 LOGICAL_LSL_REG \
|
rlm@1
|
1471 } else { \
|
rlm@1
|
1472 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
1473 } \
|
rlm@1
|
1474 if (dest == 15) { \
|
rlm@1
|
1475 OPCODE2 \
|
rlm@1
|
1476 /* todo */ \
|
rlm@1
|
1477 if (opcode & 0x00100000) { \
|
rlm@1
|
1478 clockTicks++; \
|
rlm@1
|
1479 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1480 } \
|
rlm@1
|
1481 if (armState) { \
|
rlm@1
|
1482 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1483 armNextPC = reg[15].I; \
|
rlm@1
|
1484 reg[15].I += 4; \
|
rlm@1
|
1485 } else { \
|
rlm@1
|
1486 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1487 armNextPC = reg[15].I; \
|
rlm@1
|
1488 reg[15].I += 2; \
|
rlm@1
|
1489 } \
|
rlm@1
|
1490 } else { \
|
rlm@1
|
1491 OPCODE \
|
rlm@1
|
1492 } \
|
rlm@1
|
1493 } \
|
rlm@1
|
1494 break; \
|
rlm@1
|
1495 case BASE + 2: \
|
rlm@1
|
1496 case BASE + 10: \
|
rlm@1
|
1497 { \
|
rlm@1
|
1498 /* OP Rd,Rb,Rm LSR # */ \
|
rlm@1
|
1499 int shift = (opcode >> 7) & 0x1F; \
|
rlm@1
|
1500 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1501 bool C_OUT = C_FLAG; \
|
rlm@1
|
1502 u32 value; \
|
rlm@1
|
1503 if (shift) { \
|
rlm@1
|
1504 LOGICAL_LSR_REG \
|
rlm@1
|
1505 } else { \
|
rlm@1
|
1506 value = 0; \
|
rlm@1
|
1507 C_OUT = (reg[opcode & 0x0F].I & 0x80000000) ? true : false; \
|
rlm@1
|
1508 } \
|
rlm@1
|
1509 \
|
rlm@1
|
1510 if (dest == 15) { \
|
rlm@1
|
1511 OPCODE2 \
|
rlm@1
|
1512 /* todo */ \
|
rlm@1
|
1513 if (opcode & 0x00100000) { \
|
rlm@1
|
1514 clockTicks++; \
|
rlm@1
|
1515 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1516 } \
|
rlm@1
|
1517 if (armState) { \
|
rlm@1
|
1518 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1519 armNextPC = reg[15].I; \
|
rlm@1
|
1520 reg[15].I += 4; \
|
rlm@1
|
1521 } else { \
|
rlm@1
|
1522 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1523 armNextPC = reg[15].I; \
|
rlm@1
|
1524 reg[15].I += 2; \
|
rlm@1
|
1525 } \
|
rlm@1
|
1526 } else { \
|
rlm@1
|
1527 OPCODE \
|
rlm@1
|
1528 } \
|
rlm@1
|
1529 } \
|
rlm@1
|
1530 break; \
|
rlm@1
|
1531 case BASE + 4: \
|
rlm@1
|
1532 case BASE + 12: \
|
rlm@1
|
1533 { \
|
rlm@1
|
1534 /* OP Rd,Rb,Rm ASR # */ \
|
rlm@1
|
1535 int shift = (opcode >> 7) & 0x1F; \
|
rlm@1
|
1536 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1537 bool C_OUT = C_FLAG; \
|
rlm@1
|
1538 u32 value; \
|
rlm@1
|
1539 if (shift) { \
|
rlm@1
|
1540 LOGICAL_ASR_REG \
|
rlm@1
|
1541 } else { \
|
rlm@1
|
1542 if (reg[opcode & 0x0F].I & 0x80000000) { \
|
rlm@1
|
1543 value = 0xFFFFFFFF; \
|
rlm@1
|
1544 C_OUT = true; \
|
rlm@1
|
1545 } else { \
|
rlm@1
|
1546 value = 0; \
|
rlm@1
|
1547 C_OUT = false; \
|
rlm@1
|
1548 } \
|
rlm@1
|
1549 } \
|
rlm@1
|
1550 \
|
rlm@1
|
1551 if (dest == 15) { \
|
rlm@1
|
1552 OPCODE2 \
|
rlm@1
|
1553 /* todo */ \
|
rlm@1
|
1554 if (opcode & 0x00100000) { \
|
rlm@1
|
1555 clockTicks++; \
|
rlm@1
|
1556 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1557 } \
|
rlm@1
|
1558 if (armState) { \
|
rlm@1
|
1559 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1560 armNextPC = reg[15].I; \
|
rlm@1
|
1561 reg[15].I += 4; \
|
rlm@1
|
1562 } else { \
|
rlm@1
|
1563 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1564 armNextPC = reg[15].I; \
|
rlm@1
|
1565 reg[15].I += 2; \
|
rlm@1
|
1566 } \
|
rlm@1
|
1567 } else { \
|
rlm@1
|
1568 OPCODE \
|
rlm@1
|
1569 } \
|
rlm@1
|
1570 } \
|
rlm@1
|
1571 break; \
|
rlm@1
|
1572 case BASE + 6: \
|
rlm@1
|
1573 case BASE + 14: \
|
rlm@1
|
1574 { \
|
rlm@1
|
1575 /* OP Rd,Rb,Rm ROR # */ \
|
rlm@1
|
1576 int shift = (opcode >> 7) & 0x1F; \
|
rlm@1
|
1577 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1578 bool C_OUT = C_FLAG; \
|
rlm@1
|
1579 u32 value; \
|
rlm@1
|
1580 if (shift) { \
|
rlm@1
|
1581 LOGICAL_ROR_REG \
|
rlm@1
|
1582 } else { \
|
rlm@1
|
1583 LOGICAL_RRX_REG \
|
rlm@1
|
1584 } \
|
rlm@1
|
1585 if (dest == 15) { \
|
rlm@1
|
1586 OPCODE2 \
|
rlm@1
|
1587 /* todo */ \
|
rlm@1
|
1588 if (opcode & 0x00100000) { \
|
rlm@1
|
1589 clockTicks++; \
|
rlm@1
|
1590 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1591 } \
|
rlm@1
|
1592 if (armState) { \
|
rlm@1
|
1593 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1594 armNextPC = reg[15].I; \
|
rlm@1
|
1595 reg[15].I += 4; \
|
rlm@1
|
1596 } else { \
|
rlm@1
|
1597 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1598 armNextPC = reg[15].I; \
|
rlm@1
|
1599 reg[15].I += 2; \
|
rlm@1
|
1600 } \
|
rlm@1
|
1601 } else { \
|
rlm@1
|
1602 OPCODE \
|
rlm@1
|
1603 } \
|
rlm@1
|
1604 } \
|
rlm@1
|
1605 break; \
|
rlm@1
|
1606 case BASE + 1: \
|
rlm@1
|
1607 { \
|
rlm@1
|
1608 /* OP Rd,Rb,Rm LSL Rs */ \
|
rlm@1
|
1609 clockTicks++; \
|
rlm@1
|
1610 int shift = reg[(opcode >> 8) & 15].B.B0; \
|
rlm@1
|
1611 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1612 bool C_OUT = C_FLAG; \
|
rlm@1
|
1613 u32 value; \
|
rlm@1
|
1614 if (shift) { \
|
rlm@1
|
1615 if (shift == 32) { \
|
rlm@1
|
1616 value = 0; \
|
rlm@1
|
1617 C_OUT = (reg[opcode & 0x0F].I & 1 ? true : false); \
|
rlm@1
|
1618 } else if (shift < 32) { \
|
rlm@1
|
1619 LOGICAL_LSL_REG \
|
rlm@1
|
1620 } else { \
|
rlm@1
|
1621 value = 0; \
|
rlm@1
|
1622 C_OUT = false; \
|
rlm@1
|
1623 } \
|
rlm@1
|
1624 } else { \
|
rlm@1
|
1625 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
1626 } \
|
rlm@1
|
1627 if (dest == 15) { \
|
rlm@1
|
1628 OPCODE2 \
|
rlm@1
|
1629 /* todo */ \
|
rlm@1
|
1630 if (opcode & 0x00100000) { \
|
rlm@1
|
1631 clockTicks++; \
|
rlm@1
|
1632 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1633 } \
|
rlm@1
|
1634 if (armState) { \
|
rlm@1
|
1635 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1636 armNextPC = reg[15].I; \
|
rlm@1
|
1637 reg[15].I += 4; \
|
rlm@1
|
1638 } else { \
|
rlm@1
|
1639 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1640 armNextPC = reg[15].I; \
|
rlm@1
|
1641 reg[15].I += 2; \
|
rlm@1
|
1642 } \
|
rlm@1
|
1643 } else { \
|
rlm@1
|
1644 OPCODE \
|
rlm@1
|
1645 } \
|
rlm@1
|
1646 } \
|
rlm@1
|
1647 break; \
|
rlm@1
|
1648 case BASE + 3: \
|
rlm@1
|
1649 { \
|
rlm@1
|
1650 /* OP Rd,Rb,Rm LSR Rs */ \
|
rlm@1
|
1651 clockTicks++; \
|
rlm@1
|
1652 int shift = reg[(opcode >> 8) & 15].B.B0; \
|
rlm@1
|
1653 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1654 bool C_OUT = C_FLAG; \
|
rlm@1
|
1655 u32 value; \
|
rlm@1
|
1656 if (shift) { \
|
rlm@1
|
1657 if (shift == 32) { \
|
rlm@1
|
1658 value = 0; \
|
rlm@1
|
1659 C_OUT = (reg[opcode & 0x0F].I & 0x80000000 ? true : false); \
|
rlm@1
|
1660 } else if (shift < 32) { \
|
rlm@1
|
1661 LOGICAL_LSR_REG \
|
rlm@1
|
1662 } else { \
|
rlm@1
|
1663 value = 0; \
|
rlm@1
|
1664 C_OUT = false; \
|
rlm@1
|
1665 } \
|
rlm@1
|
1666 } else { \
|
rlm@1
|
1667 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
1668 } \
|
rlm@1
|
1669 if (dest == 15) { \
|
rlm@1
|
1670 OPCODE2 \
|
rlm@1
|
1671 /* todo */ \
|
rlm@1
|
1672 if (opcode & 0x00100000) { \
|
rlm@1
|
1673 clockTicks++; \
|
rlm@1
|
1674 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1675 } \
|
rlm@1
|
1676 if (armState) { \
|
rlm@1
|
1677 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1678 armNextPC = reg[15].I; \
|
rlm@1
|
1679 reg[15].I += 4; \
|
rlm@1
|
1680 } else { \
|
rlm@1
|
1681 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1682 armNextPC = reg[15].I; \
|
rlm@1
|
1683 reg[15].I += 2; \
|
rlm@1
|
1684 } \
|
rlm@1
|
1685 } else { \
|
rlm@1
|
1686 OPCODE \
|
rlm@1
|
1687 } \
|
rlm@1
|
1688 } \
|
rlm@1
|
1689 break; \
|
rlm@1
|
1690 case BASE + 5: \
|
rlm@1
|
1691 { \
|
rlm@1
|
1692 /* OP Rd,Rb,Rm ASR Rs */ \
|
rlm@1
|
1693 clockTicks++; \
|
rlm@1
|
1694 int shift = reg[(opcode >> 8) & 15].B.B0; \
|
rlm@1
|
1695 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1696 bool C_OUT = C_FLAG; \
|
rlm@1
|
1697 u32 value; \
|
rlm@1
|
1698 if (shift < 32) { \
|
rlm@1
|
1699 if (shift) { \
|
rlm@1
|
1700 LOGICAL_ASR_REG \
|
rlm@1
|
1701 } else { \
|
rlm@1
|
1702 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
1703 } \
|
rlm@1
|
1704 } else { \
|
rlm@1
|
1705 if (reg[opcode & 0x0F].I & 0x80000000) { \
|
rlm@1
|
1706 value = 0xFFFFFFFF; \
|
rlm@1
|
1707 C_OUT = true; \
|
rlm@1
|
1708 } else { \
|
rlm@1
|
1709 value = 0; \
|
rlm@1
|
1710 C_OUT = false; \
|
rlm@1
|
1711 } \
|
rlm@1
|
1712 } \
|
rlm@1
|
1713 if (dest == 15) { \
|
rlm@1
|
1714 OPCODE2 \
|
rlm@1
|
1715 /* todo */ \
|
rlm@1
|
1716 if (opcode & 0x00100000) { \
|
rlm@1
|
1717 clockTicks++; \
|
rlm@1
|
1718 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1719 } \
|
rlm@1
|
1720 if (armState) { \
|
rlm@1
|
1721 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1722 armNextPC = reg[15].I; \
|
rlm@1
|
1723 reg[15].I += 4; \
|
rlm@1
|
1724 } else { \
|
rlm@1
|
1725 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1726 armNextPC = reg[15].I; \
|
rlm@1
|
1727 reg[15].I += 2; \
|
rlm@1
|
1728 } \
|
rlm@1
|
1729 } else { \
|
rlm@1
|
1730 OPCODE \
|
rlm@1
|
1731 } \
|
rlm@1
|
1732 } \
|
rlm@1
|
1733 break; \
|
rlm@1
|
1734 case BASE + 7: \
|
rlm@1
|
1735 { \
|
rlm@1
|
1736 /* OP Rd,Rb,Rm ROR Rs */ \
|
rlm@1
|
1737 clockTicks++; \
|
rlm@1
|
1738 int shift = reg[(opcode >> 8) & 15].B.B0; \
|
rlm@1
|
1739 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1740 bool C_OUT = C_FLAG; \
|
rlm@1
|
1741 u32 value; \
|
rlm@1
|
1742 if (shift) { \
|
rlm@1
|
1743 shift &= 0x1f; \
|
rlm@1
|
1744 if (shift) { \
|
rlm@1
|
1745 LOGICAL_ROR_REG \
|
rlm@1
|
1746 } else { \
|
rlm@1
|
1747 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
1748 C_OUT = (value & 0x80000000 ? true : false); \
|
rlm@1
|
1749 } \
|
rlm@1
|
1750 } else { \
|
rlm@1
|
1751 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
1752 C_OUT = (value & 0x80000000 ? true : false); \
|
rlm@1
|
1753 } \
|
rlm@1
|
1754 if (dest == 15) { \
|
rlm@1
|
1755 OPCODE2 \
|
rlm@1
|
1756 /* todo */ \
|
rlm@1
|
1757 if (opcode & 0x00100000) { \
|
rlm@1
|
1758 clockTicks++; \
|
rlm@1
|
1759 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1760 } \
|
rlm@1
|
1761 if (armState) { \
|
rlm@1
|
1762 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1763 armNextPC = reg[15].I; \
|
rlm@1
|
1764 reg[15].I += 4; \
|
rlm@1
|
1765 } else { \
|
rlm@1
|
1766 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1767 armNextPC = reg[15].I; \
|
rlm@1
|
1768 reg[15].I += 2; \
|
rlm@1
|
1769 } \
|
rlm@1
|
1770 } else { \
|
rlm@1
|
1771 OPCODE \
|
rlm@1
|
1772 } \
|
rlm@1
|
1773 } \
|
rlm@1
|
1774 break; \
|
rlm@1
|
1775 case BASE + 0x200: \
|
rlm@1
|
1776 case BASE + 0x201: \
|
rlm@1
|
1777 case BASE + 0x202: \
|
rlm@1
|
1778 case BASE + 0x203: \
|
rlm@1
|
1779 case BASE + 0x204: \
|
rlm@1
|
1780 case BASE + 0x205: \
|
rlm@1
|
1781 case BASE + 0x206: \
|
rlm@1
|
1782 case BASE + 0x207: \
|
rlm@1
|
1783 case BASE + 0x208: \
|
rlm@1
|
1784 case BASE + 0x209: \
|
rlm@1
|
1785 case BASE + 0x20a: \
|
rlm@1
|
1786 case BASE + 0x20b: \
|
rlm@1
|
1787 case BASE + 0x20c: \
|
rlm@1
|
1788 case BASE + 0x20d: \
|
rlm@1
|
1789 case BASE + 0x20e: \
|
rlm@1
|
1790 case BASE + 0x20f: \
|
rlm@1
|
1791 { \
|
rlm@1
|
1792 int shift = (opcode & 0xF00) >> 7; \
|
rlm@1
|
1793 int dest = (opcode >> 12) & 0x0F; \
|
rlm@1
|
1794 bool C_OUT = C_FLAG; \
|
rlm@1
|
1795 u32 value; \
|
rlm@1
|
1796 if (shift) { \
|
rlm@1
|
1797 LOGICAL_ROR_IMM \
|
rlm@1
|
1798 } else { \
|
rlm@1
|
1799 value = opcode & 0xff; \
|
rlm@1
|
1800 } \
|
rlm@1
|
1801 if (dest == 15) { \
|
rlm@1
|
1802 OPCODE2 \
|
rlm@1
|
1803 /* todo */ \
|
rlm@1
|
1804 if (opcode & 0x00100000) { \
|
rlm@1
|
1805 clockTicks++; \
|
rlm@1
|
1806 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1807 } \
|
rlm@1
|
1808 if (armState) { \
|
rlm@1
|
1809 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1810 armNextPC = reg[15].I; \
|
rlm@1
|
1811 reg[15].I += 4; \
|
rlm@1
|
1812 } else { \
|
rlm@1
|
1813 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1814 armNextPC = reg[15].I; \
|
rlm@1
|
1815 reg[15].I += 2; \
|
rlm@1
|
1816 } \
|
rlm@1
|
1817 } else { \
|
rlm@1
|
1818 OPCODE \
|
rlm@1
|
1819 } \
|
rlm@1
|
1820 } \
|
rlm@1
|
1821 break;
|
rlm@1
|
1822
|
rlm@1
|
1823 #define ARITHMETIC_DATA_OPCODE(OPCODE, OPCODE2, BASE) \
|
rlm@1
|
1824 case BASE: \
|
rlm@1
|
1825 case BASE + 8: \
|
rlm@1
|
1826 { \
|
rlm@1
|
1827 /* OP Rd,Rb,Rm LSL # */ \
|
rlm@1
|
1828 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
1829 int shift = (opcode >> 7) & 0x1F; \
|
rlm@1
|
1830 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1831 u32 value; \
|
rlm@1
|
1832 if (shift) { \
|
rlm@1
|
1833 ARITHMETIC_LSL_REG \
|
rlm@1
|
1834 } else { \
|
rlm@1
|
1835 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
1836 } \
|
rlm@1
|
1837 if (dest == 15) { \
|
rlm@1
|
1838 OPCODE2 \
|
rlm@1
|
1839 /* todo */ \
|
rlm@1
|
1840 if (opcode & 0x00100000) { \
|
rlm@1
|
1841 clockTicks++; \
|
rlm@1
|
1842 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1843 } \
|
rlm@1
|
1844 if (armState) { \
|
rlm@1
|
1845 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1846 armNextPC = reg[15].I; \
|
rlm@1
|
1847 reg[15].I += 4; \
|
rlm@1
|
1848 } else { \
|
rlm@1
|
1849 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1850 armNextPC = reg[15].I; \
|
rlm@1
|
1851 reg[15].I += 2; \
|
rlm@1
|
1852 } \
|
rlm@1
|
1853 } else { \
|
rlm@1
|
1854 OPCODE \
|
rlm@1
|
1855 } \
|
rlm@1
|
1856 } \
|
rlm@1
|
1857 break; \
|
rlm@1
|
1858 case BASE + 2: \
|
rlm@1
|
1859 case BASE + 10: \
|
rlm@1
|
1860 { \
|
rlm@1
|
1861 /* OP Rd,Rb,Rm LSR # */ \
|
rlm@1
|
1862 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
1863 int shift = (opcode >> 7) & 0x1F; \
|
rlm@1
|
1864 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1865 u32 value; \
|
rlm@1
|
1866 if (shift) { \
|
rlm@1
|
1867 ARITHMETIC_LSR_REG \
|
rlm@1
|
1868 } else { \
|
rlm@1
|
1869 value = 0; \
|
rlm@1
|
1870 } \
|
rlm@1
|
1871 if (dest == 15) { \
|
rlm@1
|
1872 OPCODE2 \
|
rlm@1
|
1873 /* todo */ \
|
rlm@1
|
1874 if (opcode & 0x00100000) { \
|
rlm@1
|
1875 clockTicks++; \
|
rlm@1
|
1876 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1877 } \
|
rlm@1
|
1878 if (armState) { \
|
rlm@1
|
1879 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1880 armNextPC = reg[15].I; \
|
rlm@1
|
1881 reg[15].I += 4; \
|
rlm@1
|
1882 } else { \
|
rlm@1
|
1883 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1884 armNextPC = reg[15].I; \
|
rlm@1
|
1885 reg[15].I += 2; \
|
rlm@1
|
1886 } \
|
rlm@1
|
1887 } else { \
|
rlm@1
|
1888 OPCODE \
|
rlm@1
|
1889 } \
|
rlm@1
|
1890 } \
|
rlm@1
|
1891 break; \
|
rlm@1
|
1892 case BASE + 4: \
|
rlm@1
|
1893 case BASE + 12: \
|
rlm@1
|
1894 { \
|
rlm@1
|
1895 /* OP Rd,Rb,Rm ASR # */ \
|
rlm@1
|
1896 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
1897 int shift = (opcode >> 7) & 0x1F; \
|
rlm@1
|
1898 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1899 u32 value; \
|
rlm@1
|
1900 if (shift) { \
|
rlm@1
|
1901 ARITHMETIC_ASR_REG \
|
rlm@1
|
1902 } else { \
|
rlm@1
|
1903 if (reg[opcode & 0x0F].I & 0x80000000) { \
|
rlm@1
|
1904 value = 0xFFFFFFFF; \
|
rlm@1
|
1905 } else value = 0; \
|
rlm@1
|
1906 } \
|
rlm@1
|
1907 if (dest == 15) { \
|
rlm@1
|
1908 OPCODE2 \
|
rlm@1
|
1909 /* todo */ \
|
rlm@1
|
1910 if (opcode & 0x00100000) { \
|
rlm@1
|
1911 clockTicks++; \
|
rlm@1
|
1912 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1913 } \
|
rlm@1
|
1914 if (armState) { \
|
rlm@1
|
1915 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1916 armNextPC = reg[15].I; \
|
rlm@1
|
1917 reg[15].I += 4; \
|
rlm@1
|
1918 } else { \
|
rlm@1
|
1919 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1920 armNextPC = reg[15].I; \
|
rlm@1
|
1921 reg[15].I += 2; \
|
rlm@1
|
1922 } \
|
rlm@1
|
1923 } else { \
|
rlm@1
|
1924 OPCODE \
|
rlm@1
|
1925 } \
|
rlm@1
|
1926 } \
|
rlm@1
|
1927 break; \
|
rlm@1
|
1928 case BASE + 6: \
|
rlm@1
|
1929 case BASE + 14: \
|
rlm@1
|
1930 { \
|
rlm@1
|
1931 /* OP Rd,Rb,Rm ROR # */ \
|
rlm@1
|
1932 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
1933 int shift = (opcode >> 7) & 0x1F; \
|
rlm@1
|
1934 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1935 u32 value; \
|
rlm@1
|
1936 if (shift) { \
|
rlm@1
|
1937 ARITHMETIC_ROR_REG \
|
rlm@1
|
1938 } else { \
|
rlm@1
|
1939 ARITHMETIC_RRX_REG \
|
rlm@1
|
1940 } \
|
rlm@1
|
1941 if (dest == 15) { \
|
rlm@1
|
1942 OPCODE2 \
|
rlm@1
|
1943 /* todo */ \
|
rlm@1
|
1944 if (opcode & 0x00100000) { \
|
rlm@1
|
1945 clockTicks++; \
|
rlm@1
|
1946 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1947 } \
|
rlm@1
|
1948 if (armState) { \
|
rlm@1
|
1949 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1950 armNextPC = reg[15].I; \
|
rlm@1
|
1951 reg[15].I += 4; \
|
rlm@1
|
1952 } else { \
|
rlm@1
|
1953 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1954 armNextPC = reg[15].I; \
|
rlm@1
|
1955 reg[15].I += 2; \
|
rlm@1
|
1956 } \
|
rlm@1
|
1957 } else { \
|
rlm@1
|
1958 OPCODE \
|
rlm@1
|
1959 } \
|
rlm@1
|
1960 } \
|
rlm@1
|
1961 break; \
|
rlm@1
|
1962 case BASE + 1: \
|
rlm@1
|
1963 { \
|
rlm@1
|
1964 /* OP Rd,Rb,Rm LSL Rs */ \
|
rlm@1
|
1965 clockTicks++; \
|
rlm@1
|
1966 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
1967 int shift = reg[(opcode >> 8) & 15].B.B0; \
|
rlm@1
|
1968 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
1969 u32 value; \
|
rlm@1
|
1970 if (shift) { \
|
rlm@1
|
1971 if (shift == 32) { \
|
rlm@1
|
1972 value = 0; \
|
rlm@1
|
1973 } else if (shift < 32) { \
|
rlm@1
|
1974 ARITHMETIC_LSL_REG \
|
rlm@1
|
1975 } else value = 0; \
|
rlm@1
|
1976 } else { \
|
rlm@1
|
1977 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
1978 } \
|
rlm@1
|
1979 if (dest == 15) { \
|
rlm@1
|
1980 OPCODE2 \
|
rlm@1
|
1981 /* todo */ \
|
rlm@1
|
1982 if (opcode & 0x00100000) { \
|
rlm@1
|
1983 clockTicks++; \
|
rlm@1
|
1984 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
1985 } \
|
rlm@1
|
1986 if (armState) { \
|
rlm@1
|
1987 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
1988 armNextPC = reg[15].I; \
|
rlm@1
|
1989 reg[15].I += 4; \
|
rlm@1
|
1990 } else { \
|
rlm@1
|
1991 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
1992 armNextPC = reg[15].I; \
|
rlm@1
|
1993 reg[15].I += 2; \
|
rlm@1
|
1994 } \
|
rlm@1
|
1995 } else { \
|
rlm@1
|
1996 OPCODE \
|
rlm@1
|
1997 } \
|
rlm@1
|
1998 } \
|
rlm@1
|
1999 break; \
|
rlm@1
|
2000 case BASE + 3: \
|
rlm@1
|
2001 { \
|
rlm@1
|
2002 /* OP Rd,Rb,Rm LSR Rs */ \
|
rlm@1
|
2003 clockTicks++; \
|
rlm@1
|
2004 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
2005 int shift = reg[(opcode >> 8) & 15].B.B0; \
|
rlm@1
|
2006 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
2007 u32 value; \
|
rlm@1
|
2008 if (shift) { \
|
rlm@1
|
2009 if (shift == 32) { \
|
rlm@1
|
2010 value = 0; \
|
rlm@1
|
2011 } else if (shift < 32) { \
|
rlm@1
|
2012 ARITHMETIC_LSR_REG \
|
rlm@1
|
2013 } else value = 0; \
|
rlm@1
|
2014 } else { \
|
rlm@1
|
2015 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
2016 } \
|
rlm@1
|
2017 if (dest == 15) { \
|
rlm@1
|
2018 OPCODE2 \
|
rlm@1
|
2019 /* todo */ \
|
rlm@1
|
2020 if (opcode & 0x00100000) { \
|
rlm@1
|
2021 clockTicks++; \
|
rlm@1
|
2022 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
2023 } \
|
rlm@1
|
2024 if (armState) { \
|
rlm@1
|
2025 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
2026 armNextPC = reg[15].I; \
|
rlm@1
|
2027 reg[15].I += 4; \
|
rlm@1
|
2028 } else { \
|
rlm@1
|
2029 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
2030 armNextPC = reg[15].I; \
|
rlm@1
|
2031 reg[15].I += 2; \
|
rlm@1
|
2032 } \
|
rlm@1
|
2033 } else { \
|
rlm@1
|
2034 OPCODE \
|
rlm@1
|
2035 } \
|
rlm@1
|
2036 } \
|
rlm@1
|
2037 break; \
|
rlm@1
|
2038 case BASE + 5: \
|
rlm@1
|
2039 { \
|
rlm@1
|
2040 /* OP Rd,Rb,Rm ASR Rs */ \
|
rlm@1
|
2041 clockTicks++; \
|
rlm@1
|
2042 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
2043 int shift = reg[(opcode >> 8) & 15].B.B0; \
|
rlm@1
|
2044 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
2045 u32 value; \
|
rlm@1
|
2046 if (shift < 32) { \
|
rlm@1
|
2047 if (shift) { \
|
rlm@1
|
2048 ARITHMETIC_ASR_REG \
|
rlm@1
|
2049 } else { \
|
rlm@1
|
2050 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
2051 } \
|
rlm@1
|
2052 } else { \
|
rlm@1
|
2053 if (reg[opcode & 0x0F].I & 0x80000000) { \
|
rlm@1
|
2054 value = 0xFFFFFFFF; \
|
rlm@1
|
2055 } else value = 0; \
|
rlm@1
|
2056 } \
|
rlm@1
|
2057 if (dest == 15) { \
|
rlm@1
|
2058 OPCODE2 \
|
rlm@1
|
2059 /* todo */ \
|
rlm@1
|
2060 if (opcode & 0x00100000) { \
|
rlm@1
|
2061 clockTicks++; \
|
rlm@1
|
2062 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
2063 } \
|
rlm@1
|
2064 if (armState) { \
|
rlm@1
|
2065 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
2066 armNextPC = reg[15].I; \
|
rlm@1
|
2067 reg[15].I += 4; \
|
rlm@1
|
2068 } else { \
|
rlm@1
|
2069 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
2070 armNextPC = reg[15].I; \
|
rlm@1
|
2071 reg[15].I += 2; \
|
rlm@1
|
2072 } \
|
rlm@1
|
2073 } else { \
|
rlm@1
|
2074 OPCODE \
|
rlm@1
|
2075 } \
|
rlm@1
|
2076 } \
|
rlm@1
|
2077 break; \
|
rlm@1
|
2078 case BASE + 7: \
|
rlm@1
|
2079 { \
|
rlm@1
|
2080 /* OP Rd,Rb,Rm ROR Rs */ \
|
rlm@1
|
2081 clockTicks++; \
|
rlm@1
|
2082 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
2083 int shift = reg[(opcode >> 8) & 15].B.B0; \
|
rlm@1
|
2084 int dest = (opcode >> 12) & 15; \
|
rlm@1
|
2085 u32 value; \
|
rlm@1
|
2086 if (shift) { \
|
rlm@1
|
2087 shift &= 0x1f; \
|
rlm@1
|
2088 if (shift) { \
|
rlm@1
|
2089 ARITHMETIC_ROR_REG \
|
rlm@1
|
2090 } else { \
|
rlm@1
|
2091 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
2092 } \
|
rlm@1
|
2093 } else { \
|
rlm@1
|
2094 value = reg[opcode & 0x0F].I; \
|
rlm@1
|
2095 } \
|
rlm@1
|
2096 if (dest == 15) { \
|
rlm@1
|
2097 OPCODE2 \
|
rlm@1
|
2098 /* todo */ \
|
rlm@1
|
2099 if (opcode & 0x00100000) { \
|
rlm@1
|
2100 clockTicks++; \
|
rlm@1
|
2101 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
2102 } \
|
rlm@1
|
2103 if (armState) { \
|
rlm@1
|
2104 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
2105 armNextPC = reg[15].I; \
|
rlm@1
|
2106 reg[15].I += 4; \
|
rlm@1
|
2107 } else { \
|
rlm@1
|
2108 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
2109 armNextPC = reg[15].I; \
|
rlm@1
|
2110 reg[15].I += 2; \
|
rlm@1
|
2111 } \
|
rlm@1
|
2112 } else { \
|
rlm@1
|
2113 OPCODE \
|
rlm@1
|
2114 } \
|
rlm@1
|
2115 } \
|
rlm@1
|
2116 break; \
|
rlm@1
|
2117 case BASE + 0x200: \
|
rlm@1
|
2118 case BASE + 0x201: \
|
rlm@1
|
2119 case BASE + 0x202: \
|
rlm@1
|
2120 case BASE + 0x203: \
|
rlm@1
|
2121 case BASE + 0x204: \
|
rlm@1
|
2122 case BASE + 0x205: \
|
rlm@1
|
2123 case BASE + 0x206: \
|
rlm@1
|
2124 case BASE + 0x207: \
|
rlm@1
|
2125 case BASE + 0x208: \
|
rlm@1
|
2126 case BASE + 0x209: \
|
rlm@1
|
2127 case BASE + 0x20a: \
|
rlm@1
|
2128 case BASE + 0x20b: \
|
rlm@1
|
2129 case BASE + 0x20c: \
|
rlm@1
|
2130 case BASE + 0x20d: \
|
rlm@1
|
2131 case BASE + 0x20e: \
|
rlm@1
|
2132 case BASE + 0x20f: \
|
rlm@1
|
2133 { \
|
rlm@1
|
2134 int shift = (opcode & 0xF00) >> 7; \
|
rlm@1
|
2135 int base = (opcode >> 16) & 0x0F; \
|
rlm@1
|
2136 int dest = (opcode >> 12) & 0x0F; \
|
rlm@1
|
2137 u32 value; \
|
rlm@1
|
2138 { \
|
rlm@1
|
2139 ARITHMETIC_ROR_IMM \
|
rlm@1
|
2140 } \
|
rlm@1
|
2141 if (dest == 15) { \
|
rlm@1
|
2142 OPCODE2 \
|
rlm@1
|
2143 /* todo */ \
|
rlm@1
|
2144 if (opcode & 0x00100000) { \
|
rlm@1
|
2145 clockTicks++; \
|
rlm@1
|
2146 CPUSwitchMode(reg[17].I & 0x1f, false); \
|
rlm@1
|
2147 } \
|
rlm@1
|
2148 if (armState) { \
|
rlm@1
|
2149 reg[15].I &= 0xFFFFFFFC; \
|
rlm@1
|
2150 armNextPC = reg[15].I; \
|
rlm@1
|
2151 reg[15].I += 4; \
|
rlm@1
|
2152 } else { \
|
rlm@1
|
2153 reg[15].I &= 0xFFFFFFFE; \
|
rlm@1
|
2154 armNextPC = reg[15].I; \
|
rlm@1
|
2155 reg[15].I += 2; \
|
rlm@1
|
2156 } \
|
rlm@1
|
2157 } else { \
|
rlm@1
|
2158 OPCODE \
|
rlm@1
|
2159 } \
|
rlm@1
|
2160 } \
|
rlm@1
|
2161 break;
|
rlm@1
|
2162
|
rlm@1
|
2163 u32 opcode = CPUReadMemoryQuick(armNextPC);
|
rlm@1
|
2164
|
rlm@1
|
2165 clockTicks = memoryWaitFetch32[(armNextPC >> 24) & 15];
|
rlm@1
|
2166
|
rlm@1
|
2167 #ifndef FINAL_VERSION
|
rlm@1
|
2168 if (armNextPC == stop)
|
rlm@1
|
2169 {
|
rlm@1
|
2170 armNextPC++;
|
rlm@1
|
2171 }
|
rlm@1
|
2172 #endif
|
rlm@1
|
2173
|
rlm@1
|
2174 armNextPC = reg[15].I;
|
rlm@1
|
2175 reg[15].I += 4;
|
rlm@1
|
2176 int cond = opcode >> 28;
|
rlm@1
|
2177 // suggested optimization for frequent cases
|
rlm@1
|
2178 bool cond_res;
|
rlm@1
|
2179 if (cond == 0x0e)
|
rlm@1
|
2180 {
|
rlm@1
|
2181 cond_res = true;
|
rlm@1
|
2182 }
|
rlm@1
|
2183 else
|
rlm@1
|
2184 {
|
rlm@1
|
2185 switch (cond)
|
rlm@1
|
2186 {
|
rlm@1
|
2187 case 0x00: // EQ
|
rlm@1
|
2188 cond_res = Z_FLAG;
|
rlm@1
|
2189 break;
|
rlm@1
|
2190 case 0x01: // NE
|
rlm@1
|
2191 cond_res = !Z_FLAG;
|
rlm@1
|
2192 break;
|
rlm@1
|
2193 case 0x02: // CS
|
rlm@1
|
2194 cond_res = C_FLAG;
|
rlm@1
|
2195 break;
|
rlm@1
|
2196 case 0x03: // CC
|
rlm@1
|
2197 cond_res = !C_FLAG;
|
rlm@1
|
2198 break;
|
rlm@1
|
2199 case 0x04: // MI
|
rlm@1
|
2200 cond_res = N_FLAG;
|
rlm@1
|
2201 break;
|
rlm@1
|
2202 case 0x05: // PL
|
rlm@1
|
2203 cond_res = !N_FLAG;
|
rlm@1
|
2204 break;
|
rlm@1
|
2205 case 0x06: // VS
|
rlm@1
|
2206 cond_res = V_FLAG;
|
rlm@1
|
2207 break;
|
rlm@1
|
2208 case 0x07: // VC
|
rlm@1
|
2209 cond_res = !V_FLAG;
|
rlm@1
|
2210 break;
|
rlm@1
|
2211 case 0x08: // HI
|
rlm@1
|
2212 cond_res = C_FLAG && !Z_FLAG;
|
rlm@1
|
2213 break;
|
rlm@1
|
2214 case 0x09: // LS
|
rlm@1
|
2215 cond_res = !C_FLAG || Z_FLAG;
|
rlm@1
|
2216 break;
|
rlm@1
|
2217 case 0x0A: // GE
|
rlm@1
|
2218 cond_res = N_FLAG == V_FLAG;
|
rlm@1
|
2219 break;
|
rlm@1
|
2220 case 0x0B: // LT
|
rlm@1
|
2221 cond_res = N_FLAG != V_FLAG;
|
rlm@1
|
2222 break;
|
rlm@1
|
2223 case 0x0C: // GT
|
rlm@1
|
2224 cond_res = !Z_FLAG && (N_FLAG == V_FLAG);
|
rlm@1
|
2225 break;
|
rlm@1
|
2226 case 0x0D: // LE
|
rlm@1
|
2227 cond_res = Z_FLAG || (N_FLAG != V_FLAG);
|
rlm@1
|
2228 break;
|
rlm@1
|
2229 case 0x0E:
|
rlm@1
|
2230 cond_res = true;
|
rlm@1
|
2231 break;
|
rlm@1
|
2232 case 0x0F:
|
rlm@1
|
2233 default:
|
rlm@1
|
2234 // ???
|
rlm@1
|
2235 cond_res = false;
|
rlm@1
|
2236 break;
|
rlm@1
|
2237 }
|
rlm@1
|
2238 }
|
rlm@1
|
2239
|
rlm@1
|
2240 if (cond_res)
|
rlm@1
|
2241 {
|
rlm@1
|
2242 switch (((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x0F))
|
rlm@1
|
2243 {
|
rlm@1
|
2244 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_AND, OP_AND, 0x000);
|
rlm@1
|
2245 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_ANDS, OP_AND, 0x010);
|
rlm@1
|
2246 case 0x009:
|
rlm@1
|
2247 {
|
rlm@1
|
2248 // MUL Rd, Rm, Rs
|
rlm@1
|
2249 int dest = (opcode >> 16) & 0x0F;
|
rlm@1
|
2250 int mult = (opcode & 0x0F);
|
rlm@1
|
2251 u32 rs = reg[(opcode >> 8) & 0x0F].I;
|
rlm@1
|
2252 reg[dest].I = reg[mult].I * rs;
|
rlm@1
|
2253 if (((s32)rs) < 0)
|
rlm@1
|
2254 rs = ~rs;
|
rlm@1
|
2255 if ((rs & 0xFFFFFF00) == 0)
|
rlm@1
|
2256 clockTicks += 2;
|
rlm@1
|
2257 else if ((rs & 0xFFFF0000) == 0)
|
rlm@1
|
2258 clockTicks += 3;
|
rlm@1
|
2259 else if ((rs & 0xFF000000) == 0)
|
rlm@1
|
2260 clockTicks += 4;
|
rlm@1
|
2261 else
|
rlm@1
|
2262 clockTicks += 5;
|
rlm@1
|
2263 }
|
rlm@1
|
2264 break;
|
rlm@1
|
2265 case 0x019:
|
rlm@1
|
2266 {
|
rlm@1
|
2267 // MULS Rd, Rm, Rs
|
rlm@1
|
2268 int dest = (opcode >> 16) & 0x0F;
|
rlm@1
|
2269 int mult = (opcode & 0x0F);
|
rlm@1
|
2270 u32 rs = reg[(opcode >> 8) & 0x0F].I;
|
rlm@1
|
2271 reg[dest].I = reg[mult].I * rs;
|
rlm@1
|
2272 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;
|
rlm@1
|
2273 Z_FLAG = (reg[dest].I) ? false : true;
|
rlm@1
|
2274 if (((s32)rs) < 0)
|
rlm@1
|
2275 rs = ~rs;
|
rlm@1
|
2276 if ((rs & 0xFFFFFF00) == 0)
|
rlm@1
|
2277 clockTicks += 2;
|
rlm@1
|
2278 else if ((rs & 0xFFFF0000) == 0)
|
rlm@1
|
2279 clockTicks += 3;
|
rlm@1
|
2280 else if ((rs & 0xFF000000) == 0)
|
rlm@1
|
2281 clockTicks += 4;
|
rlm@1
|
2282 else
|
rlm@1
|
2283 clockTicks += 5;
|
rlm@1
|
2284 }
|
rlm@1
|
2285 break;
|
rlm@1
|
2286 case 0x00b:
|
rlm@1
|
2287 case 0x02b:
|
rlm@1
|
2288 {
|
rlm@1
|
2289 // STRH Rd, [Rn], -Rm
|
rlm@1
|
2290 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2291 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2292 u32 address = reg[base].I;
|
rlm@1
|
2293 int offset = reg[opcode & 0x0F].I;
|
rlm@1
|
2294 clockTicks += 4 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2295 CPUWriteHalfWord(address, reg[dest].W.W0);
|
rlm@1
|
2296 address -= offset;
|
rlm@1
|
2297 reg[base].I = address;
|
rlm@1
|
2298 }
|
rlm@1
|
2299 break;
|
rlm@1
|
2300 case 0x04b:
|
rlm@1
|
2301 case 0x06b:
|
rlm@1
|
2302 {
|
rlm@1
|
2303 // STRH Rd, [Rn], #-offset
|
rlm@1
|
2304 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2305 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2306 u32 address = reg[base].I;
|
rlm@1
|
2307 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
|
rlm@1
|
2308 clockTicks += 4 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2309 CPUWriteHalfWord(address, reg[dest].W.W0);
|
rlm@1
|
2310 address -= offset;
|
rlm@1
|
2311 reg[base].I = address;
|
rlm@1
|
2312 }
|
rlm@1
|
2313 break;
|
rlm@1
|
2314 case 0x08b:
|
rlm@1
|
2315 case 0x0ab:
|
rlm@1
|
2316 {
|
rlm@1
|
2317 // STRH Rd, [Rn], Rm
|
rlm@1
|
2318 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2319 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2320 u32 address = reg[base].I;
|
rlm@1
|
2321 int offset = reg[opcode & 0x0F].I;
|
rlm@1
|
2322 clockTicks += 4 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2323 CPUWriteHalfWord(address, reg[dest].W.W0);
|
rlm@1
|
2324 address += offset;
|
rlm@1
|
2325 reg[base].I = address;
|
rlm@1
|
2326 }
|
rlm@1
|
2327 break;
|
rlm@1
|
2328 case 0x0cb:
|
rlm@1
|
2329 case 0x0eb:
|
rlm@1
|
2330 {
|
rlm@1
|
2331 // STRH Rd, [Rn], #offset
|
rlm@1
|
2332 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2333 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2334 u32 address = reg[base].I;
|
rlm@1
|
2335 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
|
rlm@1
|
2336 clockTicks += 4 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2337 CPUWriteHalfWord(address, reg[dest].W.W0);
|
rlm@1
|
2338 address += offset;
|
rlm@1
|
2339 reg[base].I = address;
|
rlm@1
|
2340 }
|
rlm@1
|
2341 break;
|
rlm@1
|
2342 case 0x10b:
|
rlm@1
|
2343 {
|
rlm@1
|
2344 // STRH Rd, [Rn, -Rm]
|
rlm@1
|
2345 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2346 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2347 u32 address = reg[base].I - reg[opcode & 0x0F].I;
|
rlm@1
|
2348 clockTicks += 4 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2349 CPUWriteHalfWord(address, reg[dest].W.W0);
|
rlm@1
|
2350 }
|
rlm@1
|
2351 break;
|
rlm@1
|
2352 case 0x12b:
|
rlm@1
|
2353 {
|
rlm@1
|
2354 // STRH Rd, [Rn, -Rm]!
|
rlm@1
|
2355 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2356 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2357 u32 address = reg[base].I - reg[opcode & 0x0F].I;
|
rlm@1
|
2358 clockTicks += 4 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2359 CPUWriteHalfWord(address, reg[dest].W.W0);
|
rlm@1
|
2360 reg[base].I = address;
|
rlm@1
|
2361 }
|
rlm@1
|
2362 break;
|
rlm@1
|
2363 case 0x14b:
|
rlm@1
|
2364 {
|
rlm@1
|
2365 // STRH Rd, [Rn, -#offset]
|
rlm@1
|
2366 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2367 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2368 u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2369 clockTicks += 4 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2370 CPUWriteHalfWord(address, reg[dest].W.W0);
|
rlm@1
|
2371 }
|
rlm@1
|
2372 break;
|
rlm@1
|
2373 case 0x16b:
|
rlm@1
|
2374 {
|
rlm@1
|
2375 // STRH Rd, [Rn, -#offset]!
|
rlm@1
|
2376 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2377 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2378 u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2379 clockTicks += 4 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2380 CPUWriteHalfWord(address, reg[dest].W.W0);
|
rlm@1
|
2381 reg[base].I = address;
|
rlm@1
|
2382 }
|
rlm@1
|
2383 break;
|
rlm@1
|
2384 case 0x18b:
|
rlm@1
|
2385 {
|
rlm@1
|
2386 // STRH Rd, [Rn, Rm]
|
rlm@1
|
2387 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2388 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2389 u32 address = reg[base].I + reg[opcode & 0x0F].I;
|
rlm@1
|
2390 clockTicks += 4 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2391 CPUWriteHalfWord(address, reg[dest].W.W0);
|
rlm@1
|
2392 }
|
rlm@1
|
2393 break;
|
rlm@1
|
2394 case 0x1ab:
|
rlm@1
|
2395 {
|
rlm@1
|
2396 // STRH Rd, [Rn, Rm]!
|
rlm@1
|
2397 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2398 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2399 u32 address = reg[base].I + reg[opcode & 0x0F].I;
|
rlm@1
|
2400 clockTicks += 4 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2401 CPUWriteHalfWord(address, reg[dest].W.W0);
|
rlm@1
|
2402 reg[base].I = address;
|
rlm@1
|
2403 }
|
rlm@1
|
2404 break;
|
rlm@1
|
2405 case 0x1cb:
|
rlm@1
|
2406 {
|
rlm@1
|
2407 // STRH Rd, [Rn, #offset]
|
rlm@1
|
2408 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2409 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2410 u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2411 clockTicks += 4 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2412 CPUWriteHalfWord(address, reg[dest].W.W0);
|
rlm@1
|
2413 }
|
rlm@1
|
2414 break;
|
rlm@1
|
2415 case 0x1eb:
|
rlm@1
|
2416 {
|
rlm@1
|
2417 // STRH Rd, [Rn, #offset]!
|
rlm@1
|
2418 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2419 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2420 u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2421 clockTicks += 4 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2422 CPUWriteHalfWord(address, reg[dest].W.W0);
|
rlm@1
|
2423 reg[base].I = address;
|
rlm@1
|
2424 }
|
rlm@1
|
2425 break;
|
rlm@1
|
2426 case 0x01b:
|
rlm@1
|
2427 case 0x03b:
|
rlm@1
|
2428 {
|
rlm@1
|
2429 // LDRH Rd, [Rn], -Rm
|
rlm@1
|
2430 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2431 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2432 u32 address = reg[base].I;
|
rlm@1
|
2433 int offset = reg[opcode & 0x0F].I;
|
rlm@1
|
2434 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2435 reg[dest].I = CPUReadHalfWord(address);
|
rlm@1
|
2436 if (dest != base)
|
rlm@1
|
2437 {
|
rlm@1
|
2438 address -= offset;
|
rlm@1
|
2439 reg[base].I = address;
|
rlm@1
|
2440 }
|
rlm@1
|
2441 }
|
rlm@1
|
2442 break;
|
rlm@1
|
2443 case 0x05b:
|
rlm@1
|
2444 case 0x07b:
|
rlm@1
|
2445 {
|
rlm@1
|
2446 // LDRH Rd, [Rn], #-offset
|
rlm@1
|
2447 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2448 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2449 u32 address = reg[base].I;
|
rlm@1
|
2450 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
|
rlm@1
|
2451 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2452 reg[dest].I = CPUReadHalfWord(address);
|
rlm@1
|
2453 if (dest != base)
|
rlm@1
|
2454 {
|
rlm@1
|
2455 address -= offset;
|
rlm@1
|
2456 reg[base].I = address;
|
rlm@1
|
2457 }
|
rlm@1
|
2458 }
|
rlm@1
|
2459 break;
|
rlm@1
|
2460 case 0x09b:
|
rlm@1
|
2461 case 0x0bb:
|
rlm@1
|
2462 {
|
rlm@1
|
2463 // LDRH Rd, [Rn], Rm
|
rlm@1
|
2464 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2465 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2466 u32 address = reg[base].I;
|
rlm@1
|
2467 int offset = reg[opcode & 0x0F].I;
|
rlm@1
|
2468 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2469 reg[dest].I = CPUReadHalfWord(address);
|
rlm@1
|
2470 if (dest != base)
|
rlm@1
|
2471 {
|
rlm@1
|
2472 address += offset;
|
rlm@1
|
2473 reg[base].I = address;
|
rlm@1
|
2474 }
|
rlm@1
|
2475 }
|
rlm@1
|
2476 break;
|
rlm@1
|
2477 case 0x0db:
|
rlm@1
|
2478 case 0x0fb:
|
rlm@1
|
2479 {
|
rlm@1
|
2480 // LDRH Rd, [Rn], #offset
|
rlm@1
|
2481 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2482 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2483 u32 address = reg[base].I;
|
rlm@1
|
2484 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
|
rlm@1
|
2485 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2486 reg[dest].I = CPUReadHalfWord(address);
|
rlm@1
|
2487 if (dest != base)
|
rlm@1
|
2488 {
|
rlm@1
|
2489 address += offset;
|
rlm@1
|
2490 reg[base].I = address;
|
rlm@1
|
2491 }
|
rlm@1
|
2492 }
|
rlm@1
|
2493 break;
|
rlm@1
|
2494 case 0x11b:
|
rlm@1
|
2495 {
|
rlm@1
|
2496 // LDRH Rd, [Rn, -Rm]
|
rlm@1
|
2497 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2498 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2499 u32 address = reg[base].I - reg[opcode & 0x0F].I;
|
rlm@1
|
2500 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2501 reg[dest].I = CPUReadHalfWord(address);
|
rlm@1
|
2502 }
|
rlm@1
|
2503 break;
|
rlm@1
|
2504 case 0x13b:
|
rlm@1
|
2505 {
|
rlm@1
|
2506 // LDRH Rd, [Rn, -Rm]!
|
rlm@1
|
2507 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2508 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2509 u32 address = reg[base].I - reg[opcode & 0x0F].I;
|
rlm@1
|
2510 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2511 reg[dest].I = CPUReadHalfWord(address);
|
rlm@1
|
2512 if (dest != base)
|
rlm@1
|
2513 reg[base].I = address;
|
rlm@1
|
2514 }
|
rlm@1
|
2515 break;
|
rlm@1
|
2516 case 0x15b:
|
rlm@1
|
2517 {
|
rlm@1
|
2518 // LDRH Rd, [Rn, -#offset]
|
rlm@1
|
2519 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2520 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2521 u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2522 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2523 reg[dest].I = CPUReadHalfWord(address);
|
rlm@1
|
2524 }
|
rlm@1
|
2525 break;
|
rlm@1
|
2526 case 0x17b:
|
rlm@1
|
2527 {
|
rlm@1
|
2528 // LDRH Rd, [Rn, -#offset]!
|
rlm@1
|
2529 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2530 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2531 u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2532 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2533 reg[dest].I = CPUReadHalfWord(address);
|
rlm@1
|
2534 if (dest != base)
|
rlm@1
|
2535 reg[base].I = address;
|
rlm@1
|
2536 }
|
rlm@1
|
2537 break;
|
rlm@1
|
2538 case 0x19b:
|
rlm@1
|
2539 {
|
rlm@1
|
2540 // LDRH Rd, [Rn, Rm]
|
rlm@1
|
2541 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2542 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2543 u32 address = reg[base].I + reg[opcode & 0x0F].I;
|
rlm@1
|
2544 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2545 reg[dest].I = CPUReadHalfWord(address);
|
rlm@1
|
2546 }
|
rlm@1
|
2547 break;
|
rlm@1
|
2548 case 0x1bb:
|
rlm@1
|
2549 {
|
rlm@1
|
2550 // LDRH Rd, [Rn, Rm]!
|
rlm@1
|
2551 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2552 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2553 u32 address = reg[base].I + reg[opcode & 0x0F].I;
|
rlm@1
|
2554 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2555 reg[dest].I = CPUReadHalfWord(address);
|
rlm@1
|
2556 if (dest != base)
|
rlm@1
|
2557 reg[base].I = address;
|
rlm@1
|
2558 }
|
rlm@1
|
2559 break;
|
rlm@1
|
2560 case 0x1db:
|
rlm@1
|
2561 {
|
rlm@1
|
2562 // LDRH Rd, [Rn, #offset]
|
rlm@1
|
2563 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2564 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2565 u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2566 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2567 reg[dest].I = CPUReadHalfWord(address);
|
rlm@1
|
2568 }
|
rlm@1
|
2569 break;
|
rlm@1
|
2570 case 0x1fb:
|
rlm@1
|
2571 {
|
rlm@1
|
2572 // LDRH Rd, [Rn, #offset]!
|
rlm@1
|
2573 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2574 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2575 u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2576 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2577 reg[dest].I = CPUReadHalfWord(address);
|
rlm@1
|
2578 if (dest != base)
|
rlm@1
|
2579 reg[base].I = address;
|
rlm@1
|
2580 }
|
rlm@1
|
2581 break;
|
rlm@1
|
2582 case 0x01d:
|
rlm@1
|
2583 case 0x03d:
|
rlm@1
|
2584 {
|
rlm@1
|
2585 // LDRSB Rd, [Rn], -Rm
|
rlm@1
|
2586 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2587 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2588 u32 address = reg[base].I;
|
rlm@1
|
2589 int offset = reg[opcode & 0x0F].I;
|
rlm@1
|
2590 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2591 reg[dest].I = (s8)CPUReadByte(address);
|
rlm@1
|
2592 if (dest != base)
|
rlm@1
|
2593 {
|
rlm@1
|
2594 address -= offset;
|
rlm@1
|
2595 reg[base].I = address;
|
rlm@1
|
2596 }
|
rlm@1
|
2597 }
|
rlm@1
|
2598 break;
|
rlm@1
|
2599 case 0x05d:
|
rlm@1
|
2600 case 0x07d:
|
rlm@1
|
2601 {
|
rlm@1
|
2602 // LDRSB Rd, [Rn], #-offset
|
rlm@1
|
2603 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2604 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2605 u32 address = reg[base].I;
|
rlm@1
|
2606 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
|
rlm@1
|
2607 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2608 reg[dest].I = (s8)CPUReadByte(address);
|
rlm@1
|
2609 if (dest != base)
|
rlm@1
|
2610 {
|
rlm@1
|
2611 address -= offset;
|
rlm@1
|
2612 reg[base].I = address;
|
rlm@1
|
2613 }
|
rlm@1
|
2614 }
|
rlm@1
|
2615 break;
|
rlm@1
|
2616 case 0x09d:
|
rlm@1
|
2617 case 0x0bd:
|
rlm@1
|
2618 {
|
rlm@1
|
2619 // LDRSB Rd, [Rn], Rm
|
rlm@1
|
2620 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2621 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2622 u32 address = reg[base].I;
|
rlm@1
|
2623 int offset = reg[opcode & 0x0F].I;
|
rlm@1
|
2624 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2625 reg[dest].I = (s8)CPUReadByte(address);
|
rlm@1
|
2626 if (dest != base)
|
rlm@1
|
2627 {
|
rlm@1
|
2628 address += offset;
|
rlm@1
|
2629 reg[base].I = address;
|
rlm@1
|
2630 }
|
rlm@1
|
2631 }
|
rlm@1
|
2632 break;
|
rlm@1
|
2633 case 0x0dd:
|
rlm@1
|
2634 case 0x0fd:
|
rlm@1
|
2635 {
|
rlm@1
|
2636 // LDRSB Rd, [Rn], #offset
|
rlm@1
|
2637 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2638 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2639 u32 address = reg[base].I;
|
rlm@1
|
2640 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
|
rlm@1
|
2641 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2642 reg[dest].I = (s8)CPUReadByte(address);
|
rlm@1
|
2643 if (dest != base)
|
rlm@1
|
2644 {
|
rlm@1
|
2645 address += offset;
|
rlm@1
|
2646 reg[base].I = address;
|
rlm@1
|
2647 }
|
rlm@1
|
2648 }
|
rlm@1
|
2649 break;
|
rlm@1
|
2650 case 0x11d:
|
rlm@1
|
2651 {
|
rlm@1
|
2652 // LDRSB Rd, [Rn, -Rm]
|
rlm@1
|
2653 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2654 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2655 u32 address = reg[base].I - reg[opcode & 0x0F].I;
|
rlm@1
|
2656 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2657 reg[dest].I = (s8)CPUReadByte(address);
|
rlm@1
|
2658 }
|
rlm@1
|
2659 break;
|
rlm@1
|
2660 case 0x13d:
|
rlm@1
|
2661 {
|
rlm@1
|
2662 // LDRSB Rd, [Rn, -Rm]!
|
rlm@1
|
2663 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2664 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2665 u32 address = reg[base].I - reg[opcode & 0x0F].I;
|
rlm@1
|
2666 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2667 reg[dest].I = (s8)CPUReadByte(address);
|
rlm@1
|
2668 if (dest != base)
|
rlm@1
|
2669 reg[base].I = address;
|
rlm@1
|
2670 }
|
rlm@1
|
2671 break;
|
rlm@1
|
2672 case 0x15d:
|
rlm@1
|
2673 {
|
rlm@1
|
2674 // LDRSB Rd, [Rn, -#offset]
|
rlm@1
|
2675 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2676 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2677 u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2678 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2679 reg[dest].I = (s8)CPUReadByte(address);
|
rlm@1
|
2680 }
|
rlm@1
|
2681 break;
|
rlm@1
|
2682 case 0x17d:
|
rlm@1
|
2683 {
|
rlm@1
|
2684 // LDRSB Rd, [Rn, -#offset]!
|
rlm@1
|
2685 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2686 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2687 u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2688 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2689 reg[dest].I = (s8)CPUReadByte(address);
|
rlm@1
|
2690 if (dest != base)
|
rlm@1
|
2691 reg[base].I = address;
|
rlm@1
|
2692 }
|
rlm@1
|
2693 break;
|
rlm@1
|
2694 case 0x19d:
|
rlm@1
|
2695 {
|
rlm@1
|
2696 // LDRSB Rd, [Rn, Rm]
|
rlm@1
|
2697 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2698 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2699 u32 address = reg[base].I + reg[opcode & 0x0F].I;
|
rlm@1
|
2700 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2701 reg[dest].I = (s8)CPUReadByte(address);
|
rlm@1
|
2702 }
|
rlm@1
|
2703 break;
|
rlm@1
|
2704 case 0x1bd:
|
rlm@1
|
2705 {
|
rlm@1
|
2706 // LDRSB Rd, [Rn, Rm]!
|
rlm@1
|
2707 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2708 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2709 u32 address = reg[base].I + reg[opcode & 0x0F].I;
|
rlm@1
|
2710 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2711 reg[dest].I = (s8)CPUReadByte(address);
|
rlm@1
|
2712 if (dest != base)
|
rlm@1
|
2713 reg[base].I = address;
|
rlm@1
|
2714 }
|
rlm@1
|
2715 break;
|
rlm@1
|
2716 case 0x1dd:
|
rlm@1
|
2717 {
|
rlm@1
|
2718 // LDRSB Rd, [Rn, #offset]
|
rlm@1
|
2719 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2720 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2721 u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2722 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2723 reg[dest].I = (s8)CPUReadByte(address);
|
rlm@1
|
2724 }
|
rlm@1
|
2725 break;
|
rlm@1
|
2726 case 0x1fd:
|
rlm@1
|
2727 {
|
rlm@1
|
2728 // LDRSB Rd, [Rn, #offset]!
|
rlm@1
|
2729 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2730 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2731 u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2732 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2733 reg[dest].I = (s8)CPUReadByte(address);
|
rlm@1
|
2734 if (dest != base)
|
rlm@1
|
2735 reg[base].I = address;
|
rlm@1
|
2736 }
|
rlm@1
|
2737 break;
|
rlm@1
|
2738 case 0x01f:
|
rlm@1
|
2739 case 0x03f:
|
rlm@1
|
2740 {
|
rlm@1
|
2741 // LDRSH Rd, [Rn], -Rm
|
rlm@1
|
2742 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2743 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2744 u32 address = reg[base].I;
|
rlm@1
|
2745 int offset = reg[opcode & 0x0F].I;
|
rlm@1
|
2746 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2747 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
|
rlm@1
|
2748 if (dest != base)
|
rlm@1
|
2749 {
|
rlm@1
|
2750 address -= offset;
|
rlm@1
|
2751 reg[base].I = address;
|
rlm@1
|
2752 }
|
rlm@1
|
2753 }
|
rlm@1
|
2754 break;
|
rlm@1
|
2755 case 0x05f:
|
rlm@1
|
2756 case 0x07f:
|
rlm@1
|
2757 {
|
rlm@1
|
2758 // LDRSH Rd, [Rn], #-offset
|
rlm@1
|
2759 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2760 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2761 u32 address = reg[base].I;
|
rlm@1
|
2762 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
|
rlm@1
|
2763 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2764 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
|
rlm@1
|
2765 if (dest != base)
|
rlm@1
|
2766 {
|
rlm@1
|
2767 address -= offset;
|
rlm@1
|
2768 reg[base].I = address;
|
rlm@1
|
2769 }
|
rlm@1
|
2770 }
|
rlm@1
|
2771 break;
|
rlm@1
|
2772 case 0x09f:
|
rlm@1
|
2773 case 0x0bf:
|
rlm@1
|
2774 {
|
rlm@1
|
2775 // LDRSH Rd, [Rn], Rm
|
rlm@1
|
2776 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2777 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2778 u32 address = reg[base].I;
|
rlm@1
|
2779 int offset = reg[opcode & 0x0F].I;
|
rlm@1
|
2780 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2781 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
|
rlm@1
|
2782 if (dest != base)
|
rlm@1
|
2783 {
|
rlm@1
|
2784 address += offset;
|
rlm@1
|
2785 reg[base].I = address;
|
rlm@1
|
2786 }
|
rlm@1
|
2787 }
|
rlm@1
|
2788 break;
|
rlm@1
|
2789 case 0x0df:
|
rlm@1
|
2790 case 0x0ff:
|
rlm@1
|
2791 {
|
rlm@1
|
2792 // LDRSH Rd, [Rn], #offset
|
rlm@1
|
2793 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2794 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2795 u32 address = reg[base].I;
|
rlm@1
|
2796 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
|
rlm@1
|
2797 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2798 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
|
rlm@1
|
2799 if (dest != base)
|
rlm@1
|
2800 {
|
rlm@1
|
2801 address += offset;
|
rlm@1
|
2802 reg[base].I = address;
|
rlm@1
|
2803 }
|
rlm@1
|
2804 }
|
rlm@1
|
2805 break;
|
rlm@1
|
2806 case 0x11f:
|
rlm@1
|
2807 {
|
rlm@1
|
2808 // LDRSH Rd, [Rn, -Rm]
|
rlm@1
|
2809 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2810 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2811 u32 address = reg[base].I - reg[opcode & 0x0F].I;
|
rlm@1
|
2812 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2813 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
|
rlm@1
|
2814 }
|
rlm@1
|
2815 break;
|
rlm@1
|
2816 case 0x13f:
|
rlm@1
|
2817 {
|
rlm@1
|
2818 // LDRSH Rd, [Rn, -Rm]!
|
rlm@1
|
2819 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2820 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2821 u32 address = reg[base].I - reg[opcode & 0x0F].I;
|
rlm@1
|
2822 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2823 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
|
rlm@1
|
2824 if (dest != base)
|
rlm@1
|
2825 reg[base].I = address;
|
rlm@1
|
2826 }
|
rlm@1
|
2827 break;
|
rlm@1
|
2828 case 0x15f:
|
rlm@1
|
2829 {
|
rlm@1
|
2830 // LDRSH Rd, [Rn, -#offset]
|
rlm@1
|
2831 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2832 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2833 u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2834 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2835 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
|
rlm@1
|
2836 }
|
rlm@1
|
2837 break;
|
rlm@1
|
2838 case 0x17f:
|
rlm@1
|
2839 {
|
rlm@1
|
2840 // LDRSH Rd, [Rn, -#offset]!
|
rlm@1
|
2841 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2842 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2843 u32 address = reg[base].I - ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2844 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2845 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
|
rlm@1
|
2846 if (dest != base)
|
rlm@1
|
2847 reg[base].I = address;
|
rlm@1
|
2848 }
|
rlm@1
|
2849 break;
|
rlm@1
|
2850 case 0x19f:
|
rlm@1
|
2851 {
|
rlm@1
|
2852 // LDRSH Rd, [Rn, Rm]
|
rlm@1
|
2853 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2854 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2855 u32 address = reg[base].I + reg[opcode & 0x0F].I;
|
rlm@1
|
2856 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2857 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
|
rlm@1
|
2858 }
|
rlm@1
|
2859 break;
|
rlm@1
|
2860 case 0x1bf:
|
rlm@1
|
2861 {
|
rlm@1
|
2862 // LDRSH Rd, [Rn, Rm]!
|
rlm@1
|
2863 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2864 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2865 u32 address = reg[base].I + reg[opcode & 0x0F].I;
|
rlm@1
|
2866 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2867 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
|
rlm@1
|
2868 if (dest != base)
|
rlm@1
|
2869 reg[base].I = address;
|
rlm@1
|
2870 }
|
rlm@1
|
2871 break;
|
rlm@1
|
2872 case 0x1df:
|
rlm@1
|
2873 {
|
rlm@1
|
2874 // LDRSH Rd, [Rn, #offset]
|
rlm@1
|
2875 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2876 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2877 u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2878 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2879 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
|
rlm@1
|
2880 }
|
rlm@1
|
2881 break;
|
rlm@1
|
2882 case 0x1ff:
|
rlm@1
|
2883 {
|
rlm@1
|
2884 // LDRSH Rd, [Rn, #offset]!
|
rlm@1
|
2885 int base = (opcode >> 16) & 0x0F;
|
rlm@1
|
2886 int dest = (opcode >> 12) & 0x0F;
|
rlm@1
|
2887 u32 address = reg[base].I + ((opcode & 0x0F) | ((opcode >> 4) & 0xF0));
|
rlm@1
|
2888 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
2889 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
|
rlm@1
|
2890 if (dest != base)
|
rlm@1
|
2891 reg[base].I = address;
|
rlm@1
|
2892 }
|
rlm@1
|
2893 break;
|
rlm@1
|
2894 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_EOR, OP_EOR, 0x020);
|
rlm@1
|
2895 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_EORS, OP_EOR, 0x030);
|
rlm@1
|
2896 case 0x029:
|
rlm@1
|
2897 {
|
rlm@1
|
2898 // MLA Rd, Rm, Rs, Rn
|
rlm@1
|
2899 int dest = (opcode >> 16) & 0x0F;
|
rlm@1
|
2900 int mult = (opcode & 0x0F);
|
rlm@1
|
2901 u32 rs = reg[(opcode >> 8) & 0x0F].I;
|
rlm@1
|
2902 reg[dest].I = reg[mult].I * rs + reg[(opcode >> 12) & 0x0f].I;
|
rlm@1
|
2903 if (((s32)rs) < 0)
|
rlm@1
|
2904 rs = ~rs;
|
rlm@1
|
2905 if ((rs & 0xFFFFFF00) == 0)
|
rlm@1
|
2906 clockTicks += 3;
|
rlm@1
|
2907 else if ((rs & 0xFFFF0000) == 0)
|
rlm@1
|
2908 clockTicks += 4;
|
rlm@1
|
2909 else if ((rs & 0xFF000000) == 0)
|
rlm@1
|
2910 clockTicks += 5;
|
rlm@1
|
2911 else
|
rlm@1
|
2912 clockTicks += 6;
|
rlm@1
|
2913 }
|
rlm@1
|
2914 break;
|
rlm@1
|
2915 case 0x039:
|
rlm@1
|
2916 {
|
rlm@1
|
2917 // MLAS Rd, Rm, Rs, Rn
|
rlm@1
|
2918 int dest = (opcode >> 16) & 0x0F;
|
rlm@1
|
2919 int mult = (opcode & 0x0F);
|
rlm@1
|
2920 u32 rs = reg[(opcode >> 8) & 0x0F].I;
|
rlm@1
|
2921 reg[dest].I = reg[mult].I * rs + reg[(opcode >> 12) & 0x0f].I;
|
rlm@1
|
2922 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;
|
rlm@1
|
2923 Z_FLAG = (reg[dest].I) ? false : true;
|
rlm@1
|
2924 if (((s32)rs) < 0)
|
rlm@1
|
2925 rs = ~rs;
|
rlm@1
|
2926 if ((rs & 0xFFFFFF00) == 0)
|
rlm@1
|
2927 clockTicks += 3;
|
rlm@1
|
2928 else if ((rs & 0xFFFF0000) == 0)
|
rlm@1
|
2929 clockTicks += 4;
|
rlm@1
|
2930 else if ((rs & 0xFF000000) == 0)
|
rlm@1
|
2931 clockTicks += 5;
|
rlm@1
|
2932 else
|
rlm@1
|
2933 clockTicks += 6;
|
rlm@1
|
2934 }
|
rlm@1
|
2935 break;
|
rlm@1
|
2936 ARITHMETIC_DATA_OPCODE(OP_SUB, OP_SUB, 0x040);
|
rlm@1
|
2937 ARITHMETIC_DATA_OPCODE(OP_SUBS, OP_SUB, 0x050);
|
rlm@1
|
2938 ARITHMETIC_DATA_OPCODE(OP_RSB, OP_RSB, 0x060);
|
rlm@1
|
2939 ARITHMETIC_DATA_OPCODE(OP_RSBS, OP_RSB, 0x070);
|
rlm@1
|
2940 ARITHMETIC_DATA_OPCODE(OP_ADD, OP_ADD, 0x080);
|
rlm@1
|
2941 ARITHMETIC_DATA_OPCODE(OP_ADDS, OP_ADD, 0x090);
|
rlm@1
|
2942 case 0x089:
|
rlm@1
|
2943 {
|
rlm@1
|
2944 // UMULL RdLo, RdHi, Rn, Rs
|
rlm@1
|
2945 u32 umult = reg[(opcode & 0x0F)].I;
|
rlm@1
|
2946 u32 usource = reg[(opcode >> 8) & 0x0F].I;
|
rlm@1
|
2947 int destLo = (opcode >> 12) & 0x0F;
|
rlm@1
|
2948 int destHi = (opcode >> 16) & 0x0F;
|
rlm@1
|
2949 u64 uTemp = ((u64)umult) * ((u64)usource);
|
rlm@1
|
2950 reg[destLo].I = (u32)(uTemp & 0xFFFFFFFF);
|
rlm@1
|
2951 reg[destHi].I = (u32)(uTemp >> 32);
|
rlm@1
|
2952 if ((usource & 0xFFFFFF00) == 0)
|
rlm@1
|
2953 clockTicks += 2;
|
rlm@1
|
2954 else if ((usource & 0xFFFF0000) == 0)
|
rlm@1
|
2955 clockTicks += 3;
|
rlm@1
|
2956 else if ((usource & 0xFF000000) == 0)
|
rlm@1
|
2957 clockTicks += 4;
|
rlm@1
|
2958 else
|
rlm@1
|
2959 clockTicks += 5;
|
rlm@1
|
2960 }
|
rlm@1
|
2961 break;
|
rlm@1
|
2962 case 0x099:
|
rlm@1
|
2963 {
|
rlm@1
|
2964 // UMULLS RdLo, RdHi, Rn, Rs
|
rlm@1
|
2965 u32 umult = reg[(opcode & 0x0F)].I;
|
rlm@1
|
2966 u32 usource = reg[(opcode >> 8) & 0x0F].I;
|
rlm@1
|
2967 int destLo = (opcode >> 12) & 0x0F;
|
rlm@1
|
2968 int destHi = (opcode >> 16) & 0x0F;
|
rlm@1
|
2969 u64 uTemp = ((u64)umult) * ((u64)usource);
|
rlm@1
|
2970 reg[destLo].I = (u32)(uTemp & 0xFFFFFFFF);
|
rlm@1
|
2971 reg[destHi].I = (u32)(uTemp >> 32);
|
rlm@1
|
2972 Z_FLAG = (uTemp) ? false : true;
|
rlm@1
|
2973 N_FLAG = (reg[destHi].I & 0x80000000) ? true : false;
|
rlm@1
|
2974 if ((usource & 0xFFFFFF00) == 0)
|
rlm@1
|
2975 clockTicks += 2;
|
rlm@1
|
2976 else if ((usource & 0xFFFF0000) == 0)
|
rlm@1
|
2977 clockTicks += 3;
|
rlm@1
|
2978 else if ((usource & 0xFF000000) == 0)
|
rlm@1
|
2979 clockTicks += 4;
|
rlm@1
|
2980 else
|
rlm@1
|
2981 clockTicks += 5;
|
rlm@1
|
2982 }
|
rlm@1
|
2983 break;
|
rlm@1
|
2984 ARITHMETIC_DATA_OPCODE(OP_ADC, OP_ADC, 0x0a0);
|
rlm@1
|
2985 ARITHMETIC_DATA_OPCODE(OP_ADCS, OP_ADC, 0x0b0);
|
rlm@1
|
2986 case 0x0a9:
|
rlm@1
|
2987 {
|
rlm@1
|
2988 // UMLAL RdLo, RdHi, Rn, Rs
|
rlm@1
|
2989 u32 umult = reg[(opcode & 0x0F)].I;
|
rlm@1
|
2990 u32 usource = reg[(opcode >> 8) & 0x0F].I;
|
rlm@1
|
2991 int destLo = (opcode >> 12) & 0x0F;
|
rlm@1
|
2992 int destHi = (opcode >> 16) & 0x0F;
|
rlm@1
|
2993 u64 uTemp = (u64)reg[destHi].I;
|
rlm@1
|
2994 uTemp <<= 32;
|
rlm@1
|
2995 uTemp |= (u64)reg[destLo].I;
|
rlm@1
|
2996 uTemp += ((u64)umult) * ((u64)usource);
|
rlm@1
|
2997 reg[destLo].I = (u32)(uTemp & 0xFFFFFFFF);
|
rlm@1
|
2998 reg[destHi].I = (u32)(uTemp >> 32);
|
rlm@1
|
2999 if ((usource & 0xFFFFFF00) == 0)
|
rlm@1
|
3000 clockTicks += 3;
|
rlm@1
|
3001 else if ((usource & 0xFFFF0000) == 0)
|
rlm@1
|
3002 clockTicks += 4;
|
rlm@1
|
3003 else if ((usource & 0xFF000000) == 0)
|
rlm@1
|
3004 clockTicks += 5;
|
rlm@1
|
3005 else
|
rlm@1
|
3006 clockTicks += 6;
|
rlm@1
|
3007 }
|
rlm@1
|
3008 break;
|
rlm@1
|
3009 case 0x0b9:
|
rlm@1
|
3010 {
|
rlm@1
|
3011 // UMLALS RdLo, RdHi, Rn, Rs
|
rlm@1
|
3012 u32 umult = reg[(opcode & 0x0F)].I;
|
rlm@1
|
3013 u32 usource = reg[(opcode >> 8) & 0x0F].I;
|
rlm@1
|
3014 int destLo = (opcode >> 12) & 0x0F;
|
rlm@1
|
3015 int destHi = (opcode >> 16) & 0x0F;
|
rlm@1
|
3016 u64 uTemp = (u64)reg[destHi].I;
|
rlm@1
|
3017 uTemp <<= 32;
|
rlm@1
|
3018 uTemp |= (u64)reg[destLo].I;
|
rlm@1
|
3019 uTemp += ((u64)umult) * ((u64)usource);
|
rlm@1
|
3020 reg[destLo].I = (u32)(uTemp & 0xFFFFFFFF);
|
rlm@1
|
3021 reg[destHi].I = (u32)(uTemp >> 32);
|
rlm@1
|
3022 Z_FLAG = (uTemp) ? false : true;
|
rlm@1
|
3023 N_FLAG = (reg[destHi].I & 0x80000000) ? true : false;
|
rlm@1
|
3024 if ((usource & 0xFFFFFF00) == 0)
|
rlm@1
|
3025 clockTicks += 3;
|
rlm@1
|
3026 else if ((usource & 0xFFFF0000) == 0)
|
rlm@1
|
3027 clockTicks += 4;
|
rlm@1
|
3028 else if ((usource & 0xFF000000) == 0)
|
rlm@1
|
3029 clockTicks += 5;
|
rlm@1
|
3030 else
|
rlm@1
|
3031 clockTicks += 6;
|
rlm@1
|
3032 }
|
rlm@1
|
3033 break;
|
rlm@1
|
3034 ARITHMETIC_DATA_OPCODE(OP_SBC, OP_SBC, 0x0c0);
|
rlm@1
|
3035 ARITHMETIC_DATA_OPCODE(OP_SBCS, OP_SBC, 0x0d0);
|
rlm@1
|
3036 case 0x0c9:
|
rlm@1
|
3037 {
|
rlm@1
|
3038 // SMULL RdLo, RdHi, Rm, Rs
|
rlm@1
|
3039 int destLo = (opcode >> 12) & 0x0F;
|
rlm@1
|
3040 int destHi = (opcode >> 16) & 0x0F;
|
rlm@1
|
3041 u32 rs = reg[(opcode >> 8) & 0x0F].I;
|
rlm@1
|
3042 s64 m = (s32)reg[(opcode & 0x0F)].I;
|
rlm@1
|
3043 s64 s = (s32)rs;
|
rlm@1
|
3044 s64 sTemp = m * s;
|
rlm@1
|
3045 reg[destLo].I = (u32)(sTemp & 0xFFFFFFFF);
|
rlm@1
|
3046 reg[destHi].I = (u32)(sTemp >> 32);
|
rlm@1
|
3047 if (((s32)rs) < 0)
|
rlm@1
|
3048 rs = ~rs;
|
rlm@1
|
3049 if ((rs & 0xFFFFFF00) == 0)
|
rlm@1
|
3050 clockTicks += 2;
|
rlm@1
|
3051 else if ((rs & 0xFFFF0000) == 0)
|
rlm@1
|
3052 clockTicks += 3;
|
rlm@1
|
3053 else if ((rs & 0xFF000000) == 0)
|
rlm@1
|
3054 clockTicks += 4;
|
rlm@1
|
3055 else
|
rlm@1
|
3056 clockTicks += 5;
|
rlm@1
|
3057 }
|
rlm@1
|
3058 break;
|
rlm@1
|
3059 case 0x0d9:
|
rlm@1
|
3060 {
|
rlm@1
|
3061 // SMULLS RdLo, RdHi, Rm, Rs
|
rlm@1
|
3062 int destLo = (opcode >> 12) & 0x0F;
|
rlm@1
|
3063 int destHi = (opcode >> 16) & 0x0F;
|
rlm@1
|
3064 u32 rs = reg[(opcode >> 8) & 0x0F].I;
|
rlm@1
|
3065 s64 m = (s32)reg[(opcode & 0x0F)].I;
|
rlm@1
|
3066 s64 s = (s32)rs;
|
rlm@1
|
3067 s64 sTemp = m * s;
|
rlm@1
|
3068 reg[destLo].I = (u32)(sTemp & 0xFFFFFFFF);
|
rlm@1
|
3069 reg[destHi].I = (u32)(sTemp >> 32);
|
rlm@1
|
3070 Z_FLAG = (sTemp) ? false : true;
|
rlm@1
|
3071 N_FLAG = (sTemp < 0) ? true : false;
|
rlm@1
|
3072 if (((s32)rs) < 0)
|
rlm@1
|
3073 rs = ~rs;
|
rlm@1
|
3074 if ((rs & 0xFFFFFF00) == 0)
|
rlm@1
|
3075 clockTicks += 2;
|
rlm@1
|
3076 else if ((rs & 0xFFFF0000) == 0)
|
rlm@1
|
3077 clockTicks += 3;
|
rlm@1
|
3078 else if ((rs & 0xFF000000) == 0)
|
rlm@1
|
3079 clockTicks += 4;
|
rlm@1
|
3080 else
|
rlm@1
|
3081 clockTicks += 5;
|
rlm@1
|
3082 }
|
rlm@1
|
3083 break;
|
rlm@1
|
3084 ARITHMETIC_DATA_OPCODE(OP_RSC, OP_RSC, 0x0e0);
|
rlm@1
|
3085 ARITHMETIC_DATA_OPCODE(OP_RSCS, OP_RSC, 0x0f0);
|
rlm@1
|
3086 case 0x0e9:
|
rlm@1
|
3087 {
|
rlm@1
|
3088 // SMLAL RdLo, RdHi, Rm, Rs
|
rlm@1
|
3089 int destLo = (opcode >> 12) & 0x0F;
|
rlm@1
|
3090 int destHi = (opcode >> 16) & 0x0F;
|
rlm@1
|
3091 u32 rs = reg[(opcode >> 8) & 0x0F].I;
|
rlm@1
|
3092 s64 m = (s32)reg[(opcode & 0x0F)].I;
|
rlm@1
|
3093 s64 s = (s32)rs;
|
rlm@1
|
3094 s64 sTemp = (u64)reg[destHi].I;
|
rlm@1
|
3095 sTemp <<= 32;
|
rlm@1
|
3096 sTemp |= (u64)reg[destLo].I;
|
rlm@1
|
3097 sTemp += m * s;
|
rlm@1
|
3098 reg[destLo].I = (u32)(sTemp & 0xFFFFFFFF);
|
rlm@1
|
3099 reg[destHi].I = (u32)(sTemp >> 32);
|
rlm@1
|
3100 if (((s32)rs) < 0)
|
rlm@1
|
3101 rs = ~rs;
|
rlm@1
|
3102 if ((rs & 0xFFFFFF00) == 0)
|
rlm@1
|
3103 clockTicks += 3;
|
rlm@1
|
3104 else if ((rs & 0xFFFF0000) == 0)
|
rlm@1
|
3105 clockTicks += 4;
|
rlm@1
|
3106 else if ((rs & 0xFF000000) == 0)
|
rlm@1
|
3107 clockTicks += 5;
|
rlm@1
|
3108 else
|
rlm@1
|
3109 clockTicks += 6;
|
rlm@1
|
3110 }
|
rlm@1
|
3111 break;
|
rlm@1
|
3112 case 0x0f9:
|
rlm@1
|
3113 {
|
rlm@1
|
3114 // SMLALS RdLo, RdHi, Rm, Rs
|
rlm@1
|
3115 int destLo = (opcode >> 12) & 0x0F;
|
rlm@1
|
3116 int destHi = (opcode >> 16) & 0x0F;
|
rlm@1
|
3117 u32 rs = reg[(opcode >> 8) & 0x0F].I;
|
rlm@1
|
3118 s64 m = (s32)reg[(opcode & 0x0F)].I;
|
rlm@1
|
3119 s64 s = (s32)rs;
|
rlm@1
|
3120 s64 sTemp = (u64)reg[destHi].I;
|
rlm@1
|
3121 sTemp <<= 32;
|
rlm@1
|
3122 sTemp |= (u64)reg[destLo].I;
|
rlm@1
|
3123 sTemp += m * s;
|
rlm@1
|
3124 reg[destLo].I = (u32)(sTemp & 0xFFFFFFFF);
|
rlm@1
|
3125 reg[destHi].I = (u32)(sTemp >> 32);
|
rlm@1
|
3126 Z_FLAG = (sTemp) ? false : true;
|
rlm@1
|
3127 N_FLAG = (sTemp < 0) ? true : false;
|
rlm@1
|
3128 if (((s32)rs) < 0)
|
rlm@1
|
3129 rs = ~rs;
|
rlm@1
|
3130 if ((rs & 0xFFFFFF00) == 0)
|
rlm@1
|
3131 clockTicks += 3;
|
rlm@1
|
3132 else if ((rs & 0xFFFF0000) == 0)
|
rlm@1
|
3133 clockTicks += 4;
|
rlm@1
|
3134 else if ((rs & 0xFF000000) == 0)
|
rlm@1
|
3135 clockTicks += 5;
|
rlm@1
|
3136 else
|
rlm@1
|
3137 clockTicks += 6;
|
rlm@1
|
3138 }
|
rlm@1
|
3139 break;
|
rlm@1
|
3140 LOGICAL_DATA_OPCODE(OP_TST, OP_TST, 0x110);
|
rlm@1
|
3141 case 0x100:
|
rlm@1
|
3142 // MRS Rd, CPSR
|
rlm@1
|
3143 // TODO: check if right instruction....
|
rlm@1
|
3144 CPUUpdateCPSR();
|
rlm@1
|
3145 reg[(opcode >> 12) & 0x0F].I = reg[16].I;
|
rlm@1
|
3146 break;
|
rlm@1
|
3147 case 0x109:
|
rlm@1
|
3148 {
|
rlm@1
|
3149 // SWP Rd, Rm, [Rn]
|
rlm@1
|
3150 u32 address = reg[(opcode >> 16) & 15].I;
|
rlm@1
|
3151 u32 temp = CPUReadMemory(address);
|
rlm@1
|
3152 CPUWriteMemory(address, reg[opcode & 15].I);
|
rlm@1
|
3153 reg[(opcode >> 12) & 15].I = temp;
|
rlm@1
|
3154 }
|
rlm@1
|
3155 break;
|
rlm@1
|
3156 LOGICAL_DATA_OPCODE(OP_TEQ, OP_TEQ, 0x130);
|
rlm@1
|
3157 case 0x120:
|
rlm@1
|
3158 {
|
rlm@1
|
3159 // MSR CPSR_fields, Rm
|
rlm@1
|
3160 CPUUpdateCPSR();
|
rlm@1
|
3161 u32 value = reg[opcode & 15].I;
|
rlm@1
|
3162 u32 newValue = reg[16].I;
|
rlm@1
|
3163 if (armMode > 0x10)
|
rlm@1
|
3164 {
|
rlm@1
|
3165 if (opcode & 0x00010000)
|
rlm@1
|
3166 newValue = (newValue & 0xFFFFFF00) | (value & 0x000000FF);
|
rlm@1
|
3167 if (opcode & 0x00020000)
|
rlm@1
|
3168 newValue = (newValue & 0xFFFF00FF) | (value & 0x0000FF00);
|
rlm@1
|
3169 if (opcode & 0x00040000)
|
rlm@1
|
3170 newValue = (newValue & 0xFF00FFFF) | (value & 0x00FF0000);
|
rlm@1
|
3171 }
|
rlm@1
|
3172 if (opcode & 0x00080000)
|
rlm@1
|
3173 newValue = (newValue & 0x00FFFFFF) | (value & 0xFF000000);
|
rlm@1
|
3174 newValue |= 0x10;
|
rlm@1
|
3175 CPUSwitchMode(newValue & 0x1f, false);
|
rlm@1
|
3176 reg[16].I = newValue;
|
rlm@1
|
3177 CPUUpdateFlags();
|
rlm@1
|
3178 }
|
rlm@1
|
3179 break;
|
rlm@1
|
3180 case 0x121:
|
rlm@1
|
3181 {
|
rlm@1
|
3182 // BX Rm
|
rlm@1
|
3183 // TODO: check if right instruction...
|
rlm@1
|
3184 clockTicks += 3;
|
rlm@1
|
3185 int base = opcode & 0x0F;
|
rlm@1
|
3186 armState = reg[base].I & 1 ? false : true;
|
rlm@1
|
3187 if (armState)
|
rlm@1
|
3188 {
|
rlm@1
|
3189 reg[15].I = reg[base].I & 0xFFFFFFFC;
|
rlm@1
|
3190 armNextPC = reg[15].I;
|
rlm@1
|
3191 reg[15].I += 4;
|
rlm@1
|
3192 }
|
rlm@1
|
3193 else
|
rlm@1
|
3194 {
|
rlm@1
|
3195 reg[15].I = reg[base].I & 0xFFFFFFFE;
|
rlm@1
|
3196 armNextPC = reg[15].I;
|
rlm@1
|
3197 reg[15].I += 2;
|
rlm@1
|
3198 }
|
rlm@1
|
3199 }
|
rlm@1
|
3200 break;
|
rlm@1
|
3201 ARITHMETIC_DATA_OPCODE(OP_CMP, OP_CMP, 0x150);
|
rlm@1
|
3202 case 0x140:
|
rlm@1
|
3203 // MRS Rd, SPSR
|
rlm@1
|
3204 // TODO: check if right instruction...
|
rlm@1
|
3205 reg[(opcode >> 12) & 0x0F].I = reg[17].I;
|
rlm@1
|
3206 break;
|
rlm@1
|
3207 case 0x149:
|
rlm@1
|
3208 {
|
rlm@1
|
3209 // SWPB Rd, Rm, [Rn]
|
rlm@1
|
3210 u32 address = reg[(opcode >> 16) & 15].I;
|
rlm@1
|
3211 u32 temp = CPUReadByte(address);
|
rlm@1
|
3212 CPUWriteByte(address, reg[opcode & 15].B.B0);
|
rlm@1
|
3213 reg[(opcode >> 12) & 15].I = temp;
|
rlm@1
|
3214 }
|
rlm@1
|
3215 break;
|
rlm@1
|
3216 ARITHMETIC_DATA_OPCODE(OP_CMN, OP_CMN, 0x170);
|
rlm@1
|
3217 case 0x160:
|
rlm@1
|
3218 {
|
rlm@1
|
3219 // MSR SPSR_fields, Rm
|
rlm@1
|
3220 u32 value = reg[opcode & 15].I;
|
rlm@1
|
3221 if (armMode > 0x10 && armMode < 0x1f)
|
rlm@1
|
3222 {
|
rlm@1
|
3223 if (opcode & 0x00010000)
|
rlm@1
|
3224 reg[17].I = (reg[17].I & 0xFFFFFF00) | (value & 0x000000FF);
|
rlm@1
|
3225 if (opcode & 0x00020000)
|
rlm@1
|
3226 reg[17].I = (reg[17].I & 0xFFFF00FF) | (value & 0x0000FF00);
|
rlm@1
|
3227 if (opcode & 0x00040000)
|
rlm@1
|
3228 reg[17].I = (reg[17].I & 0xFF00FFFF) | (value & 0x00FF0000);
|
rlm@1
|
3229 if (opcode & 0x00080000)
|
rlm@1
|
3230 reg[17].I = (reg[17].I & 0x00FFFFFF) | (value & 0xFF000000);
|
rlm@1
|
3231 }
|
rlm@1
|
3232 }
|
rlm@1
|
3233 break;
|
rlm@1
|
3234 LOGICAL_DATA_OPCODE(OP_ORR, OP_ORR, 0x180);
|
rlm@1
|
3235 LOGICAL_DATA_OPCODE(OP_ORRS, OP_ORR, 0x190);
|
rlm@1
|
3236 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MOV, OP_MOV, 0x1a0);
|
rlm@1
|
3237 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MOVS, OP_MOV, 0x1b0);
|
rlm@1
|
3238 LOGICAL_DATA_OPCODE(OP_BIC, OP_BIC, 0x1c0);
|
rlm@1
|
3239 LOGICAL_DATA_OPCODE(OP_BICS, OP_BIC, 0x1d0);
|
rlm@1
|
3240 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MVN, OP_MVN, 0x1e0);
|
rlm@1
|
3241 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MVNS, OP_MVN, 0x1f0);
|
rlm@1
|
3242 #ifdef BKPT_SUPPORT
|
rlm@1
|
3243 case 0x127:
|
rlm@1
|
3244 case 0x7ff: // for GDB support
|
rlm@1
|
3245 extern void (*dbgSignal)(int, int);
|
rlm@1
|
3246 reg[15].I -= 4;
|
rlm@1
|
3247 armNextPC -= 4;
|
rlm@1
|
3248 dbgSignal(5, (opcode & 0x0f) | ((opcode >> 4) & 0xfff0));
|
rlm@1
|
3249 return;
|
rlm@1
|
3250 #endif
|
rlm@1
|
3251 case 0x320:
|
rlm@1
|
3252 case 0x321:
|
rlm@1
|
3253 case 0x322:
|
rlm@1
|
3254 case 0x323:
|
rlm@1
|
3255 case 0x324:
|
rlm@1
|
3256 case 0x325:
|
rlm@1
|
3257 case 0x326:
|
rlm@1
|
3258 case 0x327:
|
rlm@1
|
3259 case 0x328:
|
rlm@1
|
3260 case 0x329:
|
rlm@1
|
3261 case 0x32a:
|
rlm@1
|
3262 case 0x32b:
|
rlm@1
|
3263 case 0x32c:
|
rlm@1
|
3264 case 0x32d:
|
rlm@1
|
3265 case 0x32e:
|
rlm@1
|
3266 case 0x32f:
|
rlm@1
|
3267 {
|
rlm@1
|
3268 // MSR CPSR_fields, #
|
rlm@1
|
3269 CPUUpdateCPSR();
|
rlm@1
|
3270 u32 value = opcode & 0xFF;
|
rlm@1
|
3271 int shift = (opcode & 0xF00) >> 7;
|
rlm@1
|
3272 if (shift)
|
rlm@1
|
3273 {
|
rlm@1
|
3274 ROR_IMM_MSR;
|
rlm@1
|
3275 }
|
rlm@1
|
3276 u32 newValue = reg[16].I;
|
rlm@1
|
3277 if (armMode > 0x10)
|
rlm@1
|
3278 {
|
rlm@1
|
3279 if (opcode & 0x00010000)
|
rlm@1
|
3280 newValue = (newValue & 0xFFFFFF00) | (value & 0x000000FF);
|
rlm@1
|
3281 if (opcode & 0x00020000)
|
rlm@1
|
3282 newValue = (newValue & 0xFFFF00FF) | (value & 0x0000FF00);
|
rlm@1
|
3283 if (opcode & 0x00040000)
|
rlm@1
|
3284 newValue = (newValue & 0xFF00FFFF) | (value & 0x00FF0000);
|
rlm@1
|
3285 }
|
rlm@1
|
3286 if (opcode & 0x00080000)
|
rlm@1
|
3287 newValue = (newValue & 0x00FFFFFF) | (value & 0xFF000000);
|
rlm@1
|
3288
|
rlm@1
|
3289 newValue |= 0x10;
|
rlm@1
|
3290
|
rlm@1
|
3291 CPUSwitchMode(newValue & 0x1f, false);
|
rlm@1
|
3292 reg[16].I = newValue;
|
rlm@1
|
3293 CPUUpdateFlags();
|
rlm@1
|
3294 }
|
rlm@1
|
3295 break;
|
rlm@1
|
3296 case 0x360:
|
rlm@1
|
3297 case 0x361:
|
rlm@1
|
3298 case 0x362:
|
rlm@1
|
3299 case 0x363:
|
rlm@1
|
3300 case 0x364:
|
rlm@1
|
3301 case 0x365:
|
rlm@1
|
3302 case 0x366:
|
rlm@1
|
3303 case 0x367:
|
rlm@1
|
3304 case 0x368:
|
rlm@1
|
3305 case 0x369:
|
rlm@1
|
3306 case 0x36a:
|
rlm@1
|
3307 case 0x36b:
|
rlm@1
|
3308 case 0x36c:
|
rlm@1
|
3309 case 0x36d:
|
rlm@1
|
3310 case 0x36e:
|
rlm@1
|
3311 case 0x36f:
|
rlm@1
|
3312 {
|
rlm@1
|
3313 // MSR SPSR_fields, #
|
rlm@1
|
3314 if (armMode > 0x10 && armMode < 0x1f)
|
rlm@1
|
3315 {
|
rlm@1
|
3316 u32 value = opcode & 0xFF;
|
rlm@1
|
3317 int shift = (opcode & 0xF00) >> 7;
|
rlm@1
|
3318 if (shift)
|
rlm@1
|
3319 {
|
rlm@1
|
3320 ROR_IMM_MSR;
|
rlm@1
|
3321 }
|
rlm@1
|
3322 if (opcode & 0x00010000)
|
rlm@1
|
3323 reg[17].I = (reg[17].I & 0xFFFFFF00) | (value & 0x000000FF);
|
rlm@1
|
3324 if (opcode & 0x00020000)
|
rlm@1
|
3325 reg[17].I = (reg[17].I & 0xFFFF00FF) | (value & 0x0000FF00);
|
rlm@1
|
3326 if (opcode & 0x00040000)
|
rlm@1
|
3327 reg[17].I = (reg[17].I & 0xFF00FFFF) | (value & 0x00FF0000);
|
rlm@1
|
3328 if (opcode & 0x00080000)
|
rlm@1
|
3329 reg[17].I = (reg[17].I & 0x00FFFFFF) | (value & 0xFF000000);
|
rlm@1
|
3330 }
|
rlm@1
|
3331 }
|
rlm@1
|
3332 break;
|
rlm@1
|
3333 CASE_16(0x400)
|
rlm@1
|
3334 // T versions shouldn't be different on GBA
|
rlm@1
|
3335 CASE_16(0x420)
|
rlm@1
|
3336 {
|
rlm@1
|
3337 // STR Rd, [Rn], -#
|
rlm@1
|
3338 int offset = opcode & 0xFFF;
|
rlm@1
|
3339 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3340 int base = (opcode >> 16) & 15;
|
rlm@1
|
3341 u32 address = reg[base].I;
|
rlm@1
|
3342 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3343 reg[base].I = address - offset;
|
rlm@1
|
3344 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3345 }
|
rlm@1
|
3346 break;
|
rlm@1
|
3347 CASE_16(0x480)
|
rlm@1
|
3348 // T versions shouldn't be different on GBA
|
rlm@1
|
3349 CASE_16(0x4a0)
|
rlm@1
|
3350 {
|
rlm@1
|
3351 // STR Rd, [Rn], #
|
rlm@1
|
3352 int offset = opcode & 0xFFF;
|
rlm@1
|
3353 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3354 int base = (opcode >> 16) & 15;
|
rlm@1
|
3355 u32 address = reg[base].I;
|
rlm@1
|
3356 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3357 reg[base].I = address + offset;
|
rlm@1
|
3358 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3359 }
|
rlm@1
|
3360 break;
|
rlm@1
|
3361 CASE_16(0x500)
|
rlm@1
|
3362 {
|
rlm@1
|
3363 // STR Rd, [Rn, -#]
|
rlm@1
|
3364 int offset = opcode & 0xFFF;
|
rlm@1
|
3365 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3366 int base = (opcode >> 16) & 15;
|
rlm@1
|
3367 u32 address = reg[base].I - offset;
|
rlm@1
|
3368 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3369 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3370 }
|
rlm@1
|
3371 break;
|
rlm@1
|
3372 CASE_16(0x520)
|
rlm@1
|
3373 {
|
rlm@1
|
3374 // STR Rd, [Rn, -#]!
|
rlm@1
|
3375 int offset = opcode & 0xFFF;
|
rlm@1
|
3376 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3377 int base = (opcode >> 16) & 15;
|
rlm@1
|
3378 u32 address = reg[base].I - offset;
|
rlm@1
|
3379 reg[base].I = address;
|
rlm@1
|
3380 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3381 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3382 }
|
rlm@1
|
3383 break;
|
rlm@1
|
3384 CASE_16(0x580)
|
rlm@1
|
3385 {
|
rlm@1
|
3386 // STR Rd, [Rn, #]
|
rlm@1
|
3387 int offset = opcode & 0xFFF;
|
rlm@1
|
3388 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3389 int base = (opcode >> 16) & 15;
|
rlm@1
|
3390 u32 address = reg[base].I + offset;
|
rlm@1
|
3391 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3392 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3393 }
|
rlm@1
|
3394 break;
|
rlm@1
|
3395 CASE_16(0x5a0)
|
rlm@1
|
3396 {
|
rlm@1
|
3397 // STR Rd, [Rn, #]!
|
rlm@1
|
3398 int offset = opcode & 0xFFF;
|
rlm@1
|
3399 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3400 int base = (opcode >> 16) & 15;
|
rlm@1
|
3401 u32 address = reg[base].I + offset;
|
rlm@1
|
3402 reg[base].I = address;
|
rlm@1
|
3403 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3404 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3405 }
|
rlm@1
|
3406 break;
|
rlm@1
|
3407 CASE_16(0x410)
|
rlm@1
|
3408 {
|
rlm@1
|
3409 // LDR Rd, [Rn], -#
|
rlm@1
|
3410 int offset = opcode & 0xFFF;
|
rlm@1
|
3411 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3412 int base = (opcode >> 16) & 15;
|
rlm@1
|
3413 u32 address = reg[base].I;
|
rlm@1
|
3414 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
3415 if (dest != base)
|
rlm@1
|
3416 reg[base].I -= offset;
|
rlm@1
|
3417 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3418 if (dest == 15)
|
rlm@1
|
3419 {
|
rlm@1
|
3420 clockTicks += 2;
|
rlm@1
|
3421 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
3422 armNextPC = reg[15].I;
|
rlm@1
|
3423 reg[15].I += 4;
|
rlm@1
|
3424 }
|
rlm@1
|
3425 }
|
rlm@1
|
3426 break;
|
rlm@1
|
3427 CASE_16(0x430)
|
rlm@1
|
3428 {
|
rlm@1
|
3429 // LDRT Rd, [Rn], -#
|
rlm@1
|
3430 int offset = opcode & 0xFFF;
|
rlm@1
|
3431 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3432 int base = (opcode >> 16) & 15;
|
rlm@1
|
3433 u32 address = reg[base].I;
|
rlm@1
|
3434 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
3435 if (dest != base)
|
rlm@1
|
3436 reg[base].I -= offset;
|
rlm@1
|
3437 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3438 }
|
rlm@1
|
3439 break;
|
rlm@1
|
3440 CASE_16(0x490)
|
rlm@1
|
3441 {
|
rlm@1
|
3442 // LDR Rd, [Rn], #
|
rlm@1
|
3443 int offset = opcode & 0xFFF;
|
rlm@1
|
3444 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3445 int base = (opcode >> 16) & 15;
|
rlm@1
|
3446 u32 address = reg[base].I;
|
rlm@1
|
3447 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
3448 if (dest != base)
|
rlm@1
|
3449 reg[base].I += offset;
|
rlm@1
|
3450 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3451 if (dest == 15)
|
rlm@1
|
3452 {
|
rlm@1
|
3453 clockTicks += 2;
|
rlm@1
|
3454 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
3455 armNextPC = reg[15].I;
|
rlm@1
|
3456 reg[15].I += 4;
|
rlm@1
|
3457 }
|
rlm@1
|
3458 }
|
rlm@1
|
3459 break;
|
rlm@1
|
3460 CASE_16(0x4b0)
|
rlm@1
|
3461 {
|
rlm@1
|
3462 // LDRT Rd, [Rn], #
|
rlm@1
|
3463 int offset = opcode & 0xFFF;
|
rlm@1
|
3464 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3465 int base = (opcode >> 16) & 15;
|
rlm@1
|
3466 u32 address = reg[base].I;
|
rlm@1
|
3467 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
3468 if (dest != base)
|
rlm@1
|
3469 reg[base].I += offset;
|
rlm@1
|
3470 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3471 }
|
rlm@1
|
3472 break;
|
rlm@1
|
3473 CASE_16(0x510)
|
rlm@1
|
3474 {
|
rlm@1
|
3475 // LDR Rd, [Rn, -#]
|
rlm@1
|
3476 int offset = opcode & 0xFFF;
|
rlm@1
|
3477 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3478 int base = (opcode >> 16) & 15;
|
rlm@1
|
3479 u32 address = reg[base].I - offset;
|
rlm@1
|
3480 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
3481 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3482 if (dest == 15)
|
rlm@1
|
3483 {
|
rlm@1
|
3484 clockTicks += 2;
|
rlm@1
|
3485 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
3486 armNextPC = reg[15].I;
|
rlm@1
|
3487 reg[15].I += 4;
|
rlm@1
|
3488 }
|
rlm@1
|
3489 }
|
rlm@1
|
3490 break;
|
rlm@1
|
3491 CASE_16(0x530)
|
rlm@1
|
3492 {
|
rlm@1
|
3493 // LDR Rd, [Rn, -#]!
|
rlm@1
|
3494 int offset = opcode & 0xFFF;
|
rlm@1
|
3495 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3496 int base = (opcode >> 16) & 15;
|
rlm@1
|
3497 u32 address = reg[base].I - offset;
|
rlm@1
|
3498 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
3499 if (dest != base)
|
rlm@1
|
3500 reg[base].I = address;
|
rlm@1
|
3501 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3502 if (dest == 15)
|
rlm@1
|
3503 {
|
rlm@1
|
3504 clockTicks += 2;
|
rlm@1
|
3505 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
3506 armNextPC = reg[15].I;
|
rlm@1
|
3507 reg[15].I += 4;
|
rlm@1
|
3508 }
|
rlm@1
|
3509 }
|
rlm@1
|
3510 break;
|
rlm@1
|
3511 CASE_16(0x590)
|
rlm@1
|
3512 {
|
rlm@1
|
3513 // LDR Rd, [Rn, #]
|
rlm@1
|
3514 int offset = opcode & 0xFFF;
|
rlm@1
|
3515 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3516 int base = (opcode >> 16) & 15;
|
rlm@1
|
3517 u32 address = reg[base].I + offset;
|
rlm@1
|
3518 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
3519 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3520 if (dest == 15)
|
rlm@1
|
3521 {
|
rlm@1
|
3522 clockTicks += 2;
|
rlm@1
|
3523 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
3524 armNextPC = reg[15].I;
|
rlm@1
|
3525 reg[15].I += 4;
|
rlm@1
|
3526 }
|
rlm@1
|
3527 }
|
rlm@1
|
3528 break;
|
rlm@1
|
3529 CASE_16(0x5b0)
|
rlm@1
|
3530 {
|
rlm@1
|
3531 // LDR Rd, [Rn, #]!
|
rlm@1
|
3532 int offset = opcode & 0xFFF;
|
rlm@1
|
3533 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3534 int base = (opcode >> 16) & 15;
|
rlm@1
|
3535 u32 address = reg[base].I + offset;
|
rlm@1
|
3536 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
3537 if (dest != base)
|
rlm@1
|
3538 reg[base].I = address;
|
rlm@1
|
3539 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3540 if (dest == 15)
|
rlm@1
|
3541 {
|
rlm@1
|
3542 clockTicks += 2;
|
rlm@1
|
3543 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
3544 armNextPC = reg[15].I;
|
rlm@1
|
3545 reg[15].I += 4;
|
rlm@1
|
3546 }
|
rlm@1
|
3547 }
|
rlm@1
|
3548 break;
|
rlm@1
|
3549 CASE_16(0x440)
|
rlm@1
|
3550 // T versions shouldn't be different on GBA
|
rlm@1
|
3551 CASE_16(0x460)
|
rlm@1
|
3552 {
|
rlm@1
|
3553 // STRB Rd, [Rn], -#
|
rlm@1
|
3554 int offset = opcode & 0xFFF;
|
rlm@1
|
3555 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3556 int base = (opcode >> 16) & 15;
|
rlm@1
|
3557 u32 address = reg[base].I;
|
rlm@1
|
3558 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
3559 reg[base].I = address - offset;
|
rlm@1
|
3560 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
3561 }
|
rlm@1
|
3562 break;
|
rlm@1
|
3563 CASE_16(0x4c0)
|
rlm@1
|
3564 // T versions shouldn't be different on GBA
|
rlm@1
|
3565 CASE_16(0x4e0)
|
rlm@1
|
3566 // STRB Rd, [Rn], #
|
rlm@1
|
3567 {
|
rlm@1
|
3568 int offset = opcode & 0xFFF;
|
rlm@1
|
3569 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3570 int base = (opcode >> 16) & 15;
|
rlm@1
|
3571 u32 address = reg[base].I;
|
rlm@1
|
3572 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
3573 reg[base].I = address + offset;
|
rlm@1
|
3574 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
3575 }
|
rlm@1
|
3576 break;
|
rlm@1
|
3577 CASE_16(0x540)
|
rlm@1
|
3578 {
|
rlm@1
|
3579 // STRB Rd, [Rn, -#]
|
rlm@1
|
3580 int offset = opcode & 0xFFF;
|
rlm@1
|
3581 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3582 int base = (opcode >> 16) & 15;
|
rlm@1
|
3583 u32 address = reg[base].I - offset;
|
rlm@1
|
3584 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
3585 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
3586 }
|
rlm@1
|
3587 break;
|
rlm@1
|
3588 CASE_16(0x560)
|
rlm@1
|
3589 {
|
rlm@1
|
3590 // STRB Rd, [Rn, -#]!
|
rlm@1
|
3591 int offset = opcode & 0xFFF;
|
rlm@1
|
3592 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3593 int base = (opcode >> 16) & 15;
|
rlm@1
|
3594 u32 address = reg[base].I - offset;
|
rlm@1
|
3595 reg[base].I = address;
|
rlm@1
|
3596 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
3597 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
3598 }
|
rlm@1
|
3599 break;
|
rlm@1
|
3600 CASE_16(0x5c0)
|
rlm@1
|
3601 {
|
rlm@1
|
3602 // STRB Rd, [Rn, #]
|
rlm@1
|
3603 int offset = opcode & 0xFFF;
|
rlm@1
|
3604 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3605 int base = (opcode >> 16) & 15;
|
rlm@1
|
3606 u32 address = reg[base].I + offset;
|
rlm@1
|
3607 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
3608 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
3609 }
|
rlm@1
|
3610 break;
|
rlm@1
|
3611 CASE_16(0x5e0)
|
rlm@1
|
3612 {
|
rlm@1
|
3613 // STRB Rd, [Rn, #]!
|
rlm@1
|
3614 int offset = opcode & 0xFFF;
|
rlm@1
|
3615 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3616 int base = (opcode >> 16) & 15;
|
rlm@1
|
3617 u32 address = reg[base].I + offset;
|
rlm@1
|
3618 reg[base].I = address;
|
rlm@1
|
3619 CPUWriteByte(address, reg[dest].I);
|
rlm@1
|
3620 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
3621 }
|
rlm@1
|
3622 break;
|
rlm@1
|
3623 CASE_16(0x450)
|
rlm@1
|
3624 // T versions shouldn't be different
|
rlm@1
|
3625 CASE_16(0x470)
|
rlm@1
|
3626 {
|
rlm@1
|
3627 // LDRB Rd, [Rn], -#
|
rlm@1
|
3628 int offset = opcode & 0xFFF;
|
rlm@1
|
3629 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3630 int base = (opcode >> 16) & 15;
|
rlm@1
|
3631 u32 address = reg[base].I;
|
rlm@1
|
3632 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
3633 if (dest != base)
|
rlm@1
|
3634 reg[base].I -= offset;
|
rlm@1
|
3635 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
3636 }
|
rlm@1
|
3637 break;
|
rlm@1
|
3638 CASE_16(0x4d0)
|
rlm@1
|
3639 CASE_16(0x4f0) // T versions should not be different
|
rlm@1
|
3640 {
|
rlm@1
|
3641 // LDRB Rd, [Rn], #
|
rlm@1
|
3642 int offset = opcode & 0xFFF;
|
rlm@1
|
3643 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3644 int base = (opcode >> 16) & 15;
|
rlm@1
|
3645 u32 address = reg[base].I;
|
rlm@1
|
3646 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
3647 if (dest != base)
|
rlm@1
|
3648 reg[base].I += offset;
|
rlm@1
|
3649 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
3650 }
|
rlm@1
|
3651 break;
|
rlm@1
|
3652 CASE_16(0x550)
|
rlm@1
|
3653 {
|
rlm@1
|
3654 // LDRB Rd, [Rn, -#]
|
rlm@1
|
3655 int offset = opcode & 0xFFF;
|
rlm@1
|
3656 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3657 int base = (opcode >> 16) & 15;
|
rlm@1
|
3658 u32 address = reg[base].I - offset;
|
rlm@1
|
3659 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
3660 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
3661 }
|
rlm@1
|
3662 break;
|
rlm@1
|
3663 CASE_16(0x570)
|
rlm@1
|
3664 {
|
rlm@1
|
3665 // LDRB Rd, [Rn, -#]!
|
rlm@1
|
3666 int offset = opcode & 0xFFF;
|
rlm@1
|
3667 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3668 int base = (opcode >> 16) & 15;
|
rlm@1
|
3669 u32 address = reg[base].I - offset;
|
rlm@1
|
3670 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
3671 if (dest != base)
|
rlm@1
|
3672 reg[base].I = address;
|
rlm@1
|
3673 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
3674 }
|
rlm@1
|
3675 break;
|
rlm@1
|
3676 CASE_16(0x5d0)
|
rlm@1
|
3677 {
|
rlm@1
|
3678 // LDRB Rd, [Rn, #]
|
rlm@1
|
3679 int offset = opcode & 0xFFF;
|
rlm@1
|
3680 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3681 int base = (opcode >> 16) & 15;
|
rlm@1
|
3682 u32 address = reg[base].I + offset;
|
rlm@1
|
3683 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
3684 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
3685 }
|
rlm@1
|
3686 break;
|
rlm@1
|
3687 CASE_16(0x5f0)
|
rlm@1
|
3688 {
|
rlm@1
|
3689 // LDRB Rd, [Rn, #]!
|
rlm@1
|
3690 int offset = opcode & 0xFFF;
|
rlm@1
|
3691 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3692 int base = (opcode >> 16) & 15;
|
rlm@1
|
3693 u32 address = reg[base].I + offset;
|
rlm@1
|
3694 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
3695 if (dest != base)
|
rlm@1
|
3696 reg[base].I = address;
|
rlm@1
|
3697 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
3698 }
|
rlm@1
|
3699 break;
|
rlm@1
|
3700 case 0x600:
|
rlm@1
|
3701 case 0x608:
|
rlm@1
|
3702 // T versions are the same
|
rlm@1
|
3703 case 0x620:
|
rlm@1
|
3704 case 0x628:
|
rlm@1
|
3705 {
|
rlm@1
|
3706 // STR Rd, [Rn], -Rm, LSL #
|
rlm@1
|
3707 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
3708 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3709 int base = (opcode >> 16) & 15;
|
rlm@1
|
3710 u32 address = reg[base].I;
|
rlm@1
|
3711 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3712 reg[base].I = address - offset;
|
rlm@1
|
3713 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3714 }
|
rlm@1
|
3715 break;
|
rlm@1
|
3716 case 0x602:
|
rlm@1
|
3717 case 0x60a:
|
rlm@1
|
3718 // T versions are the same
|
rlm@1
|
3719 case 0x622:
|
rlm@1
|
3720 case 0x62a:
|
rlm@1
|
3721 {
|
rlm@1
|
3722 // STR Rd, [Rn], -Rm, LSR #
|
rlm@1
|
3723 int shift = (opcode >> 7) & 31;
|
rlm@1
|
3724 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
3725 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3726 int base = (opcode >> 16) & 15;
|
rlm@1
|
3727 u32 address = reg[base].I;
|
rlm@1
|
3728 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3729 reg[base].I = address - offset;
|
rlm@1
|
3730 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3731 }
|
rlm@1
|
3732 break;
|
rlm@1
|
3733 case 0x604:
|
rlm@1
|
3734 case 0x60c:
|
rlm@1
|
3735 // T versions are the same
|
rlm@1
|
3736 case 0x624:
|
rlm@1
|
3737 case 0x62c:
|
rlm@1
|
3738 {
|
rlm@1
|
3739 // STR Rd, [Rn], -Rm, ASR #
|
rlm@1
|
3740 int shift = (opcode >> 7) & 31;
|
rlm@1
|
3741 int offset;
|
rlm@1
|
3742 if (shift)
|
rlm@1
|
3743 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
3744 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
3745 offset = 0xFFFFFFFF;
|
rlm@1
|
3746 else
|
rlm@1
|
3747 offset = 0;
|
rlm@1
|
3748 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3749 int base = (opcode >> 16) & 15;
|
rlm@1
|
3750 u32 address = reg[base].I;
|
rlm@1
|
3751 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3752 reg[base].I = address - offset;
|
rlm@1
|
3753 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3754 }
|
rlm@1
|
3755 break;
|
rlm@1
|
3756 case 0x606:
|
rlm@1
|
3757 case 0x60e:
|
rlm@1
|
3758 // T versions are the same
|
rlm@1
|
3759 case 0x626:
|
rlm@1
|
3760 case 0x62e:
|
rlm@1
|
3761 {
|
rlm@1
|
3762 // STR Rd, [Rn], -Rm, ROR #
|
rlm@1
|
3763 int shift = (opcode >> 7) & 31;
|
rlm@1
|
3764 u32 value = reg[opcode & 15].I;
|
rlm@1
|
3765 if (shift)
|
rlm@1
|
3766 {
|
rlm@1
|
3767 ROR_VALUE;
|
rlm@1
|
3768 }
|
rlm@1
|
3769 else
|
rlm@1
|
3770 {
|
rlm@1
|
3771 RCR_VALUE;
|
rlm@1
|
3772 }
|
rlm@1
|
3773 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3774 int base = (opcode >> 16) & 15;
|
rlm@1
|
3775 u32 address = reg[base].I;
|
rlm@1
|
3776 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3777 reg[base].I = address - value;
|
rlm@1
|
3778 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3779 }
|
rlm@1
|
3780 break;
|
rlm@1
|
3781 case 0x680:
|
rlm@1
|
3782 case 0x688:
|
rlm@1
|
3783 // T versions are the same
|
rlm@1
|
3784 case 0x6a0:
|
rlm@1
|
3785 case 0x6a8:
|
rlm@1
|
3786 {
|
rlm@1
|
3787 // STR Rd, [Rn], Rm, LSL #
|
rlm@1
|
3788 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
3789 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3790 int base = (opcode >> 16) & 15;
|
rlm@1
|
3791 u32 address = reg[base].I;
|
rlm@1
|
3792 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3793 reg[base].I = address + offset;
|
rlm@1
|
3794 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3795 }
|
rlm@1
|
3796 break;
|
rlm@1
|
3797 case 0x682:
|
rlm@1
|
3798 case 0x68a:
|
rlm@1
|
3799 // T versions are the same
|
rlm@1
|
3800 case 0x6a2:
|
rlm@1
|
3801 case 0x6aa:
|
rlm@1
|
3802 {
|
rlm@1
|
3803 // STR Rd, [Rn], Rm, LSR #
|
rlm@1
|
3804 int shift = (opcode >> 7) & 31;
|
rlm@1
|
3805 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
3806 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3807 int base = (opcode >> 16) & 15;
|
rlm@1
|
3808 u32 address = reg[base].I;
|
rlm@1
|
3809 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3810 reg[base].I = address + offset;
|
rlm@1
|
3811 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3812 }
|
rlm@1
|
3813 break;
|
rlm@1
|
3814 case 0x684:
|
rlm@1
|
3815 case 0x68c:
|
rlm@1
|
3816 // T versions are the same
|
rlm@1
|
3817 case 0x6a4:
|
rlm@1
|
3818 case 0x6ac:
|
rlm@1
|
3819 {
|
rlm@1
|
3820 // STR Rd, [Rn], Rm, ASR #
|
rlm@1
|
3821 int shift = (opcode >> 7) & 31;
|
rlm@1
|
3822 int offset;
|
rlm@1
|
3823 if (shift)
|
rlm@1
|
3824 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
3825 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
3826 offset = 0xFFFFFFFF;
|
rlm@1
|
3827 else
|
rlm@1
|
3828 offset = 0;
|
rlm@1
|
3829 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3830 int base = (opcode >> 16) & 15;
|
rlm@1
|
3831 u32 address = reg[base].I;
|
rlm@1
|
3832 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3833 reg[base].I = address + offset;
|
rlm@1
|
3834 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3835 }
|
rlm@1
|
3836 break;
|
rlm@1
|
3837 case 0x686:
|
rlm@1
|
3838 case 0x68e:
|
rlm@1
|
3839 // T versions are the same
|
rlm@1
|
3840 case 0x6a6:
|
rlm@1
|
3841 case 0x6ae:
|
rlm@1
|
3842 {
|
rlm@1
|
3843 // STR Rd, [Rn], Rm, ROR #
|
rlm@1
|
3844 int shift = (opcode >> 7) & 31;
|
rlm@1
|
3845 u32 value = reg[opcode & 15].I;
|
rlm@1
|
3846 if (shift)
|
rlm@1
|
3847 {
|
rlm@1
|
3848 ROR_VALUE;
|
rlm@1
|
3849 }
|
rlm@1
|
3850 else
|
rlm@1
|
3851 {
|
rlm@1
|
3852 RCR_VALUE;
|
rlm@1
|
3853 }
|
rlm@1
|
3854 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3855 int base = (opcode >> 16) & 15;
|
rlm@1
|
3856 u32 address = reg[base].I;
|
rlm@1
|
3857 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3858 reg[base].I = address + value;
|
rlm@1
|
3859 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3860 }
|
rlm@1
|
3861 break;
|
rlm@1
|
3862 case 0x700:
|
rlm@1
|
3863 case 0x708:
|
rlm@1
|
3864 {
|
rlm@1
|
3865 // STR Rd, [Rn, -Rm, LSL #]
|
rlm@1
|
3866 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
3867 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3868 int base = (opcode >> 16) & 15;
|
rlm@1
|
3869 u32 address = reg[base].I - offset;
|
rlm@1
|
3870 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3871 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3872 }
|
rlm@1
|
3873 break;
|
rlm@1
|
3874 case 0x702:
|
rlm@1
|
3875 case 0x70a:
|
rlm@1
|
3876 {
|
rlm@1
|
3877 // STR Rd, [Rn, -Rm, LSR #]
|
rlm@1
|
3878 int shift = (opcode >> 7) & 31;
|
rlm@1
|
3879 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
3880 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3881 int base = (opcode >> 16) & 15;
|
rlm@1
|
3882 u32 address = reg[base].I - offset;
|
rlm@1
|
3883 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3884 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3885 }
|
rlm@1
|
3886 break;
|
rlm@1
|
3887 case 0x704:
|
rlm@1
|
3888 case 0x70c:
|
rlm@1
|
3889 {
|
rlm@1
|
3890 // STR Rd, [Rn, -Rm, ASR #]
|
rlm@1
|
3891 int shift = (opcode >> 7) & 31;
|
rlm@1
|
3892 int offset;
|
rlm@1
|
3893 if (shift)
|
rlm@1
|
3894 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
3895 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
3896 offset = 0xFFFFFFFF;
|
rlm@1
|
3897 else
|
rlm@1
|
3898 offset = 0;
|
rlm@1
|
3899 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3900 int base = (opcode >> 16) & 15;
|
rlm@1
|
3901 u32 address = reg[base].I - offset;
|
rlm@1
|
3902 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3903 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3904 }
|
rlm@1
|
3905 break;
|
rlm@1
|
3906 case 0x706:
|
rlm@1
|
3907 case 0x70e:
|
rlm@1
|
3908 {
|
rlm@1
|
3909 // STR Rd, [Rn, -Rm, ROR #]
|
rlm@1
|
3910 int shift = (opcode >> 7) & 31;
|
rlm@1
|
3911 u32 value = reg[opcode & 15].I;
|
rlm@1
|
3912 if (shift)
|
rlm@1
|
3913 {
|
rlm@1
|
3914 ROR_VALUE;
|
rlm@1
|
3915 }
|
rlm@1
|
3916 else
|
rlm@1
|
3917 {
|
rlm@1
|
3918 RCR_VALUE;
|
rlm@1
|
3919 }
|
rlm@1
|
3920 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3921 int base = (opcode >> 16) & 15;
|
rlm@1
|
3922 u32 address = reg[base].I - value;
|
rlm@1
|
3923 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3924 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3925 }
|
rlm@1
|
3926 break;
|
rlm@1
|
3927 case 0x720:
|
rlm@1
|
3928 case 0x728:
|
rlm@1
|
3929 {
|
rlm@1
|
3930 // STR Rd, [Rn, -Rm, LSL #]!
|
rlm@1
|
3931 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
3932 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3933 int base = (opcode >> 16) & 15;
|
rlm@1
|
3934 u32 address = reg[base].I - offset;
|
rlm@1
|
3935 reg[base].I = address;
|
rlm@1
|
3936 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3937 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3938 }
|
rlm@1
|
3939 break;
|
rlm@1
|
3940 case 0x722:
|
rlm@1
|
3941 case 0x72a:
|
rlm@1
|
3942 {
|
rlm@1
|
3943 // STR Rd, [Rn, -Rm, LSR #]!
|
rlm@1
|
3944 int shift = (opcode >> 7) & 31;
|
rlm@1
|
3945 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
3946 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3947 int base = (opcode >> 16) & 15;
|
rlm@1
|
3948 u32 address = reg[base].I - offset;
|
rlm@1
|
3949 reg[base].I = address;
|
rlm@1
|
3950 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3951 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3952 }
|
rlm@1
|
3953 break;
|
rlm@1
|
3954 case 0x724:
|
rlm@1
|
3955 case 0x72c:
|
rlm@1
|
3956 {
|
rlm@1
|
3957 // STR Rd, [Rn, -Rm, ASR #]!
|
rlm@1
|
3958 int shift = (opcode >> 7) & 31;
|
rlm@1
|
3959 int offset;
|
rlm@1
|
3960 if (shift)
|
rlm@1
|
3961 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
3962 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
3963 offset = 0xFFFFFFFF;
|
rlm@1
|
3964 else
|
rlm@1
|
3965 offset = 0;
|
rlm@1
|
3966 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3967 int base = (opcode >> 16) & 15;
|
rlm@1
|
3968 u32 address = reg[base].I - offset;
|
rlm@1
|
3969 reg[base].I = address;
|
rlm@1
|
3970 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3971 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3972 }
|
rlm@1
|
3973 break;
|
rlm@1
|
3974 case 0x726:
|
rlm@1
|
3975 case 0x72e:
|
rlm@1
|
3976 {
|
rlm@1
|
3977 // STR Rd, [Rn, -Rm, ROR #]!
|
rlm@1
|
3978 int shift = (opcode >> 7) & 31;
|
rlm@1
|
3979 u32 value = reg[opcode & 15].I;
|
rlm@1
|
3980 if (shift)
|
rlm@1
|
3981 {
|
rlm@1
|
3982 ROR_VALUE;
|
rlm@1
|
3983 }
|
rlm@1
|
3984 else
|
rlm@1
|
3985 {
|
rlm@1
|
3986 RCR_VALUE;
|
rlm@1
|
3987 }
|
rlm@1
|
3988 int dest = (opcode >> 12) & 15;
|
rlm@1
|
3989 int base = (opcode >> 16) & 15;
|
rlm@1
|
3990 u32 address = reg[base].I - value;
|
rlm@1
|
3991 reg[base].I = address;
|
rlm@1
|
3992 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
3993 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
3994 }
|
rlm@1
|
3995 break;
|
rlm@1
|
3996 case 0x780:
|
rlm@1
|
3997 case 0x788:
|
rlm@1
|
3998 {
|
rlm@1
|
3999 // STR Rd, [Rn, Rm, LSL #]
|
rlm@1
|
4000 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
4001 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4002 int base = (opcode >> 16) & 15;
|
rlm@1
|
4003 u32 address = reg[base].I + offset;
|
rlm@1
|
4004 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
4005 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4006 }
|
rlm@1
|
4007 break;
|
rlm@1
|
4008 case 0x782:
|
rlm@1
|
4009 case 0x78a:
|
rlm@1
|
4010 {
|
rlm@1
|
4011 // STR Rd, [Rn, Rm, LSR #]
|
rlm@1
|
4012 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4013 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
4014 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4015 int base = (opcode >> 16) & 15;
|
rlm@1
|
4016 u32 address = reg[base].I + offset;
|
rlm@1
|
4017 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
4018 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4019 }
|
rlm@1
|
4020 break;
|
rlm@1
|
4021 case 0x784:
|
rlm@1
|
4022 case 0x78c:
|
rlm@1
|
4023 {
|
rlm@1
|
4024 // STR Rd, [Rn, Rm, ASR #]
|
rlm@1
|
4025 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4026 int offset;
|
rlm@1
|
4027 if (shift)
|
rlm@1
|
4028 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
4029 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
4030 offset = 0xFFFFFFFF;
|
rlm@1
|
4031 else
|
rlm@1
|
4032 offset = 0;
|
rlm@1
|
4033 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4034 int base = (opcode >> 16) & 15;
|
rlm@1
|
4035 u32 address = reg[base].I + offset;
|
rlm@1
|
4036 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
4037 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4038 }
|
rlm@1
|
4039 break;
|
rlm@1
|
4040 case 0x786:
|
rlm@1
|
4041 case 0x78e:
|
rlm@1
|
4042 {
|
rlm@1
|
4043 // STR Rd, [Rn, Rm, ROR #]
|
rlm@1
|
4044 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4045 u32 value = reg[opcode & 15].I;
|
rlm@1
|
4046 if (shift)
|
rlm@1
|
4047 {
|
rlm@1
|
4048 ROR_VALUE;
|
rlm@1
|
4049 }
|
rlm@1
|
4050 else
|
rlm@1
|
4051 {
|
rlm@1
|
4052 RCR_VALUE;
|
rlm@1
|
4053 }
|
rlm@1
|
4054 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4055 int base = (opcode >> 16) & 15;
|
rlm@1
|
4056 u32 address = reg[base].I + value;
|
rlm@1
|
4057 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
4058 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4059 }
|
rlm@1
|
4060 break;
|
rlm@1
|
4061 case 0x7a0:
|
rlm@1
|
4062 case 0x7a8:
|
rlm@1
|
4063 {
|
rlm@1
|
4064 // STR Rd, [Rn, Rm, LSL #]!
|
rlm@1
|
4065 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
4066 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4067 int base = (opcode >> 16) & 15;
|
rlm@1
|
4068 u32 address = reg[base].I + offset;
|
rlm@1
|
4069 reg[base].I = address;
|
rlm@1
|
4070 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
4071 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4072 }
|
rlm@1
|
4073 break;
|
rlm@1
|
4074 case 0x7a2:
|
rlm@1
|
4075 case 0x7aa:
|
rlm@1
|
4076 {
|
rlm@1
|
4077 // STR Rd, [Rn, Rm, LSR #]!
|
rlm@1
|
4078 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4079 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
4080 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4081 int base = (opcode >> 16) & 15;
|
rlm@1
|
4082 u32 address = reg[base].I + offset;
|
rlm@1
|
4083 reg[base].I = address;
|
rlm@1
|
4084 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
4085 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4086 }
|
rlm@1
|
4087 break;
|
rlm@1
|
4088 case 0x7a4:
|
rlm@1
|
4089 case 0x7ac:
|
rlm@1
|
4090 {
|
rlm@1
|
4091 // STR Rd, [Rn, Rm, ASR #]!
|
rlm@1
|
4092 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4093 int offset;
|
rlm@1
|
4094 if (shift)
|
rlm@1
|
4095 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
4096 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
4097 offset = 0xFFFFFFFF;
|
rlm@1
|
4098 else
|
rlm@1
|
4099 offset = 0;
|
rlm@1
|
4100 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4101 int base = (opcode >> 16) & 15;
|
rlm@1
|
4102 u32 address = reg[base].I + offset;
|
rlm@1
|
4103 reg[base].I = address;
|
rlm@1
|
4104 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
4105 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4106 }
|
rlm@1
|
4107 break;
|
rlm@1
|
4108 case 0x7a6:
|
rlm@1
|
4109 case 0x7ae:
|
rlm@1
|
4110 {
|
rlm@1
|
4111 // STR Rd, [Rn, Rm, ROR #]!
|
rlm@1
|
4112 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4113 u32 value = reg[opcode & 15].I;
|
rlm@1
|
4114 if (shift)
|
rlm@1
|
4115 {
|
rlm@1
|
4116 ROR_VALUE;
|
rlm@1
|
4117 }
|
rlm@1
|
4118 else
|
rlm@1
|
4119 {
|
rlm@1
|
4120 RCR_VALUE;
|
rlm@1
|
4121 }
|
rlm@1
|
4122 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4123 int base = (opcode >> 16) & 15;
|
rlm@1
|
4124 u32 address = reg[base].I + value;
|
rlm@1
|
4125 reg[base].I = address;
|
rlm@1
|
4126 CPUWriteMemory(address, reg[dest].I);
|
rlm@1
|
4127 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4128 }
|
rlm@1
|
4129 break;
|
rlm@1
|
4130 case 0x610:
|
rlm@1
|
4131 case 0x618:
|
rlm@1
|
4132 // T versions are the same
|
rlm@1
|
4133 case 0x630:
|
rlm@1
|
4134 case 0x638:
|
rlm@1
|
4135 {
|
rlm@1
|
4136 // LDR Rd, [Rn], -Rm, LSL #
|
rlm@1
|
4137 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
4138 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4139 int base = (opcode >> 16) & 15;
|
rlm@1
|
4140 u32 address = reg[base].I;
|
rlm@1
|
4141 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4142 if (dest != base)
|
rlm@1
|
4143 reg[base].I = address - offset;
|
rlm@1
|
4144 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4145 if (dest == 15)
|
rlm@1
|
4146 {
|
rlm@1
|
4147 clockTicks += 2;
|
rlm@1
|
4148 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4149 armNextPC = reg[15].I;
|
rlm@1
|
4150 reg[15].I += 4;
|
rlm@1
|
4151 }
|
rlm@1
|
4152 }
|
rlm@1
|
4153 break;
|
rlm@1
|
4154 case 0x612:
|
rlm@1
|
4155 case 0x61a:
|
rlm@1
|
4156 // T versions are the same
|
rlm@1
|
4157 case 0x632:
|
rlm@1
|
4158 case 0x63a:
|
rlm@1
|
4159 {
|
rlm@1
|
4160 // LDR Rd, [Rn], -Rm, LSR #
|
rlm@1
|
4161 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4162 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
4163 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4164 int base = (opcode >> 16) & 15;
|
rlm@1
|
4165 u32 address = reg[base].I;
|
rlm@1
|
4166 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4167 if (dest != base)
|
rlm@1
|
4168 reg[base].I = address - offset;
|
rlm@1
|
4169 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4170 if (dest == 15)
|
rlm@1
|
4171 {
|
rlm@1
|
4172 clockTicks += 2;
|
rlm@1
|
4173 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4174 armNextPC = reg[15].I;
|
rlm@1
|
4175 reg[15].I += 4;
|
rlm@1
|
4176 }
|
rlm@1
|
4177 }
|
rlm@1
|
4178 break;
|
rlm@1
|
4179 case 0x614:
|
rlm@1
|
4180 case 0x61c:
|
rlm@1
|
4181 // T versions are the same
|
rlm@1
|
4182 case 0x634:
|
rlm@1
|
4183 case 0x63c:
|
rlm@1
|
4184 {
|
rlm@1
|
4185 // LDR Rd, [Rn], -Rm, ASR #
|
rlm@1
|
4186 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4187 int offset;
|
rlm@1
|
4188 if (shift)
|
rlm@1
|
4189 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
4190 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
4191 offset = 0xFFFFFFFF;
|
rlm@1
|
4192 else
|
rlm@1
|
4193 offset = 0;
|
rlm@1
|
4194 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4195 int base = (opcode >> 16) & 15;
|
rlm@1
|
4196 u32 address = reg[base].I;
|
rlm@1
|
4197 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4198 if (dest != base)
|
rlm@1
|
4199 reg[base].I = address - offset;
|
rlm@1
|
4200 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4201 if (dest == 15)
|
rlm@1
|
4202 {
|
rlm@1
|
4203 clockTicks += 2;
|
rlm@1
|
4204 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4205 armNextPC = reg[15].I;
|
rlm@1
|
4206 reg[15].I += 4;
|
rlm@1
|
4207 }
|
rlm@1
|
4208 }
|
rlm@1
|
4209 break;
|
rlm@1
|
4210 case 0x616:
|
rlm@1
|
4211 case 0x61e:
|
rlm@1
|
4212 // T versions are the same
|
rlm@1
|
4213 case 0x636:
|
rlm@1
|
4214 case 0x63e:
|
rlm@1
|
4215 {
|
rlm@1
|
4216 // LDR Rd, [Rn], -Rm, ROR #
|
rlm@1
|
4217 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4218 u32 value = reg[opcode & 15].I;
|
rlm@1
|
4219 if (shift)
|
rlm@1
|
4220 {
|
rlm@1
|
4221 ROR_VALUE;
|
rlm@1
|
4222 }
|
rlm@1
|
4223 else
|
rlm@1
|
4224 {
|
rlm@1
|
4225 RCR_VALUE;
|
rlm@1
|
4226 }
|
rlm@1
|
4227 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4228 int base = (opcode >> 16) & 15;
|
rlm@1
|
4229 u32 address = reg[base].I;
|
rlm@1
|
4230 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4231 if (dest != base)
|
rlm@1
|
4232 reg[base].I = address - value;
|
rlm@1
|
4233 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4234 if (dest == 15)
|
rlm@1
|
4235 {
|
rlm@1
|
4236 clockTicks += 2;
|
rlm@1
|
4237 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4238 armNextPC = reg[15].I;
|
rlm@1
|
4239 reg[15].I += 4;
|
rlm@1
|
4240 }
|
rlm@1
|
4241 }
|
rlm@1
|
4242 break;
|
rlm@1
|
4243 case 0x690:
|
rlm@1
|
4244 case 0x698:
|
rlm@1
|
4245 // T versions are the same
|
rlm@1
|
4246 case 0x6b0:
|
rlm@1
|
4247 case 0x6b8:
|
rlm@1
|
4248 {
|
rlm@1
|
4249 // LDR Rd, [Rn], Rm, LSL #
|
rlm@1
|
4250 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
4251 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4252 int base = (opcode >> 16) & 15;
|
rlm@1
|
4253 u32 address = reg[base].I;
|
rlm@1
|
4254 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4255 if (dest != base)
|
rlm@1
|
4256 reg[base].I = address + offset;
|
rlm@1
|
4257 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4258 if (dest == 15)
|
rlm@1
|
4259 {
|
rlm@1
|
4260 clockTicks += 2;
|
rlm@1
|
4261 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4262 armNextPC = reg[15].I;
|
rlm@1
|
4263 reg[15].I += 4;
|
rlm@1
|
4264 }
|
rlm@1
|
4265 }
|
rlm@1
|
4266 break;
|
rlm@1
|
4267 case 0x692:
|
rlm@1
|
4268 case 0x69a:
|
rlm@1
|
4269 // T versions are the same
|
rlm@1
|
4270 case 0x6b2:
|
rlm@1
|
4271 case 0x6ba:
|
rlm@1
|
4272 {
|
rlm@1
|
4273 // LDR Rd, [Rn], Rm, LSR #
|
rlm@1
|
4274 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4275 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
4276 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4277 int base = (opcode >> 16) & 15;
|
rlm@1
|
4278 u32 address = reg[base].I;
|
rlm@1
|
4279 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4280 if (dest != base)
|
rlm@1
|
4281 reg[base].I = address + offset;
|
rlm@1
|
4282 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4283 if (dest == 15)
|
rlm@1
|
4284 {
|
rlm@1
|
4285 clockTicks += 2;
|
rlm@1
|
4286 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4287 armNextPC = reg[15].I;
|
rlm@1
|
4288 reg[15].I += 4;
|
rlm@1
|
4289 }
|
rlm@1
|
4290 }
|
rlm@1
|
4291 break;
|
rlm@1
|
4292 case 0x694:
|
rlm@1
|
4293 case 0x69c:
|
rlm@1
|
4294 // T versions are the same
|
rlm@1
|
4295 case 0x6b4:
|
rlm@1
|
4296 case 0x6bc:
|
rlm@1
|
4297 {
|
rlm@1
|
4298 // LDR Rd, [Rn], Rm, ASR #
|
rlm@1
|
4299 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4300 int offset;
|
rlm@1
|
4301 if (shift)
|
rlm@1
|
4302 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
4303 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
4304 offset = 0xFFFFFFFF;
|
rlm@1
|
4305 else
|
rlm@1
|
4306 offset = 0;
|
rlm@1
|
4307 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4308 int base = (opcode >> 16) & 15;
|
rlm@1
|
4309 u32 address = reg[base].I;
|
rlm@1
|
4310 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4311 if (dest != base)
|
rlm@1
|
4312 reg[base].I = address + offset;
|
rlm@1
|
4313 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4314 if (dest == 15)
|
rlm@1
|
4315 {
|
rlm@1
|
4316 clockTicks += 2;
|
rlm@1
|
4317 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4318 armNextPC = reg[15].I;
|
rlm@1
|
4319 reg[15].I += 4;
|
rlm@1
|
4320 }
|
rlm@1
|
4321 }
|
rlm@1
|
4322 break;
|
rlm@1
|
4323 case 0x696:
|
rlm@1
|
4324 case 0x69e:
|
rlm@1
|
4325 // T versions are the same
|
rlm@1
|
4326 case 0x6b6:
|
rlm@1
|
4327 case 0x6be:
|
rlm@1
|
4328 {
|
rlm@1
|
4329 // LDR Rd, [Rn], Rm, ROR #
|
rlm@1
|
4330 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4331 u32 value = reg[opcode & 15].I;
|
rlm@1
|
4332 if (shift)
|
rlm@1
|
4333 {
|
rlm@1
|
4334 ROR_VALUE;
|
rlm@1
|
4335 }
|
rlm@1
|
4336 else
|
rlm@1
|
4337 {
|
rlm@1
|
4338 RCR_VALUE;
|
rlm@1
|
4339 }
|
rlm@1
|
4340 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4341 int base = (opcode >> 16) & 15;
|
rlm@1
|
4342 u32 address = reg[base].I;
|
rlm@1
|
4343 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4344 if (dest != base)
|
rlm@1
|
4345 reg[base].I = address + value;
|
rlm@1
|
4346 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4347 if (dest == 15)
|
rlm@1
|
4348 {
|
rlm@1
|
4349 clockTicks += 2;
|
rlm@1
|
4350 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4351 armNextPC = reg[15].I;
|
rlm@1
|
4352 reg[15].I += 4;
|
rlm@1
|
4353 }
|
rlm@1
|
4354 }
|
rlm@1
|
4355 break;
|
rlm@1
|
4356 case 0x710:
|
rlm@1
|
4357 case 0x718:
|
rlm@1
|
4358 {
|
rlm@1
|
4359 // LDR Rd, [Rn, -Rm, LSL #]
|
rlm@1
|
4360 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
4361 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4362 int base = (opcode >> 16) & 15;
|
rlm@1
|
4363 u32 address = reg[base].I - offset;
|
rlm@1
|
4364 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4365 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4366 if (dest == 15)
|
rlm@1
|
4367 {
|
rlm@1
|
4368 clockTicks += 2;
|
rlm@1
|
4369 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4370 armNextPC = reg[15].I;
|
rlm@1
|
4371 reg[15].I += 4;
|
rlm@1
|
4372 }
|
rlm@1
|
4373 }
|
rlm@1
|
4374 break;
|
rlm@1
|
4375 case 0x712:
|
rlm@1
|
4376 case 0x71a:
|
rlm@1
|
4377 {
|
rlm@1
|
4378 // LDR Rd, [Rn, -Rm, LSR #]
|
rlm@1
|
4379 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4380 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
4381 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4382 int base = (opcode >> 16) & 15;
|
rlm@1
|
4383 u32 address = reg[base].I - offset;
|
rlm@1
|
4384 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4385 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4386 if (dest == 15)
|
rlm@1
|
4387 {
|
rlm@1
|
4388 clockTicks += 2;
|
rlm@1
|
4389 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4390 armNextPC = reg[15].I;
|
rlm@1
|
4391 reg[15].I += 4;
|
rlm@1
|
4392 }
|
rlm@1
|
4393 }
|
rlm@1
|
4394 break;
|
rlm@1
|
4395 case 0x714:
|
rlm@1
|
4396 case 0x71c:
|
rlm@1
|
4397 {
|
rlm@1
|
4398 // LDR Rd, [Rn, -Rm, ASR #]
|
rlm@1
|
4399 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4400 int offset;
|
rlm@1
|
4401 if (shift)
|
rlm@1
|
4402 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
4403 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
4404 offset = 0xFFFFFFFF;
|
rlm@1
|
4405 else
|
rlm@1
|
4406 offset = 0;
|
rlm@1
|
4407 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4408 int base = (opcode >> 16) & 15;
|
rlm@1
|
4409 u32 address = reg[base].I - offset;
|
rlm@1
|
4410 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4411 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4412 if (dest == 15)
|
rlm@1
|
4413 {
|
rlm@1
|
4414 clockTicks += 2;
|
rlm@1
|
4415 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4416 armNextPC = reg[15].I;
|
rlm@1
|
4417 reg[15].I += 4;
|
rlm@1
|
4418 }
|
rlm@1
|
4419 }
|
rlm@1
|
4420 break;
|
rlm@1
|
4421 case 0x716:
|
rlm@1
|
4422 case 0x71e:
|
rlm@1
|
4423 {
|
rlm@1
|
4424 // LDR Rd, [Rn, -Rm, ROR #]
|
rlm@1
|
4425 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4426 u32 value = reg[opcode & 15].I;
|
rlm@1
|
4427 if (shift)
|
rlm@1
|
4428 {
|
rlm@1
|
4429 ROR_VALUE;
|
rlm@1
|
4430 }
|
rlm@1
|
4431 else
|
rlm@1
|
4432 {
|
rlm@1
|
4433 RCR_VALUE;
|
rlm@1
|
4434 }
|
rlm@1
|
4435 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4436 int base = (opcode >> 16) & 15;
|
rlm@1
|
4437 u32 address = reg[base].I - value;
|
rlm@1
|
4438 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4439 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4440 if (dest == 15)
|
rlm@1
|
4441 {
|
rlm@1
|
4442 clockTicks += 2;
|
rlm@1
|
4443 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4444 armNextPC = reg[15].I;
|
rlm@1
|
4445 reg[15].I += 4;
|
rlm@1
|
4446 }
|
rlm@1
|
4447 }
|
rlm@1
|
4448 break;
|
rlm@1
|
4449 case 0x730:
|
rlm@1
|
4450 case 0x738:
|
rlm@1
|
4451 {
|
rlm@1
|
4452 // LDR Rd, [Rn, -Rm, LSL #]!
|
rlm@1
|
4453 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
4454 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4455 int base = (opcode >> 16) & 15;
|
rlm@1
|
4456 u32 address = reg[base].I - offset;
|
rlm@1
|
4457 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4458 if (dest != base)
|
rlm@1
|
4459 reg[base].I = address;
|
rlm@1
|
4460 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4461 if (dest == 15)
|
rlm@1
|
4462 {
|
rlm@1
|
4463 clockTicks += 2;
|
rlm@1
|
4464 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4465 armNextPC = reg[15].I;
|
rlm@1
|
4466 reg[15].I += 4;
|
rlm@1
|
4467 }
|
rlm@1
|
4468 }
|
rlm@1
|
4469 break;
|
rlm@1
|
4470 case 0x732:
|
rlm@1
|
4471 case 0x73a:
|
rlm@1
|
4472 {
|
rlm@1
|
4473 // LDR Rd, [Rn, -Rm, LSR #]!
|
rlm@1
|
4474 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4475 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
4476 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4477 int base = (opcode >> 16) & 15;
|
rlm@1
|
4478 u32 address = reg[base].I - offset;
|
rlm@1
|
4479 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4480 if (dest != base)
|
rlm@1
|
4481 reg[base].I = address;
|
rlm@1
|
4482 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4483 if (dest == 15)
|
rlm@1
|
4484 {
|
rlm@1
|
4485 clockTicks += 2;
|
rlm@1
|
4486 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4487 armNextPC = reg[15].I;
|
rlm@1
|
4488 reg[15].I += 4;
|
rlm@1
|
4489 }
|
rlm@1
|
4490 }
|
rlm@1
|
4491 break;
|
rlm@1
|
4492 case 0x734:
|
rlm@1
|
4493 case 0x73c:
|
rlm@1
|
4494 {
|
rlm@1
|
4495 // LDR Rd, [Rn, -Rm, ASR #]!
|
rlm@1
|
4496 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4497 int offset;
|
rlm@1
|
4498 if (shift)
|
rlm@1
|
4499 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
4500 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
4501 offset = 0xFFFFFFFF;
|
rlm@1
|
4502 else
|
rlm@1
|
4503 offset = 0;
|
rlm@1
|
4504 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4505 int base = (opcode >> 16) & 15;
|
rlm@1
|
4506 u32 address = reg[base].I - offset;
|
rlm@1
|
4507 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4508 if (dest != base)
|
rlm@1
|
4509 reg[base].I = address;
|
rlm@1
|
4510 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4511 if (dest == 15)
|
rlm@1
|
4512 {
|
rlm@1
|
4513 clockTicks += 2;
|
rlm@1
|
4514 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4515 armNextPC = reg[15].I;
|
rlm@1
|
4516 reg[15].I += 4;
|
rlm@1
|
4517 }
|
rlm@1
|
4518 }
|
rlm@1
|
4519 break;
|
rlm@1
|
4520 case 0x736:
|
rlm@1
|
4521 case 0x73e:
|
rlm@1
|
4522 {
|
rlm@1
|
4523 // LDR Rd, [Rn, -Rm, ROR #]!
|
rlm@1
|
4524 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4525 u32 value = reg[opcode & 15].I;
|
rlm@1
|
4526 if (shift)
|
rlm@1
|
4527 {
|
rlm@1
|
4528 ROR_VALUE;
|
rlm@1
|
4529 }
|
rlm@1
|
4530 else
|
rlm@1
|
4531 {
|
rlm@1
|
4532 RCR_VALUE;
|
rlm@1
|
4533 }
|
rlm@1
|
4534 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4535 int base = (opcode >> 16) & 15;
|
rlm@1
|
4536 u32 address = reg[base].I - value;
|
rlm@1
|
4537 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4538 if (dest != base)
|
rlm@1
|
4539 reg[base].I = address;
|
rlm@1
|
4540 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4541 if (dest == 15)
|
rlm@1
|
4542 {
|
rlm@1
|
4543 clockTicks += 2;
|
rlm@1
|
4544 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4545 armNextPC = reg[15].I;
|
rlm@1
|
4546 reg[15].I += 4;
|
rlm@1
|
4547 }
|
rlm@1
|
4548 }
|
rlm@1
|
4549 break;
|
rlm@1
|
4550 case 0x790:
|
rlm@1
|
4551 case 0x798:
|
rlm@1
|
4552 {
|
rlm@1
|
4553 // LDR Rd, [Rn, Rm, LSL #]
|
rlm@1
|
4554 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
4555 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4556 int base = (opcode >> 16) & 15;
|
rlm@1
|
4557 u32 address = reg[base].I + offset;
|
rlm@1
|
4558 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4559 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4560 if (dest == 15)
|
rlm@1
|
4561 {
|
rlm@1
|
4562 clockTicks += 2;
|
rlm@1
|
4563 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4564 armNextPC = reg[15].I;
|
rlm@1
|
4565 reg[15].I += 4;
|
rlm@1
|
4566 }
|
rlm@1
|
4567 }
|
rlm@1
|
4568 break;
|
rlm@1
|
4569 case 0x792:
|
rlm@1
|
4570 case 0x79a:
|
rlm@1
|
4571 {
|
rlm@1
|
4572 // LDR Rd, [Rn, Rm, LSR #]
|
rlm@1
|
4573 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4574 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
4575 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4576 int base = (opcode >> 16) & 15;
|
rlm@1
|
4577 u32 address = reg[base].I + offset;
|
rlm@1
|
4578 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4579 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4580 if (dest == 15)
|
rlm@1
|
4581 {
|
rlm@1
|
4582 clockTicks += 2;
|
rlm@1
|
4583 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4584 armNextPC = reg[15].I;
|
rlm@1
|
4585 reg[15].I += 4;
|
rlm@1
|
4586 }
|
rlm@1
|
4587 }
|
rlm@1
|
4588 break;
|
rlm@1
|
4589 case 0x794:
|
rlm@1
|
4590 case 0x79c:
|
rlm@1
|
4591 {
|
rlm@1
|
4592 // LDR Rd, [Rn, Rm, ASR #]
|
rlm@1
|
4593 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4594 int offset;
|
rlm@1
|
4595 if (shift)
|
rlm@1
|
4596 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
4597 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
4598 offset = 0xFFFFFFFF;
|
rlm@1
|
4599 else
|
rlm@1
|
4600 offset = 0;
|
rlm@1
|
4601 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4602 int base = (opcode >> 16) & 15;
|
rlm@1
|
4603 u32 address = reg[base].I + offset;
|
rlm@1
|
4604 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4605 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4606 if (dest == 15)
|
rlm@1
|
4607 {
|
rlm@1
|
4608 clockTicks += 2;
|
rlm@1
|
4609 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4610 armNextPC = reg[15].I;
|
rlm@1
|
4611 reg[15].I += 4;
|
rlm@1
|
4612 }
|
rlm@1
|
4613 }
|
rlm@1
|
4614 break;
|
rlm@1
|
4615 case 0x796:
|
rlm@1
|
4616 case 0x79e:
|
rlm@1
|
4617 {
|
rlm@1
|
4618 // LDR Rd, [Rn, Rm, ROR #]
|
rlm@1
|
4619 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4620 u32 value = reg[opcode & 15].I;
|
rlm@1
|
4621 if (shift)
|
rlm@1
|
4622 {
|
rlm@1
|
4623 ROR_VALUE;
|
rlm@1
|
4624 }
|
rlm@1
|
4625 else
|
rlm@1
|
4626 {
|
rlm@1
|
4627 RCR_VALUE;
|
rlm@1
|
4628 }
|
rlm@1
|
4629 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4630 int base = (opcode >> 16) & 15;
|
rlm@1
|
4631 u32 address = reg[base].I + value;
|
rlm@1
|
4632 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4633 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4634 if (dest == 15)
|
rlm@1
|
4635 {
|
rlm@1
|
4636 clockTicks += 2;
|
rlm@1
|
4637 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4638 armNextPC = reg[15].I;
|
rlm@1
|
4639 reg[15].I += 4;
|
rlm@1
|
4640 }
|
rlm@1
|
4641 }
|
rlm@1
|
4642 break;
|
rlm@1
|
4643 case 0x7b0:
|
rlm@1
|
4644 case 0x7b8:
|
rlm@1
|
4645 {
|
rlm@1
|
4646 // LDR Rd, [Rn, Rm, LSL #]!
|
rlm@1
|
4647 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
4648 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4649 int base = (opcode >> 16) & 15;
|
rlm@1
|
4650 u32 address = reg[base].I + offset;
|
rlm@1
|
4651 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4652 if (dest != base)
|
rlm@1
|
4653 reg[base].I = address;
|
rlm@1
|
4654 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4655 if (dest == 15)
|
rlm@1
|
4656 {
|
rlm@1
|
4657 clockTicks += 2;
|
rlm@1
|
4658 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4659 armNextPC = reg[15].I;
|
rlm@1
|
4660 reg[15].I += 4;
|
rlm@1
|
4661 }
|
rlm@1
|
4662 }
|
rlm@1
|
4663 break;
|
rlm@1
|
4664 case 0x7b2:
|
rlm@1
|
4665 case 0x7ba:
|
rlm@1
|
4666 {
|
rlm@1
|
4667 // LDR Rd, [Rn, Rm, LSR #]!
|
rlm@1
|
4668 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4669 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
4670 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4671 int base = (opcode >> 16) & 15;
|
rlm@1
|
4672 u32 address = reg[base].I + offset;
|
rlm@1
|
4673 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4674 if (dest != base)
|
rlm@1
|
4675 reg[base].I = address;
|
rlm@1
|
4676 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4677 if (dest == 15)
|
rlm@1
|
4678 {
|
rlm@1
|
4679 clockTicks += 2;
|
rlm@1
|
4680 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4681 armNextPC = reg[15].I;
|
rlm@1
|
4682 reg[15].I += 4;
|
rlm@1
|
4683 }
|
rlm@1
|
4684 }
|
rlm@1
|
4685 break;
|
rlm@1
|
4686 case 0x7b4:
|
rlm@1
|
4687 case 0x7bc:
|
rlm@1
|
4688 {
|
rlm@1
|
4689 // LDR Rd, [Rn, Rm, ASR #]!
|
rlm@1
|
4690 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4691 int offset;
|
rlm@1
|
4692 if (shift)
|
rlm@1
|
4693 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
4694 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
4695 offset = 0xFFFFFFFF;
|
rlm@1
|
4696 else
|
rlm@1
|
4697 offset = 0;
|
rlm@1
|
4698 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4699 int base = (opcode >> 16) & 15;
|
rlm@1
|
4700 u32 address = reg[base].I + offset;
|
rlm@1
|
4701 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4702 if (dest != base)
|
rlm@1
|
4703 reg[base].I = address;
|
rlm@1
|
4704 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4705 if (dest == 15)
|
rlm@1
|
4706 {
|
rlm@1
|
4707 clockTicks += 2;
|
rlm@1
|
4708 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4709 armNextPC = reg[15].I;
|
rlm@1
|
4710 reg[15].I += 4;
|
rlm@1
|
4711 }
|
rlm@1
|
4712 }
|
rlm@1
|
4713 break;
|
rlm@1
|
4714 case 0x7b6:
|
rlm@1
|
4715 case 0x7be:
|
rlm@1
|
4716 {
|
rlm@1
|
4717 // LDR Rd, [Rn, Rm, ROR #]!
|
rlm@1
|
4718 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4719 u32 value = reg[opcode & 15].I;
|
rlm@1
|
4720 if (shift)
|
rlm@1
|
4721 {
|
rlm@1
|
4722 ROR_VALUE;
|
rlm@1
|
4723 }
|
rlm@1
|
4724 else
|
rlm@1
|
4725 {
|
rlm@1
|
4726 RCR_VALUE;
|
rlm@1
|
4727 }
|
rlm@1
|
4728 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4729 int base = (opcode >> 16) & 15;
|
rlm@1
|
4730 u32 address = reg[base].I + value;
|
rlm@1
|
4731 reg[dest].I = CPUReadMemory(address);
|
rlm@1
|
4732 if (dest != base)
|
rlm@1
|
4733 reg[base].I = address;
|
rlm@1
|
4734 clockTicks += 3 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
4735 if (dest == 15)
|
rlm@1
|
4736 {
|
rlm@1
|
4737 clockTicks += 2;
|
rlm@1
|
4738 reg[15].I &= 0xFFFFFFFC;
|
rlm@1
|
4739 armNextPC = reg[15].I;
|
rlm@1
|
4740 reg[15].I += 4;
|
rlm@1
|
4741 }
|
rlm@1
|
4742 }
|
rlm@1
|
4743 break;
|
rlm@1
|
4744 case 0x640:
|
rlm@1
|
4745 case 0x648:
|
rlm@1
|
4746 // T versions are the same
|
rlm@1
|
4747 case 0x660:
|
rlm@1
|
4748 case 0x668:
|
rlm@1
|
4749 {
|
rlm@1
|
4750 // STRB Rd, [Rn], -Rm, LSL #
|
rlm@1
|
4751 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
4752 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4753 int base = (opcode >> 16) & 15;
|
rlm@1
|
4754 u32 address = reg[base].I;
|
rlm@1
|
4755 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
4756 reg[base].I = address - offset;
|
rlm@1
|
4757 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
4758 }
|
rlm@1
|
4759 break;
|
rlm@1
|
4760 case 0x642:
|
rlm@1
|
4761 case 0x64a:
|
rlm@1
|
4762 // T versions are the same
|
rlm@1
|
4763 case 0x662:
|
rlm@1
|
4764 case 0x66a:
|
rlm@1
|
4765 {
|
rlm@1
|
4766 // STRB Rd, [Rn], -Rm, LSR #
|
rlm@1
|
4767 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4768 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
4769 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4770 int base = (opcode >> 16) & 15;
|
rlm@1
|
4771 u32 address = reg[base].I;
|
rlm@1
|
4772 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
4773 reg[base].I = address - offset;
|
rlm@1
|
4774 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
4775 }
|
rlm@1
|
4776 break;
|
rlm@1
|
4777 case 0x644:
|
rlm@1
|
4778 case 0x64c:
|
rlm@1
|
4779 // T versions are the same
|
rlm@1
|
4780 case 0x664:
|
rlm@1
|
4781 case 0x66c:
|
rlm@1
|
4782 {
|
rlm@1
|
4783 // STRB Rd, [Rn], -Rm, ASR #
|
rlm@1
|
4784 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4785 int offset;
|
rlm@1
|
4786 if (shift)
|
rlm@1
|
4787 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
4788 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
4789 offset = 0xFFFFFFFF;
|
rlm@1
|
4790 else
|
rlm@1
|
4791 offset = 0;
|
rlm@1
|
4792 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4793 int base = (opcode >> 16) & 15;
|
rlm@1
|
4794 u32 address = reg[base].I;
|
rlm@1
|
4795 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
4796 reg[base].I = address - offset;
|
rlm@1
|
4797 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
4798 }
|
rlm@1
|
4799 break;
|
rlm@1
|
4800 case 0x646:
|
rlm@1
|
4801 case 0x64e:
|
rlm@1
|
4802 // T versions are the same
|
rlm@1
|
4803 case 0x666:
|
rlm@1
|
4804 case 0x66e:
|
rlm@1
|
4805 {
|
rlm@1
|
4806 // STRB Rd, [Rn], -Rm, ROR #
|
rlm@1
|
4807 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4808 u32 value = reg[opcode & 15].I;
|
rlm@1
|
4809 if (shift)
|
rlm@1
|
4810 {
|
rlm@1
|
4811 ROR_VALUE;
|
rlm@1
|
4812 }
|
rlm@1
|
4813 else
|
rlm@1
|
4814 {
|
rlm@1
|
4815 RCR_VALUE;
|
rlm@1
|
4816 }
|
rlm@1
|
4817 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4818 int base = (opcode >> 16) & 15;
|
rlm@1
|
4819 u32 address = reg[base].I;
|
rlm@1
|
4820 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
4821 reg[base].I = address - value;
|
rlm@1
|
4822 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
4823 }
|
rlm@1
|
4824 break;
|
rlm@1
|
4825 case 0x6c0:
|
rlm@1
|
4826 case 0x6c8:
|
rlm@1
|
4827 // T versions are the same
|
rlm@1
|
4828 case 0x6e0:
|
rlm@1
|
4829 case 0x6e8:
|
rlm@1
|
4830 {
|
rlm@1
|
4831 // STRB Rd, [Rn], Rm, LSL #
|
rlm@1
|
4832 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
4833 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4834 int base = (opcode >> 16) & 15;
|
rlm@1
|
4835 u32 address = reg[base].I;
|
rlm@1
|
4836 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
4837 reg[base].I = address + offset;
|
rlm@1
|
4838 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
4839 }
|
rlm@1
|
4840 break;
|
rlm@1
|
4841 case 0x6c2:
|
rlm@1
|
4842 case 0x6ca:
|
rlm@1
|
4843 // T versions are the same
|
rlm@1
|
4844 case 0x6e2:
|
rlm@1
|
4845 case 0x6ea:
|
rlm@1
|
4846 {
|
rlm@1
|
4847 // STRB Rd, [Rn], Rm, LSR #
|
rlm@1
|
4848 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4849 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
4850 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4851 int base = (opcode >> 16) & 15;
|
rlm@1
|
4852 u32 address = reg[base].I;
|
rlm@1
|
4853 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
4854 reg[base].I = address + offset;
|
rlm@1
|
4855 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
4856 }
|
rlm@1
|
4857 break;
|
rlm@1
|
4858 case 0x6c4:
|
rlm@1
|
4859 case 0x6cc:
|
rlm@1
|
4860 // T versions are the same
|
rlm@1
|
4861 case 0x6e4:
|
rlm@1
|
4862 case 0x6ec:
|
rlm@1
|
4863 {
|
rlm@1
|
4864 // STR Rd, [Rn], Rm, ASR #
|
rlm@1
|
4865 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4866 int offset;
|
rlm@1
|
4867 if (shift)
|
rlm@1
|
4868 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
4869 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
4870 offset = 0xFFFFFFFF;
|
rlm@1
|
4871 else
|
rlm@1
|
4872 offset = 0;
|
rlm@1
|
4873 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4874 int base = (opcode >> 16) & 15;
|
rlm@1
|
4875 u32 address = reg[base].I;
|
rlm@1
|
4876 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
4877 reg[base].I = address + offset;
|
rlm@1
|
4878 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
4879 }
|
rlm@1
|
4880 break;
|
rlm@1
|
4881 case 0x6c6:
|
rlm@1
|
4882 case 0x6ce:
|
rlm@1
|
4883 // T versions are the same
|
rlm@1
|
4884 case 0x6e6:
|
rlm@1
|
4885 case 0x6ee:
|
rlm@1
|
4886 {
|
rlm@1
|
4887 // STRB Rd, [Rn], Rm, ROR #
|
rlm@1
|
4888 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4889 u32 value = reg[opcode & 15].I;
|
rlm@1
|
4890 if (shift)
|
rlm@1
|
4891 {
|
rlm@1
|
4892 ROR_VALUE;
|
rlm@1
|
4893 }
|
rlm@1
|
4894 else
|
rlm@1
|
4895 {
|
rlm@1
|
4896 RCR_VALUE;
|
rlm@1
|
4897 }
|
rlm@1
|
4898 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4899 int base = (opcode >> 16) & 15;
|
rlm@1
|
4900 u32 address = reg[base].I;
|
rlm@1
|
4901 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
4902 reg[base].I = address + value;
|
rlm@1
|
4903 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
4904 }
|
rlm@1
|
4905 break;
|
rlm@1
|
4906 case 0x740:
|
rlm@1
|
4907 case 0x748:
|
rlm@1
|
4908 {
|
rlm@1
|
4909 // STRB Rd, [Rn, -Rm, LSL #]
|
rlm@1
|
4910 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
4911 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4912 int base = (opcode >> 16) & 15;
|
rlm@1
|
4913 u32 address = reg[base].I - offset;
|
rlm@1
|
4914 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
4915 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
4916 }
|
rlm@1
|
4917 break;
|
rlm@1
|
4918 case 0x742:
|
rlm@1
|
4919 case 0x74a:
|
rlm@1
|
4920 {
|
rlm@1
|
4921 // STRB Rd, [Rn, -Rm, LSR #]
|
rlm@1
|
4922 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4923 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
4924 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4925 int base = (opcode >> 16) & 15;
|
rlm@1
|
4926 u32 address = reg[base].I - offset;
|
rlm@1
|
4927 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
4928 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
4929 }
|
rlm@1
|
4930 break;
|
rlm@1
|
4931 case 0x744:
|
rlm@1
|
4932 case 0x74c:
|
rlm@1
|
4933 {
|
rlm@1
|
4934 // STRB Rd, [Rn, -Rm, ASR #]
|
rlm@1
|
4935 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4936 int offset;
|
rlm@1
|
4937 if (shift)
|
rlm@1
|
4938 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
4939 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
4940 offset = 0xFFFFFFFF;
|
rlm@1
|
4941 else
|
rlm@1
|
4942 offset = 0;
|
rlm@1
|
4943 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4944 int base = (opcode >> 16) & 15;
|
rlm@1
|
4945 u32 address = reg[base].I - offset;
|
rlm@1
|
4946 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
4947 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
4948 }
|
rlm@1
|
4949 break;
|
rlm@1
|
4950 case 0x746:
|
rlm@1
|
4951 case 0x74e:
|
rlm@1
|
4952 {
|
rlm@1
|
4953 // STRB Rd, [Rn, -Rm, ROR #]
|
rlm@1
|
4954 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4955 u32 value = reg[opcode & 15].I;
|
rlm@1
|
4956 if (shift)
|
rlm@1
|
4957 {
|
rlm@1
|
4958 ROR_VALUE;
|
rlm@1
|
4959 }
|
rlm@1
|
4960 else
|
rlm@1
|
4961 {
|
rlm@1
|
4962 RCR_VALUE;
|
rlm@1
|
4963 }
|
rlm@1
|
4964 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4965 int base = (opcode >> 16) & 15;
|
rlm@1
|
4966 u32 address = reg[base].I - value;
|
rlm@1
|
4967 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
4968 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
4969 }
|
rlm@1
|
4970 break;
|
rlm@1
|
4971 case 0x760:
|
rlm@1
|
4972 case 0x768:
|
rlm@1
|
4973 {
|
rlm@1
|
4974 // STRB Rd, [Rn, -Rm, LSL #]!
|
rlm@1
|
4975 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
4976 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4977 int base = (opcode >> 16) & 15;
|
rlm@1
|
4978 u32 address = reg[base].I - offset;
|
rlm@1
|
4979 reg[base].I = address;
|
rlm@1
|
4980 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
4981 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
4982 }
|
rlm@1
|
4983 break;
|
rlm@1
|
4984 case 0x762:
|
rlm@1
|
4985 case 0x76a:
|
rlm@1
|
4986 {
|
rlm@1
|
4987 // STRB Rd, [Rn, -Rm, LSR #]!
|
rlm@1
|
4988 int shift = (opcode >> 7) & 31;
|
rlm@1
|
4989 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
4990 int dest = (opcode >> 12) & 15;
|
rlm@1
|
4991 int base = (opcode >> 16) & 15;
|
rlm@1
|
4992 u32 address = reg[base].I - offset;
|
rlm@1
|
4993 reg[base].I = address;
|
rlm@1
|
4994 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
4995 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
4996 }
|
rlm@1
|
4997 break;
|
rlm@1
|
4998 case 0x764:
|
rlm@1
|
4999 case 0x76c:
|
rlm@1
|
5000 {
|
rlm@1
|
5001 // STRB Rd, [Rn, -Rm, ASR #]!
|
rlm@1
|
5002 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5003 int offset;
|
rlm@1
|
5004 if (shift)
|
rlm@1
|
5005 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
5006 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
5007 offset = 0xFFFFFFFF;
|
rlm@1
|
5008 else
|
rlm@1
|
5009 offset = 0;
|
rlm@1
|
5010 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5011 int base = (opcode >> 16) & 15;
|
rlm@1
|
5012 u32 address = reg[base].I - offset;
|
rlm@1
|
5013 reg[base].I = address;
|
rlm@1
|
5014 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
5015 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5016 }
|
rlm@1
|
5017 break;
|
rlm@1
|
5018 case 0x766:
|
rlm@1
|
5019 case 0x76e:
|
rlm@1
|
5020 {
|
rlm@1
|
5021 // STRB Rd, [Rn, -Rm, ROR #]!
|
rlm@1
|
5022 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5023 u32 value = reg[opcode & 15].I;
|
rlm@1
|
5024 if (shift)
|
rlm@1
|
5025 {
|
rlm@1
|
5026 ROR_VALUE;
|
rlm@1
|
5027 }
|
rlm@1
|
5028 else
|
rlm@1
|
5029 {
|
rlm@1
|
5030 RCR_VALUE;
|
rlm@1
|
5031 }
|
rlm@1
|
5032 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5033 int base = (opcode >> 16) & 15;
|
rlm@1
|
5034 u32 address = reg[base].I - value;
|
rlm@1
|
5035 reg[base].I = address;
|
rlm@1
|
5036 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
5037 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5038 }
|
rlm@1
|
5039 break;
|
rlm@1
|
5040 case 0x7c0:
|
rlm@1
|
5041 case 0x7c8:
|
rlm@1
|
5042 {
|
rlm@1
|
5043 // STRB Rd, [Rn, Rm, LSL #]
|
rlm@1
|
5044 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
5045 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5046 int base = (opcode >> 16) & 15;
|
rlm@1
|
5047 u32 address = reg[base].I + offset;
|
rlm@1
|
5048 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
5049 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5050 }
|
rlm@1
|
5051 break;
|
rlm@1
|
5052 case 0x7c2:
|
rlm@1
|
5053 case 0x7ca:
|
rlm@1
|
5054 {
|
rlm@1
|
5055 // STRB Rd, [Rn, Rm, LSR #]
|
rlm@1
|
5056 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5057 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
5058 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5059 int base = (opcode >> 16) & 15;
|
rlm@1
|
5060 u32 address = reg[base].I + offset;
|
rlm@1
|
5061 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
5062 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5063 }
|
rlm@1
|
5064 break;
|
rlm@1
|
5065 case 0x7c4:
|
rlm@1
|
5066 case 0x7cc:
|
rlm@1
|
5067 {
|
rlm@1
|
5068 // STRB Rd, [Rn, Rm, ASR #]
|
rlm@1
|
5069 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5070 int offset;
|
rlm@1
|
5071 if (shift)
|
rlm@1
|
5072 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
5073 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
5074 offset = 0xFFFFFFFF;
|
rlm@1
|
5075 else
|
rlm@1
|
5076 offset = 0;
|
rlm@1
|
5077 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5078 int base = (opcode >> 16) & 15;
|
rlm@1
|
5079 u32 address = reg[base].I + offset;
|
rlm@1
|
5080 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
5081 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5082 }
|
rlm@1
|
5083 break;
|
rlm@1
|
5084 case 0x7c6:
|
rlm@1
|
5085 case 0x7ce:
|
rlm@1
|
5086 {
|
rlm@1
|
5087 // STRB Rd, [Rn, Rm, ROR #]
|
rlm@1
|
5088 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5089 u32 value = reg[opcode & 15].I;
|
rlm@1
|
5090 if (shift)
|
rlm@1
|
5091 {
|
rlm@1
|
5092 ROR_VALUE;
|
rlm@1
|
5093 }
|
rlm@1
|
5094 else
|
rlm@1
|
5095 {
|
rlm@1
|
5096 RCR_VALUE;
|
rlm@1
|
5097 }
|
rlm@1
|
5098 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5099 int base = (opcode >> 16) & 15;
|
rlm@1
|
5100 u32 address = reg[base].I + value;
|
rlm@1
|
5101 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
5102 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5103 }
|
rlm@1
|
5104 break;
|
rlm@1
|
5105 case 0x7e0:
|
rlm@1
|
5106 case 0x7e8:
|
rlm@1
|
5107 {
|
rlm@1
|
5108 // STRB Rd, [Rn, Rm, LSL #]!
|
rlm@1
|
5109 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
5110 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5111 int base = (opcode >> 16) & 15;
|
rlm@1
|
5112 u32 address = reg[base].I + offset;
|
rlm@1
|
5113 reg[base].I = address;
|
rlm@1
|
5114 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
5115 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5116 }
|
rlm@1
|
5117 break;
|
rlm@1
|
5118 case 0x7e2:
|
rlm@1
|
5119 case 0x7ea:
|
rlm@1
|
5120 {
|
rlm@1
|
5121 // STRB Rd, [Rn, Rm, LSR #]!
|
rlm@1
|
5122 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5123 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
5124 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5125 int base = (opcode >> 16) & 15;
|
rlm@1
|
5126 u32 address = reg[base].I + offset;
|
rlm@1
|
5127 reg[base].I = address;
|
rlm@1
|
5128 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
5129 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5130 }
|
rlm@1
|
5131 break;
|
rlm@1
|
5132 case 0x7e4:
|
rlm@1
|
5133 case 0x7ec:
|
rlm@1
|
5134 {
|
rlm@1
|
5135 // STRB Rd, [Rn, Rm, ASR #]!
|
rlm@1
|
5136 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5137 int offset;
|
rlm@1
|
5138 if (shift)
|
rlm@1
|
5139 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
5140 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
5141 offset = 0xFFFFFFFF;
|
rlm@1
|
5142 else
|
rlm@1
|
5143 offset = 0;
|
rlm@1
|
5144 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5145 int base = (opcode >> 16) & 15;
|
rlm@1
|
5146 u32 address = reg[base].I + offset;
|
rlm@1
|
5147 reg[base].I = address;
|
rlm@1
|
5148 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
5149 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5150 }
|
rlm@1
|
5151 break;
|
rlm@1
|
5152 case 0x7e6:
|
rlm@1
|
5153 case 0x7ee:
|
rlm@1
|
5154 {
|
rlm@1
|
5155 // STRB Rd, [Rn, Rm, ROR #]!
|
rlm@1
|
5156 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5157 u32 value = reg[opcode & 15].I;
|
rlm@1
|
5158 if (shift)
|
rlm@1
|
5159 {
|
rlm@1
|
5160 ROR_VALUE;
|
rlm@1
|
5161 }
|
rlm@1
|
5162 else
|
rlm@1
|
5163 {
|
rlm@1
|
5164 RCR_VALUE;
|
rlm@1
|
5165 }
|
rlm@1
|
5166 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5167 int base = (opcode >> 16) & 15;
|
rlm@1
|
5168 u32 address = reg[base].I + value;
|
rlm@1
|
5169 reg[base].I = address;
|
rlm@1
|
5170 CPUWriteByte(address, reg[dest].B.B0);
|
rlm@1
|
5171 clockTicks += 2 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5172 }
|
rlm@1
|
5173 break;
|
rlm@1
|
5174 case 0x650:
|
rlm@1
|
5175 case 0x658:
|
rlm@1
|
5176 // T versions are the same
|
rlm@1
|
5177 case 0x670:
|
rlm@1
|
5178 case 0x678:
|
rlm@1
|
5179 {
|
rlm@1
|
5180 // LDRB Rd, [Rn], -Rm, LSL #
|
rlm@1
|
5181 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
5182 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5183 int base = (opcode >> 16) & 15;
|
rlm@1
|
5184 u32 address = reg[base].I;
|
rlm@1
|
5185 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5186 if (dest != base)
|
rlm@1
|
5187 reg[base].I = address - offset;
|
rlm@1
|
5188 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5189 }
|
rlm@1
|
5190 break;
|
rlm@1
|
5191 case 0x652:
|
rlm@1
|
5192 case 0x65a:
|
rlm@1
|
5193 // T versions are the same
|
rlm@1
|
5194 case 0x672:
|
rlm@1
|
5195 case 0x67a:
|
rlm@1
|
5196 {
|
rlm@1
|
5197 // LDRB Rd, [Rn], -Rm, LSR #
|
rlm@1
|
5198 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5199 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
5200 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5201 int base = (opcode >> 16) & 15;
|
rlm@1
|
5202 u32 address = reg[base].I;
|
rlm@1
|
5203 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5204 if (dest != base)
|
rlm@1
|
5205 reg[base].I = address - offset;
|
rlm@1
|
5206 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5207 }
|
rlm@1
|
5208 break;
|
rlm@1
|
5209 case 0x654:
|
rlm@1
|
5210 case 0x65c:
|
rlm@1
|
5211 // T versions are the same
|
rlm@1
|
5212 case 0x674:
|
rlm@1
|
5213 case 0x67c:
|
rlm@1
|
5214 {
|
rlm@1
|
5215 // LDRB Rd, [Rn], -Rm, ASR #
|
rlm@1
|
5216 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5217 int offset;
|
rlm@1
|
5218 if (shift)
|
rlm@1
|
5219 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
5220 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
5221 offset = 0xFFFFFFFF;
|
rlm@1
|
5222 else
|
rlm@1
|
5223 offset = 0;
|
rlm@1
|
5224 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5225 int base = (opcode >> 16) & 15;
|
rlm@1
|
5226 u32 address = reg[base].I;
|
rlm@1
|
5227 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5228 if (dest != base)
|
rlm@1
|
5229 reg[base].I = address - offset;
|
rlm@1
|
5230 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5231 }
|
rlm@1
|
5232 break;
|
rlm@1
|
5233 case 0x656:
|
rlm@1
|
5234 case 0x65e:
|
rlm@1
|
5235 // T versions are the same
|
rlm@1
|
5236 case 0x676:
|
rlm@1
|
5237 case 0x67e:
|
rlm@1
|
5238 {
|
rlm@1
|
5239 // LDRB Rd, [Rn], -Rm, ROR #
|
rlm@1
|
5240 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5241 u32 value = reg[opcode & 15].I;
|
rlm@1
|
5242 if (shift)
|
rlm@1
|
5243 {
|
rlm@1
|
5244 ROR_VALUE;
|
rlm@1
|
5245 }
|
rlm@1
|
5246 else
|
rlm@1
|
5247 {
|
rlm@1
|
5248 RCR_VALUE;
|
rlm@1
|
5249 }
|
rlm@1
|
5250 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5251 int base = (opcode >> 16) & 15;
|
rlm@1
|
5252 u32 address = reg[base].I;
|
rlm@1
|
5253 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5254 if (dest != base)
|
rlm@1
|
5255 reg[base].I = address - value;
|
rlm@1
|
5256 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5257 }
|
rlm@1
|
5258 break;
|
rlm@1
|
5259 case 0x6d0:
|
rlm@1
|
5260 case 0x6d8:
|
rlm@1
|
5261 // T versions are the same
|
rlm@1
|
5262 case 0x6f0:
|
rlm@1
|
5263 case 0x6f8:
|
rlm@1
|
5264 {
|
rlm@1
|
5265 // LDRB Rd, [Rn], Rm, LSL #
|
rlm@1
|
5266 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
5267 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5268 int base = (opcode >> 16) & 15;
|
rlm@1
|
5269 u32 address = reg[base].I;
|
rlm@1
|
5270 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5271 if (dest != base)
|
rlm@1
|
5272 reg[base].I = address + offset;
|
rlm@1
|
5273 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5274 }
|
rlm@1
|
5275 break;
|
rlm@1
|
5276 case 0x6d2:
|
rlm@1
|
5277 case 0x6da:
|
rlm@1
|
5278 // T versions are the same
|
rlm@1
|
5279 case 0x6f2:
|
rlm@1
|
5280 case 0x6fa:
|
rlm@1
|
5281 {
|
rlm@1
|
5282 // LDRB Rd, [Rn], Rm, LSR #
|
rlm@1
|
5283 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5284 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
5285 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5286 int base = (opcode >> 16) & 15;
|
rlm@1
|
5287 u32 address = reg[base].I;
|
rlm@1
|
5288 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5289 if (dest != base)
|
rlm@1
|
5290 reg[base].I = address + offset;
|
rlm@1
|
5291 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5292 }
|
rlm@1
|
5293 break;
|
rlm@1
|
5294 case 0x6d4:
|
rlm@1
|
5295 case 0x6dc:
|
rlm@1
|
5296 // T versions are the same
|
rlm@1
|
5297 case 0x6f4:
|
rlm@1
|
5298 case 0x6fc:
|
rlm@1
|
5299 {
|
rlm@1
|
5300 // LDRB Rd, [Rn], Rm, ASR #
|
rlm@1
|
5301 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5302 int offset;
|
rlm@1
|
5303 if (shift)
|
rlm@1
|
5304 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
5305 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
5306 offset = 0xFFFFFFFF;
|
rlm@1
|
5307 else
|
rlm@1
|
5308 offset = 0;
|
rlm@1
|
5309 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5310 int base = (opcode >> 16) & 15;
|
rlm@1
|
5311 u32 address = reg[base].I;
|
rlm@1
|
5312 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5313 if (dest != base)
|
rlm@1
|
5314 reg[base].I = address + offset;
|
rlm@1
|
5315 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5316 }
|
rlm@1
|
5317 break;
|
rlm@1
|
5318 case 0x6d6:
|
rlm@1
|
5319 case 0x6de:
|
rlm@1
|
5320 // T versions are the same
|
rlm@1
|
5321 case 0x6f6:
|
rlm@1
|
5322 case 0x6fe:
|
rlm@1
|
5323 {
|
rlm@1
|
5324 // LDRB Rd, [Rn], Rm, ROR #
|
rlm@1
|
5325 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5326 u32 value = reg[opcode & 15].I;
|
rlm@1
|
5327 if (shift)
|
rlm@1
|
5328 {
|
rlm@1
|
5329 ROR_VALUE;
|
rlm@1
|
5330 }
|
rlm@1
|
5331 else
|
rlm@1
|
5332 {
|
rlm@1
|
5333 RCR_VALUE;
|
rlm@1
|
5334 }
|
rlm@1
|
5335 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5336 int base = (opcode >> 16) & 15;
|
rlm@1
|
5337 u32 address = reg[base].I;
|
rlm@1
|
5338 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5339 if (dest != base)
|
rlm@1
|
5340 reg[base].I = address + value;
|
rlm@1
|
5341 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5342 }
|
rlm@1
|
5343 break;
|
rlm@1
|
5344 case 0x750:
|
rlm@1
|
5345 case 0x758:
|
rlm@1
|
5346 {
|
rlm@1
|
5347 // LDRB Rd, [Rn, -Rm, LSL #]
|
rlm@1
|
5348 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
5349 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5350 int base = (opcode >> 16) & 15;
|
rlm@1
|
5351 u32 address = reg[base].I - offset;
|
rlm@1
|
5352 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5353 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5354 }
|
rlm@1
|
5355 break;
|
rlm@1
|
5356 case 0x752:
|
rlm@1
|
5357 case 0x75a:
|
rlm@1
|
5358 {
|
rlm@1
|
5359 // LDRB Rd, [Rn, -Rm, LSR #]
|
rlm@1
|
5360 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5361 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
5362 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5363 int base = (opcode >> 16) & 15;
|
rlm@1
|
5364 u32 address = reg[base].I - offset;
|
rlm@1
|
5365 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5366 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5367 }
|
rlm@1
|
5368 break;
|
rlm@1
|
5369 case 0x754:
|
rlm@1
|
5370 case 0x75c:
|
rlm@1
|
5371 {
|
rlm@1
|
5372 // LDRB Rd, [Rn, -Rm, ASR #]
|
rlm@1
|
5373 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5374 int offset;
|
rlm@1
|
5375 if (shift)
|
rlm@1
|
5376 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
5377 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
5378 offset = 0xFFFFFFFF;
|
rlm@1
|
5379 else
|
rlm@1
|
5380 offset = 0;
|
rlm@1
|
5381 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5382 int base = (opcode >> 16) & 15;
|
rlm@1
|
5383 u32 address = reg[base].I - offset;
|
rlm@1
|
5384 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5385 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5386 }
|
rlm@1
|
5387 break;
|
rlm@1
|
5388 case 0x756:
|
rlm@1
|
5389 case 0x75e:
|
rlm@1
|
5390 {
|
rlm@1
|
5391 // LDRB Rd, [Rn, -Rm, ROR #]
|
rlm@1
|
5392 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5393 u32 value = reg[opcode & 15].I;
|
rlm@1
|
5394 if (shift)
|
rlm@1
|
5395 {
|
rlm@1
|
5396 ROR_VALUE;
|
rlm@1
|
5397 }
|
rlm@1
|
5398 else
|
rlm@1
|
5399 {
|
rlm@1
|
5400 RCR_VALUE;
|
rlm@1
|
5401 }
|
rlm@1
|
5402 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5403 int base = (opcode >> 16) & 15;
|
rlm@1
|
5404 u32 address = reg[base].I - value;
|
rlm@1
|
5405 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5406 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5407 }
|
rlm@1
|
5408 break;
|
rlm@1
|
5409 case 0x770:
|
rlm@1
|
5410 case 0x778:
|
rlm@1
|
5411 {
|
rlm@1
|
5412 // LDRB Rd, [Rn, -Rm, LSL #]!
|
rlm@1
|
5413 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
5414 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5415 int base = (opcode >> 16) & 15;
|
rlm@1
|
5416 u32 address = reg[base].I - offset;
|
rlm@1
|
5417 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5418 if (dest != base)
|
rlm@1
|
5419 reg[base].I = address;
|
rlm@1
|
5420 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5421 }
|
rlm@1
|
5422 break;
|
rlm@1
|
5423 case 0x772:
|
rlm@1
|
5424 case 0x77a:
|
rlm@1
|
5425 {
|
rlm@1
|
5426 // LDRB Rd, [Rn, -Rm, LSR #]!
|
rlm@1
|
5427 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5428 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
5429 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5430 int base = (opcode >> 16) & 15;
|
rlm@1
|
5431 u32 address = reg[base].I - offset;
|
rlm@1
|
5432 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5433 if (dest != base)
|
rlm@1
|
5434 reg[base].I = address;
|
rlm@1
|
5435 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5436 }
|
rlm@1
|
5437 break;
|
rlm@1
|
5438 case 0x774:
|
rlm@1
|
5439 case 0x77c:
|
rlm@1
|
5440 {
|
rlm@1
|
5441 // LDRB Rd, [Rn, -Rm, ASR #]!
|
rlm@1
|
5442 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5443 int offset;
|
rlm@1
|
5444 if (shift)
|
rlm@1
|
5445 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
5446 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
5447 offset = 0xFFFFFFFF;
|
rlm@1
|
5448 else
|
rlm@1
|
5449 offset = 0;
|
rlm@1
|
5450 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5451 int base = (opcode >> 16) & 15;
|
rlm@1
|
5452 u32 address = reg[base].I - offset;
|
rlm@1
|
5453 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5454 if (dest != base)
|
rlm@1
|
5455 reg[base].I = address;
|
rlm@1
|
5456 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5457 }
|
rlm@1
|
5458 break;
|
rlm@1
|
5459 case 0x776:
|
rlm@1
|
5460 case 0x77e:
|
rlm@1
|
5461 {
|
rlm@1
|
5462 // LDRB Rd, [Rn, -Rm, ROR #]!
|
rlm@1
|
5463 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5464 u32 value = reg[opcode & 15].I;
|
rlm@1
|
5465 if (shift)
|
rlm@1
|
5466 {
|
rlm@1
|
5467 ROR_VALUE;
|
rlm@1
|
5468 }
|
rlm@1
|
5469 else
|
rlm@1
|
5470 {
|
rlm@1
|
5471 RCR_VALUE;
|
rlm@1
|
5472 }
|
rlm@1
|
5473 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5474 int base = (opcode >> 16) & 15;
|
rlm@1
|
5475 u32 address = reg[base].I - value;
|
rlm@1
|
5476 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5477 if (dest != base)
|
rlm@1
|
5478 reg[base].I = address;
|
rlm@1
|
5479 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5480 }
|
rlm@1
|
5481 break;
|
rlm@1
|
5482 case 0x7d0:
|
rlm@1
|
5483 case 0x7d8:
|
rlm@1
|
5484 {
|
rlm@1
|
5485 // LDRB Rd, [Rn, Rm, LSL #]
|
rlm@1
|
5486 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
5487 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5488 int base = (opcode >> 16) & 15;
|
rlm@1
|
5489 u32 address = reg[base].I + offset;
|
rlm@1
|
5490 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5491 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5492 }
|
rlm@1
|
5493 break;
|
rlm@1
|
5494 case 0x7d2:
|
rlm@1
|
5495 case 0x7da:
|
rlm@1
|
5496 {
|
rlm@1
|
5497 // LDRB Rd, [Rn, Rm, LSR #]
|
rlm@1
|
5498 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5499 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
5500 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5501 int base = (opcode >> 16) & 15;
|
rlm@1
|
5502 u32 address = reg[base].I + offset;
|
rlm@1
|
5503 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5504 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5505 }
|
rlm@1
|
5506 break;
|
rlm@1
|
5507 case 0x7d4:
|
rlm@1
|
5508 case 0x7dc:
|
rlm@1
|
5509 {
|
rlm@1
|
5510 // LDRB Rd, [Rn, Rm, ASR #]
|
rlm@1
|
5511 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5512 int offset;
|
rlm@1
|
5513 if (shift)
|
rlm@1
|
5514 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
5515 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
5516 offset = 0xFFFFFFFF;
|
rlm@1
|
5517 else
|
rlm@1
|
5518 offset = 0;
|
rlm@1
|
5519 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5520 int base = (opcode >> 16) & 15;
|
rlm@1
|
5521 u32 address = reg[base].I + offset;
|
rlm@1
|
5522 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5523 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5524 }
|
rlm@1
|
5525 break;
|
rlm@1
|
5526 case 0x7d6:
|
rlm@1
|
5527 case 0x7de:
|
rlm@1
|
5528 {
|
rlm@1
|
5529 // LDRB Rd, [Rn, Rm, ROR #]
|
rlm@1
|
5530 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5531 u32 value = reg[opcode & 15].I;
|
rlm@1
|
5532 if (shift)
|
rlm@1
|
5533 {
|
rlm@1
|
5534 ROR_VALUE;
|
rlm@1
|
5535 }
|
rlm@1
|
5536 else
|
rlm@1
|
5537 {
|
rlm@1
|
5538 RCR_VALUE;
|
rlm@1
|
5539 }
|
rlm@1
|
5540 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5541 int base = (opcode >> 16) & 15;
|
rlm@1
|
5542 u32 address = reg[base].I + value;
|
rlm@1
|
5543 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5544 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5545 }
|
rlm@1
|
5546 break;
|
rlm@1
|
5547 case 0x7f0:
|
rlm@1
|
5548 case 0x7f8:
|
rlm@1
|
5549 {
|
rlm@1
|
5550 // LDRB Rd, [Rn, Rm, LSL #]!
|
rlm@1
|
5551 int offset = reg[opcode & 15].I << ((opcode >> 7) & 31);
|
rlm@1
|
5552 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5553 int base = (opcode >> 16) & 15;
|
rlm@1
|
5554 u32 address = reg[base].I + offset;
|
rlm@1
|
5555 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5556 if (dest != base)
|
rlm@1
|
5557 reg[base].I = address;
|
rlm@1
|
5558 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5559 }
|
rlm@1
|
5560 break;
|
rlm@1
|
5561 case 0x7f2:
|
rlm@1
|
5562 case 0x7fa:
|
rlm@1
|
5563 {
|
rlm@1
|
5564 // LDRB Rd, [Rn, Rm, LSR #]!
|
rlm@1
|
5565 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5566 int offset = shift ? reg[opcode & 15].I >> shift : 0;
|
rlm@1
|
5567 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5568 int base = (opcode >> 16) & 15;
|
rlm@1
|
5569 u32 address = reg[base].I + offset;
|
rlm@1
|
5570 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5571 if (dest != base)
|
rlm@1
|
5572 reg[base].I = address;
|
rlm@1
|
5573 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5574 }
|
rlm@1
|
5575 break;
|
rlm@1
|
5576 case 0x7f4:
|
rlm@1
|
5577 case 0x7fc:
|
rlm@1
|
5578 {
|
rlm@1
|
5579 // LDRB Rd, [Rn, Rm, ASR #]!
|
rlm@1
|
5580 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5581 int offset;
|
rlm@1
|
5582 if (shift)
|
rlm@1
|
5583 offset = (int)((s32)reg[opcode & 15].I >> shift);
|
rlm@1
|
5584 else if (reg[opcode & 15].I & 0x80000000)
|
rlm@1
|
5585 offset = 0xFFFFFFFF;
|
rlm@1
|
5586 else
|
rlm@1
|
5587 offset = 0;
|
rlm@1
|
5588 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5589 int base = (opcode >> 16) & 15;
|
rlm@1
|
5590 u32 address = reg[base].I + offset;
|
rlm@1
|
5591 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5592 if (dest != base)
|
rlm@1
|
5593 reg[base].I = address;
|
rlm@1
|
5594 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5595 }
|
rlm@1
|
5596 break;
|
rlm@1
|
5597 case 0x7f6:
|
rlm@1
|
5598 case 0x7fe:
|
rlm@1
|
5599 {
|
rlm@1
|
5600 // LDRB Rd, [Rn, Rm, ROR #]!
|
rlm@1
|
5601 int shift = (opcode >> 7) & 31;
|
rlm@1
|
5602 u32 value = reg[opcode & 15].I;
|
rlm@1
|
5603 if (shift)
|
rlm@1
|
5604 {
|
rlm@1
|
5605 ROR_VALUE;
|
rlm@1
|
5606 }
|
rlm@1
|
5607 else
|
rlm@1
|
5608 {
|
rlm@1
|
5609 RCR_VALUE;
|
rlm@1
|
5610 }
|
rlm@1
|
5611 int dest = (opcode >> 12) & 15;
|
rlm@1
|
5612 int base = (opcode >> 16) & 15;
|
rlm@1
|
5613 u32 address = reg[base].I + value;
|
rlm@1
|
5614 reg[dest].I = CPUReadByte(address);
|
rlm@1
|
5615 if (dest != base)
|
rlm@1
|
5616 reg[base].I = address;
|
rlm@1
|
5617 clockTicks += 3 + CPUUpdateTicksAccess16(address);
|
rlm@1
|
5618 }
|
rlm@1
|
5619 break;
|
rlm@1
|
5620 #define STMW_REG(val, num) \
|
rlm@1
|
5621 if (opcode & (val)) { \
|
rlm@1
|
5622 CPUWriteMemory(address, reg[(num)].I); \
|
rlm@1
|
5623 if (!offset) { \
|
rlm@1
|
5624 reg[base].I = temp; \
|
rlm@1
|
5625 clockTicks += 1 + CPUUpdateTicksAccess32(address); \
|
rlm@1
|
5626 offset = 1; \
|
rlm@1
|
5627 } else { \
|
rlm@1
|
5628 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); \
|
rlm@1
|
5629 } \
|
rlm@1
|
5630 address += 4; \
|
rlm@1
|
5631 }
|
rlm@1
|
5632 #define STM_REG(val, num) \
|
rlm@1
|
5633 if (opcode & (val)) { \
|
rlm@1
|
5634 CPUWriteMemory(address, reg[(num)].I); \
|
rlm@1
|
5635 if (!offset) { \
|
rlm@1
|
5636 clockTicks += 1 + CPUUpdateTicksAccess32(address); \
|
rlm@1
|
5637 offset = 1; \
|
rlm@1
|
5638 } else { \
|
rlm@1
|
5639 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); \
|
rlm@1
|
5640 } \
|
rlm@1
|
5641 address += 4; \
|
rlm@1
|
5642 }
|
rlm@1
|
5643
|
rlm@1
|
5644 CASE_16(0x800)
|
rlm@1
|
5645 // STMDA Rn, {Rlist}
|
rlm@1
|
5646 {
|
rlm@1
|
5647 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
5648 u32 temp = reg[base].I -
|
rlm@1
|
5649 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
5650 u32 address = (temp + 4) & 0xFFFFFFFC;
|
rlm@1
|
5651 clockTicks += 2;
|
rlm@1
|
5652 int offset = 0;
|
rlm@1
|
5653 STM_REG(1, 0);
|
rlm@1
|
5654 STM_REG(2, 1);
|
rlm@1
|
5655 STM_REG(4, 2);
|
rlm@1
|
5656 STM_REG(8, 3);
|
rlm@1
|
5657 STM_REG(16, 4);
|
rlm@1
|
5658 STM_REG(32, 5);
|
rlm@1
|
5659 STM_REG(64, 6);
|
rlm@1
|
5660 STM_REG(128, 7);
|
rlm@1
|
5661 STM_REG(256, 8);
|
rlm@1
|
5662 STM_REG(512, 9);
|
rlm@1
|
5663 STM_REG(1024, 10);
|
rlm@1
|
5664 STM_REG(2048, 11);
|
rlm@1
|
5665 STM_REG(4096, 12);
|
rlm@1
|
5666 STM_REG(8192, 13);
|
rlm@1
|
5667 STM_REG(16384, 14);
|
rlm@1
|
5668 if (opcode & 32768)
|
rlm@1
|
5669 {
|
rlm@1
|
5670 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
5671 if (!offset)
|
rlm@1
|
5672 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
5673 else
|
rlm@1
|
5674 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
5675 }
|
rlm@1
|
5676 }
|
rlm@1
|
5677 break;
|
rlm@1
|
5678 CASE_16(0x820)
|
rlm@1
|
5679 {
|
rlm@1
|
5680 // STMDA Rn!, {Rlist}
|
rlm@1
|
5681 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
5682 u32 temp = reg[base].I -
|
rlm@1
|
5683 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
5684 u32 address = (temp + 4) & 0xFFFFFFFC;
|
rlm@1
|
5685 clockTicks += 2;
|
rlm@1
|
5686 int offset = 0;
|
rlm@1
|
5687
|
rlm@1
|
5688 STMW_REG(1, 0);
|
rlm@1
|
5689 STMW_REG(2, 1);
|
rlm@1
|
5690 STMW_REG(4, 2);
|
rlm@1
|
5691 STMW_REG(8, 3);
|
rlm@1
|
5692 STMW_REG(16, 4);
|
rlm@1
|
5693 STMW_REG(32, 5);
|
rlm@1
|
5694 STMW_REG(64, 6);
|
rlm@1
|
5695 STMW_REG(128, 7);
|
rlm@1
|
5696 STMW_REG(256, 8);
|
rlm@1
|
5697 STMW_REG(512, 9);
|
rlm@1
|
5698 STMW_REG(1024, 10);
|
rlm@1
|
5699 STMW_REG(2048, 11);
|
rlm@1
|
5700 STMW_REG(4096, 12);
|
rlm@1
|
5701 STMW_REG(8192, 13);
|
rlm@1
|
5702 STMW_REG(16384, 14);
|
rlm@1
|
5703 if (opcode & 32768)
|
rlm@1
|
5704 {
|
rlm@1
|
5705 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
5706 if (!offset)
|
rlm@1
|
5707 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
5708 else
|
rlm@1
|
5709 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
5710 reg[base].I = temp;
|
rlm@1
|
5711 }
|
rlm@1
|
5712 }
|
rlm@1
|
5713 break;
|
rlm@1
|
5714 CASE_16(0x840)
|
rlm@1
|
5715 {
|
rlm@1
|
5716 // STMDA Rn, {Rlist}^
|
rlm@1
|
5717 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
5718 u32 temp = reg[base].I -
|
rlm@1
|
5719 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
5720 u32 address = (temp + 4) & 0xFFFFFFFC;
|
rlm@1
|
5721 clockTicks += 2;
|
rlm@1
|
5722 int offset = 0;
|
rlm@1
|
5723
|
rlm@1
|
5724 STM_REG(1, 0);
|
rlm@1
|
5725 STM_REG(2, 1);
|
rlm@1
|
5726 STM_REG(4, 2);
|
rlm@1
|
5727 STM_REG(8, 3);
|
rlm@1
|
5728 STM_REG(16, 4);
|
rlm@1
|
5729 STM_REG(32, 5);
|
rlm@1
|
5730 STM_REG(64, 6);
|
rlm@1
|
5731 STM_REG(128, 7);
|
rlm@1
|
5732
|
rlm@1
|
5733 if (armMode == 0x11)
|
rlm@1
|
5734 {
|
rlm@1
|
5735 STM_REG(256, R8_FIQ);
|
rlm@1
|
5736 STM_REG(512, R9_FIQ);
|
rlm@1
|
5737 STM_REG(1024, R10_FIQ);
|
rlm@1
|
5738 STM_REG(2048, R11_FIQ);
|
rlm@1
|
5739 STM_REG(4096, R12_FIQ);
|
rlm@1
|
5740 }
|
rlm@1
|
5741 else
|
rlm@1
|
5742 {
|
rlm@1
|
5743 STM_REG(256, 8);
|
rlm@1
|
5744 STM_REG(512, 9);
|
rlm@1
|
5745 STM_REG(1024, 10);
|
rlm@1
|
5746 STM_REG(2048, 11);
|
rlm@1
|
5747 STM_REG(4096, 12);
|
rlm@1
|
5748 }
|
rlm@1
|
5749
|
rlm@1
|
5750 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
5751 {
|
rlm@1
|
5752 STM_REG(8192, R13_USR);
|
rlm@1
|
5753 STM_REG(16384, R14_USR);
|
rlm@1
|
5754 }
|
rlm@1
|
5755 else
|
rlm@1
|
5756 {
|
rlm@1
|
5757 STM_REG(8192, 13);
|
rlm@1
|
5758 STM_REG(16384, 14);
|
rlm@1
|
5759 }
|
rlm@1
|
5760
|
rlm@1
|
5761 if (opcode & 32768)
|
rlm@1
|
5762 {
|
rlm@1
|
5763 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
5764 if (!offset)
|
rlm@1
|
5765 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
5766 else
|
rlm@1
|
5767 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
5768 }
|
rlm@1
|
5769 }
|
rlm@1
|
5770 break;
|
rlm@1
|
5771 CASE_16(0x860)
|
rlm@1
|
5772 {
|
rlm@1
|
5773 // STMDA Rn!, {Rlist}^
|
rlm@1
|
5774 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
5775 u32 temp = reg[base].I -
|
rlm@1
|
5776 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
5777 u32 address = (temp + 4) & 0xFFFFFFFC;
|
rlm@1
|
5778 clockTicks += 2;
|
rlm@1
|
5779 int offset = 0;
|
rlm@1
|
5780
|
rlm@1
|
5781 STMW_REG(1, 0);
|
rlm@1
|
5782 STMW_REG(2, 1);
|
rlm@1
|
5783 STMW_REG(4, 2);
|
rlm@1
|
5784 STMW_REG(8, 3);
|
rlm@1
|
5785 STMW_REG(16, 4);
|
rlm@1
|
5786 STMW_REG(32, 5);
|
rlm@1
|
5787 STMW_REG(64, 6);
|
rlm@1
|
5788 STMW_REG(128, 7);
|
rlm@1
|
5789
|
rlm@1
|
5790 if (armMode == 0x11)
|
rlm@1
|
5791 {
|
rlm@1
|
5792 STMW_REG(256, R8_FIQ);
|
rlm@1
|
5793 STMW_REG(512, R9_FIQ);
|
rlm@1
|
5794 STMW_REG(1024, R10_FIQ);
|
rlm@1
|
5795 STMW_REG(2048, R11_FIQ);
|
rlm@1
|
5796 STMW_REG(4096, R12_FIQ);
|
rlm@1
|
5797 }
|
rlm@1
|
5798 else
|
rlm@1
|
5799 {
|
rlm@1
|
5800 STMW_REG(256, 8);
|
rlm@1
|
5801 STMW_REG(512, 9);
|
rlm@1
|
5802 STMW_REG(1024, 10);
|
rlm@1
|
5803 STMW_REG(2048, 11);
|
rlm@1
|
5804 STMW_REG(4096, 12);
|
rlm@1
|
5805 }
|
rlm@1
|
5806
|
rlm@1
|
5807 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
5808 {
|
rlm@1
|
5809 STMW_REG(8192, R13_USR);
|
rlm@1
|
5810 STMW_REG(16384, R14_USR);
|
rlm@1
|
5811 }
|
rlm@1
|
5812 else
|
rlm@1
|
5813 {
|
rlm@1
|
5814 STMW_REG(8192, 13);
|
rlm@1
|
5815 STMW_REG(16384, 14);
|
rlm@1
|
5816 }
|
rlm@1
|
5817
|
rlm@1
|
5818 if (opcode & 32768)
|
rlm@1
|
5819 {
|
rlm@1
|
5820 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
5821 if (!offset)
|
rlm@1
|
5822 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
5823 else
|
rlm@1
|
5824 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
5825 reg[base].I = temp;
|
rlm@1
|
5826 }
|
rlm@1
|
5827 }
|
rlm@1
|
5828 break;
|
rlm@1
|
5829
|
rlm@1
|
5830 CASE_16(0x880)
|
rlm@1
|
5831 {
|
rlm@1
|
5832 // STMIA Rn, {Rlist}
|
rlm@1
|
5833 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
5834 u32 address = reg[base].I & 0xFFFFFFFC;
|
rlm@1
|
5835 clockTicks += 2;
|
rlm@1
|
5836 int offset = 0;
|
rlm@1
|
5837 STM_REG(1, 0);
|
rlm@1
|
5838 STM_REG(2, 1);
|
rlm@1
|
5839 STM_REG(4, 2);
|
rlm@1
|
5840 STM_REG(8, 3);
|
rlm@1
|
5841 STM_REG(16, 4);
|
rlm@1
|
5842 STM_REG(32, 5);
|
rlm@1
|
5843 STM_REG(64, 6);
|
rlm@1
|
5844 STM_REG(128, 7);
|
rlm@1
|
5845 STM_REG(256, 8);
|
rlm@1
|
5846 STM_REG(512, 9);
|
rlm@1
|
5847 STM_REG(1024, 10);
|
rlm@1
|
5848 STM_REG(2048, 11);
|
rlm@1
|
5849 STM_REG(4096, 12);
|
rlm@1
|
5850 STM_REG(8192, 13);
|
rlm@1
|
5851 STM_REG(16384, 14);
|
rlm@1
|
5852 if (opcode & 32768)
|
rlm@1
|
5853 {
|
rlm@1
|
5854 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
5855 if (!offset)
|
rlm@1
|
5856 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
5857 else
|
rlm@1
|
5858 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
5859 }
|
rlm@1
|
5860 }
|
rlm@1
|
5861 break;
|
rlm@1
|
5862 CASE_16(0x8a0)
|
rlm@1
|
5863 {
|
rlm@1
|
5864 // STMIA Rn!, {Rlist}
|
rlm@1
|
5865 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
5866 u32 address = reg[base].I & 0xFFFFFFFC;
|
rlm@1
|
5867 clockTicks += 2;
|
rlm@1
|
5868 int offset = 0;
|
rlm@1
|
5869 u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 0xFF] +
|
rlm@1
|
5870 cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
5871 STMW_REG(1, 0);
|
rlm@1
|
5872 STMW_REG(2, 1);
|
rlm@1
|
5873 STMW_REG(4, 2);
|
rlm@1
|
5874 STMW_REG(8, 3);
|
rlm@1
|
5875 STMW_REG(16, 4);
|
rlm@1
|
5876 STMW_REG(32, 5);
|
rlm@1
|
5877 STMW_REG(64, 6);
|
rlm@1
|
5878 STMW_REG(128, 7);
|
rlm@1
|
5879 STMW_REG(256, 8);
|
rlm@1
|
5880 STMW_REG(512, 9);
|
rlm@1
|
5881 STMW_REG(1024, 10);
|
rlm@1
|
5882 STMW_REG(2048, 11);
|
rlm@1
|
5883 STMW_REG(4096, 12);
|
rlm@1
|
5884 STMW_REG(8192, 13);
|
rlm@1
|
5885 STMW_REG(16384, 14);
|
rlm@1
|
5886 if (opcode & 32768)
|
rlm@1
|
5887 {
|
rlm@1
|
5888 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
5889 if (!offset)
|
rlm@1
|
5890 {
|
rlm@1
|
5891 reg[base].I = temp;
|
rlm@1
|
5892 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
5893 }
|
rlm@1
|
5894 else
|
rlm@1
|
5895 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
5896 }
|
rlm@1
|
5897 }
|
rlm@1
|
5898 break;
|
rlm@1
|
5899 CASE_16(0x8c0)
|
rlm@1
|
5900 {
|
rlm@1
|
5901 // STMIA Rn, {Rlist}^
|
rlm@1
|
5902 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
5903 u32 address = reg[base].I & 0xFFFFFFFC;
|
rlm@1
|
5904 clockTicks += 2;
|
rlm@1
|
5905 int offset = 0;
|
rlm@1
|
5906 STM_REG(1, 0);
|
rlm@1
|
5907 STM_REG(2, 1);
|
rlm@1
|
5908 STM_REG(4, 2);
|
rlm@1
|
5909 STM_REG(8, 3);
|
rlm@1
|
5910 STM_REG(16, 4);
|
rlm@1
|
5911 STM_REG(32, 5);
|
rlm@1
|
5912 STM_REG(64, 6);
|
rlm@1
|
5913 STM_REG(128, 7);
|
rlm@1
|
5914 if (armMode == 0x11)
|
rlm@1
|
5915 {
|
rlm@1
|
5916 STM_REG(256, R8_FIQ);
|
rlm@1
|
5917 STM_REG(512, R9_FIQ);
|
rlm@1
|
5918 STM_REG(1024, R10_FIQ);
|
rlm@1
|
5919 STM_REG(2048, R11_FIQ);
|
rlm@1
|
5920 STM_REG(4096, R12_FIQ);
|
rlm@1
|
5921 }
|
rlm@1
|
5922 else
|
rlm@1
|
5923 {
|
rlm@1
|
5924 STM_REG(256, 8);
|
rlm@1
|
5925 STM_REG(512, 9);
|
rlm@1
|
5926 STM_REG(1024, 10);
|
rlm@1
|
5927 STM_REG(2048, 11);
|
rlm@1
|
5928 STM_REG(4096, 12);
|
rlm@1
|
5929 }
|
rlm@1
|
5930 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
5931 {
|
rlm@1
|
5932 STM_REG(8192, R13_USR);
|
rlm@1
|
5933 STM_REG(16384, R14_USR);
|
rlm@1
|
5934 }
|
rlm@1
|
5935 else
|
rlm@1
|
5936 {
|
rlm@1
|
5937 STM_REG(8192, 13);
|
rlm@1
|
5938 STM_REG(16384, 14);
|
rlm@1
|
5939 }
|
rlm@1
|
5940 if (opcode & 32768)
|
rlm@1
|
5941 {
|
rlm@1
|
5942 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
5943 if (!offset)
|
rlm@1
|
5944 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
5945 else
|
rlm@1
|
5946 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
5947 }
|
rlm@1
|
5948 }
|
rlm@1
|
5949 break;
|
rlm@1
|
5950 CASE_16(0x8e0)
|
rlm@1
|
5951 {
|
rlm@1
|
5952 // STMIA Rn!, {Rlist}^
|
rlm@1
|
5953 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
5954 u32 address = reg[base].I & 0xFFFFFFFC;
|
rlm@1
|
5955 clockTicks += 2;
|
rlm@1
|
5956 int offset = 0;
|
rlm@1
|
5957 u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 0xFF] +
|
rlm@1
|
5958 cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
5959 STMW_REG(1, 0);
|
rlm@1
|
5960 STMW_REG(2, 1);
|
rlm@1
|
5961 STMW_REG(4, 2);
|
rlm@1
|
5962 STMW_REG(8, 3);
|
rlm@1
|
5963 STMW_REG(16, 4);
|
rlm@1
|
5964 STMW_REG(32, 5);
|
rlm@1
|
5965 STMW_REG(64, 6);
|
rlm@1
|
5966 STMW_REG(128, 7);
|
rlm@1
|
5967 if (armMode == 0x11)
|
rlm@1
|
5968 {
|
rlm@1
|
5969 STMW_REG(256, R8_FIQ);
|
rlm@1
|
5970 STMW_REG(512, R9_FIQ);
|
rlm@1
|
5971 STMW_REG(1024, R10_FIQ);
|
rlm@1
|
5972 STMW_REG(2048, R11_FIQ);
|
rlm@1
|
5973 STMW_REG(4096, R12_FIQ);
|
rlm@1
|
5974 }
|
rlm@1
|
5975 else
|
rlm@1
|
5976 {
|
rlm@1
|
5977 STMW_REG(256, 8);
|
rlm@1
|
5978 STMW_REG(512, 9);
|
rlm@1
|
5979 STMW_REG(1024, 10);
|
rlm@1
|
5980 STMW_REG(2048, 11);
|
rlm@1
|
5981 STMW_REG(4096, 12);
|
rlm@1
|
5982 }
|
rlm@1
|
5983 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
5984 {
|
rlm@1
|
5985 STMW_REG(8192, R13_USR);
|
rlm@1
|
5986 STMW_REG(16384, R14_USR);
|
rlm@1
|
5987 }
|
rlm@1
|
5988 else
|
rlm@1
|
5989 {
|
rlm@1
|
5990 STMW_REG(8192, 13);
|
rlm@1
|
5991 STMW_REG(16384, 14);
|
rlm@1
|
5992 }
|
rlm@1
|
5993 if (opcode & 32768)
|
rlm@1
|
5994 {
|
rlm@1
|
5995 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
5996 if (!offset)
|
rlm@1
|
5997 {
|
rlm@1
|
5998 reg[base].I = temp;
|
rlm@1
|
5999 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6000 }
|
rlm@1
|
6001 else
|
rlm@1
|
6002 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6003 }
|
rlm@1
|
6004 }
|
rlm@1
|
6005 break;
|
rlm@1
|
6006
|
rlm@1
|
6007 CASE_16(0x900)
|
rlm@1
|
6008 {
|
rlm@1
|
6009 // STMDB Rn, {Rlist}
|
rlm@1
|
6010 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6011 u32 temp = reg[base].I -
|
rlm@1
|
6012 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
6013 u32 address = temp & 0xFFFFFFFC;
|
rlm@1
|
6014 clockTicks += 2;
|
rlm@1
|
6015 int offset = 0;
|
rlm@1
|
6016 STM_REG(1, 0);
|
rlm@1
|
6017 STM_REG(2, 1);
|
rlm@1
|
6018 STM_REG(4, 2);
|
rlm@1
|
6019 STM_REG(8, 3);
|
rlm@1
|
6020 STM_REG(16, 4);
|
rlm@1
|
6021 STM_REG(32, 5);
|
rlm@1
|
6022 STM_REG(64, 6);
|
rlm@1
|
6023 STM_REG(128, 7);
|
rlm@1
|
6024 STM_REG(256, 8);
|
rlm@1
|
6025 STM_REG(512, 9);
|
rlm@1
|
6026 STM_REG(1024, 10);
|
rlm@1
|
6027 STM_REG(2048, 11);
|
rlm@1
|
6028 STM_REG(4096, 12);
|
rlm@1
|
6029 STM_REG(8192, 13);
|
rlm@1
|
6030 STM_REG(16384, 14);
|
rlm@1
|
6031 if (opcode & 32768)
|
rlm@1
|
6032 {
|
rlm@1
|
6033 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
6034 if (!offset)
|
rlm@1
|
6035 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6036 else
|
rlm@1
|
6037 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6038 }
|
rlm@1
|
6039 }
|
rlm@1
|
6040 break;
|
rlm@1
|
6041 CASE_16(0x920)
|
rlm@1
|
6042 {
|
rlm@1
|
6043 // STMDB Rn!, {Rlist}
|
rlm@1
|
6044 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6045 u32 temp = reg[base].I -
|
rlm@1
|
6046 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
6047 u32 address = temp & 0xFFFFFFFC;
|
rlm@1
|
6048 clockTicks += 2;
|
rlm@1
|
6049 int offset = 0;
|
rlm@1
|
6050
|
rlm@1
|
6051 STMW_REG(1, 0);
|
rlm@1
|
6052 STMW_REG(2, 1);
|
rlm@1
|
6053 STMW_REG(4, 2);
|
rlm@1
|
6054 STMW_REG(8, 3);
|
rlm@1
|
6055 STMW_REG(16, 4);
|
rlm@1
|
6056 STMW_REG(32, 5);
|
rlm@1
|
6057 STMW_REG(64, 6);
|
rlm@1
|
6058 STMW_REG(128, 7);
|
rlm@1
|
6059 STMW_REG(256, 8);
|
rlm@1
|
6060 STMW_REG(512, 9);
|
rlm@1
|
6061 STMW_REG(1024, 10);
|
rlm@1
|
6062 STMW_REG(2048, 11);
|
rlm@1
|
6063 STMW_REG(4096, 12);
|
rlm@1
|
6064 STMW_REG(8192, 13);
|
rlm@1
|
6065 STMW_REG(16384, 14);
|
rlm@1
|
6066 if (opcode & 32768)
|
rlm@1
|
6067 {
|
rlm@1
|
6068 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
6069 if (!offset)
|
rlm@1
|
6070 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6071 else
|
rlm@1
|
6072 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6073 reg[base].I = temp;
|
rlm@1
|
6074 }
|
rlm@1
|
6075 }
|
rlm@1
|
6076 break;
|
rlm@1
|
6077 CASE_16(0x940)
|
rlm@1
|
6078 {
|
rlm@1
|
6079 // STMDB Rn, {Rlist}^
|
rlm@1
|
6080 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6081 u32 temp = reg[base].I -
|
rlm@1
|
6082 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
6083 u32 address = temp & 0xFFFFFFFC;
|
rlm@1
|
6084 clockTicks += 2;
|
rlm@1
|
6085 int offset = 0;
|
rlm@1
|
6086
|
rlm@1
|
6087 STM_REG(1, 0);
|
rlm@1
|
6088 STM_REG(2, 1);
|
rlm@1
|
6089 STM_REG(4, 2);
|
rlm@1
|
6090 STM_REG(8, 3);
|
rlm@1
|
6091 STM_REG(16, 4);
|
rlm@1
|
6092 STM_REG(32, 5);
|
rlm@1
|
6093 STM_REG(64, 6);
|
rlm@1
|
6094 STM_REG(128, 7);
|
rlm@1
|
6095
|
rlm@1
|
6096 if (armMode == 0x11)
|
rlm@1
|
6097 {
|
rlm@1
|
6098 STM_REG(256, R8_FIQ);
|
rlm@1
|
6099 STM_REG(512, R9_FIQ);
|
rlm@1
|
6100 STM_REG(1024, R10_FIQ);
|
rlm@1
|
6101 STM_REG(2048, R11_FIQ);
|
rlm@1
|
6102 STM_REG(4096, R12_FIQ);
|
rlm@1
|
6103 }
|
rlm@1
|
6104 else
|
rlm@1
|
6105 {
|
rlm@1
|
6106 STM_REG(256, 8);
|
rlm@1
|
6107 STM_REG(512, 9);
|
rlm@1
|
6108 STM_REG(1024, 10);
|
rlm@1
|
6109 STM_REG(2048, 11);
|
rlm@1
|
6110 STM_REG(4096, 12);
|
rlm@1
|
6111 }
|
rlm@1
|
6112
|
rlm@1
|
6113 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
6114 {
|
rlm@1
|
6115 STM_REG(8192, R13_USR);
|
rlm@1
|
6116 STM_REG(16384, R14_USR);
|
rlm@1
|
6117 }
|
rlm@1
|
6118 else
|
rlm@1
|
6119 {
|
rlm@1
|
6120 STM_REG(8192, 13);
|
rlm@1
|
6121 STM_REG(16384, 14);
|
rlm@1
|
6122 }
|
rlm@1
|
6123
|
rlm@1
|
6124 if (opcode & 32768)
|
rlm@1
|
6125 {
|
rlm@1
|
6126 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
6127 if (!offset)
|
rlm@1
|
6128 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6129 else
|
rlm@1
|
6130 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6131 }
|
rlm@1
|
6132 }
|
rlm@1
|
6133 break;
|
rlm@1
|
6134 CASE_16(0x960)
|
rlm@1
|
6135 {
|
rlm@1
|
6136 // STMDB Rn!, {Rlist}^
|
rlm@1
|
6137 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6138 u32 temp = reg[base].I -
|
rlm@1
|
6139 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
6140 u32 address = temp & 0xFFFFFFFC;
|
rlm@1
|
6141 clockTicks += 2;
|
rlm@1
|
6142 int offset = 0;
|
rlm@1
|
6143
|
rlm@1
|
6144 STMW_REG(1, 0);
|
rlm@1
|
6145 STMW_REG(2, 1);
|
rlm@1
|
6146 STMW_REG(4, 2);
|
rlm@1
|
6147 STMW_REG(8, 3);
|
rlm@1
|
6148 STMW_REG(16, 4);
|
rlm@1
|
6149 STMW_REG(32, 5);
|
rlm@1
|
6150 STMW_REG(64, 6);
|
rlm@1
|
6151 STMW_REG(128, 7);
|
rlm@1
|
6152
|
rlm@1
|
6153 if (armMode == 0x11)
|
rlm@1
|
6154 {
|
rlm@1
|
6155 STMW_REG(256, R8_FIQ);
|
rlm@1
|
6156 STMW_REG(512, R9_FIQ);
|
rlm@1
|
6157 STMW_REG(1024, R10_FIQ);
|
rlm@1
|
6158 STMW_REG(2048, R11_FIQ);
|
rlm@1
|
6159 STMW_REG(4096, R12_FIQ);
|
rlm@1
|
6160 }
|
rlm@1
|
6161 else
|
rlm@1
|
6162 {
|
rlm@1
|
6163 STMW_REG(256, 8);
|
rlm@1
|
6164 STMW_REG(512, 9);
|
rlm@1
|
6165 STMW_REG(1024, 10);
|
rlm@1
|
6166 STMW_REG(2048, 11);
|
rlm@1
|
6167 STMW_REG(4096, 12);
|
rlm@1
|
6168 }
|
rlm@1
|
6169
|
rlm@1
|
6170 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
6171 {
|
rlm@1
|
6172 STMW_REG(8192, R13_USR);
|
rlm@1
|
6173 STMW_REG(16384, R14_USR);
|
rlm@1
|
6174 }
|
rlm@1
|
6175 else
|
rlm@1
|
6176 {
|
rlm@1
|
6177 STMW_REG(8192, 13);
|
rlm@1
|
6178 STMW_REG(16384, 14);
|
rlm@1
|
6179 }
|
rlm@1
|
6180
|
rlm@1
|
6181 if (opcode & 32768)
|
rlm@1
|
6182 {
|
rlm@1
|
6183 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
6184 if (!offset)
|
rlm@1
|
6185 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6186 else
|
rlm@1
|
6187 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6188 reg[base].I = temp;
|
rlm@1
|
6189 }
|
rlm@1
|
6190 }
|
rlm@1
|
6191 break;
|
rlm@1
|
6192
|
rlm@1
|
6193 CASE_16(0x980)
|
rlm@1
|
6194 // STMIB Rn, {Rlist}
|
rlm@1
|
6195 {
|
rlm@1
|
6196 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6197 u32 address = (reg[base].I + 4) & 0xFFFFFFFC;
|
rlm@1
|
6198 clockTicks += 2;
|
rlm@1
|
6199 int offset = 0;
|
rlm@1
|
6200 STM_REG(1, 0);
|
rlm@1
|
6201 STM_REG(2, 1);
|
rlm@1
|
6202 STM_REG(4, 2);
|
rlm@1
|
6203 STM_REG(8, 3);
|
rlm@1
|
6204 STM_REG(16, 4);
|
rlm@1
|
6205 STM_REG(32, 5);
|
rlm@1
|
6206 STM_REG(64, 6);
|
rlm@1
|
6207 STM_REG(128, 7);
|
rlm@1
|
6208 STM_REG(256, 8);
|
rlm@1
|
6209 STM_REG(512, 9);
|
rlm@1
|
6210 STM_REG(1024, 10);
|
rlm@1
|
6211 STM_REG(2048, 11);
|
rlm@1
|
6212 STM_REG(4096, 12);
|
rlm@1
|
6213 STM_REG(8192, 13);
|
rlm@1
|
6214 STM_REG(16384, 14);
|
rlm@1
|
6215 if (opcode & 32768)
|
rlm@1
|
6216 {
|
rlm@1
|
6217 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
6218 if (!offset)
|
rlm@1
|
6219 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6220 else
|
rlm@1
|
6221 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6222 }
|
rlm@1
|
6223 }
|
rlm@1
|
6224 break;
|
rlm@1
|
6225 CASE_16(0x9a0)
|
rlm@1
|
6226 {
|
rlm@1
|
6227 // STMIB Rn!, {Rlist}
|
rlm@1
|
6228 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6229 u32 address = (reg[base].I + 4) & 0xFFFFFFFC;
|
rlm@1
|
6230 clockTicks += 2;
|
rlm@1
|
6231 int offset = 0;
|
rlm@1
|
6232 u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 0xFF] +
|
rlm@1
|
6233 cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
6234 STMW_REG(1, 0);
|
rlm@1
|
6235 STMW_REG(2, 1);
|
rlm@1
|
6236 STMW_REG(4, 2);
|
rlm@1
|
6237 STMW_REG(8, 3);
|
rlm@1
|
6238 STMW_REG(16, 4);
|
rlm@1
|
6239 STMW_REG(32, 5);
|
rlm@1
|
6240 STMW_REG(64, 6);
|
rlm@1
|
6241 STMW_REG(128, 7);
|
rlm@1
|
6242 STMW_REG(256, 8);
|
rlm@1
|
6243 STMW_REG(512, 9);
|
rlm@1
|
6244 STMW_REG(1024, 10);
|
rlm@1
|
6245 STMW_REG(2048, 11);
|
rlm@1
|
6246 STMW_REG(4096, 12);
|
rlm@1
|
6247 STMW_REG(8192, 13);
|
rlm@1
|
6248 STMW_REG(16384, 14);
|
rlm@1
|
6249 if (opcode & 32768)
|
rlm@1
|
6250 {
|
rlm@1
|
6251 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
6252 if (!offset)
|
rlm@1
|
6253 {
|
rlm@1
|
6254 reg[base].I = temp;
|
rlm@1
|
6255 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6256 }
|
rlm@1
|
6257 else
|
rlm@1
|
6258 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6259 }
|
rlm@1
|
6260 }
|
rlm@1
|
6261 break;
|
rlm@1
|
6262 CASE_16(0x9c0)
|
rlm@1
|
6263 {
|
rlm@1
|
6264 // STMIB Rn, {Rlist}^
|
rlm@1
|
6265 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6266 u32 address = (reg[base].I + 4) & 0xFFFFFFFC;
|
rlm@1
|
6267 clockTicks += 2;
|
rlm@1
|
6268 int offset = 0;
|
rlm@1
|
6269 STM_REG(1, 0);
|
rlm@1
|
6270 STM_REG(2, 1);
|
rlm@1
|
6271 STM_REG(4, 2);
|
rlm@1
|
6272 STM_REG(8, 3);
|
rlm@1
|
6273 STM_REG(16, 4);
|
rlm@1
|
6274 STM_REG(32, 5);
|
rlm@1
|
6275 STM_REG(64, 6);
|
rlm@1
|
6276 STM_REG(128, 7);
|
rlm@1
|
6277 if (armMode == 0x11)
|
rlm@1
|
6278 {
|
rlm@1
|
6279 STM_REG(256, R8_FIQ);
|
rlm@1
|
6280 STM_REG(512, R9_FIQ);
|
rlm@1
|
6281 STM_REG(1024, R10_FIQ);
|
rlm@1
|
6282 STM_REG(2048, R11_FIQ);
|
rlm@1
|
6283 STM_REG(4096, R12_FIQ);
|
rlm@1
|
6284 }
|
rlm@1
|
6285 else
|
rlm@1
|
6286 {
|
rlm@1
|
6287 STM_REG(256, 8);
|
rlm@1
|
6288 STM_REG(512, 9);
|
rlm@1
|
6289 STM_REG(1024, 10);
|
rlm@1
|
6290 STM_REG(2048, 11);
|
rlm@1
|
6291 STM_REG(4096, 12);
|
rlm@1
|
6292 }
|
rlm@1
|
6293 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
6294 {
|
rlm@1
|
6295 STM_REG(8192, R13_USR);
|
rlm@1
|
6296 STM_REG(16384, R14_USR);
|
rlm@1
|
6297 }
|
rlm@1
|
6298 else
|
rlm@1
|
6299 {
|
rlm@1
|
6300 STM_REG(8192, 13);
|
rlm@1
|
6301 STM_REG(16384, 14);
|
rlm@1
|
6302 }
|
rlm@1
|
6303 if (opcode & 32768)
|
rlm@1
|
6304 {
|
rlm@1
|
6305 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
6306 if (!offset)
|
rlm@1
|
6307 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6308 else
|
rlm@1
|
6309 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6310 }
|
rlm@1
|
6311 }
|
rlm@1
|
6312 break;
|
rlm@1
|
6313 CASE_16(0x9e0)
|
rlm@1
|
6314 {
|
rlm@1
|
6315 // STMIB Rn!, {Rlist}^
|
rlm@1
|
6316 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6317 u32 address = (reg[base].I + 4) & 0xFFFFFFFC;
|
rlm@1
|
6318 clockTicks += 2;
|
rlm@1
|
6319 int offset = 0;
|
rlm@1
|
6320 u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 0xFF] +
|
rlm@1
|
6321 cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
6322 STMW_REG(1, 0);
|
rlm@1
|
6323 STMW_REG(2, 1);
|
rlm@1
|
6324 STMW_REG(4, 2);
|
rlm@1
|
6325 STMW_REG(8, 3);
|
rlm@1
|
6326 STMW_REG(16, 4);
|
rlm@1
|
6327 STMW_REG(32, 5);
|
rlm@1
|
6328 STMW_REG(64, 6);
|
rlm@1
|
6329 STMW_REG(128, 7);
|
rlm@1
|
6330 if (armMode == 0x11)
|
rlm@1
|
6331 {
|
rlm@1
|
6332 STMW_REG(256, R8_FIQ);
|
rlm@1
|
6333 STMW_REG(512, R9_FIQ);
|
rlm@1
|
6334 STMW_REG(1024, R10_FIQ);
|
rlm@1
|
6335 STMW_REG(2048, R11_FIQ);
|
rlm@1
|
6336 STMW_REG(4096, R12_FIQ);
|
rlm@1
|
6337 }
|
rlm@1
|
6338 else
|
rlm@1
|
6339 {
|
rlm@1
|
6340 STMW_REG(256, 8);
|
rlm@1
|
6341 STMW_REG(512, 9);
|
rlm@1
|
6342 STMW_REG(1024, 10);
|
rlm@1
|
6343 STMW_REG(2048, 11);
|
rlm@1
|
6344 STMW_REG(4096, 12);
|
rlm@1
|
6345 }
|
rlm@1
|
6346 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
6347 {
|
rlm@1
|
6348 STMW_REG(8192, R13_USR);
|
rlm@1
|
6349 STMW_REG(16384, R14_USR);
|
rlm@1
|
6350 }
|
rlm@1
|
6351 else
|
rlm@1
|
6352 {
|
rlm@1
|
6353 STMW_REG(8192, 13);
|
rlm@1
|
6354 STMW_REG(16384, 14);
|
rlm@1
|
6355 }
|
rlm@1
|
6356 if (opcode & 32768)
|
rlm@1
|
6357 {
|
rlm@1
|
6358 CPUWriteMemory(address, reg[15].I + 4);
|
rlm@1
|
6359 if (!offset)
|
rlm@1
|
6360 {
|
rlm@1
|
6361 reg[base].I = temp;
|
rlm@1
|
6362 clockTicks += 1 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6363 }
|
rlm@1
|
6364 else
|
rlm@1
|
6365 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6366 }
|
rlm@1
|
6367 }
|
rlm@1
|
6368 break;
|
rlm@1
|
6369
|
rlm@1
|
6370 #define LDM_REG(val, num) \
|
rlm@1
|
6371 if (opcode & (val)) { \
|
rlm@1
|
6372 reg[(num)].I = CPUReadMemory(address); \
|
rlm@1
|
6373 if (offset) \
|
rlm@1
|
6374 clockTicks += 1 + CPUUpdateTicksAccessSeq32(address); \
|
rlm@1
|
6375 else { \
|
rlm@1
|
6376 clockTicks += 1 + CPUUpdateTicksAccess32(address); \
|
rlm@1
|
6377 offset = 1; \
|
rlm@1
|
6378 } \
|
rlm@1
|
6379 address += 4; \
|
rlm@1
|
6380 }
|
rlm@1
|
6381
|
rlm@1
|
6382 CASE_16(0x810)
|
rlm@1
|
6383 {
|
rlm@1
|
6384 // LDMDA Rn, {Rlist}
|
rlm@1
|
6385 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6386 u32 temp = reg[base].I -
|
rlm@1
|
6387 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
6388 u32 address = (temp + 4) & 0xFFFFFFFC;
|
rlm@1
|
6389 clockTicks += 2;
|
rlm@1
|
6390 int offset = 0;
|
rlm@1
|
6391 LDM_REG(1, 0);
|
rlm@1
|
6392 LDM_REG(2, 1);
|
rlm@1
|
6393 LDM_REG(4, 2);
|
rlm@1
|
6394 LDM_REG(8, 3);
|
rlm@1
|
6395 LDM_REG(16, 4);
|
rlm@1
|
6396 LDM_REG(32, 5);
|
rlm@1
|
6397 LDM_REG(64, 6);
|
rlm@1
|
6398 LDM_REG(128, 7);
|
rlm@1
|
6399 LDM_REG(256, 8);
|
rlm@1
|
6400 LDM_REG(512, 9);
|
rlm@1
|
6401 LDM_REG(1024, 10);
|
rlm@1
|
6402 LDM_REG(2048, 11);
|
rlm@1
|
6403 LDM_REG(4096, 12);
|
rlm@1
|
6404 LDM_REG(8192, 13);
|
rlm@1
|
6405 LDM_REG(16384, 14);
|
rlm@1
|
6406 if (opcode & 32768)
|
rlm@1
|
6407 {
|
rlm@1
|
6408 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
6409 if (!offset)
|
rlm@1
|
6410 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6411 else
|
rlm@1
|
6412 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6413 armNextPC = reg[15].I;
|
rlm@1
|
6414 reg[15].I += 4;
|
rlm@1
|
6415 }
|
rlm@1
|
6416 }
|
rlm@1
|
6417 break;
|
rlm@1
|
6418 CASE_16(0x830)
|
rlm@1
|
6419 {
|
rlm@1
|
6420 // LDMDA Rn!, {Rlist}
|
rlm@1
|
6421 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6422 u32 temp = reg[base].I -
|
rlm@1
|
6423 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
6424 u32 address = (temp + 4) & 0xFFFFFFFC;
|
rlm@1
|
6425 clockTicks += 2;
|
rlm@1
|
6426 int offset = 0;
|
rlm@1
|
6427 LDM_REG(1, 0);
|
rlm@1
|
6428 LDM_REG(2, 1);
|
rlm@1
|
6429 LDM_REG(4, 2);
|
rlm@1
|
6430 LDM_REG(8, 3);
|
rlm@1
|
6431 LDM_REG(16, 4);
|
rlm@1
|
6432 LDM_REG(32, 5);
|
rlm@1
|
6433 LDM_REG(64, 6);
|
rlm@1
|
6434 LDM_REG(128, 7);
|
rlm@1
|
6435 LDM_REG(256, 8);
|
rlm@1
|
6436 LDM_REG(512, 9);
|
rlm@1
|
6437 LDM_REG(1024, 10);
|
rlm@1
|
6438 LDM_REG(2048, 11);
|
rlm@1
|
6439 LDM_REG(4096, 12);
|
rlm@1
|
6440 LDM_REG(8192, 13);
|
rlm@1
|
6441 LDM_REG(16384, 14);
|
rlm@1
|
6442 if (opcode & 32768)
|
rlm@1
|
6443 {
|
rlm@1
|
6444 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
6445 if (!offset)
|
rlm@1
|
6446 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6447 else
|
rlm@1
|
6448 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6449 armNextPC = reg[15].I;
|
rlm@1
|
6450 reg[15].I += 4;
|
rlm@1
|
6451 }
|
rlm@1
|
6452 if (!(opcode & (1 << base)))
|
rlm@1
|
6453 reg[base].I = temp;
|
rlm@1
|
6454 }
|
rlm@1
|
6455 break;
|
rlm@1
|
6456 CASE_16(0x850)
|
rlm@1
|
6457 {
|
rlm@1
|
6458 // LDMDA Rn, {Rlist}^
|
rlm@1
|
6459 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6460 u32 temp = reg[base].I -
|
rlm@1
|
6461 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
6462 u32 address = (temp + 4) & 0xFFFFFFFC;
|
rlm@1
|
6463 clockTicks += 2;
|
rlm@1
|
6464 int offset = 0;
|
rlm@1
|
6465 if (opcode & 0x8000)
|
rlm@1
|
6466 {
|
rlm@1
|
6467 LDM_REG(1, 0);
|
rlm@1
|
6468 LDM_REG(2, 1);
|
rlm@1
|
6469 LDM_REG(4, 2);
|
rlm@1
|
6470 LDM_REG(8, 3);
|
rlm@1
|
6471 LDM_REG(16, 4);
|
rlm@1
|
6472 LDM_REG(32, 5);
|
rlm@1
|
6473 LDM_REG(64, 6);
|
rlm@1
|
6474 LDM_REG(128, 7);
|
rlm@1
|
6475 LDM_REG(256, 8);
|
rlm@1
|
6476 LDM_REG(512, 9);
|
rlm@1
|
6477 LDM_REG(1024, 10);
|
rlm@1
|
6478 LDM_REG(2048, 11);
|
rlm@1
|
6479 LDM_REG(4096, 12);
|
rlm@1
|
6480 LDM_REG(8192, 13);
|
rlm@1
|
6481 LDM_REG(16384, 14);
|
rlm@1
|
6482
|
rlm@1
|
6483 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
6484 if (!offset)
|
rlm@1
|
6485 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6486 else
|
rlm@1
|
6487 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6488
|
rlm@1
|
6489 CPUSwitchMode(reg[17].I & 0x1f, false);
|
rlm@1
|
6490 if (armState)
|
rlm@1
|
6491 {
|
rlm@1
|
6492 armNextPC = reg[15].I & 0xFFFFFFFC;
|
rlm@1
|
6493 reg[15].I = armNextPC + 4;
|
rlm@1
|
6494 }
|
rlm@1
|
6495 else
|
rlm@1
|
6496 {
|
rlm@1
|
6497 armNextPC = reg[15].I & 0xFFFFFFFE;
|
rlm@1
|
6498 reg[15].I = armNextPC + 2;
|
rlm@1
|
6499 }
|
rlm@1
|
6500 }
|
rlm@1
|
6501 else
|
rlm@1
|
6502 {
|
rlm@1
|
6503 LDM_REG(1, 0);
|
rlm@1
|
6504 LDM_REG(2, 1);
|
rlm@1
|
6505 LDM_REG(4, 2);
|
rlm@1
|
6506 LDM_REG(8, 3);
|
rlm@1
|
6507 LDM_REG(16, 4);
|
rlm@1
|
6508 LDM_REG(32, 5);
|
rlm@1
|
6509 LDM_REG(64, 6);
|
rlm@1
|
6510 LDM_REG(128, 7);
|
rlm@1
|
6511
|
rlm@1
|
6512 if (armMode == 0x11)
|
rlm@1
|
6513 {
|
rlm@1
|
6514 LDM_REG(256, R8_FIQ);
|
rlm@1
|
6515 LDM_REG(512, R9_FIQ);
|
rlm@1
|
6516 LDM_REG(1024, R10_FIQ);
|
rlm@1
|
6517 LDM_REG(2048, R11_FIQ);
|
rlm@1
|
6518 LDM_REG(4096, R12_FIQ);
|
rlm@1
|
6519 }
|
rlm@1
|
6520 else
|
rlm@1
|
6521 {
|
rlm@1
|
6522 LDM_REG(256, 8);
|
rlm@1
|
6523 LDM_REG(512, 9);
|
rlm@1
|
6524 LDM_REG(1024, 10);
|
rlm@1
|
6525 LDM_REG(2048, 11);
|
rlm@1
|
6526 LDM_REG(4096, 12);
|
rlm@1
|
6527 }
|
rlm@1
|
6528
|
rlm@1
|
6529 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
6530 {
|
rlm@1
|
6531 LDM_REG(8192, R13_USR);
|
rlm@1
|
6532 LDM_REG(16384, R14_USR);
|
rlm@1
|
6533 }
|
rlm@1
|
6534 else
|
rlm@1
|
6535 {
|
rlm@1
|
6536 LDM_REG(8192, 13);
|
rlm@1
|
6537 LDM_REG(16384, 14);
|
rlm@1
|
6538 }
|
rlm@1
|
6539 }
|
rlm@1
|
6540 }
|
rlm@1
|
6541 break;
|
rlm@1
|
6542 CASE_16(0x870)
|
rlm@1
|
6543 {
|
rlm@1
|
6544 // LDMDA Rn!, {Rlist}^
|
rlm@1
|
6545 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6546 u32 temp = reg[base].I -
|
rlm@1
|
6547 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
6548 u32 address = (temp + 4) & 0xFFFFFFFC;
|
rlm@1
|
6549 clockTicks += 2;
|
rlm@1
|
6550 int offset = 0;
|
rlm@1
|
6551 if (opcode & 0x8000)
|
rlm@1
|
6552 {
|
rlm@1
|
6553 LDM_REG(1, 0);
|
rlm@1
|
6554 LDM_REG(2, 1);
|
rlm@1
|
6555 LDM_REG(4, 2);
|
rlm@1
|
6556 LDM_REG(8, 3);
|
rlm@1
|
6557 LDM_REG(16, 4);
|
rlm@1
|
6558 LDM_REG(32, 5);
|
rlm@1
|
6559 LDM_REG(64, 6);
|
rlm@1
|
6560 LDM_REG(128, 7);
|
rlm@1
|
6561 LDM_REG(256, 8);
|
rlm@1
|
6562 LDM_REG(512, 9);
|
rlm@1
|
6563 LDM_REG(1024, 10);
|
rlm@1
|
6564 LDM_REG(2048, 11);
|
rlm@1
|
6565 LDM_REG(4096, 12);
|
rlm@1
|
6566 LDM_REG(8192, 13);
|
rlm@1
|
6567 LDM_REG(16384, 14);
|
rlm@1
|
6568
|
rlm@1
|
6569 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
6570 if (!offset)
|
rlm@1
|
6571 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6572 else
|
rlm@1
|
6573 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6574
|
rlm@1
|
6575 if (!(opcode & (1 << base)))
|
rlm@1
|
6576 reg[base].I = temp;
|
rlm@1
|
6577
|
rlm@1
|
6578 CPUSwitchMode(reg[17].I & 0x1f, false);
|
rlm@1
|
6579 if (armState)
|
rlm@1
|
6580 {
|
rlm@1
|
6581 armNextPC = reg[15].I & 0xFFFFFFFC;
|
rlm@1
|
6582 reg[15].I = armNextPC + 4;
|
rlm@1
|
6583 }
|
rlm@1
|
6584 else
|
rlm@1
|
6585 {
|
rlm@1
|
6586 armNextPC = reg[15].I & 0xFFFFFFFE;
|
rlm@1
|
6587 reg[15].I = armNextPC + 2;
|
rlm@1
|
6588 }
|
rlm@1
|
6589 }
|
rlm@1
|
6590 else
|
rlm@1
|
6591 {
|
rlm@1
|
6592 LDM_REG(1, 0);
|
rlm@1
|
6593 LDM_REG(2, 1);
|
rlm@1
|
6594 LDM_REG(4, 2);
|
rlm@1
|
6595 LDM_REG(8, 3);
|
rlm@1
|
6596 LDM_REG(16, 4);
|
rlm@1
|
6597 LDM_REG(32, 5);
|
rlm@1
|
6598 LDM_REG(64, 6);
|
rlm@1
|
6599 LDM_REG(128, 7);
|
rlm@1
|
6600
|
rlm@1
|
6601 if (armMode == 0x11)
|
rlm@1
|
6602 {
|
rlm@1
|
6603 LDM_REG(256, R8_FIQ);
|
rlm@1
|
6604 LDM_REG(512, R9_FIQ);
|
rlm@1
|
6605 LDM_REG(1024, R10_FIQ);
|
rlm@1
|
6606 LDM_REG(2048, R11_FIQ);
|
rlm@1
|
6607 LDM_REG(4096, R12_FIQ);
|
rlm@1
|
6608 }
|
rlm@1
|
6609 else
|
rlm@1
|
6610 {
|
rlm@1
|
6611 LDM_REG(256, 8);
|
rlm@1
|
6612 LDM_REG(512, 9);
|
rlm@1
|
6613 LDM_REG(1024, 10);
|
rlm@1
|
6614 LDM_REG(2048, 11);
|
rlm@1
|
6615 LDM_REG(4096, 12);
|
rlm@1
|
6616 }
|
rlm@1
|
6617
|
rlm@1
|
6618 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
6619 {
|
rlm@1
|
6620 LDM_REG(8192, R13_USR);
|
rlm@1
|
6621 LDM_REG(16384, R14_USR);
|
rlm@1
|
6622 }
|
rlm@1
|
6623 else
|
rlm@1
|
6624 {
|
rlm@1
|
6625 LDM_REG(8192, 13);
|
rlm@1
|
6626 LDM_REG(16384, 14);
|
rlm@1
|
6627 }
|
rlm@1
|
6628
|
rlm@1
|
6629 if (!(opcode & (1 << base)))
|
rlm@1
|
6630 reg[base].I = temp;
|
rlm@1
|
6631 }
|
rlm@1
|
6632 }
|
rlm@1
|
6633 break;
|
rlm@1
|
6634
|
rlm@1
|
6635 CASE_16(0x890)
|
rlm@1
|
6636 {
|
rlm@1
|
6637 // LDMIA Rn, {Rlist}
|
rlm@1
|
6638 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6639 u32 address = reg[base].I & 0xFFFFFFFC;
|
rlm@1
|
6640 clockTicks += 2;
|
rlm@1
|
6641 int offset = 0;
|
rlm@1
|
6642 LDM_REG(1, 0);
|
rlm@1
|
6643 LDM_REG(2, 1);
|
rlm@1
|
6644 LDM_REG(4, 2);
|
rlm@1
|
6645 LDM_REG(8, 3);
|
rlm@1
|
6646 LDM_REG(16, 4);
|
rlm@1
|
6647 LDM_REG(32, 5);
|
rlm@1
|
6648 LDM_REG(64, 6);
|
rlm@1
|
6649 LDM_REG(128, 7);
|
rlm@1
|
6650 LDM_REG(256, 8);
|
rlm@1
|
6651 LDM_REG(512, 9);
|
rlm@1
|
6652 LDM_REG(1024, 10);
|
rlm@1
|
6653 LDM_REG(2048, 11);
|
rlm@1
|
6654 LDM_REG(4096, 12);
|
rlm@1
|
6655 LDM_REG(8192, 13);
|
rlm@1
|
6656 LDM_REG(16384, 14);
|
rlm@1
|
6657 if (opcode & 32768)
|
rlm@1
|
6658 {
|
rlm@1
|
6659 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
6660 if (!offset)
|
rlm@1
|
6661 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6662 else
|
rlm@1
|
6663 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6664 armNextPC = reg[15].I;
|
rlm@1
|
6665 reg[15].I += 4;
|
rlm@1
|
6666 }
|
rlm@1
|
6667 }
|
rlm@1
|
6668 break;
|
rlm@1
|
6669 CASE_16(0x8b0)
|
rlm@1
|
6670 {
|
rlm@1
|
6671 // LDMIA Rn!, {Rlist}
|
rlm@1
|
6672 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6673 u32 temp = reg[base].I +
|
rlm@1
|
6674 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
6675 u32 address = reg[base].I & 0xFFFFFFFC;
|
rlm@1
|
6676 clockTicks += 2;
|
rlm@1
|
6677 int offset = 0;
|
rlm@1
|
6678 LDM_REG(1, 0);
|
rlm@1
|
6679 LDM_REG(2, 1);
|
rlm@1
|
6680 LDM_REG(4, 2);
|
rlm@1
|
6681 LDM_REG(8, 3);
|
rlm@1
|
6682 LDM_REG(16, 4);
|
rlm@1
|
6683 LDM_REG(32, 5);
|
rlm@1
|
6684 LDM_REG(64, 6);
|
rlm@1
|
6685 LDM_REG(128, 7);
|
rlm@1
|
6686 LDM_REG(256, 8);
|
rlm@1
|
6687 LDM_REG(512, 9);
|
rlm@1
|
6688 LDM_REG(1024, 10);
|
rlm@1
|
6689 LDM_REG(2048, 11);
|
rlm@1
|
6690 LDM_REG(4096, 12);
|
rlm@1
|
6691 LDM_REG(8192, 13);
|
rlm@1
|
6692 LDM_REG(16384, 14);
|
rlm@1
|
6693 if (opcode & 32768)
|
rlm@1
|
6694 {
|
rlm@1
|
6695 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
6696 if (!offset)
|
rlm@1
|
6697 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6698 else
|
rlm@1
|
6699 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6700 armNextPC = reg[15].I;
|
rlm@1
|
6701 reg[15].I += 4;
|
rlm@1
|
6702 }
|
rlm@1
|
6703 if (!(opcode & (1 << base)))
|
rlm@1
|
6704 reg[base].I = temp;
|
rlm@1
|
6705 }
|
rlm@1
|
6706 break;
|
rlm@1
|
6707 CASE_16(0x8d0)
|
rlm@1
|
6708 {
|
rlm@1
|
6709 // LDMIA Rn, {Rlist}^
|
rlm@1
|
6710 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6711 u32 address = reg[base].I & 0xFFFFFFFC;
|
rlm@1
|
6712 clockTicks += 2;
|
rlm@1
|
6713 int offset = 0;
|
rlm@1
|
6714 if (opcode & 0x8000)
|
rlm@1
|
6715 {
|
rlm@1
|
6716 LDM_REG(1, 0);
|
rlm@1
|
6717 LDM_REG(2, 1);
|
rlm@1
|
6718 LDM_REG(4, 2);
|
rlm@1
|
6719 LDM_REG(8, 3);
|
rlm@1
|
6720 LDM_REG(16, 4);
|
rlm@1
|
6721 LDM_REG(32, 5);
|
rlm@1
|
6722 LDM_REG(64, 6);
|
rlm@1
|
6723 LDM_REG(128, 7);
|
rlm@1
|
6724 LDM_REG(256, 8);
|
rlm@1
|
6725 LDM_REG(512, 9);
|
rlm@1
|
6726 LDM_REG(1024, 10);
|
rlm@1
|
6727 LDM_REG(2048, 11);
|
rlm@1
|
6728 LDM_REG(4096, 12);
|
rlm@1
|
6729 LDM_REG(8192, 13);
|
rlm@1
|
6730 LDM_REG(16384, 14);
|
rlm@1
|
6731
|
rlm@1
|
6732 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
6733 if (!offset)
|
rlm@1
|
6734 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6735 else
|
rlm@1
|
6736 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6737
|
rlm@1
|
6738 CPUSwitchMode(reg[17].I & 0x1f, false);
|
rlm@1
|
6739 if (armState)
|
rlm@1
|
6740 {
|
rlm@1
|
6741 armNextPC = reg[15].I & 0xFFFFFFFC;
|
rlm@1
|
6742 reg[15].I = armNextPC + 4;
|
rlm@1
|
6743 }
|
rlm@1
|
6744 else
|
rlm@1
|
6745 {
|
rlm@1
|
6746 armNextPC = reg[15].I & 0xFFFFFFFE;
|
rlm@1
|
6747 reg[15].I = armNextPC + 2;
|
rlm@1
|
6748 }
|
rlm@1
|
6749 }
|
rlm@1
|
6750 else
|
rlm@1
|
6751 {
|
rlm@1
|
6752 LDM_REG(1, 0);
|
rlm@1
|
6753 LDM_REG(2, 1);
|
rlm@1
|
6754 LDM_REG(4, 2);
|
rlm@1
|
6755 LDM_REG(8, 3);
|
rlm@1
|
6756 LDM_REG(16, 4);
|
rlm@1
|
6757 LDM_REG(32, 5);
|
rlm@1
|
6758 LDM_REG(64, 6);
|
rlm@1
|
6759 LDM_REG(128, 7);
|
rlm@1
|
6760
|
rlm@1
|
6761 if (armMode == 0x11)
|
rlm@1
|
6762 {
|
rlm@1
|
6763 LDM_REG(256, R8_FIQ);
|
rlm@1
|
6764 LDM_REG(512, R9_FIQ);
|
rlm@1
|
6765 LDM_REG(1024, R10_FIQ);
|
rlm@1
|
6766 LDM_REG(2048, R11_FIQ);
|
rlm@1
|
6767 LDM_REG(4096, R12_FIQ);
|
rlm@1
|
6768 }
|
rlm@1
|
6769 else
|
rlm@1
|
6770 {
|
rlm@1
|
6771 LDM_REG(256, 8);
|
rlm@1
|
6772 LDM_REG(512, 9);
|
rlm@1
|
6773 LDM_REG(1024, 10);
|
rlm@1
|
6774 LDM_REG(2048, 11);
|
rlm@1
|
6775 LDM_REG(4096, 12);
|
rlm@1
|
6776 }
|
rlm@1
|
6777
|
rlm@1
|
6778 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
6779 {
|
rlm@1
|
6780 LDM_REG(8192, R13_USR);
|
rlm@1
|
6781 LDM_REG(16384, R14_USR);
|
rlm@1
|
6782 }
|
rlm@1
|
6783 else
|
rlm@1
|
6784 {
|
rlm@1
|
6785 LDM_REG(8192, 13);
|
rlm@1
|
6786 LDM_REG(16384, 14);
|
rlm@1
|
6787 }
|
rlm@1
|
6788 }
|
rlm@1
|
6789 }
|
rlm@1
|
6790 break;
|
rlm@1
|
6791 CASE_16(0x8f0)
|
rlm@1
|
6792 {
|
rlm@1
|
6793 // LDMIA Rn!, {Rlist}^
|
rlm@1
|
6794 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6795 u32 temp = reg[base].I +
|
rlm@1
|
6796 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
6797 u32 address = reg[base].I & 0xFFFFFFFC;
|
rlm@1
|
6798 clockTicks += 2;
|
rlm@1
|
6799 int offset = 0;
|
rlm@1
|
6800 if (opcode & 0x8000)
|
rlm@1
|
6801 {
|
rlm@1
|
6802 LDM_REG(1, 0);
|
rlm@1
|
6803 LDM_REG(2, 1);
|
rlm@1
|
6804 LDM_REG(4, 2);
|
rlm@1
|
6805 LDM_REG(8, 3);
|
rlm@1
|
6806 LDM_REG(16, 4);
|
rlm@1
|
6807 LDM_REG(32, 5);
|
rlm@1
|
6808 LDM_REG(64, 6);
|
rlm@1
|
6809 LDM_REG(128, 7);
|
rlm@1
|
6810 LDM_REG(256, 8);
|
rlm@1
|
6811 LDM_REG(512, 9);
|
rlm@1
|
6812 LDM_REG(1024, 10);
|
rlm@1
|
6813 LDM_REG(2048, 11);
|
rlm@1
|
6814 LDM_REG(4096, 12);
|
rlm@1
|
6815 LDM_REG(8192, 13);
|
rlm@1
|
6816 LDM_REG(16384, 14);
|
rlm@1
|
6817
|
rlm@1
|
6818 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
6819 if (!offset)
|
rlm@1
|
6820 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6821 else
|
rlm@1
|
6822 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6823
|
rlm@1
|
6824 if (!(opcode & (1 << base)))
|
rlm@1
|
6825 reg[base].I = temp;
|
rlm@1
|
6826
|
rlm@1
|
6827 CPUSwitchMode(reg[17].I & 0x1f, false);
|
rlm@1
|
6828 if (armState)
|
rlm@1
|
6829 {
|
rlm@1
|
6830 armNextPC = reg[15].I & 0xFFFFFFFC;
|
rlm@1
|
6831 reg[15].I = armNextPC + 4;
|
rlm@1
|
6832 }
|
rlm@1
|
6833 else
|
rlm@1
|
6834 {
|
rlm@1
|
6835 armNextPC = reg[15].I & 0xFFFFFFFE;
|
rlm@1
|
6836 reg[15].I = armNextPC + 2;
|
rlm@1
|
6837 }
|
rlm@1
|
6838 }
|
rlm@1
|
6839 else
|
rlm@1
|
6840 {
|
rlm@1
|
6841 LDM_REG(1, 0);
|
rlm@1
|
6842 LDM_REG(2, 1);
|
rlm@1
|
6843 LDM_REG(4, 2);
|
rlm@1
|
6844 LDM_REG(8, 3);
|
rlm@1
|
6845 LDM_REG(16, 4);
|
rlm@1
|
6846 LDM_REG(32, 5);
|
rlm@1
|
6847 LDM_REG(64, 6);
|
rlm@1
|
6848 LDM_REG(128, 7);
|
rlm@1
|
6849
|
rlm@1
|
6850 if (armMode == 0x11)
|
rlm@1
|
6851 {
|
rlm@1
|
6852 LDM_REG(256, R8_FIQ);
|
rlm@1
|
6853 LDM_REG(512, R9_FIQ);
|
rlm@1
|
6854 LDM_REG(1024, R10_FIQ);
|
rlm@1
|
6855 LDM_REG(2048, R11_FIQ);
|
rlm@1
|
6856 LDM_REG(4096, R12_FIQ);
|
rlm@1
|
6857 }
|
rlm@1
|
6858 else
|
rlm@1
|
6859 {
|
rlm@1
|
6860 LDM_REG(256, 8);
|
rlm@1
|
6861 LDM_REG(512, 9);
|
rlm@1
|
6862 LDM_REG(1024, 10);
|
rlm@1
|
6863 LDM_REG(2048, 11);
|
rlm@1
|
6864 LDM_REG(4096, 12);
|
rlm@1
|
6865 }
|
rlm@1
|
6866
|
rlm@1
|
6867 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
6868 {
|
rlm@1
|
6869 LDM_REG(8192, R13_USR);
|
rlm@1
|
6870 LDM_REG(16384, R14_USR);
|
rlm@1
|
6871 }
|
rlm@1
|
6872 else
|
rlm@1
|
6873 {
|
rlm@1
|
6874 LDM_REG(8192, 13);
|
rlm@1
|
6875 LDM_REG(16384, 14);
|
rlm@1
|
6876 }
|
rlm@1
|
6877
|
rlm@1
|
6878 if (!(opcode & (1 << base)))
|
rlm@1
|
6879 reg[base].I = temp;
|
rlm@1
|
6880 }
|
rlm@1
|
6881 }
|
rlm@1
|
6882 break;
|
rlm@1
|
6883
|
rlm@1
|
6884 CASE_16(0x910)
|
rlm@1
|
6885 {
|
rlm@1
|
6886 // LDMDB Rn, {Rlist}
|
rlm@1
|
6887 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6888 u32 temp = reg[base].I -
|
rlm@1
|
6889 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
6890 u32 address = temp & 0xFFFFFFFC;
|
rlm@1
|
6891 clockTicks += 2;
|
rlm@1
|
6892 int offset = 0;
|
rlm@1
|
6893 LDM_REG(1, 0);
|
rlm@1
|
6894 LDM_REG(2, 1);
|
rlm@1
|
6895 LDM_REG(4, 2);
|
rlm@1
|
6896 LDM_REG(8, 3);
|
rlm@1
|
6897 LDM_REG(16, 4);
|
rlm@1
|
6898 LDM_REG(32, 5);
|
rlm@1
|
6899 LDM_REG(64, 6);
|
rlm@1
|
6900 LDM_REG(128, 7);
|
rlm@1
|
6901 LDM_REG(256, 8);
|
rlm@1
|
6902 LDM_REG(512, 9);
|
rlm@1
|
6903 LDM_REG(1024, 10);
|
rlm@1
|
6904 LDM_REG(2048, 11);
|
rlm@1
|
6905 LDM_REG(4096, 12);
|
rlm@1
|
6906 LDM_REG(8192, 13);
|
rlm@1
|
6907 LDM_REG(16384, 14);
|
rlm@1
|
6908 if (opcode & 32768)
|
rlm@1
|
6909 {
|
rlm@1
|
6910 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
6911 if (!offset)
|
rlm@1
|
6912 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6913 else
|
rlm@1
|
6914 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6915 armNextPC = reg[15].I;
|
rlm@1
|
6916 reg[15].I += 4;
|
rlm@1
|
6917 }
|
rlm@1
|
6918 }
|
rlm@1
|
6919 break;
|
rlm@1
|
6920 CASE_16(0x930)
|
rlm@1
|
6921 {
|
rlm@1
|
6922 // LDMDB Rn!, {Rlist}
|
rlm@1
|
6923 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6924 u32 temp = reg[base].I -
|
rlm@1
|
6925 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
6926 u32 address = temp & 0xFFFFFFFC;
|
rlm@1
|
6927 clockTicks += 2;
|
rlm@1
|
6928 int offset = 0;
|
rlm@1
|
6929 LDM_REG(1, 0);
|
rlm@1
|
6930 LDM_REG(2, 1);
|
rlm@1
|
6931 LDM_REG(4, 2);
|
rlm@1
|
6932 LDM_REG(8, 3);
|
rlm@1
|
6933 LDM_REG(16, 4);
|
rlm@1
|
6934 LDM_REG(32, 5);
|
rlm@1
|
6935 LDM_REG(64, 6);
|
rlm@1
|
6936 LDM_REG(128, 7);
|
rlm@1
|
6937 LDM_REG(256, 8);
|
rlm@1
|
6938 LDM_REG(512, 9);
|
rlm@1
|
6939 LDM_REG(1024, 10);
|
rlm@1
|
6940 LDM_REG(2048, 11);
|
rlm@1
|
6941 LDM_REG(4096, 12);
|
rlm@1
|
6942 LDM_REG(8192, 13);
|
rlm@1
|
6943 LDM_REG(16384, 14);
|
rlm@1
|
6944 if (opcode & 32768)
|
rlm@1
|
6945 {
|
rlm@1
|
6946 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
6947 if (!offset)
|
rlm@1
|
6948 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6949 else
|
rlm@1
|
6950 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6951 armNextPC = reg[15].I;
|
rlm@1
|
6952 reg[15].I += 4;
|
rlm@1
|
6953 }
|
rlm@1
|
6954 if (!(opcode & (1 << base)))
|
rlm@1
|
6955 reg[base].I = temp;
|
rlm@1
|
6956 }
|
rlm@1
|
6957 break;
|
rlm@1
|
6958 CASE_16(0x950)
|
rlm@1
|
6959 {
|
rlm@1
|
6960 // LDMDB Rn, {Rlist}^
|
rlm@1
|
6961 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
6962 u32 temp = reg[base].I -
|
rlm@1
|
6963 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
6964 u32 address = temp & 0xFFFFFFFC;
|
rlm@1
|
6965 clockTicks += 2;
|
rlm@1
|
6966 int offset = 0;
|
rlm@1
|
6967 if (opcode & 0x8000)
|
rlm@1
|
6968 {
|
rlm@1
|
6969 LDM_REG(1, 0);
|
rlm@1
|
6970 LDM_REG(2, 1);
|
rlm@1
|
6971 LDM_REG(4, 2);
|
rlm@1
|
6972 LDM_REG(8, 3);
|
rlm@1
|
6973 LDM_REG(16, 4);
|
rlm@1
|
6974 LDM_REG(32, 5);
|
rlm@1
|
6975 LDM_REG(64, 6);
|
rlm@1
|
6976 LDM_REG(128, 7);
|
rlm@1
|
6977 LDM_REG(256, 8);
|
rlm@1
|
6978 LDM_REG(512, 9);
|
rlm@1
|
6979 LDM_REG(1024, 10);
|
rlm@1
|
6980 LDM_REG(2048, 11);
|
rlm@1
|
6981 LDM_REG(4096, 12);
|
rlm@1
|
6982 LDM_REG(8192, 13);
|
rlm@1
|
6983 LDM_REG(16384, 14);
|
rlm@1
|
6984
|
rlm@1
|
6985 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
6986 if (!offset)
|
rlm@1
|
6987 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
6988 else
|
rlm@1
|
6989 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
6990
|
rlm@1
|
6991 CPUSwitchMode(reg[17].I & 0x1f, false);
|
rlm@1
|
6992 if (armState)
|
rlm@1
|
6993 {
|
rlm@1
|
6994 armNextPC = reg[15].I & 0xFFFFFFFC;
|
rlm@1
|
6995 reg[15].I = armNextPC + 4;
|
rlm@1
|
6996 }
|
rlm@1
|
6997 else
|
rlm@1
|
6998 {
|
rlm@1
|
6999 armNextPC = reg[15].I & 0xFFFFFFFE;
|
rlm@1
|
7000 reg[15].I = armNextPC + 2;
|
rlm@1
|
7001 }
|
rlm@1
|
7002 }
|
rlm@1
|
7003 else
|
rlm@1
|
7004 {
|
rlm@1
|
7005 LDM_REG(1, 0);
|
rlm@1
|
7006 LDM_REG(2, 1);
|
rlm@1
|
7007 LDM_REG(4, 2);
|
rlm@1
|
7008 LDM_REG(8, 3);
|
rlm@1
|
7009 LDM_REG(16, 4);
|
rlm@1
|
7010 LDM_REG(32, 5);
|
rlm@1
|
7011 LDM_REG(64, 6);
|
rlm@1
|
7012 LDM_REG(128, 7);
|
rlm@1
|
7013
|
rlm@1
|
7014 if (armMode == 0x11)
|
rlm@1
|
7015 {
|
rlm@1
|
7016 LDM_REG(256, R8_FIQ);
|
rlm@1
|
7017 LDM_REG(512, R9_FIQ);
|
rlm@1
|
7018 LDM_REG(1024, R10_FIQ);
|
rlm@1
|
7019 LDM_REG(2048, R11_FIQ);
|
rlm@1
|
7020 LDM_REG(4096, R12_FIQ);
|
rlm@1
|
7021 }
|
rlm@1
|
7022 else
|
rlm@1
|
7023 {
|
rlm@1
|
7024 LDM_REG(256, 8);
|
rlm@1
|
7025 LDM_REG(512, 9);
|
rlm@1
|
7026 LDM_REG(1024, 10);
|
rlm@1
|
7027 LDM_REG(2048, 11);
|
rlm@1
|
7028 LDM_REG(4096, 12);
|
rlm@1
|
7029 }
|
rlm@1
|
7030
|
rlm@1
|
7031 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
7032 {
|
rlm@1
|
7033 LDM_REG(8192, R13_USR);
|
rlm@1
|
7034 LDM_REG(16384, R14_USR);
|
rlm@1
|
7035 }
|
rlm@1
|
7036 else
|
rlm@1
|
7037 {
|
rlm@1
|
7038 LDM_REG(8192, 13);
|
rlm@1
|
7039 LDM_REG(16384, 14);
|
rlm@1
|
7040 }
|
rlm@1
|
7041 }
|
rlm@1
|
7042 }
|
rlm@1
|
7043 break;
|
rlm@1
|
7044 CASE_16(0x970)
|
rlm@1
|
7045 {
|
rlm@1
|
7046 // LDMDB Rn!, {Rlist}^
|
rlm@1
|
7047 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
7048 u32 temp = reg[base].I -
|
rlm@1
|
7049 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
7050 u32 address = temp & 0xFFFFFFFC;
|
rlm@1
|
7051 clockTicks += 2;
|
rlm@1
|
7052 int offset = 0;
|
rlm@1
|
7053 if (opcode & 0x8000)
|
rlm@1
|
7054 {
|
rlm@1
|
7055 LDM_REG(1, 0);
|
rlm@1
|
7056 LDM_REG(2, 1);
|
rlm@1
|
7057 LDM_REG(4, 2);
|
rlm@1
|
7058 LDM_REG(8, 3);
|
rlm@1
|
7059 LDM_REG(16, 4);
|
rlm@1
|
7060 LDM_REG(32, 5);
|
rlm@1
|
7061 LDM_REG(64, 6);
|
rlm@1
|
7062 LDM_REG(128, 7);
|
rlm@1
|
7063 LDM_REG(256, 8);
|
rlm@1
|
7064 LDM_REG(512, 9);
|
rlm@1
|
7065 LDM_REG(1024, 10);
|
rlm@1
|
7066 LDM_REG(2048, 11);
|
rlm@1
|
7067 LDM_REG(4096, 12);
|
rlm@1
|
7068 LDM_REG(8192, 13);
|
rlm@1
|
7069 LDM_REG(16384, 14);
|
rlm@1
|
7070
|
rlm@1
|
7071 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
7072 if (!offset)
|
rlm@1
|
7073 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
7074 else
|
rlm@1
|
7075 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
7076
|
rlm@1
|
7077 if (!(opcode & (1 << base)))
|
rlm@1
|
7078 reg[base].I = temp;
|
rlm@1
|
7079
|
rlm@1
|
7080 CPUSwitchMode(reg[17].I & 0x1f, false);
|
rlm@1
|
7081 if (armState)
|
rlm@1
|
7082 {
|
rlm@1
|
7083 armNextPC = reg[15].I & 0xFFFFFFFC;
|
rlm@1
|
7084 reg[15].I = armNextPC + 4;
|
rlm@1
|
7085 }
|
rlm@1
|
7086 else
|
rlm@1
|
7087 {
|
rlm@1
|
7088 armNextPC = reg[15].I & 0xFFFFFFFE;
|
rlm@1
|
7089 reg[15].I = armNextPC + 2;
|
rlm@1
|
7090 }
|
rlm@1
|
7091 }
|
rlm@1
|
7092 else
|
rlm@1
|
7093 {
|
rlm@1
|
7094 LDM_REG(1, 0);
|
rlm@1
|
7095 LDM_REG(2, 1);
|
rlm@1
|
7096 LDM_REG(4, 2);
|
rlm@1
|
7097 LDM_REG(8, 3);
|
rlm@1
|
7098 LDM_REG(16, 4);
|
rlm@1
|
7099 LDM_REG(32, 5);
|
rlm@1
|
7100 LDM_REG(64, 6);
|
rlm@1
|
7101 LDM_REG(128, 7);
|
rlm@1
|
7102
|
rlm@1
|
7103 if (armMode == 0x11)
|
rlm@1
|
7104 {
|
rlm@1
|
7105 LDM_REG(256, R8_FIQ);
|
rlm@1
|
7106 LDM_REG(512, R9_FIQ);
|
rlm@1
|
7107 LDM_REG(1024, R10_FIQ);
|
rlm@1
|
7108 LDM_REG(2048, R11_FIQ);
|
rlm@1
|
7109 LDM_REG(4096, R12_FIQ);
|
rlm@1
|
7110 }
|
rlm@1
|
7111 else
|
rlm@1
|
7112 {
|
rlm@1
|
7113 LDM_REG(256, 8);
|
rlm@1
|
7114 LDM_REG(512, 9);
|
rlm@1
|
7115 LDM_REG(1024, 10);
|
rlm@1
|
7116 LDM_REG(2048, 11);
|
rlm@1
|
7117 LDM_REG(4096, 12);
|
rlm@1
|
7118 }
|
rlm@1
|
7119
|
rlm@1
|
7120 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
7121 {
|
rlm@1
|
7122 LDM_REG(8192, R13_USR);
|
rlm@1
|
7123 LDM_REG(16384, R14_USR);
|
rlm@1
|
7124 }
|
rlm@1
|
7125 else
|
rlm@1
|
7126 {
|
rlm@1
|
7127 LDM_REG(8192, 13);
|
rlm@1
|
7128 LDM_REG(16384, 14);
|
rlm@1
|
7129 }
|
rlm@1
|
7130
|
rlm@1
|
7131 if (!(opcode & (1 << base)))
|
rlm@1
|
7132 reg[base].I = temp;
|
rlm@1
|
7133 }
|
rlm@1
|
7134 }
|
rlm@1
|
7135 break;
|
rlm@1
|
7136
|
rlm@1
|
7137 CASE_16(0x990)
|
rlm@1
|
7138 {
|
rlm@1
|
7139 // LDMIB Rn, {Rlist}
|
rlm@1
|
7140 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
7141 u32 address = (reg[base].I + 4) & 0xFFFFFFFC;
|
rlm@1
|
7142 clockTicks += 2;
|
rlm@1
|
7143 int offset = 0;
|
rlm@1
|
7144 LDM_REG(1, 0);
|
rlm@1
|
7145 LDM_REG(2, 1);
|
rlm@1
|
7146 LDM_REG(4, 2);
|
rlm@1
|
7147 LDM_REG(8, 3);
|
rlm@1
|
7148 LDM_REG(16, 4);
|
rlm@1
|
7149 LDM_REG(32, 5);
|
rlm@1
|
7150 LDM_REG(64, 6);
|
rlm@1
|
7151 LDM_REG(128, 7);
|
rlm@1
|
7152 LDM_REG(256, 8);
|
rlm@1
|
7153 LDM_REG(512, 9);
|
rlm@1
|
7154 LDM_REG(1024, 10);
|
rlm@1
|
7155 LDM_REG(2048, 11);
|
rlm@1
|
7156 LDM_REG(4096, 12);
|
rlm@1
|
7157 LDM_REG(8192, 13);
|
rlm@1
|
7158 LDM_REG(16384, 14);
|
rlm@1
|
7159 if (opcode & 32768)
|
rlm@1
|
7160 {
|
rlm@1
|
7161 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
7162 if (!offset)
|
rlm@1
|
7163 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
7164 else
|
rlm@1
|
7165 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
7166 armNextPC = reg[15].I;
|
rlm@1
|
7167 reg[15].I += 4;
|
rlm@1
|
7168 }
|
rlm@1
|
7169 }
|
rlm@1
|
7170 break;
|
rlm@1
|
7171 CASE_16(0x9b0)
|
rlm@1
|
7172 {
|
rlm@1
|
7173 // LDMIB Rn!, {Rlist}
|
rlm@1
|
7174 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
7175 u32 temp = reg[base].I +
|
rlm@1
|
7176 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
7177 u32 address = (reg[base].I + 4) & 0xFFFFFFFC;
|
rlm@1
|
7178 clockTicks += 2;
|
rlm@1
|
7179 int offset = 0;
|
rlm@1
|
7180 LDM_REG(1, 0);
|
rlm@1
|
7181 LDM_REG(2, 1);
|
rlm@1
|
7182 LDM_REG(4, 2);
|
rlm@1
|
7183 LDM_REG(8, 3);
|
rlm@1
|
7184 LDM_REG(16, 4);
|
rlm@1
|
7185 LDM_REG(32, 5);
|
rlm@1
|
7186 LDM_REG(64, 6);
|
rlm@1
|
7187 LDM_REG(128, 7);
|
rlm@1
|
7188 LDM_REG(256, 8);
|
rlm@1
|
7189 LDM_REG(512, 9);
|
rlm@1
|
7190 LDM_REG(1024, 10);
|
rlm@1
|
7191 LDM_REG(2048, 11);
|
rlm@1
|
7192 LDM_REG(4096, 12);
|
rlm@1
|
7193 LDM_REG(8192, 13);
|
rlm@1
|
7194 LDM_REG(16384, 14);
|
rlm@1
|
7195 if (opcode & 32768)
|
rlm@1
|
7196 {
|
rlm@1
|
7197 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
7198 if (!offset)
|
rlm@1
|
7199 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
7200 else
|
rlm@1
|
7201 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
7202 armNextPC = reg[15].I;
|
rlm@1
|
7203 reg[15].I += 4;
|
rlm@1
|
7204 }
|
rlm@1
|
7205 if (!(opcode & (1 << base)))
|
rlm@1
|
7206 reg[base].I = temp;
|
rlm@1
|
7207 }
|
rlm@1
|
7208 break;
|
rlm@1
|
7209 CASE_16(0x9d0)
|
rlm@1
|
7210 {
|
rlm@1
|
7211 // LDMIB Rn, {Rlist}^
|
rlm@1
|
7212 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
7213 u32 address = (reg[base].I + 4) & 0xFFFFFFFC;
|
rlm@1
|
7214 clockTicks += 2;
|
rlm@1
|
7215 int offset = 0;
|
rlm@1
|
7216 if (opcode & 0x8000)
|
rlm@1
|
7217 {
|
rlm@1
|
7218 LDM_REG(1, 0);
|
rlm@1
|
7219 LDM_REG(2, 1);
|
rlm@1
|
7220 LDM_REG(4, 2);
|
rlm@1
|
7221 LDM_REG(8, 3);
|
rlm@1
|
7222 LDM_REG(16, 4);
|
rlm@1
|
7223 LDM_REG(32, 5);
|
rlm@1
|
7224 LDM_REG(64, 6);
|
rlm@1
|
7225 LDM_REG(128, 7);
|
rlm@1
|
7226 LDM_REG(256, 8);
|
rlm@1
|
7227 LDM_REG(512, 9);
|
rlm@1
|
7228 LDM_REG(1024, 10);
|
rlm@1
|
7229 LDM_REG(2048, 11);
|
rlm@1
|
7230 LDM_REG(4096, 12);
|
rlm@1
|
7231 LDM_REG(8192, 13);
|
rlm@1
|
7232 LDM_REG(16384, 14);
|
rlm@1
|
7233
|
rlm@1
|
7234 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
7235 if (!offset)
|
rlm@1
|
7236 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
7237 else
|
rlm@1
|
7238 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
7239
|
rlm@1
|
7240 CPUSwitchMode(reg[17].I & 0x1f, false);
|
rlm@1
|
7241 if (armState)
|
rlm@1
|
7242 {
|
rlm@1
|
7243 armNextPC = reg[15].I & 0xFFFFFFFC;
|
rlm@1
|
7244 reg[15].I = armNextPC + 4;
|
rlm@1
|
7245 }
|
rlm@1
|
7246 else
|
rlm@1
|
7247 {
|
rlm@1
|
7248 armNextPC = reg[15].I & 0xFFFFFFFE;
|
rlm@1
|
7249 reg[15].I = armNextPC + 2;
|
rlm@1
|
7250 }
|
rlm@1
|
7251 }
|
rlm@1
|
7252 else
|
rlm@1
|
7253 {
|
rlm@1
|
7254 LDM_REG(1, 0);
|
rlm@1
|
7255 LDM_REG(2, 1);
|
rlm@1
|
7256 LDM_REG(4, 2);
|
rlm@1
|
7257 LDM_REG(8, 3);
|
rlm@1
|
7258 LDM_REG(16, 4);
|
rlm@1
|
7259 LDM_REG(32, 5);
|
rlm@1
|
7260 LDM_REG(64, 6);
|
rlm@1
|
7261 LDM_REG(128, 7);
|
rlm@1
|
7262
|
rlm@1
|
7263 if (armMode == 0x11)
|
rlm@1
|
7264 {
|
rlm@1
|
7265 LDM_REG(256, R8_FIQ);
|
rlm@1
|
7266 LDM_REG(512, R9_FIQ);
|
rlm@1
|
7267 LDM_REG(1024, R10_FIQ);
|
rlm@1
|
7268 LDM_REG(2048, R11_FIQ);
|
rlm@1
|
7269 LDM_REG(4096, R12_FIQ);
|
rlm@1
|
7270 }
|
rlm@1
|
7271 else
|
rlm@1
|
7272 {
|
rlm@1
|
7273 LDM_REG(256, 8);
|
rlm@1
|
7274 LDM_REG(512, 9);
|
rlm@1
|
7275 LDM_REG(1024, 10);
|
rlm@1
|
7276 LDM_REG(2048, 11);
|
rlm@1
|
7277 LDM_REG(4096, 12);
|
rlm@1
|
7278 }
|
rlm@1
|
7279
|
rlm@1
|
7280 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
7281 {
|
rlm@1
|
7282 LDM_REG(8192, R13_USR);
|
rlm@1
|
7283 LDM_REG(16384, R14_USR);
|
rlm@1
|
7284 }
|
rlm@1
|
7285 else
|
rlm@1
|
7286 {
|
rlm@1
|
7287 LDM_REG(8192, 13);
|
rlm@1
|
7288 LDM_REG(16384, 14);
|
rlm@1
|
7289 }
|
rlm@1
|
7290 }
|
rlm@1
|
7291 }
|
rlm@1
|
7292 break;
|
rlm@1
|
7293 CASE_16(0x9f0)
|
rlm@1
|
7294 {
|
rlm@1
|
7295 // LDMIB Rn!, {Rlist}^
|
rlm@1
|
7296 int base = (opcode & 0x000F0000) >> 16;
|
rlm@1
|
7297 u32 temp = reg[base].I +
|
rlm@1
|
7298 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
|
rlm@1
|
7299 u32 address = (reg[base].I + 4) & 0xFFFFFFFC;
|
rlm@1
|
7300 clockTicks += 2;
|
rlm@1
|
7301 int offset = 0;
|
rlm@1
|
7302 if (opcode & 0x8000)
|
rlm@1
|
7303 {
|
rlm@1
|
7304 LDM_REG(1, 0);
|
rlm@1
|
7305 LDM_REG(2, 1);
|
rlm@1
|
7306 LDM_REG(4, 2);
|
rlm@1
|
7307 LDM_REG(8, 3);
|
rlm@1
|
7308 LDM_REG(16, 4);
|
rlm@1
|
7309 LDM_REG(32, 5);
|
rlm@1
|
7310 LDM_REG(64, 6);
|
rlm@1
|
7311 LDM_REG(128, 7);
|
rlm@1
|
7312 LDM_REG(256, 8);
|
rlm@1
|
7313 LDM_REG(512, 9);
|
rlm@1
|
7314 LDM_REG(1024, 10);
|
rlm@1
|
7315 LDM_REG(2048, 11);
|
rlm@1
|
7316 LDM_REG(4096, 12);
|
rlm@1
|
7317 LDM_REG(8192, 13);
|
rlm@1
|
7318 LDM_REG(16384, 14);
|
rlm@1
|
7319
|
rlm@1
|
7320 reg[15].I = CPUReadMemory(address);
|
rlm@1
|
7321 if (!offset)
|
rlm@1
|
7322 clockTicks += 2 + CPUUpdateTicksAccess32(address);
|
rlm@1
|
7323 else
|
rlm@1
|
7324 clockTicks += 2 + CPUUpdateTicksAccessSeq32(address);
|
rlm@1
|
7325
|
rlm@1
|
7326 if (!(opcode & (1 << base)))
|
rlm@1
|
7327 reg[base].I = temp;
|
rlm@1
|
7328
|
rlm@1
|
7329 CPUSwitchMode(reg[17].I & 0x1f, false);
|
rlm@1
|
7330 if (armState)
|
rlm@1
|
7331 {
|
rlm@1
|
7332 armNextPC = reg[15].I & 0xFFFFFFFC;
|
rlm@1
|
7333 reg[15].I = armNextPC + 4;
|
rlm@1
|
7334 }
|
rlm@1
|
7335 else
|
rlm@1
|
7336 {
|
rlm@1
|
7337 armNextPC = reg[15].I & 0xFFFFFFFE;
|
rlm@1
|
7338 reg[15].I = armNextPC + 2;
|
rlm@1
|
7339 }
|
rlm@1
|
7340 }
|
rlm@1
|
7341 else
|
rlm@1
|
7342 {
|
rlm@1
|
7343 LDM_REG(1, 0);
|
rlm@1
|
7344 LDM_REG(2, 1);
|
rlm@1
|
7345 LDM_REG(4, 2);
|
rlm@1
|
7346 LDM_REG(8, 3);
|
rlm@1
|
7347 LDM_REG(16, 4);
|
rlm@1
|
7348 LDM_REG(32, 5);
|
rlm@1
|
7349 LDM_REG(64, 6);
|
rlm@1
|
7350 LDM_REG(128, 7);
|
rlm@1
|
7351
|
rlm@1
|
7352 if (armMode == 0x11)
|
rlm@1
|
7353 {
|
rlm@1
|
7354 LDM_REG(256, R8_FIQ);
|
rlm@1
|
7355 LDM_REG(512, R9_FIQ);
|
rlm@1
|
7356 LDM_REG(1024, R10_FIQ);
|
rlm@1
|
7357 LDM_REG(2048, R11_FIQ);
|
rlm@1
|
7358 LDM_REG(4096, R12_FIQ);
|
rlm@1
|
7359 }
|
rlm@1
|
7360 else
|
rlm@1
|
7361 {
|
rlm@1
|
7362 LDM_REG(256, 8);
|
rlm@1
|
7363 LDM_REG(512, 9);
|
rlm@1
|
7364 LDM_REG(1024, 10);
|
rlm@1
|
7365 LDM_REG(2048, 11);
|
rlm@1
|
7366 LDM_REG(4096, 12);
|
rlm@1
|
7367 }
|
rlm@1
|
7368
|
rlm@1
|
7369 if (armMode != 0x10 && armMode != 0x1f)
|
rlm@1
|
7370 {
|
rlm@1
|
7371 LDM_REG(8192, R13_USR);
|
rlm@1
|
7372 LDM_REG(16384, R14_USR);
|
rlm@1
|
7373 }
|
rlm@1
|
7374 else
|
rlm@1
|
7375 {
|
rlm@1
|
7376 LDM_REG(8192, 13);
|
rlm@1
|
7377 LDM_REG(16384, 14);
|
rlm@1
|
7378 }
|
rlm@1
|
7379
|
rlm@1
|
7380 if (!(opcode & (1 << base)))
|
rlm@1
|
7381 reg[base].I = temp;
|
rlm@1
|
7382 }
|
rlm@1
|
7383 }
|
rlm@1
|
7384 break;
|
rlm@1
|
7385 CASE_256(0xa00)
|
rlm@1
|
7386 {
|
rlm@1
|
7387 // B <offset>
|
rlm@1
|
7388 clockTicks += 3;
|
rlm@1
|
7389 int offset = opcode & 0x00FFFFFF;
|
rlm@1
|
7390 if (offset & 0x00800000)
|
rlm@1
|
7391 {
|
rlm@1
|
7392 offset |= 0xFF000000;
|
rlm@1
|
7393 }
|
rlm@1
|
7394 offset <<= 2;
|
rlm@1
|
7395 reg[15].I += offset;
|
rlm@1
|
7396 armNextPC = reg[15].I;
|
rlm@1
|
7397 reg[15].I += 4;
|
rlm@1
|
7398 }
|
rlm@1
|
7399 break;
|
rlm@1
|
7400 CASE_256(0xb00)
|
rlm@1
|
7401 {
|
rlm@1
|
7402 // BL <offset>
|
rlm@1
|
7403 clockTicks += 3;
|
rlm@1
|
7404 int offset = opcode & 0x00FFFFFF;
|
rlm@1
|
7405 if (offset & 0x00800000)
|
rlm@1
|
7406 {
|
rlm@1
|
7407 offset |= 0xFF000000;
|
rlm@1
|
7408 }
|
rlm@1
|
7409 offset <<= 2;
|
rlm@1
|
7410 reg[14].I = reg[15].I - 4;
|
rlm@1
|
7411 reg[15].I += offset;
|
rlm@1
|
7412 armNextPC = reg[15].I;
|
rlm@1
|
7413 reg[15].I += 4;
|
rlm@1
|
7414 }
|
rlm@1
|
7415 break;
|
rlm@1
|
7416 CASE_256(0xf00)
|
rlm@1
|
7417 // SWI <comment>
|
rlm@1
|
7418 clockTicks += 3;
|
rlm@1
|
7419 CPUSoftwareInterrupt(opcode & 0x00FFFFFF);
|
rlm@1
|
7420 break;
|
rlm@1
|
7421 #ifdef GP_SUPPORT
|
rlm@1
|
7422 case 0xe11:
|
rlm@1
|
7423 case 0xe13:
|
rlm@1
|
7424 case 0xe15:
|
rlm@1
|
7425 case 0xe17:
|
rlm@1
|
7426 case 0xe19:
|
rlm@1
|
7427 case 0xe1b:
|
rlm@1
|
7428 case 0xe1d:
|
rlm@1
|
7429 case 0xe1f:
|
rlm@1
|
7430 // MRC
|
rlm@1
|
7431 break;
|
rlm@1
|
7432 case 0xe01:
|
rlm@1
|
7433 case 0xe03:
|
rlm@1
|
7434 case 0xe05:
|
rlm@1
|
7435 case 0xe07:
|
rlm@1
|
7436 case 0xe09:
|
rlm@1
|
7437 case 0xe0b:
|
rlm@1
|
7438 case 0xe0d:
|
rlm@1
|
7439 case 0xe0f:
|
rlm@1
|
7440 // MRC
|
rlm@1
|
7441 break;
|
rlm@1
|
7442 #endif
|
rlm@1
|
7443 default:
|
rlm@1
|
7444 #ifdef GBA_LOGGING
|
rlm@1
|
7445 if (systemVerbose & VERBOSE_UNDEFINED)
|
rlm@1
|
7446 log("Undefined ARM instruction %08x at %08x\n", opcode,
|
rlm@1
|
7447 armNextPC - 4);
|
rlm@1
|
7448 #endif
|
rlm@1
|
7449 CPUUndefinedException();
|
rlm@1
|
7450 break;
|
rlm@1
|
7451 // END
|
rlm@1
|
7452 }
|
rlm@1
|
7453 }
|