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