1 /*
2  *  Copyright (C) 2005-2020  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  *  MIPS 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 /*
38  *  COPROC_AVAILABILITY_CHECK(n) checks for the coprocessor available bit for
39  *  coprocessor number n, and causes a CoProcessor Unusable exception if it
40  *  is not set.  (Note: For coprocessor 0 checks, use cop0_availability_check!)
41  */
42 #ifndef	COPROC_AVAILABILITY_CHECK
43 #define	COPROC_AVAILABILITY_CHECK(x)		{		\
44 		const int cpnr = (x);					\
45 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page) \
46 		    / sizeof(struct mips_instr_call);			\
47 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)		\
48 		    << MIPS_INSTR_ALIGNMENT_SHIFT);			\
49 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);	\
50 		if (!(cpu->cd.mips.coproc[0]->reg[COP0_STATUS] &	\
51 		    ((1 << cpnr) << STATUS_CU_SHIFT)) ) {		\
52 			mips_cpu_exception(cpu, EXCEPTION_CPU,		\
53 			    0, 0, cpnr, 0, 0, 0);			\
54 			return;						\
55 		}							\
56 	}
57 #endif
58 
59 
60 #ifndef	COP0_AVAILABILITY_CHECK_INCLUDED
61 #define	COP0_AVAILABILITY_CHECK_INCLUDED
62 /*
63  *  cop0_availability_check() causes a CoProcessor Unusable exception if
64  *  we are currently running in usermode, and the coprocessor available bit
65  *  for coprocessor 0 is not set.
66  *
67  *  Returns 1 if ok (i.e. if the coprocessor was usable), 0 on exceptions.
68  */
cop0_availability_check(struct cpu * cpu,struct mips_instr_call * ic)69 int cop0_availability_check(struct cpu *cpu, struct mips_instr_call *ic)
70 {
71 	int in_usermode = 0;
72 	struct mips_coproc *cp0 = cpu->cd.mips.coproc[0];
73 
74 	switch (cpu->cd.mips.cpu_type.exc_model) {
75 	case EXC3K:
76 		/*
77 		 *  NOTE: If the KU bit is checked, Linux crashes.
78 		 *  It is the PC that counts.
79 		 *
80 		 *  TODO: Check whether this is true or not for R4000 as well.
81 		 */
82 		/*  TODO: if (cp0->reg[COP0_STATUS] & MIPS1_SR_KU_CUR)  */
83 		if (cpu->pc <= 0x7fffffff)
84 			in_usermode = 1;
85 		break;
86 	default:
87 		/*  R4000 etc:  (TODO: How about supervisor mode?)  */
88 		if (((cp0->reg[COP0_STATUS] &
89 		    STATUS_KSU_MASK) >> STATUS_KSU_SHIFT) != KSU_KERNEL)
90 			in_usermode = 1;
91 		if (cp0->reg[COP0_STATUS] & (STATUS_ERL | STATUS_EXL))
92 			in_usermode = 0;
93 		break;
94 	}
95 
96 	if (in_usermode) {
97 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
98 		    / sizeof(struct mips_instr_call);
99 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
100 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
101 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
102 		if (!(cpu->cd.mips.coproc[0]->reg[COP0_STATUS] &
103 		    (1 << STATUS_CU_SHIFT)) ) {
104 			mips_cpu_exception(cpu, EXCEPTION_CPU,
105 			    0, 0, /* cpnr */ 0, 0, 0, 0);
106 			return 0;
107 		}
108 	}
109 
110 	return 1;
111 }
112 #endif
113 
114 
115 /*
116  *  invalid:  For catching bugs.
117  */
X(invalid)118 X(invalid)
119 {
120 	fatal("FATAL ERROR: An internal error occured in the MIPS"
121 	    " dyntrans code. Please contact the author with detailed"
122 	    " repro steps on how to trigger this bug.\n");
123 	exit(1);
124 }
125 
126 
127 /*
128  *  reserved:  Attempt to execute a reserved instruction (e.g. a 64-bit
129  *             instruction on an emulated 32-bit processor).
130  */
X(reserved)131 X(reserved)
132 {
133 	/*  Synchronize the PC and cause an exception:  */
134 	int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
135 	    / sizeof(struct mips_instr_call);
136 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
137 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
138 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
139 	mips_cpu_exception(cpu, EXCEPTION_RI, 0, 0, 0, 0, 0, 0);
140 }
141 
142 
143 /*
144  *  cpu:  Cause a CoProcessor Unusable exception.
145  *
146  *  arg[0] = the number of the coprocessor
147  */
X(cpu)148 X(cpu)
149 {
150 	/*  Synchronize the PC and cause an exception:  */
151 	int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
152 	    / sizeof(struct mips_instr_call);
153 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
154 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
155 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
156 	mips_cpu_exception(cpu, EXCEPTION_CPU, 0, 0, ic->arg[0], 0, 0, 0);
157 }
158 
159 
160 /*
161  *  nop:  Do nothing.
162  */
X(nop)163 X(nop)
164 {
165 }
166 
167 
168 /*
169  *  beq:  Branch if equal
170  *  bne:  Branch if not equal
171  *  b:  Branch (comparing a register to itself, always true)
172  *
173  *  arg[0] = pointer to rs
174  *  arg[1] = pointer to rt
175  *  arg[2] = (int32_t) relative offset from the next instruction
176  */
X(beq)177 X(beq)
178 {
179 	MODE_int_t old_pc = cpu->pc;
180 	MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
181 	int x = rs == rt;
182 	cpu->delay_slot = TO_BE_DELAYED;
183 	ic[1].f(cpu, ic+1);
184 	cpu->n_translated_instrs ++;
185 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
186 		/*  Note: Must be non-delayed when jumping to the new pc:  */
187 		cpu->delay_slot = NOT_DELAYED;
188 		if (x) {
189 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
190 			    MIPS_INSTR_ALIGNMENT_SHIFT);
191 			cpu->pc = old_pc + (int32_t)ic->arg[2];
192 			quick_pc_to_pointers(cpu);
193 		} else
194 			cpu->cd.mips.next_ic ++;
195 	} else
196 		cpu->delay_slot = NOT_DELAYED;
197 }
X(beq_samepage)198 X(beq_samepage)
199 {
200 	MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
201 	int x = rs == rt;
202 	cpu->delay_slot = TO_BE_DELAYED;
203 	ic[1].f(cpu, ic+1);
204 	cpu->n_translated_instrs ++;
205 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
206 		if (x)
207 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
208 			    ic->arg[2];
209 		else
210 			cpu->cd.mips.next_ic ++;
211 	}
212 	cpu->delay_slot = NOT_DELAYED;
213 }
X(beq_samepage_addiu)214 X(beq_samepage_addiu)
215 {
216 	MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
217 	cpu->n_translated_instrs ++;
218 	reg(ic[1].arg[1]) = (int32_t)
219 	    ((int32_t)reg(ic[1].arg[0]) + (int32_t)ic[1].arg[2]);
220 	if (rs == rt)
221 		cpu->cd.mips.next_ic = (struct mips_instr_call *) ic->arg[2];
222 	else
223 		cpu->cd.mips.next_ic ++;
224 }
X(beq_samepage_nop)225 X(beq_samepage_nop)
226 {
227 	MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
228 	cpu->n_translated_instrs ++;
229 	if (rs == rt)
230 		cpu->cd.mips.next_ic = (struct mips_instr_call *) ic->arg[2];
231 	else
232 		cpu->cd.mips.next_ic ++;
233 }
X(bne)234 X(bne)
235 {
236 	MODE_int_t old_pc = cpu->pc;
237 	MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
238 	int x = rs != rt;
239 	cpu->delay_slot = TO_BE_DELAYED;
240 	ic[1].f(cpu, ic+1);
241 	cpu->n_translated_instrs ++;
242 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
243 		/*  Note: Must be non-delayed when jumping to the new pc:  */
244 		cpu->delay_slot = NOT_DELAYED;
245 		if (x) {
246 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
247 			    MIPS_INSTR_ALIGNMENT_SHIFT);
248 			cpu->pc = old_pc + (int32_t)ic->arg[2];
249 			quick_pc_to_pointers(cpu);
250 		} else
251 			cpu->cd.mips.next_ic ++;
252 	} else
253 		cpu->delay_slot = NOT_DELAYED;
254 }
X(bne_samepage)255 X(bne_samepage)
256 {
257 	MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
258 	int x = rs != rt;
259 	cpu->delay_slot = TO_BE_DELAYED;
260 	ic[1].f(cpu, ic+1);
261 	cpu->n_translated_instrs ++;
262 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
263 		if (x)
264 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
265 			    ic->arg[2];
266 		else
267 			cpu->cd.mips.next_ic ++;
268 	}
269 	cpu->delay_slot = NOT_DELAYED;
270 }
X(bne_samepage_addiu)271 X(bne_samepage_addiu)
272 {
273 	MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
274 	cpu->n_translated_instrs ++;
275 	reg(ic[1].arg[1]) = (int32_t)
276 	    ((int32_t)reg(ic[1].arg[0]) + (int32_t)ic[1].arg[2]);
277 	if (rs != rt)
278 		cpu->cd.mips.next_ic = (struct mips_instr_call *) ic->arg[2];
279 	else
280 		cpu->cd.mips.next_ic ++;
281 }
X(bne_samepage_nop)282 X(bne_samepage_nop)
283 {
284 	MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
285 	cpu->n_translated_instrs ++;
286 	if (rs != rt)
287 		cpu->cd.mips.next_ic = (struct mips_instr_call *) ic->arg[2];
288 	else
289 		cpu->cd.mips.next_ic ++;
290 }
X(b)291 X(b)
292 {
293 	MODE_int_t old_pc = cpu->pc;
294 	cpu->delay_slot = TO_BE_DELAYED;
295 	ic[1].f(cpu, ic+1);
296 	cpu->n_translated_instrs ++;
297 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
298 		/*  Note: Must be non-delayed when jumping to the new pc:  */
299 		cpu->delay_slot = NOT_DELAYED;
300 		old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
301 		    MIPS_INSTR_ALIGNMENT_SHIFT);
302 		cpu->pc = old_pc + (int32_t)ic->arg[2];
303 		quick_pc_to_pointers(cpu);
304 	} else
305 		cpu->delay_slot = NOT_DELAYED;
306 }
X(b_samepage)307 X(b_samepage)
308 {
309 	cpu->delay_slot = TO_BE_DELAYED;
310 	ic[1].f(cpu, ic+1);
311 	cpu->n_translated_instrs ++;
312 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)))
313 		cpu->cd.mips.next_ic = (struct mips_instr_call *) ic->arg[2];
314 	cpu->delay_slot = NOT_DELAYED;
315 }
316 
317 
318 /*
319  *  beql:  Branch if equal likely
320  *  bnel:  Branch if not equal likely
321  *
322  *  arg[0] = pointer to rs
323  *  arg[1] = pointer to rt
324  *  arg[2] = (int32_t) relative offset from the next instruction
325  */
X(beql)326 X(beql)
327 {
328 	MODE_int_t old_pc = cpu->pc;
329 	MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
330 	int x = rs == rt;
331 	cpu->delay_slot = TO_BE_DELAYED;
332 	if (x)
333 		ic[1].f(cpu, ic+1);
334 	cpu->n_translated_instrs ++;
335 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
336 		/*  Note: Must be non-delayed when jumping to the new pc:  */
337 		cpu->delay_slot = NOT_DELAYED;
338 		if (x) {
339 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
340 			    MIPS_INSTR_ALIGNMENT_SHIFT);
341 			cpu->pc = old_pc + (int32_t)ic->arg[2];
342 			quick_pc_to_pointers(cpu);
343 		} else
344 			cpu->cd.mips.next_ic ++;
345 	} else
346 		cpu->delay_slot = NOT_DELAYED;
347 }
X(beql_samepage)348 X(beql_samepage)
349 {
350 	MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
351 	int x = rs == rt;
352 	cpu->delay_slot = TO_BE_DELAYED;
353 	if (x)
354 		ic[1].f(cpu, ic+1);
355 	cpu->n_translated_instrs ++;
356 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
357 		if (x)
358 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
359 			    ic->arg[2];
360 		else
361 			cpu->cd.mips.next_ic ++;
362 	}
363 	cpu->delay_slot = NOT_DELAYED;
364 }
X(bnel)365 X(bnel)
366 {
367 	MODE_int_t old_pc = cpu->pc;
368 	MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
369 	int x = rs != rt;
370 	cpu->delay_slot = TO_BE_DELAYED;
371 	if (x)
372 		ic[1].f(cpu, ic+1);
373 	cpu->n_translated_instrs ++;
374 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
375 		/*  Note: Must be non-delayed when jumping to the new pc:  */
376 		cpu->delay_slot = NOT_DELAYED;
377 		if (x) {
378 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
379 			    MIPS_INSTR_ALIGNMENT_SHIFT);
380 			cpu->pc = old_pc + (int32_t)ic->arg[2];
381 			quick_pc_to_pointers(cpu);
382 		} else
383 			cpu->cd.mips.next_ic ++;
384 	} else
385 		cpu->delay_slot = NOT_DELAYED;
386 }
X(bnel_samepage)387 X(bnel_samepage)
388 {
389 	MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
390 	int x = rs != rt;
391 	cpu->delay_slot = TO_BE_DELAYED;
392 	if (x)
393 		ic[1].f(cpu, ic+1);
394 	cpu->n_translated_instrs ++;
395 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
396 		if (x)
397 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
398 			    ic->arg[2];
399 		else
400 			cpu->cd.mips.next_ic ++;
401 	}
402 	cpu->delay_slot = NOT_DELAYED;
403 }
404 
405 
406 /*
407  *  blez:   Branch if less than or equal
408  *  blezl:  Branch if less than or equal likely
409  *
410  *  arg[0] = pointer to rs
411  *  arg[2] = (int32_t) relative offset from the next instruction
412  */
X(blez)413 X(blez)
414 {
415 	MODE_int_t old_pc = cpu->pc;
416 	MODE_int_t rs = reg(ic->arg[0]);
417 	int x = (rs <= 0);
418 	cpu->delay_slot = TO_BE_DELAYED;
419 	ic[1].f(cpu, ic+1);
420 	cpu->n_translated_instrs ++;
421 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
422 		/*  Note: Must be non-delayed when jumping to the new pc:  */
423 		cpu->delay_slot = NOT_DELAYED;
424 		if (x) {
425 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
426 			    MIPS_INSTR_ALIGNMENT_SHIFT);
427 			cpu->pc = old_pc + (int32_t)ic->arg[2];
428 			quick_pc_to_pointers(cpu);
429 		} else
430 			cpu->cd.mips.next_ic ++;
431 	} else
432 		cpu->delay_slot = NOT_DELAYED;
433 }
X(blez_samepage)434 X(blez_samepage)
435 {
436 	MODE_int_t rs = reg(ic->arg[0]);
437 	int x = (rs <= 0);
438 	cpu->delay_slot = TO_BE_DELAYED;
439 	ic[1].f(cpu, ic+1);
440 	cpu->n_translated_instrs ++;
441 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
442 		if (x)
443 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
444 			    ic->arg[2];
445 		else
446 			cpu->cd.mips.next_ic ++;
447 	}
448 	cpu->delay_slot = NOT_DELAYED;
449 }
X(blezl)450 X(blezl)
451 {
452 	MODE_int_t old_pc = cpu->pc;
453 	MODE_int_t rs = reg(ic->arg[0]);
454 	int x = (rs <= 0);
455 	cpu->delay_slot = TO_BE_DELAYED;
456 	if (x)
457 		ic[1].f(cpu, ic+1);
458 	cpu->n_translated_instrs ++;
459 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
460 		/*  Note: Must be non-delayed when jumping to the new pc:  */
461 		cpu->delay_slot = NOT_DELAYED;
462 		if (x) {
463 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
464 			    MIPS_INSTR_ALIGNMENT_SHIFT);
465 			cpu->pc = old_pc + (int32_t)ic->arg[2];
466 			quick_pc_to_pointers(cpu);
467 		} else
468 			cpu->cd.mips.next_ic ++;
469 	} else
470 		cpu->delay_slot = NOT_DELAYED;
471 }
X(blezl_samepage)472 X(blezl_samepage)
473 {
474 	MODE_int_t rs = reg(ic->arg[0]);
475 	int x = (rs <= 0);
476 	cpu->delay_slot = TO_BE_DELAYED;
477 	if (x)
478 		ic[1].f(cpu, ic+1);
479 	cpu->n_translated_instrs ++;
480 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
481 		if (x)
482 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
483 			    ic->arg[2];
484 		else
485 			cpu->cd.mips.next_ic ++;
486 	}
487 	cpu->delay_slot = NOT_DELAYED;
488 }
489 
490 
491 /*
492  *  bltz:   Branch if less than
493  *  bltzl:  Branch if less than likely
494  *
495  *  arg[0] = pointer to rs
496  *  arg[2] = (int32_t) relative offset from the next instruction
497  */
X(bltz)498 X(bltz)
499 {
500 	MODE_int_t old_pc = cpu->pc;
501 	MODE_int_t rs = reg(ic->arg[0]);
502 	int x = (rs < 0);
503 	cpu->delay_slot = TO_BE_DELAYED;
504 	ic[1].f(cpu, ic+1);
505 	cpu->n_translated_instrs ++;
506 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
507 		/*  Note: Must be non-delayed when jumping to the new pc:  */
508 		cpu->delay_slot = NOT_DELAYED;
509 		if (x) {
510 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
511 			    MIPS_INSTR_ALIGNMENT_SHIFT);
512 			cpu->pc = old_pc + (int32_t)ic->arg[2];
513 			quick_pc_to_pointers(cpu);
514 		} else
515 			cpu->cd.mips.next_ic ++;
516 	} else
517 		cpu->delay_slot = NOT_DELAYED;
518 }
X(bltz_samepage)519 X(bltz_samepage)
520 {
521 	MODE_int_t rs = reg(ic->arg[0]);
522 	int x = (rs < 0);
523 	cpu->delay_slot = TO_BE_DELAYED;
524 	ic[1].f(cpu, ic+1);
525 	cpu->n_translated_instrs ++;
526 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
527 		if (x)
528 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
529 			    ic->arg[2];
530 		else
531 			cpu->cd.mips.next_ic ++;
532 	}
533 	cpu->delay_slot = NOT_DELAYED;
534 }
X(bltzl)535 X(bltzl)
536 {
537 	MODE_int_t old_pc = cpu->pc;
538 	MODE_int_t rs = reg(ic->arg[0]);
539 	int x = (rs < 0);
540 	cpu->delay_slot = TO_BE_DELAYED;
541 	if (x)
542 		ic[1].f(cpu, ic+1);
543 	cpu->n_translated_instrs ++;
544 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
545 		/*  Note: Must be non-delayed when jumping to the new pc:  */
546 		cpu->delay_slot = NOT_DELAYED;
547 		if (x) {
548 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
549 			    MIPS_INSTR_ALIGNMENT_SHIFT);
550 			cpu->pc = old_pc + (int32_t)ic->arg[2];
551 			quick_pc_to_pointers(cpu);
552 		} else
553 			cpu->cd.mips.next_ic ++;
554 	} else
555 		cpu->delay_slot = NOT_DELAYED;
556 }
X(bltzl_samepage)557 X(bltzl_samepage)
558 {
559 	MODE_int_t rs = reg(ic->arg[0]);
560 	int x = (rs < 0);
561 	cpu->delay_slot = TO_BE_DELAYED;
562 	if (x)
563 		ic[1].f(cpu, ic+1);
564 	cpu->n_translated_instrs ++;
565 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
566 		if (x)
567 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
568 			    ic->arg[2];
569 		else
570 			cpu->cd.mips.next_ic ++;
571 	}
572 	cpu->delay_slot = NOT_DELAYED;
573 }
574 
575 
576 /*
577  *  bgez:   Branch if greater than or equal
578  *  bgezl:  Branch if greater than or equal likely
579  *
580  *  arg[0] = pointer to rs
581  *  arg[2] = (int32_t) relative offset from the next instruction
582  */
X(bgez)583 X(bgez)
584 {
585 	MODE_int_t old_pc = cpu->pc;
586 	MODE_int_t rs = reg(ic->arg[0]);
587 	int x = (rs >= 0);
588 	cpu->delay_slot = TO_BE_DELAYED;
589 	ic[1].f(cpu, ic+1);
590 	cpu->n_translated_instrs ++;
591 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
592 		/*  Note: Must be non-delayed when jumping to the new pc:  */
593 		cpu->delay_slot = NOT_DELAYED;
594 		if (x) {
595 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
596 			    MIPS_INSTR_ALIGNMENT_SHIFT);
597 			cpu->pc = old_pc + (int32_t)ic->arg[2];
598 			quick_pc_to_pointers(cpu);
599 		} else
600 			cpu->cd.mips.next_ic ++;
601 	} else
602 		cpu->delay_slot = NOT_DELAYED;
603 }
X(bgez_samepage)604 X(bgez_samepage)
605 {
606 	MODE_int_t rs = reg(ic->arg[0]);
607 	int x = (rs >= 0);
608 	cpu->delay_slot = TO_BE_DELAYED;
609 	ic[1].f(cpu, ic+1);
610 	cpu->n_translated_instrs ++;
611 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
612 		if (x)
613 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
614 			    ic->arg[2];
615 		else
616 			cpu->cd.mips.next_ic ++;
617 	}
618 	cpu->delay_slot = NOT_DELAYED;
619 }
X(bgezl)620 X(bgezl)
621 {
622 	MODE_int_t old_pc = cpu->pc;
623 	MODE_int_t rs = reg(ic->arg[0]);
624 	int x = (rs >= 0);
625 	cpu->delay_slot = TO_BE_DELAYED;
626 	if (x)
627 		ic[1].f(cpu, ic+1);
628 	cpu->n_translated_instrs ++;
629 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
630 		/*  Note: Must be non-delayed when jumping to the new pc:  */
631 		cpu->delay_slot = NOT_DELAYED;
632 		if (x) {
633 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
634 			    MIPS_INSTR_ALIGNMENT_SHIFT);
635 			cpu->pc = old_pc + (int32_t)ic->arg[2];
636 			quick_pc_to_pointers(cpu);
637 		} else
638 			cpu->cd.mips.next_ic ++;
639 	} else
640 		cpu->delay_slot = NOT_DELAYED;
641 }
X(bgezl_samepage)642 X(bgezl_samepage)
643 {
644 	MODE_int_t rs = reg(ic->arg[0]);
645 	int x = (rs >= 0);
646 	cpu->delay_slot = TO_BE_DELAYED;
647 	if (x)
648 		ic[1].f(cpu, ic+1);
649 	cpu->n_translated_instrs ++;
650 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
651 		if (x)
652 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
653 			    ic->arg[2];
654 		else
655 			cpu->cd.mips.next_ic ++;
656 	}
657 	cpu->delay_slot = NOT_DELAYED;
658 }
659 
660 
661 /*
662  *  bgezal:   Branch if greater than or equal (and link)
663  *  bgezall:  Branch if greater than or equal (and link) likely
664  *
665  *  arg[0] = pointer to rs
666  *  arg[2] = (int32_t) relative offset from the next instruction
667  */
X(bgezal)668 X(bgezal)
669 {
670 	MODE_int_t old_pc = cpu->pc;
671 	MODE_int_t rs = reg(ic->arg[0]);
672 	int x = (rs >= 0), low_pc;
673 
674 	cpu->delay_slot = TO_BE_DELAYED;
675 	low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
676 	    / sizeof(struct mips_instr_call);
677 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
678 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
679 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
680 	cpu->cd.mips.gpr[MIPS_GPR_RA] = cpu->pc + 8;
681 
682 	ic[1].f(cpu, ic+1);
683 	cpu->n_translated_instrs ++;
684 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
685 		/*  Note: Must be non-delayed when jumping to the new pc:  */
686 		cpu->delay_slot = NOT_DELAYED;
687 		if (x) {
688 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
689 			    MIPS_INSTR_ALIGNMENT_SHIFT);
690 			cpu->pc = old_pc + (int32_t)ic->arg[2];
691 			quick_pc_to_pointers(cpu);
692 		} else
693 			cpu->cd.mips.next_ic ++;
694 	} else
695 		cpu->delay_slot = NOT_DELAYED;
696 }
X(bgezal_samepage)697 X(bgezal_samepage)
698 {
699 	MODE_int_t rs = reg(ic->arg[0]);
700 	int x = (rs >= 0), low_pc;
701 
702 	cpu->delay_slot = TO_BE_DELAYED;
703 	low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
704 	    / sizeof(struct mips_instr_call);
705 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
706 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
707 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
708 	cpu->cd.mips.gpr[MIPS_GPR_RA] = cpu->pc + 8;
709 
710 	ic[1].f(cpu, ic+1);
711 	cpu->n_translated_instrs ++;
712 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
713 		if (x)
714 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
715 			    ic->arg[2];
716 		else
717 			cpu->cd.mips.next_ic ++;
718 	}
719 	cpu->delay_slot = NOT_DELAYED;
720 }
X(bgezall)721 X(bgezall)
722 {
723 	MODE_int_t old_pc = cpu->pc;
724 	MODE_int_t rs = reg(ic->arg[0]);
725 	int x = (rs >= 0), low_pc;
726 
727 	cpu->delay_slot = TO_BE_DELAYED;
728 	low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
729 	    / sizeof(struct mips_instr_call);
730 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
731 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
732 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
733 	cpu->cd.mips.gpr[MIPS_GPR_RA] = cpu->pc + 8;
734 
735 	if (x)
736 		ic[1].f(cpu, ic+1);
737 	cpu->n_translated_instrs ++;
738 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
739 		/*  Note: Must be non-delayed when jumping to the new pc:  */
740 		cpu->delay_slot = NOT_DELAYED;
741 		if (x) {
742 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
743 			    MIPS_INSTR_ALIGNMENT_SHIFT);
744 			cpu->pc = old_pc + (int32_t)ic->arg[2];
745 			quick_pc_to_pointers(cpu);
746 		} else
747 			cpu->cd.mips.next_ic ++;
748 	} else
749 		cpu->delay_slot = NOT_DELAYED;
750 }
X(bgezall_samepage)751 X(bgezall_samepage)
752 {
753 	MODE_int_t rs = reg(ic->arg[0]);
754 	int x = (rs >= 0), low_pc;
755 
756 	cpu->delay_slot = TO_BE_DELAYED;
757 	low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
758 	    / sizeof(struct mips_instr_call);
759 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
760 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
761 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
762 	cpu->cd.mips.gpr[MIPS_GPR_RA] = cpu->pc + 8;
763 
764 	if (x)
765 		ic[1].f(cpu, ic+1);
766 	cpu->n_translated_instrs ++;
767 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
768 		if (x)
769 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
770 			    ic->arg[2];
771 		else
772 			cpu->cd.mips.next_ic ++;
773 	}
774 	cpu->delay_slot = NOT_DELAYED;
775 }
776 
777 
778 /*
779  *  bltzal:   Branch if less than zero (and link)
780  *  bltzall:  Branch if less than zero (and link) likely
781  *
782  *  arg[0] = pointer to rs
783  *  arg[2] = (int32_t) relative offset from the next instruction
784  */
X(bltzal)785 X(bltzal)
786 {
787 	MODE_int_t old_pc = cpu->pc;
788 	MODE_int_t rs = reg(ic->arg[0]);
789 	int x = (rs < 0), low_pc;
790 
791 	cpu->delay_slot = TO_BE_DELAYED;
792 	low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
793 	    / sizeof(struct mips_instr_call);
794 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
795 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
796 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
797 	cpu->cd.mips.gpr[MIPS_GPR_RA] = cpu->pc + 8;
798 
799 	ic[1].f(cpu, ic+1);
800 	cpu->n_translated_instrs ++;
801 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
802 		/*  Note: Must be non-delayed when jumping to the new pc:  */
803 		cpu->delay_slot = NOT_DELAYED;
804 		if (x) {
805 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
806 			    MIPS_INSTR_ALIGNMENT_SHIFT);
807 			cpu->pc = old_pc + (int32_t)ic->arg[2];
808 			quick_pc_to_pointers(cpu);
809 		} else
810 			cpu->cd.mips.next_ic ++;
811 	} else
812 		cpu->delay_slot = NOT_DELAYED;
813 }
X(bltzal_samepage)814 X(bltzal_samepage)
815 {
816 	MODE_int_t rs = reg(ic->arg[0]);
817 	int x = (rs < 0), low_pc;
818 
819 	cpu->delay_slot = TO_BE_DELAYED;
820 	low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
821 	    / sizeof(struct mips_instr_call);
822 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
823 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
824 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
825 	cpu->cd.mips.gpr[MIPS_GPR_RA] = cpu->pc + 8;
826 
827 	ic[1].f(cpu, ic+1);
828 	cpu->n_translated_instrs ++;
829 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
830 		if (x)
831 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
832 			    ic->arg[2];
833 		else
834 			cpu->cd.mips.next_ic ++;
835 	}
836 	cpu->delay_slot = NOT_DELAYED;
837 }
X(bltzall)838 X(bltzall)
839 {
840 	MODE_int_t old_pc = cpu->pc;
841 	MODE_int_t rs = reg(ic->arg[0]);
842 	int x = (rs < 0), low_pc;
843 
844 	cpu->delay_slot = TO_BE_DELAYED;
845 	low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
846 	    / sizeof(struct mips_instr_call);
847 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
848 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
849 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
850 	cpu->cd.mips.gpr[MIPS_GPR_RA] = cpu->pc + 8;
851 
852 	if (x)
853 		ic[1].f(cpu, ic+1);
854 	cpu->n_translated_instrs ++;
855 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
856 		/*  Note: Must be non-delayed when jumping to the new pc:  */
857 		cpu->delay_slot = NOT_DELAYED;
858 		if (x) {
859 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
860 			    MIPS_INSTR_ALIGNMENT_SHIFT);
861 			cpu->pc = old_pc + (int32_t)ic->arg[2];
862 			quick_pc_to_pointers(cpu);
863 		} else
864 			cpu->cd.mips.next_ic ++;
865 	} else
866 		cpu->delay_slot = NOT_DELAYED;
867 }
X(bltzall_samepage)868 X(bltzall_samepage)
869 {
870 	MODE_int_t rs = reg(ic->arg[0]);
871 	int x = (rs < 0), low_pc;
872 
873 	cpu->delay_slot = TO_BE_DELAYED;
874 	low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
875 	    / sizeof(struct mips_instr_call);
876 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
877 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
878 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
879 	cpu->cd.mips.gpr[MIPS_GPR_RA] = cpu->pc + 8;
880 
881 	if (x)
882 		ic[1].f(cpu, ic+1);
883 	cpu->n_translated_instrs ++;
884 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
885 		if (x)
886 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
887 			    ic->arg[2];
888 		else
889 			cpu->cd.mips.next_ic ++;
890 	}
891 	cpu->delay_slot = NOT_DELAYED;
892 }
893 
894 
895 /*
896  *  bgtz:   Branch if greater than zero
897  *  bgtzl:  Branch if greater than zero likely
898  *
899  *  arg[0] = pointer to rs
900  *  arg[2] = (int32_t) relative offset from the next instruction
901  */
X(bgtz)902 X(bgtz)
903 {
904 	MODE_int_t old_pc = cpu->pc;
905 	MODE_int_t rs = reg(ic->arg[0]);
906 	int x = (rs > 0);
907 	cpu->delay_slot = TO_BE_DELAYED;
908 	ic[1].f(cpu, ic+1);
909 	cpu->n_translated_instrs ++;
910 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
911 		/*  Note: Must be non-delayed when jumping to the new pc:  */
912 		cpu->delay_slot = NOT_DELAYED;
913 		if (x) {
914 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
915 			    MIPS_INSTR_ALIGNMENT_SHIFT);
916 			cpu->pc = old_pc + (int32_t)ic->arg[2];
917 			quick_pc_to_pointers(cpu);
918 		} else
919 			cpu->cd.mips.next_ic ++;
920 	} else
921 		cpu->delay_slot = NOT_DELAYED;
922 }
X(bgtz_samepage)923 X(bgtz_samepage)
924 {
925 	MODE_int_t rs = reg(ic->arg[0]);
926 	int x = (rs > 0);
927 	cpu->delay_slot = TO_BE_DELAYED;
928 	ic[1].f(cpu, ic+1);
929 	cpu->n_translated_instrs ++;
930 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
931 		if (x)
932 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
933 			    ic->arg[2];
934 		else
935 			cpu->cd.mips.next_ic ++;
936 	}
937 	cpu->delay_slot = NOT_DELAYED;
938 }
X(bgtzl)939 X(bgtzl)
940 {
941 	MODE_int_t old_pc = cpu->pc;
942 	MODE_int_t rs = reg(ic->arg[0]);
943 	int x = (rs > 0);
944 	cpu->delay_slot = TO_BE_DELAYED;
945 	if (x)
946 		ic[1].f(cpu, ic+1);
947 	cpu->n_translated_instrs ++;
948 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
949 		/*  Note: Must be non-delayed when jumping to the new pc:  */
950 		cpu->delay_slot = NOT_DELAYED;
951 		if (x) {
952 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
953 			    MIPS_INSTR_ALIGNMENT_SHIFT);
954 			cpu->pc = old_pc + (int32_t)ic->arg[2];
955 			quick_pc_to_pointers(cpu);
956 		} else
957 			cpu->cd.mips.next_ic ++;
958 	} else
959 		cpu->delay_slot = NOT_DELAYED;
960 }
X(bgtzl_samepage)961 X(bgtzl_samepage)
962 {
963 	MODE_int_t rs = reg(ic->arg[0]);
964 	int x = (rs > 0);
965 	cpu->delay_slot = TO_BE_DELAYED;
966 	if (x)
967 		ic[1].f(cpu, ic+1);
968 	cpu->n_translated_instrs ++;
969 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
970 		if (x)
971 			cpu->cd.mips.next_ic = (struct mips_instr_call *)
972 			    ic->arg[2];
973 		else
974 			cpu->cd.mips.next_ic ++;
975 	}
976 	cpu->delay_slot = NOT_DELAYED;
977 }
978 
979 
980 /*
981  *  jr, jalr: Jump to a register [and link].
982  *
983  *  arg[0] = ptr to rs
984  *  arg[1] = ptr to rd (for jalr)
985  *  arg[2] = (int32_t) relative offset of the next instruction
986  */
X(jr)987 X(jr)
988 {
989 	MODE_int_t rs = reg(ic->arg[0]);
990 	cpu->delay_slot = TO_BE_DELAYED;
991 	ic[1].f(cpu, ic+1);
992 	cpu->n_translated_instrs ++;
993 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
994 		cpu->pc = rs;
995 		/*  Note: Must be non-delayed when jumping to the new pc:  */
996 		cpu->delay_slot = NOT_DELAYED;
997 		quick_pc_to_pointers(cpu);
998 	} else
999 		cpu->delay_slot = NOT_DELAYED;
1000 }
X(jr_ra)1001 X(jr_ra)
1002 {
1003 	MODE_int_t rs = cpu->cd.mips.gpr[MIPS_GPR_RA];
1004 	cpu->delay_slot = TO_BE_DELAYED;
1005 	ic[1].f(cpu, ic+1);
1006 	cpu->n_translated_instrs ++;
1007 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
1008 		cpu->pc = rs;
1009 		/*  Note: Must be non-delayed when jumping to the new pc:  */
1010 		cpu->delay_slot = NOT_DELAYED;
1011 		quick_pc_to_pointers(cpu);
1012 	} else
1013 		cpu->delay_slot = NOT_DELAYED;
1014 }
X(jr_ra_addiu)1015 X(jr_ra_addiu)
1016 {
1017 	/*  jr ra, followed by an addiu  */
1018 	MODE_int_t rs = cpu->cd.mips.gpr[MIPS_GPR_RA];
1019 	reg(ic[1].arg[1]) = (int32_t)
1020 	    ((int32_t)reg(ic[1].arg[0]) + (int32_t)ic[1].arg[2]);
1021 	cpu->pc = rs;
1022 	quick_pc_to_pointers(cpu);
1023 	cpu->n_translated_instrs ++;
1024 }
X(jr_ra_trace)1025 X(jr_ra_trace)
1026 {
1027 	MODE_int_t rs = cpu->cd.mips.gpr[MIPS_GPR_RA];
1028 	cpu->delay_slot = TO_BE_DELAYED;
1029 	ic[1].f(cpu, ic+1);
1030 	cpu->n_translated_instrs ++;
1031 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
1032 		cpu->pc = rs;
1033 		cpu_functioncall_trace_return(cpu);
1034 		/*  Note: Must be non-delayed when jumping to the new pc:  */
1035 		cpu->delay_slot = NOT_DELAYED;
1036 		quick_pc_to_pointers(cpu);
1037 	} else
1038 		cpu->delay_slot = NOT_DELAYED;
1039 }
X(jalr)1040 X(jalr)
1041 {
1042 	MODE_int_t rs = reg(ic->arg[0]), rd;
1043 	cpu->delay_slot = TO_BE_DELAYED;
1044 	rd = cpu->pc & ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
1045 	    MIPS_INSTR_ALIGNMENT_SHIFT);
1046 	rd += (int32_t)ic->arg[2];
1047 	reg(ic->arg[1]) = rd;
1048 	ic[1].f(cpu, ic+1);
1049 	cpu->n_translated_instrs ++;
1050 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
1051 		cpu->pc = rs;
1052 		/*  Note: Must be non-delayed when jumping to the new pc:  */
1053 		cpu->delay_slot = NOT_DELAYED;
1054 		quick_pc_to_pointers(cpu);
1055 	} else
1056 		cpu->delay_slot = NOT_DELAYED;
1057 }
X(jalr_trace)1058 X(jalr_trace)
1059 {
1060 	MODE_int_t rs = reg(ic->arg[0]), rd;
1061 	cpu->delay_slot = TO_BE_DELAYED;
1062 	rd = cpu->pc & ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
1063 	    MIPS_INSTR_ALIGNMENT_SHIFT);
1064 	rd += (int32_t)ic->arg[2];
1065 	reg(ic->arg[1]) = rd;
1066 	ic[1].f(cpu, ic+1);
1067 	cpu->n_translated_instrs ++;
1068 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
1069 		cpu->pc = rs;
1070 		cpu_functioncall_trace(cpu, cpu->pc);
1071 		/*  Note: Must be non-delayed when jumping to the new pc:  */
1072 		cpu->delay_slot = NOT_DELAYED;
1073 		quick_pc_to_pointers(cpu);
1074 	} else
1075 		cpu->delay_slot = NOT_DELAYED;
1076 }
1077 
1078 
1079 /*
1080  *  j, jal:  Jump [and link].
1081  *
1082  *  arg[0] = lowest 28 bits of new pc.
1083  *  arg[1] = offset from start of page to the jal instruction + 8
1084  */
X(j)1085 X(j)
1086 {
1087 	MODE_int_t old_pc = cpu->pc;
1088 	cpu->delay_slot = TO_BE_DELAYED;
1089 	ic[1].f(cpu, ic+1);
1090 	cpu->n_translated_instrs ++;
1091 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
1092 		/*  Note: Must be non-delayed when jumping to the new pc:  */
1093 		cpu->delay_slot = NOT_DELAYED;
1094 		old_pc &= ~0x03ffffff;
1095 		cpu->pc = old_pc | (uint32_t)ic->arg[0];
1096 		quick_pc_to_pointers(cpu);
1097 	} else
1098 		cpu->delay_slot = NOT_DELAYED;
1099 }
X(jal)1100 X(jal)
1101 {
1102 	MODE_int_t old_pc = cpu->pc;
1103 	cpu->delay_slot = TO_BE_DELAYED;
1104 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<<MIPS_INSTR_ALIGNMENT_SHIFT);
1105 	cpu->cd.mips.gpr[31] = (MODE_int_t)cpu->pc + (int32_t)ic->arg[1];
1106 	ic[1].f(cpu, ic+1);
1107 	cpu->n_translated_instrs ++;
1108 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
1109 		/*  Note: Must be non-delayed when jumping to the new pc:  */
1110 		cpu->delay_slot = NOT_DELAYED;
1111 		old_pc &= ~0x03ffffff;
1112 		cpu->pc = old_pc | (int32_t)ic->arg[0];
1113 		quick_pc_to_pointers(cpu);
1114 	} else
1115 		cpu->delay_slot = NOT_DELAYED;
1116 }
X(jal_trace)1117 X(jal_trace)
1118 {
1119 	MODE_int_t old_pc = cpu->pc;
1120 	cpu->delay_slot = TO_BE_DELAYED;
1121 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<<MIPS_INSTR_ALIGNMENT_SHIFT);
1122 	cpu->cd.mips.gpr[31] = (MODE_int_t)cpu->pc + (int32_t)ic->arg[1];
1123 	ic[1].f(cpu, ic+1);
1124 	cpu->n_translated_instrs ++;
1125 	if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
1126 		/*  Note: Must be non-delayed when jumping to the new pc:  */
1127 		cpu->delay_slot = NOT_DELAYED;
1128 		old_pc &= ~0x03ffffff;
1129 		cpu->pc = old_pc | (int32_t)ic->arg[0];
1130 		cpu_functioncall_trace(cpu, cpu->pc);
1131 		quick_pc_to_pointers(cpu);
1132 	} else
1133 		cpu->delay_slot = NOT_DELAYED;
1134 }
1135 
1136 
1137 /*
1138  *  cache:  Cache operation.
1139  */
X(cache)1140 X(cache)
1141 {
1142 	/*  TODO: Implement cache operations.  */
1143 
1144 	/*  Make sure the rmw bit is cleared:  */
1145 	cpu->cd.mips.rmw = 0;
1146 }
1147 
1148 
1149 /*
1150  *  tgei:  Trap if Greater-or-Equal Immediate.
1151  *  tgeiu:  Trap if Greater-or-Equal Immediate Unsigned.
1152  *  tlti:  Trap if Less-Than Immediate.
1153  *  tltiu:  Trap if Less-Than Immediate Unsigned.
1154  *  teqi:  Trap if Equal Immediate.
1155  *  tnei:  Trap if Not-Equal Immediate.
1156  *
1157  *  arg[0] = pointer to rs
1158  *  arg[2] = immediate value, sign-extended to native word size
1159  */
X(tgei)1160 X(tgei)
1161 {
1162 	MODE_int_t rs = reg(ic->arg[0]);
1163 	MODE_int_t imm = ic->arg[2];
1164 
1165 	if (rs >= imm) {
1166 		/*  Synchronize the PC and cause an exception:  */
1167 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1168 		    / sizeof(struct mips_instr_call);
1169 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1170 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1171 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1172 		mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1173 	}
1174 }
X(tgeiu)1175 X(tgeiu)
1176 {
1177 	MODE_uint_t rs = reg(ic->arg[0]);
1178 	MODE_uint_t imm = ic->arg[2];
1179 
1180 	if (rs >= imm) {
1181 		/*  Synchronize the PC and cause an exception:  */
1182 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1183 		    / sizeof(struct mips_instr_call);
1184 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1185 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1186 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1187 		mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1188 	}
1189 }
X(tlti)1190 X(tlti)
1191 {
1192 	MODE_int_t rs = reg(ic->arg[0]);
1193 	MODE_int_t imm = ic->arg[2];
1194 
1195 	if (rs < imm) {
1196 		/*  Synchronize the PC and cause an exception:  */
1197 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1198 		    / sizeof(struct mips_instr_call);
1199 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1200 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1201 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1202 		mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1203 	}
1204 }
X(tltiu)1205 X(tltiu)
1206 {
1207 	MODE_uint_t rs = reg(ic->arg[0]);
1208 	MODE_uint_t imm = ic->arg[2];
1209 
1210 	if (rs < imm) {
1211 		/*  Synchronize the PC and cause an exception:  */
1212 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1213 		    / sizeof(struct mips_instr_call);
1214 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1215 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1216 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1217 		mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1218 	}
1219 }
X(teqi)1220 X(teqi)
1221 {
1222 	MODE_uint_t rs = reg(ic->arg[0]);
1223 	MODE_uint_t imm = ic->arg[2];
1224 
1225 	if (rs == imm) {
1226 		/*  Synchronize the PC and cause an exception:  */
1227 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1228 		    / sizeof(struct mips_instr_call);
1229 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1230 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1231 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1232 		mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1233 	}
1234 }
X(tnei)1235 X(tnei)
1236 {
1237 	MODE_uint_t rs = reg(ic->arg[0]);
1238 	MODE_uint_t imm = ic->arg[2];
1239 
1240 	if (rs != imm) {
1241 		/*  Synchronize the PC and cause an exception:  */
1242 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1243 		    / sizeof(struct mips_instr_call);
1244 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1245 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1246 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1247 		mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1248 	}
1249 }
1250 
1251 
1252 /*
1253  *  ins: Insert bitfield.
1254  *
1255  *  arg[0] = pointer to rt
1256  *  arg[1] = pointer to rs
1257  *  arg[2] = (msb << 5) + lsb
1258  */
X(ins)1259 X(ins)
1260 {
1261 	int msb = ic->arg[2] >> 5, pos = ic->arg[2] & 0x1f;
1262 	int size = msb + 1 - pos;
1263 	uint32_t rt = reg(ic->arg[0]);
1264 	uint32_t rs = reg(ic->arg[1]);
1265 	uint32_t mask = (uint32_t)(-1) << pos;
1266 
1267 	mask <<= (32 - pos - size);
1268 	mask >>= (32 - pos - size);
1269 
1270 	reg(ic->arg[0]) = (int32_t) ((rt & ~mask) | ((rs << pos) & mask));
1271 }
1272 
1273 
1274 /*
1275  *  ext:  Extract bitfield.
1276  *
1277  *  arg[0] = pointer to rt
1278  *  arg[1] = pointer to rs
1279  *  arg[2] = (msbd << 5) + lsb
1280  */
X(ext)1281 X(ext)
1282 {
1283 	int msbd = ic->arg[2] >> 5, lsb = ic->arg[2] & 0x1f;
1284 	int size = msbd + 1;
1285 	uint32_t rs = reg(ic->arg[1]);
1286 	uint32_t x = (rs << (32-lsb-size)) >> (32-lsb-size);
1287 	reg(ic->arg[0]) = (int32_t) (x >> lsb);
1288 }
1289 
1290 
1291 /*
1292  *  dext:  Extract bitfield (64-bit).
1293  *
1294  *  arg[0] = pointer to rt
1295  *  arg[1] = pointer to rs
1296  *  arg[2] = (msbd << 6) + lsb
1297  */
X(dext)1298 X(dext)
1299 {
1300 	int msbd = ic->arg[2] >> 6, lsb = ic->arg[2] & 0x3f;
1301 	int size = msbd + 1;
1302 	uint64_t rs = reg(ic->arg[1]);
1303 	uint64_t x = (rs << (uint64_t)(64-lsb-size)) >> (uint64_t)(64-lsb-size);
1304 	reg(ic->arg[0]) = x >> lsb;
1305 }
1306 
1307 
1308 /*
1309  *  dsbh:  Doubleword swap bytes within half-word
1310  *  dshd:  Doubleword swap half-words within double-word
1311  *  wsbh:  Word swap bytes within half-word
1312  *  seb:   Sign-extend byte
1313  *  seh:   Sign-extend half-word
1314  *
1315  *  arg[0] = pointer to rt
1316  *  arg[1] = pointer to rd
1317  */
X(dsbh)1318 X(dsbh)
1319 {
1320 	uint64_t x = reg(ic->arg[0]);
1321 	x = ((x & 0x00ff00ff00ff00ffULL) << 8)
1322 	  | ((x & 0xff00ff00ff00ff00ULL) >> 8);
1323 	reg(ic->arg[1]) = x;
1324 }
X(dshd)1325 X(dshd)
1326 {
1327 	uint64_t x = reg(ic->arg[0]);
1328 	x = ((x & 0x000000000000ffffULL) << 48)
1329 	  | ((x & 0x00000000ffff0000ULL) << 16)
1330 	  | ((x & 0x0000ffff00000000ULL) >> 16)
1331 	  | ((x & 0xffff000000000000ULL) >> 48);
1332 	reg(ic->arg[1]) = x;
1333 }
X(wsbh)1334 X(wsbh)
1335 {
1336 	uint32_t x = reg(ic->arg[0]);
1337 	x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8);
1338 	reg(ic->arg[1]) = (int32_t) x;
1339 }
X(seb)1340 X(seb) { reg(ic->arg[1]) = (int8_t)reg(ic->arg[0]); }
X(seh)1341 X(seh) { reg(ic->arg[1]) = (int16_t)reg(ic->arg[0]); }
1342 
1343 
1344 /*
1345  *  2-register + immediate:
1346  *
1347  *  arg[0] = pointer to rs
1348  *  arg[1] = pointer to rt
1349  *  arg[2] = uint32_t immediate value
1350  */
X(andi)1351 X(andi) { reg(ic->arg[1]) = reg(ic->arg[0]) & (uint32_t)ic->arg[2]; }
X(ori)1352 X(ori)  { reg(ic->arg[1]) = reg(ic->arg[0]) | (uint32_t)ic->arg[2]; }
X(xori)1353 X(xori) { reg(ic->arg[1]) = reg(ic->arg[0]) ^ (uint32_t)ic->arg[2]; }
1354 
1355 
1356 /*
1357  *  2-register:
1358  *
1359  *  arg[0] = ptr to rs
1360  *  arg[1] = ptr to rt
1361  */
X(div)1362 X(div)
1363 {
1364 	int32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1365 	int32_t res, rem;
1366 	if (b == 0)
1367 		res = 0, rem = a;
1368 	else if (a == (int32_t)0x80000000U && b == -1)
1369 		res = 0, rem = 0;
1370 	else
1371 		res = a / b, rem = a - b*res;
1372 	cpu->cd.mips.lo = (int32_t)res;
1373 	cpu->cd.mips.hi = (int32_t)rem;
1374 }
X(divu)1375 X(divu)
1376 {
1377 	uint32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1378 	uint32_t res, rem;
1379 	if (b == 0)
1380 		res = 0, rem = a;
1381 	else
1382 		res = a / b, rem = a - b*res;
1383 	cpu->cd.mips.lo = (int32_t)res;
1384 	cpu->cd.mips.hi = (int32_t)rem;
1385 }
X(ddiv)1386 X(ddiv)
1387 {
1388 	int64_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1389 	int64_t res, rem;
1390 	if (b == 0)
1391 		res = 0;
1392 	else if (a == (int64_t)0x8000000000000000ULL && b == -1)
1393 		res = 0;
1394 	else
1395 		res = a / b;
1396 	rem = a - b*res;
1397 	cpu->cd.mips.lo = res;
1398 	cpu->cd.mips.hi = rem;
1399 }
X(ddivu)1400 X(ddivu)
1401 {
1402 	uint64_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1403 	uint64_t res, rem;
1404 	if (b == 0)
1405 		res = 0;
1406 	else
1407 		res = a / b;
1408 	rem = a - b*res;
1409 	cpu->cd.mips.lo = res;
1410 	cpu->cd.mips.hi = rem;
1411 }
X(mult)1412 X(mult)
1413 {
1414 	int32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1415 	int64_t res = (int64_t)a * (int64_t)b;
1416 	cpu->cd.mips.lo = (int32_t)res;
1417 	cpu->cd.mips.hi = (int32_t)(res >> 32);
1418 }
X(mult_r5900)1419 X(mult_r5900)
1420 {
1421 	/*  C790/TX79/R5900 multiplication, stores result in
1422 	    hi, lo, and a third register  */
1423 	int32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1424 	int64_t res = (int64_t)a * (int64_t)b;
1425 	cpu->cd.mips.lo = (int32_t)res;
1426 	cpu->cd.mips.hi = (int32_t)(res >> 32);
1427 	reg(ic->arg[2]) = (int32_t)res;
1428 }
X(multu)1429 X(multu)
1430 {
1431 	uint32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1432 	uint64_t res = (uint64_t)a * (uint64_t)b;
1433 	cpu->cd.mips.lo = (int32_t)res;
1434 	cpu->cd.mips.hi = (int32_t)(res >> 32);
1435 }
X(multu_r5900)1436 X(multu_r5900)
1437 {
1438 	/*  C790/TX79/R5900 multiplication, stores result in
1439 	    hi, lo, and a third register  */
1440 	uint32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1441 	uint64_t res = (uint64_t)a * (uint64_t)b;
1442 	cpu->cd.mips.lo = (int32_t)res;
1443 	cpu->cd.mips.hi = (int32_t)(res >> 32);
1444 	reg(ic->arg[2]) = (int32_t)res;
1445 }
X(dmult)1446 X(dmult)
1447 {
1448 	uint64_t a = reg(ic->arg[0]), b = reg(ic->arg[1]), c = 0;
1449 	uint64_t hi = 0, lo = 0;
1450 	int neg = 0;
1451 	if (a >> 63)
1452 		neg = !neg, a = -a;
1453 	if (b >> 63)
1454 		neg = !neg, b = -b;
1455 	for (; a; a >>= 1) {
1456 		if (a & 1) {
1457 			uint64_t old_lo = lo;
1458 			hi += c;
1459 			lo += b;
1460 			if (lo < old_lo)
1461 				hi ++;
1462 		}
1463 		c = (c << 1) | (b >> 63); b <<= 1;
1464 	}
1465 	if (neg) {
1466 		if (lo == 0)
1467 			hi --;
1468 		lo --;
1469 		hi ^= (int64_t) -1;
1470 		lo ^= (int64_t) -1;
1471 	}
1472 	cpu->cd.mips.lo = lo;
1473 	cpu->cd.mips.hi = hi;
1474 }
X(dmultu)1475 X(dmultu)
1476 {
1477 	uint64_t a = reg(ic->arg[0]), b = reg(ic->arg[1]), c = 0;
1478 	uint64_t hi = 0, lo = 0;
1479 	for (; a; a >>= 1) {
1480 		if (a & 1) {
1481 			uint64_t old_lo = lo;
1482 			hi += c;
1483 			lo += b;
1484 			if (lo < old_lo)
1485 				hi ++;
1486 		}
1487 		c = (c << 1) | (b >> 63); b <<= 1;
1488 	}
1489 	cpu->cd.mips.lo = lo;
1490 	cpu->cd.mips.hi = hi;
1491 }
X(tge)1492 X(tge)
1493 {
1494 	MODE_int_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1495 	if (a >= b) {
1496 		/*  Synch. PC and cause an exception:  */
1497 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1498 		    / sizeof(struct mips_instr_call);
1499 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1500 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1501 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1502 		mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1503 	}
1504 }
X(tgeu)1505 X(tgeu)
1506 {
1507 	MODE_uint_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1508 	if (a >= b) {
1509 		/*  Synch. PC and cause an exception:  */
1510 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1511 		    / sizeof(struct mips_instr_call);
1512 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1513 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1514 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1515 		mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1516 	}
1517 }
X(tlt)1518 X(tlt)
1519 {
1520 	MODE_int_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1521 	if (a < b) {
1522 		/*  Synch. PC and cause an exception:  */
1523 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1524 		    / sizeof(struct mips_instr_call);
1525 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1526 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1527 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1528 		mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1529 	}
1530 }
X(tltu)1531 X(tltu)
1532 {
1533 	MODE_uint_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1534 	if (a < b) {
1535 		/*  Synch. PC and cause an exception:  */
1536 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1537 		    / sizeof(struct mips_instr_call);
1538 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1539 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1540 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1541 		mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1542 	}
1543 }
X(teq)1544 X(teq)
1545 {
1546 	MODE_uint_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1547 	if (a == b) {
1548 		/*  Synch. PC and cause an exception:  */
1549 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1550 		    / sizeof(struct mips_instr_call);
1551 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1552 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1553 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1554 		mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1555 	}
1556 }
X(tne)1557 X(tne)
1558 {
1559 	MODE_uint_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1560 	if (a != b) {
1561 		/*  Synch. PC and cause an exception:  */
1562 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1563 		    / sizeof(struct mips_instr_call);
1564 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1565 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1566 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1567 		mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1568 	}
1569 }
1570 
1571 
1572 /*
1573  *  3-register arithmetic instructions:
1574  *
1575  *  arg[0] = ptr to rs
1576  *  arg[1] = ptr to rt
1577  *  arg[2] = ptr to rd
1578  */
X(addu)1579 X(addu) { reg(ic->arg[2]) = (int32_t)(reg(ic->arg[0]) + reg(ic->arg[1])); }
X(add)1580 X(add)
1581 {
1582 	int32_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
1583 	int32_t rd = rs + rt;
1584 
1585 	if (unlikely((rs >= 0 && rt >= 0 && rd < 0) || (rs < 0 && rt < 0 && rd >= 0))) {
1586 		/*  Synch. PC and cause an exception:  */
1587 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1588 		    / sizeof(struct mips_instr_call);
1589 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1590 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1591 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1592 		mips_cpu_exception(cpu, EXCEPTION_OV, 0, 0, 0, 0, 0, 0);
1593 	} else
1594 		reg(ic->arg[2]) = rd;
1595 }
X(daddu)1596 X(daddu){ reg(ic->arg[2]) = reg(ic->arg[0]) + reg(ic->arg[1]); }
X(dadd)1597 X(dadd)
1598 {
1599 	int64_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
1600 	int64_t rd = rs + rt;
1601 
1602 	if (unlikely((rs >= 0 && rt >= 0 && rd < 0) || (rs < 0 && rt < 0 && rd >= 0))) {
1603 		/*  Synch. PC and cause an exception:  */
1604 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1605 		    / sizeof(struct mips_instr_call);
1606 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1607 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1608 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1609 		mips_cpu_exception(cpu, EXCEPTION_OV, 0, 0, 0, 0, 0, 0);
1610 	} else
1611 		reg(ic->arg[2]) = rd;
1612 }
X(subu)1613 X(subu) { reg(ic->arg[2]) = (int32_t)(reg(ic->arg[0]) - reg(ic->arg[1])); }
X(sub)1614 X(sub)
1615 {
1616 	/*  NOTE: Negating rt and using addition. TODO: Is this correct?  */
1617 	int32_t rs = reg(ic->arg[0]), rt = - reg(ic->arg[1]);
1618 	int32_t rd = rs + rt;
1619 
1620 	if (unlikely((rs >= 0 && rt >= 0 && rd < 0) || (rs < 0 && rt < 0 && rd >= 0))) {
1621 		/*  Synch. PC and cause an exception:  */
1622 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1623 		    / sizeof(struct mips_instr_call);
1624 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1625 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1626 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1627 		mips_cpu_exception(cpu, EXCEPTION_OV, 0, 0, 0, 0, 0, 0);
1628 	} else
1629 		reg(ic->arg[2]) = rd;
1630 }
X(dsubu)1631 X(dsubu){ reg(ic->arg[2]) = reg(ic->arg[0]) - reg(ic->arg[1]); }
X(dsub)1632 X(dsub)
1633 {
1634 	/*  NOTE: Negating rt and using addition. TODO: Is this correct?  */
1635 	int64_t rs = reg(ic->arg[0]), rt = - reg(ic->arg[1]);
1636 	int64_t rd = rs + rt;
1637 
1638 	if (unlikely((rs >= 0 && rt >= 0 && rd < 0) || (rs < 0 && rt < 0 && rd >= 0))) {
1639 		/*  Synch. PC and cause an exception:  */
1640 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1641 		    / sizeof(struct mips_instr_call);
1642 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1643 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1644 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1645 		mips_cpu_exception(cpu, EXCEPTION_OV, 0, 0, 0, 0, 0, 0);
1646 	} else
1647 		reg(ic->arg[2]) = rd;
1648 }
X(slt)1649 X(slt) {
1650 	reg(ic->arg[2]) =
1651 	    (MODE_int_t)reg(ic->arg[0]) < (MODE_int_t)reg(ic->arg[1]);
1652 }
X(sltu)1653 X(sltu) {
1654 	reg(ic->arg[2]) =
1655 	    (MODE_uint_t)reg(ic->arg[0]) < (MODE_uint_t)reg(ic->arg[1]);
1656 }
X(and)1657 X(and) { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]); }
X(or)1658 X(or)  { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]); }
X(xor)1659 X(xor) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); }
X(nor)1660 X(nor) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1])); }
X(sll)1661 X(sll) { reg(ic->arg[2]) = (int32_t)(reg(ic->arg[0]) << (int32_t)ic->arg[1]); }
X(sllv)1662 X(sllv){ int32_t sa = reg(ic->arg[1]) & 31;
1663 	 reg(ic->arg[2]) = (int32_t)(reg(ic->arg[0]) << sa); }
X(srl)1664 X(srl) { reg(ic->arg[2]) = (int32_t)((uint32_t)reg(ic->arg[0]) >> ic->arg[1]); }
X(srlv)1665 X(srlv){ int32_t sa = reg(ic->arg[1]) & 31;
1666 	 reg(ic->arg[2]) = (int32_t)((uint32_t)reg(ic->arg[0]) >> sa); }
X(sra)1667 X(sra) { reg(ic->arg[2]) = (int32_t)((int32_t)reg(ic->arg[0]) >> ic->arg[1]); }
X(srav)1668 X(srav){ int32_t sa = reg(ic->arg[1]) & 31;
1669 	 reg(ic->arg[2]) = (int32_t)((int32_t)reg(ic->arg[0]) >> sa); }
X(dsll)1670 X(dsll) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) << (int64_t)ic->arg[1]; }
X(dsllv)1671 X(dsllv){ int64_t sa = reg(ic->arg[1]) & 63;
1672 	 reg(ic->arg[2]) = reg(ic->arg[0]) << sa; }
X(dsrl)1673 X(dsrl) { reg(ic->arg[2]) = (int64_t)((uint64_t)reg(ic->arg[0]) >>
1674 	(uint64_t) ic->arg[1]);}
X(dsrlv)1675 X(dsrlv){ int64_t sa = reg(ic->arg[1]) & 63;
1676 	 reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) >> sa; }
X(dsra)1677 X(dsra) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) >> (int64_t)ic->arg[1]; }
X(dsrav)1678 X(dsrav){ int64_t sa = reg(ic->arg[1]) & 63;
1679 	 reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) >> sa; }
X(mul)1680 X(mul) { reg(ic->arg[2]) = (int32_t)
1681 	( (int32_t)reg(ic->arg[0]) * (int32_t)reg(ic->arg[1]) ); }
X(movn)1682 X(movn) { if (reg(ic->arg[1])) reg(ic->arg[2]) = reg(ic->arg[0]); }
X(movz)1683 X(movz) { if (!reg(ic->arg[1])) reg(ic->arg[2]) = reg(ic->arg[0]); }
1684 
X(ror)1685 X(ror)
1686 {
1687 	uint32_t result = reg(ic->arg[0]);
1688 	int sa = ic->arg[1];
1689 
1690 	result = (result >> sa) | (result << (32-sa));
1691 
1692 	reg(ic->arg[2]) = (int32_t) result;
1693 }
1694 
X(rorv)1695 X(rorv)
1696 {
1697 	uint32_t result = reg(ic->arg[0]);
1698 	int sa = reg(ic->arg[1]);
1699 
1700 	result = (result >> sa) | (result << (32-sa));
1701 
1702 	reg(ic->arg[2]) = (int32_t) result;
1703 }
1704 
1705 
1706 /*
1707  *  p*:  128-bit C790/TX79/R5900 stuff
1708  *
1709  *  arg[0] = rs (note: not a pointer)
1710  *  arg[1] = rt (note: not a pointer)
1711  *  arg[2] = rd (note: not a pointer)
1712  */
X(por)1713 X(por)
1714 {
1715 	cpu->cd.mips.gpr[ic->arg[2]] = cpu->cd.mips.gpr[ic->arg[0]] |
1716 	    cpu->cd.mips.gpr[ic->arg[1]];
1717 	cpu->cd.mips.gpr_quadhi[ic->arg[2]] =
1718 	    cpu->cd.mips.gpr_quadhi[ic->arg[0]] |
1719 	    cpu->cd.mips.gpr_quadhi[ic->arg[1]];
1720 }
X(pextlw)1721 X(pextlw)
1722 {
1723 	uint64_t lo, hi;
1724 
1725 	lo = (uint32_t)cpu->cd.mips.gpr[ic->arg[1]] |
1726 	    (uint64_t)((uint64_t)cpu->cd.mips.gpr[ic->arg[0]] << 32);
1727 	hi = (cpu->cd.mips.gpr[ic->arg[0]] & 0xffffffff00000000ULL) |
1728 	    (uint32_t)((uint64_t)cpu->cd.mips.gpr[ic->arg[1]] >> 32);
1729 
1730 	cpu->cd.mips.gpr[ic->arg[2]] = lo;
1731 	cpu->cd.mips.gpr_quadhi[ic->arg[2]] = hi;
1732 }
1733 
1734 
1735 /*
1736  *  madd, maddu, msub, msubu: Multiply-and-add/subtract
1737  *
1738  *  arg[0] = ptr to rs
1739  *  arg[1] = ptr to rt
1740  *  arg[2] = ptr to rd (only used on R5900/TX79)
1741  */
X(madd)1742 X(madd)
1743 {
1744 	int64_t rs = (int32_t)reg(ic->arg[0]), rt = (int32_t)reg(ic->arg[1]);
1745 	int64_t sum = rs * rt,
1746 	    hilo = (cpu->cd.mips.hi << 32) | (uint32_t)(cpu->cd.mips.lo);
1747 	hilo += sum;
1748 	cpu->cd.mips.hi = (int32_t)(hilo>>32); cpu->cd.mips.lo = (int32_t)hilo;
1749 }
X(madd_rd)1750 X(madd_rd)
1751 {
1752 	int64_t rs = (int32_t)reg(ic->arg[0]), rt = (int32_t)reg(ic->arg[1]);
1753 	int64_t sum = rs * rt,
1754 	    hilo = (cpu->cd.mips.hi << 32) | (uint32_t)(cpu->cd.mips.lo);
1755 	hilo += sum;
1756 	cpu->cd.mips.hi = (int32_t)(hilo>>32); cpu->cd.mips.lo = (int32_t)hilo;
1757 	reg(ic->arg[2]) = (int32_t)hilo;
1758 }
X(msub)1759 X(msub)
1760 {
1761 	int64_t rs = (int32_t)reg(ic->arg[0]), rt = (int32_t)reg(ic->arg[1]);
1762 	int64_t sum = rs * rt,
1763 	    hilo = (cpu->cd.mips.hi << 32) | (uint32_t)(cpu->cd.mips.lo);
1764 	hilo -= sum;
1765 	cpu->cd.mips.hi = (int32_t)(hilo>>32); cpu->cd.mips.lo = (int32_t)hilo;
1766 }
X(maddu)1767 X(maddu)
1768 {
1769 	int64_t rs = (uint32_t)reg(ic->arg[0]), rt = (uint32_t)reg(ic->arg[1]);
1770 	int64_t sum = rs * rt,
1771 	    hilo = (cpu->cd.mips.hi << 32) | (uint32_t)(cpu->cd.mips.lo);
1772 	hilo += sum;
1773 	cpu->cd.mips.hi = (int32_t)(hilo>>32); cpu->cd.mips.lo = (int32_t)hilo;
1774 }
X(maddu_rd)1775 X(maddu_rd)
1776 {
1777 	int64_t rs = (uint32_t)reg(ic->arg[0]), rt = (uint32_t)reg(ic->arg[1]);
1778 	int64_t sum = rs * rt,
1779 	    hilo = (cpu->cd.mips.hi << 32) | (uint32_t)(cpu->cd.mips.lo);
1780 	hilo += sum;
1781 	cpu->cd.mips.hi = (int32_t)(hilo>>32); cpu->cd.mips.lo = (int32_t)hilo;
1782 	reg(ic->arg[2]) = (int32_t)hilo;
1783 }
X(msubu)1784 X(msubu)
1785 {
1786 	int64_t rs = (uint32_t)reg(ic->arg[0]), rt = (uint32_t)reg(ic->arg[1]);
1787 	int64_t sum = rs * rt,
1788 	    hilo = (cpu->cd.mips.hi << 32) | (uint32_t)(cpu->cd.mips.lo);
1789 	hilo -= sum;
1790 	cpu->cd.mips.hi = (int32_t)(hilo>>32); cpu->cd.mips.lo = (int32_t)hilo;
1791 }
1792 
1793 
1794 /*
1795  *  mov:  Move one register into another.
1796  *
1797  *  arg[0] = pointer to source
1798  *  arg[2] = pointer to destination
1799  */
X(mov)1800 X(mov)  { reg(ic->arg[2]) = reg(ic->arg[0]); }
1801 
1802 
1803 /*
1804  *  clz, clo, dclz, dclo: Count leading zeroes/ones.
1805  *
1806  *  arg[0] = pointer to rs
1807  *  arg[1] = pointer to rd
1808  */
X(clz)1809 X(clz)
1810 {
1811 	uint32_t x = reg(ic->arg[0]);
1812 	int count;
1813 	for (count=0; count<32; count++) {
1814 		if (x & 0x80000000UL)
1815 			break;
1816 		x <<= 1;
1817 	}
1818 	reg(ic->arg[1]) = count;
1819 }
X(clo)1820 X(clo)
1821 {
1822 	uint32_t x = reg(ic->arg[0]);
1823 	int count;
1824 	for (count=0; count<32; count++) {
1825 		if (!(x & 0x80000000UL))
1826 			break;
1827 		x <<= 1;
1828 	}
1829 	reg(ic->arg[1]) = count;
1830 }
X(dclz)1831 X(dclz)
1832 {
1833 	uint64_t x = reg(ic->arg[0]);
1834 	int count;
1835 	for (count=0; count<64; count++) {
1836 		if (x & 0x8000000000000000ULL)
1837 			break;
1838 		x <<= 1;
1839 	}
1840 	reg(ic->arg[1]) = count;
1841 }
X(dclo)1842 X(dclo)
1843 {
1844 	uint64_t x = reg(ic->arg[0]);
1845 	int count;
1846 	for (count=0; count<64; count++) {
1847 		if (!(x & 0x8000000000000000ULL))
1848 			break;
1849 		x <<= 1;
1850 	}
1851 	reg(ic->arg[1]) = count;
1852 }
1853 
1854 
1855 /*
1856  *  addi, daddi: Add immediate, overflow detection.
1857  *  addiu, daddiu: Add immediate.
1858  *  slti:   Set if less than immediate (signed 32-bit)
1859  *  sltiu:  Set if less than immediate (signed 32-bit, but unsigned compare)
1860  *
1861  *  arg[0] = pointer to rs
1862  *  arg[1] = pointer to rt
1863  *  arg[2] = (int32_t) immediate value
1864  */
X(addi)1865 X(addi)
1866 {
1867 	int32_t rs = reg(ic->arg[0]), imm = (int32_t)ic->arg[2];
1868 	int32_t rt = rs + imm;
1869 
1870 	if (unlikely((rs >= 0 && imm >= 0 && rt < 0) || (rs < 0 && imm < 0 && rt >= 0))) {
1871 		/*  Synch. PC and cause an exception:  */
1872 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1873 		    / sizeof(struct mips_instr_call);
1874 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1875 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1876 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1877 		mips_cpu_exception(cpu, EXCEPTION_OV, 0, 0, 0, 0, 0, 0);
1878 	} else
1879 		reg(ic->arg[1]) = rt;
1880 }
X(addiu)1881 X(addiu)
1882 {
1883 	reg(ic->arg[1]) = (int32_t)
1884 	    ((int32_t)reg(ic->arg[0]) + (int32_t)ic->arg[2]);
1885 }
X(daddi)1886 X(daddi)
1887 {
1888 	int64_t rs = reg(ic->arg[0]), imm = (int32_t)ic->arg[2];
1889 	int64_t rt = rs + imm;
1890 
1891 	if (unlikely((rs >= 0 && imm >= 0 && rt < 0) || (rs < 0 && imm < 0 && rt >= 0))) {
1892 		/*  Synch. PC and cause an exception:  */
1893 		int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
1894 		    / sizeof(struct mips_instr_call);
1895 		cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
1896 		    << MIPS_INSTR_ALIGNMENT_SHIFT);
1897 		cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1898 		mips_cpu_exception(cpu, EXCEPTION_OV, 0, 0, 0, 0, 0, 0);
1899 	} else
1900 		reg(ic->arg[1]) = rt;
1901 }
X(daddiu)1902 X(daddiu)
1903 {
1904 	reg(ic->arg[1]) = reg(ic->arg[0]) + (int32_t)ic->arg[2];
1905 }
X(slti)1906 X(slti)
1907 {
1908 	reg(ic->arg[1]) = (MODE_int_t)reg(ic->arg[0]) < (int32_t)ic->arg[2];
1909 }
X(sltiu)1910 X(sltiu)
1911 {
1912 	reg(ic->arg[1]) = (MODE_uint_t)reg(ic->arg[0]) <
1913 	   ((MODE_uint_t)(int32_t)ic->arg[2]);
1914 }
1915 
1916 
1917 /*
1918  *  set:  Set a register to an immediate (signed) 32-bit value.
1919  *        (This is the actual implementation of the lui instruction.)
1920  *
1921  *  arg[0] = pointer to the register
1922  *  arg[1] = (int32_t) immediate value
1923  */
X(set)1924 X(set)
1925 {
1926 	reg(ic->arg[0]) = (int32_t)ic->arg[1];
1927 }
1928 
1929 
1930 /*
1931  *  cfc0:         Copy from Coprocessor 0.
1932  *  mfc0, dmfc0:  Move from Coprocessor 0.
1933  *  mtc0, dmtc0:  Move to Coprocessor 0.
1934  *
1935  *  arg[0] = pointer to GPR (rt)
1936  *  arg[1] = coprocessor 0 register number | (select << 5)   (or for the
1937  *           cfc0 instruction, the coprocessor control register number)
1938  *  arg[2] = relative addr of this instruction within the page
1939  */
X(cfc0)1940 X(cfc0)
1941 {
1942 	int fs = ic->arg[1] & 31;
1943 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<<MIPS_INSTR_ALIGNMENT_SHIFT);
1944 	cpu->pc |= ic->arg[2];
1945 	/*  TODO: cause exception if necessary  */
1946 	reg(ic->arg[0]) = (int32_t)cpu->cd.mips.coproc[0]->fcr[fs];
1947 }
X(mfc0)1948 X(mfc0)
1949 {
1950 	int rd = ic->arg[1] & 31, select = ic->arg[1] >> 5;
1951 	uint64_t tmp;
1952 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<<MIPS_INSTR_ALIGNMENT_SHIFT);
1953 	cpu->pc |= ic->arg[2];
1954 	/*  TODO: cause exception if necessary  */
1955 	coproc_register_read(cpu, cpu->cd.mips.coproc[0], rd, &tmp, select);
1956 	reg(ic->arg[0]) = (int32_t)tmp;
1957 }
X(mfc0_select0)1958 X(mfc0_select0)
1959 {
1960 	/*  Fast int32_t read, with no side effects:  */
1961 	int rd = ic->arg[1] & 31;
1962 #if 0
1963 	uint64_t tmp;
1964 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<<MIPS_INSTR_ALIGNMENT_SHIFT);
1965 	cpu->pc |= ic->arg[2];
1966 	/*  TODO: cause exception if necessary  */
1967 #endif
1968 	reg(ic->arg[0]) = (int32_t)cpu->cd.mips.coproc[0]->reg[rd];
1969 }
X(mtc0)1970 X(mtc0)
1971 {
1972 	int rd = ic->arg[1] & 31, select = ic->arg[1] >> 5;
1973 	uint64_t tmp = (int32_t) reg(ic->arg[0]);
1974 
1975 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<<MIPS_INSTR_ALIGNMENT_SHIFT);
1976 	cpu->pc |= ic->arg[2];
1977 
1978 	/*  TODO: cause exception if necessary  */
1979 	coproc_register_write(cpu, cpu->cd.mips.coproc[0], rd, &tmp, 0, select);
1980 
1981 	/*
1982 	 *  Interrupts enabled, and any interrupt pending? (Note/TODO: This
1983 	 *  code is duplicated in cpu_dyntrans.c. Fix this?)
1984 	 */
1985 	if (rd == COP0_STATUS && !cpu->delay_slot) {
1986 		uint32_t status = cpu->cd.mips.coproc[0]->reg[COP0_STATUS];
1987 		uint32_t cause = cpu->cd.mips.coproc[0]->reg[COP0_CAUSE];
1988 		/*  NOTE: STATUS_IE happens to match the enable bit also
1989 		    on R2000/R3000, so this is ok.  */
1990 		if (cpu->cd.mips.cpu_type.exc_model != EXC3K) {
1991 			if (status & (STATUS_EXL | STATUS_ERL))
1992 				status &= ~STATUS_IE;
1993 		}
1994 		/*  Ugly R5900 special case:  (TODO: move this?)  */
1995 		if (cpu->cd.mips.cpu_type.rev == MIPS_R5900 &&
1996 		    !(status & R5900_STATUS_EIE))
1997 			status &= ~STATUS_IE;
1998 		if (status & STATUS_IE && (status & cause & STATUS_IM_MASK)) {
1999 			cpu->pc += sizeof(uint32_t);
2000 			mips_cpu_exception(cpu, EXCEPTION_INT, 0, 0,0,0,0,0);
2001 		}
2002 	}
2003 }
X(dmfc0)2004 X(dmfc0)
2005 {
2006 	int rd = ic->arg[1] & 31, select = ic->arg[1] >> 5;
2007 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<<MIPS_INSTR_ALIGNMENT_SHIFT);
2008 	cpu->pc |= ic->arg[2];
2009 	/*  TODO: cause exception if necessary  */
2010 	coproc_register_read(cpu, cpu->cd.mips.coproc[0], rd,
2011 	    (uint64_t *)ic->arg[0], select);
2012 }
X(dmfc0_select0)2013 X(dmfc0_select0)
2014 {
2015 	/*  Fast int64_t read, with no side effects:  */
2016 	int rd = ic->arg[1] & 31;
2017 #if 0
2018 	uint64_t tmp;
2019 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<<MIPS_INSTR_ALIGNMENT_SHIFT);
2020 	cpu->pc |= ic->arg[2];
2021 	/*  TODO: cause exception if necessary  */
2022 #endif
2023 	reg(ic->arg[0]) = cpu->cd.mips.coproc[0]->reg[rd];
2024 }
X(dmtc0)2025 X(dmtc0)
2026 {
2027 	int rd = ic->arg[1] & 31, select = ic->arg[1] >> 5;
2028 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<<MIPS_INSTR_ALIGNMENT_SHIFT);
2029 	cpu->pc |= ic->arg[2];
2030 	/*  TODO: cause exception if necessary  */
2031 	coproc_register_write(cpu, cpu->cd.mips.coproc[0], rd,
2032 	    (uint64_t *)ic->arg[0], 1, select);
2033 }
2034 
2035 
2036 /*
2037  *  cop1_bc:  Floating point conditional branch.
2038  *
2039  *  arg[0] = cc
2040  *  arg[1] = nd (=2) and tf (=1) bits
2041  *  arg[2] = offset (relative to start of this page)
2042  */
X(cop1_bc)2043 X(cop1_bc)
2044 {
2045 	MODE_int_t old_pc = cpu->pc;
2046 	int x, cc = ic->arg[0];
2047 
2048 	COPROC_AVAILABILITY_CHECK(1);
2049 
2050 	/*  Get the correct condition code bit:  */
2051 	if (cc == 0)
2052 		x = (cpu->cd.mips.coproc[1]->fcr[MIPS_FPU_FCSR]
2053 		    >> MIPS_FCSR_FCC0_SHIFT) & 1;
2054 	else
2055 		x = (cpu->cd.mips.coproc[1]->fcr[MIPS_FPU_FCSR]
2056 		    >> (MIPS_FCSR_FCC1_SHIFT + cc-1)) & 1;
2057 
2058 	/*  Branch on false? Then invert the truth value.  */
2059 	if (!(ic->arg[1] & 1))
2060 		x ^= 1;
2061 
2062 	/*  Execute the delay slot (except if it is nullified):  */
2063 	cpu->delay_slot = TO_BE_DELAYED;
2064 	if (x || !(ic->arg[1] & 2))
2065 		ic[1].f(cpu, ic+1);
2066 	cpu->n_translated_instrs ++;
2067 
2068 	if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
2069 		/*  Note: Must be non-delayed when jumping to the new pc:  */
2070 		cpu->delay_slot = NOT_DELAYED;
2071 		if (x) {
2072 			old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
2073 			    MIPS_INSTR_ALIGNMENT_SHIFT);
2074 			cpu->pc = old_pc + (int32_t)ic->arg[2];
2075 			quick_pc_to_pointers(cpu);
2076 		} else
2077 			cpu->cd.mips.next_ic ++;
2078 	} else
2079 		cpu->delay_slot = NOT_DELAYED;
2080 }
2081 
2082 
2083 /*
2084  *  cop1_slow:  Fallback to legacy cop1 code. (Slow, but it should work.)
2085  */
X(cop1_slow)2086 X(cop1_slow)
2087 {
2088 	COPROC_AVAILABILITY_CHECK(1);
2089 
2090 	coproc_function(cpu, cpu->cd.mips.coproc[1], 1, ic->arg[0], 0, 1);
2091 }
2092 
2093 
2094 /*
2095  *  syscall, break:  Synchronize the PC and cause an exception.
2096  */
X(syscall)2097 X(syscall)
2098 {
2099 	int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
2100 	    / sizeof(struct mips_instr_call);
2101 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<< MIPS_INSTR_ALIGNMENT_SHIFT);
2102 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
2103 	mips_cpu_exception(cpu, EXCEPTION_SYS, 0, 0, 0, 0, 0, 0);
2104 }
X(break)2105 X(break)
2106 {
2107 	int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
2108 	    / sizeof(struct mips_instr_call);
2109 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<< MIPS_INSTR_ALIGNMENT_SHIFT);
2110 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
2111 	mips_cpu_exception(cpu, EXCEPTION_BP, 0, 0, 0, 0, 0, 0);
2112 }
X(reboot)2113 X(reboot)
2114 {
2115 	if (!cop0_availability_check(cpu, ic))
2116 		return;
2117 
2118 	cpu->running = 0;
2119 	debugger_n_steps_left_before_interaction = 0;
2120 	cpu->cd.mips.next_ic = &nothing_call;
2121 }
2122 
2123 
2124 /*
2125  *  promemul:  PROM software emulation.
2126  */
X(promemul)2127 X(promemul)
2128 {
2129 	/*  Synchronize the PC and call the correct emulation layer:  */
2130 	MODE_int_t old_pc;
2131 	int res, low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
2132 	    / sizeof(struct mips_instr_call);
2133 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<< MIPS_INSTR_ALIGNMENT_SHIFT);
2134 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
2135 	old_pc = cpu->pc;
2136 
2137 	switch (cpu->machine->machine_type) {
2138 	case MACHINE_PMAX:
2139 		res = decstation_prom_emul(cpu);
2140 		break;
2141 	case MACHINE_PS2:
2142 		res = playstation2_sifbios_emul(cpu);
2143 		break;
2144 	case MACHINE_ARC:
2145 	case MACHINE_SGI:
2146 		res = arcbios_emul(cpu);
2147 		break;
2148 	case MACHINE_EVBMIPS:
2149 		res = yamon_emul(cpu);
2150 		break;
2151 	default:fatal("TODO: Unimplemented machine type for PROM magic trap\n");
2152 		exit(1);
2153 	}
2154 
2155 	if (res) {
2156 		/*  Return from the PROM call:  */
2157 		cpu->pc = (MODE_int_t)cpu->cd.mips.gpr[MIPS_GPR_RA];
2158 		cpu->delay_slot = NOT_DELAYED;
2159 
2160 		if (cpu->machine->show_trace_tree)
2161 			cpu_functioncall_trace_return(cpu);
2162 	} else {
2163 		/*  The PROM call blocks.  */
2164 		cpu->n_translated_instrs += 10;
2165 		cpu->pc = old_pc;
2166 	}
2167 
2168 	quick_pc_to_pointers(cpu);
2169 }
2170 
2171 
2172 /*
2173  *  tlbw: TLB write indexed and random
2174  *
2175  *  arg[0] = 1 for random, 0 for indexed
2176  *  arg[2] = relative addr of this instruction within the page
2177  */
X(tlbw)2178 X(tlbw)
2179 {
2180 	if (!cop0_availability_check(cpu, ic))
2181 		return;
2182 
2183 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<<MIPS_INSTR_ALIGNMENT_SHIFT);
2184 	cpu->pc |= ic->arg[2];
2185 	coproc_tlbwri(cpu, ic->arg[0]);
2186 }
2187 
2188 
2189 /*
2190  *  tlbp: TLB probe
2191  *  tlbr: TLB read
2192  *
2193  *  arg[2] = relative addr of this instruction within the page
2194  */
X(tlbp)2195 X(tlbp)
2196 {
2197 	if (!cop0_availability_check(cpu, ic))
2198 		return;
2199 
2200 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<<MIPS_INSTR_ALIGNMENT_SHIFT);
2201 	cpu->pc |= ic->arg[2];
2202 	coproc_tlbpr(cpu, 0);
2203 }
X(tlbr)2204 X(tlbr)
2205 {
2206 	if (!cop0_availability_check(cpu, ic))
2207 		return;
2208 
2209 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)<<MIPS_INSTR_ALIGNMENT_SHIFT);
2210 	cpu->pc |= ic->arg[2];
2211 	coproc_tlbpr(cpu, 1);
2212 }
2213 
2214 
2215 /*
2216  *  ei_or_di:  MIPS32/64 rev 2, Enable or disable interrupts
2217  *
2218  *  arg[0] = ptr to rt
2219  *  arg[1] = non-zero to enable interrupts
2220  */
X(ei_or_di)2221 X(ei_or_di)
2222 {
2223 	reg(ic->arg[0]) = cpu->cd.mips.coproc[0]->reg[COP0_STATUS];
2224 	if (ic->arg[1])
2225 		cpu->cd.mips.coproc[0]->reg[COP0_STATUS] |= STATUS_IE;
2226 	else
2227 		cpu->cd.mips.coproc[0]->reg[COP0_STATUS] &= ~STATUS_IE;
2228 }
2229 
2230 
2231 /*
2232  *  rfe: Return from exception handler (R2000/R3000)
2233  */
X(rfe)2234 X(rfe)
2235 {
2236 	if (!cop0_availability_check(cpu, ic))
2237 		return;
2238 
2239 	/*  Just rotate the interrupt/user bits:  */
2240 	cpu->cd.mips.coproc[0]->reg[COP0_STATUS] =
2241 	    (cpu->cd.mips.coproc[0]->reg[COP0_STATUS] & ~0x3f) |
2242 	    ((cpu->cd.mips.coproc[0]->reg[COP0_STATUS] & 0x3c) >> 2);
2243 
2244 	/*
2245 	 *  Note: no pc to pointers conversion is necessary here. Usually the
2246 	 *  rfe instruction resides in the delay slot of a jr k0/k1, and
2247 	 *  it is up to that instruction to do the pointer conversion.
2248 	 */
2249 }
2250 
2251 
2252 /*
2253  *  eret: Return from exception handler (non-R3000 style)
2254  */
X(eret)2255 X(eret)
2256 {
2257 	if (!cop0_availability_check(cpu, ic))
2258 		return;
2259 
2260 	if (cpu->cd.mips.coproc[0]->reg[COP0_STATUS] & STATUS_ERL) {
2261 		cpu->pc = cpu->cd.mips.coproc[0]->reg[COP0_ERROREPC];
2262 		cpu->cd.mips.coproc[0]->reg[COP0_STATUS] &= ~STATUS_ERL;
2263 	} else {
2264 		cpu->pc = cpu->cd.mips.coproc[0]->reg[COP0_EPC];
2265 		cpu->delay_slot = 0;
2266 		cpu->cd.mips.coproc[0]->reg[COP0_STATUS] &= ~STATUS_EXL;
2267 	}
2268 
2269 	quick_pc_to_pointers(cpu);
2270 
2271 	cpu->cd.mips.rmw = 0;   /*  the "LL bit"  */
2272 }
2273 
2274 
2275 /*
2276  *  deret: Return from debug (EJTAG) handler
2277  */
X(deret)2278 X(deret)
2279 {
2280 	if (!cop0_availability_check(cpu, ic))
2281 		return;
2282 
2283 	/*
2284 	 *  According to the MIPS64 manual, deret loads PC from the DEPC cop0
2285 	 *  register, and jumps there immediately. No delay slot.
2286 	 *
2287 	 *  TODO: This instruction is only available if the processor is in
2288 	 *  debug mode. (What does that mean?)
2289 	 *
2290 	 *  TODO: This instruction is undefined in a delay slot.
2291 	 */
2292 
2293 	cpu->pc = cpu->cd.mips.coproc[0]->reg[COP0_DEPC];
2294 	cpu->delay_slot = 0;
2295 	cpu->cd.mips.coproc[0]->reg[COP0_STATUS] &= ~STATUS_EXL;
2296 	quick_pc_to_pointers(cpu);
2297 }
2298 
2299 
2300 /*
2301  *  idle:  Called from the implementation of wait, or netbsd_pmax_idle.
2302  */
X(idle)2303 X(idle)
2304 {
2305 	/*
2306 	 *  If there is an interrupt, then just return. Otherwise
2307 	 *  re-run the wait instruction (after a delay).
2308 	 */
2309 	uint32_t status = cpu->cd.mips.coproc[0]->reg[COP0_STATUS];
2310 	uint32_t cause = cpu->cd.mips.coproc[0]->reg[COP0_CAUSE];
2311 
2312 	if (cpu->cd.mips.cpu_type.exc_model != EXC3K) {
2313 		if (status & (STATUS_EXL | STATUS_ERL))
2314 			status &= ~STATUS_IE;
2315 	}
2316 
2317 	/*  Ugly R5900 special case:  (TODO: move this?)  */
2318 	if (cpu->cd.mips.cpu_type.rev == MIPS_R5900 &&
2319 	    !(status & R5900_STATUS_EIE))
2320 		status &= ~STATUS_IE;
2321 	if (status & STATUS_IE && (status & cause & STATUS_IM_MASK))
2322 		return;
2323 
2324 	cpu->cd.mips.next_ic = ic;
2325 	cpu->is_halted = 1;
2326 	cpu->has_been_idling = 1;
2327 
2328 	/*
2329 	 *  There was no interrupt. Go to sleep.
2330 	 *
2331 	 *  TODO:
2332 	 *
2333 	 *  Think about how to actually implement this usleep stuff,
2334 	 *  in an SMP and/or timing accurate environment.
2335 	 */
2336 
2337 	if (cpu->machine->ncpus == 1) {
2338 		static int x = 0;
2339 
2340 		if ((++x) == 300) {
2341 			usleep(20);
2342 			x = 0;
2343 		}
2344 
2345 		cpu->n_translated_instrs += N_SAFE_DYNTRANS_LIMIT / 6;
2346 	}
2347 }
2348 
2349 
2350 /*
2351  *  wait: Wait for external interrupt.
2352  */
X(wait)2353 X(wait)
2354 {
2355 	if (!cop0_availability_check(cpu, ic))
2356 		return;
2357 
2358 	instr(idle)(cpu, ic);
2359 }
2360 
2361 
2362 /*
2363  *  rdhwr: Read CPUNum hardware register into gpr (MIPS32/64 rev 2).
2364  *
2365  *  arg[0] = ptr to rt (destination register)
2366  */
X(rdhwr_cpunum)2367 X(rdhwr_cpunum)
2368 {
2369 	reg(ic->arg[0]) = cpu->cpu_id;
2370 }
2371 
2372 
2373 /*
2374  *  rdhwr: Read CC (cycle count) register into gpr (MIPS32/64 rev 2).
2375  *
2376  *  arg[0] = ptr to rt (destination register)
2377  */
X(rdhwr_cc)2378 X(rdhwr_cc)
2379 {
2380 	reg(ic->arg[0]) = cpu->cd.mips.coproc[0]->reg[COP0_COUNT];
2381 }
2382 
2383 
2384 #include "tmp_mips_loadstore.cc"
2385 
2386 
2387 /*
2388  *  Load linked / store conditional:
2389  *
2390  *  A Load-linked instruction initiates a RMW (read-modify-write) sequence.
2391  *  COP0_LLADDR is updated for diagnostic purposes, except for CPUs in the
2392  *  R10000 family.
2393  *
2394  *  A Store-conditional instruction ends the sequence.
2395  *
2396  *  arg[0] = ptr to rt
2397  *  arg[1] = ptr to rs
2398  *  arg[2] = int32_t imm
2399  */
X(ll)2400 X(ll)
2401 {
2402 	MODE_int_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
2403 	int low_pc;
2404 	uint8_t word[sizeof(uint32_t)];
2405 
2406 	/*  Synch. PC and load using slow memory_rw():  */
2407 	low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
2408 	    / sizeof(struct mips_instr_call);
2409 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
2410 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
2411 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
2412 
2413 	if (addr & (sizeof(word)-1)) {
2414 		fatal("TODO: load linked unaligned access: exception\n");
2415 		exit(1);
2416 	}
2417 
2418 	if (!cpu->memory_rw(cpu, cpu->mem, addr, word,
2419 	    sizeof(word), MEM_READ, CACHE_DATA)) {
2420 		/*  An exception occurred.  */
2421 		return;
2422 	}
2423 
2424 	cpu->cd.mips.rmw = 1;
2425 	cpu->cd.mips.rmw_addr = addr;
2426 	cpu->cd.mips.rmw_len = sizeof(word);
2427 	if (cpu->cd.mips.cpu_type.exc_model != MMU10K)
2428 		cpu->cd.mips.coproc[0]->reg[COP0_LLADDR] =
2429 		    (addr >> 4) & 0xffffffffULL;
2430 
2431 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
2432 		reg(ic->arg[0]) = (int32_t) (word[0] + (word[1] << 8)
2433 		    + (word[2] << 16) + (word[3] << 24));
2434 	else
2435 		reg(ic->arg[0]) = (int32_t) (word[3] + (word[2] << 8)
2436 		    + (word[1] << 16) + (word[0] << 24));
2437 }
X(lld)2438 X(lld)
2439 {
2440 	MODE_int_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
2441 	int low_pc;
2442 	uint8_t word[sizeof(uint64_t)];
2443 
2444 	/*  Synch. PC and load using slow memory_rw():  */
2445 	low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
2446 	    / sizeof(struct mips_instr_call);
2447 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
2448 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
2449 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
2450 
2451 	if (addr & (sizeof(word)-1)) {
2452 		fatal("TODO: load linked unaligned access: exception\n");
2453 		exit(1);
2454 	}
2455 
2456 	if (!cpu->memory_rw(cpu, cpu->mem, addr, word,
2457 	    sizeof(word), MEM_READ, CACHE_DATA)) {
2458 		/*  An exception occurred.  */
2459 		return;
2460 	}
2461 
2462 	cpu->cd.mips.rmw = 1;
2463 	cpu->cd.mips.rmw_addr = addr;
2464 	cpu->cd.mips.rmw_len = sizeof(word);
2465 	if (cpu->cd.mips.cpu_type.exc_model != MMU10K)
2466 		cpu->cd.mips.coproc[0]->reg[COP0_LLADDR] =
2467 		    (addr >> 4) & 0xffffffffULL;
2468 
2469 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
2470 		reg(ic->arg[0]) = word[0] + (word[1] << 8)
2471 		    + (word[2] << 16) + ((uint64_t)word[3] << 24) +
2472 		    + ((uint64_t)word[4] << 32) + ((uint64_t)word[5] << 40)
2473 		    + ((uint64_t)word[6] << 48) + ((uint64_t)word[7] << 56);
2474 	else
2475 		reg(ic->arg[0]) = word[7] + (word[6] << 8)
2476 		    + (word[5] << 16) + ((uint64_t)word[4] << 24) +
2477 		    + ((uint64_t)word[3] << 32) + ((uint64_t)word[2] << 40)
2478 		    + ((uint64_t)word[1] << 48) + ((uint64_t)word[0] << 56);
2479 }
X(sc)2480 X(sc)
2481 {
2482 	MODE_int_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
2483 	uint64_t r = reg(ic->arg[0]);
2484 	int low_pc, i;
2485 	uint8_t word[sizeof(uint32_t)];
2486 
2487 	/*  Synch. PC and store using slow memory_rw():  */
2488 	low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
2489 	    / sizeof(struct mips_instr_call);
2490 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
2491 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
2492 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
2493 
2494 	if (addr & (sizeof(word)-1)) {
2495 		fatal("TODO: sc unaligned access: exception\n");
2496 		exit(1);
2497 	}
2498 
2499 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
2500 		word[0]=r; word[1]=r>>8; word[2]=r>>16; word[3]=r>>24;
2501 	} else {
2502 		word[3]=r; word[2]=r>>8; word[1]=r>>16; word[0]=r>>24;
2503 	}
2504 
2505 	/*  If rmw is 0, then the store failed.  (This cache-line was written
2506 	    to by someone else.)  */
2507 	if (cpu->cd.mips.rmw == 0 || (MODE_int_t)cpu->cd.mips.rmw_addr != addr
2508 	    || cpu->cd.mips.rmw_len != sizeof(word)) {
2509 		reg(ic->arg[0]) = 0;
2510 		cpu->cd.mips.rmw = 0;
2511 		return;
2512 	}
2513 
2514 	if (!cpu->memory_rw(cpu, cpu->mem, addr, word,
2515 	    sizeof(word), MEM_WRITE, CACHE_DATA)) {
2516 		/*  An exception occurred.  */
2517 		return;
2518 	}
2519 
2520 	/*  We succeeded. Let's invalidate everybody else's store to this
2521 	    cache line:  */
2522 	for (i=0; i<cpu->machine->ncpus; i++) {
2523 		if (cpu->machine->cpus[i]->cd.mips.rmw) {
2524 			uint64_t yaddr = addr, xaddr = cpu->machine->cpus[i]->
2525 			    cd.mips.rmw_addr;
2526 			uint64_t mask = ~(cpu->machine->cpus[i]->
2527 			    cd.mips.cache_linesize[CACHE_DATA] - 1);
2528 			xaddr &= mask;
2529 			yaddr &= mask;
2530 			if (xaddr == yaddr)
2531 				cpu->machine->cpus[i]->cd.mips.rmw = 0;
2532 		}
2533 	}
2534 
2535 	reg(ic->arg[0]) = 1;
2536 	cpu->cd.mips.rmw = 0;
2537 }
X(scd)2538 X(scd)
2539 {
2540 	MODE_int_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
2541 	uint64_t r = reg(ic->arg[0]);
2542 	int low_pc, i;
2543 	uint8_t word[sizeof(uint64_t)];
2544 
2545 	/*  Synch. PC and store using slow memory_rw():  */
2546 	low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
2547 	    / sizeof(struct mips_instr_call);
2548 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
2549 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
2550 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
2551 
2552 	if (addr & (sizeof(word)-1)) {
2553 		fatal("TODO: sc unaligned access: exception\n");
2554 		exit(1);
2555 	}
2556 
2557 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
2558 		word[0]=r;     word[1]=r>>8; word[2]=r>>16; word[3]=r>>24;
2559 		word[4]=r>>32; word[5]=r>>40; word[6]=r>>48; word[7]=r>>56;
2560 	} else {
2561 		word[7]=r;     word[6]=r>>8; word[5]=r>>16; word[4]=r>>24;
2562 		word[3]=r>>32; word[2]=r>>40; word[1]=r>>48; word[0]=r>>56;
2563 	}
2564 
2565 	/*  If rmw is 0, then the store failed.  (This cache-line was written
2566 	    to by someone else.)  */
2567 	if (cpu->cd.mips.rmw == 0 || (MODE_int_t)cpu->cd.mips.rmw_addr != addr
2568 	    || cpu->cd.mips.rmw_len != sizeof(word)) {
2569 		reg(ic->arg[0]) = 0;
2570 		cpu->cd.mips.rmw = 0;
2571 		return;
2572 	}
2573 
2574 	if (!cpu->memory_rw(cpu, cpu->mem, addr, word,
2575 	    sizeof(word), MEM_WRITE, CACHE_DATA)) {
2576 		/*  An exception occurred.  */
2577 		return;
2578 	}
2579 
2580 	/*  We succeeded. Let's invalidate everybody else's store to this
2581 	    cache line:  */
2582 	for (i=0; i<cpu->machine->ncpus; i++) {
2583 		if (cpu->machine->cpus[i]->cd.mips.rmw) {
2584 			uint64_t yaddr = addr, xaddr = cpu->machine->cpus[i]->
2585 			    cd.mips.rmw_addr;
2586 			uint64_t mask = ~(cpu->machine->cpus[i]->
2587 			    cd.mips.cache_linesize[CACHE_DATA] - 1);
2588 			xaddr &= mask;
2589 			yaddr &= mask;
2590 			if (xaddr == yaddr)
2591 				cpu->machine->cpus[i]->cd.mips.rmw = 0;
2592 		}
2593 	}
2594 
2595 	reg(ic->arg[0]) = 1;
2596 	cpu->cd.mips.rmw = 0;
2597 }
2598 
2599 
2600 /*
2601  *  lwc1, swc1:  Coprocessor 1 load/store (32-bit)
2602  *  ldc1, sdc1:  Coprocessor 1 load/store (64-bit)
2603  *
2604  *  arg[0] = ptr to coprocessor register
2605  *  arg[1] = ptr to rs (base pointer register)
2606  *  arg[2] = int32_t imm
2607  */
X(lwc1)2608 X(lwc1)
2609 {
2610 	COPROC_AVAILABILITY_CHECK(1);
2611 
2612 #ifdef MODE32
2613 	mips32_loadstore
2614 #else
2615 	mips_loadstore
2616 #endif
2617 	    [ (cpu->byte_order == EMUL_LITTLE_ENDIAN? 0 : 16) + 2 * 2 + 1]
2618 	    (cpu, ic);
2619 }
X(swc1)2620 X(swc1)
2621 {
2622 	COPROC_AVAILABILITY_CHECK(1);
2623 
2624 #ifdef MODE32
2625 	mips32_loadstore
2626 #else
2627 	mips_loadstore
2628 #endif
2629 	    [ (cpu->byte_order == EMUL_LITTLE_ENDIAN? 0 : 16) + 8 + 2 * 2]
2630 	    (cpu, ic);
2631 }
X(ldc1)2632 X(ldc1)
2633 {
2634 	int use_fp_pairs =
2635 	    !(cpu->cd.mips.coproc[0]->reg[COP0_STATUS] & STATUS_FR);
2636 	uint64_t fpr, *backup_ptr;
2637 
2638 	COPROC_AVAILABILITY_CHECK(1);
2639 
2640 	backup_ptr = (uint64_t *) ic->arg[0];
2641 	ic->arg[0] = (size_t) &fpr;
2642 
2643 #ifdef MODE32
2644 	mips32_loadstore
2645 #else
2646 	mips_loadstore
2647 #endif
2648 	    [ (cpu->byte_order == EMUL_LITTLE_ENDIAN? 0 : 16) + 3 * 2 + 1]
2649 	    (cpu, ic);
2650 
2651 	if (use_fp_pairs) {
2652 		backup_ptr[0] = (int64_t)(int32_t) fpr;
2653 		backup_ptr[1] = (int64_t)(int32_t) (fpr >> 32);
2654 	} else {
2655 		*backup_ptr = fpr;
2656 	}
2657 
2658 	ic->arg[0] = (size_t) backup_ptr;
2659 }
X(sdc1)2660 X(sdc1)
2661 {
2662 	int use_fp_pairs =
2663 	    !(cpu->cd.mips.coproc[0]->reg[COP0_STATUS] & STATUS_FR);
2664 	uint64_t fpr, *backup_ptr;
2665 
2666 	COPROC_AVAILABILITY_CHECK(1);
2667 
2668 	backup_ptr = (uint64_t *) ic->arg[0];
2669 	ic->arg[0] = (size_t) &fpr;
2670 
2671 	if (use_fp_pairs) {
2672 		uint32_t lo = backup_ptr[0];
2673 		uint32_t hi = backup_ptr[1];
2674 		fpr = (((uint64_t)hi) << 32) | lo;
2675 	} else {
2676 		fpr = *backup_ptr;
2677 	}
2678 
2679 #ifdef MODE32
2680 	mips32_loadstore
2681 #else
2682 	mips_loadstore
2683 #endif
2684 	    [ (cpu->byte_order == EMUL_LITTLE_ENDIAN? 0 : 16) + 8 + 3 * 2]
2685 	    (cpu, ic);
2686 
2687 	ic->arg[0] = (size_t) backup_ptr;
2688 }
2689 
2690 
2691 /*
2692  *  Unaligned loads/stores:
2693  *
2694  *  arg[0] = ptr to rt
2695  *  arg[1] = ptr to rs
2696  *  arg[2] = int32_t imm
2697  */
X(lwl)2698 X(lwl) { mips_unaligned_loadstore(cpu, ic, 1, sizeof(uint32_t), 0); }
X(lwr)2699 X(lwr) { mips_unaligned_loadstore(cpu, ic, 0, sizeof(uint32_t), 0); }
X(ldl)2700 X(ldl) { mips_unaligned_loadstore(cpu, ic, 1, sizeof(uint64_t), 0); }
X(ldr)2701 X(ldr) { mips_unaligned_loadstore(cpu, ic, 0, sizeof(uint64_t), 0); }
X(swl)2702 X(swl) { mips_unaligned_loadstore(cpu, ic, 1, sizeof(uint32_t), 1); }
X(swr)2703 X(swr) { mips_unaligned_loadstore(cpu, ic, 0, sizeof(uint32_t), 1); }
X(sdl)2704 X(sdl) { mips_unaligned_loadstore(cpu, ic, 1, sizeof(uint64_t), 1); }
X(sdr)2705 X(sdr) { mips_unaligned_loadstore(cpu, ic, 0, sizeof(uint64_t), 1); }
2706 
2707 
2708 /*
2709  *  di, ei: R5900 interrupt enable/disable.
2710  *
2711  *  TODO: check the R5900_STATUS_EDI bit in the status register. If it is
2712  *  cleared, and we are not running in kernel mode, then both the EI and DI
2713  *  instructions should be treated as NOPs!
2714  */
X(di_r5900)2715 X(di_r5900)
2716 {
2717 	if (!cop0_availability_check(cpu, ic))
2718 		return;
2719 
2720 	cpu->cd.mips.coproc[0]->reg[COP0_STATUS] &= ~R5900_STATUS_EIE;
2721 }
X(ei_r5900)2722 X(ei_r5900)
2723 {
2724 	if (!cop0_availability_check(cpu, ic))
2725 		return;
2726 
2727 	cpu->cd.mips.coproc[0]->reg[COP0_STATUS] |= R5900_STATUS_EIE;
2728 }
2729 
2730 
2731 /*****************************************************************************/
2732 
2733 
2734 /*
2735  *  memset_addiu_bne_sw:
2736  *
2737  *  s:	addiu	rX,rX,4			rX = arg[0] and arg[1]
2738  *	bne	rY,rX,s  (or rX,rY,s)	rt=arg[1], rs=arg[0]
2739  *	sw	rZ,-4(rX)		rt=arg[0], rs=arg[1]
2740  */
X(memset_addiu_bne_sw)2741 X(memset_addiu_bne_sw)
2742 {
2743 	MODE_uint_t rX = reg(ic->arg[0]), rZ = reg(ic[2].arg[0]);
2744 	uint64_t *rYp = (uint64_t *) ic[1].arg[0];
2745 	MODE_uint_t rY, bytes_to_write;
2746 	unsigned char *page;
2747 	int partial = 0;
2748 
2749 #ifdef MODE32
2750 	page = cpu->cd.mips.host_store[rX >> 12];
2751 #else
2752 	{
2753 		const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
2754 		const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
2755 		const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
2756 		uint32_t x1 = (rX >> (64-DYNTRANS_L1N)) & mask1;
2757 		uint32_t x2 = (rX >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
2758 		uint32_t x3 = (rX >> (64-DYNTRANS_L1N-DYNTRANS_L2N-DYNTRANS_L3N)) & mask3;
2759 		struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.mips.l1_64[x1];
2760 		struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
2761 		page = l3->host_store[x3];
2762 	}
2763 #endif
2764 
2765 	/*  Fallback:  */
2766 	if (cpu->delay_slot || page == NULL || (rX & 3) != 0 || rZ != 0) {
2767 		instr(addiu)(cpu, ic);
2768 		return;
2769 	}
2770 
2771 	if (rYp == (uint64_t *) ic->arg[0])
2772 		rYp = (uint64_t *) ic[1].arg[1];
2773 
2774 	rY = reg(rYp);
2775 
2776 	bytes_to_write = rY - rX;
2777 	if ((rX & 0xfff) + bytes_to_write > 0x1000) {
2778 		bytes_to_write = 0x1000 - (rX & 0xfff);
2779 		partial = 1;
2780 	}
2781 
2782 	/*  printf("rX = %08x\n", (int)rX);
2783 	    printf("rY = %08x\n", (int)rY);
2784 	    printf("rZ = %08x\n", (int)rZ);
2785 	    printf("%i bytes\n", (int)bytes_to_write);  */
2786 
2787 	memset(page + (rX & 0xfff), 0, bytes_to_write);
2788 
2789 	reg(ic->arg[0]) = rX + bytes_to_write;
2790 
2791 	cpu->n_translated_instrs += bytes_to_write / 4 * 3 - 1;
2792 	cpu->cd.mips.next_ic = partial?
2793 	    (struct mips_instr_call *) &ic[0] :
2794 	    (struct mips_instr_call *) &ic[3];
2795 }
2796 
2797 
2798 /*  multi_{l,s}w_2, _3, etc.  */
2799 #include "tmp_mips_loadstore_multi.cc"
2800 
2801 
2802 /*
2803  *  multi_addu_3:
2804  */
X(multi_addu_3)2805 X(multi_addu_3)
2806 {
2807 	/*  Fallback:  */
2808 	if (cpu->delay_slot) {
2809 		instr(addu)(cpu, ic);
2810 		return;
2811 	}
2812 
2813 	reg(ic[0].arg[2]) = (int32_t)(reg(ic[0].arg[0]) + reg(ic[0].arg[1]));
2814 	reg(ic[1].arg[2]) = (int32_t)(reg(ic[1].arg[0]) + reg(ic[1].arg[1]));
2815 	reg(ic[2].arg[2]) = (int32_t)(reg(ic[2].arg[0]) + reg(ic[2].arg[1]));
2816 	cpu->n_translated_instrs += 2;
2817 	cpu->cd.mips.next_ic = ic + 3;
2818 }
2819 
2820 
2821 /*
2822  *  netbsd_r3k_picache_do_inv:
2823  *
2824  *  ic[0]	mtc0	rV,status
2825  *     1	nop
2826  *     2	nop
2827  *     3  s:	addiu	rX,rX,4
2828  *     4	bne	rY,rX,s
2829  *     5	sb	zr,-4(rX)
2830  *     6	nop
2831  *     7	nop
2832  *     8	mtc0	rT,status
2833  */
X(netbsd_r3k_picache_do_inv)2834 X(netbsd_r3k_picache_do_inv)
2835 {
2836 	MODE_uint_t rx = reg(ic[3].arg[0]), ry = reg(ic[4].arg[1]);
2837 
2838 	/*  Fallback if the environment isn't exactly right:  */
2839 	if (!(reg(ic[0].arg[0]) & MIPS1_ISOL_CACHES) ||
2840 	    (rx & 3) || (ry & 3) || cpu->delay_slot) {
2841 		instr(mtc0)(cpu, ic);
2842 		return;
2843         }
2844 
2845 	reg(ic[3].arg[0]) = ry;
2846 	cpu->n_translated_instrs += (ry - rx + 4) / 4 * 3 + 4;
2847 
2848 	/*  Run the last mtc0 instruction:  */
2849 	cpu->cd.mips.next_ic = ic + 8;
2850 }
2851 
2852 
2853 #ifdef MODE32
2854 /*
2855  *  netbsd_pmax_idle():
2856  *
2857  *  s:  lui     rX, hi
2858  *      lw      rY, lo(rX)
2859  *      nop
2860  *      beq     zr, rY, s
2861  *      nop
2862  */
X(netbsd_pmax_idle)2863 X(netbsd_pmax_idle)
2864 {
2865 	uint32_t addr, pageindex, i;
2866 	int32_t *page;
2867 
2868 	reg(ic[0].arg[0]) = (int32_t)ic[0].arg[1];
2869 
2870 	addr = reg(ic[0].arg[0]) + (int32_t)ic[1].arg[2];
2871 	pageindex = addr >> 12;
2872 	i = (addr & 0xfff) >> 2;
2873 	page = (int32_t *) cpu->cd.mips.host_load[pageindex];
2874 
2875 	/*  Fallback:  */
2876 	if (cpu->delay_slot || page == NULL || page[i] != 0)
2877 		return;
2878 
2879 	instr(idle)(cpu, ic);
2880 }
2881 
2882 
2883 /*
2884  *  linux_pmax_idle():
2885  *
2886  *  s:  lui     rX, hi
2887  *      lw      rX, lo(rX)
2888  *      nop
2889  *      bne     zr, rX, ...
2890  *      nop
2891  *      lw      rX, ofs(gp)
2892  *      nop
2893  *      beq     zr, rX, s
2894  *      nop
2895  */
X(linux_pmax_idle)2896 X(linux_pmax_idle)
2897 {
2898 	uint32_t addr, addr2, pageindex, pageindex2, i, i2;
2899 	int32_t *page, *page2;
2900 
2901 	reg(ic[0].arg[0]) = (int32_t)ic[0].arg[1];
2902 
2903 	addr = reg(ic[0].arg[0]) + (int32_t)ic[1].arg[2];
2904 	pageindex = addr >> 12;
2905 	i = (addr & 0xfff) >> 2;
2906 	page = (int32_t *) cpu->cd.mips.host_load[pageindex];
2907 
2908 	addr2 = reg(ic[5].arg[1]) + (int32_t)ic[5].arg[2];
2909 	pageindex2 = addr2 >> 12;
2910 	i2 = (addr2 & 0xfff) >> 2;
2911 	page2 = (int32_t *) cpu->cd.mips.host_load[pageindex2];
2912 
2913 	/*  Fallback:  */
2914 	if (cpu->delay_slot || page == NULL || page[i] != 0 || page2[i2] != 0)
2915 		return;
2916 
2917 	instr(idle)(cpu, ic);
2918 }
2919 #endif
2920 
2921 
2922 /*
2923  *  strlen_lb_addiu_bne_nop():
2924  *
2925  *  Used by some versions of NetBSD.
2926  *
2927  *  s:	lb      rV,0(rX)	(lb = signed, lbu = unsigned)
2928  *	addiu   rX,rX,1
2929  *	bne	zr,rV,s
2930  *	nop
2931  */
X(strlen_lb_addiu_bne_nop)2932 X(strlen_lb_addiu_bne_nop)
2933 {
2934 	MODE_uint_t rx = reg(ic[0].arg[1]);
2935 	MODE_int_t rv;
2936 	signed char *page;
2937 	int i;
2938 
2939 #ifdef MODE32
2940 	page = (signed char *) cpu->cd.mips.host_load[rx >> 12];
2941 #else
2942 	{
2943 		const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
2944 		const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
2945 		const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
2946 		uint32_t x1 = (rx >> (64-DYNTRANS_L1N)) & mask1;
2947 		uint32_t x2 = (rx >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
2948 		uint32_t x3 = (rx >> (64-DYNTRANS_L1N-DYNTRANS_L2N-DYNTRANS_L3N)) & mask3;
2949 		struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.mips.l1_64[x1];
2950 		struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
2951 		page = (signed char *) l3->host_load[x3];
2952 	}
2953 #endif
2954 
2955 	/*
2956 	 *  Fallback:
2957 	 *
2958 	 *  If the first instruction (the lb/lbu) is in the delay slot of a
2959 	 *  branch instruction, we bail out.
2960 	 *
2961 	 *  Also, if the page for the strlen string to measure is not in the
2962 	 *  fast host_load arrays, we bail out and let the normal lb/lbu
2963 	 *  implementation handle it (and if the string is long enough, we
2964 	 *  will get back into this instruction combination code anyway).
2965 	 *
2966 	 *  The reason why we can run a fixed load instruction as the fall-
2967 	 *  back (say, signed lb) rather than checking whether to run lb or
2968 	 *  lbu, is as follows:
2969 	 *
2970 	 *  If the loaded byte is 0x00, we break out of the strlen loop. This
2971 	 *  value would be the same regardless of whether lb or lbu is used.
2972 	 *
2973 	 *  If the loaded byte is not 0x00, say, 0x8a, it does not matter
2974 	 *  whether the loaded rV value is 0xffffffffffffff8a or
2975 	 *  0x000000000000008a. The only way to get out of the strlen loop is
2976 	 *  to read rV as 0x00, _except_ for CPU exceptions (either interrupts
2977 	 *  or page-fault exceptions). But it is extremely unlikely that any
2978 	 *  exception handling code in any guest OS would do anything other
2979 	 *  than preserve rV (whatever its value is) and restore it when the
2980 	 *  exception handling is done. So this discrepancy should be ok.
2981 	 */
2982 	if (cpu->delay_slot || page == NULL) {
2983 #ifdef MODE32
2984 		mips32_loadstore[1](cpu, ic);
2985 #else
2986 		mips_loadstore[1](cpu, ic);
2987 #endif
2988 		return;
2989 	}
2990 
2991 	i = rx & 0xfff;
2992 
2993 	/*
2994 	 *  TODO: This loop can be optimized further for optimal
2995 	 *  performance on the host, e.g. by reading full words...
2996 	 */
2997 	do {
2998 		rv = page[i ++];
2999 	} while (i < 0x1000 && rv != 0);
3000 
3001 	cpu->n_translated_instrs += (i - (rx & 0xfff)) * 4 - 1;
3002 
3003 	reg(ic[0].arg[1]) = (rx & ~0xfff) + i;
3004 	reg(ic[2].arg[0]) = rv;
3005 
3006 	/*  Done with the loop? Or continue on the next rx page?  */
3007 	if (rv == 0)
3008 		cpu->cd.mips.next_ic = ic + 4;
3009 	else
3010 		cpu->cd.mips.next_ic = ic;
3011 }
3012 
3013 
3014 /*
3015  *  addiu_bne_samepage_addiu:
3016  */
X(addiu_bne_samepage_addiu)3017 X(addiu_bne_samepage_addiu)
3018 {
3019 	MODE_uint_t rs, rt;
3020 
3021 	if (cpu->delay_slot) {
3022 		instr(addiu)(cpu, ic);
3023 		return;
3024 	}
3025 
3026 	cpu->n_translated_instrs += 2;
3027 	reg(ic[0].arg[1]) = (int32_t)
3028 	    ((int32_t)reg(ic[0].arg[0]) + (int32_t)ic[0].arg[2]);
3029 	rs = reg(ic[1].arg[0]);
3030 	rt = reg(ic[1].arg[1]);
3031 	reg(ic[2].arg[1]) = (int32_t)
3032 	    ((int32_t)reg(ic[2].arg[0]) + (int32_t)ic[2].arg[2]);
3033 	if (rs != rt)
3034 		cpu->cd.mips.next_ic = (struct mips_instr_call *) ic[1].arg[2];
3035 	else
3036 		cpu->cd.mips.next_ic = ic + 3;
3037 }
3038 
3039 
3040 /*
3041  *  xor_andi_sll:
3042  */
X(xor_andi_sll)3043 X(xor_andi_sll)
3044 {
3045 	/*  Fallback:  */
3046 	if (cpu->delay_slot) {
3047 		instr(xor)(cpu, ic);
3048 		return;
3049 	}
3050 
3051 	reg(ic[0].arg[2]) = reg(ic[0].arg[0]) ^ reg(ic[0].arg[1]);
3052 	reg(ic[1].arg[1]) = reg(ic[1].arg[0]) & (uint32_t)ic[1].arg[2];
3053 	reg(ic[2].arg[2]) = (int32_t)(reg(ic[2].arg[0])<<(int32_t)ic[2].arg[1]);
3054 
3055 	cpu->n_translated_instrs += 2;
3056 	cpu->cd.mips.next_ic = ic + 3;
3057 }
3058 
3059 
3060 /*
3061  *  andi_sll:
3062  */
X(andi_sll)3063 X(andi_sll)
3064 {
3065 	/*  Fallback:  */
3066 	if (cpu->delay_slot) {
3067 		instr(andi)(cpu, ic);
3068 		return;
3069 	}
3070 
3071 	reg(ic[0].arg[1]) = reg(ic[0].arg[0]) & (uint32_t)ic[0].arg[2];
3072 	reg(ic[1].arg[2]) = (int32_t)(reg(ic[1].arg[0])<<(int32_t)ic[1].arg[1]);
3073 
3074 	cpu->n_translated_instrs ++;
3075 	cpu->cd.mips.next_ic = ic + 2;
3076 }
3077 
3078 
3079 /*
3080  *  lui_ori:
3081  */
X(lui_ori)3082 X(lui_ori)
3083 {
3084 	/*  Fallback:  */
3085 	if (cpu->delay_slot) {
3086 		instr(set)(cpu, ic);
3087 		return;
3088 	}
3089 
3090 	reg(ic[0].arg[0]) = (int32_t)ic[0].arg[1];
3091 	reg(ic[1].arg[1]) = reg(ic[1].arg[0]) | (uint32_t)ic[1].arg[2];
3092 
3093 	cpu->n_translated_instrs ++;
3094 	cpu->cd.mips.next_ic = ic + 2;
3095 }
3096 
3097 
3098 /*
3099  *  lui_addiu:
3100  */
X(lui_addiu)3101 X(lui_addiu)
3102 {
3103 	/*  Fallback:  */
3104 	if (cpu->delay_slot) {
3105 		instr(set)(cpu, ic);
3106 		return;
3107 	}
3108 
3109 	reg(ic[0].arg[0]) = (int32_t)ic[0].arg[1];
3110 	reg(ic[1].arg[1]) = (int32_t)
3111 	    ((int32_t)reg(ic[1].arg[0]) + (int32_t)ic[1].arg[2]);
3112 
3113 	cpu->n_translated_instrs ++;
3114 	cpu->cd.mips.next_ic = ic + 2;
3115 }
3116 
3117 
3118 /*
3119  *  b_samepage_addiu:
3120  *
3121  *  Combination of branch within the same page, followed by addiu.
3122  */
X(b_samepage_addiu)3123 X(b_samepage_addiu)
3124 {
3125 	reg(ic[1].arg[1]) = (int32_t)
3126 	    ( (int32_t)reg(ic[1].arg[0]) + (int32_t)ic[1].arg[2] );
3127 	cpu->n_translated_instrs ++;
3128 	cpu->cd.mips.next_ic = (struct mips_instr_call *) ic->arg[2];
3129 }
3130 
3131 
3132 /*
3133  *  b_samepage_daddiu:
3134  *
3135  *  Combination of branch within the same page, followed by daddiu.
3136  */
X(b_samepage_daddiu)3137 X(b_samepage_daddiu)
3138 {
3139 	*(uint64_t *)ic[1].arg[1] = *(uint64_t *)ic[1].arg[0] +
3140 	    (int32_t)ic[1].arg[2];
3141 	cpu->n_translated_instrs ++;
3142 	cpu->cd.mips.next_ic = (struct mips_instr_call *) ic->arg[2];
3143 }
3144 
3145 
3146 /*****************************************************************************/
3147 
3148 
X(end_of_page)3149 X(end_of_page)
3150 {
3151 	/*  Update the PC:  (offset 0, but on the next page)  */
3152 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
3153 	    MIPS_INSTR_ALIGNMENT_SHIFT);
3154 	cpu->pc += (MIPS_IC_ENTRIES_PER_PAGE << MIPS_INSTR_ALIGNMENT_SHIFT);
3155 
3156 	/*  end_of_page doesn't count as an executed instruction:  */
3157 	cpu->n_translated_instrs --;
3158 
3159 	/*
3160 	 *  Find the new physpage and update translation pointers.
3161 	 *
3162 	 *  Note: This may cause an exception, if e.g. the new page is
3163 	 *  not accessible.
3164 	 */
3165 	quick_pc_to_pointers(cpu);
3166 
3167 	/*  Simple jump to the next page (if we are lucky):  */
3168 	if (cpu->delay_slot == NOT_DELAYED)
3169 		return;
3170 
3171 	/*
3172 	 *  If we were in a delay slot, and we got an exception while doing
3173 	 *  quick_pc_to_pointers, then return. The function which called
3174 	 *  end_of_page should handle this case.
3175 	 */
3176 	if (cpu->delay_slot == EXCEPTION_IN_DELAY_SLOT)
3177 		return;
3178 
3179 	/*
3180 	 *  Tricky situation; the delay slot is on the next virtual page.
3181 	 *  Calling to_be_translated will translate one instruction manually,
3182 	 *  execute it, and then discard it.
3183 	 */
3184 	/*  fatal("[ end_of_page: delay slot across page boundary! ]\n");  */
3185 
3186 	instr(to_be_translated)(cpu, cpu->cd.mips.next_ic);
3187 
3188 	/*  The instruction in the delay slot has now executed.  */
3189 	/*  fatal("[ end_of_page: back from executing the delay slot, %i ]\n",
3190 	    cpu->delay_slot);  */
3191 
3192 	/*  Find the physpage etc of the instruction in the delay slot
3193 	    (or, if there was an exception, the exception handler):  */
3194 	quick_pc_to_pointers(cpu);
3195 }
3196 
3197 
X(end_of_page2)3198 X(end_of_page2)
3199 {
3200 	/*  Synchronize PC on the _second_ instruction on the next page:  */
3201 	int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
3202 	    / sizeof(struct mips_instr_call);
3203 	cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
3204 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
3205 	cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
3206 
3207 	/*  This doesn't count as an executed instruction.  */
3208 	cpu->n_translated_instrs --;
3209 
3210 	quick_pc_to_pointers(cpu);
3211 
3212 	if (cpu->delay_slot == NOT_DELAYED)
3213 		return;
3214 
3215 	fatal("end_of_page2: fatal error, we're in a delay slot\n");
3216 	exit(1);
3217 }
3218 
3219 
3220 /*****************************************************************************/
3221 
3222 
3223 /*
3224  *  Combine:  Multiple SW in a row using the same base register
3225  *
3226  *	sw	r?,???(rX)
3227  *	sw	r?,???(rX)
3228  *	sw	r?,???(rX)
3229  *	...
3230  *
3231  *  and memset loops, etc.
3232  */
COMBINE(sw)3233 void COMBINE(sw)(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
3234 {
3235 	int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3236 	    & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3237 
3238 	if (n_back < 4)
3239 		return;
3240 
3241 	/*  Convert a multi_sw_4 to a multi_sw_5:  */
3242 	if ((ic[-4].f == instr(multi_sw_4_be) ||
3243 	    ic[-4].f == instr(multi_sw_4_le)) &&
3244 	    ic[-4].arg[1] == ic[0].arg[1]) {
3245 		if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3246 			ic[-4].f = instr(multi_sw_5_le);
3247 		else
3248 			ic[-4].f = instr(multi_sw_5_be);
3249 	}
3250 
3251 	/*  Convert a multi_sw_3 to a multi_sw_4:  */
3252 	if ((ic[-3].f == instr(multi_sw_3_be) ||
3253 	    ic[-3].f == instr(multi_sw_3_le)) &&
3254 	    ic[-3].arg[1] == ic[0].arg[1]) {
3255 		if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3256 			ic[-3].f = instr(multi_sw_4_le);
3257 		else
3258 			ic[-3].f = instr(multi_sw_4_be);
3259 	}
3260 
3261 	/*  Convert a multi_sw_2 to a multi_sw_3:  */
3262 	if ((ic[-2].f == instr(multi_sw_2_be) ||
3263 	    ic[-2].f == instr(multi_sw_2_le)) &&
3264 	    ic[-2].arg[1] == ic[0].arg[1]) {
3265 		if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3266 			ic[-2].f = instr(multi_sw_3_le);
3267 		else
3268 			ic[-2].f = instr(multi_sw_3_be);
3269 	}
3270 
3271 	if (ic[-1].f == ic[0].f && ic[-1].arg[1] == ic[0].arg[1]) {
3272 		if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3273 			ic[-1].f = instr(multi_sw_2_le);
3274 		else
3275 			ic[-1].f = instr(multi_sw_2_be);
3276 	}
3277 
3278 	if (ic[-2].f == instr(addiu) && ic[-2].arg[0] == ic[-2].arg[1] &&
3279 	    (int32_t)ic[-2].arg[2] == 4 &&
3280 	    ic[-1].f == instr(bne_samepage) &&
3281 	    (ic[-1].arg[0] == ic[-2].arg[0] ||
3282 		ic[-1].arg[1] == ic[-2].arg[0]) &&
3283 	    ic[-1].arg[0] != ic[-1].arg[1] &&
3284 	    ic[-1].arg[2] == (size_t) &ic[-2] &&
3285 	    ic[0].arg[0] != ic[0].arg[1] &&
3286 	    ic[0].arg[1] == ic[-2].arg[0] && (int32_t)ic[0].arg[2] == -4) {
3287 		ic[-2].f = instr(memset_addiu_bne_sw);
3288 	}
3289 }
3290 
3291 
3292 /*
3293  *  Combine:  Multiple LW in a row using the same base register
3294  *
3295  *	lw	r?,???(rX)
3296  *	lw	r?,???(rX)
3297  *	lw	r?,???(rX)
3298  *	...
3299  */
COMBINE(lw)3300 void COMBINE(lw)(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
3301 {
3302 	int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3303 	    & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3304 
3305 	if (n_back < 4)
3306 		return;
3307 
3308 	/*  Convert a multi_lw_4 to a multi_lw_5:  */
3309 	if ((ic[-4].f == instr(multi_lw_4_be) ||
3310 	    ic[-4].f == instr(multi_lw_4_le)) &&
3311 	    ic[-4].arg[1] == ic[0].arg[1] &&
3312 	    ic[-1].arg[0] != ic[0].arg[1]) {
3313 		if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3314 			ic[-4].f = instr(multi_lw_5_le);
3315 		else
3316 			ic[-4].f = instr(multi_lw_5_be);
3317 	}
3318 
3319 	/*  Convert a multi_lw_3 to a multi_lw_4:  */
3320 	if ((ic[-3].f == instr(multi_lw_3_be) ||
3321 	    ic[-3].f == instr(multi_lw_3_le)) &&
3322 	    ic[-3].arg[1] == ic[0].arg[1] &&
3323 	    ic[-1].arg[0] != ic[0].arg[1]) {
3324 		if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3325 			ic[-3].f = instr(multi_lw_4_le);
3326 		else
3327 			ic[-3].f = instr(multi_lw_4_be);
3328 	}
3329 
3330 	/*  Convert a multi_lw_2 to a multi_lw_3:  */
3331 	if ((ic[-2].f == instr(multi_lw_2_be) ||
3332 	    ic[-2].f == instr(multi_lw_2_le)) &&
3333 	    ic[-2].arg[1] == ic[0].arg[1] &&
3334 	    ic[-1].arg[0] != ic[0].arg[1]) {
3335 		if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3336 			ic[-2].f = instr(multi_lw_3_le);
3337 		else
3338 			ic[-2].f = instr(multi_lw_3_be);
3339 	}
3340 
3341 	/*  Note: Loads to the base register are not allowed in slot -1.  */
3342 	if (ic[-1].f == ic[0].f &&
3343 	    ic[-1].arg[1] == ic[0].arg[1] &&
3344 	    ic[-1].arg[0] != ic[0].arg[1]) {
3345 		if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3346 			ic[-1].f = instr(multi_lw_2_le);
3347 		else
3348 			ic[-1].f = instr(multi_lw_2_be);
3349 	}
3350 }
3351 
3352 
3353 /*
3354  *  Combine:  NetBSD/pmax 3.0 R2000/R3000 physical cache invalidation loop
3355  *
3356  *  Instruction cache loop:
3357  *
3358  *  ic[-8]	mtc0	rV,status
3359  *     -7	nop
3360  *     -6	nop
3361  *     -5  s:	addiu	rX,rX,4
3362  *     -4	bne	rY,rX,s
3363  *     -3	sb	zr,-4(rX)
3364  *     -2	nop
3365  *     -1	nop
3366  *      0	mtc0	rT,status
3367  */
COMBINE(netbsd_r3k_cache_inv)3368 void COMBINE(netbsd_r3k_cache_inv)(struct cpu *cpu,
3369 	struct mips_instr_call *ic, int low_addr)
3370 {
3371 	int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3372 	    & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3373 
3374 	if (n_back < 8)
3375 		return;
3376 
3377 	if (ic[-8].f == instr(mtc0) && ic[-8].arg[1] == COP0_STATUS &&
3378 	    ic[-7].f == instr(nop) && ic[-6].f == instr(nop) &&
3379 	    ic[-5].f == instr(addiu) && ic[-5].arg[0] == ic[-5].arg[1] &&
3380 	    (int32_t)ic[-5].arg[2] == 4 && ic[-4].f == instr(bne_samepage) &&
3381 	    ic[-4].arg[0] == ic[-5].arg[0] && ic[-4].arg[0] != ic[-4].arg[1] &&
3382 	    ic[-4].arg[2] == (size_t) &ic[-5] &&
3383 	    ic[-3].arg[1] == ic[-5].arg[0] &&
3384 	    ic[-2].f == instr(nop) && ic[-1].f == instr(nop)) {
3385 		ic[-8].f = instr(netbsd_r3k_picache_do_inv);
3386 	}
3387 }
3388 
3389 
3390 /*
3391  *  Combine: something ending with a nop.
3392  *
3393  *	NetBSD's strlen core.
3394  *	[Conditional] branch, followed by nop.
3395  *	NetBSD/pmax' idle loop (and possibly others as well).
3396  *	Linux/pmax' idle loop.
3397  */
COMBINE(nop)3398 void COMBINE(nop)(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
3399 {
3400 	int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3401 	    & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3402 
3403 	if (n_back < 8)
3404 		return;
3405 
3406 #ifdef MODE32
3407 	if (ic[-8].f == instr(set) &&
3408 	    ic[-7].f == mips32_loadstore[4 + 1] &&
3409 	    ic[-7].arg[0] == ic[-1].arg[0] &&
3410 	    ic[-7].arg[0] == ic[-3].arg[0] &&
3411 	    ic[-7].arg[0] == ic[-5].arg[0] &&
3412 	    ic[-7].arg[0] == ic[-7].arg[1] &&
3413 	    ic[-7].arg[0] == ic[-8].arg[0] &&
3414 	    ic[-6].f == instr(nop) &&
3415 	    ic[-5].arg[1] == (size_t) &cpu->cd.mips.gpr[MIPS_GPR_ZERO] &&
3416 	    ic[-5].f == instr(bne_samepage_nop) &&
3417 	    ic[-4].f == instr(nop) &&
3418 	    ic[-3].f == mips32_loadstore[4 + 1] &&
3419 	    ic[-2].f == instr(nop) &&
3420 	    ic[-1].arg[1] == (size_t) &cpu->cd.mips.gpr[MIPS_GPR_ZERO] &&
3421 	    ic[-1].arg[2] == (size_t) &ic[-8] &&
3422 	    ic[-1].f == instr(beq_samepage)) {
3423 		ic[-8].f = instr(linux_pmax_idle);
3424 		return;
3425 	}
3426 
3427 	if (ic[-4].f == instr(set) &&
3428 	    ic[-3].f == mips32_loadstore[4 + 1] &&
3429 	    ic[-3].arg[0] == ic[-1].arg[0] &&
3430 	    ic[-3].arg[1] == ic[-4].arg[0] &&
3431 	    ic[-2].f == instr(nop) &&
3432 	    ic[-1].arg[1] == (size_t) &cpu->cd.mips.gpr[MIPS_GPR_ZERO] &&
3433 	    ic[-1].arg[2] == (size_t) &ic[-4] &&
3434 	    ic[-1].f == instr(beq_samepage)) {
3435 		ic[-4].f = instr(netbsd_pmax_idle);
3436 		return;
3437 	}
3438 
3439 	if ((ic[-3].f == mips32_loadstore[1] || ic[-3].f == mips32_loadstore[1+16]) &&
3440 	    ic[-3].arg[2] == 0 &&
3441 	    ic[-3].arg[0] == ic[-1].arg[0] && ic[-3].arg[1] == ic[-2].arg[0] &&
3442 	    ic[-2].arg[0] == ic[-2].arg[1] && ic[-2].arg[2] == 1 &&
3443 	    ic[-2].f == instr(addiu) && ic[-1].arg[2] == (size_t) &ic[-3] &&
3444 	    ic[-1].arg[1] == (size_t) &cpu->cd.mips.gpr[MIPS_GPR_ZERO] &&
3445 	    ic[-1].f == instr(bne_samepage)) {
3446 		ic[-3].f = instr(strlen_lb_addiu_bne_nop);
3447 		return;
3448 	}
3449 #else
3450 	if ((ic[-3].f == mips_loadstore[1] || ic[-3].f == mips_loadstore[1+16]) &&
3451 	    ic[-3].arg[2] == 0 &&
3452 	    ic[-3].arg[0] == ic[-1].arg[0] && ic[-3].arg[1] == ic[-2].arg[0] &&
3453 	    ic[-2].arg[0] == ic[-2].arg[1] && ic[-2].arg[2] == 1 &&
3454 	    ic[-2].f == instr(addiu) && ic[-1].arg[2] == (size_t) &ic[-3] &&
3455 	    ic[-1].arg[1] == (size_t) &cpu->cd.mips.gpr[MIPS_GPR_ZERO] &&
3456 	    ic[-1].f == instr(bne_samepage)) {
3457 		ic[-3].f = instr(strlen_lb_addiu_bne_nop);
3458 		return;
3459 	}
3460 #endif
3461 
3462 	if (ic[-1].f == instr(bne_samepage)) {
3463 		ic[-1].f = instr(bne_samepage_nop);
3464 		return;
3465 	}
3466 
3467 	if (ic[-1].f == instr(beq_samepage)) {
3468 		ic[-1].f = instr(beq_samepage_nop);
3469 		return;
3470 	}
3471 
3472 	/*  TODO: other branches that are followed by nop should be here  */
3473 }
3474 
3475 
3476 /*
3477  *  Combine:
3478  *
3479  *	xor + andi + sll
3480  *	andi + sll
3481  */
COMBINE(sll)3482 void COMBINE(sll)(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
3483 {
3484 	int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3485 	    & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3486 
3487 	if (n_back < 2)
3488 		return;
3489 
3490 	if (ic[-2].f == instr(xor) && ic[-1].f == instr(andi)) {
3491 		ic[-2].f = instr(xor_andi_sll);
3492 		return;
3493 	}
3494 
3495 	if (ic[-1].f == instr(andi)) {
3496 		ic[-1].f = instr(andi_sll);
3497 		return;
3498 	}
3499 }
3500 
3501 
3502 /*
3503  *  lui + ori
3504  */
COMBINE(ori)3505 void COMBINE(ori)(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
3506 {
3507 	int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3508 	    & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3509 
3510 	if (n_back < 1)
3511 		return;
3512 
3513 	if (ic[-1].f == instr(set)) {
3514 		ic[-1].f = instr(lui_ori);
3515 		return;
3516 	}
3517 }
3518 
3519 
3520 /*
3521  *  addu + addu + addu
3522  */
COMBINE(addu)3523 void COMBINE(addu)(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
3524 {
3525 	int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3526 	    & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3527 
3528 	if (n_back < 4)
3529 		return;
3530 
3531 	/*  Avoid "overlapping" instruction combinations:  */
3532 	if (ic[-4].f == instr(multi_addu_3) ||
3533 	    ic[-3].f == instr(multi_addu_3))
3534 		return;
3535 
3536 	if (ic[-2].f == instr(addu) && ic[-1].f == instr(addu)) {
3537 		ic[-2].f = instr(multi_addu_3);
3538 		return;
3539 	}
3540 }
3541 
3542 
3543 /*
3544  *  Combine:
3545  *
3546  *	[Conditional] branch, followed by addiu.
3547  */
COMBINE(addiu)3548 void COMBINE(addiu)(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
3549 {
3550 	int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3551 	    & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3552 
3553 	if (n_back < 2)
3554 		return;
3555 
3556 	if (ic[-2].f == instr(addiu) &&
3557 	    ic[-1].f == instr(bne_samepage)) {
3558 		ic[-2].f = instr(addiu_bne_samepage_addiu);
3559 		return;
3560 	}
3561 
3562 	if (ic[-1].f == instr(set)) {
3563 		ic[-1].f = instr(lui_addiu);
3564 		return;
3565 	}
3566 
3567 	if (ic[-1].f == instr(b_samepage)) {
3568 		ic[-1].f = instr(b_samepage_addiu);
3569 		return;
3570 	}
3571 
3572 	if (ic[-1].f == instr(beq_samepage)) {
3573 		ic[-1].f = instr(beq_samepage_addiu);
3574 		return;
3575 	}
3576 
3577 	if (ic[-1].f == instr(bne_samepage)) {
3578 		ic[-1].f = instr(bne_samepage_addiu);
3579 		return;
3580 	}
3581 
3582 	if (ic[-1].f == instr(jr_ra)) {
3583 		ic[-1].f = instr(jr_ra_addiu);
3584 		return;
3585 	}
3586 
3587 	/*  TODO: other branches that are followed by addiu should be here  */
3588 }
3589 
3590 
3591 /*
3592  *  Combine: [Conditional] branch, followed by daddiu.
3593  */
COMBINE(b_daddiu)3594 void COMBINE(b_daddiu)(struct cpu *cpu, struct mips_instr_call *ic,
3595 	int low_addr)
3596 {
3597 	int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3598 	    & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3599 
3600 	if (n_back < 1)
3601 		return;
3602 
3603 	if (ic[-1].f == instr(b_samepage)) {
3604 		ic[-1].f = instr(b_samepage_daddiu);
3605 	}
3606 
3607 	/*  TODO: other branches that are followed by daddiu should be here  */
3608 }
3609 
3610 
3611 /*****************************************************************************/
3612 
3613 
3614 /*
3615  *  mips_instr_to_be_translated():
3616  *
3617  *  Translate an instruction word into a mips_instr_call. ic is filled in with
3618  *  valid data for the translated instruction, or a "nothing" instruction if
3619  *  there was a translation failure. The newly translated instruction is then
3620  *  executed.
3621  */
X(to_be_translated)3622 X(to_be_translated)
3623 {
3624 	uint64_t addr, low_pc;
3625 	uint32_t iword, imm;
3626 	unsigned char *page;
3627 	unsigned char ib[4];
3628 	int main_opcode, rt, rs, rd, sa, s6, x64 = 0, s10;
3629 	int in_crosspage_delayslot = 0;
3630 	void (*samepage_function)(struct cpu *, struct mips_instr_call *);
3631 	int store, signedness, size;
3632 
3633 	/*  Figure out the (virtual) address of the instruction:  */
3634 	low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
3635 	    / sizeof(struct mips_instr_call);
3636 
3637 	/*  Special case for branch with delayslot on the next page:  */
3638 	if (cpu->delay_slot == TO_BE_DELAYED && low_pc == 0) {
3639 		/*  fatal("[ delay-slot translation across page "
3640 		    "boundary ]\n");  */
3641 		in_crosspage_delayslot = 1;
3642 	}
3643 
3644 	addr = cpu->pc & ~((MIPS_IC_ENTRIES_PER_PAGE-1)
3645 	    << MIPS_INSTR_ALIGNMENT_SHIFT);
3646 	addr += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
3647 	cpu->pc = (MODE_int_t)addr;
3648 	addr &= ~((1 << MIPS_INSTR_ALIGNMENT_SHIFT) - 1);
3649 
3650 	/*  Read the instruction word from memory:  */
3651 #ifdef MODE32
3652 	page = cpu->cd.mips.host_load[(uint32_t)addr >> 12];
3653 #else
3654 	{
3655 		const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
3656 		const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
3657 		const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
3658 		uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
3659 		uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
3660 		uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
3661 		    DYNTRANS_L3N)) & mask3;
3662 		struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.mips.l1_64[x1];
3663 		struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
3664 		page = l3->host_load[x3];
3665 	}
3666 #endif
3667 
3668 	if (page != NULL) {
3669 		/*  fatal("TRANSLATION HIT!\n");  */
3670 		memcpy(ib, page + (addr & 0xffc), sizeof(ib));
3671 	} else {
3672 		/*  fatal("TRANSLATION MISS!\n");  */
3673 		if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
3674 		    sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
3675 			fatal("to_be_translated(): read failed: TODO\n");
3676 			goto bad;
3677 		}
3678 	}
3679 
3680 	{
3681 		uint32_t *p = (uint32_t *) ib;
3682 		iword = *p;
3683 	}
3684 
3685 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3686 		iword = LE32_TO_HOST(iword);
3687 	else
3688 		iword = BE32_TO_HOST(iword);
3689 
3690 
3691 #define DYNTRANS_TO_BE_TRANSLATED_HEAD
3692 #include "cpu_dyntrans.cc"
3693 #undef  DYNTRANS_TO_BE_TRANSLATED_HEAD
3694 
3695 
3696 	/*
3697 	 *  Translate the instruction:
3698  	 *
3699 	 *  NOTE: _NEVER_ allow writes to the zero register; all instructions
3700 	 *  that use the zero register as their destination should be treated
3701 	 *  as NOPs, except those that access memory (they should use the
3702 	 *  scratch register instead).
3703 	 */
3704 
3705 	main_opcode = iword >> 26;
3706 	rs = (iword >> 21) & 31;
3707 	rt = (iword >> 16) & 31;
3708 	rd = (iword >> 11) & 31;
3709 	sa = (iword >>  6) & 31;
3710 	imm = (int16_t)iword;
3711 	s6 = iword & 63;
3712 	s10 = (rs << 5) | sa;
3713 
3714 	switch (main_opcode) {
3715 
3716 	case HI6_SPECIAL:
3717 		switch (s6) {
3718 
3719 		case SPECIAL_SLL:
3720 		case SPECIAL_SLLV:
3721 		case SPECIAL_SRL:
3722 		case SPECIAL_SRLV:
3723 		case SPECIAL_SRA:
3724 		case SPECIAL_SRAV:
3725 		case SPECIAL_DSRL:
3726 		case SPECIAL_DSRLV:
3727 		case SPECIAL_DSRL32:
3728 		case SPECIAL_DSLL:
3729 		case SPECIAL_DSLLV:
3730 		case SPECIAL_DSLL32:
3731 		case SPECIAL_DSRA:
3732 		case SPECIAL_DSRAV:
3733 		case SPECIAL_DSRA32:
3734 			switch (s6) {
3735 			case SPECIAL_SLL:  ic->f = instr(sll); break;
3736 			case SPECIAL_SLLV: ic->f = instr(sllv); sa = -1; break;
3737 			case SPECIAL_SRL:  ic->f = instr(srl); break;
3738 			case SPECIAL_SRLV: ic->f = instr(srlv); sa = -1; break;
3739 			case SPECIAL_SRA:  ic->f = instr(sra); break;
3740 			case SPECIAL_SRAV: ic->f = instr(srav); sa = -1; break;
3741 			case SPECIAL_DSRL: ic->f = instr(dsrl); x64=1; break;
3742 			case SPECIAL_DSRLV:ic->f = instr(dsrlv);
3743 					   x64 = 1; sa = -1; break;
3744 			case SPECIAL_DSRL32:ic->f= instr(dsrl); x64=1;
3745 					   sa += 32; break;
3746 			case SPECIAL_DSLL: ic->f = instr(dsll); x64=1; break;
3747 			case SPECIAL_DSLLV:ic->f = instr(dsllv);
3748 					   x64 = 1; sa = -1; break;
3749 			case SPECIAL_DSLL32:ic->f= instr(dsll); x64=1;
3750 					   sa += 32; break;
3751 			case SPECIAL_DSRA: ic->f = instr(dsra); x64=1; break;
3752 			case SPECIAL_DSRAV:ic->f = instr(dsrav);
3753 					   x64 = 1; sa = -1; break;
3754 			case SPECIAL_DSRA32:ic->f = instr(dsra); x64=1;
3755 					   sa += 32; break;
3756 			}
3757 
3758 			ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
3759 			if (sa >= 0)
3760 				ic->arg[1] = sa;
3761 			else
3762 				ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
3763 			ic->arg[2] = (size_t)&cpu->cd.mips.gpr[rd];
3764 
3765 			/*  Special checks for MIPS32/64 revision 2 opcodes,
3766 			    such as rotation instructions:  */
3767 			if (sa >= 0 && rs != 0x00) {
3768 				if (cpu->cd.mips.cpu_type.isa_level < 32 ||
3769 				    cpu->cd.mips.cpu_type.isa_revision < 2) {
3770 					static int warning_rotate = 0;
3771 					if (!warning_rotate &&
3772 					    !cpu->translation_readahead) {
3773 						fatal("[ WARNING! MIPS32/64 "
3774 						    "revision 2 rotate opcode"
3775 						    " used, but the %s process"
3776 						    "or does not implement "
3777 						    "such instructions. Only "
3778 						    "printing this "
3779 						    "warning once. ]\n",
3780 						    cpu->cd.mips.cpu_type.name);
3781 						warning_rotate = 1;
3782 					}
3783 					ic->f = instr(reserved);
3784 					break;
3785 				}
3786 				switch (rs) {
3787 				case 0x01:
3788 					switch (s6) {
3789 					case SPECIAL_SRL:	/*  ror (aka. rotr?) */
3790 						ic->f = instr(ror);
3791 						break;
3792 					default:goto bad;
3793 					}
3794 					break;
3795 				default:goto bad;
3796 				}
3797 			}
3798 			if (sa < 0 && (s10 & 0x1f) != 0) {
3799 				int orig_sa = (iword >>  6) & 31;
3800 				switch (s6) {
3801 				case SPECIAL_SRLV:	/*  rorv (aka. rotrv?) */
3802 					if (orig_sa == 0x01) {
3803 						ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
3804 						ic->f = instr(rorv);
3805 					}
3806 					break;
3807 				default:goto bad;
3808 				}
3809 				break;
3810 			}
3811 
3812 			if (rd == MIPS_GPR_ZERO)
3813 				ic->f = instr(nop);
3814 			if (ic->f == instr(sll))
3815 				cpu->cd.mips.combination_check = COMBINE(sll);
3816 			if (ic->f == instr(nop))
3817 				cpu->cd.mips.combination_check = COMBINE(nop);
3818 			break;
3819 
3820 		case SPECIAL_ADD:
3821 		case SPECIAL_ADDU:
3822 		case SPECIAL_SUB:
3823 		case SPECIAL_SUBU:
3824 		case SPECIAL_DADD:
3825 		case SPECIAL_DADDU:
3826 		case SPECIAL_DSUB:
3827 		case SPECIAL_DSUBU:
3828 		case SPECIAL_SLT:
3829 		case SPECIAL_SLTU:
3830 		case SPECIAL_AND:
3831 		case SPECIAL_OR:
3832 		case SPECIAL_XOR:
3833 		case SPECIAL_NOR:
3834 		case SPECIAL_MOVN:
3835 		case SPECIAL_MOVZ:
3836 		case SPECIAL_MFHI:
3837 		case SPECIAL_MFLO:
3838 		case SPECIAL_MTHI:
3839 		case SPECIAL_MTLO:
3840 		case SPECIAL_DIV:
3841 		case SPECIAL_DIVU:
3842 		case SPECIAL_DDIV:
3843 		case SPECIAL_DDIVU:
3844 		case SPECIAL_MULT:
3845 		case SPECIAL_MULTU:
3846 		case SPECIAL_DMULT:
3847 		case SPECIAL_DMULTU:
3848 		case SPECIAL_TGE:
3849 		case SPECIAL_TGEU:
3850 		case SPECIAL_TLT:
3851 		case SPECIAL_TLTU:
3852 		case SPECIAL_TEQ:
3853 		case SPECIAL_TNE:
3854 			switch (s6) {
3855 			case SPECIAL_ADD:   ic->f = instr(add); break;
3856 			case SPECIAL_ADDU:  ic->f = instr(addu); break;
3857 			case SPECIAL_SUB:   ic->f = instr(sub); break;
3858 			case SPECIAL_SUBU:  ic->f = instr(subu); break;
3859 			case SPECIAL_DADD:  ic->f = instr(dadd); x64=1; break;
3860 			case SPECIAL_DADDU: ic->f = instr(daddu); x64=1; break;
3861 			case SPECIAL_DSUB:  ic->f = instr(dsub); x64=1; break;
3862 			case SPECIAL_DSUBU: ic->f = instr(dsubu); x64=1; break;
3863 			case SPECIAL_SLT:   ic->f = instr(slt); break;
3864 			case SPECIAL_SLTU:  ic->f = instr(sltu); break;
3865 			case SPECIAL_AND:   ic->f = instr(and); break;
3866 			case SPECIAL_OR:    ic->f = instr(or); break;
3867 			case SPECIAL_XOR:   ic->f = instr(xor); break;
3868 			case SPECIAL_NOR:   ic->f = instr(nor); break;
3869 			case SPECIAL_MFHI:  ic->f = instr(mov); break;
3870 			case SPECIAL_MFLO:  ic->f = instr(mov); break;
3871 			case SPECIAL_MTHI:  ic->f = instr(mov); break;
3872 			case SPECIAL_MTLO:  ic->f = instr(mov); break;
3873 			case SPECIAL_DIV:   ic->f = instr(div); break;
3874 			case SPECIAL_DIVU:  ic->f = instr(divu); break;
3875 			case SPECIAL_DDIV:  ic->f = instr(ddiv); x64=1; break;
3876 			case SPECIAL_DDIVU: ic->f = instr(ddivu); x64=1; break;
3877 			case SPECIAL_MULT : ic->f = instr(mult); break;
3878 			case SPECIAL_MULTU: ic->f = instr(multu); break;
3879 			case SPECIAL_DMULT: ic->f = instr(dmult); x64=1; break;
3880 			case SPECIAL_DMULTU:ic->f = instr(dmultu); x64=1; break;
3881 			case SPECIAL_TGE:   ic->f = instr(tge); break;
3882 			case SPECIAL_TGEU:  ic->f = instr(tgeu); break;
3883 			case SPECIAL_TLT:   ic->f = instr(tlt); break;
3884 			case SPECIAL_TLTU:  ic->f = instr(tltu); break;
3885 			case SPECIAL_TEQ:   ic->f = instr(teq); break;
3886 			case SPECIAL_TNE:   ic->f = instr(tne); break;
3887 			case SPECIAL_MOVN:  ic->f = instr(movn); break;
3888 			case SPECIAL_MOVZ:  ic->f = instr(movz); break;
3889 			}
3890 
3891 			ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
3892 			ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt];
3893 			ic->arg[2] = (size_t)&cpu->cd.mips.gpr[rd];
3894 
3895 			switch (s6) {
3896 			case SPECIAL_MFHI:
3897 				ic->arg[0] = (size_t)&cpu->cd.mips.hi;
3898 				break;
3899 			case SPECIAL_MFLO:
3900 				ic->arg[0] = (size_t)&cpu->cd.mips.lo;
3901 				break;
3902 			case SPECIAL_MTHI:
3903 				ic->arg[2] = (size_t)&cpu->cd.mips.hi;
3904 				break;
3905 			case SPECIAL_MTLO:
3906 				ic->arg[2] = (size_t)&cpu->cd.mips.lo;
3907 				break;
3908 			}
3909 			/*  Special cases for rd:  */
3910 			switch (s6) {
3911 			case SPECIAL_MTHI:
3912 			case SPECIAL_MTLO:
3913 			case SPECIAL_DIV:
3914 			case SPECIAL_DIVU:
3915 			case SPECIAL_DDIV:
3916 			case SPECIAL_DDIVU:
3917 			case SPECIAL_MULT:
3918 			case SPECIAL_MULTU:
3919 			case SPECIAL_DMULT:
3920 			case SPECIAL_DMULTU:
3921 				if (s6 == SPECIAL_MULT && rd != MIPS_GPR_ZERO) {
3922 					if (cpu->cd.mips.cpu_type.rev ==
3923 					    MIPS_R5900) {
3924 						ic->f = instr(mult_r5900);
3925 						break;
3926 					}
3927 					break;
3928 				}
3929 				if (s6 == SPECIAL_MULTU && rd!=MIPS_GPR_ZERO) {
3930 					if (cpu->cd.mips.cpu_type.rev ==
3931 					    MIPS_R5900) {
3932 						ic->f = instr(multu_r5900);
3933 						break;
3934 					}
3935 				}
3936 				if (rd != MIPS_GPR_ZERO) {
3937 					if (!cpu->translation_readahead)
3938 						fatal("TODO: rd NON-zero\n");
3939 					goto bad;
3940 				}
3941 				/*  These instructions don't use rd.  */
3942 				break;
3943 			case SPECIAL_TGE:
3944 			case SPECIAL_TGEU:
3945 			case SPECIAL_TLT:
3946 			case SPECIAL_TLTU:
3947 			case SPECIAL_TEQ:
3948 			case SPECIAL_TNE:
3949 				/*  In these instructions, rd is a 'code',
3950 				    only read by trap handling software.  */
3951 				break;
3952 			default:if (rd == MIPS_GPR_ZERO)
3953 					ic->f = instr(nop);
3954 			}
3955 
3956 			if (ic->f == instr(addu))
3957 				cpu->cd.mips.combination_check = COMBINE(addu);
3958 
3959 			break;
3960 
3961 		case SPECIAL_JR:
3962 		case SPECIAL_JALR:
3963 			ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
3964 			ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rd];
3965 			if (s6 == SPECIAL_JALR && rd == MIPS_GPR_ZERO)
3966 				s6 = SPECIAL_JR;
3967 			ic->arg[2] = (addr & 0xffc) + 8;
3968 			switch (s6) {
3969 			case SPECIAL_JR:
3970 				if (rs == MIPS_GPR_RA) {
3971 					if (cpu->machine->show_trace_tree)
3972 						ic->f = instr(jr_ra_trace);
3973 					else
3974 						ic->f = instr(jr_ra);
3975 				} else {
3976 					ic->f = instr(jr);
3977 				}
3978 				if (cpu->translation_readahead > 2)
3979 					cpu->translation_readahead = 2;
3980 				break;
3981 			case SPECIAL_JALR:
3982 				if (cpu->machine->show_trace_tree)
3983 					ic->f = instr(jalr_trace);
3984 				else
3985 					ic->f = instr(jalr);
3986 				break;
3987 			}
3988 			if (cpu->delay_slot) {
3989 				if (!cpu->translation_readahead)
3990 					fatal("TODO: branch in delay "
3991 					    "slot? (1)\n");
3992 				goto bad;
3993 			}
3994 			break;
3995 
3996 		case SPECIAL_SYSCALL:
3997 			if (((iword >> 6) & 0xfffff) == 0x30378) {
3998 				/*  "Magic trap" for PROM emulation:  */
3999 				ic->f = instr(promemul);
4000 			} else {
4001 				ic->f = instr(syscall);
4002 			}
4003 			break;
4004 
4005 		case SPECIAL_BREAK:
4006 			if (((iword >> 6) & 0xfffff) == 0x30378) {
4007 				/*  "Magic trap" for REBOOT:  */
4008 				ic->f = instr(reboot);
4009 			} else {
4010 				ic->f = instr(break);
4011 			}
4012 			break;
4013 
4014 		case SPECIAL_SYNC:
4015 			ic->f = instr(nop);
4016 			break;
4017 
4018 		default:goto bad;
4019 		}
4020 		break;
4021 
4022 	case HI6_BEQ:
4023 	case HI6_BNE:
4024 	case HI6_BEQL:
4025 	case HI6_BNEL:
4026 	case HI6_BLEZ:
4027 	case HI6_BLEZL:
4028 	case HI6_BGTZ:
4029 	case HI6_BGTZL:
4030 		samepage_function = NULL;  /*  get rid of a compiler warning  */
4031 		switch (main_opcode) {
4032 		case HI6_BEQ:
4033 			ic->f = instr(beq);
4034 			samepage_function = instr(beq_samepage);
4035 			/*  Special case: comparing a register with itself:  */
4036 			if (rs == rt) {
4037 				ic->f = instr(b);
4038 				samepage_function = instr(b_samepage);
4039 			}
4040 			break;
4041 		case HI6_BNE:
4042 			ic->f = instr(bne);
4043 			samepage_function = instr(bne_samepage);
4044 			break;
4045 		case HI6_BEQL:
4046 			ic->f = instr(beql);
4047 			samepage_function = instr(beql_samepage);
4048 			/*  Special case: comparing a register with itself:  */
4049 			if (rs == rt) {
4050 				ic->f = instr(b);
4051 				samepage_function = instr(b_samepage);
4052 			}
4053 			break;
4054 		case HI6_BNEL:
4055 			ic->f = instr(bnel);
4056 			samepage_function = instr(bnel_samepage);
4057 			break;
4058 		case HI6_BLEZ:
4059 			ic->f = instr(blez);
4060 			samepage_function = instr(blez_samepage);
4061 			break;
4062 		case HI6_BLEZL:
4063 			ic->f = instr(blezl);
4064 			samepage_function = instr(blezl_samepage);
4065 			break;
4066 		case HI6_BGTZ:
4067 			ic->f = instr(bgtz);
4068 			samepage_function = instr(bgtz_samepage);
4069 			break;
4070 		case HI6_BGTZL:
4071 			ic->f = instr(bgtzl);
4072 			samepage_function = instr(bgtzl_samepage);
4073 			break;
4074 		}
4075 		ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4076 		ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt];
4077 		ic->arg[2] = (int32_t) ( (imm << MIPS_INSTR_ALIGNMENT_SHIFT)
4078 		    + (addr & 0xffc) + 4 );
4079 		/*  Is the offset from the start of the current page still
4080 		    within the same page? Then use the samepage_function:  */
4081 		if ((uint32_t)ic->arg[2] < ((MIPS_IC_ENTRIES_PER_PAGE - 1)
4082 		    << MIPS_INSTR_ALIGNMENT_SHIFT) && (addr & 0xffc) < 0xffc) {
4083 			ic->arg[2] = (size_t) (cpu->cd.mips.cur_ic_page +
4084 			    ((ic->arg[2] >> MIPS_INSTR_ALIGNMENT_SHIFT)
4085 			    & (MIPS_IC_ENTRIES_PER_PAGE - 1)));
4086 			ic->f = samepage_function;
4087 		}
4088 		if (cpu->delay_slot) {
4089 			if (!cpu->translation_readahead)
4090 				fatal("TODO: branch in delay slot? (2)\n");
4091 			goto bad;
4092 		}
4093 		break;
4094 
4095 	case HI6_ADDI:
4096 	case HI6_ADDIU:
4097 	case HI6_SLTI:
4098 	case HI6_SLTIU:
4099 	case HI6_DADDI:
4100 	case HI6_DADDIU:
4101 	case HI6_ANDI:
4102 	case HI6_ORI:
4103 	case HI6_XORI:
4104 		ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4105 		ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt];
4106 		if (main_opcode == HI6_ADDI ||
4107 		    main_opcode == HI6_ADDIU ||
4108 		    main_opcode == HI6_SLTI ||
4109 		    main_opcode == HI6_SLTIU ||
4110 		    main_opcode == HI6_DADDI ||
4111 		    main_opcode == HI6_DADDIU)
4112 			ic->arg[2] = (int16_t)iword;
4113 		else
4114 			ic->arg[2] = (uint16_t)iword;
4115 
4116 		switch (main_opcode) {
4117 		case HI6_ADDI:    ic->f = instr(addi); break;
4118 		case HI6_ADDIU:   ic->f = instr(addiu); break;
4119 		case HI6_SLTI:    ic->f = instr(slti); break;
4120 		case HI6_SLTIU:   ic->f = instr(sltiu); break;
4121 		case HI6_DADDI:   ic->f = instr(daddi); x64 = 1; break;
4122 		case HI6_DADDIU:  ic->f = instr(daddiu); x64 = 1; break;
4123 		case HI6_ANDI:    ic->f = instr(andi); break;
4124 		case HI6_ORI:     ic->f = instr(ori); break;
4125 		case HI6_XORI:    ic->f = instr(xori); break;
4126 		}
4127 
4128 		if (ic->arg[2] == 0) {
4129 			if ((cpu->is_32bit && ic->f == instr(addiu)) ||
4130 			    (!cpu->is_32bit && ic->f == instr(daddiu))) {
4131 				ic->f = instr(mov);
4132 				ic->arg[2] = ic->arg[1];
4133 			}
4134 		}
4135 
4136 		if (rt == MIPS_GPR_ZERO)
4137 			ic->f = instr(nop);
4138 
4139 		if (ic->f == instr(ori))
4140 			cpu->cd.mips.combination_check = COMBINE(ori);
4141 		if (ic->f == instr(addiu))
4142 			cpu->cd.mips.combination_check = COMBINE(addiu);
4143 		if (ic->f == instr(daddiu))
4144 			cpu->cd.mips.combination_check = COMBINE(b_daddiu);
4145 		break;
4146 
4147 	case HI6_LUI:
4148 		ic->f = instr(set);
4149 		ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4150 		ic->arg[1] = (int32_t) (imm << 16);
4151 		/*  NOTE: Don't use arg[2] here. It can be used with
4152 		    instruction combinations, to do lui + addiu, etc.  */
4153 		if (rt == MIPS_GPR_ZERO)
4154 			ic->f = instr(nop);
4155 		break;
4156 
4157 	case HI6_J:
4158 	case HI6_JAL:
4159 		switch (main_opcode) {
4160 		case HI6_J:
4161 			ic->f = instr(j);
4162 			if (cpu->translation_readahead > 2)
4163 				cpu->translation_readahead = 2;
4164 			break;
4165 		case HI6_JAL:
4166 			if (cpu->machine->show_trace_tree)
4167 				ic->f = instr(jal_trace);
4168 			else
4169 				ic->f = instr(jal);
4170 			break;
4171 		}
4172 		ic->arg[0] = (iword & 0x03ffffff) << 2;
4173 		ic->arg[1] = (addr & 0xffc) + 8;
4174 		if (cpu->delay_slot) {
4175 			if (!cpu->translation_readahead)
4176 				fatal("TODO: branch in delay slot (=%i)? (3);"
4177 				    " addr=%016" PRIx64" iword=%08" PRIx32"\n",
4178 				    cpu->delay_slot, (uint64_t)addr, iword);
4179 			goto bad;
4180 		}
4181 		break;
4182 
4183 	case HI6_COP0:
4184 		/*  TODO: Is checking bit 25 enough, or perhaps all bits
4185 		    25..21 must be checked?  */
4186 		if ((iword >> 25) & 1) {
4187 			ic->arg[2] = addr & 0xffc;
4188 			switch (iword & 0xff) {
4189 			case COP0_TLBR:
4190 				ic->f = instr(tlbr);
4191 				break;
4192 			case COP0_TLBWI:
4193 			case COP0_TLBWR:
4194 				ic->f = instr(tlbw);
4195 				ic->arg[0] = (iword & 0xff) == COP0_TLBWR;
4196 				break;
4197 			case COP0_TLBP:
4198 				ic->f = instr(tlbp);
4199 				break;
4200 			case COP0_RFE:
4201 				ic->f = instr(rfe);
4202 				break;
4203 			case COP0_ERET:
4204 				ic->f = instr(eret);
4205 				break;
4206 			case COP0_DERET:
4207 				ic->f = instr(deret);
4208 				break;
4209 			case COP0_WAIT:
4210 				ic->f = instr(wait);
4211 				if (cpu->cd.mips.cpu_type.rev != MIPS_RM5200 &&
4212 				    cpu->cd.mips.cpu_type.isa_level < 32) {
4213 					static int warned = 0;
4214 					ic->f = instr(reserved);
4215 					if (!warned &&
4216 					    !cpu->translation_readahead) {
4217 						fatal("{ WARNING: Attempt to "
4218 						    "execute the WAIT instruct"
4219 					            "ion, but the emulated CPU "
4220 						    "is neither RM52xx, nor "
4221 						    "MIPS32/64! }\n");
4222 						warned = 1;
4223 					}
4224 				}
4225 				break;
4226 			case COP0_STANDBY:
4227 				/*  NOTE: Reusing the 'wait' instruction:  */
4228 				ic->f = instr(wait);
4229 				if (cpu->cd.mips.cpu_type.rev != MIPS_R4100) {
4230 					static int warned = 0;
4231 					ic->f = instr(reserved);
4232 					if (!warned &&
4233 					    !cpu->translation_readahead) {
4234 						fatal("{ WARNING: Attempt to "
4235 						    "execute a R41xx instruct"
4236 					            "ion, but the emulated CPU "
4237 						    "doesn't support it! }\n");
4238 						warned = 1;
4239 					}
4240 				}
4241 				break;
4242 			case COP0_HIBERNATE:
4243 				/*  TODO  */
4244 				goto bad;
4245 			case COP0_SUSPEND:
4246 				/*  Used by NetBSD on HPCmips (VR41xx) to
4247 				    halt the machine.  */
4248 				ic->f = instr(reboot);
4249 				break;
4250 			case COP0_EI:
4251 				if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
4252 					ic->f = instr(ei_r5900);
4253 				} else
4254 					goto bad;
4255 				break;
4256 			case COP0_DI:
4257 				if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
4258 					ic->f = instr(di_r5900);
4259 				} else
4260 					goto bad;
4261 				break;
4262 			default:if (!cpu->translation_readahead)
4263 					fatal("UNIMPLEMENTED cop0 (func "
4264 					    "0x%02x)\n", iword & 0xff);
4265 				goto bad;
4266 			}
4267 			break;
4268 		}
4269 
4270 		/*  rs contains the coprocessor opcode!  */
4271 		switch (rs) {
4272 		case COPz_CFCz:
4273 			ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4274 			ic->arg[1] = rd + ((iword & 7) << 5);
4275 			ic->arg[2] = addr & 0xffc;
4276 			ic->f = instr(cfc0);
4277 			if (rt == MIPS_GPR_ZERO)
4278 				ic->f = instr(nop);
4279 			break;
4280 		case COPz_MFCz:
4281 		case COPz_DMFCz:
4282 			ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4283 			ic->arg[1] = rd + ((iword & 7) << 5);
4284 			ic->arg[2] = addr & 0xffc;
4285 			ic->f = rs == COPz_MFCz? instr(mfc0) : instr(dmfc0);
4286 			if (rs == COPz_MFCz && (iword & 7) == 0 &&
4287 			    rd != COP0_COUNT)
4288 				ic->f = instr(mfc0_select0);
4289 			if (rs == COPz_DMFCz && (iword & 7) == 0 &&
4290 			    rd != COP0_COUNT)
4291 				ic->f = instr(dmfc0_select0);
4292 			if (rt == MIPS_GPR_ZERO)
4293 				ic->f = instr(nop);
4294 			break;
4295 		case COPz_MTCz:
4296 		case COPz_DMTCz:
4297 			ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4298 			ic->arg[1] = rd + ((iword & 7) << 5);
4299 			ic->arg[2] = addr & 0xffc;
4300 			ic->f = rs == COPz_MTCz? instr(mtc0) : instr(dmtc0);
4301 
4302 			if (cpu->cd.mips.cpu_type.exc_model == EXC3K &&
4303 			    rs == COPz_MTCz && rd == COP0_STATUS)
4304 				cpu->cd.mips.combination_check =
4305 				    COMBINE(netbsd_r3k_cache_inv);
4306 
4307 			break;
4308 		case COPz_MFMCz:
4309 			if ((iword & 0xffdf) == 0x6000) {
4310 				/*  MIPS32/64 rev 2 "ei" or "di":   */
4311 				if (cpu->cd.mips.cpu_type.isa_level < 32 ||
4312 				    cpu->cd.mips.cpu_type.isa_revision < 2) {
4313 					static int warning_ei_di = 0;
4314 					if (!warning_ei_di &&
4315 					    !cpu->translation_readahead) {
4316 						fatal("[ WARNING! MIPS32/64 "
4317 						    "revision 2 di or ei opcode"
4318 						    " used, but the %s process"
4319 						    "or does not implement "
4320 						    "such instructions. Only "
4321 						    "printing this "
4322 						    "warning once. ]\n",
4323 						    cpu->cd.mips.cpu_type.name);
4324 						warning_ei_di = 1;
4325 					}
4326 					ic->f = instr(reserved);
4327 					break;
4328 				}
4329 				ic->f = instr(ei_or_di);
4330 				ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4331 				if (rt == MIPS_GPR_ZERO)
4332 					ic->arg[0] =
4333 					    (size_t)&cpu->cd.mips.scratch;
4334 				ic->arg[1] = iword & 0x20;
4335 			} else {
4336 				if (!cpu->translation_readahead)
4337 					fatal("Unimplemented COP0_MFMCz\n");
4338 				goto bad;
4339 			}
4340 			break;
4341 		case COPz_BCzc:
4342 			if (iword == 0x4100ffff) {
4343 				/*  R2020 DECstation write-loop thingy.  */
4344 				ic->f = instr(nop);
4345 			} else {
4346 				if (!cpu->translation_readahead)
4347 					fatal("Unimplemented COP0_BCzc\n");
4348 				goto bad;
4349 			}
4350 			break;
4351 
4352 		default:if (!cpu->translation_readahead)
4353 				fatal("UNIMPLEMENTED cop0 (rs = %i)\n", rs);
4354 			goto bad;
4355 		}
4356 		break;
4357 
4358 	case HI6_COP1:
4359 		/*  Always cause a coprocessor unusable exception if
4360 		    there is no floating point coprocessor:  */
4361 		if (cpu->cd.mips.cpu_type.flags & NOFPU ||
4362 		    cpu->cd.mips.coproc[1] == NULL) {
4363 			ic->f = instr(cpu);
4364 			ic->arg[0] = 1;
4365 			break;
4366 		}
4367 
4368 		/*  Bits 25..21 are floating point main opcode:  */
4369 		switch (rs) {
4370 
4371 		case COPz_BCzc:
4372 			/*  Conditional branch:  */
4373 			/*  TODO: Reimplement this in a faster way.  */
4374 			ic->f = instr(cop1_bc);
4375 			ic->arg[0] = (iword >> 18) & 7;	/*  cc  */
4376 			ic->arg[1] = (iword >> 16) & 3;	/*  nd, tf bits  */
4377 			ic->arg[2] = (int32_t) ((imm <<
4378 			    MIPS_INSTR_ALIGNMENT_SHIFT) + (addr & 0xffc) + 4);
4379 			if (cpu->delay_slot) {
4380 				if (!cpu->translation_readahead)
4381 					fatal("TODO: branch in delay slot 4\n");
4382 				goto bad;
4383 			}
4384 			if (cpu->cd.mips.cpu_type.isa_level <= 3 &&
4385 			    ic->arg[0] != 0) {
4386 				if (!cpu->translation_readahead)
4387 					fatal("Attempt to execute a non-cc-0 "
4388 					    "BC* instruction on an isa level "
4389 					    "%i cpu. TODO: How should this be "
4390 					    "handled?\n",
4391 					    cpu->cd.mips.cpu_type.isa_level);
4392 				goto bad;
4393 			}
4394 
4395 			break;
4396 
4397 		case COPz_DMFCz:
4398 		case COPz_DMTCz:
4399 			x64 = 1;
4400 			/*  FALL-THROUGH  */
4401 		case COP1_FMT_S:
4402 		case COP1_FMT_D:
4403 		case COP1_FMT_W:
4404 		case COP1_FMT_L:
4405 		case COP1_FMT_PS:
4406 		case COPz_CFCz:
4407 		case COPz_CTCz:
4408 		case COPz_MFCz:
4409 		case COPz_MTCz:
4410 			/*  Fallback to slow pre-dyntrans code, for now.  */
4411 			/*  TODO: Fix/optimize/rewrite.  */
4412 			ic->f = instr(cop1_slow);
4413 			ic->arg[0] = (uint32_t)iword & ((1 << 26) - 1);
4414 			break;
4415 
4416 		default:if (!cpu->translation_readahead)
4417 			    fatal("COP1 floating point opcode = 0x%02x\n", rs);
4418 			goto bad;
4419 		}
4420 		break;
4421 
4422 	case HI6_COP2:
4423 		/*  Always cause a coprocessor unusable exception if
4424 		    there is no coprocessor 2:  */
4425 		if (cpu->cd.mips.coproc[2] == NULL) {
4426 			ic->f = instr(cpu);
4427 			ic->arg[0] = 2;
4428 			break;
4429 		}
4430 		if (!cpu->translation_readahead)
4431 			fatal("COP2 functionality not yet implemented\n");
4432 		goto bad;
4433 		break;
4434 
4435 	case HI6_COP3:
4436 		/*  Always cause a coprocessor unusable exception if
4437 		    there is no coprocessor 3:  */
4438 		if (cpu->cd.mips.coproc[3] == NULL) {
4439 			ic->f = instr(cpu);
4440 			ic->arg[0] = 3;
4441 			break;
4442 		}
4443 
4444 		if (iword == 0x4d00ffff) {
4445 			/*  R2020 writeback thing, used by e.g. NetBSD/pmax
4446 			    on MIPSMATE.  */
4447 			ic->f = instr(nop);
4448 		} else {
4449 			if (!cpu->translation_readahead)
4450 				fatal("COP3 iword=0x%08x\n", iword);
4451 			goto bad;
4452 		}
4453 		break;
4454 
4455 	case HI6_SPECIAL2:
4456 		if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
4457 			/*  R5900, TX79/C790, have MMI instead of SPECIAL2:  */
4458 			int mmi_subopcode = (iword >> 6) & 0x1f;
4459 
4460 			switch (s6) {
4461 
4462 			case MMI_MADD:
4463 				ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4464 				ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt];
4465 				ic->arg[2] = (size_t)&cpu->cd.mips.gpr[rd];
4466 				if (rd == MIPS_GPR_ZERO)
4467 					ic->f = instr(madd);
4468 				else
4469 					ic->f = instr(madd_rd);
4470 				break;
4471 
4472 			case MMI_MADDU:
4473 				ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4474 				ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt];
4475 				ic->arg[2] = (size_t)&cpu->cd.mips.gpr[rd];
4476 				if (rd == MIPS_GPR_ZERO)
4477 					ic->f = instr(maddu);
4478 				else
4479 					ic->f = instr(maddu_rd);
4480 				break;
4481 
4482 			case MMI_MMI0:
4483 				switch (mmi_subopcode) {
4484 
4485 				case MMI0_PEXTLW:
4486 					ic->arg[0] = rs;
4487 					ic->arg[1] = rt;
4488 					ic->arg[2] = rd;
4489 					if (rd == MIPS_GPR_ZERO)
4490 						ic->f = instr(nop);
4491 					else
4492 						ic->f = instr(pextlw);
4493 					break;
4494 
4495 				default:goto bad;
4496 				}
4497 				break;
4498 
4499 			case MMI_MMI3:
4500 				switch (mmi_subopcode) {
4501 
4502 				case MMI3_POR:
4503 					ic->arg[0] = rs;
4504 					ic->arg[1] = rt;
4505 					ic->arg[2] = rd;
4506 					if (rd == MIPS_GPR_ZERO)
4507 						ic->f = instr(nop);
4508 					else
4509 						ic->f = instr(por);
4510 					break;
4511 
4512 				default:goto bad;
4513 				}
4514 				break;
4515 
4516 			default:goto bad;
4517 			}
4518 			break;
4519 		}
4520 
4521 		/*  TODO: is this correct? Or are there other non-MIPS32/64
4522 		    MIPS processors that have support for SPECIAL2 opcodes?  */
4523 		if (cpu->cd.mips.cpu_type.isa_level < 32) {
4524 			ic->f = instr(reserved);
4525 			break;
4526 		}
4527 
4528 		/*  SPECIAL2:  */
4529 		switch (s6) {
4530 
4531 		case SPECIAL2_MADD:
4532 		case SPECIAL2_MADDU:
4533 		case SPECIAL2_MSUB:
4534 		case SPECIAL2_MSUBU:
4535 			ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4536 			ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt];
4537 			switch (s6) {
4538 			case SPECIAL2_MADD: ic->f = instr(madd); break;
4539 			case SPECIAL2_MADDU:ic->f = instr(maddu); break;
4540 			case SPECIAL2_MSUB: ic->f = instr(msub); break;
4541 			case SPECIAL2_MSUBU:ic->f = instr(msubu); break;
4542 			}
4543 			break;
4544 
4545 		case SPECIAL2_MUL:
4546 			ic->f = instr(mul);
4547 			ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4548 			ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt];
4549 			ic->arg[2] = (size_t)&cpu->cd.mips.gpr[rd];
4550 			if (rd == MIPS_GPR_ZERO)
4551 				ic->f = instr(nop);
4552 			break;
4553 
4554 		case SPECIAL2_CLZ:
4555 		case SPECIAL2_CLO:
4556 		case SPECIAL2_DCLZ:
4557 		case SPECIAL2_DCLO:
4558 			switch (s6) {
4559 			case SPECIAL2_CLZ:  ic->f = instr(clz); break;
4560 			case SPECIAL2_CLO:  ic->f = instr(clo); break;
4561 			case SPECIAL2_DCLZ: ic->f = instr(dclz); break;
4562 			case SPECIAL2_DCLO: ic->f = instr(dclo); break;
4563 			}
4564 			ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4565 			ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rd];
4566 			if (rd == MIPS_GPR_ZERO)
4567 				ic->f = instr(nop);
4568 			break;
4569 
4570 		default:goto bad;
4571 		}
4572 		break;
4573 
4574 	case HI6_REGIMM:
4575 		switch (rt) {
4576 		case REGIMM_BGEZ:
4577 		case REGIMM_BGEZL:
4578 		case REGIMM_BLTZ:
4579 		case REGIMM_BLTZL:
4580 		case REGIMM_BGEZAL:
4581 		case REGIMM_BGEZALL:
4582 		case REGIMM_BLTZAL:
4583 		case REGIMM_BLTZALL:
4584 			samepage_function = NULL;
4585 			switch (rt) {
4586 			case REGIMM_BGEZ:
4587 				ic->f = instr(bgez);
4588 				samepage_function = instr(bgez_samepage);
4589 				break;
4590 			case REGIMM_BGEZL:
4591 				ic->f = instr(bgezl);
4592 				samepage_function = instr(bgezl_samepage);
4593 				break;
4594 			case REGIMM_BLTZ:
4595 				ic->f = instr(bltz);
4596 				samepage_function = instr(bltz_samepage);
4597 				break;
4598 			case REGIMM_BLTZL:
4599 				ic->f = instr(bltzl);
4600 				samepage_function = instr(bltzl_samepage);
4601 				break;
4602 			case REGIMM_BGEZAL:
4603 				ic->f = instr(bgezal);
4604 				samepage_function = instr(bgezal_samepage);
4605 				break;
4606 			case REGIMM_BGEZALL:
4607 				ic->f = instr(bgezall);
4608 				samepage_function = instr(bgezall_samepage);
4609 				break;
4610 			case REGIMM_BLTZAL:
4611 				ic->f = instr(bltzal);
4612 				samepage_function = instr(bltzal_samepage);
4613 				break;
4614 			case REGIMM_BLTZALL:
4615 				ic->f = instr(bltzall);
4616 				samepage_function = instr(bltzall_samepage);
4617 				break;
4618 			}
4619 			ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4620 			ic->arg[2] = (imm << MIPS_INSTR_ALIGNMENT_SHIFT)
4621 			    + (addr & 0xffc) + 4;
4622 			/*  Is the offset from the start of the current page
4623 			    still within the same page? Then use the
4624 			    samepage_function:  */
4625 			if ((uint32_t)ic->arg[2] < ((MIPS_IC_ENTRIES_PER_PAGE-1)
4626 			    << MIPS_INSTR_ALIGNMENT_SHIFT) && (addr & 0xffc)
4627 			    < 0xffc) {
4628 				ic->arg[2] = (size_t) (cpu->cd.mips.cur_ic_page+
4629 				    ((ic->arg[2] >> MIPS_INSTR_ALIGNMENT_SHIFT)
4630 				    & (MIPS_IC_ENTRIES_PER_PAGE - 1)));
4631 				ic->f = samepage_function;
4632 			}
4633 			if (cpu->delay_slot) {
4634 				if (!cpu->translation_readahead)
4635 					fatal("TODO: branch in delay slot:5\n");
4636 				goto bad;
4637 			}
4638 			break;
4639 
4640 		case REGIMM_TGEI:
4641 		case REGIMM_TGEIU:
4642 		case REGIMM_TLTI:
4643 		case REGIMM_TLTIU:
4644 		case REGIMM_TEQI:
4645 		case REGIMM_TNEI:
4646 			switch (rt) {
4647 			case REGIMM_TGEI:	ic->f = instr(tgei); break;
4648 			case REGIMM_TGEIU:	ic->f = instr(tgeiu); break;
4649 			case REGIMM_TLTI:	ic->f = instr(tlti); break;
4650 			case REGIMM_TLTIU:	ic->f = instr(tltiu); break;
4651 			case REGIMM_TEQI:	ic->f = instr(teqi); break;
4652 			case REGIMM_TNEI:	ic->f = instr(tnei); break;
4653 			}
4654 			ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4655 			ic->arg[2] = (int64_t)(int16_t)imm;
4656 
4657 			if (cpu->cd.mips.cpu_type.isa_level < 32) {
4658 				static int warning = 0;
4659 				if (!warning && !cpu->translation_readahead) {
4660 					fatal("[ WARNING! Trap opcode used, but"
4661 					    " the %s processor does not implement "
4662 					    "such instructions. Only printing this "
4663 					    "warning once. ]\n",
4664 					    cpu->cd.mips.cpu_type.name);
4665 					warning = 1;
4666 				}
4667 				ic->f = instr(reserved);
4668 			}
4669 			break;
4670 
4671 		default:if (!cpu->translation_readahead)
4672 				fatal("UNIMPLEMENTED regimm rt=%i\n", rt);
4673 			goto bad;
4674 		}
4675 		break;
4676 
4677 	case HI6_LB:
4678 	case HI6_LBU:
4679 	case HI6_SB:
4680 	case HI6_LH:
4681 	case HI6_LHU:
4682 	case HI6_SH:
4683 	case HI6_LW:
4684 	case HI6_LWU:
4685 	case HI6_SW:
4686 	case HI6_LD:
4687 	case HI6_SD:
4688 		/*  TODO: LWU should probably also be x64=1?  */
4689 		size = 2; signedness = 0; store = 0;
4690 		switch (main_opcode) {
4691 		case HI6_LB:  size = 0; signedness = 1; break;
4692 		case HI6_LBU: size = 0; break;
4693 		case HI6_LH:  size = 1; signedness = 1; break;
4694 		case HI6_LHU: size = 1; break;
4695 		case HI6_LW:  signedness = 1; break;
4696 		case HI6_LWU: break;
4697 		case HI6_LD:  size = 3; x64 = 1; break;
4698 		case HI6_SB:  store = 1; size = 0; break;
4699 		case HI6_SH:  store = 1; size = 1; break;
4700 		case HI6_SW:  store = 1; break;
4701 		case HI6_SD:  store = 1; size = 3; x64 = 1; break;
4702 		}
4703 
4704 		ic->f =
4705 #ifdef MODE32
4706 		    mips32_loadstore
4707 #else
4708 		    mips_loadstore
4709 #endif
4710 		    [ (cpu->byte_order == EMUL_LITTLE_ENDIAN? 0 : 16)
4711 		    + store * 8 + size * 2 + signedness];
4712 		ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4713 		ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
4714 		ic->arg[2] = (int32_t)imm;
4715 
4716 		/*  Load into the dummy scratch register, if rt = zero  */
4717 		if (!store && rt == MIPS_GPR_ZERO)
4718 			ic->arg[0] = (size_t)&cpu->cd.mips.scratch;
4719 
4720 		if (main_opcode == HI6_LW)
4721 			cpu->cd.mips.combination_check = COMBINE(lw);
4722 		if (main_opcode == HI6_SW)
4723 			cpu->cd.mips.combination_check = COMBINE(sw);
4724 		break;
4725 
4726 	case HI6_LL:
4727 	case HI6_LLD:
4728 	case HI6_SC:
4729 	case HI6_SCD:
4730 		/*  32-bit load-linked/store-condition for ISA II and up:  */
4731 		/*  (64-bit load-linked/store-condition for ISA III...)  */
4732 		if (cpu->cd.mips.cpu_type.isa_level < 2) {
4733 			ic->f = instr(reserved);
4734 			break;
4735 		}
4736 
4737 		store = 0;
4738 		switch (main_opcode) {
4739 		case HI6_LL:  ic->f = instr(ll); break;
4740 		case HI6_LLD: ic->f = instr(lld); x64 = 1; break;
4741 		case HI6_SC:  ic->f = instr(sc); store = 1; break;
4742 		case HI6_SCD: ic->f = instr(scd); store = 1; x64 = 1; break;
4743 		}
4744 		ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4745 		ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
4746 		ic->arg[2] = (int32_t)imm;
4747 		if (!store && rt == MIPS_GPR_ZERO) {
4748 			if (!cpu->translation_readahead)
4749 				fatal("HM... unusual load linked\n");
4750 			goto bad;
4751 		}
4752 		break;
4753 
4754 	case HI6_LWL:
4755 	case HI6_LWR:
4756 	case HI6_LDL:
4757 	case HI6_LDR:
4758 	case HI6_SWL:
4759 	case HI6_SWR:
4760 	case HI6_SDL:
4761 	case HI6_SDR:
4762 		/*  TODO: replace these with faster versions...  */
4763 		store = 0;
4764 		switch (main_opcode) {
4765 		case HI6_LWL: ic->f = instr(lwl); break;
4766 		case HI6_LWR: ic->f = instr(lwr); break;
4767 		case HI6_LDL: ic->f = instr(ldl); x64 = 1; break;
4768 		case HI6_LDR: ic->f = instr(ldr); x64 = 1; break;
4769 		case HI6_SWL: ic->f = instr(swl); store = 1; break;
4770 		case HI6_SWR: ic->f = instr(swr); store = 1; break;
4771 		case HI6_SDL: ic->f = instr(sdl); store = 1; x64 = 1; break;
4772 		case HI6_SDR: ic->f = instr(sdr); store = 1; x64 = 1; break;
4773 		}
4774 		ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4775 		ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
4776 		ic->arg[2] = (int32_t)imm;
4777 
4778 		/*  Load into the dummy scratch register, if rt = zero  */
4779 		if (!store && rt == MIPS_GPR_ZERO)
4780 			ic->arg[0] = (size_t)&cpu->cd.mips.scratch;
4781 		break;
4782 
4783 	case HI6_LWC1:
4784 	case HI6_SWC1:
4785 	case HI6_LDC1:
4786 	case HI6_SDC1:
4787 		/*  64-bit floating-point load/store for ISA II and up...  */
4788 		if ((main_opcode == HI6_LDC1 || main_opcode == HI6_SDC1)
4789 		    && cpu->cd.mips.cpu_type.isa_level < 2) {
4790 			ic->f = instr(reserved);
4791 			break;
4792 		}
4793 
4794 		ic->arg[0] = (size_t)&cpu->cd.mips.coproc[1]->reg[rt];
4795 		ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
4796 		ic->arg[2] = (int32_t)imm;
4797 		switch (main_opcode) {
4798 		case HI6_LWC1: ic->f = instr(lwc1); break;
4799 		case HI6_LDC1: ic->f = instr(ldc1); break;
4800 		case HI6_SWC1: ic->f = instr(swc1); break;
4801 		case HI6_SDC1: ic->f = instr(sdc1); break;
4802 		}
4803 
4804 		/*  Cause a coprocessor unusable exception if
4805 		    there is no floating point coprocessor:  */
4806 		if (cpu->cd.mips.cpu_type.flags & NOFPU ||
4807 		    cpu->cd.mips.coproc[1] == NULL) {
4808 			ic->f = instr(cpu);
4809 			ic->arg[0] = 1;
4810 		}
4811 		break;
4812 
4813 	case HI6_LWC3:
4814 		/*  PREF (prefetch) on ISA IV and MIPS32/64:  */
4815 		if (cpu->cd.mips.cpu_type.isa_level >= 4) {
4816 			/*  Treat as nop for now:  */
4817 			ic->f = instr(nop);
4818 		} else {
4819 			if (!cpu->translation_readahead)
4820 				fatal("TODO: lwc3 not implemented yet\n");
4821 			goto bad;
4822 		}
4823 		break;
4824 
4825 	case HI6_LQ_MDMX:
4826 		if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
4827 			if (!cpu->translation_readahead)
4828 				fatal("TODO: R5900 128-bit loads\n");
4829 			goto bad;
4830 		}
4831 
4832 		if (!cpu->translation_readahead)
4833 			fatal("TODO: MDMX\n");
4834 
4835 		goto bad;
4836 		/*  break  */
4837 
4838 	case HI6_SQ_SPECIAL3:
4839 		if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
4840 			if (!cpu->translation_readahead)
4841 				fatal("TODO: R5900 128-bit stores\n");
4842 			goto bad;
4843 		}
4844 
4845 		if (cpu->cd.mips.cpu_type.isa_level < 32 ||
4846 		    cpu->cd.mips.cpu_type.isa_revision < 2) {
4847 			static int warning = 0;
4848 			if (!warning && !cpu->translation_readahead) {
4849 				fatal("[ WARNING! SPECIAL3 opcode used, but"
4850 				    " the %s processor does not implement "
4851 				    "such instructions. Only printing this "
4852 				    "warning once. ]\n",
4853 				    cpu->cd.mips.cpu_type.name);
4854 				warning = 1;
4855 			}
4856 			ic->f = instr(reserved);
4857 			break;
4858 		}
4859 
4860 		switch (s6) {
4861 
4862 		case SPECIAL3_EXT:
4863 			{
4864 				int msbd = rd, lsb = (iword >> 6) & 0x1f;
4865 				ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4866 				ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
4867 				ic->arg[2] = (msbd << 5) + lsb;
4868 				ic->f = instr(ext);
4869 				if (rt == MIPS_GPR_ZERO)
4870 					ic->f = instr(nop);
4871 			}
4872 			break;
4873 
4874 		case SPECIAL3_DEXT:
4875 		case SPECIAL3_DEXTM:
4876 		case SPECIAL3_DEXTU:
4877 			{
4878 				int msbd = rd, lsb = (iword >> 6) & 0x1f;
4879 				if (s6 == SPECIAL3_DEXTM)
4880 					msbd += 32;
4881 				if (s6 == SPECIAL3_DEXTU)
4882 					lsb += 32;
4883 				ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4884 				ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
4885 				ic->arg[2] = (msbd << 6) + lsb;
4886 				ic->f = instr(dext);
4887 				if (rt == MIPS_GPR_ZERO)
4888 					ic->f = instr(nop);
4889 			}
4890 			break;
4891 
4892 		case SPECIAL3_INS:
4893 			{
4894 				int msb = rd, lsb = (iword >> 6) & 0x1f;
4895 				ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4896 				ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
4897 				ic->arg[2] = (msb << 5) + lsb;
4898 				ic->f = instr(ins);
4899 				if (rt == MIPS_GPR_ZERO)
4900 					ic->f = instr(nop);
4901 			}
4902 			break;
4903 
4904 		case SPECIAL3_BSHFL:
4905 			ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4906 			ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rd];
4907 			switch (s10) {
4908 			case BSHFL_WSBH:
4909 				ic->f = instr(wsbh);
4910 				break;
4911 			case BSHFL_SEB:
4912 				ic->f = instr(seb);
4913 				break;
4914 			case BSHFL_SEH:
4915 				ic->f = instr(seh);
4916 				break;
4917 			default:goto bad;
4918 			}
4919 			break;
4920 
4921 		case SPECIAL3_DBSHFL:
4922 			ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4923 			ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rd];
4924 			switch (s10) {
4925 			case BSHFL_DSBH:
4926 				ic->f = instr(dsbh);
4927 				break;
4928 			case BSHFL_DSHD:
4929 				ic->f = instr(dshd);
4930 				break;
4931 			default:goto bad;
4932 			}
4933 			break;
4934 
4935 		case SPECIAL3_RDHWR:
4936 			ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4937 
4938 			switch (rd) {
4939 
4940 			case 0:	ic->f = instr(rdhwr_cpunum);
4941 				if (rt == MIPS_GPR_ZERO)
4942 					ic->f = instr(nop);
4943 				break;
4944 
4945 			case 2:	ic->f = instr(rdhwr_cc);
4946 				if (rt == MIPS_GPR_ZERO)
4947 					ic->f = instr(nop);
4948 				break;
4949 
4950                         case 29: ic->f = instr(reserved);
4951                                  break;
4952 
4953 			default:if (!cpu->translation_readahead)
4954 					fatal("unimplemented rdhwr "
4955 					    "register rd=%i\n", rd);
4956 				goto bad;
4957 			}
4958 			break;
4959 
4960 		default:goto bad;
4961 		}
4962 		break;
4963 
4964 	case HI6_CACHE:
4965 		/*  TODO: rt and op etc...  */
4966 		ic->f = instr(cache);
4967 		break;
4968 
4969 	default:goto bad;
4970 	}
4971 
4972 
4973 #ifdef MODE32
4974 	if (x64) {
4975 		static int has_warned = 0;
4976 		if (!has_warned && !cpu->translation_readahead) {
4977 			fatal("[ WARNING/NOTE: attempt to execute a 64-bit"
4978 			    " instruction on an emulated 32-bit processor; "
4979 			    "pc=0x%08" PRIx32" ]\n", (uint32_t)cpu->pc);
4980 			has_warned = 1;
4981 		}
4982 		if (cpu->translation_readahead)
4983 			goto bad;
4984 		else
4985 			ic->f = instr(reserved);
4986 	}
4987 #else
4988 	(void)x64; // avoid compiler warning
4989 #endif
4990 
4991 
4992 #define	DYNTRANS_TO_BE_TRANSLATED_TAIL
4993 #include "cpu_dyntrans.cc"
4994 #undef	DYNTRANS_TO_BE_TRANSLATED_TAIL
4995 }
4996 
4997