1 // license:BSD-3-Clause
2 // copyright-holders:David Haywood
3
4 #include "emu.h"
5 #include "sh.h"
6 #include "sh_dasm.h"
7 #include "cpu/drcumlsh.h"
8
device_start()9 void sh_common_execution::device_start()
10 {
11 /* allocate the implementation-specific state from the full cache */
12 m_sh2_state = (internal_sh2_state *)m_cache.alloc_near(sizeof(internal_sh2_state));
13
14 save_item(NAME(m_sh2_state->pc));
15 save_item(NAME(m_sh2_state->sr));
16 save_item(NAME(m_sh2_state->pr));
17 save_item(NAME(m_sh2_state->gbr));
18 save_item(NAME(m_sh2_state->vbr));
19 save_item(NAME(m_sh2_state->mach));
20 save_item(NAME(m_sh2_state->macl));
21 save_item(NAME(m_sh2_state->r));
22 save_item(NAME(m_sh2_state->ea));
23 save_item(NAME(m_sh2_state->m_delay));
24 save_item(NAME(m_sh2_state->pending_irq));
25 save_item(NAME(m_sh2_state->pending_nmi));
26 save_item(NAME(m_sh2_state->irqline));
27 save_item(NAME(m_sh2_state->evec));
28 save_item(NAME(m_sh2_state->irqsr));
29 save_item(NAME(m_sh2_state->target));
30 save_item(NAME(m_sh2_state->internal_irq_level));
31 save_item(NAME(m_sh2_state->sleep_mode));
32 save_item(NAME(m_sh2_state->icount));
33
34 m_sh2_state->pc = 0;
35 m_sh2_state->pr = 0;
36 m_sh2_state->sr = 0;
37 m_sh2_state->gbr = 0;
38 m_sh2_state->vbr = 0;
39 m_sh2_state->mach = 0;
40 m_sh2_state->macl = 0;
41 memset(m_sh2_state->r, 0, sizeof(m_sh2_state->r));
42 m_sh2_state->ea = 0;
43 m_sh2_state->m_delay = 0;
44 m_sh2_state->pending_irq = 0;
45 m_sh2_state->pending_nmi = 0;
46 m_sh2_state->irqline = 0;
47 m_sh2_state->evec = 0;
48 m_sh2_state->irqsr = 0;
49 m_sh2_state->target = 0;
50 m_sh2_state->internal_irq_level = 0;
51 m_sh2_state->icount = 0;
52 m_sh2_state->sleep_mode = 0;
53 m_sh2_state->arg0 = 0;
54
55 state_add(SH4_PC, "PC", m_sh2_state->pc).formatstr("%08X").callimport();
56 state_add(SH_SR, "SR", m_sh2_state->sr).formatstr("%08X").callimport();
57 state_add(SH4_PR, "PR", m_sh2_state->pr).formatstr("%08X");
58 state_add(SH4_GBR, "GBR", m_sh2_state->gbr).formatstr("%08X");
59 state_add(SH4_VBR, "VBR", m_sh2_state->vbr).formatstr("%08X");
60 state_add(SH4_MACH, "MACH", m_sh2_state->mach).formatstr("%08X");
61 state_add(SH4_MACL, "MACL", m_sh2_state->macl).formatstr("%08X");
62 state_add(SH4_R0, "R0", m_sh2_state->r[0]).formatstr("%08X");
63 state_add(SH4_R1, "R1", m_sh2_state->r[1]).formatstr("%08X");
64 state_add(SH4_R2, "R2", m_sh2_state->r[2]).formatstr("%08X");
65 state_add(SH4_R3, "R3", m_sh2_state->r[3]).formatstr("%08X");
66 state_add(SH4_R4, "R4", m_sh2_state->r[4]).formatstr("%08X");
67 state_add(SH4_R5, "R5", m_sh2_state->r[5]).formatstr("%08X");
68 state_add(SH4_R6, "R6", m_sh2_state->r[6]).formatstr("%08X");
69 state_add(SH4_R7, "R7", m_sh2_state->r[7]).formatstr("%08X");
70 state_add(SH4_R8, "R8", m_sh2_state->r[8]).formatstr("%08X");
71 state_add(SH4_R9, "R9", m_sh2_state->r[9]).formatstr("%08X");
72 state_add(SH4_R10, "R10", m_sh2_state->r[10]).formatstr("%08X");
73 state_add(SH4_R11, "R11", m_sh2_state->r[11]).formatstr("%08X");
74 state_add(SH4_R12, "R12", m_sh2_state->r[12]).formatstr("%08X");
75 state_add(SH4_R13, "R13", m_sh2_state->r[13]).formatstr("%08X");
76 state_add(SH4_R14, "R14", m_sh2_state->r[14]).formatstr("%08X");
77 state_add(SH4_R15, "R15", m_sh2_state->r[15]).formatstr("%08X");
78 state_add(SH4_EA, "EA", m_sh2_state->ea).formatstr("%08X");
79
80 state_add(STATE_GENSP, "GENSP", m_sh2_state->r[15]).noshow();
81 state_add(STATE_GENFLAGS, "GENFLAGS", m_sh2_state->sr).formatstr("%20s").noshow();
82
83 set_icountptr(m_sh2_state->icount);
84
85 m_program = &space(AS_PROGRAM);
86 }
87
88
drc_start()89 void sh_common_execution::drc_start()
90 {
91 /* DRC helpers */
92 memset(m_pcflushes, 0, sizeof(m_pcflushes));
93
94 m_fastram_select = 0;
95 memset(m_fastram, 0, sizeof(m_fastram));
96
97 /* reset per-driver pcflushes */
98 m_pcfsel = 0;
99
100 /* initialize the UML generator */
101 uint32_t flags = 0;
102 m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, flags, 1, 32, 1);
103
104 /* add symbols for our stuff */
105 m_drcuml->symbol_add(&m_sh2_state->pc, sizeof(m_sh2_state->pc), "pc");
106 m_drcuml->symbol_add(&m_sh2_state->icount, sizeof(m_sh2_state->icount), "icount");
107 for (int regnum = 0; regnum < 16; regnum++)
108 {
109 char buf[10];
110 sprintf(buf, "r%d", regnum);
111 m_drcuml->symbol_add(&m_sh2_state->r[regnum], sizeof(m_sh2_state->r[regnum]), buf);
112 }
113 m_drcuml->symbol_add(&m_sh2_state->pr, sizeof(m_sh2_state->pr), "pr");
114 m_drcuml->symbol_add(&m_sh2_state->sr, sizeof(m_sh2_state->sr), "sr");
115 m_drcuml->symbol_add(&m_sh2_state->gbr, sizeof(m_sh2_state->gbr), "gbr");
116 m_drcuml->symbol_add(&m_sh2_state->vbr, sizeof(m_sh2_state->vbr), "vbr");
117 m_drcuml->symbol_add(&m_sh2_state->macl, sizeof(m_sh2_state->macl), "macl");
118 m_drcuml->symbol_add(&m_sh2_state->mach, sizeof(m_sh2_state->macl), "mach");
119
120 /* initialize the front-end helper */
121 init_drc_frontend();
122
123 /* compute the register parameters */
124 for (int regnum = 0; regnum < 16; regnum++)
125 {
126 m_regmap[regnum] = uml::mem(&m_sh2_state->r[regnum]);
127 }
128
129 /* if we have registers to spare, assign r0, r1, r2 to leftovers */
130 /* WARNING: do not use synthetic registers that are mapped here! */
131 if (!DISABLE_FAST_REGISTERS)
132 {
133 drcbe_info beinfo;
134 m_drcuml->get_backend_info(beinfo);
135 if (beinfo.direct_iregs > 4)
136 {
137 m_regmap[0] = uml::I4;
138 }
139 if (beinfo.direct_iregs > 5)
140 {
141 m_regmap[1] = uml::I5;
142 }
143 if (beinfo.direct_iregs > 6)
144 {
145 m_regmap[2] = uml::I6;
146 }
147 }
148
149 /* mark the cache dirty so it is updated on next execute */
150 m_cache_dirty = true;
151
152 save_item(NAME(m_pcfsel));
153 //save_item(NAME(m_maxpcfsel));
154 save_item(NAME(m_pcflushes));
155 }
156
157 /* code cycles t-bit
158 * 0011 nnnn mmmm 1100 1 -
159 * ADD Rm,Rn
160 */
ADD(uint32_t m,uint32_t n)161 void sh_common_execution::ADD(uint32_t m, uint32_t n)
162 {
163 m_sh2_state->r[n] += m_sh2_state->r[m];
164 }
165
166 /* code cycles t-bit
167 * 0111 nnnn iiii iiii 1 -
168 * ADD #imm,Rn
169 */
ADDI(uint32_t i,uint32_t n)170 void sh_common_execution::ADDI(uint32_t i, uint32_t n)
171 {
172 m_sh2_state->r[n] += (int32_t)(int16_t)(int8_t)i;
173 }
174
175 /* code cycles t-bit
176 * 0011 nnnn mmmm 1110 1 carry
177 * ADDC Rm,Rn
178 */
ADDC(uint32_t m,uint32_t n)179 void sh_common_execution::ADDC(uint32_t m, uint32_t n)
180 {
181 uint32_t tmp0, tmp1;
182
183 tmp1 = m_sh2_state->r[n] + m_sh2_state->r[m];
184 tmp0 = m_sh2_state->r[n];
185 m_sh2_state->r[n] = tmp1 + (m_sh2_state->sr & SH_T);
186 if (tmp0 > tmp1)
187 m_sh2_state->sr |= SH_T;
188 else
189 m_sh2_state->sr &= ~SH_T;
190 if (tmp1 > m_sh2_state->r[n])
191 m_sh2_state->sr |= SH_T;
192 }
193
194 /* code cycles t-bit
195 * 0011 nnnn mmmm 1111 1 overflow
196 * ADDV Rm,Rn
197 */
ADDV(uint32_t m,uint32_t n)198 void sh_common_execution::ADDV(uint32_t m, uint32_t n)
199 {
200 int32_t dest, src, ans;
201
202 if ((int32_t) m_sh2_state->r[n] >= 0)
203 dest = 0;
204 else
205 dest = 1;
206 if ((int32_t) m_sh2_state->r[m] >= 0)
207 src = 0;
208 else
209 src = 1;
210 src += dest;
211 m_sh2_state->r[n] += m_sh2_state->r[m];
212 if ((int32_t) m_sh2_state->r[n] >= 0)
213 ans = 0;
214 else
215 ans = 1;
216 ans += dest;
217 if (src == 0 || src == 2)
218 {
219 if (ans == 1)
220 m_sh2_state->sr |= SH_T;
221 else
222 m_sh2_state->sr &= ~SH_T;
223 }
224 else
225 m_sh2_state->sr &= ~SH_T;
226 }
227
228 /* code cycles t-bit
229 * 0010 nnnn mmmm 1001 1 -
230 * AND Rm,Rn
231 */
AND(uint32_t m,uint32_t n)232 void sh_common_execution::AND(uint32_t m, uint32_t n)
233 {
234 m_sh2_state->r[n] &= m_sh2_state->r[m];
235 }
236
237 /* code cycles t-bit
238 * 1100 1001 iiii iiii 1 -
239 * AND #imm,R0
240 */
ANDI(uint32_t i)241 void sh_common_execution::ANDI(uint32_t i)
242 {
243 m_sh2_state->r[0] &= i;
244 }
245
246 /* code cycles t-bit
247 * 1100 1101 iiii iiii 1 -
248 * AND.B #imm,@(R0,GBR)
249 */
ANDM(uint32_t i)250 void sh_common_execution::ANDM(uint32_t i)
251 {
252 uint32_t temp;
253
254 m_sh2_state->ea = m_sh2_state->gbr + m_sh2_state->r[0];
255 temp = i & RB( m_sh2_state->ea );
256 WB( m_sh2_state->ea, temp );
257 m_sh2_state->icount -= 2;
258 }
259
260 /* code cycles t-bit
261 * 1000 1011 dddd dddd 3/1 -
262 * BF disp8
263 */
BF(uint32_t d)264 void sh_common_execution::BF(uint32_t d)
265 {
266 if ((m_sh2_state->sr & SH_T) == 0)
267 {
268 int32_t disp = ((int32_t)d << 24) >> 24;
269 m_sh2_state->pc = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2;
270 m_sh2_state->icount -= 2;
271 }
272 }
273
274 /* code cycles t-bit
275 * 1000 1111 dddd dddd 3/1 -
276 * BFS disp8
277 */
BFS(uint32_t d)278 void sh_common_execution::BFS(uint32_t d)
279 {
280 if ((m_sh2_state->sr & SH_T) == 0)
281 {
282 int32_t disp = ((int32_t)d << 24) >> 24;
283 m_sh2_state->m_delay = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2;
284 m_sh2_state->icount--;
285 }
286 }
287
288 /* code cycles t-bit
289 * 1010 dddd dddd dddd 2 -
290 * BRA disp12
291 */
BRA(uint32_t d)292 void sh_common_execution::BRA(uint32_t d)
293 {
294 int32_t disp = ((int32_t)d << 20) >> 20;
295
296 #if BUSY_LOOP_HACKS
297 if (disp == -2)
298 {
299 uint32_t next_opcode = RW(m_sh2_state->pc & AM);
300 /* BRA $
301 * NOP
302 */
303 if (next_opcode == 0x0009)
304 m_sh2_state->icount %= 3; /* cycles for BRA $ and NOP taken (3) */
305 }
306 #endif
307 m_sh2_state->m_delay = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2;
308 m_sh2_state->icount--;
309 }
310
311 /* code cycles t-bit
312 * 0000 mmmm 0010 0011 2 -
313 * BRAF Rm
314 */
BRAF(uint32_t m)315 void sh_common_execution::BRAF(uint32_t m)
316 {
317 m_sh2_state->m_delay = m_sh2_state->pc + m_sh2_state->r[m] + 2;
318 m_sh2_state->icount--;
319 }
320
321 /* code cycles t-bit
322 * 1011 dddd dddd dddd 2 -
323 * BSR disp12
324 */
BSR(uint32_t d)325 void sh_common_execution::BSR(uint32_t d)
326 {
327 int32_t disp = ((int32_t)d << 20) >> 20;
328
329 m_sh2_state->pr = m_sh2_state->pc + 2;
330 m_sh2_state->m_delay = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2;
331 m_sh2_state->icount--;
332 }
333
334 /* code cycles t-bit
335 * 0000 mmmm 0000 0011 2 -
336 * BSRF Rm
337 */
BSRF(uint32_t m)338 void sh_common_execution::BSRF(uint32_t m)
339 {
340 m_sh2_state->pr = m_sh2_state->pc + 2;
341 m_sh2_state->m_delay = m_sh2_state->pc + m_sh2_state->r[m] + 2;
342 m_sh2_state->icount--;
343 }
344
345 /* code cycles t-bit
346 * 1000 1001 dddd dddd 3/1 -
347 * BT disp8
348 */
BT(uint32_t d)349 void sh_common_execution::BT(uint32_t d)
350 {
351 if ((m_sh2_state->sr & SH_T) != 0)
352 {
353 int32_t disp = ((int32_t)d << 24) >> 24;
354 m_sh2_state->pc = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2;
355 m_sh2_state->icount -= 2;
356 }
357 }
358
359 /* code cycles t-bit
360 * 1000 1101 dddd dddd 2/1 -
361 * BTS disp8
362 */
BTS(uint32_t d)363 void sh_common_execution::BTS(uint32_t d)
364 {
365 if ((m_sh2_state->sr & SH_T) != 0)
366 {
367 int32_t disp = ((int32_t)d << 24) >> 24;
368 m_sh2_state->m_delay = m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2;
369 m_sh2_state->icount--;
370 }
371 }
372
373 /* code cycles t-bit
374 * 0000 0000 0010 1000 1 -
375 * CLRMAC
376 */
CLRMAC()377 void sh_common_execution::CLRMAC()
378 {
379 m_sh2_state->mach = 0;
380 m_sh2_state->macl = 0;
381 }
382
383 /* code cycles t-bit
384 * 0000 0000 0000 1000 1 -
385 * CLRT
386 */
CLRT()387 void sh_common_execution::CLRT()
388 {
389 m_sh2_state->sr &= ~SH_T;
390 }
391
392 /* code cycles t-bit
393 * 0011 nnnn mmmm 0000 1 comparison result
394 * CMP_EQ Rm,Rn
395 */
CMPEQ(uint32_t m,uint32_t n)396 void sh_common_execution::CMPEQ(uint32_t m, uint32_t n)
397 {
398 if (m_sh2_state->r[n] == m_sh2_state->r[m])
399 m_sh2_state->sr |= SH_T;
400 else
401 m_sh2_state->sr &= ~SH_T;
402 }
403
404 /* code cycles t-bit
405 * 0011 nnnn mmmm 0011 1 comparison result
406 * CMP_GE Rm,Rn
407 */
CMPGE(uint32_t m,uint32_t n)408 void sh_common_execution::CMPGE(uint32_t m, uint32_t n)
409 {
410 if ((int32_t) m_sh2_state->r[n] >= (int32_t) m_sh2_state->r[m])
411 m_sh2_state->sr |= SH_T;
412 else
413 m_sh2_state->sr &= ~SH_T;
414 }
415
416 /* code cycles t-bit
417 * 0011 nnnn mmmm 0111 1 comparison result
418 * CMP_GT Rm,Rn
419 */
CMPGT(uint32_t m,uint32_t n)420 void sh_common_execution::CMPGT(uint32_t m, uint32_t n)
421 {
422 if ((int32_t) m_sh2_state->r[n] > (int32_t) m_sh2_state->r[m])
423 m_sh2_state->sr |= SH_T;
424 else
425 m_sh2_state->sr &= ~SH_T;
426 }
427
428 /* code cycles t-bit
429 * 0011 nnnn mmmm 0110 1 comparison result
430 * CMP_HI Rm,Rn
431 */
CMPHI(uint32_t m,uint32_t n)432 void sh_common_execution::CMPHI(uint32_t m, uint32_t n)
433 {
434 if ((uint32_t) m_sh2_state->r[n] > (uint32_t) m_sh2_state->r[m])
435 m_sh2_state->sr |= SH_T;
436 else
437 m_sh2_state->sr &= ~SH_T;
438 }
439
440 /* code cycles t-bit
441 * 0011 nnnn mmmm 0010 1 comparison result
442 * CMP_HS Rm,Rn
443 */
CMPHS(uint32_t m,uint32_t n)444 void sh_common_execution::CMPHS(uint32_t m, uint32_t n)
445 {
446 if ((uint32_t) m_sh2_state->r[n] >= (uint32_t) m_sh2_state->r[m])
447 m_sh2_state->sr |= SH_T;
448 else
449 m_sh2_state->sr &= ~SH_T;
450 }
451
452 /* code cycles t-bit
453 * 0100 nnnn 0001 0101 1 comparison result
454 * CMP_PL Rn
455 */
CMPPL(uint32_t n)456 void sh_common_execution::CMPPL(uint32_t n)
457 {
458 if ((int32_t) m_sh2_state->r[n] > 0)
459 m_sh2_state->sr |= SH_T;
460 else
461 m_sh2_state->sr &= ~SH_T;
462 }
463
464 /* code cycles t-bit
465 * 0100 nnnn 0001 0001 1 comparison result
466 * CMP_PZ Rn
467 */
CMPPZ(uint32_t n)468 void sh_common_execution::CMPPZ(uint32_t n)
469 {
470 if ((int32_t) m_sh2_state->r[n] >= 0)
471 m_sh2_state->sr |= SH_T;
472 else
473 m_sh2_state->sr &= ~SH_T;
474 }
475
476 /* code cycles t-bit
477 * 0010 nnnn mmmm 1100 1 comparison result
478 * CMP_STR Rm,Rn
479 */
CMPSTR(uint32_t m,uint32_t n)480 void sh_common_execution::CMPSTR(uint32_t m, uint32_t n)
481 {
482 uint32_t temp;
483 int32_t HH, HL, LH, LL;
484 temp = m_sh2_state->r[n] ^ m_sh2_state->r[m];
485 HH = (temp >> 24) & 0xff;
486 HL = (temp >> 16) & 0xff;
487 LH = (temp >> 8) & 0xff;
488 LL = temp & 0xff;
489 if (HH && HL && LH && LL)
490 m_sh2_state->sr &= ~SH_T;
491 else
492 m_sh2_state->sr |= SH_T;
493 }
494
495 /* code cycles t-bit
496 * 1000 1000 iiii iiii 1 comparison result
497 * CMP/EQ #imm,R0
498 */
CMPIM(uint32_t i)499 void sh_common_execution::CMPIM(uint32_t i)
500 {
501 uint32_t imm = (uint32_t)(int32_t)(int16_t)(int8_t)i;
502
503 if (m_sh2_state->r[0] == imm)
504 m_sh2_state->sr |= SH_T;
505 else
506 m_sh2_state->sr &= ~SH_T;
507 }
508
509 /* code cycles t-bit
510 * 0010 nnnn mmmm 0111 1 calculation result
511 * DIV0S Rm,Rn
512 */
DIV0S(uint32_t m,uint32_t n)513 void sh_common_execution::DIV0S(uint32_t m, uint32_t n)
514 {
515 if ((m_sh2_state->r[n] & 0x80000000) == 0)
516 m_sh2_state->sr &= ~SH_Q;
517 else
518 m_sh2_state->sr |= SH_Q;
519 if ((m_sh2_state->r[m] & 0x80000000) == 0)
520 m_sh2_state->sr &= ~SH_M;
521 else
522 m_sh2_state->sr |= SH_M;
523 if ((m_sh2_state->r[m] ^ m_sh2_state->r[n]) & 0x80000000)
524 m_sh2_state->sr |= SH_T;
525 else
526 m_sh2_state->sr &= ~SH_T;
527 }
528
529 /* code cycles t-bit
530 * 0000 0000 0001 1001 1 0
531 * DIV0U
532 */
DIV0U()533 void sh_common_execution::DIV0U()
534 {
535 m_sh2_state->sr &= ~(SH_M | SH_Q | SH_T);
536 }
537
538 /* code cycles t-bit
539 * 0011 nnnn mmmm 0100 1 calculation result
540 * DIV1 Rm,Rn
541 */
DIV1(uint32_t m,uint32_t n)542 void sh_common_execution::DIV1(uint32_t m, uint32_t n)
543 {
544 uint32_t tmp0;
545 uint32_t old_q;
546
547 old_q = m_sh2_state->sr & SH_Q;
548 if (0x80000000 & m_sh2_state->r[n])
549 m_sh2_state->sr |= SH_Q;
550 else
551 m_sh2_state->sr &= ~SH_Q;
552
553 m_sh2_state->r[n] = (m_sh2_state->r[n] << 1) | (m_sh2_state->sr & SH_T);
554
555 if (!old_q)
556 {
557 if (!(m_sh2_state->sr & SH_M))
558 {
559 tmp0 = m_sh2_state->r[n];
560 m_sh2_state->r[n] -= m_sh2_state->r[m];
561 if(!(m_sh2_state->sr & SH_Q))
562 if(m_sh2_state->r[n] > tmp0)
563 m_sh2_state->sr |= SH_Q;
564 else
565 m_sh2_state->sr &= ~SH_Q;
566 else
567 if(m_sh2_state->r[n] > tmp0)
568 m_sh2_state->sr &= ~SH_Q;
569 else
570 m_sh2_state->sr |= SH_Q;
571 }
572 else
573 {
574 tmp0 = m_sh2_state->r[n];
575 m_sh2_state->r[n] += m_sh2_state->r[m];
576 if(!(m_sh2_state->sr & SH_Q))
577 {
578 if(m_sh2_state->r[n] < tmp0)
579 m_sh2_state->sr &= ~SH_Q;
580 else
581 m_sh2_state->sr |= SH_Q;
582 }
583 else
584 {
585 if(m_sh2_state->r[n] < tmp0)
586 m_sh2_state->sr |= SH_Q;
587 else
588 m_sh2_state->sr &= ~SH_Q;
589 }
590 }
591 }
592 else
593 {
594 if (!(m_sh2_state->sr & SH_M))
595 {
596 tmp0 = m_sh2_state->r[n];
597 m_sh2_state->r[n] += m_sh2_state->r[m];
598 if(!(m_sh2_state->sr & SH_Q))
599 if(m_sh2_state->r[n] < tmp0)
600 m_sh2_state->sr |= SH_Q;
601 else
602 m_sh2_state->sr &= ~SH_Q;
603 else
604 if(m_sh2_state->r[n] < tmp0)
605 m_sh2_state->sr &= ~SH_Q;
606 else
607 m_sh2_state->sr |= SH_Q;
608 }
609 else
610 {
611 tmp0 = m_sh2_state->r[n];
612 m_sh2_state->r[n] -= m_sh2_state->r[m];
613 if(!(m_sh2_state->sr & SH_Q))
614 if(m_sh2_state->r[n] > tmp0)
615 m_sh2_state->sr &= ~SH_Q;
616 else
617 m_sh2_state->sr |= SH_Q;
618 else
619 if(m_sh2_state->r[n] > tmp0)
620 m_sh2_state->sr |= SH_Q;
621 else
622 m_sh2_state->sr &= ~SH_Q;
623 }
624 }
625
626 tmp0 = (m_sh2_state->sr & (SH_Q | SH_M));
627 if((!tmp0) || (tmp0 == 0x300)) /* if Q == M set T else clear T */
628 m_sh2_state->sr |= SH_T;
629 else
630 m_sh2_state->sr &= ~SH_T;
631 }
632
633 /* DMULS.L Rm,Rn */
DMULS(uint32_t m,uint32_t n)634 void sh_common_execution::DMULS(uint32_t m, uint32_t n)
635 {
636 uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2;
637 uint32_t temp0, temp1, temp2, temp3;
638 int32_t tempm, tempn, fnLmL;
639
640 tempn = (int32_t) m_sh2_state->r[n];
641 tempm = (int32_t) m_sh2_state->r[m];
642 if (tempn < 0)
643 tempn = 0 - tempn;
644 if (tempm < 0)
645 tempm = 0 - tempm;
646 if ((int32_t) (m_sh2_state->r[n] ^ m_sh2_state->r[m]) < 0)
647 fnLmL = -1;
648 else
649 fnLmL = 0;
650 temp1 = (uint32_t) tempn;
651 temp2 = (uint32_t) tempm;
652 RnL = temp1 & 0x0000ffff;
653 RnH = (temp1 >> 16) & 0x0000ffff;
654 RmL = temp2 & 0x0000ffff;
655 RmH = (temp2 >> 16) & 0x0000ffff;
656 temp0 = RmL * RnL;
657 temp1 = RmH * RnL;
658 temp2 = RmL * RnH;
659 temp3 = RmH * RnH;
660 Res2 = 0;
661 Res1 = temp1 + temp2;
662 if (Res1 < temp1)
663 Res2 += 0x00010000;
664 temp1 = (Res1 << 16) & 0xffff0000;
665 Res0 = temp0 + temp1;
666 if (Res0 < temp0)
667 Res2++;
668 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
669 if (fnLmL < 0)
670 {
671 Res2 = ~Res2;
672 if (Res0 == 0)
673 Res2++;
674 else
675 Res0 = (~Res0) + 1;
676 }
677 m_sh2_state->mach = Res2;
678 m_sh2_state->macl = Res0;
679 m_sh2_state->icount--;
680 }
681
682 /* DMULU.L Rm,Rn */
DMULU(uint32_t m,uint32_t n)683 void sh_common_execution::DMULU(uint32_t m, uint32_t n)
684 {
685 uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2;
686 uint32_t temp0, temp1, temp2, temp3;
687
688 RnL = m_sh2_state->r[n] & 0x0000ffff;
689 RnH = (m_sh2_state->r[n] >> 16) & 0x0000ffff;
690 RmL = m_sh2_state->r[m] & 0x0000ffff;
691 RmH = (m_sh2_state->r[m] >> 16) & 0x0000ffff;
692 temp0 = RmL * RnL;
693 temp1 = RmH * RnL;
694 temp2 = RmL * RnH;
695 temp3 = RmH * RnH;
696 Res2 = 0;
697 Res1 = temp1 + temp2;
698 if (Res1 < temp1)
699 Res2 += 0x00010000;
700 temp1 = (Res1 << 16) & 0xffff0000;
701 Res0 = temp0 + temp1;
702 if (Res0 < temp0)
703 Res2++;
704 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
705 m_sh2_state->mach = Res2;
706 m_sh2_state->macl = Res0;
707 m_sh2_state->icount--;
708 }
709
710 /* DT Rn */
DT(uint32_t n)711 void sh_common_execution::DT(uint32_t n)
712 {
713 m_sh2_state->r[n]--;
714 if (m_sh2_state->r[n] == 0)
715 m_sh2_state->sr |= SH_T;
716 else
717 m_sh2_state->sr &= ~SH_T;
718 #if BUSY_LOOP_HACKS
719 {
720 uint32_t next_opcode = RW(m_sh2_state->pc & AM);
721 /* DT Rn
722 * BF $-2
723 */
724 if (next_opcode == 0x8bfd)
725 {
726 while (m_sh2_state->r[n] > 1 && m_sh2_state->icount > 4)
727 {
728 m_sh2_state->r[n]--;
729 m_sh2_state->icount -= 4; /* cycles for DT (1) and BF taken (3) */
730 }
731 }
732 }
733 #endif
734 }
735
736 /* EXTS.B Rm,Rn */
EXTSB(uint32_t m,uint32_t n)737 void sh_common_execution::EXTSB(uint32_t m, uint32_t n)
738 {
739 m_sh2_state->r[n] = ((int32_t)m_sh2_state->r[m] << 24) >> 24;
740 }
741
742 /* EXTS.W Rm,Rn */
EXTSW(uint32_t m,uint32_t n)743 void sh_common_execution::EXTSW(uint32_t m, uint32_t n)
744 {
745 m_sh2_state->r[n] = ((int32_t)m_sh2_state->r[m] << 16) >> 16;
746 }
747
748 /* EXTU.B Rm,Rn */
EXTUB(uint32_t m,uint32_t n)749 void sh_common_execution::EXTUB(uint32_t m, uint32_t n)
750 {
751 m_sh2_state->r[n] = m_sh2_state->r[m] & 0x000000ff;
752 }
753
754 /* EXTU.W Rm,Rn */
EXTUW(uint32_t m,uint32_t n)755 void sh_common_execution::EXTUW(uint32_t m, uint32_t n)
756 {
757 m_sh2_state->r[n] = m_sh2_state->r[m] & 0x0000ffff;
758 }
759
760 /* JMP @Rm */
JMP(uint32_t m)761 void sh_common_execution::JMP(uint32_t m)
762 {
763 m_sh2_state->m_delay = m_sh2_state->ea = m_sh2_state->r[m];
764 //m_sh2_state->icount--; // not in SH4 implementation?
765 }
766
767 /* JSR @Rm */
JSR(uint32_t m)768 void sh_common_execution::JSR(uint32_t m)
769 {
770 m_sh2_state->pr = m_sh2_state->pc + 2;
771 m_sh2_state->m_delay = m_sh2_state->ea = m_sh2_state->r[m];
772 m_sh2_state->icount--;
773 }
774
775 /* LDC Rm,GBR */
LDCGBR(uint32_t m)776 void sh_common_execution::LDCGBR(uint32_t m)
777 {
778 m_sh2_state->gbr = m_sh2_state->r[m];
779 }
780
781 /* LDC Rm,VBR */
LDCVBR(uint32_t m)782 void sh_common_execution::LDCVBR(uint32_t m)
783 {
784 m_sh2_state->vbr = m_sh2_state->r[m];
785 }
786
787 /* LDC.L @Rm+,GBR */
LDCMGBR(uint32_t m)788 void sh_common_execution::LDCMGBR(uint32_t m)
789 {
790 m_sh2_state->ea = m_sh2_state->r[m];
791 m_sh2_state->gbr = RL( m_sh2_state->ea );
792 m_sh2_state->r[m] += 4;
793 m_sh2_state->icount -= 2;
794 }
795
796 /* LDC.L @Rm+,VBR */
LDCMVBR(uint32_t m)797 void sh_common_execution::LDCMVBR(uint32_t m)
798 {
799 m_sh2_state->ea = m_sh2_state->r[m];
800 m_sh2_state->vbr = RL( m_sh2_state->ea );
801 m_sh2_state->r[m] += 4;
802 m_sh2_state->icount -= 2;
803 }
804
805 /* LDS Rm,MACH */
LDSMACH(uint32_t m)806 void sh_common_execution::LDSMACH(uint32_t m)
807 {
808 m_sh2_state->mach = m_sh2_state->r[m];
809 }
810
811 /* LDS Rm,MACL */
LDSMACL(uint32_t m)812 void sh_common_execution::LDSMACL(uint32_t m)
813 {
814 m_sh2_state->macl = m_sh2_state->r[m];
815 }
816
817 /* LDS Rm,PR */
LDSPR(uint32_t m)818 void sh_common_execution::LDSPR(uint32_t m)
819 {
820 m_sh2_state->pr = m_sh2_state->r[m];
821 }
822
823 /* LDS.L @Rm+,MACH */
LDSMMACH(uint32_t m)824 void sh_common_execution::LDSMMACH(uint32_t m)
825 {
826 m_sh2_state->ea = m_sh2_state->r[m];
827 m_sh2_state->mach = RL( m_sh2_state->ea );
828 m_sh2_state->r[m] += 4;
829 }
830
831 /* LDS.L @Rm+,MACL */
LDSMMACL(uint32_t m)832 void sh_common_execution::LDSMMACL(uint32_t m)
833 {
834 m_sh2_state->ea = m_sh2_state->r[m];
835 m_sh2_state->macl = RL( m_sh2_state->ea );
836 m_sh2_state->r[m] += 4;
837 }
838
839 /* LDS.L @Rm+,PR */
LDSMPR(uint32_t m)840 void sh_common_execution::LDSMPR(uint32_t m)
841 {
842 m_sh2_state->ea = m_sh2_state->r[m];
843 m_sh2_state->pr = RL( m_sh2_state->ea );
844 m_sh2_state->r[m] += 4;
845 }
846
847 /* MAC.L @Rm+,@Rn+ */
MAC_L(uint32_t m,uint32_t n)848 void sh_common_execution::MAC_L(uint32_t m, uint32_t n)
849 {
850 uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2;
851 uint32_t temp0, temp1, temp2, temp3;
852 int32_t tempm, tempn, fnLmL;
853
854 tempn = (int32_t) RL( m_sh2_state->r[n] );
855 m_sh2_state->r[n] += 4;
856 tempm = (int32_t) RL( m_sh2_state->r[m] );
857 m_sh2_state->r[m] += 4;
858 if ((int32_t) (tempn ^ tempm) < 0)
859 fnLmL = -1;
860 else
861 fnLmL = 0;
862 if (tempn < 0)
863 tempn = 0 - tempn;
864 if (tempm < 0)
865 tempm = 0 - tempm;
866 temp1 = (uint32_t) tempn;
867 temp2 = (uint32_t) tempm;
868 RnL = temp1 & 0x0000ffff;
869 RnH = (temp1 >> 16) & 0x0000ffff;
870 RmL = temp2 & 0x0000ffff;
871 RmH = (temp2 >> 16) & 0x0000ffff;
872 temp0 = RmL * RnL;
873 temp1 = RmH * RnL;
874 temp2 = RmL * RnH;
875 temp3 = RmH * RnH;
876 Res2 = 0;
877 Res1 = temp1 + temp2;
878 if (Res1 < temp1)
879 Res2 += 0x00010000;
880 temp1 = (Res1 << 16) & 0xffff0000;
881 Res0 = temp0 + temp1;
882 if (Res0 < temp0)
883 Res2++;
884 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
885 if (fnLmL < 0)
886 {
887 Res2 = ~Res2;
888 if (Res0 == 0)
889 Res2++;
890 else
891 Res0 = (~Res0) + 1;
892 }
893 if (m_sh2_state->sr & SH_S)
894 {
895 Res0 = m_sh2_state->macl + Res0;
896 if (m_sh2_state->macl > Res0)
897 Res2++;
898 Res2 += (m_sh2_state->mach & 0x0000ffff);
899 if (((int32_t) Res2 < 0) && (Res2 < 0xffff8000))
900 {
901 Res2 = 0x00008000;
902 Res0 = 0x00000000;
903 }
904 else if (((int32_t) Res2 > 0) && (Res2 > 0x00007fff))
905 {
906 Res2 = 0x00007fff;
907 Res0 = 0xffffffff;
908 }
909 m_sh2_state->mach = Res2;
910 m_sh2_state->macl = Res0;
911 }
912 else
913 {
914 Res0 = m_sh2_state->macl + Res0;
915 if (m_sh2_state->macl > Res0)
916 Res2++;
917 Res2 += m_sh2_state->mach;
918 m_sh2_state->mach = Res2;
919 m_sh2_state->macl = Res0;
920 }
921 m_sh2_state->icount -= 2;
922 }
923
924 /* MAC.W @Rm+,@Rn+ */
MAC_W(uint32_t m,uint32_t n)925 void sh_common_execution::MAC_W(uint32_t m, uint32_t n)
926 {
927 int32_t tempm, tempn, dest, src, ans;
928 uint32_t templ;
929
930 tempn = (int32_t) RW( m_sh2_state->r[n] );
931 m_sh2_state->r[n] += 2;
932 tempm = (int32_t) RW( m_sh2_state->r[m] );
933 m_sh2_state->r[m] += 2;
934 templ = m_sh2_state->macl;
935 tempm = ((int32_t) (short) tempn * (int32_t) (short) tempm);
936 if ((int32_t) m_sh2_state->macl >= 0)
937 dest = 0;
938 else
939 dest = 1;
940 if ((int32_t) tempm >= 0)
941 {
942 src = 0;
943 tempn = 0;
944 }
945 else
946 {
947 src = 1;
948 tempn = 0xffffffff;
949 }
950 src += dest;
951 m_sh2_state->macl += tempm;
952 if ((int32_t) m_sh2_state->macl >= 0)
953 ans = 0;
954 else
955 ans = 1;
956 ans += dest;
957 if (m_sh2_state->sr & SH_S)
958 {
959 if (ans == 1)
960 {
961 if (src == 0)
962 m_sh2_state->macl = 0x7fffffff;
963 if (src == 2)
964 m_sh2_state->macl = 0x80000000;
965 }
966 }
967 else
968 {
969 m_sh2_state->mach += tempn;
970 if (templ > m_sh2_state->macl)
971 m_sh2_state->mach += 1;
972 }
973 m_sh2_state->icount -= 2;
974 }
975
976 /* MOV Rm,Rn */
MOV(uint32_t m,uint32_t n)977 void sh_common_execution::MOV(uint32_t m, uint32_t n)
978 {
979 m_sh2_state->r[n] = m_sh2_state->r[m];
980 }
981
982 /* MOV.B Rm,@Rn */
MOVBS(uint32_t m,uint32_t n)983 void sh_common_execution::MOVBS(uint32_t m, uint32_t n)
984 {
985 m_sh2_state->ea = m_sh2_state->r[n];
986 WB( m_sh2_state->ea, m_sh2_state->r[m] & 0x000000ff);
987 }
988
989 /* MOV.W Rm,@Rn */
MOVWS(uint32_t m,uint32_t n)990 void sh_common_execution::MOVWS(uint32_t m, uint32_t n)
991 {
992 m_sh2_state->ea = m_sh2_state->r[n];
993 WW( m_sh2_state->ea, m_sh2_state->r[m] & 0x0000ffff);
994 }
995
996 /* MOV.L Rm,@Rn */
MOVLS(uint32_t m,uint32_t n)997 void sh_common_execution::MOVLS(uint32_t m, uint32_t n)
998 {
999 m_sh2_state->ea = m_sh2_state->r[n];
1000 WL( m_sh2_state->ea, m_sh2_state->r[m] );
1001 }
1002
1003 /* MOV.B @Rm,Rn */
MOVBL(uint32_t m,uint32_t n)1004 void sh_common_execution::MOVBL(uint32_t m, uint32_t n)
1005 {
1006 m_sh2_state->ea = m_sh2_state->r[m];
1007 m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_sh2_state->ea );
1008 }
1009
1010 /* MOV.W @Rm,Rn */
MOVWL(uint32_t m,uint32_t n)1011 void sh_common_execution::MOVWL(uint32_t m, uint32_t n)
1012 {
1013 m_sh2_state->ea = m_sh2_state->r[m];
1014 m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t) RW( m_sh2_state->ea );
1015 }
1016
1017 /* MOV.L @Rm,Rn */
MOVLL(uint32_t m,uint32_t n)1018 void sh_common_execution::MOVLL(uint32_t m, uint32_t n)
1019 {
1020 m_sh2_state->ea = m_sh2_state->r[m];
1021 m_sh2_state->r[n] = RL( m_sh2_state->ea );
1022 }
1023
1024 /* MOV.B Rm,@-Rn */
MOVBM(uint32_t m,uint32_t n)1025 void sh_common_execution::MOVBM(uint32_t m, uint32_t n)
1026 {
1027 /* SMG : bug fix, was reading m_sh2_state->r[n] */
1028 uint32_t data = m_sh2_state->r[m] & 0x000000ff;
1029
1030 m_sh2_state->r[n] -= 1;
1031 WB( m_sh2_state->r[n], data );
1032 }
1033
1034 /* MOV.W Rm,@-Rn */
MOVWM(uint32_t m,uint32_t n)1035 void sh_common_execution::MOVWM(uint32_t m, uint32_t n)
1036 {
1037 uint32_t data = m_sh2_state->r[m] & 0x0000ffff;
1038
1039 m_sh2_state->r[n] -= 2;
1040 WW( m_sh2_state->r[n], data );
1041 }
1042
1043 /* MOV.L Rm,@-Rn */
MOVLM(uint32_t m,uint32_t n)1044 void sh_common_execution::MOVLM(uint32_t m, uint32_t n)
1045 {
1046 uint32_t data = m_sh2_state->r[m];
1047
1048 m_sh2_state->r[n] -= 4;
1049 WL( m_sh2_state->r[n], data );
1050 }
1051
1052 /* MOV.B @Rm+,Rn */
MOVBP(uint32_t m,uint32_t n)1053 void sh_common_execution::MOVBP(uint32_t m, uint32_t n)
1054 {
1055 m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_sh2_state->r[m] );
1056 if (n != m)
1057 m_sh2_state->r[m] += 1;
1058 }
1059
1060 /* MOV.W @Rm+,Rn */
MOVWP(uint32_t m,uint32_t n)1061 void sh_common_execution::MOVWP(uint32_t m, uint32_t n)
1062 {
1063 m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t) RW( m_sh2_state->r[m] );
1064 if (n != m)
1065 m_sh2_state->r[m] += 2;
1066 }
1067
1068 /* MOV.L @Rm+,Rn */
MOVLP(uint32_t m,uint32_t n)1069 void sh_common_execution::MOVLP(uint32_t m, uint32_t n)
1070 {
1071 m_sh2_state->r[n] = RL( m_sh2_state->r[m] );
1072 if (n != m)
1073 m_sh2_state->r[m] += 4;
1074 }
1075
1076 /* MOV.B Rm,@(R0,Rn) */
MOVBS0(uint32_t m,uint32_t n)1077 void sh_common_execution::MOVBS0(uint32_t m, uint32_t n)
1078 {
1079 m_sh2_state->ea = m_sh2_state->r[n] + m_sh2_state->r[0];
1080 WB( m_sh2_state->ea, m_sh2_state->r[m] & 0x000000ff );
1081 }
1082
1083 /* MOV.W Rm,@(R0,Rn) */
MOVWS0(uint32_t m,uint32_t n)1084 void sh_common_execution::MOVWS0(uint32_t m, uint32_t n)
1085 {
1086 m_sh2_state->ea = m_sh2_state->r[n] + m_sh2_state->r[0];
1087 WW( m_sh2_state->ea, m_sh2_state->r[m] & 0x0000ffff );
1088 }
1089
1090 /* MOV.L Rm,@(R0,Rn) */
MOVLS0(uint32_t m,uint32_t n)1091 void sh_common_execution::MOVLS0(uint32_t m, uint32_t n)
1092 {
1093 m_sh2_state->ea = m_sh2_state->r[n] + m_sh2_state->r[0];
1094 WL( m_sh2_state->ea, m_sh2_state->r[m] );
1095 }
1096
1097 /* MOV.B @(R0,Rm),Rn */
MOVBL0(uint32_t m,uint32_t n)1098 void sh_common_execution::MOVBL0(uint32_t m, uint32_t n)
1099 {
1100 m_sh2_state->ea = m_sh2_state->r[m] + m_sh2_state->r[0];
1101 m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_sh2_state->ea );
1102 }
1103
1104 /* MOV.W @(R0,Rm),Rn */
MOVWL0(uint32_t m,uint32_t n)1105 void sh_common_execution::MOVWL0(uint32_t m, uint32_t n)
1106 {
1107 m_sh2_state->ea = m_sh2_state->r[m] + m_sh2_state->r[0];
1108 m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t) RW( m_sh2_state->ea );
1109 }
1110
1111 /* MOV.L @(R0,Rm),Rn */
MOVLL0(uint32_t m,uint32_t n)1112 void sh_common_execution::MOVLL0(uint32_t m, uint32_t n)
1113 {
1114 m_sh2_state->ea = m_sh2_state->r[m] + m_sh2_state->r[0];
1115 m_sh2_state->r[n] = RL( m_sh2_state->ea );
1116 }
1117
1118 /* MOV #imm,Rn */
MOVI(uint32_t i,uint32_t n)1119 void sh_common_execution::MOVI(uint32_t i, uint32_t n)
1120 {
1121 m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t)(int8_t) i;
1122 }
1123
1124 /* MOV.W @(disp8,PC),Rn */
MOVWI(uint32_t d,uint32_t n)1125 void sh_common_execution::MOVWI(uint32_t d, uint32_t n)
1126 {
1127 uint32_t disp = d & 0xff;
1128 m_sh2_state->ea = m_sh2_state->pc + disp * 2 + 2;
1129 m_sh2_state->r[n] = (uint32_t)(int32_t)(int16_t) RW( m_sh2_state->ea );
1130 }
1131
1132 /* MOV.L @(disp8,PC),Rn */
MOVLI(uint32_t d,uint32_t n)1133 void sh_common_execution::MOVLI(uint32_t d, uint32_t n)
1134 {
1135 uint32_t disp = d & 0xff;
1136 m_sh2_state->ea = ((m_sh2_state->pc + 2) & ~3) + disp * 4;
1137 m_sh2_state->r[n] = RL( m_sh2_state->ea );
1138 }
1139
1140 /* MOV.B @(disp8,GBR),R0 */
MOVBLG(uint32_t d)1141 void sh_common_execution::MOVBLG(uint32_t d)
1142 {
1143 uint32_t disp = d & 0xff;
1144 m_sh2_state->ea = m_sh2_state->gbr + disp;
1145 m_sh2_state->r[0] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_sh2_state->ea );
1146 }
1147
1148 /* MOV.W @(disp8,GBR),R0 */
MOVWLG(uint32_t d)1149 void sh_common_execution::MOVWLG(uint32_t d)
1150 {
1151 uint32_t disp = d & 0xff;
1152 m_sh2_state->ea = m_sh2_state->gbr + disp * 2;
1153 m_sh2_state->r[0] = (int32_t)(int16_t) RW( m_sh2_state->ea );
1154 }
1155
1156 /* MOV.L @(disp8,GBR),R0 */
MOVLLG(uint32_t d)1157 void sh_common_execution::MOVLLG(uint32_t d)
1158 {
1159 uint32_t disp = d & 0xff;
1160 m_sh2_state->ea = m_sh2_state->gbr + disp * 4;
1161 m_sh2_state->r[0] = RL( m_sh2_state->ea );
1162 }
1163
1164 /* MOV.B R0,@(disp8,GBR) */
MOVBSG(uint32_t d)1165 void sh_common_execution::MOVBSG(uint32_t d)
1166 {
1167 uint32_t disp = d & 0xff;
1168 m_sh2_state->ea = m_sh2_state->gbr + disp;
1169 WB( m_sh2_state->ea, m_sh2_state->r[0] & 0x000000ff );
1170 }
1171
1172 /* MOV.W R0,@(disp8,GBR) */
MOVWSG(uint32_t d)1173 void sh_common_execution::MOVWSG(uint32_t d)
1174 {
1175 uint32_t disp = d & 0xff;
1176 m_sh2_state->ea = m_sh2_state->gbr + disp * 2;
1177 WW( m_sh2_state->ea, m_sh2_state->r[0] & 0x0000ffff );
1178 }
1179
1180 /* MOV.L R0,@(disp8,GBR) */
MOVLSG(uint32_t d)1181 void sh_common_execution::MOVLSG(uint32_t d)
1182 {
1183 uint32_t disp = d & 0xff;
1184 m_sh2_state->ea = m_sh2_state->gbr + disp * 4;
1185 WL( m_sh2_state->ea, m_sh2_state->r[0] );
1186 }
1187
1188 /* MOV.B R0,@(disp4,Rn) */
MOVBS4(uint32_t d,uint32_t n)1189 void sh_common_execution::MOVBS4(uint32_t d, uint32_t n)
1190 {
1191 uint32_t disp = d & 0x0f;
1192 m_sh2_state->ea = m_sh2_state->r[n] + disp;
1193 WB( m_sh2_state->ea, m_sh2_state->r[0] & 0x000000ff );
1194 }
1195
1196 /* MOV.W R0,@(disp4,Rn) */
MOVWS4(uint32_t d,uint32_t n)1197 void sh_common_execution::MOVWS4(uint32_t d, uint32_t n)
1198 {
1199 uint32_t disp = d & 0x0f;
1200 m_sh2_state->ea = m_sh2_state->r[n] + disp * 2;
1201 WW( m_sh2_state->ea, m_sh2_state->r[0] & 0x0000ffff );
1202 }
1203
1204 /* MOV.L Rm,@(disp4,Rn) */
MOVLS4(uint32_t m,uint32_t d,uint32_t n)1205 void sh_common_execution::MOVLS4(uint32_t m, uint32_t d, uint32_t n)
1206 {
1207 uint32_t disp = d & 0x0f;
1208 m_sh2_state->ea = m_sh2_state->r[n] + disp * 4;
1209 WL( m_sh2_state->ea, m_sh2_state->r[m] );
1210 }
1211
1212 /* MOV.B @(disp4,Rm),R0 */
MOVBL4(uint32_t m,uint32_t d)1213 void sh_common_execution::MOVBL4(uint32_t m, uint32_t d)
1214 {
1215 uint32_t disp = d & 0x0f;
1216 m_sh2_state->ea = m_sh2_state->r[m] + disp;
1217 m_sh2_state->r[0] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_sh2_state->ea );
1218 }
1219
1220 /* MOV.W @(disp4,Rm),R0 */
MOVWL4(uint32_t m,uint32_t d)1221 void sh_common_execution::MOVWL4(uint32_t m, uint32_t d)
1222 {
1223 uint32_t disp = d & 0x0f;
1224 m_sh2_state->ea = m_sh2_state->r[m] + disp * 2;
1225 m_sh2_state->r[0] = (uint32_t)(int32_t)(int16_t) RW( m_sh2_state->ea );
1226 }
1227
1228 /* MOV.L @(disp4,Rm),Rn */
MOVLL4(uint32_t m,uint32_t d,uint32_t n)1229 void sh_common_execution::MOVLL4(uint32_t m, uint32_t d, uint32_t n)
1230 {
1231 uint32_t disp = d & 0x0f;
1232 m_sh2_state->ea = m_sh2_state->r[m] + disp * 4;
1233 m_sh2_state->r[n] = RL( m_sh2_state->ea );
1234 }
1235
1236 /* MOVA @(disp8,PC),R0 */
MOVA(uint32_t d)1237 void sh_common_execution::MOVA(uint32_t d)
1238 {
1239 uint32_t disp = d & 0xff;
1240 m_sh2_state->ea = ((m_sh2_state->pc + 2) & ~3) + disp * 4;
1241 m_sh2_state->r[0] = m_sh2_state->ea;
1242 }
1243
1244 /* MOVT Rn */
MOVT(uint32_t n)1245 void sh_common_execution::MOVT(uint32_t n)
1246 {
1247 m_sh2_state->r[n] = m_sh2_state->sr & SH_T;
1248 }
1249
1250 /* MUL.L Rm,Rn */
MULL(uint32_t m,uint32_t n)1251 void sh_common_execution::MULL(uint32_t m, uint32_t n)
1252 {
1253 m_sh2_state->macl = m_sh2_state->r[n] * m_sh2_state->r[m];
1254 m_sh2_state->icount--;
1255 }
1256
1257 /* MULS Rm,Rn */
MULS(uint32_t m,uint32_t n)1258 void sh_common_execution::MULS(uint32_t m, uint32_t n)
1259 {
1260 m_sh2_state->macl = (int16_t) m_sh2_state->r[n] * (int16_t) m_sh2_state->r[m];
1261 }
1262
1263 /* MULU Rm,Rn */
MULU(uint32_t m,uint32_t n)1264 void sh_common_execution::MULU(uint32_t m, uint32_t n)
1265 {
1266 m_sh2_state->macl = (uint16_t) m_sh2_state->r[n] * (uint16_t) m_sh2_state->r[m];
1267 }
1268
1269 /* NEG Rm,Rn */
NEG(uint32_t m,uint32_t n)1270 void sh_common_execution::NEG(uint32_t m, uint32_t n)
1271 {
1272 m_sh2_state->r[n] = 0 - m_sh2_state->r[m];
1273 }
1274
1275 /* NEGC Rm,Rn */
NEGC(uint32_t m,uint32_t n)1276 void sh_common_execution::NEGC(uint32_t m, uint32_t n)
1277 {
1278 uint32_t temp;
1279
1280 temp = m_sh2_state->r[m];
1281 m_sh2_state->r[n] = -temp - (m_sh2_state->sr & SH_T);
1282 if (temp || (m_sh2_state->sr & SH_T))
1283 m_sh2_state->sr |= SH_T;
1284 else
1285 m_sh2_state->sr &= ~SH_T;
1286 }
1287
1288 /* NOP */
NOP(void)1289 void sh_common_execution::NOP(void)
1290 {
1291 }
1292
1293 /* NOT Rm,Rn */
NOT(uint32_t m,uint32_t n)1294 void sh_common_execution::NOT(uint32_t m, uint32_t n)
1295 {
1296 m_sh2_state->r[n] = ~m_sh2_state->r[m];
1297 }
1298
1299 /* OR Rm,Rn */
OR(uint32_t m,uint32_t n)1300 void sh_common_execution::OR(uint32_t m, uint32_t n)
1301 {
1302 m_sh2_state->r[n] |= m_sh2_state->r[m];
1303 }
1304
1305 /* OR #imm,R0 */
ORI(uint32_t i)1306 void sh_common_execution::ORI(uint32_t i)
1307 {
1308 m_sh2_state->r[0] |= i;
1309 m_sh2_state->icount -= 2; // not in SH2 implementation?
1310 }
1311
1312 /* OR.B #imm,@(R0,GBR) */
ORM(uint32_t i)1313 void sh_common_execution::ORM(uint32_t i)
1314 {
1315 uint32_t temp;
1316
1317 m_sh2_state->ea = m_sh2_state->gbr + m_sh2_state->r[0];
1318 temp = RB( m_sh2_state->ea );
1319 temp |= i;
1320 WB( m_sh2_state->ea, temp );
1321 //m_sh2_state->icount -= 2; // not in SH4 implementation?
1322 }
1323
1324 /* ROTCL Rn */
ROTCL(uint32_t n)1325 void sh_common_execution::ROTCL(uint32_t n)
1326 {
1327 uint32_t temp;
1328
1329 temp = (m_sh2_state->r[n] >> 31) & SH_T;
1330 m_sh2_state->r[n] = (m_sh2_state->r[n] << 1) | (m_sh2_state->sr & SH_T);
1331 m_sh2_state->sr = (m_sh2_state->sr & ~SH_T) | temp;
1332 }
1333
1334 /* ROTCR Rn */
ROTCR(uint32_t n)1335 void sh_common_execution::ROTCR(uint32_t n)
1336 {
1337 uint32_t temp;
1338 temp = (m_sh2_state->sr & SH_T) << 31;
1339 if (m_sh2_state->r[n] & SH_T)
1340 m_sh2_state->sr |= SH_T;
1341 else
1342 m_sh2_state->sr &= ~SH_T;
1343 m_sh2_state->r[n] = (m_sh2_state->r[n] >> 1) | temp;
1344 }
1345
1346 /* ROTL Rn */
ROTL(uint32_t n)1347 void sh_common_execution::ROTL(uint32_t n)
1348 {
1349 m_sh2_state->sr = (m_sh2_state->sr & ~SH_T) | ((m_sh2_state->r[n] >> 31) & SH_T);
1350 m_sh2_state->r[n] = (m_sh2_state->r[n] << 1) | (m_sh2_state->r[n] >> 31);
1351 }
1352
1353 /* ROTR Rn */
ROTR(uint32_t n)1354 void sh_common_execution::ROTR(uint32_t n)
1355 {
1356 m_sh2_state->sr = (m_sh2_state->sr & ~SH_T) | (m_sh2_state->r[n] & SH_T);
1357 m_sh2_state->r[n] = (m_sh2_state->r[n] >> 1) | (m_sh2_state->r[n] << 31);
1358 }
1359
1360 /* RTS */
RTS()1361 void sh_common_execution::RTS()
1362 {
1363 m_sh2_state->m_delay = m_sh2_state->ea = m_sh2_state->pr;
1364 m_sh2_state->icount--;
1365 }
1366
1367 /* SETT */
SETT()1368 void sh_common_execution::SETT()
1369 {
1370 m_sh2_state->sr |= SH_T;
1371 }
1372
1373 /* SHAL Rn (same as SHLL) */
SHAL(uint32_t n)1374 void sh_common_execution::SHAL(uint32_t n)
1375 {
1376 m_sh2_state->sr = (m_sh2_state->sr & ~SH_T) | ((m_sh2_state->r[n] >> 31) & SH_T);
1377 m_sh2_state->r[n] <<= 1;
1378 }
1379
1380 /* SHAR Rn */
SHAR(uint32_t n)1381 void sh_common_execution::SHAR(uint32_t n)
1382 {
1383 m_sh2_state->sr = (m_sh2_state->sr & ~SH_T) | (m_sh2_state->r[n] & SH_T);
1384 m_sh2_state->r[n] = (uint32_t)((int32_t)m_sh2_state->r[n] >> 1);
1385 }
1386
1387 /* SHLL Rn (same as SHAL) */
SHLL(uint32_t n)1388 void sh_common_execution::SHLL(uint32_t n)
1389 {
1390 m_sh2_state->sr = (m_sh2_state->sr & ~SH_T) | ((m_sh2_state->r[n] >> 31) & SH_T);
1391 m_sh2_state->r[n] <<= 1;
1392 }
1393
1394 /* SHLL2 Rn */
SHLL2(uint32_t n)1395 void sh_common_execution::SHLL2(uint32_t n)
1396 {
1397 m_sh2_state->r[n] <<= 2;
1398 }
1399
1400 /* SHLL8 Rn */
SHLL8(uint32_t n)1401 void sh_common_execution::SHLL8(uint32_t n)
1402 {
1403 m_sh2_state->r[n] <<= 8;
1404 }
1405
1406 /* SHLL16 Rn */
SHLL16(uint32_t n)1407 void sh_common_execution::SHLL16(uint32_t n)
1408 {
1409 m_sh2_state->r[n] <<= 16;
1410 }
1411
1412 /* SHLR Rn */
SHLR(uint32_t n)1413 void sh_common_execution::SHLR(uint32_t n)
1414 {
1415 m_sh2_state->sr = (m_sh2_state->sr & ~SH_T) | (m_sh2_state->r[n] & SH_T);
1416 m_sh2_state->r[n] >>= 1;
1417 }
1418
1419 /* SHLR2 Rn */
SHLR2(uint32_t n)1420 void sh_common_execution::SHLR2(uint32_t n)
1421 {
1422 m_sh2_state->r[n] >>= 2;
1423 }
1424
1425 /* SHLR8 Rn */
SHLR8(uint32_t n)1426 void sh_common_execution::SHLR8(uint32_t n)
1427 {
1428 m_sh2_state->r[n] >>= 8;
1429 }
1430
1431 /* SHLR16 Rn */
SHLR16(uint32_t n)1432 void sh_common_execution::SHLR16(uint32_t n)
1433 {
1434 m_sh2_state->r[n] >>= 16;
1435 }
1436
1437
1438 /* STC SR,Rn */
STCSR(uint32_t n)1439 void sh_common_execution::STCSR(uint32_t n)
1440 {
1441 m_sh2_state->r[n] = m_sh2_state->sr;
1442 }
1443
1444 /* STC GBR,Rn */
STCGBR(uint32_t n)1445 void sh_common_execution::STCGBR(uint32_t n)
1446 {
1447 m_sh2_state->r[n] = m_sh2_state->gbr;
1448 }
1449
1450 /* STC VBR,Rn */
STCVBR(uint32_t n)1451 void sh_common_execution::STCVBR(uint32_t n)
1452 {
1453 m_sh2_state->r[n] = m_sh2_state->vbr;
1454 }
1455
1456 /* STC.L SR,@-Rn */
STCMSR(uint32_t n)1457 void sh_common_execution::STCMSR(uint32_t n)
1458 {
1459 m_sh2_state->r[n] -= 4;
1460 m_sh2_state->ea = m_sh2_state->r[n];
1461 WL( m_sh2_state->ea, m_sh2_state->sr );
1462 m_sh2_state->icount--;
1463 }
1464
1465 /* STC.L GBR,@-Rn */
STCMGBR(uint32_t n)1466 void sh_common_execution::STCMGBR(uint32_t n)
1467 {
1468 m_sh2_state->r[n] -= 4;
1469 m_sh2_state->ea = m_sh2_state->r[n];
1470 WL( m_sh2_state->ea, m_sh2_state->gbr );
1471 m_sh2_state->icount--;
1472 }
1473
1474 /* STC.L VBR,@-Rn */
STCMVBR(uint32_t n)1475 void sh_common_execution::STCMVBR(uint32_t n)
1476 {
1477 m_sh2_state->r[n] -= 4;
1478 m_sh2_state->ea = m_sh2_state->r[n];
1479 WL( m_sh2_state->ea, m_sh2_state->vbr );
1480 m_sh2_state->icount--;
1481 }
1482
1483 /* STS MACH,Rn */
STSMACH(uint32_t n)1484 void sh_common_execution::STSMACH(uint32_t n)
1485 {
1486 m_sh2_state->r[n] = m_sh2_state->mach;
1487 }
1488
1489 /* STS MACL,Rn */
STSMACL(uint32_t n)1490 void sh_common_execution::STSMACL(uint32_t n)
1491 {
1492 m_sh2_state->r[n] = m_sh2_state->macl;
1493 }
1494
1495 /* STS PR,Rn */
STSPR(uint32_t n)1496 void sh_common_execution::STSPR(uint32_t n)
1497 {
1498 m_sh2_state->r[n] = m_sh2_state->pr;
1499 }
1500
1501 /* STS.L MACH,@-Rn */
STSMMACH(uint32_t n)1502 void sh_common_execution::STSMMACH(uint32_t n)
1503 {
1504 m_sh2_state->r[n] -= 4;
1505 m_sh2_state->ea = m_sh2_state->r[n];
1506 WL( m_sh2_state->ea, m_sh2_state->mach );
1507 }
1508
1509 /* STS.L MACL,@-Rn */
STSMMACL(uint32_t n)1510 void sh_common_execution::STSMMACL(uint32_t n)
1511 {
1512 m_sh2_state->r[n] -= 4;
1513 m_sh2_state->ea = m_sh2_state->r[n];
1514 WL( m_sh2_state->ea, m_sh2_state->macl );
1515 }
1516
1517 /* STS.L PR,@-Rn */
STSMPR(uint32_t n)1518 void sh_common_execution::STSMPR(uint32_t n)
1519 {
1520 m_sh2_state->r[n] -= 4;
1521 m_sh2_state->ea = m_sh2_state->r[n];
1522 WL( m_sh2_state->ea, m_sh2_state->pr );
1523 }
1524
1525 /* SUB Rm,Rn */
SUB(uint32_t m,uint32_t n)1526 void sh_common_execution::SUB(uint32_t m, uint32_t n)
1527 {
1528 m_sh2_state->r[n] -= m_sh2_state->r[m];
1529 }
1530
1531 /* SUBC Rm,Rn */
SUBC(uint32_t m,uint32_t n)1532 void sh_common_execution::SUBC(uint32_t m, uint32_t n)
1533 {
1534 uint32_t tmp0, tmp1;
1535
1536 tmp1 = m_sh2_state->r[n] - m_sh2_state->r[m];
1537 tmp0 = m_sh2_state->r[n];
1538 m_sh2_state->r[n] = tmp1 - (m_sh2_state->sr & SH_T);
1539 if (tmp0 < tmp1)
1540 m_sh2_state->sr |= SH_T;
1541 else
1542 m_sh2_state->sr &= ~SH_T;
1543 if (tmp1 < m_sh2_state->r[n])
1544 m_sh2_state->sr |= SH_T;
1545 }
1546
1547 /* SUBV Rm,Rn */
SUBV(uint32_t m,uint32_t n)1548 void sh_common_execution::SUBV(uint32_t m, uint32_t n)
1549 {
1550 int32_t dest, src, ans;
1551
1552 if ((int32_t) m_sh2_state->r[n] >= 0)
1553 dest = 0;
1554 else
1555 dest = 1;
1556 if ((int32_t) m_sh2_state->r[m] >= 0)
1557 src = 0;
1558 else
1559 src = 1;
1560 src += dest;
1561 m_sh2_state->r[n] -= m_sh2_state->r[m];
1562 if ((int32_t) m_sh2_state->r[n] >= 0)
1563 ans = 0;
1564 else
1565 ans = 1;
1566 ans += dest;
1567 if (src == 1)
1568 {
1569 if (ans == 1)
1570 m_sh2_state->sr |= SH_T;
1571 else
1572 m_sh2_state->sr &= ~SH_T;
1573 }
1574 else
1575 m_sh2_state->sr &= ~SH_T;
1576 }
1577
1578 /* SWAP.B Rm,Rn */
SWAPB(uint32_t m,uint32_t n)1579 void sh_common_execution::SWAPB(uint32_t m, uint32_t n)
1580 {
1581 uint32_t temp0, temp1;
1582
1583 temp0 = m_sh2_state->r[m] & 0xffff0000;
1584 temp1 = (m_sh2_state->r[m] & 0x000000ff) << 8;
1585 m_sh2_state->r[n] = (m_sh2_state->r[m] >> 8) & 0x000000ff;
1586 m_sh2_state->r[n] = m_sh2_state->r[n] | temp1 | temp0;
1587 }
1588
1589 /* SWAP.W Rm,Rn */
SWAPW(uint32_t m,uint32_t n)1590 void sh_common_execution::SWAPW(uint32_t m, uint32_t n)
1591 {
1592 uint32_t temp;
1593
1594 temp = (m_sh2_state->r[m] >> 16) & 0x0000ffff;
1595 m_sh2_state->r[n] = (m_sh2_state->r[m] << 16) | temp;
1596 }
1597
1598 /* TAS.B @Rn */
TAS(uint32_t n)1599 void sh_common_execution::TAS(uint32_t n)
1600 {
1601 uint32_t temp;
1602 m_sh2_state->ea = m_sh2_state->r[n];
1603 /* Bus Lock enable */
1604 temp = RB( m_sh2_state->ea );
1605 if (temp == 0)
1606 m_sh2_state->sr |= SH_T;
1607 else
1608 m_sh2_state->sr &= ~SH_T;
1609 temp |= 0x80;
1610 /* Bus Lock disable */
1611 WB( m_sh2_state->ea, temp );
1612 m_sh2_state->icount -= 3;
1613 }
1614
1615 /* TST Rm,Rn */
TST(uint32_t m,uint32_t n)1616 void sh_common_execution::TST(uint32_t m, uint32_t n)
1617 {
1618 if ((m_sh2_state->r[n] & m_sh2_state->r[m]) == 0)
1619 m_sh2_state->sr |= SH_T;
1620 else
1621 m_sh2_state->sr &= ~SH_T;
1622 }
1623
1624 /* TST #imm,R0 */
TSTI(uint32_t i)1625 void sh_common_execution::TSTI(uint32_t i)
1626 {
1627 uint32_t imm = i & 0xff;
1628
1629 if ((imm & m_sh2_state->r[0]) == 0)
1630 m_sh2_state->sr |= SH_T;
1631 else
1632 m_sh2_state->sr &= ~SH_T;
1633 }
1634
1635 /* TST.B #imm,@(R0,GBR) */
TSTM(uint32_t i)1636 void sh_common_execution::TSTM(uint32_t i)
1637 {
1638 uint32_t imm = i & 0xff;
1639
1640 m_sh2_state->ea = m_sh2_state->gbr + m_sh2_state->r[0];
1641 if ((imm & RB( m_sh2_state->ea )) == 0)
1642 m_sh2_state->sr |= SH_T;
1643 else
1644 m_sh2_state->sr &= ~SH_T;
1645 m_sh2_state->icount -= 2;
1646 }
1647
1648 /* XOR Rm,Rn */
XOR(uint32_t m,uint32_t n)1649 void sh_common_execution::XOR(uint32_t m, uint32_t n)
1650 {
1651 m_sh2_state->r[n] ^= m_sh2_state->r[m];
1652 }
1653
1654 /* XOR #imm,R0 */
XORI(uint32_t i)1655 void sh_common_execution::XORI(uint32_t i)
1656 {
1657 uint32_t imm = i & 0xff;
1658 m_sh2_state->r[0] ^= imm;
1659 }
1660
1661 /* XOR.B #imm,@(R0,GBR) */
XORM(uint32_t i)1662 void sh_common_execution::XORM(uint32_t i)
1663 {
1664 uint32_t imm = i & 0xff;
1665 uint32_t temp;
1666
1667 m_sh2_state->ea = m_sh2_state->gbr + m_sh2_state->r[0];
1668 temp = RB( m_sh2_state->ea );
1669 temp ^= imm;
1670 WB( m_sh2_state->ea, temp );
1671 m_sh2_state->icount -= 2;
1672 }
1673
1674 /* XTRCT Rm,Rn */
XTRCT(uint32_t m,uint32_t n)1675 void sh_common_execution::XTRCT(uint32_t m, uint32_t n)
1676 {
1677 uint32_t temp;
1678
1679 temp = (m_sh2_state->r[m] << 16) & 0xffff0000;
1680 m_sh2_state->r[n] = (m_sh2_state->r[n] >> 16) & 0x0000ffff;
1681 m_sh2_state->r[n] |= temp;
1682 }
1683
1684 /* SLEEP */
SLEEP()1685 void sh_common_execution::SLEEP()
1686 {
1687 /* 0 = normal mode */
1688 /* 1 = enters into power-down mode */
1689 /* 2 = go out the power-down mode after an exception */
1690 if(m_sh2_state->sleep_mode != 2)
1691 m_sh2_state->pc -= 2;
1692 m_sh2_state->icount -= 2;
1693 /* Wait_for_exception; */
1694 if(m_sh2_state->sleep_mode == 0)
1695 m_sh2_state->sleep_mode = 1;
1696 else if(m_sh2_state->sleep_mode == 2)
1697 m_sh2_state->sleep_mode = 0;
1698 }
1699
1700 /* Common dispatch */
1701
op0010(uint16_t opcode)1702 void sh_common_execution::op0010(uint16_t opcode)
1703 {
1704 switch (opcode & 15)
1705 {
1706 case 0: MOVBS(Rm, Rn); break;
1707 case 1: MOVWS(Rm, Rn); break;
1708 case 2: MOVLS(Rm, Rn); break;
1709 case 3: ILLEGAL(); break;
1710 case 4: MOVBM(Rm, Rn); break;
1711 case 5: MOVWM(Rm, Rn); break;
1712 case 6: MOVLM(Rm, Rn); break;
1713 case 7: DIV0S(Rm, Rn); break;
1714 case 8: TST(Rm, Rn); break;
1715 case 9: AND(Rm, Rn); break;
1716 case 10: XOR(Rm, Rn); break;
1717 case 11: OR(Rm, Rn); break;
1718 case 12: CMPSTR(Rm, Rn); break;
1719 case 13: XTRCT(Rm, Rn); break;
1720 case 14: MULU(Rm, Rn); break;
1721 case 15: MULS(Rm, Rn); break;
1722 }
1723 }
1724
op0011(uint16_t opcode)1725 void sh_common_execution::op0011(uint16_t opcode)
1726 {
1727 switch (opcode & 15)
1728 {
1729 case 0: CMPEQ(Rm, Rn); break;
1730 case 1: ILLEGAL(); break;
1731 case 2: CMPHS(Rm, Rn); break;
1732 case 3: CMPGE(Rm, Rn); break;
1733 case 4: DIV1(Rm, Rn); break;
1734 case 5: DMULU(Rm, Rn); break;
1735 case 6: CMPHI(Rm, Rn); break;
1736 case 7: CMPGT(Rm, Rn); break;
1737 case 8: SUB(Rm, Rn); break;
1738 case 9: ILLEGAL(); break;
1739 case 10: SUBC(Rm, Rn); break;
1740 case 11: SUBV(Rm, Rn); break;
1741 case 12: ADD(Rm, Rn); break;
1742 case 13: DMULS(Rm, Rn); break;
1743 case 14: ADDC(Rm, Rn); break;
1744 case 15: ADDV(Rm, Rn); break;
1745 }
1746 }
1747
op0110(uint16_t opcode)1748 void sh_common_execution::op0110(uint16_t opcode)
1749 {
1750 switch (opcode & 15)
1751 {
1752 case 0: MOVBL(Rm, Rn); break;
1753 case 1: MOVWL(Rm, Rn); break;
1754 case 2: MOVLL(Rm, Rn); break;
1755 case 3: MOV(Rm, Rn); break;
1756 case 4: MOVBP(Rm, Rn); break;
1757 case 5: MOVWP(Rm, Rn); break;
1758 case 6: MOVLP(Rm, Rn); break;
1759 case 7: NOT(Rm, Rn); break;
1760 case 8: SWAPB(Rm, Rn); break;
1761 case 9: SWAPW(Rm, Rn); break;
1762 case 10: NEGC(Rm, Rn); break;
1763 case 11: NEG(Rm, Rn); break;
1764 case 12: EXTUB(Rm, Rn); break;
1765 case 13: EXTUW(Rm, Rn); break;
1766 case 14: EXTSB(Rm, Rn); break;
1767 case 15: EXTSW(Rm, Rn); break;
1768 }
1769 }
1770
op1000(uint16_t opcode)1771 void sh_common_execution::op1000(uint16_t opcode)
1772 {
1773 switch ( opcode & (15<<8) )
1774 {
1775 case 0 << 8: MOVBS4(opcode & 0x0f, Rm); break;
1776 case 1 << 8: MOVWS4(opcode & 0x0f, Rm); break;
1777 case 2<< 8: ILLEGAL(); break;
1778 case 3<< 8: ILLEGAL(); break;
1779 case 4<< 8: MOVBL4(Rm, opcode & 0x0f); break;
1780 case 5<< 8: MOVWL4(Rm, opcode & 0x0f); break;
1781 case 6<< 8: ILLEGAL(); break;
1782 case 7<< 8: ILLEGAL(); break;
1783 case 8<< 8: CMPIM(opcode & 0xff); break;
1784 case 9<< 8: BT(opcode & 0xff); break;
1785 case 10<< 8: ILLEGAL(); break;
1786 case 11<< 8: BF(opcode & 0xff); break;
1787 case 12<< 8: ILLEGAL(); break;
1788 case 13<< 8: BTS(opcode & 0xff); break;
1789 case 14<< 8: ILLEGAL(); break;
1790 case 15<< 8: BFS(opcode & 0xff); break;
1791 }
1792 }
1793
1794
op1100(uint16_t opcode)1795 void sh_common_execution::op1100(uint16_t opcode)
1796 {
1797 switch (opcode & (15<<8))
1798 {
1799 case 0<<8: MOVBSG(opcode & 0xff); break;
1800 case 1<<8: MOVWSG(opcode & 0xff); break;
1801 case 2<<8: MOVLSG(opcode & 0xff); break;
1802 case 3<<8: TRAPA(opcode & 0xff); break; // sh2/4 differ
1803 case 4<<8: MOVBLG(opcode & 0xff); break;
1804 case 5<<8: MOVWLG(opcode & 0xff); break;
1805 case 6<<8: MOVLLG(opcode & 0xff); break;
1806 case 7<<8: MOVA(opcode & 0xff); break;
1807 case 8<<8: TSTI(opcode & 0xff); break;
1808 case 9<<8: ANDI(opcode & 0xff); break;
1809 case 10<<8: XORI(opcode & 0xff); break;
1810 case 11<<8: ORI(opcode & 0xff); break;
1811 case 12<<8: TSTM(opcode & 0xff); break;
1812 case 13<<8: ANDM(opcode & 0xff); break;
1813 case 14<<8: XORM(opcode & 0xff); break;
1814 case 15<<8: ORM(opcode & 0xff); break;
1815 }
1816 }
1817
1818 // SH4 cases fall through to here too
execute_one_0000(uint16_t opcode)1819 void sh_common_execution::execute_one_0000(uint16_t opcode)
1820 {
1821 // 04,05,06,07 always the same, 0c,0d,0e,0f always the same, other change based on upper bits
1822
1823 switch (opcode & 0x3F)
1824 {
1825 case 0x00: ILLEGAL(); break;
1826 case 0x01: ILLEGAL(); break;
1827 case 0x02: STCSR(Rn); break;
1828 case 0x03: BSRF(Rn); break;
1829 case 0x04: MOVBS0(Rm, Rn); break;
1830 case 0x05: MOVWS0(Rm, Rn); break;
1831 case 0x06: MOVLS0(Rm, Rn); break;
1832 case 0x07: MULL(Rm, Rn); break;
1833 case 0x08: CLRT(); break;
1834 case 0x09: NOP(); break;
1835 case 0x0a: STSMACH(Rn); break;
1836 case 0x0b: RTS(); break;
1837 case 0x0c: MOVBL0(Rm, Rn); break;
1838 case 0x0d: MOVWL0(Rm, Rn); break;
1839 case 0x0e: MOVLL0(Rm, Rn); break;
1840 case 0x0f: MAC_L(Rm, Rn); break;
1841
1842 case 0x10: ILLEGAL(); break;
1843 case 0x11: ILLEGAL(); break;
1844 case 0x12: STCGBR(Rn); break;
1845 case 0x13: ILLEGAL(); break;
1846 case 0x14: MOVBS0(Rm, Rn); break;
1847 case 0x15: MOVWS0(Rm, Rn); break;
1848 case 0x16: MOVLS0(Rm, Rn); break;
1849 case 0x17: MULL(Rm, Rn); break;
1850 case 0x18: SETT(); break;
1851 case 0x19: DIV0U(); break;
1852 case 0x1a: STSMACL(Rn); break;
1853 case 0x1b: SLEEP(); break;
1854 case 0x1c: MOVBL0(Rm, Rn); break;
1855 case 0x1d: MOVWL0(Rm, Rn); break;
1856 case 0x1e: MOVLL0(Rm, Rn); break;
1857 case 0x1f: MAC_L(Rm, Rn); break;
1858
1859 case 0x20: ILLEGAL(); break;
1860 case 0x21: ILLEGAL(); break;
1861 case 0x22: STCVBR(Rn); break;
1862 case 0x23: BRAF(Rn); break;
1863 case 0x24: MOVBS0(Rm, Rn); break;
1864 case 0x25: MOVWS0(Rm, Rn); break;
1865 case 0x26: MOVLS0(Rm, Rn); break;
1866 case 0x27: MULL(Rm, Rn); break;
1867 case 0x28: CLRMAC(); break;
1868 case 0x29: MOVT(Rn); break;
1869 case 0x2a: STSPR(Rn); break;
1870 case 0x2b: RTE(); break;
1871 case 0x2c: MOVBL0(Rm, Rn); break;
1872 case 0x2d: MOVWL0(Rm, Rn); break;
1873 case 0x2e: MOVLL0(Rm, Rn); break;
1874 case 0x2f: MAC_L(Rm, Rn); break;
1875
1876 case 0x30: ILLEGAL(); break;
1877 case 0x31: ILLEGAL(); break;
1878 case 0x32: ILLEGAL(); break;
1879 case 0x33: ILLEGAL(); break;
1880 case 0x34: MOVBS0(Rm, Rn); break;
1881 case 0x35: MOVWS0(Rm, Rn); break;
1882 case 0x36: MOVLS0(Rm, Rn); break;
1883 case 0x37: MULL(Rm, Rn); break;
1884 case 0x38: ILLEGAL(); break;
1885 case 0x39: ILLEGAL(); break;
1886 case 0x3a: ILLEGAL(); break;
1887 case 0x3b: ILLEGAL(); break;
1888 case 0x3c: MOVBL0(Rm, Rn); break;
1889 case 0x3d: MOVWL0(Rm, Rn); break;
1890 case 0x3e: MOVLL0(Rm, Rn); break;
1891 case 0x3f: MAC_L(Rm, Rn); break;
1892 }
1893 }
1894
1895 // SH4 cases fall through to here too
execute_one_4000(uint16_t opcode)1896 void sh_common_execution::execute_one_4000(uint16_t opcode)
1897 {
1898 // 0f always the same, others differ
1899
1900 switch (opcode & 0x3F)
1901 {
1902 case 0x00: SHLL(Rn); break;
1903 case 0x01: SHLR(Rn); break;
1904 case 0x02: STSMMACH(Rn); break;
1905 case 0x03: STCMSR(Rn); break;
1906 case 0x04: ROTL(Rn); break;
1907 case 0x05: ROTR(Rn); break;
1908 case 0x06: LDSMMACH(Rn); break;
1909 case 0x07: LDCMSR(opcode); break;
1910 case 0x08: SHLL2(Rn); break;
1911 case 0x09: SHLR2(Rn); break;
1912 case 0x0a: LDSMACH(Rn); break;
1913 case 0x0b: JSR(Rn); break;
1914 case 0x0c: ILLEGAL(); break;
1915 case 0x0d: ILLEGAL(); break;
1916 case 0x0e: LDCSR(opcode); break;
1917 case 0x0f: MAC_W(Rm, Rn); break;
1918
1919 case 0x10: DT(Rn); break;
1920 case 0x11: CMPPZ(Rn); break;
1921 case 0x12: STSMMACL(Rn); break;
1922 case 0x13: STCMGBR(Rn); break;
1923 case 0x14: ILLEGAL(); break;
1924 case 0x15: CMPPL(Rn); break;
1925 case 0x16: LDSMMACL(Rn); break;
1926 case 0x17: LDCMGBR(Rn); break;
1927 case 0x18: SHLL8(Rn); break;
1928 case 0x19: SHLR8(Rn); break;
1929 case 0x1a: LDSMACL(Rn); break;
1930 case 0x1b: TAS(Rn); break;
1931 case 0x1c: ILLEGAL(); break;
1932 case 0x1d: ILLEGAL(); break;
1933 case 0x1e: LDCGBR(Rn); break;
1934 case 0x1f: MAC_W(Rm, Rn); break;
1935
1936 case 0x20: SHAL(Rn); break;
1937 case 0x21: SHAR(Rn); break;
1938 case 0x22: STSMPR(Rn); break;
1939 case 0x23: STCMVBR(Rn); break;
1940 case 0x24: ROTCL(Rn); break;
1941 case 0x25: ROTCR(Rn); break;
1942 case 0x26: LDSMPR(Rn); break;
1943 case 0x27: LDCMVBR(Rn); break;
1944 case 0x28: SHLL16(Rn); break;
1945 case 0x29: SHLR16(Rn); break;
1946 case 0x2a: LDSPR(Rn); break;
1947 case 0x2b: JMP(Rn); break;
1948 case 0x2c: ILLEGAL(); break;
1949 case 0x2d: ILLEGAL(); break;
1950 case 0x2e: LDCVBR(Rn); break;
1951 case 0x2f: MAC_W(Rm, Rn); break;
1952
1953 case 0x30: ILLEGAL(); break;
1954 case 0x31: ILLEGAL(); break;
1955 case 0x32: ILLEGAL(); break;
1956 case 0x33: ILLEGAL(); break;
1957 case 0x34: ILLEGAL(); break;
1958 case 0x35: ILLEGAL(); break;
1959 case 0x36: ILLEGAL(); break;
1960 case 0x37: ILLEGAL(); break;
1961 case 0x38: ILLEGAL(); break;
1962 case 0x39: ILLEGAL(); break;
1963 case 0x3a: ILLEGAL(); break;
1964 case 0x3b: ILLEGAL(); break;
1965 case 0x3c: ILLEGAL(); break;
1966 case 0x3d: ILLEGAL(); break;
1967 case 0x3e: ILLEGAL(); break;
1968 case 0x3f: MAC_W(Rm, Rn); break;
1969
1970 }
1971 }
1972
execute_one(const uint16_t opcode)1973 void sh_common_execution::execute_one(const uint16_t opcode)
1974 {
1975 switch(opcode & 0xf000)
1976 {
1977 case 0x0000: execute_one_0000(opcode); break;
1978 case 0x1000: MOVLS4(Rm, opcode & 0x0f, Rn); break;
1979 case 0x2000: op0010(opcode); break;
1980 case 0x3000: op0011(opcode); break;
1981 case 0x4000: execute_one_4000(opcode); break;
1982 case 0x5000: MOVLL4(Rm, opcode & 0x0f, Rn); break;
1983 case 0x6000: op0110(opcode); break;
1984 case 0x7000: ADDI(opcode & 0xff, Rn); break;
1985 case 0x8000: op1000(opcode); break;
1986 case 0x9000: MOVWI(opcode & 0xff, Rn); break;
1987 case 0xa000: BRA(opcode & 0xfff); break;
1988 case 0xb000: BSR(opcode & 0xfff); break;
1989 case 0xc000: op1100(opcode); break;
1990 case 0xd000: MOVLI(opcode & 0xff, Rn); break;
1991 case 0xe000: MOVI(opcode & 0xff, Rn); break;
1992 case 0xf000: execute_one_f000(opcode); break;
1993 }
1994 }
1995
1996 // DRC / UML related
cfunc_unimplemented(void * param)1997 void cfunc_unimplemented(void *param) { ((sh_common_execution *)param)->func_unimplemented(); }
cfunc_MAC_W(void * param)1998 void cfunc_MAC_W(void *param) { ((sh_common_execution *)param)->func_MAC_W(); }
cfunc_MAC_L(void * param)1999 void cfunc_MAC_L(void *param) { ((sh_common_execution *)param)->func_MAC_L(); }
cfunc_DIV1(void * param)2000 void cfunc_DIV1(void *param) { ((sh_common_execution *)param)->func_DIV1(); }
cfunc_ADDV(void * param)2001 void cfunc_ADDV(void *param) { ((sh_common_execution *)param)->func_ADDV(); }
cfunc_SUBV(void * param)2002 void cfunc_SUBV(void *param) { ((sh_common_execution *)param)->func_SUBV(); }
cfunc_printf_probe(void * param)2003 void cfunc_printf_probe(void *param) { ((sh_common_execution *)param)->func_printf_probe(); }
2004
2005 /*-------------------------------------------------
2006 sh2drc_add_fastram - add a new fastram
2007 region
2008 -------------------------------------------------*/
2009
sh2drc_add_fastram(offs_t start,offs_t end,uint8_t readonly,void * base)2010 void sh_common_execution::sh2drc_add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base)
2011 {
2012 if (m_fastram_select < ARRAY_LENGTH(m_fastram))
2013 {
2014 m_fastram[m_fastram_select].start = start;
2015 m_fastram[m_fastram_select].end = end;
2016 m_fastram[m_fastram_select].readonly = readonly;
2017 m_fastram[m_fastram_select].base = base;
2018 m_fastram_select++;
2019 }
2020 }
2021
2022 /***************************************************************************
2023 INLINE FUNCTIONS
2024 ***************************************************************************/
2025
2026 /*-------------------------------------------------
2027 epc - compute the exception PC from a
2028 descriptor
2029 -------------------------------------------------*/
2030
epc(const opcode_desc * desc)2031 uint32_t sh_common_execution::epc(const opcode_desc *desc)
2032 {
2033 return (desc->flags & OPFLAG_IN_DELAY_SLOT) ? (desc->pc - 1) : desc->pc;
2034 }
2035
2036 /*-------------------------------------------------
2037 alloc_handle - allocate a handle if not
2038 already allocated
2039 -------------------------------------------------*/
2040
alloc_handle(uml::code_handle * & handleptr,const char * name)2041 void sh_common_execution::alloc_handle(uml::code_handle *&handleptr, const char *name)
2042 {
2043 if (!handleptr)
2044 handleptr = m_drcuml->handle_alloc(name);
2045 }
2046
2047 /*-------------------------------------------------
2048 load_fast_iregs - load any fast integer
2049 registers
2050 -------------------------------------------------*/
2051
load_fast_iregs(drcuml_block & block)2052 void sh_common_execution::load_fast_iregs(drcuml_block &block)
2053 {
2054 for (int regnum = 0; regnum < ARRAY_LENGTH(m_regmap); regnum++)
2055 {
2056 if (m_regmap[regnum].is_int_register())
2057 {
2058 UML_MOV(block, uml::parameter::make_ireg(m_regmap[regnum].ireg()), mem(&m_sh2_state->r[regnum]));
2059 }
2060 }
2061 }
2062
2063
2064 /*-------------------------------------------------
2065 save_fast_iregs - save any fast integer
2066 registers
2067 -------------------------------------------------*/
2068
save_fast_iregs(drcuml_block & block)2069 void sh_common_execution::save_fast_iregs(drcuml_block &block)
2070 {
2071 for (int regnum = 0; regnum < ARRAY_LENGTH(m_regmap); regnum++)
2072 {
2073 if (m_regmap[regnum].is_int_register())
2074 {
2075 UML_MOV(block, mem(&m_sh2_state->r[regnum]), uml::parameter::make_ireg(m_regmap[regnum].ireg()));
2076 }
2077 }
2078 }
2079
2080
2081 /*-------------------------------------------------
2082 log_desc_flags_to_string - generate a string
2083 representing the instruction description
2084 flags
2085 -------------------------------------------------*/
2086
log_desc_flags_to_string(uint32_t flags)2087 const char *sh_common_execution::log_desc_flags_to_string(uint32_t flags)
2088 {
2089 static char tempbuf[30];
2090 char *dest = tempbuf;
2091
2092 /* branches */
2093 if (flags & OPFLAG_IS_UNCONDITIONAL_BRANCH)
2094 *dest++ = 'U';
2095 else if (flags & OPFLAG_IS_CONDITIONAL_BRANCH)
2096 *dest++ = 'C';
2097 else
2098 *dest++ = '.';
2099
2100 /* intrablock branches */
2101 *dest++ = (flags & OPFLAG_INTRABLOCK_BRANCH) ? 'i' : '.';
2102
2103 /* branch targets */
2104 *dest++ = (flags & OPFLAG_IS_BRANCH_TARGET) ? 'B' : '.';
2105
2106 /* delay slots */
2107 *dest++ = (flags & OPFLAG_IN_DELAY_SLOT) ? 'D' : '.';
2108
2109 /* exceptions */
2110 if (flags & OPFLAG_WILL_CAUSE_EXCEPTION)
2111 *dest++ = 'E';
2112 else if (flags & OPFLAG_CAN_CAUSE_EXCEPTION)
2113 *dest++ = 'e';
2114 else
2115 *dest++ = '.';
2116
2117 /* read/write */
2118 if (flags & OPFLAG_READS_MEMORY)
2119 *dest++ = 'R';
2120 else if (flags & OPFLAG_WRITES_MEMORY)
2121 *dest++ = 'W';
2122 else
2123 *dest++ = '.';
2124
2125 /* TLB validation */
2126 *dest++ = (flags & OPFLAG_VALIDATE_TLB) ? 'V' : '.';
2127
2128 /* TLB modification */
2129 *dest++ = (flags & OPFLAG_MODIFIES_TRANSLATION) ? 'T' : '.';
2130
2131 /* redispatch */
2132 *dest++ = (flags & OPFLAG_REDISPATCH) ? 'R' : '.';
2133 return tempbuf;
2134 }
2135
2136
2137 /*-------------------------------------------------
2138 log_register_list - log a list of GPR registers
2139 -------------------------------------------------*/
2140
log_register_list(const char * string,const uint32_t * reglist,const uint32_t * regnostarlist)2141 void sh_common_execution::log_register_list(const char *string, const uint32_t *reglist, const uint32_t *regnostarlist)
2142 {
2143 int count = 0;
2144 int regnum;
2145
2146 /* skip if nothing */
2147 if (reglist[0] == 0 && reglist[1] == 0 && reglist[2] == 0)
2148 return;
2149
2150 m_drcuml->log_printf("[%s:", string);
2151
2152 for (regnum = 0; regnum < 16; regnum++)
2153 {
2154 if (reglist[0] & REGFLAG_R(regnum))
2155 {
2156 m_drcuml->log_printf("%sr%d", (count++ == 0) ? "" : ",", regnum);
2157 if (regnostarlist != nullptr && !(regnostarlist[0] & REGFLAG_R(regnum)))
2158 m_drcuml->log_printf("*");
2159 }
2160 }
2161
2162 if (reglist[1] & REGFLAG_PR)
2163 {
2164 m_drcuml->log_printf("%spr", (count++ == 0) ? "" : ",");
2165 if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_PR))
2166 m_drcuml->log_printf("*");
2167 }
2168
2169 if (reglist[1] & REGFLAG_SR)
2170 {
2171 m_drcuml->log_printf("%ssr", (count++ == 0) ? "" : ",");
2172 if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_SR))
2173 m_drcuml->log_printf("*");
2174 }
2175
2176 if (reglist[1] & REGFLAG_MACL)
2177 {
2178 m_drcuml->log_printf("%smacl", (count++ == 0) ? "" : ",");
2179 if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_MACL))
2180 m_drcuml->log_printf("*");
2181 }
2182
2183 if (reglist[1] & REGFLAG_MACH)
2184 {
2185 m_drcuml->log_printf("%smach", (count++ == 0) ? "" : ",");
2186 if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_MACH))
2187 m_drcuml->log_printf("*");
2188 }
2189
2190 if (reglist[1] & REGFLAG_GBR)
2191 {
2192 m_drcuml->log_printf("%sgbr", (count++ == 0) ? "" : ",");
2193 if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_GBR))
2194 m_drcuml->log_printf("*");
2195 }
2196
2197 if (reglist[1] & REGFLAG_VBR)
2198 {
2199 m_drcuml->log_printf("%svbr", (count++ == 0) ? "" : ",");
2200 if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_VBR))
2201 m_drcuml->log_printf("*");
2202 }
2203
2204 m_drcuml->log_printf("] ");
2205 }
2206
2207 /*-------------------------------------------------
2208 log_opcode_desc - log a list of descriptions
2209 -------------------------------------------------*/
2210
log_opcode_desc(const opcode_desc * desclist,int indent)2211 void sh_common_execution::log_opcode_desc(const opcode_desc *desclist, int indent)
2212 {
2213 /* open the file, creating it if necessary */
2214 if (indent == 0)
2215 m_drcuml->log_printf("\nDescriptor list @ %08X\n", desclist->pc);
2216
2217 /* output each descriptor */
2218 for ( ; desclist != nullptr; desclist = desclist->next())
2219 {
2220 std::ostringstream stream;
2221
2222 /* disassemle the current instruction and output it to the log */
2223 if (m_drcuml->logging() || m_drcuml->logging_native())
2224 {
2225 if (desclist->flags & OPFLAG_VIRTUAL_NOOP)
2226 stream << "<virtual nop>";
2227 else
2228 {
2229 sh_disassembler sh2d(false);
2230 sh2d.dasm_one(stream, desclist->pc, desclist->opptr.w[0]);
2231 }
2232 }
2233 else
2234 stream << "???";
2235 m_drcuml->log_printf("%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(desclist->flags), stream.str().c_str());
2236
2237 /* output register states */
2238 log_register_list("use", desclist->regin, nullptr);
2239 log_register_list("mod", desclist->regout, desclist->regreq);
2240 m_drcuml->log_printf("\n");
2241
2242 /* if we have a delay slot, output it recursively */
2243 if (desclist->delay.first() != nullptr)
2244 log_opcode_desc(desclist->delay.first(), indent + 1);
2245
2246 /* at the end of a sequence add a dividing line */
2247 if (desclist->flags & OPFLAG_END_SEQUENCE)
2248 m_drcuml->log_printf("-----\n");
2249 }
2250 }
2251
2252 /*-------------------------------------------------
2253 log_add_disasm_comment - add a comment
2254 including disassembly of an SH2 instruction
2255 -------------------------------------------------*/
2256
log_add_disasm_comment(drcuml_block & block,uint32_t pc,uint32_t op)2257 void sh_common_execution::log_add_disasm_comment(drcuml_block &block, uint32_t pc, uint32_t op)
2258 {
2259 if (m_drcuml->logging())
2260 {
2261 sh_disassembler sh2d(false);
2262 std::ostringstream stream;
2263 sh2d.dasm_one(stream, pc, op);
2264 block.append_comment("%08X: %s", pc, stream.str().c_str());
2265 }
2266 }
2267
2268
2269 /*-------------------------------------------------
2270 code_flush_cache - flush the cache and
2271 regenerate static code
2272 -------------------------------------------------*/
2273
code_flush_cache()2274 void sh_common_execution::code_flush_cache()
2275 {
2276 /* empty the transient cache contents */
2277 m_drcuml->reset();
2278
2279 try
2280 {
2281 /* generate the entry point and out-of-cycles handlers */
2282 static_generate_nocode_handler();
2283 static_generate_out_of_cycles();
2284 static_generate_entry_point();
2285
2286 /* add subroutines for memory accesses */
2287 static_generate_memory_accessor(1, false, "read8", m_read8);
2288 static_generate_memory_accessor(1, true, "write8", m_write8);
2289 static_generate_memory_accessor(2, false, "read16", m_read16);
2290 static_generate_memory_accessor(2, true, "write16", m_write16);
2291 static_generate_memory_accessor(4, false, "read32", m_read32);
2292 static_generate_memory_accessor(4, true, "write32", m_write32);
2293 }
2294 catch (drcuml_block::abort_compilation &)
2295 {
2296 fatalerror("Unable to generate SH2 static code\n");
2297 }
2298
2299 m_cache_dirty = false;
2300 }
2301
2302 /* Execute cycles - returns number of cycles actually run */
execute_run_drc()2303 void sh_common_execution::execute_run_drc()
2304 {
2305 int execute_result;
2306
2307 /* reset the cache if dirty */
2308 if (m_cache_dirty)
2309 code_flush_cache();
2310
2311 /* execute */
2312 do
2313 {
2314 /* run as much as we can */
2315 execute_result = m_drcuml->execute(*m_entry);
2316
2317 /* if we need to recompile, do it */
2318 if (execute_result == EXECUTE_MISSING_CODE)
2319 {
2320 code_compile_block(0, m_sh2_state->pc);
2321 }
2322 else if (execute_result == EXECUTE_UNMAPPED_CODE)
2323 {
2324 fatalerror("Attempted to execute unmapped code at PC=%08X\n", m_sh2_state->pc);
2325 }
2326 else if (execute_result == EXECUTE_RESET_CACHE)
2327 {
2328 code_flush_cache();
2329 }
2330 } while (execute_result != EXECUTE_OUT_OF_CYCLES);
2331 }
2332
2333
2334 /*-------------------------------------------------
2335 code_compile_block - compile a block of the
2336 given mode at the specified pc
2337 -------------------------------------------------*/
2338
code_compile_block(uint8_t mode,offs_t pc)2339 void sh_common_execution::code_compile_block(uint8_t mode, offs_t pc)
2340 {
2341 compiler_state compiler = { 0 };
2342 const opcode_desc *seqhead, *seqlast;
2343 const opcode_desc *desclist;
2344 bool override = false;
2345
2346 g_profiler.start(PROFILER_DRC_COMPILE);
2347
2348 /* get a description of this sequence */
2349 desclist = get_desclist(pc);
2350
2351 if (m_drcuml->logging() || m_drcuml->logging_native())
2352 log_opcode_desc(desclist, 0);
2353
2354 bool succeeded = false;
2355 while (!succeeded)
2356 {
2357 try
2358 {
2359 /* start the block */
2360 drcuml_block &block(m_drcuml->begin_block(4096));
2361
2362 /* loop until we get through all instruction sequences */
2363 for (seqhead = desclist; seqhead != nullptr; seqhead = seqlast->next())
2364 {
2365 const opcode_desc *curdesc;
2366 uint32_t nextpc;
2367
2368 /* add a code log entry */
2369 if (m_drcuml->logging())
2370 block.append_comment("-------------------------"); // comment
2371
2372 /* determine the last instruction in this sequence */
2373 for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next())
2374 if (seqlast->flags & OPFLAG_END_SEQUENCE)
2375 break;
2376 assert(seqlast != nullptr);
2377
2378 /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */
2379 if (override || !m_drcuml->hash_exists(mode, seqhead->pc))
2380 UML_HASH(block, mode, seqhead->pc); // hash mode,pc
2381
2382 /* if we already have a hash, and this is the first sequence, assume that we */
2383 /* are recompiling due to being out of sync and allow future overrides */
2384 else if (seqhead == desclist)
2385 {
2386 override = true;
2387 UML_HASH(block, mode, seqhead->pc); // hash mode,pc
2388 }
2389
2390 /* otherwise, redispatch to that fixed PC and skip the rest of the processing */
2391 else
2392 {
2393 UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000
2394 UML_HASHJMP(block, 0, seqhead->pc, *m_nocode);
2395 // hashjmp <mode>,seqhead->pc,nocode
2396 continue;
2397 }
2398
2399 /* validate this code block if we're not pointing into ROM */
2400 if (m_program->get_write_ptr(seqhead->physpc) != nullptr)
2401 generate_checksum_block(block, compiler, seqhead, seqlast);
2402
2403 /* label this instruction, if it may be jumped to locally */
2404 if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
2405 {
2406 UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000
2407 }
2408
2409 /* iterate over instructions in the sequence and compile them */
2410 for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next())
2411 {
2412 generate_sequence_instruction(block, compiler, curdesc, 0xffffffff);
2413 }
2414
2415 /* if we need to return to the start, do it */
2416 if (seqlast->flags & OPFLAG_RETURN_TO_START)
2417 {
2418 nextpc = pc;
2419 }
2420 /* otherwise we just go to the next instruction */
2421 else
2422 {
2423 nextpc = seqlast->pc + (seqlast->skipslots + 1) * 2;
2424 }
2425
2426 /* count off cycles and go there */
2427 generate_update_cycles(block, compiler, nextpc, true); // <subtract cycles>
2428
2429 /* SH2 has no modes */
2430 if (seqlast->next() == nullptr || seqlast->next()->pc != nextpc)
2431 {
2432 UML_HASHJMP(block, 0, nextpc, *m_nocode);
2433 }
2434 // hashjmp <mode>,nextpc,nocode
2435 }
2436
2437 /* end the sequence */
2438 block.end();
2439 g_profiler.stop();
2440 succeeded = true;
2441 }
2442 catch (drcuml_block::abort_compilation &)
2443 {
2444 code_flush_cache();
2445 }
2446 }
2447 }
2448
2449
2450 /*-------------------------------------------------
2451 static_generate_nocode_handler - generate an
2452 exception handler for "out of code"
2453 -------------------------------------------------*/
2454
static_generate_nocode_handler()2455 void sh_common_execution::static_generate_nocode_handler()
2456 {
2457 /* begin generating */
2458 drcuml_block &block(m_drcuml->begin_block(10));
2459
2460 /* generate a hash jump via the current mode and PC */
2461 alloc_handle(m_nocode, "nocode");
2462 UML_HANDLE(block, *m_nocode); // handle nocode
2463 UML_GETEXP(block, I0); // getexp i0
2464 UML_MOV(block, mem(&m_sh2_state->pc), I0); // mov [pc],i0
2465 save_fast_iregs(block);
2466 UML_EXIT(block, EXECUTE_MISSING_CODE); // exit EXECUTE_MISSING_CODE
2467
2468 block.end();
2469 }
2470
2471
2472 /*-------------------------------------------------
2473 static_generate_out_of_cycles - generate an
2474 out of cycles exception handler
2475 -------------------------------------------------*/
2476
static_generate_out_of_cycles()2477 void sh_common_execution::static_generate_out_of_cycles()
2478 {
2479 /* begin generating */
2480 drcuml_block &block(m_drcuml->begin_block(10));
2481
2482 /* generate a hash jump via the current mode and PC */
2483 alloc_handle(m_out_of_cycles, "out_of_cycles");
2484 UML_HANDLE(block, *m_out_of_cycles); // handle out_of_cycles
2485 UML_GETEXP(block, I0); // getexp i0
2486 UML_MOV(block, mem(&m_sh2_state->pc), I0); // mov <pc>,i0
2487 save_fast_iregs(block);
2488 UML_EXIT(block, EXECUTE_OUT_OF_CYCLES); // exit EXECUTE_OUT_OF_CYCLES
2489
2490 block.end();
2491 }
2492
2493 /*-------------------------------------------------
2494 generate_checksum_block - generate code to
2495 validate a sequence of opcodes
2496 -------------------------------------------------*/
2497
generate_checksum_block(drcuml_block & block,compiler_state & compiler,const opcode_desc * seqhead,const opcode_desc * seqlast)2498 void sh_common_execution::generate_checksum_block(drcuml_block &block, compiler_state &compiler, const opcode_desc *seqhead, const opcode_desc *seqlast)
2499 {
2500 const opcode_desc *curdesc;
2501 if (m_drcuml->logging())
2502 block.append_comment("[Validation for %08X]", seqhead->pc); // comment
2503
2504 /* loose verify or single instruction: just compare and fail */
2505 if (!(m_drcoptions & SH2DRC_STRICT_VERIFY) || seqhead->next() == nullptr)
2506 {
2507 if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP))
2508 {
2509 const void *base = m_prptr(seqhead->physpc);
2510
2511 UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x2); // load i0,base,word
2512 UML_CMP(block, I0, seqhead->opptr.w[0]); // cmp i0,*opptr
2513 UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
2514 }
2515 }
2516
2517 /* full verification; sum up everything */
2518 else
2519 {
2520 uint32_t sum = 0;
2521 const void *base = m_prptr(seqhead->physpc);
2522
2523 UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x4); // load i0,base,word
2524 sum += seqhead->opptr.w[0];
2525 for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
2526 if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
2527 {
2528 base = m_prptr(curdesc->physpc);
2529
2530 UML_LOAD(block, I1, base, 0, SIZE_WORD, SCALE_x2); // load i1,*opptr,word
2531 UML_ADD(block, I0, I0, I1); // add i0,i0,i1
2532 sum += curdesc->opptr.w[0];
2533 }
2534 UML_CMP(block, I0, sum); // cmp i0,sum
2535 UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
2536 }
2537 }
2538
2539
2540
2541 /*-------------------------------------------------
2542 generate_sequence_instruction - generate code
2543 for a single instruction in a sequence
2544 -------------------------------------------------*/
2545
generate_sequence_instruction(drcuml_block & block,compiler_state & compiler,const opcode_desc * desc,uint32_t ovrpc)2546 void sh_common_execution::generate_sequence_instruction(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t ovrpc)
2547 {
2548 offs_t expc;
2549
2550 /* add an entry for the log */
2551 if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
2552 log_add_disasm_comment(block, desc->pc, desc->opptr.w[0]);
2553
2554 /* set the PC map variable */
2555 expc = (desc->flags & OPFLAG_IN_DELAY_SLOT) ? desc->pc - 1 : desc->pc;
2556 UML_MAPVAR(block, MAPVAR_PC, expc); // mapvar PC,expc
2557
2558 /* accumulate total cycles */
2559 compiler.cycles += desc->cycles;
2560
2561 /* update the icount map variable */
2562 UML_MAPVAR(block, MAPVAR_CYCLES, compiler.cycles); // mapvar CYCLES,compiler.cycles
2563
2564 /* if we want a probe, add it here */
2565 if (desc->pc == PROBE_ADDRESS)
2566 {
2567 UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov [pc],desc->pc
2568 UML_CALLC(block, cfunc_printf_probe, this); // callc cfunc_printf_probe,sh2
2569 }
2570
2571 /* if we are debugging, call the debugger */
2572 if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
2573 {
2574 UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov [pc],desc->pc
2575 save_fast_iregs(block);
2576 UML_DEBUG(block, desc->pc); // debug desc->pc
2577 }
2578 else // not debug, see what other reasons there are for flushing the PC
2579 {
2580 if (m_drcoptions & SH2DRC_FLUSH_PC) // always flush?
2581 {
2582 UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov m_sh2_state->pc, desc->pc
2583 }
2584 else // check for driver-selected flushes
2585 {
2586 int pcflush;
2587
2588 for (pcflush = 0; pcflush < m_pcfsel; pcflush++)
2589 {
2590 if (desc->pc == m_pcflushes[pcflush])
2591 {
2592 UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov m_sh2_state->pc, desc->pc
2593 }
2594 }
2595 }
2596 }
2597
2598
2599 /* if we hit an unmapped address, fatal error */
2600 if (desc->flags & OPFLAG_COMPILER_UNMAPPED)
2601 {
2602 UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov [pc],desc->pc
2603 save_fast_iregs(block);
2604 UML_EXIT(block, EXECUTE_UNMAPPED_CODE); // exit EXECUTE_UNMAPPED_CODE
2605 }
2606
2607 /* if this is an invalid opcode, die */
2608 if (desc->flags & OPFLAG_INVALID_OPCODE)
2609 {
2610 fatalerror("SH2DRC: invalid opcode!\n");
2611 }
2612
2613 /* otherwise, unless this is a virtual no-op, it's a regular instruction */
2614 else if (!(desc->flags & OPFLAG_VIRTUAL_NOOP))
2615 {
2616 /* compile the instruction */
2617 if (!generate_opcode(block, compiler, desc, ovrpc))
2618 {
2619 // handle an illegal op
2620 UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov [pc],desc->pc
2621 UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); // mov [arg0],opcode
2622 UML_CALLC(block, cfunc_unimplemented, this); // callc cfunc_unimplemented
2623 }
2624 }
2625 }
2626
2627 /*------------------------------------------------------------------
2628 generate_delay_slot
2629 ------------------------------------------------------------------*/
2630
generate_delay_slot(drcuml_block & block,compiler_state & compiler,const opcode_desc * desc,uint32_t ovrpc)2631 void sh_common_execution::generate_delay_slot(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t ovrpc)
2632 {
2633 compiler_state compiler_temp(compiler);
2634
2635 /* compile the delay slot using temporary compiler state */
2636 assert(desc->delay.first() != nullptr);
2637 generate_sequence_instruction(block, compiler_temp, desc->delay.first(), ovrpc); // <next instruction>
2638
2639 /* update the label */
2640 compiler.labelnum = compiler_temp.labelnum;
2641 }
2642
func_unimplemented()2643 void sh_common_execution::func_unimplemented()
2644 {
2645 // set up an invalid opcode exception
2646 m_sh2_state->evec = RL( m_sh2_state->vbr + 4 * 4 );
2647 m_sh2_state->evec &= m_am;
2648 m_sh2_state->irqsr = m_sh2_state->sr;
2649 // claim it's an NMI, because it pretty much is
2650 m_sh2_state->pending_nmi = 1;
2651 }
2652
func_MAC_W()2653 void sh_common_execution::func_MAC_W()
2654 {
2655 uint16_t opcode;
2656 int n, m;
2657
2658 // recover the opcode
2659 opcode = m_sh2_state->arg0;
2660
2661 // extract the operands
2662 n = Rn;
2663 m = Rm;
2664
2665 MAC_W(m, n);
2666 }
2667
2668
func_MAC_L()2669 void sh_common_execution::func_MAC_L()
2670 {
2671 uint16_t opcode;
2672 int n, m;
2673
2674 // recover the opcode
2675 opcode = m_sh2_state->arg0;
2676
2677 // extract the operands
2678 n = Rn;
2679 m = Rm;
2680
2681 MAC_L(m, n);
2682 }
2683
2684
func_DIV1()2685 void sh_common_execution::func_DIV1()
2686 {
2687 uint16_t opcode;
2688 int n, m;
2689
2690 // recover the opcode
2691 opcode = m_sh2_state->arg0;
2692
2693 // extract the operands
2694 n = Rn;
2695 m = Rm;
2696
2697 DIV1(m, n);
2698 }
2699
2700
func_ADDV()2701 void sh_common_execution::func_ADDV()
2702 {
2703 uint16_t opcode;
2704 int n, m;
2705
2706 // recover the opcode
2707 opcode = m_sh2_state->arg0;
2708
2709 // extract the operands
2710 n = Rn;
2711 m = Rm;
2712
2713 ADDV(m, n);
2714 }
2715
2716
func_SUBV()2717 void sh_common_execution::func_SUBV()
2718 {
2719 uint16_t opcode;
2720 int n, m;
2721
2722 // recover the opcode
2723 opcode = m_sh2_state->arg0;
2724
2725 // extract the operands
2726 n = Rn;
2727 m = Rm;
2728
2729 SUBV(m, n);
2730 }
2731
2732
func_printf_probe()2733 void sh_common_execution::func_printf_probe()
2734 {
2735 uint32_t pc = m_sh2_state->pc;
2736
2737 printf(" PC=%08X r0=%08X r1=%08X r2=%08X\n",
2738 pc,
2739 (uint32_t)m_sh2_state->r[0],
2740 (uint32_t)m_sh2_state->r[1],
2741 (uint32_t)m_sh2_state->r[2]);
2742 printf(" r3=%08X r4=%08X r5=%08X r6=%08X\n",
2743 (uint32_t)m_sh2_state->r[3],
2744 (uint32_t)m_sh2_state->r[4],
2745 (uint32_t)m_sh2_state->r[5],
2746 (uint32_t)m_sh2_state->r[6]);
2747 printf(" r7=%08X r8=%08X r9=%08X r10=%08X\n",
2748 (uint32_t)m_sh2_state->r[7],
2749 (uint32_t)m_sh2_state->r[8],
2750 (uint32_t)m_sh2_state->r[9],
2751 (uint32_t)m_sh2_state->r[10]);
2752 printf(" r11=%08X r12=%08X r13=%08X r14=%08X\n",
2753 (uint32_t)m_sh2_state->r[11],
2754 (uint32_t)m_sh2_state->r[12],
2755 (uint32_t)m_sh2_state->r[13],
2756 (uint32_t)m_sh2_state->r[14]);
2757 printf(" r15=%08X macl=%08X mach=%08X gbr=%08X\n",
2758 (uint32_t)m_sh2_state->r[15],
2759 (uint32_t)m_sh2_state->macl,
2760 (uint32_t)m_sh2_state->mach,
2761 (uint32_t)m_sh2_state->gbr);
2762 printf(" evec %x irqsr %x pc=%08x\n",
2763 (uint32_t)m_sh2_state->evec,
2764 (uint32_t)m_sh2_state->irqsr, (uint32_t)m_sh2_state->pc);
2765 }
2766
2767 /*-------------------------------------------------
2768 generate_opcode - generate code for a specific
2769 opcode
2770 -------------------------------------------------*/
2771
generate_opcode(drcuml_block & block,compiler_state & compiler,const opcode_desc * desc,uint32_t ovrpc)2772 bool sh_common_execution::generate_opcode(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t ovrpc)
2773 {
2774 uint32_t scratch, scratch2;
2775 int32_t disp;
2776 uint16_t opcode = desc->opptr.w[0];
2777 uint8_t opswitch = opcode >> 12;
2778 int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0);
2779
2780 //printf("generating %04x\n", opcode);
2781
2782 switch (opswitch)
2783 {
2784 case 0:
2785 return generate_group_0(block, compiler, desc, opcode, in_delay_slot, ovrpc);
2786
2787 case 1: // MOVLS4
2788 scratch = (opcode & 0x0f) * 4;
2789 UML_ADD(block, I0, R32(Rn), scratch); // add r0, Rn, scratch
2790 UML_MOV(block, I1, R32(Rm)); // mov r1, Rm
2791 SETEA(0); // set ea for debug
2792 UML_CALLH(block, *m_write32);
2793
2794 if (!in_delay_slot)
2795 generate_update_cycles(block, compiler, desc->pc + 2, true);
2796 return true;
2797
2798 case 2:
2799 return generate_group_2(block, compiler, desc, opcode, in_delay_slot, ovrpc);
2800 case 3:
2801 return generate_group_3(block, compiler, desc, opcode, ovrpc);
2802 case 4:
2803 return generate_group_4(block, compiler, desc, opcode, in_delay_slot, ovrpc);
2804
2805 case 5: // MOVLL4
2806 scratch = (opcode & 0x0f) * 4;
2807 UML_ADD(block, I0, R32(Rm), scratch); // add r0, Rm, scratch
2808 SETEA(0); // set ea for debug
2809 UML_CALLH(block, *m_read32); // call read32
2810 UML_MOV(block, R32(Rn), I0); // mov Rn, r0
2811
2812 if (!in_delay_slot)
2813 generate_update_cycles(block, compiler, desc->pc + 2, true);
2814 return true;
2815
2816 case 6:
2817 return generate_group_6(block, compiler, desc, opcode, in_delay_slot, ovrpc);
2818
2819 case 7: // ADDI
2820 scratch = opcode & 0xff;
2821 scratch2 = (uint32_t)(int32_t)(int16_t)(int8_t)scratch;
2822 UML_ADD(block, R32(Rn), R32(Rn), scratch2); // add Rn, Rn, scratch2
2823 return true;
2824
2825 case 8:
2826 return generate_group_8(block, compiler, desc, opcode, in_delay_slot, ovrpc);
2827
2828 case 9: // MOVWI
2829 if (ovrpc == 0xffffffff)
2830 {
2831 scratch = (desc->pc + 2) + ((opcode & 0xff) * 2) + 2;
2832 }
2833 else
2834 {
2835 scratch = (ovrpc + 2) + ((opcode & 0xff) * 2) + 2;
2836 }
2837
2838 if (m_drcoptions & SH2DRC_STRICT_PCREL)
2839 {
2840 UML_MOV(block, I0, scratch); // mov r0, scratch
2841 SETEA(0); // set ea for debug
2842 UML_CALLH(block, *m_read16); // read16(r0, r1)
2843 UML_SEXT(block, R32(Rn), I0, SIZE_WORD); // sext Rn, r0, WORD
2844 }
2845 else
2846 {
2847 scratch2 = (uint32_t)(int32_t)(int16_t) RW(scratch);
2848 UML_MOV(block, R32(Rn), scratch2); // mov Rn, scratch2
2849 }
2850
2851 if (!in_delay_slot)
2852 generate_update_cycles(block, compiler, desc->pc + 2, true);
2853 return true;
2854
2855 case 10: // BRA
2856 disp = ((int32_t)opcode << 20) >> 20;
2857 m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = pc+4 + disp*2 + 2
2858
2859 generate_delay_slot(block, compiler, desc, m_sh2_state->ea-2);
2860
2861 generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles>
2862 UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // hashjmp m_sh2_state->ea
2863 return true;
2864
2865 case 11: // BSR
2866 // panicstr @ 403da22 relies on the delay slot clobbering the PR set by a BSR, so
2867 // do this before running the delay slot
2868 UML_ADD(block, mem(&m_sh2_state->pr), desc->pc, 4); // add m_pr, desc->pc, #4 (skip the current insn & delay slot)
2869
2870 disp = ((int32_t)opcode << 20) >> 20;
2871 m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = pc+4 + disp*2 + 2
2872
2873 generate_delay_slot(block, compiler, desc, m_sh2_state->ea-2);
2874
2875 generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles>
2876 UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // hashjmp m_sh2_state->ea
2877 return true;
2878
2879 case 12:
2880 return generate_group_12(block, compiler, desc, opcode, in_delay_slot, ovrpc);
2881
2882 case 13: // MOVLI
2883 if (ovrpc == 0xffffffff)
2884 {
2885 scratch = ((desc->pc + 4) & ~3) + ((opcode & 0xff) * 4);
2886 }
2887 else
2888 {
2889 scratch = ((ovrpc + 4) & ~3) + ((opcode & 0xff) * 4);
2890 }
2891
2892 if (m_drcoptions & SH2DRC_STRICT_PCREL)
2893 {
2894 UML_MOV(block, I0, scratch); // mov r0, scratch
2895 UML_CALLH(block, *m_read32); // read32(r0, r1)
2896 UML_MOV(block, R32(Rn), I0); // mov Rn, r0
2897 }
2898 else
2899 {
2900 scratch2 = RL(scratch);
2901 UML_MOV(block, R32(Rn), scratch2); // mov Rn, scratch2
2902 }
2903
2904 if (!in_delay_slot)
2905 generate_update_cycles(block, compiler, desc->pc + 2, true);
2906 return true;
2907
2908 case 14: // MOVI
2909 scratch = opcode & 0xff;
2910 scratch2 = (uint32_t)(int32_t)(int16_t)(int8_t)scratch;
2911 UML_MOV(block, R32(Rn), scratch2);
2912 return true;
2913
2914 case 15:
2915 return generate_group_15(block, compiler, desc, opcode, in_delay_slot, ovrpc);
2916 }
2917
2918 return false;
2919 }
2920
generate_group_15(drcuml_block & block,compiler_state & compiler,const opcode_desc * desc,uint16_t opcode,int in_delay_slot,uint32_t ovrpc)2921 bool sh_common_execution::generate_group_15(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
2922 {
2923 // no ops here on sh1/2
2924 return false;
2925 }
2926
generate_group_2(drcuml_block & block,compiler_state & compiler,const opcode_desc * desc,uint16_t opcode,int in_delay_slot,uint32_t ovrpc)2927 bool sh_common_execution::generate_group_2(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
2928 {
2929 switch (opcode & 15)
2930 {
2931 case 0: // MOVBS(Rm, Rn);
2932 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
2933 UML_AND(block, I1, R32(Rm), 0xff); // and r1, Rm, 0xff
2934 UML_CALLH(block, *m_write8);
2935
2936 if (!in_delay_slot)
2937 generate_update_cycles(block, compiler, desc->pc + 2, true);
2938 return true;
2939
2940 case 1: // MOVWS(Rm, Rn);
2941 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
2942 UML_AND(block, I1, R32(Rm), 0xffff); // and r1, Rm, 0xffff
2943 UML_CALLH(block, *m_write16);
2944
2945 if (!in_delay_slot)
2946 generate_update_cycles(block, compiler, desc->pc + 2, true);
2947 return true;
2948
2949 case 2: // MOVLS(Rm, Rn);
2950 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
2951 UML_MOV(block, I1, R32(Rm)); // mov r1, Rm
2952 UML_CALLH(block, *m_write32);
2953
2954 if (!in_delay_slot)
2955 generate_update_cycles(block, compiler, desc->pc + 2, true);
2956 return true;
2957
2958 case 3:
2959 return false;
2960
2961 case 4: // MOVBM(Rm, Rn);
2962 UML_MOV(block, I1, R32(Rm)); // mov r1, Rm
2963 UML_SUB(block, R32(Rn), R32(Rn), 1); // sub Rn, Rn, 1
2964 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
2965 UML_CALLH(block, *m_write8); // call write8
2966
2967 if (!in_delay_slot)
2968 generate_update_cycles(block, compiler, desc->pc + 2, true);
2969 return true;
2970
2971 case 5: // MOVWM(Rm, Rn);
2972 UML_MOV(block, I1, R32(Rm)); // mov r1, Rm
2973 UML_SUB(block, R32(Rn), R32(Rn), 2); // sub Rn, Rn, 2
2974 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
2975 UML_CALLH(block, *m_write16); // call write16
2976
2977 if (!in_delay_slot)
2978 generate_update_cycles(block, compiler, desc->pc + 2, true);
2979 return true;
2980
2981 case 6: // MOVLM(Rm, Rn);
2982 UML_MOV(block, I1, R32(Rm)); // mov r1, Rm
2983 UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, 4
2984 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
2985 UML_CALLH(block, *m_write32); // call write32
2986
2987 if (!in_delay_slot)
2988 generate_update_cycles(block, compiler, desc->pc + 2, true);
2989 return true;
2990
2991 case 13: // XTRCT(Rm, Rn);
2992 UML_SHL(block, I0, R32(Rm), 16); // shl r0, Rm, #16
2993 UML_AND(block, I0, I0, 0xffff0000); // and r0, r0, #0xffff0000
2994
2995 UML_SHR(block, I1, R32(Rn), 16); // shr, r1, Rn, #16
2996 UML_AND(block, I1, I1, 0xffff); // and r1, r1, #0x0000ffff
2997
2998 UML_OR(block, R32(Rn), I0, I1); // or Rn, r0, r1
2999 return true;
3000
3001 case 7: // DIV0S(Rm, Rn);
3002 UML_MOV(block, I0, mem(&m_sh2_state->sr)); // move r0, sr
3003 UML_AND(block, I0, I0, ~(SH_Q|SH_M|SH_T)); // and r0, r0, ~(Q|M|T) (clear the Q,M, and T bits)
3004
3005 UML_TEST(block, R32(Rn), 0x80000000); // test Rn, #0x80000000
3006 UML_JMPc(block, COND_Z, compiler.labelnum); // jz labelnum
3007
3008 UML_OR(block, I0, I0, SH_Q); // or r0, r0, Q
3009 UML_LABEL(block, compiler.labelnum++); // labelnum:
3010
3011 UML_TEST(block, R32(Rm), 0x80000000); // test Rm, #0x80000000
3012 UML_JMPc(block, COND_Z, compiler.labelnum); // jz labelnum
3013
3014 UML_OR(block, I0, I0, SH_M); // or r0, r0, M
3015 UML_LABEL(block, compiler.labelnum++); // labelnum:
3016
3017 UML_XOR(block, I1, R32(Rn), R32(Rm)); // xor r1, Rn, Rm
3018 UML_TEST(block, I1, 0x80000000); // test r1, #0x80000000
3019 UML_JMPc(block, COND_Z, compiler.labelnum); // jz labelnum
3020
3021 UML_OR(block, I0, I0, SH_T); // or r0, r0, T
3022 UML_LABEL(block, compiler.labelnum++); // labelnum:
3023 UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov sr, r0
3024 return true;
3025
3026 case 8: // TST(Rm, Rn);
3027 UML_AND(block, I0, mem(&m_sh2_state->sr), ~SH_T); // and r0, sr, ~T (clear the T bit)
3028 UML_TEST(block, R32(Rm), R32(Rn)); // test Rm, Rn
3029 UML_JMPc(block, COND_NZ, compiler.labelnum); // jnz compiler.labelnum
3030
3031 UML_OR(block, I0, I0, SH_T); // or r0, r0, T
3032 UML_LABEL(block, compiler.labelnum++); // desc->pc:
3033
3034 UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov m_sh2_state->sr, r0
3035 return true;
3036
3037 case 12: // CMPSTR(Rm, Rn);
3038 UML_XOR(block, I0, R32(Rn), R32(Rm)); // xor r0, Rn, Rm (temp)
3039
3040 UML_SHR(block, I1, I0, 24); // shr r1, r0, #24 (HH)
3041 UML_AND(block, I1, I1, 0xff); // and r1, r1, #0xff
3042
3043 UML_SHR(block, I2, I0, 16); // shr r2, r0, #16 (HL)
3044 UML_AND(block, I2, I2, 0xff); // and r2, r2, #0xff
3045
3046 UML_SHR(block, I3, I0, 8); // shr r3, r0, #8 (LH)
3047 UML_AND(block, I3, I3, 0xff); // and r3, r3, #0xff
3048
3049 UML_AND(block, I7, I0, 0xff); // and r7, r0, #0xff (LL)
3050
3051 UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and sr, sr, ~T (clear the T bit)
3052
3053 UML_CMP(block, I1, 0); // cmp r1, #0
3054 UML_JMPc(block, COND_Z, compiler.labelnum); // jnz labelnum
3055 UML_CMP(block, I2, 0); // cmp r2, #0
3056 UML_JMPc(block, COND_Z, compiler.labelnum); // jnz labelnum
3057 UML_CMP(block, I3, 0); // cmp r3, #0
3058 UML_JMPc(block, COND_Z, compiler.labelnum); // jnz labelnum
3059 UML_CMP(block, I7, 0); // cmp r7, #0
3060 UML_JMPc(block, COND_NZ, compiler.labelnum+1); // jnz labelnum
3061
3062 UML_LABEL(block, compiler.labelnum++); // labelnum:
3063 UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), SH_T); // or sr, sr, T
3064
3065 UML_LABEL(block, compiler.labelnum++); // labelnum+1:
3066 return true;
3067
3068 case 9: // AND(Rm, Rn);
3069 UML_AND(block, R32(Rn), R32(Rn), R32(Rm)); // and Rn, Rn, Rm
3070 return true;
3071
3072 case 10: // XOR(Rm, Rn);
3073 UML_XOR(block, R32(Rn), R32(Rn), R32(Rm)); // xor Rn, Rn, Rm
3074 return true;
3075
3076 case 11: // OR(Rm, Rn);
3077 UML_OR(block, R32(Rn), R32(Rn), R32(Rm)); // or Rn, Rn, Rm
3078 return true;
3079
3080 case 14: // MULU(Rm, Rn);
3081 UML_AND(block, I0, R32(Rm), 0xffff); // and r0, Rm, 0xffff
3082 UML_AND(block, I1, R32(Rn), 0xffff); // and r1, Rn, 0xffff
3083 UML_MULU(block, mem(&m_sh2_state->macl), mem(&m_sh2_state->ea), I0, I1); // mulu macl, ea, r0, r1
3084 return true;
3085
3086 case 15: // MULS(Rm, Rn);
3087 UML_SEXT(block, I0, R32(Rm), SIZE_WORD); // sext r0, Rm
3088 UML_SEXT(block, I1, R32(Rn), SIZE_WORD); // sext r1, Rn
3089 UML_MULS(block, mem(&m_sh2_state->macl), mem(&m_sh2_state->ea), I0, I1); // muls macl, ea, r0, r1
3090 return true;
3091 }
3092
3093 return false;
3094 }
3095
3096
generate_group_3(drcuml_block & block,compiler_state & compiler,const opcode_desc * desc,uint16_t opcode,uint32_t ovrpc)3097 bool sh_common_execution::generate_group_3(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, uint32_t ovrpc)
3098 {
3099 switch (opcode & 15)
3100 {
3101 case 0: // CMPEQ(Rm, Rn); (equality)
3102 UML_CMP(block, R32(Rn), R32(Rm)); // cmp Rn, Rm
3103 UML_SETc(block, COND_E, I0); // set E, r0
3104 UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, 1); // rolins sr, r0, 0, 1
3105 return true;
3106
3107 case 2: // CMPHS(Rm, Rn); (unsigned greater than or equal)
3108 UML_CMP(block, R32(Rn), R32(Rm)); // cmp Rn, Rm
3109 UML_SETc(block, COND_AE, I0); // set AE, r0
3110 UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, 1); // rolins sr, r0, 0, 1
3111 return true;
3112
3113 case 3: // CMPGE(Rm, Rn); (signed greater than or equal)
3114 UML_CMP(block, R32(Rn), R32(Rm)); // cmp Rn, Rm
3115 UML_SETc(block, COND_GE, I0); // set GE, r0
3116 UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, 1); // rolins sr, r0, 0, 1
3117 return true;
3118
3119 case 6: // CMPHI(Rm, Rn); (unsigned greater than)
3120 UML_CMP(block, R32(Rn), R32(Rm)); // cmp Rn, Rm
3121 UML_SETc(block, COND_A, I0); // set A, r0
3122 UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, 1); // rolins sr, r0, 0, 1
3123 return true;
3124
3125 case 7: // CMPGT(Rm, Rn); (signed greater than)
3126 UML_CMP(block, R32(Rn), R32(Rm)); // cmp Rn, Rm
3127 UML_SETc(block, COND_G, I0); // set G, r0
3128 UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, 1); // rolins sr, r0, 0, 1
3129 return true;
3130
3131 case 1:
3132 case 9:
3133 return false;
3134
3135 case 4: // DIV1(Rm, Rn);
3136 save_fast_iregs(block);
3137 UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
3138 UML_CALLC(block, cfunc_DIV1, this);
3139 load_fast_iregs(block);
3140 return true;
3141
3142 case 5: // DMULU(Rm, Rn);
3143 if (m_cpu_type > CPU_TYPE_SH1)
3144 {
3145 UML_MULU(block, mem(&m_sh2_state->macl), mem(&m_sh2_state->mach), R32(Rn), R32(Rm));
3146 return true;
3147 }
3148 break;
3149
3150 case 13: // DMULS(Rm, Rn);
3151 if (m_cpu_type > CPU_TYPE_SH1)
3152 {
3153 UML_MULS(block, mem(&m_sh2_state->macl), mem(&m_sh2_state->mach), R32(Rn), R32(Rm));
3154 return true;
3155 }
3156 break;
3157
3158 case 8: // SUB(Rm, Rn);
3159 UML_SUB(block, R32(Rn), R32(Rn), R32(Rm)); // sub Rn, Rn, Rm
3160 return true;
3161
3162 case 12: // ADD(Rm, Rn);
3163 UML_ADD(block, R32(Rn), R32(Rn), R32(Rm)); // add Rn, Rn, Rm
3164 return true;
3165
3166 case 10: // SUBC(Rm, Rn);
3167 UML_CARRY(block, mem(&m_sh2_state->sr), 0); // carry = T (T is bit 0 of SR)
3168 UML_SUBB(block, R32(Rn), R32(Rn), R32(Rm)); // addc Rn, Rn, Rm
3169 UML_SETc(block, COND_C, I0); // setc i0, C
3170 UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins sr,i0,0,T
3171 return true;
3172
3173 case 11: // SUBV(Rm, Rn);
3174 save_fast_iregs(block);
3175 UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
3176 UML_CALLC(block, cfunc_SUBV, this);
3177 load_fast_iregs(block);
3178 return true;
3179
3180 case 14: // ADDC(Rm, Rn);
3181 UML_CARRY(block, mem(&m_sh2_state->sr), 0); // carry = T (T is bit 0 of SR)
3182 UML_ADDC(block, R32(Rn), R32(Rn), R32(Rm)); // addc Rn, Rn, Rm
3183 UML_SETc(block, COND_C, I0); // setc i0, C
3184 UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins sr,i0,0,T
3185 return true;
3186
3187 case 15: // ADDV(Rm, Rn);
3188 save_fast_iregs(block);
3189 UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
3190 UML_CALLC(block, cfunc_ADDV, this);
3191 load_fast_iregs(block);
3192 return true;
3193 }
3194 return false;
3195 }
3196
3197
generate_group_6(drcuml_block & block,compiler_state & compiler,const opcode_desc * desc,uint16_t opcode,int in_delay_slot,uint32_t ovrpc)3198 bool sh_common_execution::generate_group_6(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
3199 {
3200 switch (opcode & 15)
3201 {
3202 case 0: // MOVBL(Rm, Rn);
3203 UML_MOV(block, I0, R32(Rm)); // mov r0, Rm
3204 SETEA(0); // debug: ea = r0
3205 UML_CALLH(block, *m_read8); // call read8
3206 UML_SEXT(block, R32(Rn), I0, SIZE_BYTE); // sext Rn, r0, BYTE
3207
3208 if (!in_delay_slot)
3209 generate_update_cycles(block, compiler, desc->pc + 2, true);
3210 return true;
3211
3212 case 1: // MOVWL(Rm, Rn);
3213 UML_MOV(block, I0, R32(Rm)); // mov r0, Rm
3214 SETEA(0); // debug: ea = r0
3215 UML_CALLH(block, *m_read16); // call read16
3216 UML_SEXT(block, R32(Rn), I0, SIZE_WORD); // sext Rn, r0, WORD
3217
3218 if (!in_delay_slot)
3219 generate_update_cycles(block, compiler, desc->pc + 2, true);
3220 return true;
3221
3222 case 2: // MOVLL(Rm, Rn);
3223 UML_MOV(block, I0, R32(Rm)); // mov r0, Rm
3224 SETEA(0); // debug: ea = r0
3225 UML_CALLH(block, *m_read32); // call read32
3226 UML_MOV(block, R32(Rn), I0); // mov Rn, r0
3227
3228 if (!in_delay_slot)
3229 generate_update_cycles(block, compiler, desc->pc + 2, true);
3230 return true;
3231
3232 case 3: // MOV(Rm, Rn);
3233 UML_MOV(block, R32(Rn), R32(Rm)); // mov Rn, Rm
3234 return true;
3235
3236 case 7: // NOT(Rm, Rn);
3237 UML_XOR(block, R32(Rn), R32(Rm), 0xffffffff); // xor Rn, Rm, 0xffffffff
3238 return true;
3239
3240 case 9: // SWAPW(Rm, Rn);
3241 UML_ROL(block, R32(Rn), R32(Rm), 16); // rol Rn, Rm, 16
3242 return true;
3243
3244 case 11: // NEG(Rm, Rn);
3245 UML_SUB(block, R32(Rn), 0, R32(Rm)); // sub Rn, 0, Rm
3246 return true;
3247
3248 case 12: // EXTUB(Rm, Rn);
3249 UML_AND(block, R32(Rn), R32(Rm), 0x000000ff); // and Rn, Rm, 0xff
3250 return true;
3251
3252 case 13: // EXTUW(Rm, Rn);
3253 UML_AND(block, R32(Rn), R32(Rm), 0x0000ffff); // and Rn, Rm, 0xffff
3254 return true;
3255
3256 case 14: // EXTSB(Rm, Rn);
3257 UML_SEXT(block, R32(Rn), R32(Rm), SIZE_BYTE); // sext Rn, Rm, BYTE
3258 return true;
3259
3260 case 15: // EXTSW(Rm, Rn);
3261 UML_SEXT(block, R32(Rn), R32(Rm), SIZE_WORD); // sext Rn, Rm, WORD
3262 return true;
3263
3264 case 4: // MOVBP(Rm, Rn);
3265 UML_MOV(block, I0, R32(Rm)); // mov r0, Rm
3266 UML_CALLH(block, *m_read8); // call read8
3267 UML_SEXT(block, R32(Rn), I0, SIZE_BYTE); // sext Rn, r0, BYTE
3268
3269 if (Rm != Rn)
3270 UML_ADD(block, R32(Rm), R32(Rm), 1); // add Rm, Rm, #1
3271
3272 if (!in_delay_slot)
3273 generate_update_cycles(block, compiler, desc->pc + 2, true);
3274 return true;
3275
3276 case 5: // MOVWP(Rm, Rn);
3277 UML_MOV(block, I0, R32(Rm)); // mov r0, Rm
3278 UML_CALLH(block, *m_read16); // call read16
3279 UML_SEXT(block, R32(Rn), I0, SIZE_WORD); // sext Rn, r0, WORD
3280
3281 if (Rm != Rn)
3282 UML_ADD(block, R32(Rm), R32(Rm), 2); // add Rm, Rm, #2
3283
3284 if (!in_delay_slot)
3285 generate_update_cycles(block, compiler, desc->pc + 2, true);
3286 return true;
3287
3288 case 6: // MOVLP(Rm, Rn);
3289 UML_MOV(block, I0, R32(Rm)); // mov r0, Rm
3290 UML_CALLH(block, *m_read32); // call read32
3291 UML_MOV(block, R32(Rn), I0); // mov Rn, r0
3292
3293 if (Rm != Rn)
3294 UML_ADD(block, R32(Rm), R32(Rm), 4); // add Rm, Rm, #4
3295
3296 if (!in_delay_slot)
3297 generate_update_cycles(block, compiler, desc->pc + 2, true);
3298 return true;
3299
3300 case 8: // SWAPB(Rm, Rn);
3301 UML_AND(block, I0, R32(Rm), 0xffff0000); // and r0, Rm, #0xffff0000
3302 UML_AND(block, I1, R32(Rm), 0x000000ff); // and r0, Rm, #0x000000ff
3303 UML_AND(block, I2, R32(Rm), 0x0000ff00); // and r0, Rm, #0x0000ff00
3304 UML_SHL(block, I1, I1, 8); // shl r1, r1, #8
3305 UML_SHR(block, I2, I2, 8); // shr r2, r2, #8
3306 UML_OR(block, I0, I0, I1); // or r0, r0, r1
3307 UML_OR(block, R32(Rn), I0, I2); // or Rn, r0, r2
3308 return true;
3309
3310 case 10: // NEGC(Rm, Rn);
3311 UML_MOV(block, I0, mem(&m_sh2_state->sr)); // mov r0, sr (save SR)
3312 UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and sr, sr, ~T (clear the T bit)
3313 UML_CARRY(block, I0, 0); // carry = T (T is bit 0 of SR)
3314 UML_SUBB(block, R32(Rn), 0, R32(Rm)); // subb Rn, #0, Rm
3315
3316 UML_JMPc(block, COND_NC, compiler.labelnum); // jnc labelnum
3317
3318 UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), SH_T); // or sr, sr, T
3319
3320 UML_LABEL(block, compiler.labelnum++); // labelnum:
3321
3322 return true;
3323 }
3324
3325 return false;
3326 }
3327
generate_group_8(drcuml_block & block,compiler_state & compiler,const opcode_desc * desc,uint16_t opcode,int in_delay_slot,uint32_t ovrpc)3328 bool sh_common_execution::generate_group_8(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
3329 {
3330 int32_t disp;
3331 uint32_t udisp;
3332 uml::code_label templabel;
3333
3334 switch ( opcode & (15<<8) )
3335 {
3336 case 0 << 8: // MOVBS4(opcode & 0x0f, Rm);
3337 udisp = (opcode & 0x0f);
3338 UML_ADD(block, I0, R32(Rm), udisp); // add r0, Rm, udisp
3339 UML_MOV(block, I1, R32(0)); // mov r1, R0
3340 UML_CALLH(block, *m_write8); // call write8
3341
3342 if (!in_delay_slot)
3343 generate_update_cycles(block, compiler, desc->pc + 2, true);
3344 return true;
3345
3346 case 1 << 8: // MOVWS4(opcode & 0x0f, Rm);
3347 udisp = (opcode & 0x0f) * 2;
3348 UML_ADD(block, I0, R32(Rm), udisp); // add r0, Rm, udisp
3349 UML_MOV(block, I1, R32(0)); // mov r1, R0
3350 UML_CALLH(block, *m_write16); // call write16
3351
3352 if (!in_delay_slot)
3353 generate_update_cycles(block, compiler, desc->pc + 2, true);
3354 return true;
3355
3356 case 2<< 8:
3357 case 3<< 8:
3358 case 6<< 8:
3359 case 7<< 8:
3360 case 10<< 8:
3361 case 12<< 8:
3362 case 14<< 8:
3363 return false;
3364
3365 case 4<< 8: // MOVBL4(Rm, opcode & 0x0f);
3366 udisp = opcode & 0x0f;
3367 UML_ADD(block, I0, R32(Rm), udisp); // add r0, Rm, udisp
3368 SETEA(0);
3369 UML_CALLH(block, *m_read8); // call read8
3370 UML_SEXT(block, R32(0), I0, SIZE_BYTE); // sext R0, r0, BYTE
3371
3372 if (!in_delay_slot)
3373 generate_update_cycles(block, compiler, desc->pc + 2, true);
3374 return true;
3375
3376 case 5<< 8: // MOVWL4(Rm, opcode & 0x0f);
3377 udisp = (opcode & 0x0f)*2;
3378 UML_ADD(block, I0, R32(Rm), udisp); // add r0, Rm, udisp
3379 SETEA(0);
3380 UML_CALLH(block, *m_read16); // call read16
3381 UML_SEXT(block, R32(0), I0, SIZE_WORD); // sext R0, r0, WORD
3382
3383 if (!in_delay_slot)
3384 generate_update_cycles(block, compiler, desc->pc + 2, true);
3385 return true;
3386
3387 case 8<< 8: // CMPIM(opcode & 0xff);
3388 UML_AND(block, I0, mem(&m_sh2_state->sr), ~SH_T); // and r0, sr, ~T (clear the T bit)
3389
3390 UML_SEXT(block, I1, opcode&0xff, SIZE_BYTE); // sext r1, opcode&0xff, BYTE
3391 UML_CMP(block, I1, R32(0)); // cmp r1, R0
3392 UML_JMPc(block, COND_NZ, compiler.labelnum); // jnz compiler.labelnum (if negative)
3393
3394 UML_OR(block, I0, I0, SH_T); // or r0, r0, T
3395
3396 UML_LABEL(block, compiler.labelnum++); // labelnum:
3397 UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov m_sh2_state->sr, r0
3398 return true;
3399
3400 case 9<< 8: // BT(opcode & 0xff);
3401 UML_TEST(block, mem(&m_sh2_state->sr), SH_T); // test m_sh2_state->sr, T
3402 UML_JMPc(block, COND_Z, compiler.labelnum); // jz compiler.labelnum
3403
3404 disp = ((int32_t)opcode << 24) >> 24;
3405 m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = destination
3406
3407 generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles>
3408 UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // jmp m_sh2_state->ea
3409
3410 UML_LABEL(block, compiler.labelnum++); // labelnum:
3411 return true;
3412
3413 case 11<< 8: // BF(opcode & 0xff);
3414 UML_TEST(block, mem(&m_sh2_state->sr), SH_T); // test m_sh2_state->sr, T
3415 UML_JMPc(block, COND_NZ, compiler.labelnum); // jnz compiler.labelnum
3416
3417 disp = ((int32_t)opcode << 24) >> 24;
3418 m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = destination
3419
3420 generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles>
3421 UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // jmp m_sh2_state->ea
3422
3423 UML_LABEL(block, compiler.labelnum++); // labelnum:
3424 return true;
3425
3426 case 13<< 8: // BTS(opcode & 0xff);
3427 if (m_cpu_type > CPU_TYPE_SH1)
3428 {
3429 UML_TEST(block, mem(&m_sh2_state->sr), SH_T); // test m_sh2_state->sr, T
3430 UML_JMPc(block, COND_Z, compiler.labelnum); // jz compiler.labelnum
3431
3432 disp = ((int32_t)opcode << 24) >> 24;
3433 m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = destination
3434
3435 templabel = compiler.labelnum; // save our label
3436 compiler.labelnum++; // make sure the delay slot doesn't use it
3437 generate_delay_slot(block, compiler, desc, m_sh2_state->ea-2);
3438
3439 generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles>
3440 UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // jmp m_sh2_state->ea
3441
3442 UML_LABEL(block, templabel); // labelnum:
3443 return true;
3444 }
3445 break;
3446
3447 case 15<< 8: // BFS(opcode & 0xff);
3448 if (m_cpu_type > CPU_TYPE_SH1)
3449 {
3450 UML_TEST(block, mem(&m_sh2_state->sr), SH_T); // test m_sh2_state->sr, T
3451 UML_JMPc(block, COND_NZ, compiler.labelnum); // jnz compiler.labelnum
3452
3453 disp = ((int32_t)opcode << 24) >> 24;
3454 m_sh2_state->ea = (desc->pc + 2) + disp * 2 + 2; // m_sh2_state->ea = destination
3455
3456 templabel = compiler.labelnum; // save our label
3457 compiler.labelnum++; // make sure the delay slot doesn't use it
3458 generate_delay_slot(block, compiler, desc, m_sh2_state->ea-2); // delay slot only if the branch is taken
3459
3460 generate_update_cycles(block, compiler, m_sh2_state->ea, true); // <subtract cycles>
3461 UML_HASHJMP(block, 0, m_sh2_state->ea, *m_nocode); // jmp m_sh2_state->ea
3462
3463 UML_LABEL(block, templabel); // labelnum:
3464 return true;
3465 }
3466 break;
3467 }
3468
3469 return false;
3470 }
3471
generate_group_12_TRAPA(drcuml_block & block,compiler_state & compiler,const opcode_desc * desc,uint16_t opcode,int in_delay_slot,uint32_t ovrpc)3472 bool sh_common_execution::generate_group_12_TRAPA(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
3473 {
3474 uint32_t scratch = (opcode & 0xff) * 4;
3475 UML_ADD(block, mem(&m_sh2_state->ea), mem(&m_sh2_state->vbr), scratch); // add ea, vbr, scratch
3476
3477 UML_SUB(block, R32(15), R32(15), 4); // sub R15, R15, #4
3478 UML_MOV(block, I0, R32(15)); // mov r0, R15
3479 UML_MOV(block, I1, mem(&m_sh2_state->sr)); // mov r1, sr
3480 UML_CALLH(block, *m_write32); // write32
3481
3482 UML_SUB(block, R32(15), R32(15), 4); // sub R15, R15, #4
3483 UML_MOV(block, I0, R32(15)); // mov r0, R15
3484 UML_MOV(block, I1, desc->pc + 2); // mov r1, pc+2
3485 UML_CALLH(block, *m_write32); // write32
3486
3487 UML_MOV(block, I0, mem(&m_sh2_state->ea)); // mov r0, ea
3488 UML_CALLH(block, *m_read32); // read32
3489 UML_HASHJMP(block, 0, I0, *m_nocode); // jmp (r0)
3490
3491 return true;
3492 }
3493
generate_group_12(drcuml_block & block,compiler_state & compiler,const opcode_desc * desc,uint16_t opcode,int in_delay_slot,uint32_t ovrpc)3494 bool sh_common_execution::generate_group_12(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
3495 {
3496 uint32_t scratch;
3497
3498 switch (opcode & (15<<8))
3499 {
3500 case 0<<8: // MOVBSG(opcode & 0xff);
3501 scratch = (opcode & 0xff);
3502 UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch
3503 UML_AND(block, I1, R32(0), 0xff); // and r1, R0, 0xff
3504 UML_CALLH(block, *m_write8); // call write8
3505
3506 if (!in_delay_slot)
3507 generate_update_cycles(block, compiler, desc->pc + 2, true);
3508 return true;
3509
3510 case 1<<8: // MOVWSG(opcode & 0xff);
3511 scratch = (opcode & 0xff) * 2;
3512 UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch
3513 UML_AND(block, I1, R32(0), 0xffff); // and r1, R0, 0xffff
3514 UML_CALLH(block, *m_write16); // call write16
3515
3516 if (!in_delay_slot)
3517 generate_update_cycles(block, compiler, desc->pc + 2, true);
3518 return true;
3519
3520 case 2<<8: // MOVLSG(opcode & 0xff);
3521 scratch = (opcode & 0xff) * 4;
3522 UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch
3523 UML_MOV(block, I1, R32(0)); // mov r1, R0
3524 UML_CALLH(block, *m_write32); // call write32
3525
3526 if (!in_delay_slot)
3527 generate_update_cycles(block, compiler, desc->pc + 2, true);
3528 return true;
3529
3530 case 3<<8: // TRAPA(opcode & 0xff);
3531 return generate_group_12_TRAPA(block, compiler, desc, opcode, in_delay_slot, ovrpc);
3532
3533 case 4<<8: // MOVBLG(opcode & 0xff);
3534 scratch = (opcode & 0xff);
3535 UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch
3536 UML_CALLH(block, *m_read8); // call read16
3537 UML_SEXT(block, R32(0), I0, SIZE_BYTE); // sext R0, r0, BYTE
3538
3539 if (!in_delay_slot)
3540 generate_update_cycles(block, compiler, desc->pc + 2, true);
3541 return true;
3542
3543 case 5<<8: // MOVWLG(opcode & 0xff);
3544 scratch = (opcode & 0xff) * 2;
3545 UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch
3546 UML_CALLH(block, *m_read16); // call read16
3547 UML_SEXT(block, R32(0), I0, SIZE_WORD); // sext R0, r0, WORD
3548
3549 if (!in_delay_slot)
3550 generate_update_cycles(block, compiler, desc->pc + 2, true);
3551 return true;
3552
3553 case 6<<8: // MOVLLG(opcode & 0xff);
3554 scratch = (opcode & 0xff) * 4;
3555 UML_ADD(block, I0, mem(&m_sh2_state->gbr), scratch); // add r0, gbr, scratch
3556 UML_CALLH(block, *m_read32); // call read32
3557 UML_MOV(block, R32(0), I0); // mov R0, r0
3558
3559 if (!in_delay_slot)
3560 generate_update_cycles(block, compiler, desc->pc + 2, true);
3561 return true;
3562
3563 case 7<<8: // MOVA(opcode & 0xff);
3564 scratch = (opcode & 0xff) * 4;
3565 scratch += ((desc->pc + 4) & ~3);
3566
3567 UML_MOV(block, R32(0), scratch); // mov R0, scratch
3568 return true;
3569
3570 case 8<<8: // TSTI(opcode & 0xff);
3571 scratch = opcode & 0xff;
3572
3573 UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and sr, sr, ~T (clear the T bit)
3574 UML_AND(block, I0, R32(0), scratch); // and r0, R0, scratch
3575 UML_CMP(block, I0, 0); // cmp r0, #0
3576 UML_JMPc(block, COND_NZ, compiler.labelnum); // jnz labelnum
3577
3578 UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), SH_T); // or sr, sr, T
3579
3580 UML_LABEL(block, compiler.labelnum++); // labelnum:
3581 return true;
3582
3583 case 9<<8: // ANDI(opcode & 0xff);
3584 UML_AND(block, R32(0), R32(0), opcode & 0xff); // and r0, r0, opcode & 0xff
3585 return true;
3586
3587 case 10<<8: // XORI(opcode & 0xff);
3588 UML_XOR(block, R32(0), R32(0), opcode & 0xff); // xor r0, r0, opcode & 0xff
3589 return true;
3590
3591 case 11<<8: // ORI(opcode & 0xff);
3592 UML_OR(block, R32(0), R32(0), opcode & 0xff); // or r0, r0, opcode & 0xff
3593 return true;
3594
3595 case 12<<8: // TSTM(opcode & 0xff);
3596 UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and sr, sr, ~T (clear the T bit)
3597 UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr
3598 UML_CALLH(block, *m_read8); // read8
3599
3600 UML_AND(block, I0, I0, opcode & 0xff);
3601 UML_CMP(block, I0, 0); // cmp r0, #0
3602 UML_JMPc(block, COND_NZ, compiler.labelnum); // jnz labelnum
3603
3604 UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), SH_T); // or sr, sr, T
3605
3606 UML_LABEL(block, compiler.labelnum++); // labelnum:
3607 return true;
3608
3609 case 13<<8: // ANDM(opcode & 0xff);
3610 UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr
3611 UML_CALLH(block, *m_read8); // read8
3612
3613 UML_AND(block, I1, I0, opcode&0xff); // and r1, r0, #opcode&0xff
3614 UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr
3615 SETEA(0);
3616 UML_CALLH(block, *m_write8); // write8
3617 return true;
3618
3619 case 14<<8: // XORM(opcode & 0xff);
3620 UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr
3621 UML_CALLH(block, *m_read8); // read8
3622
3623 UML_XOR(block, I1, I0, opcode&0xff); // xor r1, r0, #opcode&0xff
3624 UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr
3625 SETEA(0);
3626 UML_CALLH(block, *m_write8); // write8
3627 return true;
3628
3629 case 15<<8: // ORM(opcode & 0xff);
3630 UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr
3631 UML_CALLH(block, *m_read8); // read8
3632
3633 UML_OR(block, I1, I0, opcode&0xff); // or r1, r0, #opcode&0xff
3634 UML_ADD(block, I0, R32(0), mem(&m_sh2_state->gbr)); // add r0, R0, gbr
3635 SETEA(0);
3636 UML_CALLH(block, *m_write8); // write8
3637 return true;
3638 }
3639
3640 return false;
3641 }
3642
generate_group_0_RTE(drcuml_block & block,compiler_state & compiler,const opcode_desc * desc,uint16_t opcode,int in_delay_slot,uint32_t ovrpc)3643 bool sh_common_execution::generate_group_0_RTE(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
3644 {
3645 generate_delay_slot(block, compiler, desc, 0xffffffff);
3646
3647 UML_MOV(block, I0, R32(15)); // mov r0, R15
3648 UML_CALLH(block, *m_read32); // call read32
3649 UML_MOV(block, mem(&m_sh2_state->pc), I0); // mov pc, r0
3650 UML_ADD(block, R32(15), R32(15), 4); // add R15, R15, #4
3651
3652 UML_MOV(block, I0, R32(15)); // mov r0, R15
3653 UML_CALLH(block, *m_read32); // call read32
3654 UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov sr, r0
3655 UML_ADD(block, R32(15), R32(15), 4); // add R15, R15, #4
3656
3657 compiler.checkints = true;
3658 UML_MOV(block, mem(&m_sh2_state->ea), mem(&m_sh2_state->pc)); // mov ea, pc
3659 generate_update_cycles(block, compiler, uml::mem(&m_sh2_state->ea), true); // <subtract cycles>
3660 UML_HASHJMP(block, 0, mem(&m_sh2_state->pc), *m_nocode); // and jump to the "resume PC"
3661
3662 return true;
3663 }
3664
3665
generate_group_0(drcuml_block & block,compiler_state & compiler,const opcode_desc * desc,uint16_t opcode,int in_delay_slot,uint32_t ovrpc)3666 bool sh_common_execution::generate_group_0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
3667 {
3668 switch (opcode & 0x3F)
3669 {
3670 case 0x00: // these are all illegal
3671 case 0x01:
3672 case 0x10:
3673 case 0x11:
3674 case 0x13:
3675 case 0x20:
3676 case 0x21:
3677 case 0x30:
3678 case 0x31:
3679 case 0x32:
3680 case 0x33:
3681 case 0x38:
3682 case 0x39:
3683 case 0x3a:
3684 case 0x3b:
3685 return false;
3686
3687 case 0x09: // NOP();
3688 return true;
3689
3690 case 0x02: // STCSR(Rn);
3691 UML_MOV(block, R32(Rn), mem(&m_sh2_state->sr));
3692 return true;
3693
3694 case 0x03: // BSRF(Rn);
3695 if (m_cpu_type > CPU_TYPE_SH1)
3696 {
3697 UML_ADD(block, mem(&m_sh2_state->target), R32(Rn), 4); // add target, Rm, #4
3698 UML_ADD(block, mem(&m_sh2_state->target), mem(&m_sh2_state->target), desc->pc); // add target, target, pc
3699
3700 // 32x Cosmic Carnage @ 6002cb0 relies on the delay slot
3701 // clobbering the calculated PR, so do it first
3702 UML_ADD(block, mem(&m_sh2_state->pr), desc->pc, 4); // add m_pr, desc->pc, #4 (skip the current insn & delay slot)
3703
3704 generate_delay_slot(block, compiler, desc, m_sh2_state->target);
3705
3706 generate_update_cycles(block, compiler, uml::mem(&m_sh2_state->target), true); // <subtract cycles>
3707 UML_HASHJMP(block, 0, mem(&m_sh2_state->target), *m_nocode); // jmp target
3708 return true;
3709 }
3710 break;
3711
3712 case 0x04: // MOVBS0(Rm, Rn);
3713 case 0x14: // MOVBS0(Rm, Rn);
3714 case 0x24: // MOVBS0(Rm, Rn);
3715 case 0x34: // MOVBS0(Rm, Rn);
3716 UML_ADD(block, I0, R32(0), R32(Rn)); // add r0, R0, Rn
3717 UML_AND(block, I1, R32(Rm), 0x000000ff); // and r1, Rm, 0xff
3718 UML_CALLH(block, *m_write8); // call write8
3719
3720 if (!in_delay_slot)
3721 generate_update_cycles(block, compiler, desc->pc + 2, true);
3722 return true;
3723
3724 case 0x05: // MOVWS0(Rm, Rn);
3725 case 0x15: // MOVWS0(Rm, Rn);
3726 case 0x25: // MOVWS0(Rm, Rn);
3727 case 0x35: // MOVWS0(Rm, Rn);
3728 UML_ADD(block, I0, R32(0), R32(Rn)); // add r0, R0, Rn
3729 UML_AND(block, I1, R32(Rm), 0x0000ffff); // and r1, Rm, 0xffff
3730 UML_CALLH(block, *m_write16); // call write16
3731
3732 if (!in_delay_slot)
3733 generate_update_cycles(block, compiler, desc->pc + 2, true);
3734 return true;
3735
3736 case 0x06: // MOVLS0(Rm, Rn);
3737 case 0x16: // MOVLS0(Rm, Rn);
3738 case 0x26: // MOVLS0(Rm, Rn);
3739 case 0x36: // MOVLS0(Rm, Rn);
3740 UML_ADD(block, I0, R32(0), R32(Rn)); // add r0, R0, Rn
3741 UML_MOV(block, I1, R32(Rm)); // mov r1, Rm
3742 UML_CALLH(block, *m_write32); // call write32
3743
3744 if (!in_delay_slot)
3745 generate_update_cycles(block, compiler, desc->pc + 2, true);
3746 return true;
3747
3748 case 0x07: // MULL(Rm, Rn);
3749 case 0x17: // MULL(Rm, Rn);
3750 case 0x27: // MULL(Rm, Rn);
3751 case 0x37: // MULL(Rm, Rn);
3752 if (m_cpu_type > CPU_TYPE_SH1)
3753 {
3754 UML_MULU(block, mem(&m_sh2_state->macl), mem(&m_sh2_state->ea), R32(Rn), R32(Rm)); // mulu macl, ea, Rn, Rm
3755 return true;
3756 }
3757 break;
3758
3759 case 0x08: // CLRT();
3760 UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and r0, sr, ~T (clear the T bit)
3761 return true;
3762
3763 case 0x0a: // STSMACH(Rn);
3764 UML_MOV(block, R32(Rn), mem(&m_sh2_state->mach)); // mov Rn, mach
3765 return true;
3766
3767 case 0x0b: // RTS();
3768 UML_MOV(block, mem(&m_sh2_state->target), mem(&m_sh2_state->pr)); // mov target, pr (in case of d-slot shenanigans)
3769
3770 generate_delay_slot(block, compiler, desc, m_sh2_state->target);
3771
3772 generate_update_cycles(block, compiler, uml::mem(&m_sh2_state->target), true); // <subtract cycles>
3773 UML_HASHJMP(block, 0, mem(&m_sh2_state->target), *m_nocode);
3774 return true;
3775
3776 case 0x0c: // MOVBL0(Rm, Rn);
3777 case 0x1c: // MOVBL0(Rm, Rn);
3778 case 0x2c: // MOVBL0(Rm, Rn);
3779 case 0x3c: // MOVBL0(Rm, Rn);
3780 UML_ADD(block, I0, R32(0), R32(Rm)); // add r0, R0, Rm
3781 UML_CALLH(block, *m_read8); // call read8
3782 UML_SEXT(block, R32(Rn), I0, SIZE_BYTE); // sext Rn, r0, BYTE
3783
3784 if (!in_delay_slot)
3785 generate_update_cycles(block, compiler, desc->pc + 2, true);
3786 return true;
3787
3788 case 0x0d: // MOVWL0(Rm, Rn);
3789 case 0x1d: // MOVWL0(Rm, Rn);
3790 case 0x2d: // MOVWL0(Rm, Rn);
3791 case 0x3d: // MOVWL0(Rm, Rn);
3792 UML_ADD(block, I0, R32(0), R32(Rm)); // add r0, R0, Rm
3793 UML_CALLH(block, *m_read16); // call read16
3794 UML_SEXT(block, R32(Rn), I0, SIZE_WORD); // sext Rn, r0, WORD
3795
3796 if (!in_delay_slot)
3797 generate_update_cycles(block, compiler, desc->pc + 2, true);
3798 return true;
3799
3800 case 0x0e: // MOVLL0(Rm, Rn);
3801 case 0x1e: // MOVLL0(Rm, Rn);
3802 case 0x2e: // MOVLL0(Rm, Rn);
3803 case 0x3e: // MOVLL0(Rm, Rn);
3804 UML_ADD(block, I0, R32(0), R32(Rm)); // add r0, R0, Rm
3805 UML_CALLH(block, *m_read32); // call read32
3806 UML_MOV(block, R32(Rn), I0); // mov Rn, r0
3807
3808 if (!in_delay_slot)
3809 generate_update_cycles(block, compiler, desc->pc + 2, true);
3810 return true;
3811
3812 case 0x0f: // MAC_L(Rm, Rn);
3813 case 0x1f: // MAC_L(Rm, Rn);
3814 case 0x2f: // MAC_L(Rm, Rn);
3815 case 0x3f: // MAC_L(Rm, Rn);
3816 if (m_cpu_type > CPU_TYPE_SH1)
3817 {
3818 save_fast_iregs(block);
3819 UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
3820 UML_CALLC(block, cfunc_MAC_L, this);
3821 load_fast_iregs(block);
3822 return true;
3823 }
3824 break;
3825
3826 case 0x12: // STCGBR(Rn);
3827 UML_MOV(block, R32(Rn), mem(&m_sh2_state->gbr)); // mov Rn, gbr
3828 return true;
3829
3830 case 0x18: // SETT();
3831 UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), SH_T); // or sr, sr, T
3832 return true;
3833
3834 case 0x19: // DIV0U();
3835 UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~(SH_M|SH_Q|SH_T)); // and sr, sr, ~(M|Q|T)
3836 return true;
3837
3838 case 0x1a: // STSMACL(Rn);
3839 UML_MOV(block, R32(Rn), mem(&m_sh2_state->macl)); // mov Rn, macl
3840 return true;
3841
3842 case 0x1b: // SLEEP();
3843 UML_MOV(block, I0, mem(&m_sh2_state->sleep_mode)); // mov i0, sleep_mode
3844 UML_CMP(block, I0, 0x2); // cmp i0, #2
3845 UML_JMPc(block, COND_E, compiler.labelnum); // beq labelnum
3846 // sleep mode != 2
3847 UML_MOV(block, mem(&m_sh2_state->sleep_mode), 0x1); // mov sleep_mode, #1
3848 generate_update_cycles(block, compiler, desc->pc, true); // repeat this insn
3849 UML_JMP(block, compiler.labelnum+1); // jmp labelnum+1
3850
3851 UML_LABEL(block, compiler.labelnum++); // labelnum:
3852 // sleep_mode == 2
3853 UML_MOV(block, mem(&m_sh2_state->sleep_mode), 0x0); // sleep_mode = 0
3854 generate_update_cycles(block, compiler, desc->pc+2, true); // go to next insn
3855
3856 UML_LABEL(block, compiler.labelnum++); // labelnum+1:
3857 return true;
3858
3859 case 0x22: // STCVBR(Rn);
3860 UML_MOV(block, R32(Rn), mem(&m_sh2_state->vbr)); // mov Rn, vbr
3861 return true;
3862
3863 case 0x23: // BRAF(Rn);
3864 if (m_cpu_type > CPU_TYPE_SH1)
3865 {
3866 UML_ADD(block, mem(&m_sh2_state->target), R32(Rn), desc->pc+4); // add target, Rn, pc+4
3867
3868 generate_delay_slot(block, compiler, desc, m_sh2_state->target);
3869
3870 generate_update_cycles(block, compiler, uml::mem(&m_sh2_state->target), true); // <subtract cycles>
3871 UML_HASHJMP(block, 0, mem(&m_sh2_state->target), *m_nocode); // jmp target
3872 return true;
3873 }
3874 break;
3875
3876 case 0x28: // CLRMAC();
3877 UML_MOV(block, mem(&m_sh2_state->macl), 0); // mov macl, #0
3878 UML_MOV(block, mem(&m_sh2_state->mach), 0); // mov mach, #0
3879 return true;
3880
3881 case 0x29: // MOVT(Rn);
3882 UML_AND(block, R32(Rn), mem(&m_sh2_state->sr), SH_T); // and Rn, sr, T
3883 return true;
3884
3885 case 0x2a: // STSPR(Rn);
3886 UML_MOV(block, R32(Rn), mem(&m_sh2_state->pr)); // mov Rn, pr
3887 return true;
3888
3889 case 0x2b: // RTE();
3890 return generate_group_0_RTE(block, compiler, desc, opcode, in_delay_slot, ovrpc);
3891 }
3892
3893 return false;
3894 }
3895
generate_group_4_LDCSR(drcuml_block & block,compiler_state & compiler,const opcode_desc * desc,uint16_t opcode,int in_delay_slot,uint32_t ovrpc)3896 bool sh_common_execution::generate_group_4_LDCSR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
3897 {
3898 // needs to be different on SH2 / 4
3899 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
3900 UML_AND(block, I0, I0, SH_FLAGS); // and r0, r0, FLAGS
3901 UML_MOV(block, mem(&m_sh2_state->sr), I0);
3902
3903 compiler.checkints = true;
3904 return true;
3905 }
3906
generate_group_4_LDCMSR(drcuml_block & block,compiler_state & compiler,const opcode_desc * desc,uint16_t opcode,int in_delay_slot,uint32_t ovrpc)3907 bool sh_common_execution::generate_group_4_LDCMSR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
3908 {
3909 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
3910 SETEA(0);
3911 UML_CALLH(block, *m_read32); // call read32
3912 UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, #4
3913 UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov sr, r0
3914
3915 compiler.checkints = true;
3916 if (!in_delay_slot)
3917 generate_update_cycles(block, compiler, desc->pc + 2, true);
3918 return true;
3919 }
3920
generate_group_4(drcuml_block & block,compiler_state & compiler,const opcode_desc * desc,uint16_t opcode,int in_delay_slot,uint32_t ovrpc)3921 bool sh_common_execution::generate_group_4(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
3922 {
3923 switch (opcode & 0x3F)
3924 {
3925 case 0x00: // SHLL(Rn);
3926 UML_SHL(block, R32(Rn), R32(Rn), 1); // shl Rn, Rn, 1
3927 UML_SETc(block, COND_C, I0); // set i0,C
3928 UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins [sr],i0,0,T
3929 return true;
3930
3931 case 0x01: // SHLR(Rn);
3932 UML_SHR(block, R32(Rn), R32(Rn), 1); // shr Rn, Rn, 1
3933 UML_SETc(block, COND_C, I0); // set i0,C
3934 UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins [sr],i0,0,T
3935 return true;
3936
3937 case 0x04: // ROTL(Rn);
3938 UML_ROL(block, R32(Rn), R32(Rn), 1); // rol Rn, Rn, 1
3939 UML_SETc(block, COND_C, I0); // set i0,C
3940 UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins [sr],i0,0,T
3941 return true;
3942
3943 case 0x05: // ROTR(Rn);
3944 UML_ROR(block, R32(Rn), R32(Rn), 1); // ror Rn, Rn, 1
3945 UML_SETc(block, COND_C, I0); // set i0,C
3946 UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins [sr],i0,0,T
3947 return true;
3948
3949 case 0x02: // STSMMACH(Rn);
3950 UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, #4
3951 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
3952 UML_MOV(block, I1, mem(&m_sh2_state->mach)); // mov r1, mach
3953 SETEA(0); // set ea for debug
3954 UML_CALLH(block, *m_write32); // call write32
3955
3956 if (!in_delay_slot)
3957 generate_update_cycles(block, compiler, desc->pc + 2, true);
3958 return true;
3959
3960 case 0x03: // STCMSR(Rn);
3961 UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, #4
3962 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
3963 UML_MOV(block, I1, mem(&m_sh2_state->sr)); // mov r1, sr
3964 SETEA(0); // set ea for debug
3965 UML_CALLH(block, *m_write32); // call write32
3966
3967 if (!in_delay_slot)
3968 generate_update_cycles(block, compiler, desc->pc + 2, true);
3969 return true;
3970
3971 case 0x06: // LDSMMACH(Rn);
3972 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
3973 SETEA(0);
3974 UML_CALLH(block, *m_read32); // call read32
3975 UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, #4
3976 UML_MOV(block, mem(&m_sh2_state->mach), I0); // mov mach, r0
3977
3978 if (!in_delay_slot)
3979 generate_update_cycles(block, compiler, desc->pc + 2, true);
3980 return true;
3981
3982 case 0x07: // LDCMSR(Rn);
3983 return generate_group_4_LDCMSR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
3984
3985 case 0x08: // SHLL2(Rn);
3986 UML_SHL(block, R32(Rn), R32(Rn), 2);
3987 return true;
3988
3989 case 0x09: // SHLR2(Rn);
3990 UML_SHR(block, R32(Rn), R32(Rn), 2);
3991 return true;
3992
3993 case 0x18: // SHLL8(Rn);
3994 UML_SHL(block, R32(Rn), R32(Rn), 8);
3995 return true;
3996
3997 case 0x19: // SHLR8(Rn);
3998 UML_SHR(block, R32(Rn), R32(Rn), 8);
3999 return true;
4000
4001 case 0x28: // SHLL16(Rn);
4002 UML_SHL(block, R32(Rn), R32(Rn), 16);
4003 return true;
4004
4005 case 0x29: // SHLR16(Rn);
4006 UML_SHR(block, R32(Rn), R32(Rn), 16);
4007 return true;
4008
4009 case 0x0a: // LDSMACH(Rn);
4010 UML_MOV(block, mem(&m_sh2_state->mach), R32(Rn)); // mov mach, Rn
4011 return true;
4012
4013 case 0x0b: // JSR(Rn);
4014 UML_MOV(block, mem(&m_sh2_state->target), R32(Rn)); // mov target, Rn
4015
4016 UML_ADD(block, mem(&m_sh2_state->pr), desc->pc, 4); // add m_pr, desc->pc, #4 (skip the current insn & delay slot)
4017
4018 generate_delay_slot(block, compiler, desc, m_sh2_state->target-4);
4019
4020 generate_update_cycles(block, compiler, uml::mem(&m_sh2_state->target), true); // <subtract cycles>
4021 UML_HASHJMP(block, 0, mem(&m_sh2_state->target), *m_nocode); // and do the jump
4022 return true;
4023
4024 case 0x0e: // LDCSR(Rn);
4025 return generate_group_4_LDCSR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
4026
4027 case 0x0f: // MAC_W(Rm, Rn);
4028 case 0x1f: // MAC_W(Rm, Rn);
4029 case 0x2f: // MAC_W(Rm, Rn);
4030 case 0x3f: // MAC_W(Rm, Rn);
4031 save_fast_iregs(block);
4032 UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
4033 UML_CALLC(block, cfunc_MAC_W, this);
4034 load_fast_iregs(block);
4035 return true;
4036
4037 case 0x10: // DT(Rn);
4038 if (m_cpu_type > CPU_TYPE_SH1)
4039 {
4040 UML_AND(block, I0, mem(&m_sh2_state->sr), ~SH_T); // and r0, sr, ~T (clear the T bit)
4041 UML_SUB(block, R32(Rn), R32(Rn), 1); // sub Rn, Rn, 1
4042 UML_JMPc(block, COND_NZ, compiler.labelnum); // jz compiler.labelnum
4043
4044 UML_OR(block, I0, I0, SH_T); // or r0, r0, T
4045 UML_LABEL(block, compiler.labelnum++); // desc->pc:
4046
4047 UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov m_sh2_state->sr, r0
4048 return true;
4049 }
4050 break;
4051
4052 case 0x11: // CMPPZ(Rn);
4053 UML_AND(block, I0, mem(&m_sh2_state->sr), ~SH_T); // and r0, sr, ~T (clear the T bit)
4054
4055 UML_CMP(block, R32(Rn), 0); // cmp Rn, 0
4056 UML_JMPc(block, COND_S, compiler.labelnum); // js compiler.labelnum (if negative)
4057
4058 UML_OR(block, I0, I0, SH_T); // or r0, r0, T
4059 UML_LABEL(block, compiler.labelnum++); // desc->pc:
4060
4061 UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov m_sh2_state->sr, r0
4062 return true;
4063
4064 case 0x15: // CMPPL(Rn);
4065 UML_AND(block, I0, mem(&m_sh2_state->sr), ~SH_T); // and r0, sr, ~T (clear the T bit)
4066
4067 UML_CMP(block, R32(Rn), 0); // cmp Rn, 0
4068
4069 UML_JMPc(block, COND_S, compiler.labelnum); // js compiler.labelnum (if negative)
4070 UML_JMPc(block, COND_Z, compiler.labelnum); // jz compiler.labelnum (if zero)
4071
4072 UML_OR(block, I0, I0, SH_T); // or r0, r0, T
4073
4074 UML_LABEL(block, compiler.labelnum++); // desc->pc:
4075 UML_MOV(block, mem(&m_sh2_state->sr), I0); // mov m_sh2_state->sr, r0
4076 return true;
4077
4078 case 0x12: // STSMMACL(Rn);
4079 UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, #4
4080 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
4081 UML_MOV(block, I1, mem(&m_sh2_state->macl)); // mov r1, macl
4082 SETEA(0); // set ea for debug
4083 UML_CALLH(block, *m_write32); // call write32
4084
4085 if (!in_delay_slot)
4086 generate_update_cycles(block, compiler, desc->pc + 2, true);
4087 return true;
4088
4089 case 0x13: // STCMGBR(Rn);
4090 UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, #4
4091 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
4092 UML_MOV(block, I1, mem(&m_sh2_state->gbr)); // mov r1, gbr
4093 SETEA(0); // set ea for debug
4094 UML_CALLH(block, *m_write32); // call write32
4095
4096 if (!in_delay_slot)
4097 generate_update_cycles(block, compiler, desc->pc + 2, true);
4098 return true;
4099
4100 case 0x16: // LDSMMACL(Rn);
4101 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
4102 SETEA(0);
4103 UML_CALLH(block, *m_read32); // call read32
4104 UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, #4
4105 UML_MOV(block, mem(&m_sh2_state->macl), I0); // mov macl, r0
4106
4107 if (!in_delay_slot)
4108 generate_update_cycles(block, compiler, desc->pc + 2, true);
4109 return true;
4110
4111 case 0x17: // LDCMGBR(Rn);
4112 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
4113 SETEA(0);
4114 UML_CALLH(block, *m_read32); // call read32
4115 UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, #4
4116 UML_MOV(block, mem(&m_sh2_state->gbr), I0); // mov gbr, r0
4117
4118 if (!in_delay_slot)
4119 generate_update_cycles(block, compiler, desc->pc + 2, true);
4120 return true;
4121
4122 case 0x1a: // LDSMACL(Rn);
4123 UML_MOV(block, mem(&m_sh2_state->macl), R32(Rn)); // mov macl, Rn
4124 return true;
4125
4126 case 0x1b: // TAS(Rn);
4127 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
4128 SETEA(0);
4129 UML_CALLH(block, *m_read8); // call read8
4130
4131 UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and sr, sr, ~T
4132
4133 UML_CMP(block, I0, 0); // cmp r0, #0
4134 UML_JMPc(block, COND_NZ, compiler.labelnum); // jnz labelnum
4135
4136 UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), SH_T); // or sr, sr, T
4137
4138 UML_LABEL(block, compiler.labelnum++); // labelnum:
4139
4140 UML_OR(block, I1, I0, 0x80); // or r1, r0, #0x80
4141
4142 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
4143 UML_CALLH(block, *m_write8); // write the value back
4144
4145 if (!in_delay_slot)
4146 generate_update_cycles(block, compiler, desc->pc + 2, true);
4147 return true;
4148
4149 case 0x1e: // LDCGBR(Rn);
4150 UML_MOV(block, mem(&m_sh2_state->gbr), R32(Rn)); // mov gbr, Rn
4151 return true;
4152
4153 case 0x20: // SHAL(Rn);
4154 UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and sr, sr, ~T
4155 UML_SHR(block, I0, R32(Rn), 31); // shr r0, Rn, 31
4156 UML_AND(block, I0, I0, SH_T); // and r0, r0, T
4157 UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), I0); // or sr, sr, r0
4158 UML_SHL(block, R32(Rn), R32(Rn), 1); // shl Rn, Rn, 1
4159 return true;
4160
4161 case 0x21: // SHAR(Rn);
4162 UML_AND(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), ~SH_T); // and sr, sr, ~T
4163 UML_AND(block, I0, R32(Rn), SH_T); // and r0, Rn, T
4164 UML_OR(block, mem(&m_sh2_state->sr), mem(&m_sh2_state->sr), I0); // or sr, sr, r0
4165 UML_SAR(block, R32(Rn), R32(Rn), 1); // sar Rn, Rn, 1
4166 return true;
4167
4168 case 0x22: // STSMPR(Rn);
4169 UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, 4
4170 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
4171 SETEA(0);
4172 UML_MOV(block, I1, mem(&m_sh2_state->pr)); // mov r1, pr
4173 UML_CALLH(block, *m_write32); // call write32
4174
4175 if (!in_delay_slot)
4176 generate_update_cycles(block, compiler, desc->pc + 2, true);
4177 return true;
4178
4179 case 0x23: // STCMVBR(Rn);
4180 UML_SUB(block, R32(Rn), R32(Rn), 4); // sub Rn, Rn, 4
4181 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
4182 SETEA(0);
4183 UML_MOV(block, I1, mem(&m_sh2_state->vbr)); // mov r1, vbr
4184 UML_CALLH(block, *m_write32); // call write32
4185
4186 if (!in_delay_slot)
4187 generate_update_cycles(block, compiler, desc->pc + 2, true);
4188 return true;
4189
4190 case 0x24: // ROTCL(Rn);
4191 UML_CARRY(block, mem(&m_sh2_state->sr), 0); // carry sr,0
4192 UML_ROLC(block, R32(Rn), R32(Rn), 1); // rolc Rn,Rn,1
4193 UML_SETc(block, COND_C, I0); // set i0,C
4194 UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins sr,i0,0,T
4195 return true;
4196
4197 case 0x25: // ROTCR(Rn);
4198 UML_CARRY(block, mem(&m_sh2_state->sr), 0); // carry sr,0
4199 UML_RORC(block, R32(Rn), R32(Rn), 1); // rorc Rn,Rn,1
4200 UML_SETc(block, COND_C, I0); // set i0,C
4201 UML_ROLINS(block, mem(&m_sh2_state->sr), I0, 0, SH_T); // rolins sr,i0,0,T
4202 return true;
4203
4204 case 0x26: // LDSMPR(Rn);
4205 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
4206 SETEA(0);
4207 UML_CALLH(block, *m_read32); // call read32
4208 UML_MOV(block, mem(&m_sh2_state->pr), I0); // mov m_pr, r0
4209 UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, Rn, #4
4210
4211 if (!in_delay_slot)
4212 generate_update_cycles(block, compiler, desc->pc + 2, true);
4213 return true;
4214
4215 case 0x27: // LDCMVBR(Rn);
4216 UML_MOV(block, I0, R32(Rn)); // mov r0, Rn
4217 SETEA(0);
4218 UML_CALLH(block, *m_read32); // call read32
4219 UML_MOV(block, mem(&m_sh2_state->vbr), I0); // mov m_sh2_state->vbr, r0
4220 UML_ADD(block, R32(Rn), R32(Rn), 4); // add Rn, Rn, #4
4221
4222 if (!in_delay_slot)
4223 generate_update_cycles(block, compiler, desc->pc + 2, true);
4224 return true;
4225
4226 case 0x2a: // LDSPR(Rn);
4227 UML_MOV(block, mem(&m_sh2_state->pr), R32(Rn)); // mov m_pr, Rn
4228 return true;
4229
4230 case 0x2b: // JMP(Rn);
4231 UML_MOV(block, mem(&m_sh2_state->target), R32(Rn)); // mov target, Rn
4232
4233 generate_delay_slot(block, compiler, desc, m_sh2_state->target);
4234
4235 generate_update_cycles(block, compiler, uml::mem(&m_sh2_state->target), true); // <subtract cycles>
4236 UML_HASHJMP(block, 0, mem(&m_sh2_state->target), *m_nocode); // jmp (target)
4237 return true;
4238
4239 case 0x2e: // LDCVBR(Rn);
4240 UML_MOV(block, mem(&m_sh2_state->vbr), R32(Rn)); // mov vbr, Rn
4241 return true;
4242
4243 case 0x0c:
4244 case 0x0d:
4245 case 0x14:
4246 case 0x1c:
4247 case 0x1d:
4248 case 0x2c:
4249 case 0x2d:
4250 case 0x30:
4251 case 0x31:
4252 case 0x32:
4253 case 0x33:
4254 case 0x34:
4255 case 0x35:
4256 case 0x36:
4257 case 0x37:
4258 case 0x38:
4259 case 0x39:
4260 case 0x3a:
4261 case 0x3b:
4262 case 0x3c:
4263 case 0x3d:
4264 case 0x3e:
4265 return false;
4266 }
4267
4268 return false;
4269 }
4270
4271
4272 /***************************************************************************
4273 CORE CALLBACKS
4274 ***************************************************************************/
4275
4276 /*-------------------------------------------------
4277 sh2drc_set_options - configure DRC options
4278 -------------------------------------------------*/
4279
sh2drc_set_options(uint32_t options)4280 void sh_common_execution::sh2drc_set_options(uint32_t options)
4281 {
4282 if (!allow_drc()) return;
4283 m_drcoptions = options;
4284 }
4285
4286
4287 /*-------------------------------------------------
4288 sh2drc_add_pcflush - add a new address where
4289 the PC must be flushed for speedups to work
4290 -------------------------------------------------*/
4291
sh2drc_add_pcflush(offs_t address)4292 void sh_common_execution::sh2drc_add_pcflush(offs_t address)
4293 {
4294 if (!allow_drc()) return;
4295
4296 if (m_pcfsel < ARRAY_LENGTH(m_pcflushes))
4297 m_pcflushes[m_pcfsel++] = address;
4298 }
4299