1 /*
2  *  Copyright (C) 2005-2018  Anders Gavare.  All rights reserved.
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions are met:
6  *
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. The name of the author may not be used to endorse or promote products
13  *     derived from this software without specific prior written permission.
14  *
15  *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  *  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  *  SUCH DAMAGE.
26  *
27  *
28  *  SH instructions.
29  *
30  *  Individual functions should keep track of cpu->n_translated_instrs.
31  *  (If no instruction was executed, then it should be decreased. If, say, 4
32  *  instructions were combined into one function and executed, then it should
33  *  be increased by 3.)
34  */
35 
36 
37 #define	SYNCH_PC		{					\
38 		int low_pc = ((size_t)ic - (size_t)cpu->cd.sh.cur_ic_page) \
39 		    / sizeof(struct sh_instr_call);			\
40 		cpu->pc &= ~((SH_IC_ENTRIES_PER_PAGE-1)			\
41 		    << SH_INSTR_ALIGNMENT_SHIFT);			\
42 		cpu->pc += (low_pc << SH_INSTR_ALIGNMENT_SHIFT);	\
43 	}
44 
45 #define	ABORT_EXECUTION	  {	SYNCH_PC;				\
46 				fatal("Execution aborted at: pc = 0x%08x\n", (int)cpu->pc); \
47 				cpu->cd.sh.next_ic = &nothing_call;	\
48 				cpu->running = 0;			\
49 				debugger_n_steps_left_before_interaction = 0; }
50 
51 #define	RES_INST_IF_NOT_MD						\
52 	if (!(cpu->cd.sh.sr & SH_SR_MD)) {				\
53 		SYNCH_PC;						\
54 		sh_exception(cpu, EXPEVT_RES_INST, 0, 0);		\
55 		return;							\
56 	}
57 
58 #define	FLOATING_POINT_AVAILABLE_CHECK					\
59 	if (cpu->cd.sh.sr & SH_SR_FD) {					\
60 		/*  FPU disabled: Cause exception.  */			\
61 		SYNCH_PC;						\
62 		if (cpu->delay_slot)					\
63 			sh_exception(cpu, EXPEVT_FPU_SLOT_DISABLE, 0, 0);\
64 		else							\
65 			sh_exception(cpu, EXPEVT_FPU_DISABLE, 0, 0);	\
66 		return;							\
67 	}
68 
69 
70 /*
71  *  nop: Nothing
72  */
X(nop)73 X(nop)
74 {
75 }
76 
77 
78 /*
79  *  sleep:  Wait for interrupt
80  */
X(sleep)81 X(sleep)
82 {
83 	RES_INST_IF_NOT_MD;
84 
85 	/*
86 	 *  If there is an interrupt, then just return. Otherwise
87 	 *  re-run the sleep instruction (after a delay).
88 	 */
89 	if (cpu->cd.sh.int_to_assert > 0 && !(cpu->cd.sh.sr & SH_SR_BL)
90 	    && ((cpu->cd.sh.sr & SH_SR_IMASK) >> SH_SR_IMASK_SHIFT)
91 	    < cpu->cd.sh.int_level)
92 		return;
93 
94 	cpu->cd.sh.next_ic = ic;
95 	cpu->is_halted = 1;
96 	cpu->has_been_idling = 1;
97 
98 	/*
99 	 *  There was no interrupt. Let the host sleep for a while.
100 	 *
101 	 *  TODO:
102 	 *
103 	 *  Think about how to actually implement this usleep stuff,
104 	 *  in an SMP and/or timing accurate environment.
105 	 */
106 
107 	if (cpu->machine->ncpus == 1) {
108 		static int x = 0;
109 
110 		if ((++x) == 600) {
111 			usleep(10);
112 			x = 0;
113 		}
114 
115 		cpu->n_translated_instrs += N_SAFE_DYNTRANS_LIMIT / 6;
116 	}
117 }
118 
119 
120 /*
121  *  sett:     t = 1
122  *  sets:     s = 1
123  *  clrt:     t = 1
124  *  clrs:     s = 1
125  *  movt_rn:  rn = t
126  *  clrmac:   mach = macl = 0
127  *
128  *  arg[1] = ptr to rn
129  */
X(sett)130 X(sett)    { cpu->cd.sh.sr |= SH_SR_T; }
X(sets)131 X(sets)    { cpu->cd.sh.sr |= SH_SR_S; }
X(clrt)132 X(clrt)    { cpu->cd.sh.sr &= ~SH_SR_T; }
X(clrs)133 X(clrs)    { cpu->cd.sh.sr &= ~SH_SR_S; }
X(movt_rn)134 X(movt_rn) { reg(ic->arg[1]) = cpu->cd.sh.sr & SH_SR_T? 1 : 0; }
X(clrmac)135 X(clrmac)  { cpu->cd.sh.macl = cpu->cd.sh.mach = 0; }
136 
137 
138 /*
139  *  mov_rm_rn:     rn = rm
140  *  neg_rm_rn:     rn = -rm
141  *  negc_rm_rn:    rn = -rm - t, t = borrow
142  *  not_rm_rn:     rn = ~rm
143  *  swap_b_rm_rn:  rn = rm with lowest 2 bytes swapped
144  *  swap_w_rm_rn:  rn = rm with high and low 16-bit words swapped
145  *  exts_b_rm_rn:  rn = (int8_t) rm
146  *  extu_b_rm_rn:  rn = (uint8_t) rm
147  *  exts_w_rm_rn:  rn = (int16_t) rm
148  *  extu_w_rm_rn:  rn = (uint16_t) rm
149  *
150  *  arg[0] = ptr to rm
151  *  arg[1] = ptr to rn
152  */
X(mov_rm_rn)153 X(mov_rm_rn)    { reg(ic->arg[1]) = reg(ic->arg[0]); }
X(not_rm_rn)154 X(not_rm_rn)    { reg(ic->arg[1]) = ~reg(ic->arg[0]); }
X(neg_rm_rn)155 X(neg_rm_rn)    { reg(ic->arg[1]) = -reg(ic->arg[0]); }
X(negc_rm_rn)156 X(negc_rm_rn)
157 {
158 	uint64_t res = 0;
159 	res -= (uint64_t) reg(ic->arg[0]);
160 	if (cpu->cd.sh.sr & SH_SR_T)
161 		res --;
162 	if ((res >> 32) & 1)
163 		cpu->cd.sh.sr |= SH_SR_T;
164 	else
165 		cpu->cd.sh.sr &= ~SH_SR_T;
166 	reg(ic->arg[1]) = (uint32_t) res;
167 }
X(swap_b_rm_rn)168 X(swap_b_rm_rn)
169 {
170 	uint32_t r = reg(ic->arg[0]);
171 	reg(ic->arg[1]) = (r & 0xffff0000) | ((r >> 8)&0xff) | ((r&0xff) << 8);
172 }
X(swap_w_rm_rn)173 X(swap_w_rm_rn)
174 {
175 	uint32_t r = reg(ic->arg[0]);
176 	reg(ic->arg[1]) = (r >> 16) | (r << 16);
177 }
X(exts_b_rm_rn)178 X(exts_b_rm_rn) { reg(ic->arg[1]) = (int8_t)reg(ic->arg[0]); }
X(extu_b_rm_rn)179 X(extu_b_rm_rn) { reg(ic->arg[1]) = (uint8_t)reg(ic->arg[0]); }
X(exts_w_rm_rn)180 X(exts_w_rm_rn) { reg(ic->arg[1]) = (int16_t)reg(ic->arg[0]); }
X(extu_w_rm_rn)181 X(extu_w_rm_rn) { reg(ic->arg[1]) = (uint16_t)reg(ic->arg[0]); }
182 /*  Note: rm and rn are the same on these:  */
X(extu_b_rm)183 X(extu_b_rm)    { reg(ic->arg[1]) = (uint8_t)reg(ic->arg[1]); }
X(extu_w_rm)184 X(extu_w_rm)    { reg(ic->arg[1]) = (uint16_t)reg(ic->arg[1]); }
185 
186 
187 /*
188  *  and_imm_r0:  r0 &= imm
189  *  xor_imm_r0:  r0 ^= imm
190  *  tst_imm_r0:  t = (r0 & imm) == 0
191  *  or_imm_r0:   r0 |= imm
192  *
193  *  arg[0] = imm
194  */
X(and_imm_r0)195 X(and_imm_r0) { cpu->cd.sh.r[0] &= ic->arg[0]; }
X(xor_imm_r0)196 X(xor_imm_r0) { cpu->cd.sh.r[0] ^= ic->arg[0]; }
X(or_imm_r0)197 X(or_imm_r0)  { cpu->cd.sh.r[0] |= ic->arg[0]; }
X(tst_imm_r0)198 X(tst_imm_r0)
199 {
200 	if (cpu->cd.sh.r[0] & ic->arg[0])
201 		cpu->cd.sh.sr &= ~SH_SR_T;
202 	else
203 		cpu->cd.sh.sr |= SH_SR_T;
204 }
205 
206 
207 /*
208  *  xor_b_imm_r0_gbr:  mem[r0+gbr] |= imm
209  *  or_b_imm_r0_gbr:   mem[r0+gbr] ^= imm
210  *  and_b_imm_r0_gbr:  mem[r0+gbr] &= imm
211  *
212  *  arg[0] = imm
213  */
X(xor_b_imm_r0_gbr)214 X(xor_b_imm_r0_gbr)
215 {
216 	uint32_t addr = cpu->cd.sh.gbr + cpu->cd.sh.r[0];
217 	uint8_t *p = (uint8_t *) cpu->cd.sh.host_store[addr >> 12];
218 
219 	if (p != NULL) {
220 		p[addr & 0xfff] ^= ic->arg[0];
221 	} else {
222 		uint8_t data;
223 		SYNCH_PC;
224 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
225 		   sizeof(data), MEM_READ, CACHE_DATA)) {
226 			/*  Exception.  */
227 			return;
228 		}
229 		data ^= ic->arg[0];
230 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
231 		   sizeof(data), MEM_WRITE, CACHE_DATA)) {
232 			/*  Exception.  */
233 			return;
234 		}
235 	}
236 }
X(or_b_imm_r0_gbr)237 X(or_b_imm_r0_gbr)
238 {
239 	uint32_t addr = cpu->cd.sh.gbr + cpu->cd.sh.r[0];
240 	uint8_t *p = (uint8_t *) cpu->cd.sh.host_store[addr >> 12];
241 
242 	if (p != NULL) {
243 		p[addr & 0xfff] |= ic->arg[0];
244 	} else {
245 		uint8_t data;
246 		SYNCH_PC;
247 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
248 		   sizeof(data), MEM_READ, CACHE_DATA)) {
249 			/*  Exception.  */
250 			return;
251 		}
252 		data |= ic->arg[0];
253 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
254 		   sizeof(data), MEM_WRITE, CACHE_DATA)) {
255 			/*  Exception.  */
256 			return;
257 		}
258 	}
259 }
X(and_b_imm_r0_gbr)260 X(and_b_imm_r0_gbr)
261 {
262 	uint32_t addr = cpu->cd.sh.gbr + cpu->cd.sh.r[0];
263 	uint8_t *p = (uint8_t *) cpu->cd.sh.host_store[addr >> 12];
264 
265 	if (p != NULL) {
266 		p[addr & 0xfff] &= ic->arg[0];
267 	} else {
268 		uint8_t data;
269 		SYNCH_PC;
270 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
271 		   sizeof(data), MEM_READ, CACHE_DATA)) {
272 			/*  Exception.  */
273 			return;
274 		}
275 		data &= ic->arg[0];
276 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
277 		   sizeof(data), MEM_WRITE, CACHE_DATA)) {
278 			/*  Exception.  */
279 			return;
280 		}
281 	}
282 }
283 
284 
285 /*
286  *  mov_imm_rn:  Set rn to a signed 8-bit value
287  *  add_imm_rn:  Add a signed 8-bit value to Rn
288  *
289  *  arg[0] = int8_t imm, extended to at least int32_t
290  *  arg[1] = ptr to rn
291  */
X(mov_imm_rn)292 X(mov_imm_rn) { reg(ic->arg[1]) = ic->arg[0]; }
X(mov_0_rn)293 X(mov_0_rn)   { reg(ic->arg[1]) = 0; }
X(add_imm_rn)294 X(add_imm_rn) { reg(ic->arg[1]) += ic->arg[0]; }
X(inc_rn)295 X(inc_rn)     { reg(ic->arg[1]) ++; }
X(add_4_rn)296 X(add_4_rn)   { reg(ic->arg[1]) += 4; }
X(sub_4_rn)297 X(sub_4_rn)   { reg(ic->arg[1]) -= 4; }
X(dec_rn)298 X(dec_rn)     { reg(ic->arg[1]) --; }
299 
300 
301 /*
302  *  mov_b_rm_predec_rn:     mov.b reg,@-Rn
303  *  mov_w_rm_predec_rn:     mov.w reg,@-Rn
304  *  mov_l_rm_predec_rn:     mov.l reg,@-Rn
305  *  stc_l_rm_predec_rn_md:  mov.l reg,@-Rn, with MD status bit check
306  *
307  *  arg[0] = ptr to rm  (or other register)
308  *  arg[1] = ptr to rn
309  */
X(mov_b_rm_predec_rn)310 X(mov_b_rm_predec_rn)
311 {
312 	uint32_t addr = reg(ic->arg[1]) - sizeof(uint8_t);
313 	int8_t *p = (int8_t *) cpu->cd.sh.host_store[addr >> 12];
314 	int8_t data = reg(ic->arg[0]);
315 	if (p != NULL) {
316 		p[addr & 0xfff] = data;
317 		reg(ic->arg[1]) = addr;
318 	} else {
319 		SYNCH_PC;
320 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
321 		   sizeof(data), MEM_WRITE, CACHE_DATA)) {
322 			/*  Exception.  */
323 			return;
324 		}
325 		/*  The store was ok:  */
326 		reg(ic->arg[1]) = addr;
327 	}
328 }
X(mov_w_rm_predec_rn)329 X(mov_w_rm_predec_rn)
330 {
331 	uint32_t addr = reg(ic->arg[1]) - sizeof(uint16_t);
332 	uint16_t *p = (uint16_t *) cpu->cd.sh.host_store[addr >> 12];
333 	uint16_t data = reg(ic->arg[0]);
334 
335 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
336 		data = LE16_TO_HOST(data);
337 	else
338 		data = BE16_TO_HOST(data);
339 
340 	if (p != NULL) {
341 		p[(addr & 0xfff) >> 1] = data;
342 		reg(ic->arg[1]) = addr;
343 	} else {
344 		SYNCH_PC;
345 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
346 		   sizeof(data), MEM_WRITE, CACHE_DATA)) {
347 			/*  Exception.  */
348 			return;
349 		}
350 		/*  The store was ok:  */
351 		reg(ic->arg[1]) = addr;
352 	}
353 }
X(mov_l_rm_predec_rn)354 X(mov_l_rm_predec_rn)
355 {
356 	uint32_t addr = reg(ic->arg[1]) - sizeof(uint32_t);
357 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_store[addr >> 12];
358 	uint32_t data = reg(ic->arg[0]);
359 
360 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
361 		data = LE32_TO_HOST(data);
362 	else
363 		data = BE32_TO_HOST(data);
364 
365 	if (p != NULL) {
366 		p[(addr & 0xfff) >> 2] = data;
367 		reg(ic->arg[1]) = addr;
368 	} else {
369 		SYNCH_PC;
370 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
371 		   sizeof(data), MEM_WRITE, CACHE_DATA)) {
372 			/*  Exception.  */
373 			return;
374 		}
375 		/*  The store was ok:  */
376 		reg(ic->arg[1]) = addr;
377 	}
378 }
X(stc_l_rm_predec_rn_md)379 X(stc_l_rm_predec_rn_md)
380 {
381 	uint32_t addr = reg(ic->arg[1]) - sizeof(uint32_t);
382 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_store[addr >> 12];
383 	uint32_t data = reg(ic->arg[0]);
384 
385 	RES_INST_IF_NOT_MD;
386 
387 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
388 		data = LE32_TO_HOST(data);
389 	else
390 		data = BE32_TO_HOST(data);
391 
392 	if (p != NULL) {
393 		p[(addr & 0xfff) >> 2] = data;
394 		reg(ic->arg[1]) = addr;
395 	} else {
396 		SYNCH_PC;
397 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
398 		   sizeof(data), MEM_WRITE, CACHE_DATA)) {
399 			/*  Exception.  */
400 			return;
401 		}
402 		/*  The store was ok:  */
403 		reg(ic->arg[1]) = addr;
404 	}
405 }
406 
407 
408 /*
409  *  mov_l_disp_pc_rn:  Load a 32-bit value into a register,
410  *                     from an immediate address relative to the pc.
411  *
412  *  arg[0] = offset from beginning of the current pc's page
413  *  arg[1] = ptr to rn
414  */
X(mov_l_disp_pc_rn)415 X(mov_l_disp_pc_rn)
416 {
417 	uint32_t addr = ic->arg[0] + (cpu->pc &
418 	    ~((SH_IC_ENTRIES_PER_PAGE-1) << SH_INSTR_ALIGNMENT_SHIFT));
419 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_load[addr >> 12];
420 	uint32_t data;
421 
422 	if (p != NULL) {
423 		data = p[(addr & 0xfff) >> 2];
424 	} else {
425 		SYNCH_PC;
426 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
427 		    sizeof(data), MEM_READ, CACHE_DATA)) {
428 			/*  Exception.  */
429 			return;
430 		}
431 	}
432 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
433 		data = LE32_TO_HOST(data);
434 	else
435 		data = BE32_TO_HOST(data);
436 	reg(ic->arg[1]) = data;
437 }
438 
439 
440 /*
441  *  mova_r0:  Set r0 to an address close to the program counter.
442  *
443  *  arg[0] = relative offset from beginning of the current pc's page
444  */
X(mova_r0)445 X(mova_r0)
446 {
447 	cpu->cd.sh.r[0] = ic->arg[0] + (cpu->pc &
448 	    ~((SH_IC_ENTRIES_PER_PAGE-1) << SH_INSTR_ALIGNMENT_SHIFT));
449 }
450 
451 
452 /*
453  *  mov_w_disp_pc_rn:  Load a 16-bit value into a register,
454  *                     from an immediate address relative to the pc.
455  *
456  *  arg[0] = offset from beginning of the current pc's page
457  *  arg[1] = ptr to rn
458  */
X(mov_w_disp_pc_rn)459 X(mov_w_disp_pc_rn)
460 {
461 	uint32_t addr = ic->arg[0] + (cpu->pc &
462 	    ~((SH_IC_ENTRIES_PER_PAGE-1) << SH_INSTR_ALIGNMENT_SHIFT));
463 	uint16_t *p = (uint16_t *) cpu->cd.sh.host_load[addr >> 12];
464 	uint16_t data;
465 
466 	if (p != NULL) {
467 		data = p[(addr & 0xfff) >> 1];
468 	} else {
469 		SYNCH_PC;
470 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
471 		    sizeof(data), MEM_READ, CACHE_DATA)) {
472 			/*  Exception.  */
473 			return;
474 		}
475 	}
476 
477 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
478 		data = LE16_TO_HOST(data);
479 	else
480 		data = BE16_TO_HOST(data);
481 
482 	reg(ic->arg[1]) = (int16_t)data;
483 }
484 
485 
486 /*
487  *  load_b_rm_rn:      Load an int8_t value into Rn from address Rm.
488  *  load_w_rm_rn:      Load an int16_t value into Rn from address Rm.
489  *  load_l_rm_rn:      Load a 32-bit value into Rn from address Rm.
490  *  fmov_rm_frn:       Load a floating point value into FRn from address Rm.
491  *  fmov_r0_rm_frn:    Load a floating point value into FRn from address R0+Rm.
492  *  fmov_rm_postinc_frn: Load a floating point value into FRn from address Rm.
493  *  mov_b_r0_rm_rn:    Load an int8_t value into Rn from address Rm + R0.
494  *  mov_w_r0_rm_rn:    Load an int16_t value into Rn from address Rm + R0.
495  *  mov_l_r0_rm_rn:    Load a 32-bit value into Rn from address Rm + R0.
496  *  mov_l_disp_rm_rn:  Load a 32-bit value into Rn from address Rm + disp.
497  *  mov_b_disp_rn_r0:  Load an int8_t from Rn+disp into R0.
498  *  mov_w_disp_rn_r0:  Load an int16_t from Rn+disp into R0.
499  *  mov_b_disp_gbr_r0: Load an int8_t from GBR+disp into R0.
500  *  mov_w_disp_gbr_r0: Load an int16_t from GBR+disp into R0.
501  *  mov_l_disp_gbr_r0: Load an int32_t from GBR+disp into R0.
502  *  mov_b_arg1_postinc_to_arg0:
503  *  mov_w_arg1_postinc_to_arg0:
504  *  mov_l_arg1_postinc_to_arg0:
505  *  mov_l_arg1_postinc_to_arg0_md:  With MD (privilege level) check.
506  *  mov_l_arg1_postinc_to_arg0_fp:  With FP check.
507  *
508  *  arg[0] = ptr to rm   (or rm + (lo4 << 4) for disp)
509  *  arg[1] = ptr to rn
510  */
X(load_b_rm_rn)511 X(load_b_rm_rn)
512 {
513 	uint32_t addr = reg(ic->arg[0]);
514 	uint8_t *p = (uint8_t *) cpu->cd.sh.host_load[addr >> 12];
515 	uint8_t data;
516 
517 	if (p != NULL) {
518 		data = p[addr & 0xfff];
519 	} else {
520 		SYNCH_PC;
521 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
522 		    sizeof(data), MEM_READ, CACHE_DATA)) {
523 			/*  Exception.  */
524 			return;
525 		}
526 	}
527 	reg(ic->arg[1]) = (int8_t) data;
528 }
X(load_w_rm_rn)529 X(load_w_rm_rn)
530 {
531 	uint32_t addr = reg(ic->arg[0]);
532 	int16_t *p = (int16_t *) cpu->cd.sh.host_load[addr >> 12];
533 	int16_t data;
534 
535 	if (p != NULL) {
536 		data = p[(addr & 0xfff) >> 1];
537 	} else {
538 		SYNCH_PC;
539 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
540 		    sizeof(data), MEM_READ, CACHE_DATA)) {
541 			/*  Exception.  */
542 			return;
543 		}
544 	}
545 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
546 		data = LE16_TO_HOST(data);
547 	else
548 		data = BE16_TO_HOST(data);
549 	reg(ic->arg[1]) = data;
550 }
X(load_l_rm_rn)551 X(load_l_rm_rn)
552 {
553 	uint32_t addr = reg(ic->arg[0]);
554 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_load[addr >> 12];
555 	uint32_t data;
556 
557 	if (p != NULL) {
558 		data = p[(addr & 0xfff) >> 2];
559 	} else {
560 		SYNCH_PC;
561 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
562 		    sizeof(data), MEM_READ, CACHE_DATA)) {
563 			/*  Exception.  */
564 			return;
565 		}
566 	}
567 
568 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
569 		data = LE32_TO_HOST(data);
570 	else
571 		data = BE32_TO_HOST(data);
572 	reg(ic->arg[1]) = data;
573 }
X(fmov_rm_frn)574 X(fmov_rm_frn)
575 {
576 	uint32_t addr = reg(ic->arg[0]);
577 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_load[addr >> 12];
578 	uint32_t data;
579 
580 	FLOATING_POINT_AVAILABLE_CHECK;
581 
582 	uint32_t data2 = 0;
583 	if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
584 		// Register pair. Read second word first, then fallback
585 		// to read the first word.
586 
587 		// Check if it is to an odd register first.
588 		size_t r1 = ic->arg[1];
589 		int ofs = (r1 - (size_t)&cpu->cd.sh.fr[0]) / sizeof(uint32_t);
590 		if (ofs & 1) {
591 			fatal("ODD fmov_rm_frn: TODO");
592 			exit(1);
593 			r1 = (size_t)&cpu->cd.sh.xf[ofs & ~1];
594 		}
595 
596 		SYNCH_PC;
597 		if (!cpu->memory_rw(cpu, cpu->mem, addr + 4, (unsigned char *)&data,
598 		    sizeof(data), MEM_READ, CACHE_DATA)) {
599 			/*  Exception.  */
600 			return;
601 		}
602 
603 		data2 = data;
604 
605 		// fall-through to read the first word in the pair:
606 	}
607 
608 	if (p != NULL) {
609 		data = p[(addr & 0xfff) >> 2];
610 	} else {
611 		SYNCH_PC;
612 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
613 		    sizeof(data), MEM_READ, CACHE_DATA)) {
614 			/*  Exception.  */
615 			return;
616 		}
617 	}
618 
619 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
620 		data = LE32_TO_HOST(data);
621 	else
622 		data = BE32_TO_HOST(data);
623 
624 	reg(ic->arg[1]) = data;
625 
626 	// TODO: How about little endian: read words in opposite order?
627 	if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
628 		if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
629 			data2 = LE32_TO_HOST(data2);
630 		else
631 			data2 = BE32_TO_HOST(data2);
632 		reg(ic->arg[1] + 4) = data2;
633 	}
634 }
X(fmov_r0_rm_frn)635 X(fmov_r0_rm_frn)
636 {
637 	uint32_t data, addr = reg(ic->arg[0]) + cpu->cd.sh.r[0];
638 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_load[addr >> 12];
639 
640 	FLOATING_POINT_AVAILABLE_CHECK;
641 
642 	if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
643 		fatal("fmov_r0_rm_frn: sz=1 (register pair): TODO\n");
644 		ABORT_EXECUTION;
645 		return;
646 	}
647 
648 	if (p != NULL) {
649 		data = p[(addr & 0xfff) >> 2];
650 	} else {
651 		SYNCH_PC;
652 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
653 		    sizeof(data), MEM_READ, CACHE_DATA)) {
654 			/*  Exception.  */
655 			return;
656 		}
657 	}
658 
659 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
660 		data = LE32_TO_HOST(data);
661 	else
662 		data = BE32_TO_HOST(data);
663 
664 	reg(ic->arg[1]) = data;
665 }
X(fmov_rm_postinc_frn)666 X(fmov_rm_postinc_frn)
667 {
668 	int d = cpu->cd.sh.fpscr & SH_FPSCR_SZ;
669 	uint32_t data, data2, addr = reg(ic->arg[0]);
670 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_load[addr >> 12];
671 	size_t r1 = ic->arg[1];
672 
673 	if (d) {
674 		/*  xd instead of dr?  */
675 		int ofs = (r1 - (size_t)&cpu->cd.sh.fr[0]) / sizeof(uint32_t);
676 		if (ofs & 1)
677 			r1 = (size_t)&cpu->cd.sh.xf[ofs & ~1];
678 	}
679 
680 	FLOATING_POINT_AVAILABLE_CHECK;
681 
682 	if (p != NULL) {
683 		data = p[(addr & 0xfff) >> 2];
684 	} else {
685 		SYNCH_PC;
686 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
687 		    sizeof(data), MEM_READ, CACHE_DATA)) {
688 			/*  Exception.  */
689 			return;
690 		}
691 	}
692 
693 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
694 		data = LE32_TO_HOST(data);
695 	else
696 		data = BE32_TO_HOST(data);
697 
698 	if (d) {
699 		/*  Double-precision load:  */
700 		addr += 4;
701 		SYNCH_PC;
702 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned
703 		    char *)&data2, sizeof(data2), MEM_READ, CACHE_DATA))
704 			return;
705 
706 		if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
707 			data2 = LE32_TO_HOST(data2);
708 		else
709 			data2 = BE32_TO_HOST(data2);
710 		reg(r1 + 4) = data2;
711 	}
712 
713 	reg(r1) = data;
714 	reg(ic->arg[0]) = addr + sizeof(uint32_t);
715 }
X(mov_b_disp_gbr_r0)716 X(mov_b_disp_gbr_r0)
717 {
718 	uint32_t addr = cpu->cd.sh.gbr + ic->arg[1];
719 	int8_t *p = (int8_t *) cpu->cd.sh.host_load[addr >> 12];
720 	int8_t data;
721 	if (p != NULL) {
722 		data = p[addr & 0xfff];
723 	} else {
724 		SYNCH_PC;
725 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
726 		    sizeof(data), MEM_READ, CACHE_DATA)) {
727 			/*  Exception.  */
728 			return;
729 		}
730 	}
731 	cpu->cd.sh.r[0] = data;
732 }
X(mov_w_disp_gbr_r0)733 X(mov_w_disp_gbr_r0)
734 {
735 	uint32_t addr = cpu->cd.sh.gbr + ic->arg[1];
736 	int16_t *p = (int16_t *) cpu->cd.sh.host_load[addr >> 12];
737 	int16_t data;
738 	if (p != NULL) {
739 		data = p[(addr & 0xfff) >> 1];
740 	} else {
741 		SYNCH_PC;
742 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
743 		    sizeof(data), MEM_READ, CACHE_DATA)) {
744 			/*  Exception.  */
745 			return;
746 		}
747 	}
748 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
749 		data = LE16_TO_HOST(data);
750 	else
751 		data = BE16_TO_HOST(data);
752 	cpu->cd.sh.r[0] = data;
753 }
X(mov_l_disp_gbr_r0)754 X(mov_l_disp_gbr_r0)
755 {
756 	uint32_t addr = cpu->cd.sh.gbr + ic->arg[1];
757 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_load[addr >> 12];
758 	uint32_t data;
759 	if (p != NULL) {
760 		data = p[(addr & 0xfff) >> 2];
761 	} else {
762 		SYNCH_PC;
763 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
764 		    sizeof(data), MEM_READ, CACHE_DATA)) {
765 			/*  Exception.  */
766 			return;
767 		}
768 	}
769 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
770 		data = LE32_TO_HOST(data);
771 	else
772 		data = BE32_TO_HOST(data);
773 	cpu->cd.sh.r[0] = data;
774 }
X(mov_b_arg1_postinc_to_arg0)775 X(mov_b_arg1_postinc_to_arg0)
776 {
777 	uint32_t addr = reg(ic->arg[1]);
778 	int8_t *p = (int8_t *) cpu->cd.sh.host_load[addr >> 12];
779 	int8_t data;
780 	if (p != NULL) {
781 		data = p[addr & 0xfff];
782 	} else {
783 		SYNCH_PC;
784 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
785 		    sizeof(data), MEM_READ, CACHE_DATA)) {
786 			/*  Exception.  */
787 			return;
788 		}
789 	}
790 	/*  The load was ok:  */
791 	reg(ic->arg[1]) = addr + sizeof(int8_t);
792 	reg(ic->arg[0]) = data;
793 }
X(mov_w_arg1_postinc_to_arg0)794 X(mov_w_arg1_postinc_to_arg0)
795 {
796 	uint32_t addr = reg(ic->arg[1]);
797 	uint16_t *p = (uint16_t *) cpu->cd.sh.host_load[addr >> 12];
798 	uint16_t data;
799 
800 	if (p != NULL) {
801 		data = p[(addr & 0xfff) >> 1];
802 	} else {
803 		SYNCH_PC;
804 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
805 		    sizeof(data), MEM_READ, CACHE_DATA)) {
806 			/*  Exception.  */
807 			return;
808 		}
809 	}
810 
811 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
812 		data = LE16_TO_HOST(data);
813 	else
814 		data = BE16_TO_HOST(data);
815 	reg(ic->arg[1]) = addr + sizeof(data);
816 	reg(ic->arg[0]) = (int16_t)data;
817 }
X(mov_l_arg1_postinc_to_arg0)818 X(mov_l_arg1_postinc_to_arg0)
819 {
820 	uint32_t addr = reg(ic->arg[1]);
821 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_load[addr >> 12];
822 	uint32_t data;
823 
824 	if (p != NULL) {
825 		data = p[(addr & 0xfff) >> 2];
826 	} else {
827 		SYNCH_PC;
828 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
829 		    sizeof(data), MEM_READ, CACHE_DATA)) {
830 			/*  Exception.  */
831 			return;
832 		}
833 	}
834 	/*  The load was ok:  */
835 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
836 		data = LE32_TO_HOST(data);
837 	else
838 		data = BE32_TO_HOST(data);
839 	reg(ic->arg[1]) = addr + sizeof(data);
840 	reg(ic->arg[0]) = data;
841 }
X(mov_l_arg1_postinc_to_arg0_md)842 X(mov_l_arg1_postinc_to_arg0_md)
843 {
844 	uint32_t addr = reg(ic->arg[1]);
845 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_load[addr >> 12];
846 	uint32_t data;
847 
848 	RES_INST_IF_NOT_MD;
849 
850 	if (p != NULL) {
851 		data = p[(addr & 0xfff) >> 2];
852 	} else {
853 		SYNCH_PC;
854 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
855 		    sizeof(data), MEM_READ, CACHE_DATA)) {
856 			/*  Exception.  */
857 			return;
858 		}
859 	}
860 	/*  The load was ok:  */
861 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
862 		data = LE32_TO_HOST(data);
863 	else
864 		data = BE32_TO_HOST(data);
865 	reg(ic->arg[1]) = addr + sizeof(data);
866 
867 	/*  Special case when loading into the SR register:  */
868 	if (ic->arg[0] == (size_t)&cpu->cd.sh.sr)
869 		sh_update_sr(cpu, data);
870 	else
871 		reg(ic->arg[0]) = data;
872 }
X(mov_l_arg1_postinc_to_arg0_fp)873 X(mov_l_arg1_postinc_to_arg0_fp)
874 {
875 	uint32_t addr = reg(ic->arg[1]);
876 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_load[addr >> 12];
877 	uint32_t data;
878 
879 	FLOATING_POINT_AVAILABLE_CHECK;
880 
881 	if (p != NULL) {
882 		data = p[(addr & 0xfff) >> 2];
883 	} else {
884 		SYNCH_PC;
885 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
886 		    sizeof(data), MEM_READ, CACHE_DATA)) {
887 			/*  Exception.  */
888 			return;
889 		}
890 	}
891 	/*  The load was ok:  */
892 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
893 		data = LE32_TO_HOST(data);
894 	else
895 		data = BE32_TO_HOST(data);
896 	reg(ic->arg[1]) = addr + sizeof(data);
897 
898 	/*  Ugly special case for FPSCR:  */
899 	if (ic->arg[0] == (size_t)&cpu->cd.sh.fpscr)
900 		sh_update_fpscr(cpu, data);
901 	else
902 		reg(ic->arg[0]) = data;
903 }
X(mov_b_r0_rm_rn)904 X(mov_b_r0_rm_rn)
905 {
906 	uint32_t addr = reg(ic->arg[0]) + cpu->cd.sh.r[0];
907 	int8_t *p = (int8_t *) cpu->cd.sh.host_load[addr >> 12];
908 	int8_t data;
909 
910 	if (p != NULL) {
911 		data = p[addr & 0xfff];
912 	} else {
913 		SYNCH_PC;
914 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
915 		    sizeof(data), MEM_READ, CACHE_DATA)) {
916 			/*  Exception.  */
917 			return;
918 		}
919 	}
920 
921 	reg(ic->arg[1]) = data;
922 }
X(mov_w_r0_rm_rn)923 X(mov_w_r0_rm_rn)
924 {
925 	uint32_t addr = reg(ic->arg[0]) + cpu->cd.sh.r[0];
926 	int16_t *p = (int16_t *) cpu->cd.sh.host_load[addr >> 12];
927 	int16_t data;
928 
929 	if (p != NULL) {
930 		data = p[(addr & 0xfff) >> 1];
931 	} else {
932 		SYNCH_PC;
933 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
934 		    sizeof(data), MEM_READ, CACHE_DATA)) {
935 			/*  Exception.  */
936 			return;
937 		}
938 	}
939 
940 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
941 		data = LE16_TO_HOST(data);
942 	else
943 		data = BE16_TO_HOST(data);
944 	reg(ic->arg[1]) = data;
945 }
X(mov_l_r0_rm_rn)946 X(mov_l_r0_rm_rn)
947 {
948 	uint32_t addr = reg(ic->arg[0]) + cpu->cd.sh.r[0];
949 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_load[addr >> 12];
950 	uint32_t data;
951 
952 	if (p != NULL) {
953 		data = p[(addr & 0xfff) >> 2];
954 	} else {
955 		SYNCH_PC;
956 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
957 		    sizeof(data), MEM_READ, CACHE_DATA)) {
958 			/*  Exception.  */
959 			return;
960 		}
961 	}
962 
963 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
964 		data = LE32_TO_HOST(data);
965 	else
966 		data = BE32_TO_HOST(data);
967 	reg(ic->arg[1]) = data;
968 }
X(mov_l_disp_rm_rn)969 X(mov_l_disp_rm_rn)
970 {
971 	uint32_t addr = cpu->cd.sh.r[ic->arg[0] & 0xf] +
972 	    ((ic->arg[0] >> 4) << 2);
973 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_load[addr >> 12];
974 	uint32_t data;
975 
976 	if (p != NULL) {
977 		data = p[(addr & 0xfff) >> 2];
978 	} else {
979 		SYNCH_PC;
980 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
981 		    sizeof(data), MEM_READ, CACHE_DATA)) {
982 			/*  Exception.  */
983 			return;
984 		}
985 	}
986 
987 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
988 		data = LE32_TO_HOST(data);
989 	else
990 		data = BE32_TO_HOST(data);
991 	reg(ic->arg[1]) = data;
992 }
X(mov_b_disp_rn_r0)993 X(mov_b_disp_rn_r0)
994 {
995 	uint32_t addr = reg(ic->arg[0]) + ic->arg[1];
996 	uint8_t *p = (uint8_t *) cpu->cd.sh.host_load[addr >> 12];
997 	uint8_t data;
998 
999 	if (p != NULL) {
1000 		data = p[addr & 0xfff];
1001 	} else {
1002 		SYNCH_PC;
1003 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1004 		    sizeof(data), MEM_READ, CACHE_DATA)) {
1005 			/*  Exception.  */
1006 			return;
1007 		}
1008 	}
1009 
1010 	cpu->cd.sh.r[0] = (int8_t) data;
1011 }
X(mov_w_disp_rn_r0)1012 X(mov_w_disp_rn_r0)
1013 {
1014 	uint32_t addr = reg(ic->arg[0]) + ic->arg[1];
1015 	uint16_t *p = (uint16_t *) cpu->cd.sh.host_load[addr >> 12];
1016 	uint16_t data;
1017 
1018 	if (p != NULL) {
1019 		data = p[(addr & 0xfff) >> 1];
1020 	} else {
1021 		SYNCH_PC;
1022 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1023 		    sizeof(data), MEM_READ, CACHE_DATA)) {
1024 			/*  Exception.  */
1025 			return;
1026 		}
1027 	}
1028 
1029 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1030 		data = LE16_TO_HOST(data);
1031 	else
1032 		data = BE16_TO_HOST(data);
1033 	cpu->cd.sh.r[0] = (int16_t) data;
1034 }
1035 
1036 
1037 /*
1038  *  mov_b_store_rm_rn:  Store Rm to address Rn (8-bit).
1039  *  mov_w_store_rm_rn:  Store Rm to address Rn (16-bit).
1040  *  mov_l_store_rm_rn:  Store Rm to address Rn (32-bit).
1041  *  fmov_frm_rn:        Store FRm to address Rn.
1042  *  fmov_frm_r0_rn:     Store FRm to address R0 + Rn.
1043  *  fmov_frm_predec_rn: Store FRm to address Rn - 4 (or 8), update Rn.
1044  *  mov_b_rm_r0_rn:     Store Rm to address Rn + R0 (8-bit).
1045  *  mov_w_rm_r0_rn:     Store Rm to address Rn + R0 (16-bit).
1046  *  mov_l_rm_r0_rn:     Store Rm to address Rn + R0 (32-bit).
1047  *  mov_b_r0_disp_gbr:  Store R0 to address disp + GBR (8-bit).
1048  *  mov_w_r0_disp_gbr:  Store R0 to address disp + GBR (16-bit).
1049  *  mov_l_r0_disp_gbr:  Store R0 to address disp + GBR (32-bit).
1050  *  mov_l_rm_disp_rn:   Store Rm to address disp + Rn.
1051  *  mov_b_r0_disp_rn:   Store R0 to address disp + Rn (8-bit).
1052  *  mov_w_r0_disp_rn:   Store R0 to address disp + Rn (16-bit).
1053  *
1054  *  arg[0] = ptr to rm
1055  *  arg[1] = ptr to rn    (or  Rn+(disp<<4)  for mov_l_rm_disp_rn)
1056  *                        (or  disp          for mov_*_r0_disp_gbr)
1057  */
X(mov_b_store_rm_rn)1058 X(mov_b_store_rm_rn)
1059 {
1060 	uint32_t addr = reg(ic->arg[1]);
1061 	uint8_t *p = (uint8_t *) cpu->cd.sh.host_store[addr >> 12];
1062 	uint8_t data = reg(ic->arg[0]);
1063 
1064 	if (p != NULL) {
1065 		p[addr & 0xfff] = data;
1066 	} else {
1067 		SYNCH_PC;
1068 		if (!cpu->memory_rw(cpu, cpu->mem, addr, &data,
1069 		    sizeof(data), MEM_WRITE, CACHE_DATA)) {
1070 			/*  Exception.  */
1071 			return;
1072 		}
1073 	}
1074 }
X(mov_w_store_rm_rn)1075 X(mov_w_store_rm_rn)
1076 {
1077 	uint32_t addr = reg(ic->arg[1]);
1078 	uint16_t *p = (uint16_t *) cpu->cd.sh.host_store[addr >> 12];
1079 	uint16_t data = reg(ic->arg[0]);
1080 
1081 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1082 		data = LE16_TO_HOST(data);
1083 	else
1084 		data = BE16_TO_HOST(data);
1085 
1086 	if (p != NULL) {
1087 		p[(addr & 0xfff) >> 1] = data;
1088 	} else {
1089 		SYNCH_PC;
1090 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1091 		    sizeof(data), MEM_WRITE, CACHE_DATA)) {
1092 			/*  Exception.  */
1093 			return;
1094 		}
1095 	}
1096 }
X(mov_l_store_rm_rn)1097 X(mov_l_store_rm_rn)
1098 {
1099 	uint32_t addr = reg(ic->arg[1]);
1100 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_store[addr >> 12];
1101 	uint32_t data = reg(ic->arg[0]);
1102 
1103 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1104 		data = LE32_TO_HOST(data);
1105 	else
1106 		data = BE32_TO_HOST(data);
1107 
1108 	if (p != NULL) {
1109 		p[(addr & 0xfff) >> 2] = data;
1110 	} else {
1111 		SYNCH_PC;
1112 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1113 		    sizeof(data), MEM_WRITE, CACHE_DATA)) {
1114 			/*  Exception.  */
1115 			return;
1116 		}
1117 	}
1118 }
X(fmov_frm_rn)1119 X(fmov_frm_rn)
1120 {
1121 	uint32_t addr = reg(ic->arg[1]);
1122 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_store[addr >> 12];
1123 	uint32_t data = reg(ic->arg[0]);
1124 
1125 	FLOATING_POINT_AVAILABLE_CHECK;
1126 
1127 	if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1128 		// Register pair. Store second word first, then fallback
1129 		// to store the first word.
1130 
1131 		// Check if it is to an odd register first.
1132 		size_t r0 = ic->arg[1];
1133 		int ofs = (r0 - (size_t)&cpu->cd.sh.fr[0]) / sizeof(uint32_t);
1134 		if (ofs & 1) {
1135 			fatal("ODD fmov_frm_rn: TODO");
1136 			exit(1);
1137 			r0 = (size_t)&cpu->cd.sh.xf[ofs & ~1];
1138 		}
1139 
1140 		uint32_t data2 = reg(ic->arg[0] + 4);
1141 
1142 		SYNCH_PC;
1143 		if (!cpu->memory_rw(cpu, cpu->mem, addr + 4, (unsigned char *)&data2,
1144 		    sizeof(data2), MEM_WRITE, CACHE_DATA)) {
1145 			/*  Exception.  */
1146 			return;
1147 		}
1148 
1149 		// fall-through to write the first word in the pair:
1150 	}
1151 
1152 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1153 		data = LE32_TO_HOST(data);
1154 	else
1155 		data = BE32_TO_HOST(data);
1156 
1157 	if (p != NULL) {
1158 		p[(addr & 0xfff) >> 2] = data;
1159 	} else {
1160 		SYNCH_PC;
1161 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1162 		    sizeof(data), MEM_WRITE, CACHE_DATA)) {
1163 			/*  Exception.  */
1164 			return;
1165 		}
1166 	}
1167 }
X(fmov_frm_r0_rn)1168 X(fmov_frm_r0_rn)
1169 {
1170 	uint32_t addr = reg(ic->arg[1]) + cpu->cd.sh.r[0];
1171 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_store[addr >> 12];
1172 	uint32_t data = reg(ic->arg[0]);
1173 
1174 	FLOATING_POINT_AVAILABLE_CHECK;
1175 
1176 	if (cpu->cd.sh.fpscr & SH_FPSCR_SZ) {
1177 		fatal("fmov_frm_r0_rn: sz=1 (register pair): TODO\n");
1178 		ABORT_EXECUTION;
1179 		return;
1180 	}
1181 
1182 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1183 		data = LE32_TO_HOST(data);
1184 	else
1185 		data = BE32_TO_HOST(data);
1186 
1187 	if (p != NULL) {
1188 		p[(addr & 0xfff) >> 2] = data;
1189 	} else {
1190 		SYNCH_PC;
1191 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1192 		    sizeof(data), MEM_WRITE, CACHE_DATA)) {
1193 			/*  Exception.  */
1194 			return;
1195 		}
1196 	}
1197 }
X(fmov_frm_predec_rn)1198 X(fmov_frm_predec_rn)
1199 {
1200 	int d = cpu->cd.sh.fpscr & SH_FPSCR_SZ? 1 : 0;
1201 	uint32_t data, addr = reg(ic->arg[1]) - (d? 8 : 4);
1202 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_store[addr >> 12];
1203 	size_t r0 = ic->arg[0];
1204 
1205 	if (d) {
1206 		/*  xd instead of dr?  */
1207 		int ofs0 = (r0 - (size_t)&cpu->cd.sh.fr[0]) / sizeof(uint32_t);
1208 		if (ofs0 & 1)
1209 			r0 = (size_t)&cpu->cd.sh.xf[ofs0 & ~1];
1210 	}
1211 
1212 	data = reg(r0);
1213 
1214 	FLOATING_POINT_AVAILABLE_CHECK;
1215 
1216 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1217 		data = LE32_TO_HOST(data);
1218 	else
1219 		data = BE32_TO_HOST(data);
1220 
1221 	if (p != NULL) {
1222 		p[(addr & 0xfff) >> 2] = data;
1223 	} else {
1224 		SYNCH_PC;
1225 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1226 		    sizeof(data), MEM_WRITE, CACHE_DATA)) {
1227 			/*  Exception.  */
1228 			return;
1229 		}
1230 	}
1231 
1232 	if (d) {
1233 		/*  Store second single-precision floating point word:  */
1234 		data = reg(r0 + 4);
1235 		if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1236 			data = LE32_TO_HOST(data);
1237 		else
1238 			data = BE32_TO_HOST(data);
1239 		SYNCH_PC;
1240 		if (!cpu->memory_rw(cpu, cpu->mem, addr + 4, (unsigned
1241 		    char *)&data, sizeof(data), MEM_WRITE, CACHE_DATA))
1242 			return;
1243 	}
1244 
1245 	reg(ic->arg[1]) = addr;
1246 }
X(mov_b_rm_r0_rn)1247 X(mov_b_rm_r0_rn)
1248 {
1249 	uint32_t addr = reg(ic->arg[1]) + cpu->cd.sh.r[0];
1250 	int8_t *p = (int8_t *) cpu->cd.sh.host_store[addr >> 12];
1251 	int8_t data = reg(ic->arg[0]);
1252 	if (p != NULL) {
1253 		p[addr & 0xfff] = data;
1254 	} else {
1255 		SYNCH_PC;
1256 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1257 		    sizeof(data), MEM_WRITE, CACHE_DATA)) {
1258 			/*  Exception.  */
1259 			return;
1260 		}
1261 	}
1262 }
X(mov_w_rm_r0_rn)1263 X(mov_w_rm_r0_rn)
1264 {
1265 	uint32_t addr = reg(ic->arg[1]) + cpu->cd.sh.r[0];
1266 	uint16_t *p = (uint16_t *) cpu->cd.sh.host_store[addr >> 12];
1267 	uint16_t data = reg(ic->arg[0]);
1268 
1269 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1270 		data = LE16_TO_HOST(data);
1271 	else
1272 		data = BE16_TO_HOST(data);
1273 
1274 	if (p != NULL) {
1275 		p[(addr & 0xfff) >> 1] = data;
1276 	} else {
1277 		SYNCH_PC;
1278 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1279 		    sizeof(data), MEM_WRITE, CACHE_DATA)) {
1280 			/*  Exception.  */
1281 			return;
1282 		}
1283 	}
1284 }
X(mov_l_rm_r0_rn)1285 X(mov_l_rm_r0_rn)
1286 {
1287 	uint32_t addr = reg(ic->arg[1]) + cpu->cd.sh.r[0];
1288 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_store[addr >> 12];
1289 	uint32_t data = reg(ic->arg[0]);
1290 
1291 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1292 		data = LE32_TO_HOST(data);
1293 	else
1294 		data = BE32_TO_HOST(data);
1295 
1296 	if (p != NULL) {
1297 		p[(addr & 0xfff) >> 2] = data;
1298 	} else {
1299 		SYNCH_PC;
1300 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1301 		    sizeof(data), MEM_WRITE, CACHE_DATA)) {
1302 			/*  Exception.  */
1303 			return;
1304 		}
1305 	}
1306 }
X(mov_b_r0_disp_gbr)1307 X(mov_b_r0_disp_gbr)
1308 {
1309 	uint32_t addr = cpu->cd.sh.gbr + ic->arg[1];
1310 	uint8_t *p = (uint8_t *) cpu->cd.sh.host_store[addr >> 12];
1311 	uint8_t data = cpu->cd.sh.r[0];
1312 	if (p != NULL) {
1313 		p[addr & 0xfff] = data;
1314 	} else {
1315 		SYNCH_PC;
1316 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1317 		    sizeof(data), MEM_WRITE, CACHE_DATA)) {
1318 			/*  Exception.  */
1319 			return;
1320 		}
1321 	}
1322 }
X(mov_w_r0_disp_gbr)1323 X(mov_w_r0_disp_gbr)
1324 {
1325 	uint32_t addr = cpu->cd.sh.gbr + ic->arg[1];
1326 	uint16_t *p = (uint16_t *) cpu->cd.sh.host_store[addr >> 12];
1327 	uint16_t data = cpu->cd.sh.r[0];
1328 
1329 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1330 		data = LE16_TO_HOST(data);
1331 	else
1332 		data = BE16_TO_HOST(data);
1333 
1334 	if (p != NULL) {
1335 		p[(addr & 0xfff) >> 1] = data;
1336 	} else {
1337 		SYNCH_PC;
1338 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1339 		    sizeof(data), MEM_WRITE, CACHE_DATA)) {
1340 			/*  Exception.  */
1341 			return;
1342 		}
1343 	}
1344 }
X(mov_l_r0_disp_gbr)1345 X(mov_l_r0_disp_gbr)
1346 {
1347 	uint32_t addr = cpu->cd.sh.gbr + ic->arg[1];
1348 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_store[addr >> 12];
1349 	uint32_t data = cpu->cd.sh.r[0];
1350 
1351 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1352 		data = LE32_TO_HOST(data);
1353 	else
1354 		data = BE32_TO_HOST(data);
1355 
1356 	if (p != NULL) {
1357 		p[(addr & 0xfff) >> 2] = data;
1358 	} else {
1359 		SYNCH_PC;
1360 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1361 		    sizeof(data), MEM_WRITE, CACHE_DATA)) {
1362 			/*  Exception.  */
1363 			return;
1364 		}
1365 	}
1366 }
X(mov_l_rm_disp_rn)1367 X(mov_l_rm_disp_rn)
1368 {
1369 	uint32_t addr = cpu->cd.sh.r[ic->arg[1] & 0xf] +
1370 	    ((ic->arg[1] >> 4) << 2);
1371 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_store[addr >> 12];
1372 	uint32_t data = reg(ic->arg[0]);
1373 
1374 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1375 		data = LE32_TO_HOST(data);
1376 	else
1377 		data = BE32_TO_HOST(data);
1378 
1379 	if (p != NULL) {
1380 		p[(addr & 0xfff) >> 2] = data;
1381 	} else {
1382 		SYNCH_PC;
1383 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1384 		    sizeof(data), MEM_WRITE, CACHE_DATA)) {
1385 			/*  Exception.  */
1386 			return;
1387 		}
1388 	}
1389 }
X(mov_b_r0_disp_rn)1390 X(mov_b_r0_disp_rn)
1391 {
1392 	uint32_t addr = reg(ic->arg[0]) + ic->arg[1];
1393 	uint8_t *p = (uint8_t *) cpu->cd.sh.host_store[addr >> 12];
1394 	uint8_t data = cpu->cd.sh.r[0];
1395 
1396 	if (p != NULL) {
1397 		p[addr & 0xfff] = data;
1398 	} else {
1399 		SYNCH_PC;
1400 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1401 		    sizeof(data), MEM_WRITE, CACHE_DATA)) {
1402 			/*  Exception.  */
1403 			return;
1404 		}
1405 	}
1406 }
X(mov_w_r0_disp_rn)1407 X(mov_w_r0_disp_rn)
1408 {
1409 	uint32_t addr = reg(ic->arg[0]) + ic->arg[1];
1410 	uint16_t *p = (uint16_t *) cpu->cd.sh.host_store[addr >> 12];
1411 	uint16_t data = cpu->cd.sh.r[0];
1412 
1413 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1414 		data = LE16_TO_HOST(data);
1415 	else
1416 		data = BE16_TO_HOST(data);
1417 
1418 	if (p != NULL) {
1419 		p[(addr & 0xfff) >> 1] = data;
1420 	} else {
1421 		SYNCH_PC;
1422 		if (!cpu->memory_rw(cpu, cpu->mem, addr, (unsigned char *)&data,
1423 		    sizeof(data), MEM_WRITE, CACHE_DATA)) {
1424 			/*  Exception.  */
1425 			return;
1426 		}
1427 	}
1428 }
1429 
1430 
1431 /*
1432  *  add_rm_rn:  rn = rn + rm
1433  *  addc_rm_rn: rn = rn + rm + t
1434  *  and_rm_rn:  rn = rn & rm
1435  *  xor_rm_rn:  rn = rn ^ rm
1436  *  or_rm_rn:   rn = rn | rm
1437  *  sub_rm_rn:  rn = rn - rm
1438  *  subc_rm_rn: rn = rn - rm - t; t = borrow
1439  *  tst_rm_rn:  t = ((rm & rn) == 0)
1440  *  tst_rm:     t = (rm == 0)
1441  *  xtrct_rm_rn:  rn = (rn >> 16) | (rm << 16)
1442  *
1443  *  arg[0] = ptr to rm
1444  *  arg[1] = ptr to rn
1445  */
X(add_rm_rn)1446 X(add_rm_rn) { reg(ic->arg[1]) += reg(ic->arg[0]); }
X(addc_rm_rn)1447 X(addc_rm_rn)
1448 {
1449 	uint64_t res = reg(ic->arg[1]);
1450 	res += (uint64_t) reg(ic->arg[0]);
1451 	if (cpu->cd.sh.sr & SH_SR_T)
1452 		res ++;
1453 	if ((res >> 32) & 1)
1454 		cpu->cd.sh.sr |= SH_SR_T;
1455 	else
1456 		cpu->cd.sh.sr &= ~SH_SR_T;
1457 	reg(ic->arg[1]) = (uint32_t) res;
1458 }
X(and_rm_rn)1459 X(and_rm_rn) { reg(ic->arg[1]) &= reg(ic->arg[0]); }
X(xor_rm_rn)1460 X(xor_rm_rn) { reg(ic->arg[1]) ^= reg(ic->arg[0]); }
X(or_rm_rn)1461 X(or_rm_rn)  { reg(ic->arg[1]) |= reg(ic->arg[0]); }
X(sub_rm_rn)1462 X(sub_rm_rn) { reg(ic->arg[1]) -= reg(ic->arg[0]); }
X(subc_rm_rn)1463 X(subc_rm_rn)
1464 {
1465 	uint64_t res = reg(ic->arg[1]);
1466 	res -= (uint64_t) reg(ic->arg[0]);
1467 	if (cpu->cd.sh.sr & SH_SR_T)
1468 		res --;
1469 	if ((res >> 32) & 1)
1470 		cpu->cd.sh.sr |= SH_SR_T;
1471 	else
1472 		cpu->cd.sh.sr &= ~SH_SR_T;
1473 	reg(ic->arg[1]) = (uint32_t) res;
1474 }
X(tst_rm_rn)1475 X(tst_rm_rn)
1476 {
1477 	if (reg(ic->arg[1]) & reg(ic->arg[0]))
1478 		cpu->cd.sh.sr &= ~SH_SR_T;
1479 	else
1480 		cpu->cd.sh.sr |= SH_SR_T;
1481 }
X(tst_rm)1482 X(tst_rm)
1483 {
1484 	if (reg(ic->arg[0]))
1485 		cpu->cd.sh.sr &= ~SH_SR_T;
1486 	else
1487 		cpu->cd.sh.sr |= SH_SR_T;
1488 }
X(xtrct_rm_rn)1489 X(xtrct_rm_rn)
1490 {
1491 	uint32_t rn = reg(ic->arg[1]), rm = reg(ic->arg[0]);
1492 	reg(ic->arg[1]) = (rn >> 16) | (rm << 16);
1493 }
1494 
1495 
1496 /*
1497  *  div0u:       Division step 0; prepare for unsigned division.
1498  *  div0s_rm_rn: Division step 0; prepare for signed division.
1499  *  div1_rm_rn:  Division step 1.
1500  *
1501  *  arg[0] = ptr to rm
1502  *  arg[1] = ptr to rn
1503  */
X(div0u)1504 X(div0u)
1505 {
1506 	cpu->cd.sh.sr &= ~(SH_SR_Q | SH_SR_M | SH_SR_T);
1507 }
X(div0s_rm_rn)1508 X(div0s_rm_rn)
1509 {
1510 	int q = reg(ic->arg[1]) & 0x80000000;
1511 	int m = reg(ic->arg[0]) & 0x80000000;
1512 	uint32_t new_sr = cpu->cd.sh.sr & ~(SH_SR_Q | SH_SR_M | SH_SR_T);
1513 	if (q)
1514 		new_sr |= SH_SR_Q;
1515 	if (m)
1516 		new_sr |= SH_SR_M;
1517 	if (m ^ q)
1518 		new_sr |= SH_SR_T;
1519 	cpu->cd.sh.sr = new_sr;
1520 }
X(div1_rm_rn)1521 X(div1_rm_rn)
1522 {
1523 	uint32_t q, old_q = (cpu->cd.sh.sr & SH_SR_Q)? 1 : 0;
1524 	uint32_t m = (cpu->cd.sh.sr & SH_SR_M)? 1 : 0;
1525 	uint32_t t = (cpu->cd.sh.sr & SH_SR_T)? 1 : 0;
1526 	uint32_t op1 = reg(ic->arg[0]), op2 = reg(ic->arg[1]);
1527 	uint64_t op2_64;
1528 
1529 	q = op2 >> 31;
1530 	op2_64 = (uint32_t) ((op2 << 1) + t);
1531 	if (old_q == m)
1532 		op2_64 -= (uint64_t)op1;
1533 	else
1534 		op2_64 += (uint64_t)op1;
1535 	q ^= m ^ ((op2_64 >> 32) & 1);
1536 	t = 1 - (q ^ m);
1537 	cpu->cd.sh.sr &= ~(SH_SR_Q | SH_SR_T);
1538 	if (q)
1539 		cpu->cd.sh.sr |= SH_SR_Q;
1540 	if (t)
1541 		cpu->cd.sh.sr |= SH_SR_T;
1542 	reg(ic->arg[1]) = (uint32_t) op2_64;
1543 }
1544 
1545 
1546 /*
1547  *  mul_l_rm_rn:   MACL = Rm * Rn       (32-bit)
1548  *  muls_w_rm_rn:  MACL = Rm * Rn       (signed 16-bit * 16-bit ==> 32-bit)
1549  *  mulu_w_rm_rn:  MACL = Rm * Rn       (unsigned 16-bit * 16-bit ==> 32-bit)
1550  *  dmuls_l_rm_rn: MACH:MACL = Rm * Rn  (signed, 64-bit result)
1551  *  dmulu_l_rm_rn: MACH:MACL = Rm * Rn  (unsigned, 64-bit result)
1552  *
1553  *  arg[0] = ptr to rm
1554  *  arg[1] = ptr to rn
1555  */
X(mul_l_rm_rn)1556 X(mul_l_rm_rn)
1557 {
1558 	cpu->cd.sh.macl = reg(ic->arg[0]) * reg(ic->arg[1]);
1559 }
X(muls_w_rm_rn)1560 X(muls_w_rm_rn)
1561 {
1562 	cpu->cd.sh.macl = (int32_t)(int16_t)reg(ic->arg[0]) *
1563 	    (int32_t)(int16_t)reg(ic->arg[1]);
1564 }
X(mulu_w_rm_rn)1565 X(mulu_w_rm_rn)
1566 {
1567 	cpu->cd.sh.macl = (int32_t)(uint16_t)reg(ic->arg[0]) *
1568 	    (int32_t)(uint16_t)reg(ic->arg[1]);
1569 }
X(dmuls_l_rm_rn)1570 X(dmuls_l_rm_rn)
1571 {
1572 	uint64_t rm = (int32_t)reg(ic->arg[0]), rn = (int32_t)reg(ic->arg[1]);
1573 	uint64_t res = rm * rn;
1574 	cpu->cd.sh.mach = (uint32_t) (res >> 32);
1575 	cpu->cd.sh.macl = (uint32_t) res;
1576 }
X(dmulu_l_rm_rn)1577 X(dmulu_l_rm_rn)
1578 {
1579 	uint64_t rm = reg(ic->arg[0]), rn = reg(ic->arg[1]), res;
1580 	res = rm * rn;
1581 	cpu->cd.sh.mach = (uint32_t) (res >> 32);
1582 	cpu->cd.sh.macl = (uint32_t) res;
1583 }
1584 
1585 
1586 /*
1587  *  cmpeq_imm_r0:  rn == int8_t immediate
1588  *  cmpeq_rm_rn:   rn == rm
1589  *  cmphs_rm_rn:   rn >= rm, unsigned
1590  *  cmpge_rm_rn:   rn >= rm, signed
1591  *  cmphi_rm_rn:   rn > rm, unsigned
1592  *  cmpgt_rm_rn:   rn > rm, signed
1593  *  cmppz_rn:      rn >= 0, signed
1594  *  cmppl_rn:      rn > 0, signed
1595  *  cmp_str_rm_rn: t=1 if any bytes in rm and rn match, 0 otherwise
1596  *
1597  *  arg[0] = ptr to rm   (or imm, for cmpeq_imm_r0)
1598  *  arg[1] = ptr to rn
1599  */
X(cmpeq_imm_r0)1600 X(cmpeq_imm_r0)
1601 {
1602 	if (cpu->cd.sh.r[0] == (uint32_t)ic->arg[0])
1603 		cpu->cd.sh.sr |= SH_SR_T;
1604 	else
1605 		cpu->cd.sh.sr &= ~SH_SR_T;
1606 }
X(cmpeq_rm_rn)1607 X(cmpeq_rm_rn)
1608 {
1609 	if (reg(ic->arg[1]) == reg(ic->arg[0]))
1610 		cpu->cd.sh.sr |= SH_SR_T;
1611 	else
1612 		cpu->cd.sh.sr &= ~SH_SR_T;
1613 }
X(cmphs_rm_rn)1614 X(cmphs_rm_rn)
1615 {
1616 	if (reg(ic->arg[1]) >= reg(ic->arg[0]))
1617 		cpu->cd.sh.sr |= SH_SR_T;
1618 	else
1619 		cpu->cd.sh.sr &= ~SH_SR_T;
1620 }
X(cmpge_rm_rn)1621 X(cmpge_rm_rn)
1622 {
1623 	if ((int32_t)reg(ic->arg[1]) >= (int32_t)reg(ic->arg[0]))
1624 		cpu->cd.sh.sr |= SH_SR_T;
1625 	else
1626 		cpu->cd.sh.sr &= ~SH_SR_T;
1627 }
X(cmphi_rm_rn)1628 X(cmphi_rm_rn)
1629 {
1630 	if (reg(ic->arg[1]) > reg(ic->arg[0]))
1631 		cpu->cd.sh.sr |= SH_SR_T;
1632 	else
1633 		cpu->cd.sh.sr &= ~SH_SR_T;
1634 }
X(cmpgt_rm_rn)1635 X(cmpgt_rm_rn)
1636 {
1637 	if ((int32_t)reg(ic->arg[1]) > (int32_t)reg(ic->arg[0]))
1638 		cpu->cd.sh.sr |= SH_SR_T;
1639 	else
1640 		cpu->cd.sh.sr &= ~SH_SR_T;
1641 }
X(cmppz_rn)1642 X(cmppz_rn)
1643 {
1644 	if ((int32_t)reg(ic->arg[1]) >= 0)
1645 		cpu->cd.sh.sr |= SH_SR_T;
1646 	else
1647 		cpu->cd.sh.sr &= ~SH_SR_T;
1648 }
X(cmppl_rn)1649 X(cmppl_rn)
1650 {
1651 	if ((int32_t)reg(ic->arg[1]) > 0)
1652 		cpu->cd.sh.sr |= SH_SR_T;
1653 	else
1654 		cpu->cd.sh.sr &= ~SH_SR_T;
1655 }
X(cmp_str_rm_rn)1656 X(cmp_str_rm_rn)
1657 {
1658 	uint32_t r0 = reg(ic->arg[0]), r1 = reg(ic->arg[1]);
1659 	int t = 0;
1660 	if ((r0 & 0xff000000) == (r1 & 0xff000000))
1661 		t = 1;
1662 	else if ((r0 & 0xff0000) == (r1 & 0xff0000))
1663 		t = 1;
1664 	else if ((r0 & 0xff00) == (r1 & 0xff00))
1665 		t = 1;
1666 	else if ((r0 & 0xff) == (r1 & 0xff))
1667 		t = 1;
1668 	if (t)
1669 		cpu->cd.sh.sr |= SH_SR_T;
1670 	else
1671 		cpu->cd.sh.sr &= ~SH_SR_T;
1672 }
1673 
1674 
1675 /*
1676  *  shll_rn:  Shift rn left by 1  (t = bit that was shifted out)
1677  *  shlr_rn:  Shift rn right by 1 (t = bit that was shifted out)
1678  *  rotl_rn:  Shift rn left by 1  (t = bit that was shifted out)
1679  *  rotr_rn:  Shift rn right by 1 (t = bit that was shifted out)
1680  *  shar_rn:  Shift rn right arithmetically by 1 (t = bit that was shifted out)
1681  *  shllX_rn: Shift rn left logically by X bits
1682  *  shlrX_rn: Shift rn right logically by X bits
1683  *  rotcl_rn: Rotate rn left via the t bit
1684  *  rotcr_rn: Rotate rn right via the t bit
1685  *  dt_rn:    Decrease rn; t = (rn == 0)
1686  *
1687  *  arg[1] = ptr to rn
1688  */
X(shll_rn)1689 X(shll_rn)
1690 {
1691 	uint32_t rn = reg(ic->arg[1]);
1692 	if (rn & 0x80000000)
1693 		cpu->cd.sh.sr |= SH_SR_T;
1694 	else
1695 		cpu->cd.sh.sr &= ~SH_SR_T;
1696 	reg(ic->arg[1]) = rn << 1;
1697 }
X(shlr_rn)1698 X(shlr_rn)
1699 {
1700 	uint32_t rn = reg(ic->arg[1]);
1701 	if (rn & 1)
1702 		cpu->cd.sh.sr |= SH_SR_T;
1703 	else
1704 		cpu->cd.sh.sr &= ~SH_SR_T;
1705 	reg(ic->arg[1]) = rn >> 1;
1706 }
X(rotl_rn)1707 X(rotl_rn)
1708 {
1709 	uint32_t rn = reg(ic->arg[1]), x;
1710 	if (rn & 0x80000000) {
1711 		x = 1;
1712 		cpu->cd.sh.sr |= SH_SR_T;
1713 	} else {
1714 		x = 0;
1715 		cpu->cd.sh.sr &= ~SH_SR_T;
1716 	}
1717 	reg(ic->arg[1]) = (rn << 1) | x;
1718 }
X(rotr_rn)1719 X(rotr_rn)
1720 {
1721 	uint32_t rn = reg(ic->arg[1]);
1722 	if (rn & 1)
1723 		cpu->cd.sh.sr |= SH_SR_T;
1724 	else
1725 		cpu->cd.sh.sr &= ~SH_SR_T;
1726 	reg(ic->arg[1]) = (rn >> 1) | (rn << 31);
1727 }
X(shar_rn)1728 X(shar_rn)
1729 {
1730 	int32_t rn = reg(ic->arg[1]);
1731 	if (rn & 1)
1732 		cpu->cd.sh.sr |= SH_SR_T;
1733 	else
1734 		cpu->cd.sh.sr &= ~SH_SR_T;
1735 	reg(ic->arg[1]) = rn >> 1;
1736 }
X(rotcl_rn)1737 X(rotcl_rn)
1738 {
1739 	uint32_t rn = reg(ic->arg[1]), top;
1740 	top = rn & 0x80000000;
1741 	rn <<= 1;
1742 	if (cpu->cd.sh.sr & SH_SR_T)
1743 		rn ++;
1744 	if (top)
1745 		cpu->cd.sh.sr |= SH_SR_T;
1746 	else
1747 		cpu->cd.sh.sr &= ~SH_SR_T;
1748 	reg(ic->arg[1]) = rn;
1749 }
X(rotcr_rn)1750 X(rotcr_rn)
1751 {
1752 	uint32_t rn = reg(ic->arg[1]), bottom;
1753 	bottom = rn & 1;
1754 	rn >>= 1;
1755 	if (cpu->cd.sh.sr & SH_SR_T)
1756 		rn |= 0x80000000;
1757 	if (bottom)
1758 		cpu->cd.sh.sr |= SH_SR_T;
1759 	else
1760 		cpu->cd.sh.sr &= ~SH_SR_T;
1761 	reg(ic->arg[1]) = rn;
1762 }
X(dt_rn)1763 X(dt_rn)
1764 {
1765 	uint32_t rn = reg(ic->arg[1]) - 1;
1766 	if (rn == 0)
1767 		cpu->cd.sh.sr |= SH_SR_T;
1768 	else
1769 		cpu->cd.sh.sr &= ~SH_SR_T;
1770 	reg(ic->arg[1]) = rn;
1771 }
X(shll2_rn)1772 X(shll2_rn) { reg(ic->arg[1]) <<= 2; }
X(shll8_rn)1773 X(shll8_rn) { reg(ic->arg[1]) <<= 8; }
X(shll16_rn)1774 X(shll16_rn) { reg(ic->arg[1]) <<= 16; }
X(shlr2_rn)1775 X(shlr2_rn) { reg(ic->arg[1]) >>= 2; }
X(shlr8_rn)1776 X(shlr8_rn) { reg(ic->arg[1]) >>= 8; }
X(shlr16_rn)1777 X(shlr16_rn) { reg(ic->arg[1]) >>= 16; }
1778 
1779 
1780 /*
1781  *  shad: Shift Rn arithmetic left/right, as indicated by Rm. Result in Rn.
1782  *  shld: Shift Rn logically left/right, as indicated by Rm. Result in Rn.
1783  *
1784  *  arg[0] = ptr to rm
1785  *  arg[1] = ptr to rn
1786  */
X(shad)1787 X(shad)
1788 {
1789 	int32_t rn = reg(ic->arg[1]);
1790 	int32_t rm = reg(ic->arg[0]);
1791 	int sa = rm & 0x1f;
1792 
1793 	if (rm >= 0)
1794 		rn <<= sa;
1795 	else if (sa != 0)
1796 		rn >>= (32 - sa);
1797 	else if (rn < 0)
1798 		rn = -1;
1799 	else
1800 		rn = 0;
1801 
1802 	reg(ic->arg[1]) = rn;
1803 }
X(shld)1804 X(shld)
1805 {
1806 	uint32_t rn = reg(ic->arg[1]);
1807 	int32_t rm = reg(ic->arg[0]);
1808 	int sa = rm & 0x1f;
1809 
1810 	if (rm >= 0)
1811 		rn <<= sa;
1812 	else if (sa != 0)
1813 		rn >>= (32 - sa);
1814 	else
1815 		rn = 0;
1816 
1817 	reg(ic->arg[1]) = rn;
1818 }
1819 
1820 
1821 /*
1822  *  bra:   Branch using PC relative immediace displacement (with delay-slot)
1823  *  bsr:   Like bra, but also sets PR to the return address
1824  *  braf:  Like bra, but using a register instead of an immediate
1825  *  bsrf:  Like braf, but also sets PR to the return address
1826  *
1827  *  arg[0] = immediate offset relative to start of page,
1828  *           or ptr to target instruction, for samepage branches
1829  *  arg[1] = ptr to Rn  (for braf/bsrf)
1830  */
X(bra)1831 X(bra)
1832 {
1833 	MODE_int_t target = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<
1834 	    SH_INSTR_ALIGNMENT_SHIFT);
1835 	target += ic->arg[0];
1836 	cpu->delay_slot = TO_BE_DELAYED;
1837 	ic[1].f(cpu, ic+1);
1838 	cpu->n_translated_instrs ++;
1839 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
1840 		cpu->pc = target;
1841 		cpu->delay_slot = NOT_DELAYED;
1842 		quick_pc_to_pointers(cpu);
1843 	} else
1844 		cpu->delay_slot = NOT_DELAYED;
1845 }
X(bra_samepage)1846 X(bra_samepage)
1847 {
1848 	cpu->delay_slot = TO_BE_DELAYED;
1849 	ic[1].f(cpu, ic+1);
1850 	cpu->n_translated_instrs ++;
1851 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))
1852 		cpu->cd.sh.next_ic = (struct sh_instr_call *) ic->arg[0];
1853 	cpu->delay_slot = NOT_DELAYED;
1854 }
X(bsr)1855 X(bsr)
1856 {
1857 	MODE_int_t target = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<
1858 	    SH_INSTR_ALIGNMENT_SHIFT);
1859 	uint32_t old_pc;
1860 	SYNCH_PC;
1861 	old_pc = cpu->pc;
1862 	target += ic->arg[0];
1863 	cpu->delay_slot = TO_BE_DELAYED;
1864 	ic[1].f(cpu, ic+1);
1865 	cpu->n_translated_instrs ++;
1866 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
1867 		cpu->cd.sh.pr = old_pc + 4;
1868 		cpu->pc = target;
1869 		cpu->delay_slot = NOT_DELAYED;
1870 		quick_pc_to_pointers(cpu);
1871 	} else
1872 		cpu->delay_slot = NOT_DELAYED;
1873 }
X(bsr_trace)1874 X(bsr_trace)
1875 {
1876 	MODE_int_t target = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<
1877 	    SH_INSTR_ALIGNMENT_SHIFT);
1878 	uint32_t old_pc;
1879 	SYNCH_PC;
1880 	old_pc = cpu->pc;
1881 	target += ic->arg[0];
1882 	cpu->delay_slot = TO_BE_DELAYED;
1883 	ic[1].f(cpu, ic+1);
1884 	cpu->n_translated_instrs ++;
1885 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
1886 		cpu->cd.sh.pr = old_pc + 4;
1887 		cpu->pc = target;
1888 		cpu_functioncall_trace(cpu, cpu->pc);
1889 		cpu->delay_slot = NOT_DELAYED;
1890 		quick_pc_to_pointers(cpu);
1891 	} else
1892 		cpu->delay_slot = NOT_DELAYED;
1893 }
X(bsr_samepage)1894 X(bsr_samepage)
1895 {
1896 	uint32_t old_pc;
1897 	SYNCH_PC;
1898 	old_pc = cpu->pc;
1899 	cpu->delay_slot = TO_BE_DELAYED;
1900 	ic[1].f(cpu, ic+1);
1901 	cpu->n_translated_instrs ++;
1902 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
1903 		cpu->cd.sh.pr = old_pc + 4;
1904 		cpu->cd.sh.next_ic = (struct sh_instr_call *) ic->arg[0];
1905 	}
1906 	cpu->delay_slot = NOT_DELAYED;
1907 }
X(braf_rn)1908 X(braf_rn)
1909 {
1910 	MODE_int_t target = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<
1911 	    SH_INSTR_ALIGNMENT_SHIFT);
1912 	target += ic->arg[0] + reg(ic->arg[1]);
1913 	cpu->delay_slot = TO_BE_DELAYED;
1914 	ic[1].f(cpu, ic+1);
1915 	cpu->n_translated_instrs ++;
1916 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
1917 		cpu->pc = target;
1918 		cpu->delay_slot = NOT_DELAYED;
1919 		quick_pc_to_pointers(cpu);
1920 	} else
1921 		cpu->delay_slot = NOT_DELAYED;
1922 }
X(bsrf_rn)1923 X(bsrf_rn)
1924 {
1925 	MODE_int_t target = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<
1926 	    SH_INSTR_ALIGNMENT_SHIFT);
1927 	uint32_t old_pc;
1928 	SYNCH_PC;
1929 	old_pc = cpu->pc;
1930 	target += ic->arg[0] + reg(ic->arg[1]);
1931 	cpu->delay_slot = TO_BE_DELAYED;
1932 	ic[1].f(cpu, ic+1);
1933 	cpu->n_translated_instrs ++;
1934 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
1935 		cpu->cd.sh.pr = old_pc + 4;
1936 		cpu->pc = target;
1937 		cpu->delay_slot = NOT_DELAYED;
1938 		quick_pc_to_pointers(cpu);
1939 	} else
1940 		cpu->delay_slot = NOT_DELAYED;
1941 }
X(bsrf_rn_trace)1942 X(bsrf_rn_trace)
1943 {
1944 	MODE_int_t target = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<
1945 	    SH_INSTR_ALIGNMENT_SHIFT);
1946 	uint32_t old_pc;
1947 	SYNCH_PC;
1948 	old_pc = cpu->pc;
1949 	target += ic->arg[0] + reg(ic->arg[1]);
1950 	cpu->delay_slot = TO_BE_DELAYED;
1951 	ic[1].f(cpu, ic+1);
1952 	cpu->n_translated_instrs ++;
1953 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
1954 		cpu->cd.sh.pr = old_pc + 4;
1955 		cpu->pc = target;
1956 		cpu_functioncall_trace(cpu, cpu->pc);
1957 		cpu->delay_slot = NOT_DELAYED;
1958 		quick_pc_to_pointers(cpu);
1959 	} else
1960 		cpu->delay_slot = NOT_DELAYED;
1961 }
1962 
1963 
1964 /*
1965  *  bt: Branch if true
1966  *  bf: Branch if false
1967  *  bt/s: Branch if true (with delay-slot)
1968  *  bf/s: Branch if false (with delay-slot)
1969  *
1970  *  arg[0] = immediate offset relative to start of page
1971  *  arg[1] = for samepage functions, the new instruction pointer
1972  */
X(bt)1973 X(bt)
1974 {
1975 	if (cpu->cd.sh.sr & SH_SR_T) {
1976 		cpu->pc &= ~((SH_IC_ENTRIES_PER_PAGE-1) <<
1977 		    SH_INSTR_ALIGNMENT_SHIFT);
1978 		cpu->pc += ic->arg[0];
1979 		quick_pc_to_pointers(cpu);
1980 	}
1981 }
X(bf)1982 X(bf)
1983 {
1984 	if (!(cpu->cd.sh.sr & SH_SR_T)) {
1985 		cpu->pc &= ~((SH_IC_ENTRIES_PER_PAGE-1) <<
1986 		    SH_INSTR_ALIGNMENT_SHIFT);
1987 		cpu->pc += ic->arg[0];
1988 		quick_pc_to_pointers(cpu);
1989 	}
1990 }
X(bt_samepage)1991 X(bt_samepage)
1992 {
1993 	if (cpu->cd.sh.sr & SH_SR_T)
1994 		cpu->cd.sh.next_ic = (struct sh_instr_call *) ic->arg[1];
1995 }
X(bf_samepage)1996 X(bf_samepage)
1997 {
1998 	if (!(cpu->cd.sh.sr & SH_SR_T))
1999 		cpu->cd.sh.next_ic = (struct sh_instr_call *) ic->arg[1];
2000 }
X(bt_s)2001 X(bt_s)
2002 {
2003 	MODE_int_t target = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<
2004 	    SH_INSTR_ALIGNMENT_SHIFT);
2005 	int cond = cpu->cd.sh.sr & SH_SR_T;
2006 	target += ic->arg[0];
2007 	cpu->delay_slot = TO_BE_DELAYED;
2008 	ic[1].f(cpu, ic+1);
2009 	cpu->n_translated_instrs ++;
2010 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
2011 		cpu->delay_slot = NOT_DELAYED;
2012 		if (cond) {
2013 			cpu->pc = target;
2014 			quick_pc_to_pointers(cpu);
2015 		} else
2016 			cpu->cd.sh.next_ic ++;
2017 	} else
2018 		cpu->delay_slot = NOT_DELAYED;
2019 }
X(bf_s)2020 X(bf_s)
2021 {
2022 	MODE_int_t target = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<
2023 	    SH_INSTR_ALIGNMENT_SHIFT);
2024 	int cond = !(cpu->cd.sh.sr & SH_SR_T);
2025 	target += ic->arg[0];
2026 	cpu->delay_slot = TO_BE_DELAYED;
2027 	ic[1].f(cpu, ic+1);
2028 	cpu->n_translated_instrs ++;
2029 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
2030 		cpu->delay_slot = NOT_DELAYED;
2031 		if (cond) {
2032 			cpu->pc = target;
2033 			quick_pc_to_pointers(cpu);
2034 		} else
2035 			cpu->cd.sh.next_ic ++;
2036 	} else
2037 		cpu->delay_slot = NOT_DELAYED;
2038 }
X(bt_s_samepage)2039 X(bt_s_samepage)
2040 {
2041 	int cond = cpu->cd.sh.sr & SH_SR_T;
2042 	cpu->delay_slot = TO_BE_DELAYED;
2043 	ic[1].f(cpu, ic+1);
2044 	cpu->n_translated_instrs ++;
2045 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
2046 		cpu->delay_slot = NOT_DELAYED;
2047 		if (cond)
2048 			cpu->cd.sh.next_ic =
2049 			    (struct sh_instr_call *) ic->arg[1];
2050 		else
2051 			cpu->cd.sh.next_ic ++;
2052 	} else
2053 		cpu->delay_slot = NOT_DELAYED;
2054 }
X(bf_s_samepage)2055 X(bf_s_samepage)
2056 {
2057 	int cond = !(cpu->cd.sh.sr & SH_SR_T);
2058 	cpu->delay_slot = TO_BE_DELAYED;
2059 	ic[1].f(cpu, ic+1);
2060 	cpu->n_translated_instrs ++;
2061 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
2062 		cpu->delay_slot = NOT_DELAYED;
2063 		if (cond)
2064 			cpu->cd.sh.next_ic =
2065 			    (struct sh_instr_call *) ic->arg[1];
2066 		else
2067 			cpu->cd.sh.next_ic ++;
2068 	} else
2069 		cpu->delay_slot = NOT_DELAYED;
2070 }
2071 
2072 
2073 /*
2074  *  jmp_rn: Jump to Rn
2075  *  jsr_rn: Jump to Rn, store return address in PR.
2076  *
2077  *  arg[0] = ptr to rn
2078  */
X(jmp_rn)2079 X(jmp_rn)
2080 {
2081 	MODE_int_t target = reg(ic->arg[0]);
2082 	cpu->delay_slot = TO_BE_DELAYED;
2083 	ic[1].f(cpu, ic+1);
2084 	cpu->n_translated_instrs ++;
2085 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
2086 		cpu->pc = target;
2087 		cpu->delay_slot = NOT_DELAYED;
2088 		quick_pc_to_pointers(cpu);
2089 	} else
2090 		cpu->delay_slot = NOT_DELAYED;
2091 }
X(jmp_rn_trace)2092 X(jmp_rn_trace)
2093 {
2094 	MODE_int_t target = reg(ic->arg[0]);
2095 	cpu->delay_slot = TO_BE_DELAYED;
2096 	ic[1].f(cpu, ic+1);
2097 	cpu->n_translated_instrs ++;
2098 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
2099 		cpu->pc = target;
2100 #if 0
2101 		/*  NOTE: Jmp works like both a return, and a subroutine
2102 		    call.  */
2103 		cpu_functioncall_trace_return(cpu);
2104 		cpu_functioncall_trace(cpu, cpu->pc);
2105 #endif
2106 		cpu->delay_slot = NOT_DELAYED;
2107 		quick_pc_to_pointers(cpu);
2108 	} else
2109 		cpu->delay_slot = NOT_DELAYED;
2110 }
X(jsr_rn)2111 X(jsr_rn)
2112 {
2113 	MODE_int_t target = reg(ic->arg[0]), retaddr;
2114 	cpu->delay_slot = TO_BE_DELAYED;
2115 	retaddr = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<
2116 	    SH_INSTR_ALIGNMENT_SHIFT);
2117 	ic[1].f(cpu, ic+1);
2118 	cpu->n_translated_instrs ++;
2119 	cpu->cd.sh.pr = retaddr + (int32_t)ic->arg[1];
2120 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
2121 		cpu->pc = target;
2122 		cpu->delay_slot = NOT_DELAYED;
2123 		quick_pc_to_pointers(cpu);
2124 	} else
2125 		cpu->delay_slot = NOT_DELAYED;
2126 }
X(jsr_rn_trace)2127 X(jsr_rn_trace)
2128 {
2129 	MODE_int_t target = reg(ic->arg[0]), retaddr;
2130 	cpu->delay_slot = TO_BE_DELAYED;
2131 	retaddr = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<
2132 	    SH_INSTR_ALIGNMENT_SHIFT);
2133 	ic[1].f(cpu, ic+1);
2134 	cpu->n_translated_instrs ++;
2135 	cpu->cd.sh.pr = retaddr + (int32_t)ic->arg[1];
2136 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
2137 		cpu->pc = target;
2138 		cpu_functioncall_trace(cpu, cpu->pc);
2139 		cpu->delay_slot = NOT_DELAYED;
2140 		quick_pc_to_pointers(cpu);
2141 	} else
2142 		cpu->delay_slot = NOT_DELAYED;
2143 }
2144 
2145 
2146 /*
2147  *  rts: Jump to PR.
2148  */
X(rts)2149 X(rts)
2150 {
2151 	MODE_int_t target = cpu->cd.sh.pr;
2152 	cpu->delay_slot = TO_BE_DELAYED;
2153 	ic[1].f(cpu, ic+1);
2154 	cpu->n_translated_instrs ++;
2155 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
2156 		cpu->pc = target;
2157 		cpu->delay_slot = NOT_DELAYED;
2158 		quick_pc_to_pointers(cpu);
2159 	} else
2160 		cpu->delay_slot = NOT_DELAYED;
2161 }
X(rts_trace)2162 X(rts_trace)
2163 {
2164 	MODE_int_t target = cpu->cd.sh.pr;
2165 	cpu->delay_slot = TO_BE_DELAYED;
2166 	ic[1].f(cpu, ic+1);
2167 	cpu->n_translated_instrs ++;
2168 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
2169 		cpu->pc = target;
2170 		cpu_functioncall_trace_return(cpu);
2171 		cpu->delay_slot = NOT_DELAYED;
2172 		quick_pc_to_pointers(cpu);
2173 	} else
2174 		cpu->delay_slot = NOT_DELAYED;
2175 }
2176 
2177 
2178 /*
2179  *  rte:  Return from exception.
2180  */
X(rte)2181 X(rte)
2182 {
2183 	RES_INST_IF_NOT_MD;
2184 
2185 	cpu->delay_slot = TO_BE_DELAYED;
2186 	ic[1].f(cpu, ic+1);
2187 	cpu->n_translated_instrs ++;
2188 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
2189 		cpu->pc = cpu->cd.sh.spc;
2190 		cpu->delay_slot = NOT_DELAYED;
2191 		sh_update_sr(cpu, cpu->cd.sh.ssr);
2192 		quick_pc_to_pointers(cpu);
2193 	} else
2194 		cpu->delay_slot = NOT_DELAYED;
2195 }
2196 
2197 
2198 /*
2199  *  ldtlb:  Load UTLB entry.
2200  */
X(ldtlb)2201 X(ldtlb)
2202 {
2203 	uint32_t old_hi, old_lo;
2204 	int urc = (cpu->cd.sh.mmucr & SH4_MMUCR_URC_MASK)
2205 	    >> SH4_MMUCR_URC_SHIFT;
2206 
2207 	RES_INST_IF_NOT_MD;
2208 
2209 	old_hi = cpu->cd.sh.utlb_hi[urc];
2210 	old_lo = cpu->cd.sh.utlb_lo[urc];
2211 
2212 	cpu->cd.sh.utlb_hi[urc] = cpu->cd.sh.pteh;
2213 	cpu->cd.sh.utlb_lo[urc] = cpu->cd.sh.ptel;
2214 
2215 	/*  Invalidate the old mapping, if it belonged to the same ASID:  */
2216 	if ((old_hi & SH4_PTEH_ASID_MASK) ==
2217 	    (cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK)) {
2218 		if ((old_lo & SH4_PTEL_SZ_MASK) == SH4_PTEL_SZ_4K)
2219 			cpu->invalidate_translation_caches(cpu,
2220 			    old_hi & 0xfffff000, INVALIDATE_VADDR);
2221 		else
2222 			cpu->invalidate_translation_caches(cpu,
2223 			    0, INVALIDATE_ALL);
2224 	}
2225 }
2226 
2227 
2228 /*
2229  *  copy_privileged_register: Copy normal into privileged register, or vice
2230  *                            versa, after checking the MD status bit.
2231  *
2232  *  arg[0] = ptr to source register
2233  *  arg[1] = ptr to destination register
2234  */
X(copy_privileged_register)2235 X(copy_privileged_register)
2236 {
2237 	RES_INST_IF_NOT_MD;
2238 	reg(ic->arg[1]) = reg(ic->arg[0]);
2239 }
2240 
2241 
2242 /*
2243  *  ldc_rm_sr:      Copy Rm into SR, after checking the MD status bit.
2244  *
2245  *  arg[1] = ptr to rm
2246  */
X(ldc_rm_sr)2247 X(ldc_rm_sr)
2248 {
2249 	RES_INST_IF_NOT_MD;
2250 	sh_update_sr(cpu, reg(ic->arg[1]));
2251 
2252 #if 0
2253 /*  NOTE: This code causes NetBSD/landisk to get past a point where it
2254     otherwise hangs, but it causes Linux/Dreamcast to bug out instead. :/  */
2255 
2256 	if (!(cpu->cd.sh.sr & SH_SR_BL) && cpu->cd.sh.int_to_assert > 0 &&
2257 	    ( (cpu->cd.sh.sr & SH_SR_IMASK) >> SH_SR_IMASK_SHIFT)
2258 	    < cpu->cd.sh.int_level) {
2259 		/*  Cause interrupt immediately, by dropping out of the
2260 		    main dyntrans loop:  */
2261 		cpu->cd.sh.next_ic = &nothing_call;
2262 	}
2263 #endif
2264 }
2265 
2266 
2267 /*
2268  *  trapa:  Immediate trap.
2269  *
2270  *  arg[0] = imm << 2
2271  */
X(trapa)2272 X(trapa)
2273 {
2274 	SYNCH_PC;
2275 
2276 	if (cpu->delay_slot) {
2277 		sh_exception(cpu, EXPEVT_SLOT_INST, 0, 0);
2278 		return;
2279 	}
2280 
2281 	cpu->cd.sh.tra = ic->arg[0];
2282 	sh_exception(cpu, EXPEVT_TRAPA, 0, 0);
2283 }
2284 
2285 
2286 /*
2287  *  copy_fp_register:   Copy a register into another, with FP avail check.
2288  *  lds_rm_fpscr:       Copy Rm into FPSCR.
2289  *
2290  *  arg[0] = ptr to source
2291  *  arg[1] = ptr to destination
2292  */
X(copy_fp_register)2293 X(copy_fp_register)
2294 {
2295 	FLOATING_POINT_AVAILABLE_CHECK;
2296 	reg(ic->arg[1]) = reg(ic->arg[0]);
2297 }
X(lds_rm_fpscr)2298 X(lds_rm_fpscr)
2299 {
2300 	FLOATING_POINT_AVAILABLE_CHECK;
2301 	sh_update_fpscr(cpu, reg(ic->arg[1]));
2302 }
2303 
2304 
2305 /*
2306  *  fmov_frm_frn:  Copy one floating-point register (or pair) to another.
2307  *
2308  *  arg[0] = ptr to source float register or pair
2309  *  arg[1] = ptr to destination float register or pair
2310  */
X(fmov_frm_frn)2311 X(fmov_frm_frn)
2312 {
2313 	size_t r0, r1;
2314 	int ofs0, ofs1;
2315 
2316 	FLOATING_POINT_AVAILABLE_CHECK;
2317 
2318 	/*  Simplest case, single-precision:  */
2319 	if (!(cpu->cd.sh.fpscr & SH_FPSCR_SZ)) {
2320 		reg(ic->arg[1]) = reg(ic->arg[0]);
2321 		return;
2322 	}
2323 
2324 	/*  Double-precision:  */
2325 	r0 = ic->arg[0]; r1 = ic->arg[1];
2326 	ofs0 = (r0 - (size_t)&cpu->cd.sh.fr[0]) / sizeof(uint32_t);
2327 	ofs1 = (r1 - (size_t)&cpu->cd.sh.fr[0]) / sizeof(uint32_t);
2328 	if (ofs0 & 1)
2329 		r0 = (size_t)&cpu->cd.sh.xf[ofs0 & ~1];
2330 	if (ofs1 & 1)
2331 		r1 = (size_t)&cpu->cd.sh.xf[ofs1 & ~1];
2332 
2333 	reg(r1) = reg(r0);
2334 	reg(r1 + 4) = reg(r0 + 4);
2335 }
2336 
2337 
2338 /*
2339  *  float_fpul_frn:  Load FPUL into float register.
2340  *
2341  *  arg[0] = ptr to float register, or float register pair
2342  */
X(float_fpul_frn)2343 X(float_fpul_frn)
2344 {
2345 	int32_t fpul = cpu->cd.sh.fpul;
2346 
2347 	FLOATING_POINT_AVAILABLE_CHECK;
2348 
2349 	if (cpu->cd.sh.fpscr & SH_FPSCR_PR) {
2350 		/*  Double-precision, using a pair of registers:  */
2351 		uint64_t ieee = ieee_store_float_value(fpul, IEEE_FMT_D);
2352 		reg(ic->arg[0]) = (uint32_t) (ieee >> 32);
2353 		reg(ic->arg[0] + sizeof(uint32_t)) = (uint32_t) ieee;
2354 	} else {
2355 		/*  Single-precision:  */
2356 		uint32_t ieee = ieee_store_float_value(fpul, IEEE_FMT_S);
2357 		reg(ic->arg[0]) = (uint32_t) ieee;
2358 	}
2359 }
2360 
2361 
2362 /*
2363  *  ftrc_frm_fpul:  Truncate a float register into FPUL.
2364  *
2365  *  arg[0] = ptr to float register, or float register pair
2366  */
X(ftrc_frm_fpul)2367 X(ftrc_frm_fpul)
2368 {
2369 	struct ieee_float_value op1;
2370 
2371 	FLOATING_POINT_AVAILABLE_CHECK;
2372 
2373 	if (cpu->cd.sh.fpscr & SH_FPSCR_PR) {
2374 		/*  Double-precision, using a pair of registers:  */
2375 		int64_t r1 = ((uint64_t)reg(ic->arg[0]) << 32) +
2376 		    reg(ic->arg[0] + sizeof(uint32_t));
2377 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_D);
2378 		cpu->cd.sh.fpul = (int32_t) op1.f;
2379 	} else {
2380 		/*  Single-precision:  */
2381 		ieee_interpret_float_value(reg(ic->arg[0]), &op1, IEEE_FMT_S);
2382 		cpu->cd.sh.fpul = (int32_t) op1.f;
2383 	}
2384 }
2385 
2386 
2387 /*
2388  *  fcnvsd_fpul_drn:  Convert single-precision to double-precision.
2389  *  fcnvds_drm_fpul:  Convert double-precision to single-precision.
2390  *
2391  *  arg[0] = ptr to destination (double- or single-precision float)
2392  */
X(fcnvsd_fpul_drn)2393 X(fcnvsd_fpul_drn)
2394 {
2395 	struct ieee_float_value op1;
2396 	int64_t ieee;
2397 
2398 	FLOATING_POINT_AVAILABLE_CHECK;
2399 
2400 	ieee_interpret_float_value(cpu->cd.sh.fpul, &op1, IEEE_FMT_S);
2401 	cpu->cd.sh.fpul = (int32_t) op1.f;
2402 
2403 	/*  Store double-precision result:  */
2404 	ieee = ieee_store_float_value(op1.f, IEEE_FMT_D);
2405 	reg(ic->arg[0]) = (uint32_t) (ieee >> 32);
2406 	reg(ic->arg[0] + sizeof(uint32_t)) = (uint32_t) ieee;
2407 }
X(fcnvds_drm_fpul)2408 X(fcnvds_drm_fpul)
2409 {
2410 	struct ieee_float_value op1;
2411 	int64_t r1;
2412 
2413 	FLOATING_POINT_AVAILABLE_CHECK;
2414 
2415 	r1 = reg(ic->arg[0] + sizeof(uint32_t)) +
2416 	    ((uint64_t)reg(ic->arg[0]) << 32);
2417 	ieee_interpret_float_value(r1, &op1, IEEE_FMT_D);
2418 
2419 	cpu->cd.sh.fpul = ieee_store_float_value(op1.f, IEEE_FMT_S);
2420 }
2421 
2422 
2423 /*
2424  *  fsca_fpul_drn:  Sinus/cosinus approximation.
2425  *
2426  *  Note: This is an interesting instruction. It is not included in the SH4
2427  *  manual. Some googling indicated that this might be an SH4X instruction.
2428  *  On the other hand, it is used by Dreamcast code (and the Dreamcast has an
2429  *  SH4), and a cvs comment for gdb said that this is an SH4 instruction, not
2430  *  an SH4A instruction. Well well...
2431  *
2432  *  arg[0] = ptr to single-precision float register pair
2433  */
X(fsca_fpul_drn)2434 X(fsca_fpul_drn)
2435 {
2436 	double fpulAngle = ((double)cpu->cd.sh.fpul) * 2.0 * M_PI / 65536.0;
2437 
2438 	FLOATING_POINT_AVAILABLE_CHECK;
2439 
2440 	reg(ic->arg[0]) = ieee_store_float_value(sin(fpulAngle), IEEE_FMT_S);
2441 	reg(ic->arg[0] + sizeof(uint32_t)) =
2442 	    ieee_store_float_value(cos(fpulAngle), IEEE_FMT_S);
2443 }
2444 
2445 
2446 /*
2447  *  fipr_fvm_fvn:  Vector * vector  =>  scalar
2448  *
2449  *  arg[0] = ptr to FVm
2450  *  arg[1] = ptr to FVn
2451  *
2452  *  Result of adding all   FR{m+i} * FR{n+i}  where i=0..3
2453  *  is stored in FR{n+3}.
2454  */
X(fipr_fvm_fvn)2455 X(fipr_fvm_fvn)
2456 {
2457 	struct ieee_float_value frn0, frn1, frn2, frn3;
2458 	struct ieee_float_value frm0, frm1, frm2, frm3;
2459 
2460 	FLOATING_POINT_AVAILABLE_CHECK;
2461 
2462 	ieee_interpret_float_value(reg(ic->arg[0] +  0), &frm0, IEEE_FMT_S);
2463 	ieee_interpret_float_value(reg(ic->arg[0] +  4), &frm1, IEEE_FMT_S);
2464 	ieee_interpret_float_value(reg(ic->arg[0] +  8), &frm2, IEEE_FMT_S);
2465 	ieee_interpret_float_value(reg(ic->arg[0] + 12), &frm3, IEEE_FMT_S);
2466 	ieee_interpret_float_value(reg(ic->arg[1] +  0), &frn0, IEEE_FMT_S);
2467 	ieee_interpret_float_value(reg(ic->arg[1] +  4), &frn1, IEEE_FMT_S);
2468 	ieee_interpret_float_value(reg(ic->arg[1] +  8), &frn2, IEEE_FMT_S);
2469 	ieee_interpret_float_value(reg(ic->arg[1] + 12), &frn3, IEEE_FMT_S);
2470 
2471 	frn3.f =
2472 	    frm0.f * frn0.f + frm1.f * frn1.f +
2473 	    frm2.f * frn2.f + frm3.f * frn3.f;
2474 
2475 	reg(ic->arg[1] + 12) = ieee_store_float_value(frn3.f, IEEE_FMT_S);
2476 }
2477 
2478 
2479 /*
2480  *  ftrv_xmtrx_fvn:  Matrix * vector  ==>  vector
2481  *
2482  *  arg[0] = ptr to FVn
2483  */
X(ftrv_xmtrx_fvn)2484 X(ftrv_xmtrx_fvn)
2485 {
2486 	int i;
2487 	struct ieee_float_value xmtrx[16], frn[4];
2488 	double frnp0 = 0.0, frnp1 = 0.0, frnp2 = 0.0, frnp3 = 0.0;
2489 
2490 	FLOATING_POINT_AVAILABLE_CHECK;
2491 	// TODO: FPSCR.EN.V = 1 should cause invalid operation exception?
2492 
2493 	ieee_interpret_float_value(reg(ic->arg[0] +  0), &frn[0], IEEE_FMT_S);
2494 	ieee_interpret_float_value(reg(ic->arg[0] +  4), &frn[1], IEEE_FMT_S);
2495 	ieee_interpret_float_value(reg(ic->arg[0] +  8), &frn[2], IEEE_FMT_S);
2496 	ieee_interpret_float_value(reg(ic->arg[0] + 12), &frn[3], IEEE_FMT_S);
2497 
2498 	for (i=0; i<16; i++)
2499 		ieee_interpret_float_value(cpu->cd.sh.xf[i],
2500 		    &xmtrx[i], IEEE_FMT_S);
2501 
2502 	for (i=0; i<4; i++)
2503 		frnp0 += xmtrx[i*4].f * frn[i].f;
2504 
2505 	for (i=0; i<4; i++)
2506 		frnp1 += xmtrx[i*4 + 1].f * frn[i].f;
2507 
2508 	for (i=0; i<4; i++)
2509 		frnp2 += xmtrx[i*4 + 2].f * frn[i].f;
2510 
2511 	for (i=0; i<4; i++)
2512 		frnp3 += xmtrx[i*4 + 3].f * frn[i].f;
2513 
2514 	reg(ic->arg[0] +  0) = ieee_store_float_value(frnp0, IEEE_FMT_S);
2515 	reg(ic->arg[0] +  4) = ieee_store_float_value(frnp1, IEEE_FMT_S);
2516 	reg(ic->arg[0] +  8) = ieee_store_float_value(frnp2, IEEE_FMT_S);
2517 	reg(ic->arg[0] + 12) = ieee_store_float_value(frnp3, IEEE_FMT_S);
2518 }
2519 
2520 
2521 /*
2522  *  fldi:  Load immediate (0.0 or 1.0) into floating point register.
2523  *  fneg:  Negate a floating point register
2524  *  fabs:  Get the absolute value of a floating point register
2525  *  fsqrt: Calculate square root
2526  *  fsrra: Calculate 1 / (square root)
2527  *
2528  *  arg[0] = ptr to fp register
2529  *  arg[1] = (uint32_t) immediate value (for fldi)
2530  */
X(fldi_frn)2531 X(fldi_frn)
2532 {
2533 	FLOATING_POINT_AVAILABLE_CHECK;
2534 	reg(ic->arg[0]) = ic->arg[1];
2535 }
X(fneg_frn)2536 X(fneg_frn)
2537 {
2538 	FLOATING_POINT_AVAILABLE_CHECK;
2539 
2540 	// Hm. If in double register mode... and the register is pointing to
2541 	// an _odd_ register, what happens then?
2542 	if (cpu->cd.sh.fpscr & SH_FPSCR_PR) {
2543 		int ofs0 = (ic->arg[0] - (size_t)&cpu->cd.sh.fr[0]) / sizeof(uint32_t);
2544 		if (ofs0 & 1) {
2545 			fatal("TODO: fneg_frn odd register in double prec. mode.\n");
2546 			exit(1);
2547 		}
2548 	}
2549 
2550 	/*  Note: This also works for double-precision.  */
2551 	reg(ic->arg[0]) ^= 0x80000000;
2552 }
X(fabs_frn)2553 X(fabs_frn)
2554 {
2555 	FLOATING_POINT_AVAILABLE_CHECK;
2556 
2557 	// Hm. If in double register mode... and the register is pointing to
2558 	// an _odd_ register, what happens then?
2559 	if (cpu->cd.sh.fpscr & SH_FPSCR_PR) {
2560 		int ofs0 = (ic->arg[0] - (size_t)&cpu->cd.sh.fr[0]) / sizeof(uint32_t);
2561 		if (ofs0 & 1) {
2562 			fatal("TODO: fneg_frn odd register in double prec. mode.\n");
2563 			exit(1);
2564 		}
2565 	}
2566 
2567 	/*  Note: This also works for double-precision.  */
2568 	reg(ic->arg[0]) &= 0x7fffffff;
2569 }
X(fsqrt_frn)2570 X(fsqrt_frn)
2571 {
2572 	struct ieee_float_value op1;
2573 
2574 	FLOATING_POINT_AVAILABLE_CHECK;
2575 
2576 	if (cpu->cd.sh.fpscr & SH_FPSCR_PR) {
2577 		/*  Double-precision:  */
2578 		int64_t r1, ieee;
2579 		r1 = reg(ic->arg[0] + sizeof(uint32_t)) +
2580 		    ((uint64_t)reg(ic->arg[0]) << 32);
2581 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_D);
2582 		ieee = ieee_store_float_value(sqrt(op1.f), IEEE_FMT_D);
2583 		reg(ic->arg[0]) = (uint32_t) (ieee >> 32);
2584 		reg(ic->arg[0] + sizeof(uint32_t)) = (uint32_t) ieee;
2585 	} else {
2586 		/*  Single-precision:  */
2587 		int32_t ieee, r1 = reg(ic->arg[0]);
2588 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_S);
2589 		ieee = ieee_store_float_value(sqrt(op1.f), IEEE_FMT_S);
2590 		reg(ic->arg[0]) = ieee;
2591 	}
2592 }
X(fsrra_frn)2593 X(fsrra_frn)
2594 {
2595 	// I'm guessing that this is 1/sqrt. That's how it is described at
2596 	// http://yam.20to4.net/dreamcast/hints/index.html at least.
2597 
2598 	struct ieee_float_value op1;
2599 
2600 	FLOATING_POINT_AVAILABLE_CHECK;
2601 
2602 	if (cpu->cd.sh.fpscr & SH_FPSCR_PR) {
2603 		/*  Double-precision:  */
2604 		fatal("Double-precision fsrra? TODO\n");
2605 		ABORT_EXECUTION;
2606 		return;
2607 	} else {
2608 		/*  Single-precision:  */
2609 		int32_t ieee, r1 = reg(ic->arg[0]);
2610 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_S);
2611 		ieee = ieee_store_float_value(1.0f / sqrt(op1.f), IEEE_FMT_S);
2612 		reg(ic->arg[0]) = ieee;
2613 	}
2614 }
2615 
2616 
2617 /*
2618  *  fadd_frm_frn:     Floating point addition.
2619  *  fsub_frm_frn:     Floating point subtraction.
2620  *  fmul_frm_frn:     Floating point multiplication.
2621  *  fdiv_frm_frn:     Floating point division.
2622  *  fmac_fr0_frm_frn: Multiply-and-accumulate.
2623  *  fcmp_eq_frm_frn:  Floating point greater-than comparison.
2624  *  fcmp_gt_frm_frn:  Floating point greater-than comparison.
2625  *
2626  *  arg[0] = ptr to float register FRm
2627  *  arg[1] = ptr to float register FRn
2628  */
X(fadd_frm_frn)2629 X(fadd_frm_frn)
2630 {
2631 	struct ieee_float_value op1, op2;
2632 
2633 	FLOATING_POINT_AVAILABLE_CHECK;
2634 
2635 	if (cpu->cd.sh.fpscr & SH_FPSCR_PR) {
2636 		/*  Double-precision, using a pair of registers:  */
2637 		int64_t r1, r2, ieee;
2638 		double result;
2639 
2640 		r1 = reg(ic->arg[0] + sizeof(uint32_t)) +
2641 		    ((uint64_t)reg(ic->arg[0]) << 32);
2642 		r2 = reg(ic->arg[1] + sizeof(uint32_t)) +
2643 		    ((uint64_t)reg(ic->arg[1]) << 32);
2644 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_D);
2645 		ieee_interpret_float_value(r2, &op2, IEEE_FMT_D);
2646 
2647 		result = op2.f + op1.f;
2648 		ieee = ieee_store_float_value(result, IEEE_FMT_D);
2649 		reg(ic->arg[1]) = (uint32_t) (ieee >> 32);
2650 		reg(ic->arg[1] + sizeof(uint32_t)) = (uint32_t) ieee;
2651 	} else {
2652 		/*  Single-precision:  */
2653 		uint32_t r1, r2, ieee;
2654 		double result;
2655 
2656 		r1 = reg(ic->arg[0]);
2657 		r2 = reg(ic->arg[1]);
2658 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_S);
2659 		ieee_interpret_float_value(r2, &op2, IEEE_FMT_S);
2660 
2661 		result = op2.f + op1.f;
2662 		ieee = ieee_store_float_value(result, IEEE_FMT_S);
2663 		reg(ic->arg[1]) = (uint32_t) ieee;
2664 	}
2665 }
X(fsub_frm_frn)2666 X(fsub_frm_frn)
2667 {
2668 	struct ieee_float_value op1, op2;
2669 
2670 	FLOATING_POINT_AVAILABLE_CHECK;
2671 
2672 	if (cpu->cd.sh.fpscr & SH_FPSCR_PR) {
2673 		/*  Double-precision, using a pair of registers:  */
2674 		int64_t r1, r2, ieee;
2675 		double result;
2676 		r1 = reg(ic->arg[0] + sizeof(uint32_t)) +
2677 		    ((uint64_t)reg(ic->arg[0]) << 32);
2678 		r2 = reg(ic->arg[1] + sizeof(uint32_t)) +
2679 		    ((uint64_t)reg(ic->arg[1]) << 32);
2680 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_D);
2681 		ieee_interpret_float_value(r2, &op2, IEEE_FMT_D);
2682 		result = op2.f - op1.f;
2683 		ieee = ieee_store_float_value(result, IEEE_FMT_D);
2684 		reg(ic->arg[1]) = (uint32_t) (ieee >> 32);
2685 		reg(ic->arg[1] + sizeof(uint32_t)) = (uint32_t) ieee;
2686 	} else {
2687 		/*  Single-precision:  */
2688 		uint32_t r1, r2, ieee;
2689 		double result;
2690 		r1 = reg(ic->arg[0]);
2691 		r2 = reg(ic->arg[1]);
2692 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_S);
2693 		ieee_interpret_float_value(r2, &op2, IEEE_FMT_S);
2694 		result = op2.f - op1.f;
2695 		ieee = ieee_store_float_value(result, IEEE_FMT_S);
2696 		reg(ic->arg[1]) = (uint32_t) ieee;
2697 	}
2698 }
X(fmul_frm_frn)2699 X(fmul_frm_frn)
2700 {
2701 	struct ieee_float_value op1, op2;
2702 
2703 	FLOATING_POINT_AVAILABLE_CHECK;
2704 
2705 	if (cpu->cd.sh.fpscr & SH_FPSCR_PR) {
2706 		/*  Double-precision, using a pair of registers:  */
2707 		int64_t r1, r2, ieee;
2708 		double result;
2709 
2710 		r1 = reg(ic->arg[0] + sizeof(uint32_t)) +
2711 		    ((uint64_t)reg(ic->arg[0]) << 32);
2712 		r2 = reg(ic->arg[1] + sizeof(uint32_t)) +
2713 		    ((uint64_t)reg(ic->arg[1]) << 32);
2714 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_D);
2715 		ieee_interpret_float_value(r2, &op2, IEEE_FMT_D);
2716 
2717 		result = op2.f * op1.f;
2718 		ieee = ieee_store_float_value(result, IEEE_FMT_D);
2719 		reg(ic->arg[1]) = (uint32_t) (ieee >> 32);
2720 		reg(ic->arg[1] + sizeof(uint32_t)) = (uint32_t) ieee;
2721 	} else {
2722 		/*  Single-precision:  */
2723 		uint32_t r1, r2, ieee;
2724 		double result;
2725 
2726 		r1 = reg(ic->arg[0]);
2727 		r2 = reg(ic->arg[1]);
2728 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_S);
2729 		ieee_interpret_float_value(r2, &op2, IEEE_FMT_S);
2730 
2731 		result = op2.f * op1.f;
2732 		ieee = ieee_store_float_value(result, IEEE_FMT_S);
2733 		reg(ic->arg[1]) = (uint32_t) ieee;
2734 	}
2735 }
X(fdiv_frm_frn)2736 X(fdiv_frm_frn)
2737 {
2738 	struct ieee_float_value op1, op2;
2739 
2740 	FLOATING_POINT_AVAILABLE_CHECK;
2741 
2742 	if (cpu->cd.sh.fpscr & SH_FPSCR_PR) {
2743 		/*  Double-precision, using a pair of registers:  */
2744 		int64_t r1, r2, ieee;
2745 		double result;
2746 
2747 		r1 = reg(ic->arg[0] + sizeof(uint32_t)) +
2748 		    ((uint64_t)reg(ic->arg[0]) << 32);
2749 		r2 = reg(ic->arg[1] + sizeof(uint32_t)) +
2750 		    ((uint64_t)reg(ic->arg[1]) << 32);
2751 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_D);
2752 		ieee_interpret_float_value(r2, &op2, IEEE_FMT_D);
2753 
2754 		if (op1.f != 0.0)
2755 			result = op2.f / op1.f;
2756 		else
2757 			result = 0.0;
2758 
2759 		ieee = ieee_store_float_value(result, IEEE_FMT_D);
2760 
2761 		reg(ic->arg[1]) = (uint32_t) (ieee >> 32);
2762 		reg(ic->arg[1] + sizeof(uint32_t)) = (uint32_t) ieee;
2763 	} else {
2764 		/*  Single-precision:  */
2765 		uint32_t r1, r2, ieee;
2766 		double result;
2767 
2768 		r1 = reg(ic->arg[0]);
2769 		r2 = reg(ic->arg[1]);
2770 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_S);
2771 		ieee_interpret_float_value(r2, &op2, IEEE_FMT_S);
2772 
2773 		if (op1.f != 0.0)
2774 			result = op2.f / op1.f;
2775 		else
2776 			result = 0.0;
2777 
2778 		ieee = ieee_store_float_value(result, IEEE_FMT_S);
2779 
2780 		reg(ic->arg[1]) = (uint32_t) ieee;
2781 	}
2782 }
X(fmac_fr0_frm_frn)2783 X(fmac_fr0_frm_frn)
2784 {
2785 	struct ieee_float_value op1, op2, op0;
2786 	int32_t r1, r2, fr0 = cpu->cd.sh.fr[0], ieee;
2787 
2788 	FLOATING_POINT_AVAILABLE_CHECK;
2789 
2790 	r1 = reg(ic->arg[0]), r2 = reg(ic->arg[1]);
2791 	ieee_interpret_float_value(fr0, &op0, IEEE_FMT_S);
2792 	ieee_interpret_float_value(r1, &op1, IEEE_FMT_S);
2793 	ieee_interpret_float_value(r2, &op2, IEEE_FMT_S);
2794 	ieee = ieee_store_float_value(op0.f * op1.f + op2.f, IEEE_FMT_S);
2795 	reg(ic->arg[1]) = ieee;
2796 }
X(fcmp_eq_frm_frn)2797 X(fcmp_eq_frm_frn)
2798 {
2799 	struct ieee_float_value op1, op2;
2800 
2801 	FLOATING_POINT_AVAILABLE_CHECK;
2802 
2803 	if (cpu->cd.sh.fpscr & SH_FPSCR_PR) {
2804 		/*  Double-precision, using a pair of registers:  */
2805 		int64_t r1, r2;
2806 		r1 = reg(ic->arg[0] + sizeof(uint32_t)) +
2807 		    ((uint64_t)reg(ic->arg[0]) << 32);
2808 		r2 = reg(ic->arg[1] + sizeof(uint32_t)) +
2809 		    ((uint64_t)reg(ic->arg[1]) << 32);
2810 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_D);
2811 		ieee_interpret_float_value(r2, &op2, IEEE_FMT_D);
2812 	} else {
2813 		/*  Single-precision:  */
2814 		uint32_t r1 = reg(ic->arg[0]), r2 = reg(ic->arg[1]);
2815 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_S);
2816 		ieee_interpret_float_value(r2, &op2, IEEE_FMT_S);
2817 	}
2818 
2819 	if (op2.f == op1.f)
2820 		cpu->cd.sh.sr |= SH_SR_T;
2821 	else
2822 		cpu->cd.sh.sr &= ~SH_SR_T;
2823 }
X(fcmp_gt_frm_frn)2824 X(fcmp_gt_frm_frn)
2825 {
2826 	struct ieee_float_value op1, op2;
2827 
2828 	FLOATING_POINT_AVAILABLE_CHECK;
2829 
2830 	if (cpu->cd.sh.fpscr & SH_FPSCR_PR) {
2831 		/*  Double-precision, using a pair of registers:  */
2832 		int64_t r1, r2;
2833 		r1 = reg(ic->arg[0] + sizeof(uint32_t)) +
2834 		    ((uint64_t)reg(ic->arg[0]) << 32);
2835 		r2 = reg(ic->arg[1] + sizeof(uint32_t)) +
2836 		    ((uint64_t)reg(ic->arg[1]) << 32);
2837 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_D);
2838 		ieee_interpret_float_value(r2, &op2, IEEE_FMT_D);
2839 	} else {
2840 		/*  Single-precision:  */
2841 		uint32_t r1 = reg(ic->arg[0]), r2 = reg(ic->arg[1]);
2842 		ieee_interpret_float_value(r1, &op1, IEEE_FMT_S);
2843 		ieee_interpret_float_value(r2, &op2, IEEE_FMT_S);
2844 	}
2845 
2846 	if (op2.f > op1.f)
2847 		cpu->cd.sh.sr |= SH_SR_T;
2848 	else
2849 		cpu->cd.sh.sr &= ~SH_SR_T;
2850 }
2851 
2852 
2853 /*
2854  *  frchg:  Change floating-point register banks.
2855  *  fschg:  Change floating-point register size.
2856  */
X(frchg)2857 X(frchg)
2858 {
2859 	FLOATING_POINT_AVAILABLE_CHECK;
2860 	sh_update_fpscr(cpu, cpu->cd.sh.fpscr ^ SH_FPSCR_FR);
2861 }
X(fschg)2862 X(fschg)
2863 {
2864 	FLOATING_POINT_AVAILABLE_CHECK;
2865 	sh_update_fpscr(cpu, cpu->cd.sh.fpscr ^ SH_FPSCR_SZ);
2866 }
2867 
2868 
2869 /*
2870  *  pref_rn:  Prefetch.
2871  *
2872  *  TODO: According to the SH4 manual, "OTLBMULTIHIT or RADDERR may be
2873  *  delivered", so those things should be checked for. Not implemented yet.
2874  *
2875  *  arg[1] = ptr to Rn
2876  */
X(pref_rn)2877 X(pref_rn)
2878 {
2879 	uint32_t addr = reg(ic->arg[1]), extaddr;
2880 	int sq_nr, ofs;
2881 
2882 	if (addr < 0xe0000000U || addr >= 0xe4000000U)
2883 	{
2884 		// printf("[ SH4 pref 0x%08x (pc = 0x%08x) ]\n", addr, (int)cpu->pc);
2885 		return;
2886 	}
2887 
2888 	SYNCH_PC;
2889 
2890 	// Calculate the external address:
2891 	extaddr = addr & 0x03ffffe0;
2892 	sq_nr = addr & 0x20? 1 : 0;
2893 
2894 	// if (addr & 0x0000001f)
2895 	//	debug("[ WARNING: SH4 Store Queue, addr = 0x%08x... lowest 5 "
2896 	//	    "bits are non-zero. Ignoring. ]\n", addr);
2897 
2898 	if (sq_nr == 0)
2899 		extaddr |= (((cpu->cd.sh.qacr0 >> 2) & 7) << 26);
2900 	else
2901 		extaddr |= (((cpu->cd.sh.qacr1 >> 2) & 7) << 26);
2902 
2903 	// fatal("[ SH4 pref: SQ extaddr = 0x%08x (pc = 0x%08x) ]\n", extaddr, (int)cpu->pc);
2904 
2905 	// Is the MMU turned on?
2906 	if (cpu->cd.sh.mmucr & SH4_MMUCR_AT) {
2907 		// When the SQMD bit in MMUCR is set, user access is prohibited
2908 		// if the MMU is enabled.
2909 		if (cpu->cd.sh.mmucr & SH4_MMUCR_SQMD) {
2910 			bool inUserMode = (cpu->cd.sh.sr & SH_SR_MD) ? false : true;
2911 			if (inUserMode) {
2912 				sh_exception(cpu, EXPEVT_RES_INST, 0, 0);
2913 				return;
2914 			}
2915 		}
2916 
2917 		fatal("Store Queue to external memory, when "
2918 		    "MMU enabled: Not yet implemented... TODO\n");
2919 		ABORT_EXECUTION;
2920 		return;
2921 	}
2922 
2923 	for (ofs = 0; ofs < 32; ofs += sizeof(uint32_t)) {
2924 		uint32_t word;
2925 		cpu->memory_rw(cpu, cpu->mem, 0xe0000000UL + ofs
2926 		    + sq_nr * 0x20, (unsigned char *)
2927 		    &word, sizeof(word), MEM_READ, PHYSICAL);
2928 		// fatal("  addr %08x: %08x\n", (extaddr + ofs), word);
2929 		cpu->memory_rw(cpu, cpu->mem, extaddr+ofs, (unsigned char *)
2930 		    &word, sizeof(word), MEM_WRITE, PHYSICAL);
2931 	}
2932 }
2933 
2934 
2935 /*
2936  *  tas_b_rn: Test-and-Set.
2937  *
2938  *  arg[1] = ptr to Rn
2939  */
X(tas_b_rn)2940 X(tas_b_rn)
2941 {
2942 	uint32_t addr = reg(ic->arg[1]);
2943 	uint8_t byte, newbyte;
2944 
2945 	SYNCH_PC;
2946 
2947 	if (!cpu->memory_rw(cpu, cpu->mem, addr, &byte, 1, MEM_READ,
2948 	   CACHE_DATA)) {
2949 		/*  Exception.  */
2950 		return;
2951 	}
2952 
2953 	newbyte = byte | 0x80;
2954 
2955 	if (!cpu->memory_rw(cpu, cpu->mem, addr, &newbyte, 1, MEM_WRITE,
2956 	   CACHE_DATA)) {
2957 		/*  Exception.  */
2958 		return;
2959 	}
2960 
2961 	if (byte == 0)
2962 		cpu->cd.sh.sr |= SH_SR_T;
2963 	else
2964 		cpu->cd.sh.sr &= ~SH_SR_T;
2965 }
2966 
2967 
2968 /*
2969  *  prom_emul:
2970  */
X(prom_emul)2971 X(prom_emul)
2972 {
2973 	uint32_t old_pc;
2974 	SYNCH_PC;
2975 	old_pc = cpu->pc;
2976 
2977 	switch (cpu->machine->machine_type) {
2978 	case MACHINE_DREAMCAST:
2979 		dreamcast_emul(cpu);
2980 		break;
2981 	case MACHINE_LANDISK:
2982 		sh_ipl_g_emul(cpu);
2983 		break;
2984 	default:
2985 		fatal("SH prom_emul: unimplemented machine type.\n");
2986 		exit(1);
2987 	}
2988 
2989 	if (!cpu->running) {
2990 		cpu->n_translated_instrs --;
2991 		cpu->cd.sh.next_ic = &nothing_call;
2992 	} else if ((uint32_t)cpu->pc != old_pc) {
2993 		/*  The PC value was changed by the PROM call.  */
2994 		quick_pc_to_pointers(cpu);
2995 	}
2996 }
2997 
2998 
2999 /*****************************************************************************/
3000 
3001 
3002 /*
3003  *  bt_samepage_wait_for_variable:
3004  *
3005  *  Loop which reads a variable in memory forever until it changes state,
3006  *  can most likely only change state if an interrupt occurs. Simulate speed
3007  *  by skipping ahead quickly, until the next interrupt occurs.
3008  *
3009  *	z:  mov.l  (X,gbr),r0		mov_l_disp_gbr_r0 with arg[1] = X
3010  *          cmp/eq r0,rY		cmpeq_rm_rn with args 0 and 1 being r0 and rY
3011  *          bt     x			bt_samepage with arg[1] = z
3012  */
X(bt_samepage_wait_for_variable)3013 X(bt_samepage_wait_for_variable)
3014 {
3015 	if (cpu->delay_slot) {
3016 		instr(mov_l_disp_gbr_r0)(cpu, ic);
3017 		return;
3018 	}
3019 
3020 	// mov_l_disp_gbr_r0:
3021 	// Bail out quickly if the memory is not on a readable page.
3022 	uint32_t addr = cpu->cd.sh.gbr + ic->arg[1];
3023 	uint32_t *p = (uint32_t *) cpu->cd.sh.host_load[addr >> 12];
3024 	if (p == NULL) {
3025 		instr(mov_l_disp_gbr_r0)(cpu, ic);
3026 		return;
3027 	}
3028 
3029 	uint32_t data = p[(addr & 0xfff) >> 2];
3030 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3031 		data = LE32_TO_HOST(data);
3032 	else
3033 		data = BE32_TO_HOST(data);
3034 
3035 	cpu->cd.sh.r[0] = data;
3036 
3037 	// cmpeq_rm_rn:
3038 	if (reg(ic[1].arg[1]) == reg(ic[1].arg[0]))
3039 		cpu->cd.sh.sr |= SH_SR_T;
3040 	else
3041 		cpu->cd.sh.sr &= ~SH_SR_T;
3042 
3043 	// Loop for a "long time" if the two registered were equal.
3044 	if (cpu->cd.sh.sr & SH_SR_T) {
3045 		// Some bogus amount of instructions.
3046 		// TODO: Make nicer?
3047 		cpu->n_translated_instrs += 500;
3048 		cpu->cd.sh.next_ic = ic;	// "jump to z"
3049 	} else {
3050 		// otherwise, get out of the loop.
3051 		cpu->n_translated_instrs += 2;
3052 		cpu->cd.sh.next_ic = ic + 3;
3053 	}
3054 }
3055 
3056 
3057 /*****************************************************************************/
3058 
3059 
3060 /*
3061  *  Combine: something ending with a bt_samepage.
3062  *
3063  *  See comment for bt_samepage_wait_for_variable above for details.
3064  */
COMBINE(bt_samepage)3065 void COMBINE(bt_samepage)(struct cpu *cpu, struct sh_instr_call *ic, int low_addr)
3066 {
3067 	int n_back = (low_addr >> SH_INSTR_ALIGNMENT_SHIFT)
3068 	    & (SH_IC_ENTRIES_PER_PAGE - 1);
3069 
3070 	if (n_back < 2)
3071 		return;
3072 
3073 	if (ic[-2].f == instr(mov_l_disp_gbr_r0) &&
3074 	    ic[-1].f == instr(cmpeq_rm_rn) &&
3075 	    (ic[-1].arg[0] == (size_t) &cpu->cd.sh.r[0] ||
3076 	     ic[-1].arg[1] == (size_t) &cpu->cd.sh.r[0]) &&
3077 	    ic[0].arg[1] == (size_t) &ic[-2]) {
3078 		ic[-2].f = instr(bt_samepage_wait_for_variable);
3079 	}
3080 }
3081 
3082 
3083 /*****************************************************************************/
3084 
3085 
X(end_of_page)3086 X(end_of_page)
3087 {
3088 	/*  Update the PC:  (offset 0, but on the next page)  */
3089 	cpu->pc &= ~((SH_IC_ENTRIES_PER_PAGE-1) <<
3090 	    SH_INSTR_ALIGNMENT_SHIFT);
3091 	cpu->pc += (SH_IC_ENTRIES_PER_PAGE << SH_INSTR_ALIGNMENT_SHIFT);
3092 
3093 	/*  end_of_page doesn't count as an executed instruction:  */
3094 	cpu->n_translated_instrs --;
3095 
3096 	/*
3097 	 *  Find the new physpage and update translation pointers.
3098 	 *
3099 	 *  Note: This may cause an exception, if e.g. the new page is
3100 	 *  not accessible.
3101 	 */
3102 	quick_pc_to_pointers(cpu);
3103 
3104 	/*  Simple jump to the next page (if we are lucky):  */
3105 	if (cpu->delay_slot == NOT_DELAYED)
3106 		return;
3107 
3108 	/*
3109 	 *  If we were in a delay slot, and we got an exception while doing
3110 	 *  quick_pc_to_pointers, then return. The function which called
3111 	 *  end_of_page should handle this case.
3112 	 */
3113 	if (cpu->delay_slot == EXCEPTION_IN_DELAY_SLOT)
3114 		return;
3115 
3116 	/*
3117 	 *  Tricky situation; the delay slot is on the next virtual page.
3118 	 *  Calling to_be_translated will translate one instruction manually,
3119 	 *  execute it, and then discard it.
3120 	 */
3121 	/*  fatal("[ end_of_page: delay slot across page boundary! ]\n");  */
3122 
3123 	instr(to_be_translated)(cpu, cpu->cd.sh.next_ic);
3124 
3125 	/*  The instruction in the delay slot has now executed.  */
3126 	/*  fatal("[ end_of_page: back from executing the delay slot, %i ]\n",
3127 	    cpu->delay_slot);  */
3128 
3129 	/*  Find the physpage etc of the instruction in the delay slot
3130 	    (or, if there was an exception, the exception handler):  */
3131 	quick_pc_to_pointers(cpu);
3132 }
3133 
3134 
X(end_of_page2)3135 X(end_of_page2)
3136 {
3137 	/*  Synchronize PC on the _second_ instruction on the next page:  */
3138 	int low_pc = ((size_t)ic - (size_t)cpu->cd.sh.cur_ic_page)
3139 	    / sizeof(struct sh_instr_call);
3140 	cpu->pc &= ~((SH_IC_ENTRIES_PER_PAGE-1)
3141 	    << SH_INSTR_ALIGNMENT_SHIFT);
3142 	cpu->pc += (low_pc << SH_INSTR_ALIGNMENT_SHIFT);
3143 
3144 	/*  This doesn't count as an executed instruction.  */
3145 	cpu->n_translated_instrs --;
3146 
3147 	quick_pc_to_pointers(cpu);
3148 
3149 	if (cpu->delay_slot == NOT_DELAYED)
3150 		return;
3151 
3152 	fatal("end_of_page2: fatal error, we're in a delay slot\n");
3153 	exit(1);
3154 }
3155 
3156 
3157 /*****************************************************************************/
3158 
3159 
3160 /*
3161  *  sh_instr_to_be_translated():
3162  *
3163  *  Translate an instruction word into an sh_instr_call. ic is filled in with
3164  *  valid data for the translated instruction, or a "nothing" instruction if
3165  *  there was a translation failure. The newly translated instruction is then
3166  *  executed.
3167  */
X(to_be_translated)3168 X(to_be_translated)
3169 {
3170 	uint32_t addr, low_pc, iword;
3171 	unsigned char *page;
3172 	unsigned char ib[2];
3173 	int main_opcode, isize = sizeof(ib);
3174 	int in_crosspage_delayslot = 0, r8, r4, lo4, lo8;
3175 	void (*samepage_function)(struct cpu *, struct sh_instr_call *);
3176 
3177 	/*  Figure out the (virtual) address of the instruction:  */
3178 	low_pc = ((size_t)ic - (size_t)cpu->cd.sh.cur_ic_page)
3179 	    / sizeof(struct sh_instr_call);
3180 
3181 	/*  Special case for branch with delayslot on the next page:  */
3182 	if (cpu->delay_slot == TO_BE_DELAYED && low_pc == 0) {
3183 		/*  fatal("[ delay-slot translation across page "
3184 		    "boundary ]\n");  */
3185 		in_crosspage_delayslot = 1;
3186 	}
3187 
3188 	addr = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1)
3189 	    << SH_INSTR_ALIGNMENT_SHIFT);
3190 	addr += (low_pc << SH_INSTR_ALIGNMENT_SHIFT);
3191 	cpu->pc = (MODE_int_t)addr;
3192 	addr &= ~((1 << SH_INSTR_ALIGNMENT_SHIFT) - 1);
3193 
3194 	/*  Read the instruction word from memory:  */
3195 	page = cpu->cd.sh.host_load[(uint32_t)addr >> 12];
3196 
3197 	if (page != NULL) {
3198 		/*  fatal("TRANSLATION HIT!\n");  */
3199 		memcpy(ib, page + (addr & 0xfff), isize);
3200 	} else {
3201 		/*  fatal("TRANSLATION MISS!\n");  */
3202 		if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
3203 		    isize, MEM_READ, CACHE_INSTRUCTION)) {
3204 			fatal("to_be_translated(): read failed: TODO\n");
3205 			goto bad;
3206 		}
3207 	}
3208 
3209 	{
3210 		uint16_t *p = (uint16_t *) ib;
3211 		iword = *p;
3212 	}
3213 
3214 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3215 		iword = LE16_TO_HOST(iword);
3216 	else
3217 		iword = BE16_TO_HOST(iword);
3218 
3219 	main_opcode = iword >> 12;
3220 	r8 = (iword >> 8) & 0xf;
3221 	r4 = (iword >> 4) & 0xf;
3222 	lo8 = iword & 0xff;
3223 	lo4 = iword & 0xf;
3224 
3225 
3226 #define DYNTRANS_TO_BE_TRANSLATED_HEAD
3227 #include "cpu_dyntrans.cc"
3228 #undef  DYNTRANS_TO_BE_TRANSLATED_HEAD
3229 
3230 
3231 	/*
3232 	 *  Translate the instruction:
3233 	 */
3234 
3235 	/*  Default args. for many instructions:  */
3236 	ic->arg[0] = (size_t)&cpu->cd.sh.r[r4];	/* m */
3237 	ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];	/* n */
3238 
3239 	switch (main_opcode) {
3240 
3241 	case 0x0:
3242 		if (lo4 == 0x4) {
3243 			/*  MOV.B Rm,@(R0,Rn)  */
3244 			ic->f = instr(mov_b_rm_r0_rn);
3245 		} else if (lo4 == 0x5) {
3246 			/*  MOV.W Rm,@(R0,Rn)  */
3247 			ic->f = instr(mov_w_rm_r0_rn);
3248 		} else if (lo4 == 0x6) {
3249 			/*  MOV.L Rm,@(R0,Rn)  */
3250 			ic->f = instr(mov_l_rm_r0_rn);
3251 		} else if (lo4 == 0x7) {
3252 			/*  MUL.L Rm,Rn  */
3253 			ic->f = instr(mul_l_rm_rn);
3254 		} else if (iword == 0x000b) {
3255 			if (cpu->machine->show_trace_tree)
3256 				ic->f = instr(rts_trace);
3257 			else
3258 				ic->f = instr(rts);
3259 		} else if (lo4 == 0xc) {
3260 			/*  MOV.B @(R0,Rm),Rn  */
3261 			ic->f = instr(mov_b_r0_rm_rn);
3262 		} else if (lo4 == 0xd) {
3263 			/*  MOV.W @(R0,Rm),Rn  */
3264 			ic->f = instr(mov_w_r0_rm_rn);
3265 		} else if (lo4 == 0xe) {
3266 			/*  MOV.L @(R0,Rm),Rn  */
3267 			ic->f = instr(mov_l_r0_rm_rn);
3268 		} else if (iword == 0x0008) {
3269 			/*  CLRT  */
3270 			ic->f = instr(clrt);
3271 		} else if (iword == 0x0018) {
3272 			/*  SETT  */
3273 			ic->f = instr(sett);
3274 		} else if (iword == 0x0019) {
3275 			/*  DIV0U  */
3276 			ic->f = instr(div0u);
3277 		} else if (iword == 0x001b) {
3278 			/*  SLEEP  */
3279 			ic->f = instr(sleep);
3280 		} else if (iword == 0x0028) {
3281 			/*  CLRMAC  */
3282 			ic->f = instr(clrmac);
3283 		} else if (iword == 0x002b) {
3284 			/*  RTE  */
3285 			ic->f = instr(rte);
3286 		} else if (iword == 0x0038) {
3287 			/*  LDTLB  */
3288 			ic->f = instr(ldtlb);
3289 		} else if (iword == 0x0048) {
3290 			/*  CLRS  */
3291 			ic->f = instr(clrs);
3292 		} else if (iword == 0x0058) {
3293 			/*  SETS  */
3294 			ic->f = instr(sets);
3295 		} else if ((lo8 & 0x8f) == 0x82) {
3296 			/*  STC Rm_BANK, Rn  */
3297 			ic->f = instr(copy_privileged_register);
3298 			ic->arg[0] = (size_t)&cpu->cd.sh.r_bank[(lo8 >> 4) & 7];
3299 		} else if (iword == SH_INVALID_INSTR) {
3300 			/*  PROM emulation (GXemul specific)  */
3301 			ic->f = instr(prom_emul);
3302 		} else {
3303 			switch (lo8) {
3304 			case 0x02:	/*  STC SR,Rn  */
3305 				ic->f = instr(copy_privileged_register);
3306 				ic->arg[0] = (size_t)&cpu->cd.sh.sr;
3307 				break;
3308 			case 0x03:	/*  BSRF Rn  */
3309 				if (cpu->machine->show_trace_tree)
3310 					ic->f = instr(bsrf_rn_trace);
3311 				else
3312 					ic->f = instr(bsrf_rn);
3313 
3314 				ic->arg[0] = (int32_t) (addr &
3315 				    ((SH_IC_ENTRIES_PER_PAGE-1)
3316 				    << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4;
3317 				/*  arg[1] is Rn  */
3318 				break;
3319 			case 0x09:	/*  NOP  */
3320 				ic->f = instr(nop);
3321 				if (iword & 0x0f00) {
3322 					if (!cpu->translation_readahead)
3323 						fatal("Unimplemented NOP"
3324 						    " variant?\n");
3325 					goto bad;
3326 				}
3327 				break;
3328 			case 0x0a:	/*  STS MACH,Rn  */
3329 				ic->f = instr(mov_rm_rn);
3330 				ic->arg[0] = (size_t)&cpu->cd.sh.mach;
3331 				break;
3332 			case 0x12:	/*  STC GBR,Rn  */
3333 				ic->f = instr(mov_rm_rn);
3334 				ic->arg[0] = (size_t)&cpu->cd.sh.gbr;
3335 				break;
3336 			case 0x1a:	/*  STS MACL,Rn  */
3337 				ic->f = instr(mov_rm_rn);
3338 				ic->arg[0] = (size_t)&cpu->cd.sh.macl;
3339 				break;
3340 			case 0x22:	/*  STC VBR,Rn  */
3341 				ic->f = instr(copy_privileged_register);
3342 				ic->arg[0] = (size_t)&cpu->cd.sh.vbr;
3343 				break;
3344 			case 0x23:	/*  BRAF Rn  */
3345 				ic->f = instr(braf_rn);
3346 				ic->arg[0] = (int32_t) (addr &
3347 				    ((SH_IC_ENTRIES_PER_PAGE-1)
3348 				    << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4;
3349 				/*  arg[1] is Rn  */
3350 				break;
3351 			case 0x29:	/*  MOVT Rn  */
3352 				ic->f = instr(movt_rn);
3353 				break;
3354 			case 0x2a:	/*  STS PR,Rn  */
3355 				ic->f = instr(mov_rm_rn);
3356 				ic->arg[0] = (size_t)&cpu->cd.sh.pr;
3357 				break;
3358 			case 0x32:	/*  STC SSR,Rn  */
3359 				ic->f = instr(copy_privileged_register);
3360 				ic->arg[0] = (size_t)&cpu->cd.sh.ssr;
3361 				break;
3362 			case 0x42:	/*  STC SPC,Rn  */
3363 				ic->f = instr(copy_privileged_register);
3364 				ic->arg[0] = (size_t)&cpu->cd.sh.spc;
3365 				break;
3366 			case 0x5a:	/*  STS FPUL,Rn  */
3367 				ic->f = instr(copy_fp_register);
3368 				ic->arg[0] = (size_t)&cpu->cd.sh.fpul;
3369 				ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];
3370 				break;
3371 			case 0x6a:	/*  STS FPSCR,Rn  */
3372 				ic->f = instr(copy_fp_register);
3373 				ic->arg[0] = (size_t)&cpu->cd.sh.fpscr;
3374 				ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];
3375 				break;
3376 			case 0x83:	/*  PREF @Rn  */
3377 				ic->f = instr(pref_rn);
3378 				break;
3379 			case 0x93:	/*  OCBI @Rn  */
3380 				/*  Treat as nop for now:  */
3381 				/*  TODO: Implement this.  */
3382 				ic->f = instr(nop);
3383 				break;
3384 			case 0xa3:	/*  OCBP @Rn  */
3385 				/*  Treat as nop for now:  */
3386 				/*  TODO: Implement this.  */
3387 				ic->f = instr(nop);
3388 				break;
3389 			case 0xb3:	/*  OCBWB @Rn  */
3390 				/*  Treat as nop for now:  */
3391 				/*  TODO: Implement this.  */
3392 				ic->f = instr(nop);
3393 				break;
3394 			case 0xc3:	/*  MOVCA.L R0,@Rn  */
3395 				/*  Treat as nop for now:  */
3396 				/*  TODO: Implement this.  */
3397 				ic->f = instr(nop);
3398 				break;
3399 			case 0xfa:	/*  STC DBR,Rn  */
3400 				ic->f = instr(copy_privileged_register);
3401 				ic->arg[0] = (size_t)&cpu->cd.sh.dbr;
3402 				ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];
3403 				break;
3404 			default:if (!cpu->translation_readahead)
3405 					fatal("Unimplemented opcode 0x%x,"
3406 					    "0x%03x\n", main_opcode,
3407 					    iword & 0xfff);
3408 				goto bad;
3409 			}
3410 		}
3411 		break;
3412 
3413 	case 0x1:
3414 		ic->f = instr(mov_l_rm_disp_rn);
3415 		ic->arg[1] = r8 + (lo4 << 4);
3416 		break;
3417 
3418 	case 0x2:
3419 		switch (lo4) {
3420 		case 0x0:	/*  MOV.B Rm,@Rn  */
3421 			ic->f = instr(mov_b_store_rm_rn);
3422 			break;
3423 		case 0x1:	/*  MOV.W Rm,@Rn  */
3424 			ic->f = instr(mov_w_store_rm_rn);
3425 			break;
3426 		case 0x2:	/*  MOV.L Rm,@Rn  */
3427 			ic->f = instr(mov_l_store_rm_rn);
3428 			break;
3429 		case 0x4:	/*  MOV.B Rm,@-Rn  */
3430 			ic->f = instr(mov_b_rm_predec_rn);
3431 			break;
3432 		case 0x5:	/*  MOV.W Rm,@-Rn  */
3433 			ic->f = instr(mov_w_rm_predec_rn);
3434 			break;
3435 		case 0x6:	/*  MOV.L Rm,@-Rn  */
3436 			ic->f = instr(mov_l_rm_predec_rn);
3437 			break;
3438 		case 0x7:	/*  DIV0S Rm,Rn  */
3439 			ic->f = instr(div0s_rm_rn);
3440 			break;
3441 		case 0x8:	/*  TST Rm,Rn  */
3442 			ic->f = instr(tst_rm_rn);
3443 			if (r8 == r4)
3444 				ic->f = instr(tst_rm);
3445 			break;
3446 		case 0x9:	/*  AND Rm,Rn  */
3447 			ic->f = instr(and_rm_rn);
3448 			break;
3449 		case 0xa:	/*  XOR Rm,Rn  */
3450 			ic->f = instr(xor_rm_rn);
3451 			break;
3452 		case 0xb:	/*  OR Rm,Rn  */
3453 			ic->f = instr(or_rm_rn);
3454 			break;
3455 		case 0xc:	/*  CMP/STR Rm,Rn  */
3456 			ic->f = instr(cmp_str_rm_rn);
3457 			break;
3458 		case 0xd:	/*  XTRCT Rm,Rn  */
3459 			ic->f = instr(xtrct_rm_rn);
3460 			break;
3461 		case 0xe:	/*  MULU.W Rm,Rn  */
3462 			ic->f = instr(mulu_w_rm_rn);
3463 			break;
3464 		case 0xf:	/*  MULS.W Rm,Rn  */
3465 			ic->f = instr(muls_w_rm_rn);
3466 			break;
3467 		default:if (!cpu->translation_readahead)
3468 				fatal("Unimplemented opcode 0x%x,0x%x\n",
3469 				    main_opcode, lo4);
3470 			goto bad;
3471 		}
3472 		break;
3473 
3474 	case 0x3:
3475 		switch (lo4) {
3476 		case 0x0:	/*  CMP/EQ Rm,Rn  */
3477 			ic->f = instr(cmpeq_rm_rn);
3478 			break;
3479 		case 0x2:	/*  CMP/HS Rm,Rn  */
3480 			ic->f = instr(cmphs_rm_rn);
3481 			break;
3482 		case 0x3:	/*  CMP/GE Rm,Rn  */
3483 			ic->f = instr(cmpge_rm_rn);
3484 			break;
3485 		case 0x4:	/*  DIV1 Rm,Rn  */
3486 			ic->f = instr(div1_rm_rn);
3487 			break;
3488 		case 0x5:	/*  DMULU.L Rm,Rn  */
3489 			ic->f = instr(dmulu_l_rm_rn);
3490 			break;
3491 		case 0x6:	/*  CMP/HI Rm,Rn  */
3492 			ic->f = instr(cmphi_rm_rn);
3493 			break;
3494 		case 0x7:	/*  CMP/GT Rm,Rn  */
3495 			ic->f = instr(cmpgt_rm_rn);
3496 			break;
3497 		case 0x8:	/*  SUB Rm,Rn  */
3498 			ic->f = instr(sub_rm_rn);
3499 			break;
3500 		case 0xa:	/*  SUBC Rm,Rn  */
3501 			ic->f = instr(subc_rm_rn);
3502 			break;
3503 		case 0xc:	/*  ADD Rm,Rn  */
3504 			ic->f = instr(add_rm_rn);
3505 			break;
3506 		case 0xd:	/*  DMULS.L Rm,Rn  */
3507 			ic->f = instr(dmuls_l_rm_rn);
3508 			break;
3509 		case 0xe:	/*  ADDC Rm,Rn  */
3510 			ic->f = instr(addc_rm_rn);
3511 			break;
3512 		default:if (!cpu->translation_readahead)
3513 				fatal("Unimplemented opcode 0x%x,0x%x\n",
3514 				    main_opcode, lo4);
3515 			goto bad;
3516 		}
3517 		break;
3518 
3519 	case 0x4:
3520 		if (lo4 == 0xc) {
3521 			ic->f = instr(shad);
3522 		} else if (lo4 == 0xd) {
3523 			ic->f = instr(shld);
3524 		} else if ((lo8 & 0x8f) == 0x83) {
3525 			/*  STC.L Rm_BANK,@-Rn  */
3526 			ic->f = instr(stc_l_rm_predec_rn_md);
3527 			ic->arg[0] = (size_t)&cpu->cd.sh.r_bank[
3528 			    (lo8 >> 4) & 7];	/* m */
3529 		} else if ((lo8 & 0x8f) == 0x87) {
3530 			/*   LDC.L @Rm+,Rn_BANK  */
3531 			ic->f = instr(mov_l_arg1_postinc_to_arg0_md);
3532 			ic->arg[0] = (size_t)&cpu->cd.sh.r_bank[(lo8 >> 4) & 7];
3533 		} else if ((lo8 & 0x8f) == 0x8e) {
3534 			/*  LDC Rm, Rn_BANK  */
3535 			ic->f = instr(copy_privileged_register);
3536 			ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];
3537 			ic->arg[1] = (size_t)&cpu->cd.sh.r_bank[(lo8 >> 4) & 7];
3538 		} else {
3539 			switch (lo8) {
3540 			case 0x00:	/*  SHLL Rn  */
3541 				ic->f = instr(shll_rn);
3542 				break;
3543 			case 0x01:	/*  SHLR Rn  */
3544 				ic->f = instr(shlr_rn);
3545 				break;
3546 			case 0x02:	/*  STS.L MACH,@-Rn  */
3547 				ic->f = instr(mov_l_rm_predec_rn);
3548 				ic->arg[0] = (size_t)&cpu->cd.sh.mach;
3549 				break;
3550 			case 0x03:	/*  STC.L SR,@-Rn  */
3551 				ic->f = instr(stc_l_rm_predec_rn_md);
3552 				ic->arg[0] = (size_t)&cpu->cd.sh.sr;
3553 				break;
3554 			case 0x04:	/*  ROTL Rn  */
3555 				ic->f = instr(rotl_rn);
3556 				break;
3557 			case 0x05:	/*  ROTR Rn  */
3558 				ic->f = instr(rotr_rn);
3559 				break;
3560 			case 0x06:	/*  LDS.L @Rm+,MACH  */
3561 				ic->f = instr(mov_l_arg1_postinc_to_arg0);
3562 				ic->arg[0] = (size_t)&cpu->cd.sh.mach;
3563 				break;
3564 			case 0x07:	/*  LDC.L @Rm+,SR  */
3565 				ic->f = instr(mov_l_arg1_postinc_to_arg0_md);
3566 				ic->arg[0] = (size_t)&cpu->cd.sh.sr;
3567 				break;
3568 			case 0x08:	/*  SHLL2 Rn  */
3569 				ic->f = instr(shll2_rn);
3570 				break;
3571 			case 0x09:	/*  SHLR2 Rn  */
3572 				ic->f = instr(shlr2_rn);
3573 				break;
3574 			case 0x0a:	/*  LDS Rm,MACH  */
3575 				ic->f = instr(mov_rm_rn);
3576 				ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];	/* m */
3577 				ic->arg[1] = (size_t)&cpu->cd.sh.mach;
3578 				break;
3579 			case 0x0b:	/*  JSR @Rn  */
3580 				if (cpu->machine->show_trace_tree)
3581 					ic->f = instr(jsr_rn_trace);
3582 				else
3583 					ic->f = instr(jsr_rn);
3584 				ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];	/* n */
3585 				ic->arg[1] = (addr & 0xffe) + 4;
3586 				break;
3587 			case 0x0e:	/*  LDC Rm,SR  */
3588 				ic->f = instr(ldc_rm_sr);
3589 				break;
3590 			case 0x10:	/*  DT Rn  */
3591 				ic->f = instr(dt_rn);
3592 				break;
3593 			case 0x11:	/*  CMP/PZ Rn  */
3594 				ic->f = instr(cmppz_rn);
3595 				break;
3596 			case 0x12:	/*  STS.L MACL,@-Rn  */
3597 				ic->f = instr(mov_l_rm_predec_rn);
3598 				ic->arg[0] = (size_t)&cpu->cd.sh.macl;
3599 				break;
3600 			case 0x13:	/*  STC.L GBR,@-Rn  */
3601 				ic->f = instr(mov_l_rm_predec_rn);
3602 				ic->arg[0] = (size_t)&cpu->cd.sh.gbr;
3603 				break;
3604 			case 0x15:	/*  CMP/PL Rn  */
3605 				ic->f = instr(cmppl_rn);
3606 				break;
3607 			case 0x16:	/*  LDS.L @Rm+,MACL  */
3608 				ic->f = instr(mov_l_arg1_postinc_to_arg0);
3609 				ic->arg[0] = (size_t)&cpu->cd.sh.macl;
3610 				break;
3611 			case 0x17:	/*  LDC.L @Rm+,GBR  */
3612 				ic->f = instr(mov_l_arg1_postinc_to_arg0);
3613 				ic->arg[0] = (size_t)&cpu->cd.sh.gbr;
3614 				break;
3615 			case 0x18:	/*  SHLL8 Rn  */
3616 				ic->f = instr(shll8_rn);
3617 				break;
3618 			case 0x19:	/*  SHLR8 Rn  */
3619 				ic->f = instr(shlr8_rn);
3620 				break;
3621 			case 0x1a:	/*  LDS Rm,MACL  */
3622 				ic->f = instr(mov_rm_rn);
3623 				ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];	/* m */
3624 				ic->arg[1] = (size_t)&cpu->cd.sh.macl;
3625 				break;
3626 			case 0x1b:	/*  TAS.B @Rn  */
3627 				ic->f = instr(tas_b_rn);
3628 				break;
3629 			case 0x1e:	/*  LDC Rm,GBR  */
3630 				ic->f = instr(mov_rm_rn);
3631 				ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];	/* m */
3632 				ic->arg[1] = (size_t)&cpu->cd.sh.gbr;
3633 				break;
3634 			case 0x20:	/*  SHAL Rn  */
3635 				ic->f = instr(shll_rn);  /*  NOTE: shll  */
3636 				break;
3637 			case 0x21:	/*  SHAR Rn  */
3638 				ic->f = instr(shar_rn);
3639 				break;
3640 			case 0x22:	/*  STS.L PR,@-Rn  */
3641 				ic->f = instr(mov_l_rm_predec_rn);
3642 				ic->arg[0] = (size_t)&cpu->cd.sh.pr;	/* m */
3643 				ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];	/* n */
3644 				break;
3645 			case 0x23:	/*  STC.L VBR,@-Rn  */
3646 				ic->f = instr(stc_l_rm_predec_rn_md);
3647 				ic->arg[0] = (size_t)&cpu->cd.sh.vbr;
3648 				break;
3649 			case 0x24:	/*  ROTCL Rn  */
3650 				ic->f = instr(rotcl_rn);
3651 				break;
3652 			case 0x25:	/*  ROTCR Rn  */
3653 				ic->f = instr(rotcr_rn);
3654 				break;
3655 			case 0x26:	/*  LDS.L @Rm+,PR  */
3656 				ic->f = instr(mov_l_arg1_postinc_to_arg0);
3657 				ic->arg[0] = (size_t)&cpu->cd.sh.pr;
3658 				break;
3659 			case 0x27:	/*  LDC.L @Rm+,VBR  */
3660 				ic->f = instr(mov_l_arg1_postinc_to_arg0_md);
3661 				ic->arg[0] = (size_t)&cpu->cd.sh.vbr;
3662 				break;
3663 			case 0x28:	/*  SHLL16 Rn  */
3664 				ic->f = instr(shll16_rn);
3665 				break;
3666 			case 0x29:	/*  SHLR16 Rn  */
3667 				ic->f = instr(shlr16_rn);
3668 				break;
3669 			case 0x2a:	/*  LDS Rm,PR  */
3670 				ic->f = instr(mov_rm_rn);
3671 				ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];	/* m */
3672 				ic->arg[1] = (size_t)&cpu->cd.sh.pr;
3673 				break;
3674 			case 0x2b:	/*  JMP @Rn  */
3675 				if (cpu->machine->show_trace_tree)
3676 					ic->f = instr(jmp_rn_trace);
3677 				else
3678 					ic->f = instr(jmp_rn);
3679 				ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];	/* n */
3680 				ic->arg[1] = (addr & 0xffe) + 4;
3681 				break;
3682 			case 0x2e:	/*  LDC Rm,VBR  */
3683 				ic->f = instr(copy_privileged_register);
3684 				ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];	/* m */
3685 				ic->arg[1] = (size_t)&cpu->cd.sh.vbr;
3686 				break;
3687 			case 0x33:	/*  STC.L SSR,@-Rn  */
3688 				ic->f = instr(stc_l_rm_predec_rn_md);
3689 				ic->arg[0] = (size_t)&cpu->cd.sh.ssr;
3690 				break;
3691 			case 0x37:	/*  LDC.L @Rm+,SSR  */
3692 				ic->f = instr(mov_l_arg1_postinc_to_arg0_md);
3693 				ic->arg[0] = (size_t)&cpu->cd.sh.ssr;
3694 				break;
3695 			case 0x3e:	/*  LDC rm,SSR  */
3696 				ic->f = instr(copy_privileged_register);
3697 				ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];	/* m */
3698 				ic->arg[1] = (size_t)&cpu->cd.sh.ssr;
3699 				break;
3700 			case 0x43:	/*  STC.L SPC,@-Rn  */
3701 				ic->f = instr(stc_l_rm_predec_rn_md);
3702 				ic->arg[0] = (size_t)&cpu->cd.sh.spc;
3703 				break;
3704 			case 0x47:	/*  LDC.L @Rm+,SPC  */
3705 				ic->f = instr(mov_l_arg1_postinc_to_arg0_md);
3706 				ic->arg[0] = (size_t)&cpu->cd.sh.spc;
3707 				break;
3708 			case 0x4e:	/*  LDC rm,SPC  */
3709 				ic->f = instr(copy_privileged_register);
3710 				ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];	/* m */
3711 				ic->arg[1] = (size_t)&cpu->cd.sh.spc;
3712 				break;
3713 			case 0x52:	/*  STS.L FPUL,@-Rn  */
3714 				ic->f = instr(mov_l_rm_predec_rn);
3715 				ic->arg[0] = (size_t)&cpu->cd.sh.fpul;
3716 				ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];	/* n */
3717 				break;
3718 			case 0x56:	/*  LDS.L @Rm+,FPUL  */
3719 				ic->f = instr(mov_l_arg1_postinc_to_arg0_fp);
3720 				ic->arg[0] = (size_t)&cpu->cd.sh.fpul;
3721 				break;
3722 			case 0x5a:	/*  LDS Rm,FPUL  */
3723 				ic->f = instr(copy_fp_register);
3724 				ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];	/* m */
3725 				ic->arg[1] = (size_t)&cpu->cd.sh.fpul;
3726 				break;
3727 			case 0x62:	/*  STS.L FPSCR,@-Rn  */
3728 				ic->f = instr(mov_l_rm_predec_rn);
3729 				ic->arg[0] = (size_t)&cpu->cd.sh.fpscr;
3730 				ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];	/* n */
3731 				break;
3732 			case 0x66:	/*  LDS.L @Rm+,FPSCR  */
3733 				/*  Note: Loading into FPSCR is a specia
3734 				    case (need to call sh_update_fpsrc()).  */
3735 				ic->f = instr(mov_l_arg1_postinc_to_arg0_fp);
3736 				ic->arg[0] = (size_t)&cpu->cd.sh.fpscr;
3737 				break;
3738 			case 0x6a:	/*  LDS Rm,FPSCR  */
3739 				ic->f = instr(lds_rm_fpscr);
3740 				/*  arg 1 = R8 = Rm  */
3741 				break;
3742 			case 0xfa:	/*  LDC Rm,DBR  */
3743 				ic->f = instr(copy_privileged_register);
3744 				ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];
3745 				ic->arg[1] = (size_t)&cpu->cd.sh.dbr;
3746 				break;
3747 			default:if (!cpu->translation_readahead)
3748 					fatal("Unimplemented opcode 0x%x,"
3749 					    "0x%02x\n", main_opcode, lo8);
3750 				goto bad;
3751 			}
3752 		}
3753 		break;
3754 
3755 	case 0x5:
3756 		ic->f = instr(mov_l_disp_rm_rn);
3757 		ic->arg[0] = r4 + (lo4 << 4);
3758 		break;
3759 
3760 	case 0x6:
3761 		switch (lo4) {
3762 		case 0x0:	/*  MOV.B @Rm,Rn  */
3763 			ic->f = instr(load_b_rm_rn);
3764 			break;
3765 		case 0x1:	/*  MOV.W @Rm,Rn  */
3766 			ic->f = instr(load_w_rm_rn);
3767 			break;
3768 		case 0x2:	/*  MOV.L @Rm,Rn  */
3769 			ic->f = instr(load_l_rm_rn);
3770 			break;
3771 		case 0x3:	/*  MOV Rm,Rn  */
3772 			ic->f = instr(mov_rm_rn);
3773 			break;
3774 		case 0x4:	/*  MOV.B @Rm+,Rn  */
3775 			ic->f = instr(mov_b_arg1_postinc_to_arg0);
3776 			/*  Note: Order  */
3777 			ic->arg[1] = (size_t)&cpu->cd.sh.r[r4];	/* m */
3778 			ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];	/* n */
3779 			break;
3780 		case 0x5:	/*  MOV.W @Rm+,Rn  */
3781 			ic->f = instr(mov_w_arg1_postinc_to_arg0);
3782 			/*  Note: Order  */
3783 			ic->arg[1] = (size_t)&cpu->cd.sh.r[r4];	/* m */
3784 			ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];	/* n */
3785 			break;
3786 		case 0x6:	/*  MOV.L @Rm+,Rn  */
3787 			ic->f = instr(mov_l_arg1_postinc_to_arg0);
3788 			/*  Note: Order  */
3789 			ic->arg[1] = (size_t)&cpu->cd.sh.r[r4];	/* m */
3790 			ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];	/* n */
3791 			break;
3792 		case 0x7:	/*  NOT Rm,Rn  */
3793 			ic->f = instr(not_rm_rn);
3794 			break;
3795 		case 0x8:	/*  SWAP.B Rm,Rn  */
3796 			ic->f = instr(swap_b_rm_rn);
3797 			break;
3798 		case 0x9:	/*  SWAP.W Rm,Rn  */
3799 			ic->f = instr(swap_w_rm_rn);
3800 			break;
3801 		case 0xa:	/*  NEGC Rm,Rn  */
3802 			ic->f = instr(negc_rm_rn);
3803 			break;
3804 		case 0xb:	/*  NEG Rm,Rn  */
3805 			ic->f = instr(neg_rm_rn);
3806 			break;
3807 		case 0xc:	/*  EXTU.B Rm,Rn  */
3808 			ic->f = instr(extu_b_rm_rn);
3809 			if (r8 == r4)
3810 				ic->f = instr(extu_b_rm);
3811 			break;
3812 		case 0xd:	/*  EXTU.W Rm,Rn  */
3813 			ic->f = instr(extu_w_rm_rn);
3814 			if (r8 == r4)
3815 				ic->f = instr(extu_w_rm);
3816 			break;
3817 		case 0xe:	/*  EXTS.B Rm,Rn  */
3818 			ic->f = instr(exts_b_rm_rn);
3819 			break;
3820 		case 0xf:	/*  EXTS.W Rm,Rn  */
3821 			ic->f = instr(exts_w_rm_rn);
3822 			break;
3823 		default:if (!cpu->translation_readahead)
3824 				fatal("Unimplemented opcode 0x%x,0x%x\n",
3825 				    main_opcode, lo4);
3826 			goto bad;
3827 		}
3828 		break;
3829 
3830 	case 0x7:	/*  ADD #imm,Rn  */
3831 		ic->f = instr(add_imm_rn);
3832 		ic->arg[0] = (int8_t)lo8;
3833 		ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];		/* n */
3834 		if (lo8 == 1)
3835 			ic->f = instr(inc_rn);
3836 		if (lo8 == 4)
3837 			ic->f = instr(add_4_rn);
3838 		if (lo8 == 0xfc)
3839 			ic->f = instr(sub_4_rn);
3840 		if (lo8 == 0xff)
3841 			ic->f = instr(dec_rn);
3842 		break;
3843 
3844 	case 0x8:
3845 		/*  Displacement from beginning of page = default arg 0.  */
3846 		ic->arg[0] = (int8_t)lo8 * 2 +
3847 		    (addr & ((SH_IC_ENTRIES_PER_PAGE-1)
3848 		    << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4;
3849 		samepage_function = NULL;
3850 
3851 		switch (r8) {
3852 		case 0x0:	/*  MOV.B R0,@(disp,Rn)  */
3853 			ic->f = instr(mov_b_r0_disp_rn);
3854 			ic->arg[0] = (size_t)&cpu->cd.sh.r[r4];	/* n */
3855 			ic->arg[1] = lo4;
3856 			break;
3857 		case 0x1:	/*  MOV.W R0,@(disp,Rn)  */
3858 			ic->f = instr(mov_w_r0_disp_rn);
3859 			ic->arg[0] = (size_t)&cpu->cd.sh.r[r4];	/* n */
3860 			ic->arg[1] = lo4 * 2;
3861 			break;
3862 		case 0x4:	/*  MOV.B @(disp,Rn),R0  */
3863 			ic->f = instr(mov_b_disp_rn_r0);
3864 			ic->arg[0] = (size_t)&cpu->cd.sh.r[r4];	/* n */
3865 			ic->arg[1] = lo4;
3866 			break;
3867 		case 0x5:	/*  MOV.W @(disp,Rn),R0  */
3868 			ic->f = instr(mov_w_disp_rn_r0);
3869 			ic->arg[0] = (size_t)&cpu->cd.sh.r[r4];	/* n */
3870 			ic->arg[1] = lo4 * 2;
3871 			break;
3872 		case 0x8:	/*  CMP/EQ #imm,R0  */
3873 			ic->f = instr(cmpeq_imm_r0);
3874 			ic->arg[0] = (int8_t)lo8;
3875 			break;
3876 		case 0x9:	/*  BT (disp,PC)  */
3877 			ic->f = instr(bt);
3878 			samepage_function = instr(bt_samepage);
3879 			break;
3880 		case 0xb:	/*  BF (disp,PC)  */
3881 			ic->f = instr(bf);
3882 			samepage_function = instr(bf_samepage);
3883 			break;
3884 		case 0xd:	/*  BT/S (disp,PC)  */
3885 			ic->f = instr(bt_s);
3886 			samepage_function = instr(bt_s_samepage);
3887 			break;
3888 		case 0xf:	/*  BF/S (disp,PC)  */
3889 			ic->f = instr(bf_s);
3890 			samepage_function = instr(bf_s_samepage);
3891 			break;
3892 		default:if (!cpu->translation_readahead)
3893 				fatal("Unimplemented opcode 0x%x,0x%x\n",
3894 				    main_opcode, r8);
3895 			goto bad;
3896 		}
3897 
3898 		/*  samepage branches:  */
3899 		if (samepage_function != NULL && ic->arg[0] < 0x1000 &&
3900 		    (addr & 0xfff) < 0xffe) {
3901 			ic->arg[1] = (size_t) (cpu->cd.sh.cur_ic_page +
3902 			    (ic->arg[0] >> SH_INSTR_ALIGNMENT_SHIFT));
3903 			ic->f = samepage_function;
3904 		}
3905 
3906 		if (ic->f == instr(bt_samepage))
3907 			cpu->cd.sh.combination_check = COMBINE(bt_samepage);
3908 
3909 		break;
3910 
3911 	case 0x9:	/*  MOV.W @(disp,PC),Rn  */
3912 		ic->f = instr(mov_w_disp_pc_rn);
3913 		ic->arg[0] = lo8 * 2 + (addr & ((SH_IC_ENTRIES_PER_PAGE-1)
3914 		    << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4;
3915 
3916 		/*  If the word is reachable from the same page as the
3917 		    current address, then optimize it as a mov_imm_rn:  */
3918 		if (ic->arg[0] < 0x1000 && page != NULL) {
3919 			uint16_t *p = (uint16_t *) page;
3920 			uint16_t data = p[ic->arg[0] >> 1];
3921 			if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3922 				data = LE16_TO_HOST(data);
3923 			else
3924 				data = BE16_TO_HOST(data);
3925 			ic->f = instr(mov_imm_rn);
3926 			ic->arg[0] = (int16_t) data;
3927 		}
3928 		break;
3929 
3930 	case 0xa:	/*  BRA disp  */
3931 	case 0xb:	/*  BSR disp  */
3932 		samepage_function = NULL;
3933 
3934 		switch (main_opcode) {
3935 		case 0xa:
3936 			ic->f = instr(bra);
3937 			samepage_function = instr(bra_samepage);
3938 			break;
3939 		case 0xb:
3940 			if (cpu->machine->show_trace_tree)
3941 				ic->f = instr(bsr_trace);
3942 			else
3943 			{
3944 				ic->f = instr(bsr);
3945 				samepage_function = instr(bsr_samepage);
3946 			}
3947 			break;
3948 		}
3949 
3950 		ic->arg[0] = (int32_t) ( (addr & ((SH_IC_ENTRIES_PER_PAGE-1)
3951 		    << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4 +
3952 		    (((int32_t)(int16_t)((iword & 0xfff) << 4)) >> 3) );
3953 
3954 		/*  samepage branches:  */
3955 		if (samepage_function != NULL && ic->arg[0] < 0x1000 &&
3956 		    (addr & 0xfff) < 0xffe) {
3957 			ic->arg[0] = (size_t) (cpu->cd.sh.cur_ic_page +
3958 			    (ic->arg[0] >> SH_INSTR_ALIGNMENT_SHIFT));
3959 			ic->f = samepage_function;
3960 		}
3961 		break;
3962 
3963 	case 0xc:
3964 		switch (r8) {
3965 		case 0x0:
3966 			ic->f = instr(mov_b_r0_disp_gbr);
3967 			ic->arg[1] = lo8;
3968 			break;
3969 		case 0x1:
3970 			ic->f = instr(mov_w_r0_disp_gbr);
3971 			ic->arg[1] = lo8 << 1;
3972 			break;
3973 		case 0x2:
3974 			ic->f = instr(mov_l_r0_disp_gbr);
3975 			ic->arg[1] = lo8 << 2;
3976 			break;
3977 		case 0x3:
3978 			ic->f = instr(trapa);
3979 			ic->arg[0] = lo8 << 2;
3980 			break;
3981 		case 0x4:
3982 			ic->f = instr(mov_b_disp_gbr_r0);
3983 			ic->arg[1] = lo8;
3984 			break;
3985 		case 0x5:
3986 			ic->f = instr(mov_w_disp_gbr_r0);
3987 			ic->arg[1] = lo8 << 1;
3988 			break;
3989 		case 0x6:
3990 			ic->f = instr(mov_l_disp_gbr_r0);
3991 			ic->arg[1] = lo8 << 2;
3992 			break;
3993 		case 0x7:	/*  MOVA @(disp,pc),R0  */
3994 			ic->f = instr(mova_r0);
3995 			ic->arg[0] = lo8 * 4 + (addr &
3996 			    ((SH_IC_ENTRIES_PER_PAGE-1)
3997 			    << SH_INSTR_ALIGNMENT_SHIFT) & ~3) + 4;
3998 			break;
3999 		case 0x8:	/*  TST #imm,R0  */
4000 			ic->f = instr(tst_imm_r0);
4001 			ic->arg[0] = lo8;
4002 			break;
4003 		case 0x9:	/*  AND #imm,R0  */
4004 			ic->f = instr(and_imm_r0);
4005 			ic->arg[0] = lo8;
4006 			break;
4007 		case 0xa:	/*  XOR #imm,R0  */
4008 			ic->f = instr(xor_imm_r0);
4009 			ic->arg[0] = lo8;
4010 			break;
4011 		case 0xb:	/*  OR #imm,R0  */
4012 			ic->f = instr(or_imm_r0);
4013 			ic->arg[0] = lo8;
4014 			break;
4015 		case 0xd:	/*  AND.B #imm,@(R0,GBR)  */
4016 			ic->f = instr(and_b_imm_r0_gbr);
4017 			ic->arg[0] = lo8;
4018 			break;
4019 		case 0xe:	/*  XOR.B #imm,@(R0,GBR)  */
4020 			ic->f = instr(xor_b_imm_r0_gbr);
4021 			ic->arg[0] = lo8;
4022 			break;
4023 		case 0xf:	/*  OR.B #imm,@(R0,GBR)  */
4024 			ic->f = instr(or_b_imm_r0_gbr);
4025 			ic->arg[0] = lo8;
4026 			break;
4027 		default:if (!cpu->translation_readahead)
4028 				fatal("Unimplemented opcode 0x%x,0x%x\n",
4029 				    main_opcode, r8);
4030 			goto bad;
4031 		}
4032 		break;
4033 
4034 	case 0xd:	/*  MOV.L @(disp,PC),Rn  */
4035 		ic->f = instr(mov_l_disp_pc_rn);
4036 		ic->arg[0] = lo8 * 4 + (addr & ((SH_IC_ENTRIES_PER_PAGE-1)
4037 		    << SH_INSTR_ALIGNMENT_SHIFT) & ~3) + 4;
4038 
4039 		/*  If the word is reachable from the same page as the
4040 		    current address, then optimize it as a mov_imm_rn:  */
4041 		if (ic->arg[0] < 0x1000 && page != NULL) {
4042 			uint32_t *p = (uint32_t *) page;
4043 			uint32_t data = p[ic->arg[0] >> 2];
4044 			if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
4045 				data = LE32_TO_HOST(data);
4046 			else
4047 				data = BE32_TO_HOST(data);
4048 			ic->f = instr(mov_imm_rn);
4049 			ic->arg[0] = data;
4050 		}
4051 		break;
4052 
4053 	case 0xe:	/*  MOV #imm,Rn  */
4054 		ic->f = instr(mov_imm_rn);
4055 		ic->arg[0] = (int8_t)lo8;
4056 		ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];	/* n */
4057 		if (lo8 == 0)
4058 			ic->f = instr(mov_0_rn);
4059 		break;
4060 
4061 	case 0xf:
4062 		if (lo4 == 0x0) {
4063 			/*  FADD FRm,FRn  */
4064 			ic->f = instr(fadd_frm_frn);
4065 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r4];
4066 			ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];
4067 		} else if (lo4 == 0x1) {
4068 			/*  FSUB FRm,FRn  */
4069 			ic->f = instr(fsub_frm_frn);
4070 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r4];
4071 			ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];
4072 		} else if (lo4 == 0x2) {
4073 			/*  FMUL FRm,FRn  */
4074 			ic->f = instr(fmul_frm_frn);
4075 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r4];
4076 			ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];
4077 		} else if (lo4 == 0x3) {
4078 			/*  FDIV FRm,FRn  */
4079 			ic->f = instr(fdiv_frm_frn);
4080 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r4];
4081 			ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];
4082 		} else if (lo4 == 0x4) {
4083 			/*  FCMP/EQ FRm,FRn  */
4084 			ic->f = instr(fcmp_eq_frm_frn);
4085 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r4];
4086 			ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];
4087 		} else if (lo4 == 0x5) {
4088 			/*  FCMP/GT FRm,FRn  */
4089 			ic->f = instr(fcmp_gt_frm_frn);
4090 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r4];
4091 			ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];
4092 		} else if (lo4 == 0x6) {
4093 			/*  FMOV @(R0,Rm),FRn  */
4094 			ic->f = instr(fmov_r0_rm_frn);
4095 			ic->arg[0] = (size_t)&cpu->cd.sh.r[r4];  /* m */
4096 			ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];
4097 		} else if (lo4 == 0x7) {
4098 			/*  FMOV FRm,@(R0,Rn)  */
4099 			ic->f = instr(fmov_frm_r0_rn);
4100 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r4];  /* m */
4101 			ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];
4102 		} else if (lo4 == 0x8) {
4103 			/*  FMOV @Rm,FRn  */
4104 			ic->f = instr(fmov_rm_frn);
4105 			ic->arg[0] = (size_t)&cpu->cd.sh.r[r4];  /* m */
4106 			ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];
4107 		} else if (lo4 == 0x9) {
4108 			/*  FMOV @Rm+,FRn  */
4109 			ic->f = instr(fmov_rm_postinc_frn);
4110 			ic->arg[0] = (size_t)&cpu->cd.sh.r[r4];  /* m */
4111 			ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];
4112 		} else if (lo4 == 0xa) {
4113 			/*  FMOV FRm,@Rn  */
4114 			ic->f = instr(fmov_frm_rn);
4115 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r4];  /* m */
4116 			ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];
4117 		} else if (lo4 == 0xb) {
4118 			/*  FMOV FRm,@-Rn  */
4119 			ic->f = instr(fmov_frm_predec_rn);
4120 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r4];  /* m */
4121 			ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];
4122 		} else if (lo4 == 0xc) {
4123 			/*  FMOV FRm,FRn  */
4124 			ic->f = instr(fmov_frm_frn);
4125 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r4];
4126 			ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];
4127 		} else if (lo8 == 0x0d) {
4128 			/*  FSTS FPUL,FRn  */
4129 			ic->f = instr(copy_fp_register);
4130 			ic->arg[0] = (size_t)&cpu->cd.sh.fpul;
4131 			ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];
4132 		} else if (lo8 == 0x1d) {
4133 			/*  FLDS FRn,FPUL  */
4134 			ic->f = instr(copy_fp_register);
4135 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];
4136 			ic->arg[1] = (size_t)&cpu->cd.sh.fpul;
4137 		} else if (lo8 == 0x2d) {
4138 			/*  FLOAT FPUL,FRn  */
4139 			ic->f = instr(float_fpul_frn);
4140 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];
4141 		} else if (lo8 == 0x3d) {
4142 			/*  FTRC FRm,FPUL  */
4143 			ic->f = instr(ftrc_frm_fpul);
4144 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];
4145 		} else if (lo8 == 0x4d) {
4146 			/*  FNEG FRn  */
4147 			ic->f = instr(fneg_frn);
4148 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];
4149 		} else if (lo8 == 0x5d) {
4150 			/*  FABS FRn  */
4151 			ic->f = instr(fabs_frn);
4152 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];
4153 		} else if (lo8 == 0x6d) {
4154 			/*  FSQRT FRn  */
4155 			ic->f = instr(fsqrt_frn);
4156 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];
4157 		} else if (lo8 == 0x7d) {
4158 			/*  FSRRA FRn  */
4159 			ic->f = instr(fsrra_frn);
4160 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];
4161 		} else if (lo8 == 0x8d) {
4162 			/*  FLDI0 FRn  */
4163 			ic->f = instr(fldi_frn);
4164 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];
4165 			ic->arg[1] = 0x00000000;
4166 		} else if (lo8 == 0x9d) {
4167 			/*  FLDI1 FRn  */
4168 			ic->f = instr(fldi_frn);
4169 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];
4170 			ic->arg[1] = 0x3f800000;
4171 		} else if ((iword & 0x01ff) == 0x00ad) {
4172 			/*  FCNVSD FPUL,DRn  */
4173 			ic->f = instr(fcnvsd_fpul_drn);
4174 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];
4175 		} else if ((iword & 0x01ff) == 0x00bd) {
4176 			/*  FCNVDS DRm,FPUL  */
4177 			ic->f = instr(fcnvds_drm_fpul);
4178 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];
4179 		} else if (lo8 == 0xed) {
4180 			/*  FIPR FVm,FVn  */
4181 			ic->f = instr(fipr_fvm_fvn);
4182 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[(r8<<2) & 0xc];  /* m */
4183 			ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8 & 0xc];  /* n */
4184 		} else if ((iword & 0x01ff) == 0x00fd) {
4185 			/*  FSCA FPUL,DRn  */
4186 			ic->f = instr(fsca_fpul_drn);
4187 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];
4188 		} else if (iword == 0xf3fd) {
4189 			/*  FSCHG  */
4190 			ic->f = instr(fschg);
4191 		} else if (iword == 0xfbfd) {
4192 			/*  FRCHG  */
4193 			ic->f = instr(frchg);
4194 		} else if ((iword & 0xf3ff) == 0xf1fd) {
4195 			/*  FTRV XMTRX, FVn  */
4196 			ic->f = instr(ftrv_xmtrx_fvn);
4197 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8 & 0xc];
4198 		} else if (lo4 == 0xe) {
4199 			/*  FMAC FR0,FRm,FRn  */
4200 			ic->f = instr(fmac_fr0_frm_frn);
4201 			ic->arg[0] = (size_t)&cpu->cd.sh.fr[r4];
4202 			ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];
4203 		} else {
4204 			if (!cpu->translation_readahead)
4205 				fatal("Unimplemented opcode 0x%x,0x%02x\n",
4206 				    main_opcode, lo8);
4207 			goto bad;
4208 		}
4209 		break;
4210 
4211 	default:if (!cpu->translation_readahead)
4212 			fatal("Unimplemented main opcode 0x%x\n", main_opcode);
4213 		goto bad;
4214 	}
4215 
4216 
4217 #define	DYNTRANS_TO_BE_TRANSLATED_TAIL
4218 #include "cpu_dyntrans.cc"
4219 #undef	DYNTRANS_TO_BE_TRANSLATED_TAIL
4220 }
4221 
4222