cpu_mips_instr.cc Source File

Back to the index.

cpu_mips_instr.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2009 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  */
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] &
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);
101  cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
102  if (!(cpu->cd.mips.coproc[0]->reg[COP0_STATUS] &
103  (1 << STATUS_CU_SHIFT)) ) {
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  */
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  */
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);
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  */
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);
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  */
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  */
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;
183  ic[1].f(cpu, ic+1);
185  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
186  /* Note: Must be non-delayed when jumping to the new pc: */
188  if (x) {
189  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
191  cpu->pc = old_pc + (int32_t)ic->arg[2];
193  } else
194  cpu->cd.mips.next_ic ++;
195  } else
197 }
198 X(beq_samepage)
199 {
200  MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
201  int x = rs == rt;
203  ic[1].f(cpu, ic+1);
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  }
213 }
214 X(beq_samepage_addiu)
215 {
216  MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
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 }
225 X(beq_samepage_nop)
226 {
227  MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
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 }
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;
240  ic[1].f(cpu, ic+1);
242  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
243  /* Note: Must be non-delayed when jumping to the new pc: */
245  if (x) {
246  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
248  cpu->pc = old_pc + (int32_t)ic->arg[2];
250  } else
251  cpu->cd.mips.next_ic ++;
252  } else
254 }
255 X(bne_samepage)
256 {
257  MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
258  int x = rs != rt;
260  ic[1].f(cpu, ic+1);
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  }
270 }
271 X(bne_samepage_addiu)
272 {
273  MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
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 }
282 X(bne_samepage_nop)
283 {
284  MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
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 }
291 X(b)
292 {
293  MODE_int_t old_pc = cpu->pc;
295  ic[1].f(cpu, ic+1);
297  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
298  /* Note: Must be non-delayed when jumping to the new pc: */
300  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
302  cpu->pc = old_pc + (int32_t)ic->arg[2];
304  } else
306 }
307 X(b_samepage)
308 {
310  ic[1].f(cpu, ic+1);
312  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)))
313  cpu->cd.mips.next_ic = (struct mips_instr_call *) ic->arg[2];
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  */
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;
332  if (x)
333  ic[1].f(cpu, ic+1);
335  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
336  /* Note: Must be non-delayed when jumping to the new pc: */
338  if (x) {
339  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
341  cpu->pc = old_pc + (int32_t)ic->arg[2];
343  } else
344  cpu->cd.mips.next_ic ++;
345  } else
347 }
348 X(beql_samepage)
349 {
350  MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
351  int x = rs == rt;
353  if (x)
354  ic[1].f(cpu, ic+1);
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  }
364 }
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;
371  if (x)
372  ic[1].f(cpu, ic+1);
374  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
375  /* Note: Must be non-delayed when jumping to the new pc: */
377  if (x) {
378  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
380  cpu->pc = old_pc + (int32_t)ic->arg[2];
382  } else
383  cpu->cd.mips.next_ic ++;
384  } else
386 }
387 X(bnel_samepage)
388 {
389  MODE_uint_t rs = reg(ic->arg[0]), rt = reg(ic->arg[1]);
390  int x = rs != rt;
392  if (x)
393  ic[1].f(cpu, ic+1);
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  }
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  */
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);
419  ic[1].f(cpu, ic+1);
421  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
422  /* Note: Must be non-delayed when jumping to the new pc: */
424  if (x) {
425  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
427  cpu->pc = old_pc + (int32_t)ic->arg[2];
429  } else
430  cpu->cd.mips.next_ic ++;
431  } else
433 }
434 X(blez_samepage)
435 {
436  MODE_int_t rs = reg(ic->arg[0]);
437  int x = (rs <= 0);
439  ic[1].f(cpu, ic+1);
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  }
449 }
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);
456  if (x)
457  ic[1].f(cpu, ic+1);
459  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
460  /* Note: Must be non-delayed when jumping to the new pc: */
462  if (x) {
463  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
465  cpu->pc = old_pc + (int32_t)ic->arg[2];
467  } else
468  cpu->cd.mips.next_ic ++;
469  } else
471 }
472 X(blezl_samepage)
473 {
474  MODE_int_t rs = reg(ic->arg[0]);
475  int x = (rs <= 0);
477  if (x)
478  ic[1].f(cpu, ic+1);
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  }
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  */
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);
504  ic[1].f(cpu, ic+1);
506  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
507  /* Note: Must be non-delayed when jumping to the new pc: */
509  if (x) {
510  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
512  cpu->pc = old_pc + (int32_t)ic->arg[2];
514  } else
515  cpu->cd.mips.next_ic ++;
516  } else
518 }
519 X(bltz_samepage)
520 {
521  MODE_int_t rs = reg(ic->arg[0]);
522  int x = (rs < 0);
524  ic[1].f(cpu, ic+1);
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  }
534 }
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);
541  if (x)
542  ic[1].f(cpu, ic+1);
544  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
545  /* Note: Must be non-delayed when jumping to the new pc: */
547  if (x) {
548  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
550  cpu->pc = old_pc + (int32_t)ic->arg[2];
552  } else
553  cpu->cd.mips.next_ic ++;
554  } else
556 }
557 X(bltzl_samepage)
558 {
559  MODE_int_t rs = reg(ic->arg[0]);
560  int x = (rs < 0);
562  if (x)
563  ic[1].f(cpu, ic+1);
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  }
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  */
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);
589  ic[1].f(cpu, ic+1);
591  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
592  /* Note: Must be non-delayed when jumping to the new pc: */
594  if (x) {
595  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
597  cpu->pc = old_pc + (int32_t)ic->arg[2];
599  } else
600  cpu->cd.mips.next_ic ++;
601  } else
603 }
604 X(bgez_samepage)
605 {
606  MODE_int_t rs = reg(ic->arg[0]);
607  int x = (rs >= 0);
609  ic[1].f(cpu, ic+1);
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  }
619 }
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);
626  if (x)
627  ic[1].f(cpu, ic+1);
629  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
630  /* Note: Must be non-delayed when jumping to the new pc: */
632  if (x) {
633  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
635  cpu->pc = old_pc + (int32_t)ic->arg[2];
637  } else
638  cpu->cd.mips.next_ic ++;
639  } else
641 }
642 X(bgezl_samepage)
643 {
644  MODE_int_t rs = reg(ic->arg[0]);
645  int x = (rs >= 0);
647  if (x)
648  ic[1].f(cpu, ic+1);
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  }
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  */
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 
675  low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
676  / sizeof(struct mips_instr_call);
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);
684  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
685  /* Note: Must be non-delayed when jumping to the new pc: */
687  if (x) {
688  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
690  cpu->pc = old_pc + (int32_t)ic->arg[2];
692  } else
693  cpu->cd.mips.next_ic ++;
694  } else
696 }
697 X(bgezal_samepage)
698 {
699  MODE_int_t rs = reg(ic->arg[0]);
700  int x = (rs >= 0), low_pc;
701 
703  low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
704  / sizeof(struct mips_instr_call);
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);
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  }
720 }
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 
728  low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
729  / sizeof(struct mips_instr_call);
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);
738  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
739  /* Note: Must be non-delayed when jumping to the new pc: */
741  if (x) {
742  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
744  cpu->pc = old_pc + (int32_t)ic->arg[2];
746  } else
747  cpu->cd.mips.next_ic ++;
748  } else
750 }
751 X(bgezall_samepage)
752 {
753  MODE_int_t rs = reg(ic->arg[0]);
754  int x = (rs >= 0), low_pc;
755 
757  low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
758  / sizeof(struct mips_instr_call);
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);
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  }
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  */
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 
792  low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
793  / sizeof(struct mips_instr_call);
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);
801  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
802  /* Note: Must be non-delayed when jumping to the new pc: */
804  if (x) {
805  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
807  cpu->pc = old_pc + (int32_t)ic->arg[2];
809  } else
810  cpu->cd.mips.next_ic ++;
811  } else
813 }
814 X(bltzal_samepage)
815 {
816  MODE_int_t rs = reg(ic->arg[0]);
817  int x = (rs < 0), low_pc;
818 
820  low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
821  / sizeof(struct mips_instr_call);
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);
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  }
837 }
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 
845  low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
846  / sizeof(struct mips_instr_call);
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);
855  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
856  /* Note: Must be non-delayed when jumping to the new pc: */
858  if (x) {
859  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
861  cpu->pc = old_pc + (int32_t)ic->arg[2];
863  } else
864  cpu->cd.mips.next_ic ++;
865  } else
867 }
868 X(bltzall_samepage)
869 {
870  MODE_int_t rs = reg(ic->arg[0]);
871  int x = (rs < 0), low_pc;
872 
874  low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
875  / sizeof(struct mips_instr_call);
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);
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  }
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  */
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);
908  ic[1].f(cpu, ic+1);
910  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
911  /* Note: Must be non-delayed when jumping to the new pc: */
913  if (x) {
914  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
916  cpu->pc = old_pc + (int32_t)ic->arg[2];
918  } else
919  cpu->cd.mips.next_ic ++;
920  } else
922 }
923 X(bgtz_samepage)
924 {
925  MODE_int_t rs = reg(ic->arg[0]);
926  int x = (rs > 0);
928  ic[1].f(cpu, ic+1);
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  }
938 }
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);
945  if (x)
946  ic[1].f(cpu, ic+1);
948  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
949  /* Note: Must be non-delayed when jumping to the new pc: */
951  if (x) {
952  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
954  cpu->pc = old_pc + (int32_t)ic->arg[2];
956  } else
957  cpu->cd.mips.next_ic ++;
958  } else
960 }
961 X(bgtzl_samepage)
962 {
963  MODE_int_t rs = reg(ic->arg[0]);
964  int x = (rs > 0);
966  if (x)
967  ic[1].f(cpu, ic+1);
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  }
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  */
987 X(jr)
988 {
989  MODE_int_t rs = reg(ic->arg[0]);
991  ic[1].f(cpu, ic+1);
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: */
998  } else
1000 }
1001 X(jr_ra)
1002 {
1005  ic[1].f(cpu, ic+1);
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: */
1012  } else
1014 }
1015 X(jr_ra_addiu)
1016 {
1017  /* jr ra, followed by an addiu */
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;
1024 }
1025 X(jr_ra_trace)
1026 {
1029  ic[1].f(cpu, ic+1);
1031  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
1032  cpu->pc = rs;
1034  /* Note: Must be non-delayed when jumping to the new pc: */
1037  } else
1039 }
1040 X(jalr)
1041 {
1042  MODE_int_t rs = reg(ic->arg[0]), rd;
1044  rd = cpu->pc & ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
1046  rd += (int32_t)ic->arg[2];
1047  reg(ic->arg[1]) = rd;
1048  ic[1].f(cpu, ic+1);
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: */
1055  } else
1057 }
1058 X(jalr_trace)
1059 {
1060  MODE_int_t rs = reg(ic->arg[0]), rd;
1062  rd = cpu->pc & ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
1064  rd += (int32_t)ic->arg[2];
1065  reg(ic->arg[1]) = rd;
1066  ic[1].f(cpu, ic+1);
1068  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
1069  cpu->pc = rs;
1071  /* Note: Must be non-delayed when jumping to the new pc: */
1074  } else
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  */
1085 X(j)
1086 {
1087  MODE_int_t old_pc = cpu->pc;
1089  ic[1].f(cpu, ic+1);
1091  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
1092  /* Note: Must be non-delayed when jumping to the new pc: */
1094  old_pc &= ~0x03ffffff;
1095  cpu->pc = old_pc | (uint32_t)ic->arg[0];
1097  } else
1099 }
1100 X(jal)
1101 {
1102  MODE_int_t old_pc = cpu->pc;
1105  cpu->cd.mips.gpr[31] = (MODE_int_t)cpu->pc + (int32_t)ic->arg[1];
1106  ic[1].f(cpu, ic+1);
1108  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
1109  /* Note: Must be non-delayed when jumping to the new pc: */
1111  old_pc &= ~0x03ffffff;
1112  cpu->pc = old_pc | (int32_t)ic->arg[0];
1114  } else
1116 }
1117 X(jal_trace)
1118 {
1119  MODE_int_t old_pc = cpu->pc;
1122  cpu->cd.mips.gpr[31] = (MODE_int_t)cpu->pc + (int32_t)ic->arg[1];
1123  ic[1].f(cpu, ic+1);
1125  if (likely(!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))) {
1126  /* Note: Must be non-delayed when jumping to the new pc: */
1128  old_pc &= ~0x03ffffff;
1129  cpu->pc = old_pc | (int32_t)ic->arg[0];
1132  } else
1134 }
1135 
1136 
1137 /*
1138  * cache: Cache operation.
1139  */
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  */
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)
1171  cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1172  mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1173  }
1174 }
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)
1186  cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1187  mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1188  }
1189 }
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)
1201  cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1202  mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1203  }
1204 }
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)
1216  cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1217  mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1218  }
1219 }
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)
1231  cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1232  mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1233  }
1234 }
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)
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  */
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 = (-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  */
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  */
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  */
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 }
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 }
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 }
1340 X(seb) { reg(ic->arg[1]) = (int8_t)reg(ic->arg[0]); }
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  */
1351 X(andi) { reg(ic->arg[1]) = reg(ic->arg[0]) & (uint32_t)ic->arg[2]; }
1352 X(ori) { reg(ic->arg[1]) = reg(ic->arg[0]) | (uint32_t)ic->arg[2]; }
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  */
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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)
1501  cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1502  mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1503  }
1504 }
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)
1514  cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1515  mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1516  }
1517 }
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)
1527  cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1528  mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1529  }
1530 }
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)
1540  cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1541  mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1542  }
1543 }
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)
1553  cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
1554  mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
1555  }
1556 }
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)
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  */
1579 X(addu) { reg(ic->arg[2]) = (int32_t)(reg(ic->arg[0]) + reg(ic->arg[1])); }
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)
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 }
1596 X(daddu){ reg(ic->arg[2]) = reg(ic->arg[0]) + reg(ic->arg[1]); }
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)
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 }
1613 X(subu) { reg(ic->arg[2]) = (int32_t)(reg(ic->arg[0]) - reg(ic->arg[1])); }
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)
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 }
1631 X(dsubu){ reg(ic->arg[2]) = reg(ic->arg[0]) - reg(ic->arg[1]); }
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)
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 }
1649 X(slt) {
1650  reg(ic->arg[2]) =
1651  (MODE_int_t)reg(ic->arg[0]) < (MODE_int_t)reg(ic->arg[1]);
1652 }
1653 X(sltu) {
1654  reg(ic->arg[2]) =
1655  (MODE_uint_t)reg(ic->arg[0]) < (MODE_uint_t)reg(ic->arg[1]);
1656 }
1657 X(and) { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]); }
1658 X(or) { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]); }
1659 X(xor) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); }
1660 X(nor) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1])); }
1661 X(sll) { reg(ic->arg[2]) = (int32_t)(reg(ic->arg[0]) << (int32_t)ic->arg[1]); }
1662 X(sllv){ int32_t sa = reg(ic->arg[1]) & 31;
1663  reg(ic->arg[2]) = (int32_t)(reg(ic->arg[0]) << sa); }
1664 X(srl) { reg(ic->arg[2]) = (int32_t)((uint32_t)reg(ic->arg[0]) >> ic->arg[1]); }
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); }
1667 X(sra) { reg(ic->arg[2]) = (int32_t)((int32_t)reg(ic->arg[0]) >> ic->arg[1]); }
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); }
1670 X(dsll) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) << (int64_t)ic->arg[1]; }
1671 X(dsllv){ int64_t sa = reg(ic->arg[1]) & 63;
1672  reg(ic->arg[2]) = reg(ic->arg[0]) << sa; }
1673 X(dsrl) { reg(ic->arg[2]) = (int64_t)((uint64_t)reg(ic->arg[0]) >>
1674  (uint64_t) ic->arg[1]);}
1675 X(dsrlv){ int64_t sa = reg(ic->arg[1]) & 63;
1676  reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) >> sa; }
1677 X(dsra) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) >> (int64_t)ic->arg[1]; }
1678 X(dsrav){ int64_t sa = reg(ic->arg[1]) & 63;
1679  reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) >> sa; }
1680 X(mul) { reg(ic->arg[2]) = (int32_t)
1681  ( (int32_t)reg(ic->arg[0]) * (int32_t)reg(ic->arg[1]) ); }
1682 X(movn) { if (reg(ic->arg[1])) reg(ic->arg[2]) = reg(ic->arg[0]); }
1683 X(movz) { if (!reg(ic->arg[1])) reg(ic->arg[2]) = reg(ic->arg[0]); }
1684 
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 
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  */
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 }
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  */
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 }
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 }
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 }
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 }
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 }
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  */
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  */
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 }
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 }
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 }
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  */
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)
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 }
1882 {
1883  reg(ic->arg[1]) = (int32_t)
1884  ((int32_t)reg(ic->arg[0]) + (int32_t)ic->arg[2]);
1885 }
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)
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 }
1902 X(daddiu)
1903 {
1904  reg(ic->arg[1]) = reg(ic->arg[0]) + (int32_t)ic->arg[2];
1905 }
1906 X(slti)
1907 {
1908  reg(ic->arg[1]) = (MODE_int_t)reg(ic->arg[0]) < (int32_t)ic->arg[2];
1909 }
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  */
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  */
1940 X(cfc0)
1941 {
1942  int fs = ic->arg[1] & 31;
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 }
1948 X(mfc0)
1949 {
1950  int rd = ic->arg[1] & 31, select = ic->arg[1] >> 5;
1951  uint64_t tmp;
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 }
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;
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 }
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 
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 }
2004 X(dmfc0)
2005 {
2006  int rd = ic->arg[1] & 31, select = ic->arg[1] >> 5;
2008  cpu->pc |= ic->arg[2];
2009  /* TODO: cause exception if necessary */
2011  (uint64_t *)ic->arg[0], select);
2012 }
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;
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 }
2025 X(dmtc0)
2026 {
2027  int rd = ic->arg[1] & 31, select = ic->arg[1] >> 5;
2029  cpu->pc |= ic->arg[2];
2030  /* TODO: cause exception if necessary */
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  */
2043 X(cop1_bc)
2044 {
2045  MODE_int_t old_pc = cpu->pc;
2046  int x, cc = ic->arg[0];
2047 
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): */
2064  if (x || !(ic->arg[1] & 2))
2065  ic[1].f(cpu, ic+1);
2067 
2069  /* Note: Must be non-delayed when jumping to the new pc: */
2071  if (x) {
2072  old_pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
2074  cpu->pc = old_pc + (int32_t)ic->arg[2];
2076  } else
2077  cpu->cd.mips.next_ic ++;
2078  } else
2080 }
2081 
2082 
2083 /*
2084  * cop1_slow: Fallback to legacy cop1 code. (Slow, but it should work.)
2085  */
2086 X(cop1_slow)
2087 {
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  */
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);
2102  cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
2103  mips_cpu_exception(cpu, EXCEPTION_SYS, 0, 0, 0, 0, 0, 0);
2104 }
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);
2110  cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
2111  mips_cpu_exception(cpu, EXCEPTION_BP, 0, 0, 0, 0, 0, 0);
2112 }
2113 X(reboot)
2114 {
2116  return;
2117 
2118  cpu->running = 0;
2120  cpu->cd.mips.next_ic = &nothing_call;
2121 }
2122 
2123 
2124 /*
2125  * promemul: PROM software emulation.
2126  */
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);
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:
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: */
2159 
2162  } else {
2163  /* The PROM call blocks. */
2164  cpu->n_translated_instrs += 10;
2165  cpu->pc = old_pc;
2166  }
2167 
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  */
2178 X(tlbw)
2179 {
2181  return;
2182 
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  */
2195 X(tlbp)
2196 {
2198  return;
2199 
2201  cpu->pc |= ic->arg[2];
2202  coproc_tlbpr(cpu, 0);
2203 }
2204 X(tlbr)
2205 {
2207  return;
2208 
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  */
2221 X(ei_or_di)
2222 {
2223  reg(ic->arg[0]) = cpu->cd.mips.coproc[0]->reg[COP0_STATUS];
2224  if (ic->arg[1])
2226  else
2228 }
2229 
2230 
2231 /*
2232  * rfe: Return from exception handler (R2000/R3000)
2233  */
2234 X(rfe)
2235 {
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  */
2255 X(eret)
2256 {
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];
2263  } else {
2264  cpu->pc = cpu->cd.mips.coproc[0]->reg[COP0_EPC];
2265  cpu->delay_slot = 0;
2267  }
2268 
2270 
2271  cpu->cd.mips.rmw = 0; /* the "LL bit" */
2272 }
2273 
2274 
2275 /*
2276  * deret: Return from debug (EJTAG) handler
2277  */
2278 X(deret)
2279 {
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;
2297 }
2298 
2299 
2300 /*
2301  * idle: Called from the implementation of wait, or netbsd_pmax_idle.
2302  */
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 
2346  }
2347 }
2348 
2349 
2350 /*
2351  * wait: Wait for external interrupt.
2352  */
2353 X(wait)
2354 {
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  */
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  */
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  */
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)
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 
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 }
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)
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 
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 }
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)
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 }
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)
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  */
2608 X(lwc1)
2609 {
2611 
2612 #ifdef MODE32
2613  mips32_loadstore
2614 #else
2616 #endif
2617  [ (cpu->byte_order == EMUL_LITTLE_ENDIAN? 0 : 16) + 2 * 2 + 1]
2618  (cpu, ic);
2619 }
2620 X(swc1)
2621 {
2623 
2624 #ifdef MODE32
2625  mips32_loadstore
2626 #else
2628 #endif
2629  [ (cpu->byte_order == EMUL_LITTLE_ENDIAN? 0 : 16) + 8 + 2 * 2]
2630  (cpu, ic);
2631 }
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 
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
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 }
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 
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
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  */
2698 X(lwl) { mips_unaligned_loadstore(cpu, ic, 1, sizeof(uint32_t), 0); }
2699 X(lwr) { mips_unaligned_loadstore(cpu, ic, 0, sizeof(uint32_t), 0); }
2700 X(ldl) { mips_unaligned_loadstore(cpu, ic, 1, sizeof(uint64_t), 0); }
2701 X(ldr) { mips_unaligned_loadstore(cpu, ic, 0, sizeof(uint64_t), 0); }
2702 X(swl) { mips_unaligned_loadstore(cpu, ic, 1, sizeof(uint32_t), 1); }
2703 X(swr) { mips_unaligned_loadstore(cpu, ic, 0, sizeof(uint32_t), 1); }
2704 X(sdl) { mips_unaligned_loadstore(cpu, ic, 1, sizeof(uint64_t), 1); }
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  */
2715 X(di_r5900)
2716 {
2718  return;
2719 
2721 }
2722 X(ei_r5900)
2723 {
2725  return;
2726 
2728 }
2729 
2730 
2731 /*****************************************************************************/
2732 
2733 
2734 /*
2735  * sw_loop:
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  */
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  page = cpu->cd.mips.host_store[rX >> 12];
2750 
2751  /* Fallback: */
2752  if (cpu->delay_slot || page == NULL || (rX & 3) != 0 || rZ != 0) {
2753  instr(addiu)(cpu, ic);
2754  return;
2755  }
2756 
2757  if (rYp == (uint64_t *) ic->arg[0])
2758  rYp = (uint64_t *) ic[1].arg[1];
2759 
2760  rY = reg(rYp);
2761 
2762  bytes_to_write = rY - rX;
2763  if ((rX & 0xfff) + bytes_to_write > 0x1000) {
2764  bytes_to_write = 0x1000 - (rX & 0xfff);
2765  partial = 1;
2766  }
2767 
2768  /* printf("rX = %08x\n", (int)rX);
2769  printf("rY = %08x\n", (int)rY);
2770  printf("rZ = %08x\n", (int)rZ);
2771  printf("%i bytes\n", (int)bytes_to_write); */
2772 
2773  memset(page + (rX & 0xfff), 0, bytes_to_write);
2774 
2775  reg(ic->arg[0]) = rX + bytes_to_write;
2776 
2777  cpu->n_translated_instrs += bytes_to_write / 4 * 3 - 1;
2778  cpu->cd.mips.next_ic = partial?
2779  (struct mips_instr_call *) &ic[0] :
2780  (struct mips_instr_call *) &ic[3];
2781 }
2782 
2783 
2784 /* multi_{l,s}w_2, _3, etc. */
2785 #include "tmp_mips_loadstore_multi.cc"
2786 
2787 
2788 /*
2789  * multi_addu_3:
2790  */
2791 X(multi_addu_3)
2792 {
2793  /* Fallback: */
2794  if (cpu->delay_slot) {
2795  instr(addu)(cpu, ic);
2796  return;
2797  }
2798 
2799  reg(ic[0].arg[2]) = (int32_t)(reg(ic[0].arg[0]) + reg(ic[0].arg[1]));
2800  reg(ic[1].arg[2]) = (int32_t)(reg(ic[1].arg[0]) + reg(ic[1].arg[1]));
2801  reg(ic[2].arg[2]) = (int32_t)(reg(ic[2].arg[0]) + reg(ic[2].arg[1]));
2802  cpu->n_translated_instrs += 2;
2803  cpu->cd.mips.next_ic = ic + 3;
2804 }
2805 
2806 
2807 /*
2808  * netbsd_r3k_picache_do_inv:
2809  *
2810  * ic[0] mtc0 rV,status
2811  * 1 nop
2812  * 2 nop
2813  * 3 s: addiu rX,rX,4
2814  * 4 bne rY,rX,s
2815  * 5 sb zr,-4(rX)
2816  * 6 nop
2817  * 7 nop
2818  * 8 mtc0 rT,status
2819  */
2820 X(netbsd_r3k_picache_do_inv)
2821 {
2822  MODE_uint_t rx = reg(ic[3].arg[0]), ry = reg(ic[4].arg[1]);
2823 
2824  /* Fallback if the environment isn't exactly right: */
2825  if (!(reg(ic[0].arg[0]) & MIPS1_ISOL_CACHES) ||
2826  (rx & 3) || (ry & 3) || cpu->delay_slot) {
2827  instr(mtc0)(cpu, ic);
2828  return;
2829  }
2830 
2831  reg(ic[3].arg[0]) = ry;
2832  cpu->n_translated_instrs += (ry - rx + 4) / 4 * 3 + 4;
2833 
2834  /* Run the last mtc0 instruction: */
2835  cpu->cd.mips.next_ic = ic + 8;
2836 }
2837 
2838 
2839 #ifdef MODE32
2840 /*
2841  * netbsd_pmax_idle():
2842  *
2843  * s: lui rX, hi
2844  * lw rY, lo(rX)
2845  * nop
2846  * beq zr, rY, s
2847  * nop
2848  */
2849 X(netbsd_pmax_idle)
2850 {
2851  uint32_t addr, pageindex, i;
2852  int32_t *page;
2853 
2854  reg(ic[0].arg[0]) = (int32_t)ic[0].arg[1];
2855 
2856  addr = reg(ic[0].arg[0]) + (int32_t)ic[1].arg[2];
2857  pageindex = addr >> 12;
2858  i = (addr & 0xfff) >> 2;
2859  page = (int32_t *) cpu->cd.mips.host_load[pageindex];
2860 
2861  /* Fallback: */
2862  if (cpu->delay_slot || page == NULL || page[i] != 0)
2863  return;
2864 
2865  instr(idle)(cpu, ic);
2866 }
2867 
2868 
2869 /*
2870  * linux_pmax_idle():
2871  *
2872  * s: lui rX, hi
2873  * lw rX, lo(rX)
2874  * nop
2875  * bne zr, rX, ...
2876  * nop
2877  * lw rX, ofs(gp)
2878  * nop
2879  * beq zr, rX, s
2880  * nop
2881  */
2882 X(linux_pmax_idle)
2883 {
2884  uint32_t addr, addr2, pageindex, pageindex2, i, i2;
2885  int32_t *page, *page2;
2886 
2887  reg(ic[0].arg[0]) = (int32_t)ic[0].arg[1];
2888 
2889  addr = reg(ic[0].arg[0]) + (int32_t)ic[1].arg[2];
2890  pageindex = addr >> 12;
2891  i = (addr & 0xfff) >> 2;
2892  page = (int32_t *) cpu->cd.mips.host_load[pageindex];
2893 
2894  addr2 = reg(ic[5].arg[1]) + (int32_t)ic[5].arg[2];
2895  pageindex2 = addr2 >> 12;
2896  i2 = (addr2 & 0xfff) >> 2;
2897  page2 = (int32_t *) cpu->cd.mips.host_load[pageindex2];
2898 
2899  /* Fallback: */
2900  if (cpu->delay_slot || page == NULL || page[i] != 0 || page2[i2] != 0)
2901  return;
2902 
2903  instr(idle)(cpu, ic);
2904 }
2905 
2906 
2907 /*
2908  * netbsd_strlen():
2909  *
2910  * lb rV,0(rX)
2911  * s: addiu rX,rX,1
2912  * bne zr,rV,s
2913  * nop
2914  */
2915 X(netbsd_strlen)
2916 {
2917  MODE_uint_t rx = reg(ic[0].arg[1]);
2918  MODE_int_t rv;
2919  signed char *page;
2920  uint32_t pageindex = rx >> 12;
2921  int i;
2922 
2923  page = (signed char *) cpu->cd.mips.host_load[pageindex];
2924 
2925  /* Fallback: */
2926  if (cpu->delay_slot || page == NULL) {
2927  /*
2928  * Normal lb: NOTE: It doesn't matter whether [1] or
2929  * [16+1] is called here, because endianness for 8-bit
2930  * loads is irrelevant. :-)
2931  */
2932  mips32_loadstore[1](cpu, ic);
2933  return;
2934  }
2935 
2936  i = rx & 0xfff;
2937 
2938  /*
2939  * TODO: This loop can be optimized further for optimal
2940  * performance on the host, e.g. by reading full words...
2941  */
2942  do {
2943  rv = page[i ++];
2944  } while (i < 0x1000 && rv != 0);
2945 
2946  cpu->n_translated_instrs += (i - (rx & 0xfff)) * 4 - 1;
2947 
2948  reg(ic[0].arg[1]) = (rx & ~0xfff) + i;
2949  reg(ic[2].arg[0]) = rv;
2950 
2951  /* Done with the loop? Or continue on the next rx page? */
2952  if (rv == 0)
2953  cpu->cd.mips.next_ic = ic + 4;
2954  else
2955  cpu->cd.mips.next_ic = ic;
2956 }
2957 #endif
2958 
2959 
2960 /*
2961  * addiu_bne_samepage_addiu:
2962  */
2963 X(addiu_bne_samepage_addiu)
2964 {
2965  MODE_uint_t rs, rt;
2966 
2967  if (cpu->delay_slot) {
2968  instr(addiu)(cpu, ic);
2969  return;
2970  }
2971 
2972  cpu->n_translated_instrs += 2;
2973  reg(ic[0].arg[1]) = (int32_t)
2974  ((int32_t)reg(ic[0].arg[0]) + (int32_t)ic[0].arg[2]);
2975  rs = reg(ic[1].arg[0]);
2976  rt = reg(ic[1].arg[1]);
2977  reg(ic[2].arg[1]) = (int32_t)
2978  ((int32_t)reg(ic[2].arg[0]) + (int32_t)ic[2].arg[2]);
2979  if (rs != rt)
2980  cpu->cd.mips.next_ic = (struct mips_instr_call *) ic[1].arg[2];
2981  else
2982  cpu->cd.mips.next_ic = ic + 3;
2983 }
2984 
2985 
2986 /*
2987  * xor_andi_sll:
2988  */
2989 X(xor_andi_sll)
2990 {
2991  /* Fallback: */
2992  if (cpu->delay_slot) {
2993  instr(xor)(cpu, ic);
2994  return;
2995  }
2996 
2997  reg(ic[0].arg[2]) = reg(ic[0].arg[0]) ^ reg(ic[0].arg[1]);
2998  reg(ic[1].arg[1]) = reg(ic[1].arg[0]) & (uint32_t)ic[1].arg[2];
2999  reg(ic[2].arg[2]) = (int32_t)(reg(ic[2].arg[0])<<(int32_t)ic[2].arg[1]);
3000 
3001  cpu->n_translated_instrs += 2;
3002  cpu->cd.mips.next_ic = ic + 3;
3003 }
3004 
3005 
3006 /*
3007  * andi_sll:
3008  */
3009 X(andi_sll)
3010 {
3011  /* Fallback: */
3012  if (cpu->delay_slot) {
3013  instr(andi)(cpu, ic);
3014  return;
3015  }
3016 
3017  reg(ic[0].arg[1]) = reg(ic[0].arg[0]) & (uint32_t)ic[0].arg[2];
3018  reg(ic[1].arg[2]) = (int32_t)(reg(ic[1].arg[0])<<(int32_t)ic[1].arg[1]);
3019 
3021  cpu->cd.mips.next_ic = ic + 2;
3022 }
3023 
3024 
3025 /*
3026  * lui_ori:
3027  */
3028 X(lui_ori)
3029 {
3030  /* Fallback: */
3031  if (cpu->delay_slot) {
3032  instr(set)(cpu, ic);
3033  return;
3034  }
3035 
3036  reg(ic[0].arg[0]) = (int32_t)ic[0].arg[1];
3037  reg(ic[1].arg[1]) = reg(ic[1].arg[0]) | (uint32_t)ic[1].arg[2];
3038 
3040  cpu->cd.mips.next_ic = ic + 2;
3041 }
3042 
3043 
3044 /*
3045  * lui_addiu:
3046  */
3047 X(lui_addiu)
3048 {
3049  /* Fallback: */
3050  if (cpu->delay_slot) {
3051  instr(set)(cpu, ic);
3052  return;
3053  }
3054 
3055  reg(ic[0].arg[0]) = (int32_t)ic[0].arg[1];
3056  reg(ic[1].arg[1]) = (int32_t)
3057  ((int32_t)reg(ic[1].arg[0]) + (int32_t)ic[1].arg[2]);
3058 
3060  cpu->cd.mips.next_ic = ic + 2;
3061 }
3062 
3063 
3064 /*
3065  * b_samepage_addiu:
3066  *
3067  * Combination of branch within the same page, followed by addiu.
3068  */
3069 X(b_samepage_addiu)
3070 {
3071  reg(ic[1].arg[1]) = (int32_t)
3072  ( (int32_t)reg(ic[1].arg[0]) + (int32_t)ic[1].arg[2] );
3074  cpu->cd.mips.next_ic = (struct mips_instr_call *) ic->arg[2];
3075 }
3076 
3077 
3078 /*
3079  * b_samepage_daddiu:
3080  *
3081  * Combination of branch within the same page, followed by daddiu.
3082  */
3083 X(b_samepage_daddiu)
3084 {
3085  *(uint64_t *)ic[1].arg[1] = *(uint64_t *)ic[1].arg[0] +
3086  (int32_t)ic[1].arg[2];
3088  cpu->cd.mips.next_ic = (struct mips_instr_call *) ic->arg[2];
3089 }
3090 
3091 
3092 /*****************************************************************************/
3093 
3094 
3095 X(end_of_page)
3096 {
3097  /* Update the PC: (offset 0, but on the next page) */
3098  cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) <<
3101 
3102  /* end_of_page doesn't count as an executed instruction: */
3104 
3105  /*
3106  * Find the new physpage and update translation pointers.
3107  *
3108  * Note: This may cause an exception, if e.g. the new page is
3109  * not accessible.
3110  */
3112 
3113  /* Simple jump to the next page (if we are lucky): */
3114  if (cpu->delay_slot == NOT_DELAYED)
3115  return;
3116 
3117  /*
3118  * If we were in a delay slot, and we got an exception while doing
3119  * quick_pc_to_pointers, then return. The function which called
3120  * end_of_page should handle this case.
3121  */
3123  return;
3124 
3125  /*
3126  * Tricky situation; the delay slot is on the next virtual page.
3127  * Calling to_be_translated will translate one instruction manually,
3128  * execute it, and then discard it.
3129  */
3130  /* fatal("[ end_of_page: delay slot across page boundary! ]\n"); */
3131 
3132  instr(to_be_translated)(cpu, cpu->cd.mips.next_ic);
3133 
3134  /* The instruction in the delay slot has now executed. */
3135  /* fatal("[ end_of_page: back from executing the delay slot, %i ]\n",
3136  cpu->delay_slot); */
3137 
3138  /* Find the physpage etc of the instruction in the delay slot
3139  (or, if there was an exception, the exception handler): */
3141 }
3142 
3143 
3144 X(end_of_page2)
3145 {
3146  /* Synchronize PC on the _second_ instruction on the next page: */
3147  int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
3148  / sizeof(struct mips_instr_call);
3149  cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
3151  cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
3152 
3153  /* This doesn't count as an executed instruction. */
3155 
3157 
3158  if (cpu->delay_slot == NOT_DELAYED)
3159  return;
3160 
3161  fatal("end_of_page2: fatal error, we're in a delay slot\n");
3162  exit(1);
3163 }
3164 
3165 
3166 /*****************************************************************************/
3167 
3168 
3169 /*
3170  * Combine: Memory fill loop (addiu, bne, sw)
3171  *
3172  * s: addiu rX,rX,4
3173  * bne rY,rX,s
3174  * sw rZ,-4(rX)
3175  */
3176 void COMBINE(sw_loop)(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
3177 {
3178  int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3179  & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3180 
3181  /* Only for 32-bit virtual address translation so far. */
3182  if (!cpu->is_32bit)
3183  return;
3184 
3185  if (n_back < 2)
3186  return;
3187 
3188  if (ic[-2].f == instr(addiu) && ic[-2].arg[0] == ic[-2].arg[1] &&
3189  (int32_t)ic[-2].arg[2] == 4 &&
3190  ic[-1].f == instr(bne_samepage) &&
3191  (ic[-1].arg[0] == ic[-2].arg[0] ||
3192  ic[-1].arg[1] == ic[-2].arg[0]) &&
3193  ic[-1].arg[0] != ic[-1].arg[1] &&
3194  ic[-1].arg[2] == (size_t) &ic[-2] &&
3195  ic[0].arg[0] != ic[0].arg[1] &&
3196  ic[0].arg[1] == ic[-2].arg[0] && (int32_t)ic[0].arg[2] == -4) {
3197  ic[-2].f = instr(sw_loop);
3198  }
3199 }
3200 
3201 
3202 /*
3203  * Combine: Multiple SW in a row using the same base register
3204  *
3205  * sw r?,???(rX)
3206  * sw r?,???(rX)
3207  * sw r?,???(rX)
3208  * ...
3209  */
3210 void COMBINE(multi_sw)(struct cpu *cpu, struct mips_instr_call *ic,
3211  int low_addr)
3212 {
3213  int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3214  & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3215 
3216  if (n_back < 4)
3217  return;
3218 
3219  /* Convert a multi_sw_4 to a multi_sw_5: */
3220  if ((ic[-4].f == instr(multi_sw_4_be) ||
3221  ic[-4].f == instr(multi_sw_4_le)) &&
3222  ic[-4].arg[1] == ic[0].arg[1]) {
3224  ic[-4].f = instr(multi_sw_5_le);
3225  else
3226  ic[-4].f = instr(multi_sw_5_be);
3227  }
3228 
3229  /* Convert a multi_sw_3 to a multi_sw_4: */
3230  if ((ic[-3].f == instr(multi_sw_3_be) ||
3231  ic[-3].f == instr(multi_sw_3_le)) &&
3232  ic[-3].arg[1] == ic[0].arg[1]) {
3234  ic[-3].f = instr(multi_sw_4_le);
3235  else
3236  ic[-3].f = instr(multi_sw_4_be);
3237  }
3238 
3239  /* Convert a multi_sw_2 to a multi_sw_3: */
3240  if ((ic[-2].f == instr(multi_sw_2_be) ||
3241  ic[-2].f == instr(multi_sw_2_le)) &&
3242  ic[-2].arg[1] == ic[0].arg[1]) {
3244  ic[-2].f = instr(multi_sw_3_le);
3245  else
3246  ic[-2].f = instr(multi_sw_3_be);
3247  }
3248 
3249  if (ic[-1].f == ic[0].f && ic[-1].arg[1] == ic[0].arg[1]) {
3251  ic[-1].f = instr(multi_sw_2_le);
3252  else
3253  ic[-1].f = instr(multi_sw_2_be);
3254  }
3255 }
3256 
3257 
3258 /*
3259  * Combine: Multiple LW in a row using the same base register
3260  *
3261  * lw r?,???(rX)
3262  * lw r?,???(rX)
3263  * lw r?,???(rX)
3264  * ...
3265  */
3266 void COMBINE(multi_lw)(struct cpu *cpu, struct mips_instr_call *ic,
3267  int low_addr)
3268 {
3269  int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3270  & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3271 
3272  if (n_back < 4)
3273  return;
3274 
3275  /* Convert a multi_lw_4 to a multi_lw_5: */
3276  if ((ic[-4].f == instr(multi_lw_4_be) ||
3277  ic[-4].f == instr(multi_lw_4_le)) &&
3278  ic[-4].arg[1] == ic[0].arg[1] &&
3279  ic[-1].arg[0] != ic[0].arg[1]) {
3281  ic[-4].f = instr(multi_lw_5_le);
3282  else
3283  ic[-4].f = instr(multi_lw_5_be);
3284  }
3285 
3286  /* Convert a multi_lw_3 to a multi_lw_4: */
3287  if ((ic[-3].f == instr(multi_lw_3_be) ||
3288  ic[-3].f == instr(multi_lw_3_le)) &&
3289  ic[-3].arg[1] == ic[0].arg[1] &&
3290  ic[-1].arg[0] != ic[0].arg[1]) {
3292  ic[-3].f = instr(multi_lw_4_le);
3293  else
3294  ic[-3].f = instr(multi_lw_4_be);
3295  }
3296 
3297  /* Convert a multi_lw_2 to a multi_lw_3: */
3298  if ((ic[-2].f == instr(multi_lw_2_be) ||
3299  ic[-2].f == instr(multi_lw_2_le)) &&
3300  ic[-2].arg[1] == ic[0].arg[1] &&
3301  ic[-1].arg[0] != ic[0].arg[1]) {
3303  ic[-2].f = instr(multi_lw_3_le);
3304  else
3305  ic[-2].f = instr(multi_lw_3_be);
3306  }
3307 
3308  /* Note: Loads to the base register are not allowed in slot -1. */
3309  if (ic[-1].f == ic[0].f &&
3310  ic[-1].arg[1] == ic[0].arg[1] &&
3311  ic[-1].arg[0] != ic[0].arg[1]) {
3313  ic[-1].f = instr(multi_lw_2_le);
3314  else
3315  ic[-1].f = instr(multi_lw_2_be);
3316  }
3317 }
3318 
3319 
3320 /*
3321  * Combine: NetBSD/pmax 3.0 R2000/R3000 physical cache invalidation loop
3322  *
3323  * Instruction cache loop:
3324  *
3325  * ic[-8] mtc0 rV,status
3326  * -7 nop
3327  * -6 nop
3328  * -5 s: addiu rX,rX,4
3329  * -4 bne rY,rX,s
3330  * -3 sb zr,-4(rX)
3331  * -2 nop
3332  * -1 nop
3333  * 0 mtc0 rT,status
3334  */
3336  struct mips_instr_call *ic, int low_addr)
3337 {
3338  int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3339  & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3340 
3341  if (n_back < 8)
3342  return;
3343 
3344  if (ic[-8].f == instr(mtc0) && ic[-8].arg[1] == COP0_STATUS &&
3345  ic[-7].f == instr(nop) && ic[-6].f == instr(nop) &&
3346  ic[-5].f == instr(addiu) && ic[-5].arg[0] == ic[-5].arg[1] &&
3347  (int32_t)ic[-5].arg[2] == 4 && ic[-4].f == instr(bne_samepage) &&
3348  ic[-4].arg[0] == ic[-5].arg[0] && ic[-4].arg[0] != ic[-4].arg[1] &&
3349  ic[-4].arg[2] == (size_t) &ic[-5] &&
3350  ic[-3].arg[1] == ic[-5].arg[0] &&
3351  ic[-2].f == instr(nop) && ic[-1].f == instr(nop)) {
3352  ic[-8].f = instr(netbsd_r3k_picache_do_inv);
3353  }
3354 }
3355 
3356 
3357 /*
3358  * Combine: something ending with a nop.
3359  *
3360  * NetBSD's strlen core.
3361  * [Conditional] branch, followed by nop.
3362  * NetBSD/pmax' idle loop (and possibly others as well).
3363  * Linux/pmax' idle loop.
3364  */
3365 void COMBINE(nop)(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
3366 {
3367  int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3368  & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3369 
3370  if (n_back < 8)
3371  return;
3372 
3373 #ifdef MODE32
3374  if (ic[-8].f == instr(set) &&
3375  ic[-7].f == mips32_loadstore[4 + 1] &&
3376  ic[-7].arg[0] == ic[-1].arg[0] &&
3377  ic[-7].arg[0] == ic[-3].arg[0] &&
3378  ic[-7].arg[0] == ic[-5].arg[0] &&
3379  ic[-7].arg[0] == ic[-7].arg[1] &&
3380  ic[-7].arg[0] == ic[-8].arg[0] &&
3381  ic[-6].f == instr(nop) &&
3382  ic[-5].arg[1] == (size_t) &cpu->cd.mips.gpr[MIPS_GPR_ZERO] &&
3383  ic[-5].f == instr(bne_samepage_nop) &&
3384  ic[-4].f == instr(nop) &&
3385  ic[-3].f == mips32_loadstore[4 + 1] &&
3386  ic[-2].f == instr(nop) &&
3387  ic[-1].arg[1] == (size_t) &cpu->cd.mips.gpr[MIPS_GPR_ZERO] &&
3388  ic[-1].arg[2] == (size_t) &ic[-8] &&
3389  ic[-1].f == instr(beq_samepage)) {
3390  ic[-8].f = instr(linux_pmax_idle);
3391  return;
3392  }
3393 
3394  if (ic[-4].f == instr(set) &&
3395  ic[-3].f == mips32_loadstore[4 + 1] &&
3396  ic[-3].arg[0] == ic[-1].arg[0] &&
3397  ic[-3].arg[1] == ic[-4].arg[0] &&
3398  ic[-2].f == instr(nop) &&
3399  ic[-1].arg[1] == (size_t) &cpu->cd.mips.gpr[MIPS_GPR_ZERO] &&
3400  ic[-1].arg[2] == (size_t) &ic[-4] &&
3401  ic[-1].f == instr(beq_samepage)) {
3402  ic[-4].f = instr(netbsd_pmax_idle);
3403  return;
3404  }
3405 
3406  if ((ic[-3].f == mips32_loadstore[1] ||
3407  ic[-3].f == mips32_loadstore[16 + 1]) &&
3408  ic[-3].arg[2] == 0 &&
3409  ic[-3].arg[0] == ic[-1].arg[0] && ic[-3].arg[1] == ic[-2].arg[0] &&
3410  ic[-2].arg[0] == ic[-2].arg[1] && ic[-2].arg[2] == 1 &&
3411  ic[-2].f == instr(addiu) && ic[-1].arg[2] == (size_t) &ic[-3] &&
3412  ic[-1].arg[1] == (size_t) &cpu->cd.mips.gpr[MIPS_GPR_ZERO] &&
3413  ic[-1].f == instr(bne_samepage)) {
3414  ic[-3].f = instr(netbsd_strlen);
3415  return;
3416  }
3417 #endif
3418 
3419  if (ic[-1].f == instr(bne_samepage)) {
3420  ic[-1].f = instr(bne_samepage_nop);
3421  return;
3422  }
3423 
3424  if (ic[-1].f == instr(beq_samepage)) {
3425  ic[-1].f = instr(beq_samepage_nop);
3426  return;
3427  }
3428 
3429  /* TODO: other branches that are followed by nop should be here */
3430 }
3431 
3432 
3433 /*
3434  * Combine:
3435  *
3436  * xor + andi + sll
3437  * andi + sll
3438  */
3439 void COMBINE(sll)(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
3440 {
3441  int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3442  & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3443 
3444  if (n_back < 2)
3445  return;
3446 
3447  if (ic[-2].f == instr(xor) && ic[-1].f == instr(andi)) {
3448  ic[-2].f = instr(xor_andi_sll);
3449  return;
3450  }
3451 
3452  if (ic[-1].f == instr(andi)) {
3453  ic[-1].f = instr(andi_sll);
3454  return;
3455  }
3456 }
3457 
3458 
3459 /*
3460  * lui + ori
3461  */
3462 void COMBINE(ori)(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
3463 {
3464  int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3465  & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3466 
3467  if (n_back < 1)
3468  return;
3469 
3470  if (ic[-1].f == instr(set)) {
3471  ic[-1].f = instr(lui_ori);
3472  return;
3473  }
3474 }
3475 
3476 
3477 /*
3478  * addu + addu + addu
3479  */
3480 void COMBINE(addu)(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
3481 {
3482  int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3483  & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3484 
3485  if (n_back < 4)
3486  return;
3487 
3488  /* Avoid "overlapping" instruction combinations: */
3489  if (ic[-4].f == instr(multi_addu_3) ||
3490  ic[-3].f == instr(multi_addu_3))
3491  return;
3492 
3493  if (ic[-2].f == instr(addu) && ic[-1].f == instr(addu)) {
3494  ic[-2].f = instr(multi_addu_3);
3495  return;
3496  }
3497 }
3498 
3499 
3500 /*
3501  * Combine:
3502  *
3503  * [Conditional] branch, followed by addiu.
3504  */
3505 void COMBINE(addiu)(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 < 2)
3511  return;
3512 
3513  if (ic[-2].f == instr(addiu) &&
3514  ic[-1].f == instr(bne_samepage)) {
3515  ic[-2].f = instr(addiu_bne_samepage_addiu);
3516  return;
3517  }
3518 
3519  if (ic[-1].f == instr(set)) {
3520  ic[-1].f = instr(lui_addiu);
3521  return;
3522  }
3523 
3524  if (ic[-1].f == instr(b_samepage)) {
3525  ic[-1].f = instr(b_samepage_addiu);
3526  return;
3527  }
3528 
3529  if (ic[-1].f == instr(beq_samepage)) {
3530  ic[-1].f = instr(beq_samepage_addiu);
3531  return;
3532  }
3533 
3534  if (ic[-1].f == instr(bne_samepage)) {
3535  ic[-1].f = instr(bne_samepage_addiu);
3536  return;
3537  }
3538 
3539  if (ic[-1].f == instr(jr_ra)) {
3540  ic[-1].f = instr(jr_ra_addiu);
3541  return;
3542  }
3543 
3544  /* TODO: other branches that are followed by addiu should be here */
3545 }
3546 
3547 
3548 /*
3549  * Combine: [Conditional] branch, followed by daddiu.
3550  */
3551 void COMBINE(b_daddiu)(struct cpu *cpu, struct mips_instr_call *ic,
3552  int low_addr)
3553 {
3554  int n_back = (low_addr >> MIPS_INSTR_ALIGNMENT_SHIFT)
3555  & (MIPS_IC_ENTRIES_PER_PAGE - 1);
3556 
3557  if (n_back < 1)
3558  return;
3559 
3560  if (ic[-1].f == instr(b_samepage)) {
3561  ic[-1].f = instr(b_samepage_daddiu);
3562  }
3563 
3564  /* TODO: other branches that are followed by daddiu should be here */
3565 }
3566 
3567 
3568 /*****************************************************************************/
3569 
3570 
3571 /*
3572  * mips_instr_to_be_translated():
3573  *
3574  * Translate an instruction word into a mips_instr_call. ic is filled in with
3575  * valid data for the translated instruction, or a "nothing" instruction if
3576  * there was a translation failure. The newly translated instruction is then
3577  * executed.
3578  */
3579 X(to_be_translated)
3580 {
3581  uint64_t addr, low_pc;
3582  uint32_t iword, imm;
3583  unsigned char *page;
3584  unsigned char ib[4];
3585  int main_opcode, rt, rs, rd, sa, s6, x64 = 0, s10;
3586  int in_crosspage_delayslot = 0;
3587  void (*samepage_function)(struct cpu *, struct mips_instr_call *);
3588  int store, signedness, size;
3589 
3590  /* Figure out the (virtual) address of the instruction: */
3591  low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
3592  / sizeof(struct mips_instr_call);
3593 
3594  /* Special case for branch with delayslot on the next page: */
3595  if (cpu->delay_slot == TO_BE_DELAYED && low_pc == 0) {
3596  /* fatal("[ delay-slot translation across page "
3597  "boundary ]\n"); */
3598  in_crosspage_delayslot = 1;
3599  }
3600 
3601  addr = cpu->pc & ~((MIPS_IC_ENTRIES_PER_PAGE-1)
3603  addr += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
3604  cpu->pc = (MODE_int_t)addr;
3605  addr &= ~((1 << MIPS_INSTR_ALIGNMENT_SHIFT) - 1);
3606 
3607  /* Read the instruction word from memory: */
3608 #ifdef MODE32
3609  page = cpu->cd.mips.host_load[(uint32_t)addr >> 12];
3610 #else
3611  {
3612  const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
3613  const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
3614  const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
3615  uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
3616  uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
3617  uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
3618  DYNTRANS_L3N)) & mask3;
3619  struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.mips.l1_64[x1];
3620  struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
3621  page = l3->host_load[x3];
3622  }
3623 #endif
3624 
3625  if (page != NULL) {
3626  /* fatal("TRANSLATION HIT!\n"); */
3627  memcpy(ib, page + (addr & 0xffc), sizeof(ib));
3628  } else {
3629  /* fatal("TRANSLATION MISS!\n"); */
3630  if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
3631  sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
3632  fatal("to_be_translated(): read failed: TODO\n");
3633  goto bad;
3634  }
3635  }
3636 
3637  {
3638  uint32_t *p = (uint32_t *) ib;
3639  iword = *p;
3640  }
3641 
3643  iword = LE32_TO_HOST(iword);
3644  else
3645  iword = BE32_TO_HOST(iword);
3646 
3647 
3648 #define DYNTRANS_TO_BE_TRANSLATED_HEAD
3649 #include "cpu_dyntrans.cc"
3650 #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
3651 
3652 
3653  /*
3654  * Translate the instruction:
3655  *
3656  * NOTE: _NEVER_ allow writes to the zero register; all instructions
3657  * that use the zero register as their destination should be treated
3658  * as NOPs, except those that access memory (they should use the
3659  * scratch register instead).
3660  */
3661 
3662  main_opcode = iword >> 26;
3663  rs = (iword >> 21) & 31;
3664  rt = (iword >> 16) & 31;
3665  rd = (iword >> 11) & 31;
3666  sa = (iword >> 6) & 31;
3667  imm = (int16_t)iword;
3668  s6 = iword & 63;
3669  s10 = (rs << 5) | sa;
3670 
3671  switch (main_opcode) {
3672 
3673  case HI6_SPECIAL:
3674  switch (s6) {
3675 
3676  case SPECIAL_SLL:
3677  case SPECIAL_SLLV:
3678  case SPECIAL_SRL:
3679  case SPECIAL_SRLV:
3680  case SPECIAL_SRA:
3681  case SPECIAL_SRAV:
3682  case SPECIAL_DSRL:
3683  case SPECIAL_DSRLV:
3684  case SPECIAL_DSRL32:
3685  case SPECIAL_DSLL:
3686  case SPECIAL_DSLLV:
3687  case SPECIAL_DSLL32:
3688  case SPECIAL_DSRA:
3689  case SPECIAL_DSRAV:
3690  case SPECIAL_DSRA32:
3691  switch (s6) {
3692  case SPECIAL_SLL: ic->f = instr(sll); break;
3693  case SPECIAL_SLLV: ic->f = instr(sllv); sa = -1; break;
3694  case SPECIAL_SRL: ic->f = instr(srl); break;
3695  case SPECIAL_SRLV: ic->f = instr(srlv); sa = -1; break;
3696  case SPECIAL_SRA: ic->f = instr(sra); break;
3697  case SPECIAL_SRAV: ic->f = instr(srav); sa = -1; break;
3698  case SPECIAL_DSRL: ic->f = instr(dsrl); x64=1; break;
3699  case SPECIAL_DSRLV:ic->f = instr(dsrlv);
3700  x64 = 1; sa = -1; break;
3701  case SPECIAL_DSRL32:ic->f= instr(dsrl); x64=1;
3702  sa += 32; break;
3703  case SPECIAL_DSLL: ic->f = instr(dsll); x64=1; break;
3704  case SPECIAL_DSLLV:ic->f = instr(dsllv);
3705  x64 = 1; sa = -1; break;
3706  case SPECIAL_DSLL32:ic->f= instr(dsll); x64=1;
3707  sa += 32; break;
3708  case SPECIAL_DSRA: ic->f = instr(dsra); x64=1; break;
3709  case SPECIAL_DSRAV:ic->f = instr(dsrav);
3710  x64 = 1; sa = -1; break;
3711  case SPECIAL_DSRA32:ic->f = instr(dsra); x64=1;
3712  sa += 32; break;
3713  }
3714 
3715  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
3716  if (sa >= 0)
3717  ic->arg[1] = sa;
3718  else
3719  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
3720  ic->arg[2] = (size_t)&cpu->cd.mips.gpr[rd];
3721 
3722  /* Special checks for MIPS32/64 revision 2 opcodes,
3723  such as rotation instructions: */
3724  if (sa >= 0 && rs != 0x00) {
3725  if (cpu->cd.mips.cpu_type.isa_level < 32 ||
3726  cpu->cd.mips.cpu_type.isa_revision < 2) {
3727  static int warning_rotate = 0;
3728  if (!warning_rotate &&
3730  fatal("[ WARNING! MIPS32/64 "
3731  "revision 2 rotate opcode"
3732  " used, but the %s process"
3733  "or does not implement "
3734  "such instructions. Only "
3735  "printing this "
3736  "warning once. ]\n",
3737  cpu->cd.mips.cpu_type.name);
3738  warning_rotate = 1;
3739  }
3740  ic->f = instr(reserved);
3741  break;
3742  }
3743  switch (rs) {
3744  case 0x01:
3745  switch (s6) {
3746  case SPECIAL_SRL: /* ror (aka. rotr?) */
3747  ic->f = instr(ror);
3748  break;
3749  default:goto bad;
3750  }
3751  break;
3752  default:goto bad;
3753  }
3754  }
3755  if (sa < 0 && (s10 & 0x1f) != 0) {
3756  int orig_sa = (iword >> 6) & 31;
3757  switch (s6) {
3758  case SPECIAL_SRLV: /* rorv (aka. rotrv?) */
3759  if (orig_sa == 0x01) {
3760  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
3761  ic->f = instr(rorv);
3762  }
3763  break;
3764  default:goto bad;
3765  }
3766  break;
3767  }
3768 
3769  if (rd == MIPS_GPR_ZERO)
3770  ic->f = instr(nop);
3771  if (ic->f == instr(sll))
3772  cpu->cd.mips.combination_check = COMBINE(sll);
3773  if (ic->f == instr(nop))
3774  cpu->cd.mips.combination_check = COMBINE(nop);
3775  break;
3776 
3777  case SPECIAL_ADD:
3778  case SPECIAL_ADDU:
3779  case SPECIAL_SUB:
3780  case SPECIAL_SUBU:
3781  case SPECIAL_DADD:
3782  case SPECIAL_DADDU:
3783  case SPECIAL_DSUB:
3784  case SPECIAL_DSUBU:
3785  case SPECIAL_SLT:
3786  case SPECIAL_SLTU:
3787  case SPECIAL_AND:
3788  case SPECIAL_OR:
3789  case SPECIAL_XOR:
3790  case SPECIAL_NOR:
3791  case SPECIAL_MOVN:
3792  case SPECIAL_MOVZ:
3793  case SPECIAL_MFHI:
3794  case SPECIAL_MFLO:
3795  case SPECIAL_MTHI:
3796  case SPECIAL_MTLO:
3797  case SPECIAL_DIV:
3798  case SPECIAL_DIVU:
3799  case SPECIAL_DDIV:
3800  case SPECIAL_DDIVU:
3801  case SPECIAL_MULT:
3802  case SPECIAL_MULTU:
3803  case SPECIAL_DMULT:
3804  case SPECIAL_DMULTU:
3805  case SPECIAL_TGE:
3806  case SPECIAL_TGEU:
3807  case SPECIAL_TLT:
3808  case SPECIAL_TLTU:
3809  case SPECIAL_TEQ:
3810  case SPECIAL_TNE:
3811  switch (s6) {
3812  case SPECIAL_ADD: ic->f = instr(add); break;
3813  case SPECIAL_ADDU: ic->f = instr(addu); break;
3814  case SPECIAL_SUB: ic->f = instr(sub); break;
3815  case SPECIAL_SUBU: ic->f = instr(subu); break;
3816  case SPECIAL_DADD: ic->f = instr(dadd); x64=1; break;
3817  case SPECIAL_DADDU: ic->f = instr(daddu); x64=1; break;
3818  case SPECIAL_DSUB: ic->f = instr(dsub); x64=1; break;
3819  case SPECIAL_DSUBU: ic->f = instr(dsubu); x64=1; break;
3820  case SPECIAL_SLT: ic->f = instr(slt); break;
3821  case SPECIAL_SLTU: ic->f = instr(sltu); break;
3822  case SPECIAL_AND: ic->f = instr(and); break;
3823  case SPECIAL_OR: ic->f = instr(or); break;
3824  case SPECIAL_XOR: ic->f = instr(xor); break;
3825  case SPECIAL_NOR: ic->f = instr(nor); break;
3826  case SPECIAL_MFHI: ic->f = instr(mov); break;
3827  case SPECIAL_MFLO: ic->f = instr(mov); break;
3828  case SPECIAL_MTHI: ic->f = instr(mov); break;
3829  case SPECIAL_MTLO: ic->f = instr(mov); break;
3830  case SPECIAL_DIV: ic->f = instr(div); break;
3831  case SPECIAL_DIVU: ic->f = instr(divu); break;
3832  case SPECIAL_DDIV: ic->f = instr(ddiv); x64=1; break;
3833  case SPECIAL_DDIVU: ic->f = instr(ddivu); x64=1; break;
3834  case SPECIAL_MULT : ic->f = instr(mult); break;
3835  case SPECIAL_MULTU: ic->f = instr(multu); break;
3836  case SPECIAL_DMULT: ic->f = instr(dmult); x64=1; break;
3837  case SPECIAL_DMULTU:ic->f = instr(dmultu); x64=1; break;
3838  case SPECIAL_TGE: ic->f = instr(tge); break;
3839  case SPECIAL_TGEU: ic->f = instr(tgeu); break;
3840  case SPECIAL_TLT: ic->f = instr(tlt); break;
3841  case SPECIAL_TLTU: ic->f = instr(tltu); break;
3842  case SPECIAL_TEQ: ic->f = instr(teq); break;
3843  case SPECIAL_TNE: ic->f = instr(tne); break;
3844  case SPECIAL_MOVN: ic->f = instr(movn); break;
3845  case SPECIAL_MOVZ: ic->f = instr(movz); break;
3846  }
3847 
3848  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
3849  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt];
3850  ic->arg[2] = (size_t)&cpu->cd.mips.gpr[rd];
3851 
3852  switch (s6) {
3853  case SPECIAL_MFHI:
3854  ic->arg[0] = (size_t)&cpu->cd.mips.hi;
3855  break;
3856  case SPECIAL_MFLO:
3857  ic->arg[0] = (size_t)&cpu->cd.mips.lo;
3858  break;
3859  case SPECIAL_MTHI:
3860  ic->arg[2] = (size_t)&cpu->cd.mips.hi;
3861  break;
3862  case SPECIAL_MTLO:
3863  ic->arg[2] = (size_t)&cpu->cd.mips.lo;
3864  break;
3865  }
3866  /* Special cases for rd: */
3867  switch (s6) {
3868  case SPECIAL_MTHI:
3869  case SPECIAL_MTLO:
3870  case SPECIAL_DIV:
3871  case SPECIAL_DIVU:
3872  case SPECIAL_DDIV:
3873  case SPECIAL_DDIVU:
3874  case SPECIAL_MULT:
3875  case SPECIAL_MULTU:
3876  case SPECIAL_DMULT:
3877  case SPECIAL_DMULTU:
3878  if (s6 == SPECIAL_MULT && rd != MIPS_GPR_ZERO) {
3879  if (cpu->cd.mips.cpu_type.rev ==
3880  MIPS_R5900) {
3881  ic->f = instr(mult_r5900);
3882  break;
3883  }
3884  break;
3885  }
3886  if (s6 == SPECIAL_MULTU && rd!=MIPS_GPR_ZERO) {
3887  if (cpu->cd.mips.cpu_type.rev ==
3888  MIPS_R5900) {
3889  ic->f = instr(multu_r5900);
3890  break;
3891  }
3892  }
3893  if (rd != MIPS_GPR_ZERO) {
3894  if (!cpu->translation_readahead)
3895  fatal("TODO: rd NON-zero\n");
3896  goto bad;
3897  }
3898  /* These instructions don't use rd. */
3899  break;
3900  case SPECIAL_TGE:
3901  case SPECIAL_TGEU:
3902  case SPECIAL_TLT:
3903  case SPECIAL_TLTU:
3904  case SPECIAL_TEQ:
3905  case SPECIAL_TNE:
3906  /* In these instructions, rd is a 'code',
3907  only read by trap handling software. */
3908  break;
3909  default:if (rd == MIPS_GPR_ZERO)
3910  ic->f = instr(nop);
3911  }
3912 
3913  if (ic->f == instr(addu))
3914  cpu->cd.mips.combination_check = COMBINE(addu);
3915 
3916  break;
3917 
3918  case SPECIAL_JR:
3919  case SPECIAL_JALR:
3920  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
3921  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rd];
3922  if (s6 == SPECIAL_JALR && rd == MIPS_GPR_ZERO)
3923  s6 = SPECIAL_JR;
3924  ic->arg[2] = (addr & 0xffc) + 8;
3925  switch (s6) {
3926  case SPECIAL_JR:
3927  if (rs == MIPS_GPR_RA) {
3928  if (cpu->machine->show_trace_tree)
3929  ic->f = instr(jr_ra_trace);
3930  else
3931  ic->f = instr(jr_ra);
3932  } else {
3933  ic->f = instr(jr);
3934  }
3935  if (cpu->translation_readahead > 2)
3937  break;
3938  case SPECIAL_JALR:
3939  if (cpu->machine->show_trace_tree)
3940  ic->f = instr(jalr_trace);
3941  else
3942  ic->f = instr(jalr);
3943  break;
3944  }
3945  if (cpu->delay_slot) {
3946  if (!cpu->translation_readahead)
3947  fatal("TODO: branch in delay "
3948  "slot? (1)\n");
3949  goto bad;
3950  }
3951  break;
3952 
3953  case SPECIAL_SYSCALL:
3954  if (((iword >> 6) & 0xfffff) == 0x30378) {
3955  /* "Magic trap" for PROM emulation: */
3956  ic->f = instr(promemul);
3957  } else {
3958  ic->f = instr(syscall);
3959  }
3960  break;
3961 
3962  case SPECIAL_BREAK:
3963  if (((iword >> 6) & 0xfffff) == 0x30378) {
3964  /* "Magic trap" for REBOOT: */
3965  ic->f = instr(reboot);
3966  } else {
3967  ic->f = instr(break);
3968  }
3969  break;
3970 
3971  case SPECIAL_SYNC:
3972  ic->f = instr(nop);
3973  break;
3974 
3975  default:goto bad;
3976  }
3977  break;
3978 
3979  case HI6_BEQ:
3980  case HI6_BNE:
3981  case HI6_BEQL:
3982  case HI6_BNEL:
3983  case HI6_BLEZ:
3984  case HI6_BLEZL:
3985  case HI6_BGTZ:
3986  case HI6_BGTZL:
3987  samepage_function = NULL; /* get rid of a compiler warning */
3988  switch (main_opcode) {
3989  case HI6_BEQ:
3990  ic->f = instr(beq);
3991  samepage_function = instr(beq_samepage);
3992  /* Special case: comparing a register with itself: */
3993  if (rs == rt) {
3994  ic->f = instr(b);
3995  samepage_function = instr(b_samepage);
3996  }
3997  break;
3998  case HI6_BNE:
3999  ic->f = instr(bne);
4000  samepage_function = instr(bne_samepage);
4001  break;
4002  case HI6_BEQL:
4003  ic->f = instr(beql);
4004  samepage_function = instr(beql_samepage);
4005  /* Special case: comparing a register with itself: */
4006  if (rs == rt) {
4007  ic->f = instr(b);
4008  samepage_function = instr(b_samepage);
4009  }
4010  break;
4011  case HI6_BNEL:
4012  ic->f = instr(bnel);
4013  samepage_function = instr(bnel_samepage);
4014  break;
4015  case HI6_BLEZ:
4016  ic->f = instr(blez);
4017  samepage_function = instr(blez_samepage);
4018  break;
4019  case HI6_BLEZL:
4020  ic->f = instr(blezl);
4021  samepage_function = instr(blezl_samepage);
4022  break;
4023  case HI6_BGTZ:
4024  ic->f = instr(bgtz);
4025  samepage_function = instr(bgtz_samepage);
4026  break;
4027  case HI6_BGTZL:
4028  ic->f = instr(bgtzl);
4029  samepage_function = instr(bgtzl_samepage);
4030  break;
4031  }
4032  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4033  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt];
4034  ic->arg[2] = (int32_t) ( (imm << MIPS_INSTR_ALIGNMENT_SHIFT)
4035  + (addr & 0xffc) + 4 );
4036  /* Is the offset from the start of the current page still
4037  within the same page? Then use the samepage_function: */
4038  if ((uint32_t)ic->arg[2] < ((MIPS_IC_ENTRIES_PER_PAGE - 1)
4039  << MIPS_INSTR_ALIGNMENT_SHIFT) && (addr & 0xffc) < 0xffc) {
4040  ic->arg[2] = (size_t) (cpu->cd.mips.cur_ic_page +
4041  ((ic->arg[2] >> MIPS_INSTR_ALIGNMENT_SHIFT)
4042  & (MIPS_IC_ENTRIES_PER_PAGE - 1)));
4043  ic->f = samepage_function;
4044  }
4045  if (cpu->delay_slot) {
4046  if (!cpu->translation_readahead)
4047  fatal("TODO: branch in delay slot? (2)\n");
4048  goto bad;
4049  }
4050  break;
4051 
4052  case HI6_ADDI:
4053  case HI6_ADDIU:
4054  case HI6_SLTI:
4055  case HI6_SLTIU:
4056  case HI6_DADDI:
4057  case HI6_DADDIU:
4058  case HI6_ANDI:
4059  case HI6_ORI:
4060  case HI6_XORI:
4061  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4062  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt];
4063  if (main_opcode == HI6_ADDI ||
4064  main_opcode == HI6_ADDIU ||
4065  main_opcode == HI6_SLTI ||
4066  main_opcode == HI6_SLTIU ||
4067  main_opcode == HI6_DADDI ||
4068  main_opcode == HI6_DADDIU)
4069  ic->arg[2] = (int16_t)iword;
4070  else
4071  ic->arg[2] = (uint16_t)iword;
4072 
4073  switch (main_opcode) {
4074  case HI6_ADDI: ic->f = instr(addi); break;
4075  case HI6_ADDIU: ic->f = instr(addiu); break;
4076  case HI6_SLTI: ic->f = instr(slti); break;
4077  case HI6_SLTIU: ic->f = instr(sltiu); break;
4078  case HI6_DADDI: ic->f = instr(daddi); x64 = 1; break;
4079  case HI6_DADDIU: ic->f = instr(daddiu); x64 = 1; break;
4080  case HI6_ANDI: ic->f = instr(andi); break;
4081  case HI6_ORI: ic->f = instr(ori); break;
4082  case HI6_XORI: ic->f = instr(xori); break;
4083  }
4084 
4085  if (ic->arg[2] == 0) {
4086  if ((cpu->is_32bit && ic->f == instr(addiu)) ||
4087  (!cpu->is_32bit && ic->f == instr(daddiu))) {
4088  ic->f = instr(mov);
4089  ic->arg[2] = ic->arg[1];
4090  }
4091  }
4092 
4093  if (rt == MIPS_GPR_ZERO)
4094  ic->f = instr(nop);
4095 
4096  if (ic->f == instr(ori))
4097  cpu->cd.mips.combination_check = COMBINE(ori);
4098  if (ic->f == instr(addiu))
4099  cpu->cd.mips.combination_check = COMBINE(addiu);
4100  if (ic->f == instr(daddiu))
4101  cpu->cd.mips.combination_check = COMBINE(b_daddiu);
4102  break;
4103 
4104  case HI6_LUI:
4105  ic->f = instr(set);
4106  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4107  ic->arg[1] = (int32_t) (imm << 16);
4108  /* NOTE: Don't use arg[2] here. It can be used with
4109  instruction combinations, to do lui + addiu, etc. */
4110  if (rt == MIPS_GPR_ZERO)
4111  ic->f = instr(nop);
4112  break;
4113 
4114  case HI6_J:
4115  case HI6_JAL:
4116  switch (main_opcode) {
4117  case HI6_J:
4118  ic->f = instr(j);
4119  if (cpu->translation_readahead > 2)
4121  break;
4122  case HI6_JAL:
4123  if (cpu->machine->show_trace_tree)
4124  ic->f = instr(jal_trace);
4125  else
4126  ic->f = instr(jal);
4127  break;
4128  }
4129  ic->arg[0] = (iword & 0x03ffffff) << 2;
4130  ic->arg[1] = (addr & 0xffc) + 8;
4131  if (cpu->delay_slot) {
4132  if (!cpu->translation_readahead)
4133  fatal("TODO: branch in delay slot (=%i)? (3);"
4134  " addr=%016" PRIx64" iword=%08" PRIx32"\n",
4135  cpu->delay_slot, (uint64_t)addr, iword);
4136  goto bad;
4137  }
4138  break;
4139 
4140  case HI6_COP0:
4141  /* TODO: Is checking bit 25 enough, or perhaps all bits
4142  25..21 must be checked? */
4143  if ((iword >> 25) & 1) {
4144  ic->arg[2] = addr & 0xffc;
4145  switch (iword & 0xff) {
4146  case COP0_TLBR:
4147  ic->f = instr(tlbr);
4148  break;
4149  case COP0_TLBWI:
4150  case COP0_TLBWR:
4151  ic->f = instr(tlbw);
4152  ic->arg[0] = (iword & 0xff) == COP0_TLBWR;
4153  break;
4154  case COP0_TLBP:
4155  ic->f = instr(tlbp);
4156  break;
4157  case COP0_RFE:
4158  ic->f = instr(rfe);
4159  break;
4160  case COP0_ERET:
4161  ic->f = instr(eret);
4162  break;
4163  case COP0_DERET:
4164  ic->f = instr(deret);
4165  break;
4166  case COP0_WAIT:
4167  ic->f = instr(wait);
4168  if (cpu->cd.mips.cpu_type.rev != MIPS_RM5200 &&
4169  cpu->cd.mips.cpu_type.isa_level < 32) {
4170  static int warned = 0;
4171  ic->f = instr(reserved);
4172  if (!warned &&
4174  fatal("{ WARNING: Attempt to "
4175  "execute the WAIT instruct"
4176  "ion, but the emulated CPU "
4177  "is neither RM52xx, nor "
4178  "MIPS32/64! }\n");
4179  warned = 1;
4180  }
4181  }
4182  break;
4183  case COP0_STANDBY:
4184  /* NOTE: Reusing the 'wait' instruction: */
4185  ic->f = instr(wait);
4186  if (cpu->cd.mips.cpu_type.rev != MIPS_R4100) {
4187  static int warned = 0;
4188  ic->f = instr(reserved);
4189  if (!warned &&
4191  fatal("{ WARNING: Attempt to "
4192  "execute a R41xx instruct"
4193  "ion, but the emulated CPU "
4194  "doesn't support it! }\n");
4195  warned = 1;
4196  }
4197  }
4198  break;
4199  case COP0_HIBERNATE:
4200  /* TODO */
4201  goto bad;
4202  case COP0_SUSPEND:
4203  /* Used by NetBSD on HPCmips (VR41xx) to
4204  halt the machine. */
4205  ic->f = instr(reboot);
4206  break;
4207  case COP0_EI:
4208  if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
4209  ic->f = instr(ei_r5900);
4210  } else
4211  goto bad;
4212  break;
4213  case COP0_DI:
4214  if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
4215  ic->f = instr(di_r5900);
4216  } else
4217  goto bad;
4218  break;
4219  default:if (!cpu->translation_readahead)
4220  fatal("UNIMPLEMENTED cop0 (func "
4221  "0x%02x)\n", iword & 0xff);
4222  goto bad;
4223  }
4224  break;
4225  }
4226 
4227  /* rs contains the coprocessor opcode! */
4228  switch (rs) {
4229  case COPz_CFCz:
4230  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4231  ic->arg[1] = rd + ((iword & 7) << 5);
4232  ic->arg[2] = addr & 0xffc;
4233  ic->f = instr(cfc0);
4234  if (rt == MIPS_GPR_ZERO)
4235  ic->f = instr(nop);
4236  break;
4237  case COPz_MFCz:
4238  case COPz_DMFCz:
4239  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4240  ic->arg[1] = rd + ((iword & 7) << 5);
4241  ic->arg[2] = addr & 0xffc;
4242  ic->f = rs == COPz_MFCz? instr(mfc0) : instr(dmfc0);
4243  if (rs == COPz_MFCz && (iword & 7) == 0 &&
4244  rd != COP0_COUNT)
4245  ic->f = instr(mfc0_select0);
4246  if (rs == COPz_DMFCz && (iword & 7) == 0 &&
4247  rd != COP0_COUNT)
4248  ic->f = instr(dmfc0_select0);
4249  if (rt == MIPS_GPR_ZERO)
4250  ic->f = instr(nop);
4251  break;
4252  case COPz_MTCz:
4253  case COPz_DMTCz:
4254  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4255  ic->arg[1] = rd + ((iword & 7) << 5);
4256  ic->arg[2] = addr & 0xffc;
4257  ic->f = rs == COPz_MTCz? instr(mtc0) : instr(dmtc0);
4258 
4259  if (cpu->cd.mips.cpu_type.exc_model == EXC3K &&
4260  rs == COPz_MTCz && rd == COP0_STATUS)
4261  cpu->cd.mips.combination_check =
4263 
4264  break;
4265  case COPz_MFMCz:
4266  if ((iword & 0xffdf) == 0x6000) {
4267  /* MIPS32/64 rev 2 "ei" or "di": */
4268  if (cpu->cd.mips.cpu_type.isa_level < 32 ||
4269  cpu->cd.mips.cpu_type.isa_revision < 2) {
4270  static int warning_ei_di = 0;
4271  if (!warning_ei_di &&
4273  fatal("[ WARNING! MIPS32/64 "
4274  "revision 2 di or ei opcode"
4275  " used, but the %s process"
4276  "or does not implement "
4277  "such instructions. Only "
4278  "printing this "
4279  "warning once. ]\n",
4280  cpu->cd.mips.cpu_type.name);
4281  warning_ei_di = 1;
4282  }
4283  ic->f = instr(reserved);
4284  break;
4285  }
4286  ic->f = instr(ei_or_di);
4287  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4288  if (rt == MIPS_GPR_ZERO)
4289  ic->arg[0] =
4290  (size_t)&cpu->cd.mips.scratch;
4291  ic->arg[1] = iword & 0x20;
4292  } else {
4293  if (!cpu->translation_readahead)
4294  fatal("Unimplemented COP0_MFMCz\n");
4295  goto bad;
4296  }
4297  break;
4298  case COPz_BCzc:
4299  if (iword == 0x4100ffff) {
4300  /* R2020 DECstation write-loop thingy. */
4301  ic->f = instr(nop);
4302  } else {
4303  if (!cpu->translation_readahead)
4304  fatal("Unimplemented COP0_BCzc\n");
4305  goto bad;
4306  }
4307  break;
4308 
4309  default:if (!cpu->translation_readahead)
4310  fatal("UNIMPLEMENTED cop0 (rs = %i)\n", rs);
4311  goto bad;
4312  }
4313  break;
4314 
4315  case HI6_COP1:
4316  /* Always cause a coprocessor unusable exception if
4317  there is no floating point coprocessor: */
4318  if (cpu->cd.mips.cpu_type.flags & NOFPU ||
4319  cpu->cd.mips.coproc[1] == NULL) {
4320  ic->f = instr(cpu);
4321  ic->arg[0] = 1;
4322  break;
4323  }
4324 
4325  /* Bits 25..21 are floating point main opcode: */
4326  switch (rs) {
4327 
4328  case COPz_BCzc:
4329  /* Conditional branch: */
4330  /* TODO: Reimplement this in a faster way. */
4331  ic->f = instr(cop1_bc);
4332  ic->arg[0] = (iword >> 18) & 7; /* cc */
4333  ic->arg[1] = (iword >> 16) & 3; /* nd, tf bits */
4334  ic->arg[2] = (int32_t) ((imm <<
4335  MIPS_INSTR_ALIGNMENT_SHIFT) + (addr & 0xffc) + 4);
4336  if (cpu->delay_slot) {
4337  if (!cpu->translation_readahead)
4338  fatal("TODO: branch in delay slot 4\n");
4339  goto bad;
4340  }
4341  if (cpu->cd.mips.cpu_type.isa_level <= 3 &&
4342  ic->arg[0] != 0) {
4343  if (!cpu->translation_readahead)
4344  fatal("Attempt to execute a non-cc-0 "
4345  "BC* instruction on an isa level "
4346  "%i cpu. TODO: How should this be "
4347  "handled?\n",
4349  goto bad;
4350  }
4351 
4352  break;
4353 
4354  case COPz_DMFCz:
4355  case COPz_DMTCz:
4356  x64 = 1;
4357  /* FALL-THROUGH */
4358  case COP1_FMT_S:
4359  case COP1_FMT_D:
4360  case COP1_FMT_W:
4361  case COP1_FMT_L:
4362  case COP1_FMT_PS:
4363  case COPz_CFCz:
4364  case COPz_CTCz:
4365  case COPz_MFCz:
4366  case COPz_MTCz:
4367  /* Fallback to slow pre-dyntrans code, for now. */
4368  /* TODO: Fix/optimize/rewrite. */
4369  ic->f = instr(cop1_slow);
4370  ic->arg[0] = (uint32_t)iword & ((1 << 26) - 1);
4371  break;
4372 
4373  default:if (!cpu->translation_readahead)
4374  fatal("COP1 floating point opcode = 0x%02x\n", rs);
4375  goto bad;
4376  }
4377  break;
4378 
4379  case HI6_COP2:
4380  /* Always cause a coprocessor unusable exception if
4381  there is no coprocessor 2: */
4382  if (cpu->cd.mips.coproc[2] == NULL) {
4383  ic->f = instr(cpu);
4384  ic->arg[0] = 2;
4385  break;
4386  }
4387  if (!cpu->translation_readahead)
4388  fatal("COP2 functionality not yet implemented\n");
4389  goto bad;
4390  break;
4391 
4392  case HI6_COP3:
4393  /* Always cause a coprocessor unusable exception if
4394  there is no coprocessor 3: */
4395  if (cpu->cd.mips.coproc[3] == NULL) {
4396  ic->f = instr(cpu);
4397  ic->arg[0] = 3;
4398  break;
4399  }
4400 
4401  if (iword == 0x4d00ffff) {
4402  /* R2020 writeback thing, used by e.g. NetBSD/pmax
4403  on MIPSMATE. */
4404  ic->f = instr(nop);
4405  } else {
4406  if (!cpu->translation_readahead)
4407  fatal("COP3 iword=0x%08x\n", iword);
4408  goto bad;
4409  }
4410  break;
4411 
4412  case HI6_SPECIAL2:
4413  if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
4414  /* R5900, TX79/C790, have MMI instead of SPECIAL2: */
4415  int mmi_subopcode = (iword >> 6) & 0x1f;
4416 
4417  switch (s6) {
4418 
4419  case MMI_MADD:
4420  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4421  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt];
4422  ic->arg[2] = (size_t)&cpu->cd.mips.gpr[rd];
4423  if (rd == MIPS_GPR_ZERO)
4424  ic->f = instr(madd);
4425  else
4426  ic->f = instr(madd_rd);
4427  break;
4428 
4429  case MMI_MADDU:
4430  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4431  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt];
4432  ic->arg[2] = (size_t)&cpu->cd.mips.gpr[rd];
4433  if (rd == MIPS_GPR_ZERO)
4434  ic->f = instr(maddu);
4435  else
4436  ic->f = instr(maddu_rd);
4437  break;
4438 
4439  case MMI_MMI0:
4440  switch (mmi_subopcode) {
4441 
4442  case MMI0_PEXTLW:
4443  ic->arg[0] = rs;
4444  ic->arg[1] = rt;
4445  ic->arg[2] = rd;
4446  if (rd == MIPS_GPR_ZERO)
4447  ic->f = instr(nop);
4448  else
4449  ic->f = instr(pextlw);
4450  break;
4451 
4452  default:goto bad;
4453  }
4454  break;
4455 
4456  case MMI_MMI3:
4457  switch (mmi_subopcode) {
4458 
4459  case MMI3_POR:
4460  ic->arg[0] = rs;
4461  ic->arg[1] = rt;
4462  ic->arg[2] = rd;
4463  if (rd == MIPS_GPR_ZERO)
4464  ic->f = instr(nop);
4465  else
4466  ic->f = instr(por);
4467  break;
4468 
4469  default:goto bad;
4470  }
4471  break;
4472 
4473  default:goto bad;
4474  }
4475  break;
4476  }
4477 
4478  /* TODO: is this correct? Or are there other non-MIPS32/64
4479  MIPS processors that have support for SPECIAL2 opcodes? */
4480  if (cpu->cd.mips.cpu_type.isa_level < 32) {
4481  ic->f = instr(reserved);
4482  break;
4483  }
4484 
4485  /* SPECIAL2: */
4486  switch (s6) {
4487 
4488  case SPECIAL2_MADD:
4489  case SPECIAL2_MADDU:
4490  case SPECIAL2_MSUB:
4491  case SPECIAL2_MSUBU:
4492  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4493  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt];
4494  switch (s6) {
4495  case SPECIAL2_MADD: ic->f = instr(madd); break;
4496  case SPECIAL2_MADDU:ic->f = instr(maddu); break;
4497  case SPECIAL2_MSUB: ic->f = instr(msub); break;
4498  case SPECIAL2_MSUBU:ic->f = instr(msubu); break;
4499  }
4500  break;
4501 
4502  case SPECIAL2_MUL:
4503  ic->f = instr(mul);
4504  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4505  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt];
4506  ic->arg[2] = (size_t)&cpu->cd.mips.gpr[rd];
4507  if (rd == MIPS_GPR_ZERO)
4508  ic->f = instr(nop);
4509  break;
4510 
4511  case SPECIAL2_CLZ:
4512  case SPECIAL2_CLO:
4513  case SPECIAL2_DCLZ:
4514  case SPECIAL2_DCLO:
4515  switch (s6) {
4516  case SPECIAL2_CLZ: ic->f = instr(clz); break;
4517  case SPECIAL2_CLO: ic->f = instr(clo); break;
4518  case SPECIAL2_DCLZ: ic->f = instr(dclz); break;
4519  case SPECIAL2_DCLO: ic->f = instr(dclo); break;
4520  }
4521  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4522  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rd];
4523  if (rd == MIPS_GPR_ZERO)
4524  ic->f = instr(nop);
4525  break;
4526 
4527  default:goto bad;
4528  }
4529  break;
4530 
4531  case HI6_REGIMM:
4532  switch (rt) {
4533  case REGIMM_BGEZ:
4534  case REGIMM_BGEZL:
4535  case REGIMM_BLTZ:
4536  case REGIMM_BLTZL:
4537  case REGIMM_BGEZAL:
4538  case REGIMM_BGEZALL:
4539  case REGIMM_BLTZAL:
4540  case REGIMM_BLTZALL:
4541  samepage_function = NULL;
4542  switch (rt) {
4543  case REGIMM_BGEZ:
4544  ic->f = instr(bgez);
4545  samepage_function = instr(bgez_samepage);
4546  break;
4547  case REGIMM_BGEZL:
4548  ic->f = instr(bgezl);
4549  samepage_function = instr(bgezl_samepage);
4550  break;
4551  case REGIMM_BLTZ:
4552  ic->f = instr(bltz);
4553  samepage_function = instr(bltz_samepage);
4554  break;
4555  case REGIMM_BLTZL:
4556  ic->f = instr(bltzl);
4557  samepage_function = instr(bltzl_samepage);
4558  break;
4559  case REGIMM_BGEZAL:
4560  ic->f = instr(bgezal);
4561  samepage_function = instr(bgezal_samepage);
4562  break;
4563  case REGIMM_BGEZALL:
4564  ic->f = instr(bgezall);
4565  samepage_function = instr(bgezall_samepage);
4566  break;
4567  case REGIMM_BLTZAL:
4568  ic->f = instr(bltzal);
4569  samepage_function = instr(bltzal_samepage);
4570  break;
4571  case REGIMM_BLTZALL:
4572  ic->f = instr(bltzall);
4573  samepage_function = instr(bltzall_samepage);
4574  break;
4575  }
4576  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4577  ic->arg[2] = (imm << MIPS_INSTR_ALIGNMENT_SHIFT)
4578  + (addr & 0xffc) + 4;
4579  /* Is the offset from the start of the current page
4580  still within the same page? Then use the
4581  samepage_function: */
4582  if ((uint32_t)ic->arg[2] < ((MIPS_IC_ENTRIES_PER_PAGE-1)
4583  << MIPS_INSTR_ALIGNMENT_SHIFT) && (addr & 0xffc)
4584  < 0xffc) {
4585  ic->arg[2] = (size_t) (cpu->cd.mips.cur_ic_page+
4586  ((ic->arg[2] >> MIPS_INSTR_ALIGNMENT_SHIFT)
4587  & (MIPS_IC_ENTRIES_PER_PAGE - 1)));
4588  ic->f = samepage_function;
4589  }
4590  if (cpu->delay_slot) {
4591  if (!cpu->translation_readahead)
4592  fatal("TODO: branch in delay slot:5\n");
4593  goto bad;
4594  }
4595  break;
4596 
4597  case REGIMM_TGEI:
4598  case REGIMM_TGEIU:
4599  case REGIMM_TLTI:
4600  case REGIMM_TLTIU:
4601  case REGIMM_TEQI:
4602  case REGIMM_TNEI:
4603  switch (rt) {
4604  case REGIMM_TGEI: ic->f = instr(tgei); break;
4605  case REGIMM_TGEIU: ic->f = instr(tgeiu); break;
4606  case REGIMM_TLTI: ic->f = instr(tlti); break;
4607  case REGIMM_TLTIU: ic->f = instr(tltiu); break;
4608  case REGIMM_TEQI: ic->f = instr(teqi); break;
4609  case REGIMM_TNEI: ic->f = instr(tnei); break;
4610  }
4611  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
4612  ic->arg[2] = (int64_t)(int16_t)imm;
4613 
4614  if (cpu->cd.mips.cpu_type.isa_level < 32) {
4615  static int warning = 0;
4616  if (!warning && !cpu->translation_readahead) {
4617  fatal("[ WARNING! Trap opcode used, but"
4618  " the %s processor does not implement "
4619  "such instructions. Only printing this "
4620  "warning once. ]\n",
4621  cpu->cd.mips.cpu_type.name);
4622  warning = 1;
4623  }
4624  ic->f = instr(reserved);
4625  }
4626  break;
4627 
4628  default:if (!cpu->translation_readahead)
4629  fatal("UNIMPLEMENTED regimm rt=%i\n", rt);
4630  goto bad;
4631  }
4632  break;
4633 
4634  case HI6_LB:
4635  case HI6_LBU:
4636  case HI6_SB:
4637  case HI6_LH:
4638  case HI6_LHU:
4639  case HI6_SH:
4640  case HI6_LW:
4641  case HI6_LWU:
4642  case HI6_SW:
4643  case HI6_LD:
4644  case HI6_SD:
4645  /* TODO: LWU should probably also be x64=1? */
4646  size = 2; signedness = 0; store = 0;
4647  switch (main_opcode) {
4648  case HI6_LB: size = 0; signedness = 1; break;
4649  case HI6_LBU: size = 0; break;
4650  case HI6_LH: size = 1; signedness = 1; break;
4651  case HI6_LHU: size = 1; break;
4652  case HI6_LW: signedness = 1; break;
4653  case HI6_LWU: break;
4654  case HI6_LD: size = 3; x64 = 1; break;
4655  case HI6_SB: store = 1; size = 0; break;
4656  case HI6_SH: store = 1; size = 1; break;
4657  case HI6_SW: store = 1; break;
4658  case HI6_SD: store = 1; size = 3; x64 = 1; break;
4659  }
4660 
4661  ic->f =
4662 #ifdef MODE32
4663  mips32_loadstore
4664 #else
4666 #endif
4667  [ (cpu->byte_order == EMUL_LITTLE_ENDIAN? 0 : 16)
4668  + store * 8 + size * 2 + signedness];
4669  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4670  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
4671  ic->arg[2] = (int32_t)imm;
4672 
4673  /* Load into the dummy scratch register, if rt = zero */
4674  if (!store && rt == MIPS_GPR_ZERO)
4675  ic->arg[0] = (size_t)&cpu->cd.mips.scratch;
4676 
4677  /* Check for multiple loads or stores in a row using the same
4678  base register: */
4679  if (main_opcode == HI6_LW)
4680  cpu->cd.mips.combination_check = COMBINE(multi_lw);
4681  if (main_opcode == HI6_SW)
4682  cpu->cd.mips.combination_check = COMBINE(multi_sw);
4683  break;
4684 
4685  case HI6_LL:
4686  case HI6_LLD:
4687  case HI6_SC:
4688  case HI6_SCD:
4689  /* 32-bit load-linked/store-condition for ISA II and up: */
4690  /* (64-bit load-linked/store-condition for ISA III...) */
4691  if (cpu->cd.mips.cpu_type.isa_level < 2) {
4692  ic->f = instr(reserved);
4693  break;
4694  }
4695 
4696  store = 0;
4697  switch (main_opcode) {
4698  case HI6_LL: ic->f = instr(ll); break;
4699  case HI6_LLD: ic->f = instr(lld); x64 = 1; break;
4700  case HI6_SC: ic->f = instr(sc); store = 1; break;
4701  case HI6_SCD: ic->f = instr(scd); store = 1; x64 = 1; break;
4702  }
4703  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4704  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
4705  ic->arg[2] = (int32_t)imm;
4706  if (!store && rt == MIPS_GPR_ZERO) {
4707  if (!cpu->translation_readahead)
4708  fatal("HM... unusual load linked\n");
4709  goto bad;
4710  }
4711  break;
4712 
4713  case HI6_LWL:
4714  case HI6_LWR:
4715  case HI6_LDL:
4716  case HI6_LDR:
4717  case HI6_SWL:
4718  case HI6_SWR:
4719  case HI6_SDL:
4720  case HI6_SDR:
4721  /* TODO: replace these with faster versions... */
4722  store = 0;
4723  switch (main_opcode) {
4724  case HI6_LWL: ic->f = instr(lwl); break;
4725  case HI6_LWR: ic->f = instr(lwr); break;
4726  case HI6_LDL: ic->f = instr(ldl); x64 = 1; break;
4727  case HI6_LDR: ic->f = instr(ldr); x64 = 1; break;
4728  case HI6_SWL: ic->f = instr(swl); store = 1; break;
4729  case HI6_SWR: ic->f = instr(swr); store = 1; break;
4730  case HI6_SDL: ic->f = instr(sdl); store = 1; x64 = 1; break;
4731  case HI6_SDR: ic->f = instr(sdr); store = 1; x64 = 1; break;
4732  }
4733  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4734  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
4735  ic->arg[2] = (int32_t)imm;
4736 
4737  /* Load into the dummy scratch register, if rt = zero */
4738  if (!store && rt == MIPS_GPR_ZERO)
4739  ic->arg[0] = (size_t)&cpu->cd.mips.scratch;
4740  break;
4741 
4742  case HI6_LWC1:
4743  case HI6_SWC1:
4744  case HI6_LDC1:
4745  case HI6_SDC1:
4746  /* 64-bit floating-point load/store for ISA II and up... */
4747  if ((main_opcode == HI6_LDC1 || main_opcode == HI6_SDC1)
4748  && cpu->cd.mips.cpu_type.isa_level < 2) {
4749  ic->f = instr(reserved);
4750  break;
4751  }
4752 
4753  ic->arg[0] = (size_t)&cpu->cd.mips.coproc[1]->reg[rt];
4754  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
4755  ic->arg[2] = (int32_t)imm;
4756  switch (main_opcode) {
4757  case HI6_LWC1: ic->f = instr(lwc1); break;
4758  case HI6_LDC1: ic->f = instr(ldc1); break;
4759  case HI6_SWC1: ic->f = instr(swc1); break;
4760  case HI6_SDC1: ic->f = instr(sdc1); break;
4761  }
4762 
4763  /* Cause a coprocessor unusable exception if
4764  there is no floating point coprocessor: */
4765  if (cpu->cd.mips.cpu_type.flags & NOFPU ||
4766  cpu->cd.mips.coproc[1] == NULL) {
4767  ic->f = instr(cpu);
4768  ic->arg[0] = 1;
4769  }
4770  break;
4771 
4772  case HI6_LWC3:
4773  /* PREF (prefetch) on ISA IV and MIPS32/64: */
4774  if (cpu->cd.mips.cpu_type.isa_level >= 4) {
4775  /* Treat as nop for now: */
4776  ic->f = instr(nop);
4777  } else {
4778  if (!cpu->translation_readahead)
4779  fatal("TODO: lwc3 not implemented yet\n");
4780  goto bad;
4781  }
4782  break;
4783 
4784  case HI6_LQ_MDMX:
4785  if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
4786  if (!cpu->translation_readahead)
4787  fatal("TODO: R5900 128-bit loads\n");
4788  goto bad;
4789  }
4790 
4791  if (!cpu->translation_readahead)
4792  fatal("TODO: MDMX\n");
4793 
4794  goto bad;
4795  /* break */
4796 
4797  case HI6_SQ_SPECIAL3:
4798  if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) {
4799  if (!cpu->translation_readahead)
4800  fatal("TODO: R5900 128-bit stores\n");
4801  goto bad;
4802  }
4803 
4804  if (cpu->cd.mips.cpu_type.isa_level < 32 ||
4805  cpu->cd.mips.cpu_type.isa_revision < 2) {
4806  static int warning = 0;
4807  if (!warning && !cpu->translation_readahead) {
4808  fatal("[ WARNING! SPECIAL3 opcode used, but"
4809  " the %s processor does not implement "
4810  "such instructions. Only printing this "
4811  "warning once. ]\n",
4812  cpu->cd.mips.cpu_type.name);
4813  warning = 1;
4814  }
4815  ic->f = instr(reserved);
4816  break;
4817  }
4818 
4819  switch (s6) {
4820 
4821  case SPECIAL3_EXT:
4822  {
4823  int msbd = rd, lsb = (iword >> 6) & 0x1f;
4824  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4825  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
4826  ic->arg[2] = (msbd << 5) + lsb;
4827  ic->f = instr(ext);
4828  if (rt == MIPS_GPR_ZERO)
4829  ic->f = instr(nop);
4830  }
4831  break;
4832 
4833  case SPECIAL3_DEXT:
4834  case SPECIAL3_DEXTM:
4835  case SPECIAL3_DEXTU:
4836  {
4837  int msbd = rd, lsb = (iword >> 6) & 0x1f;
4838  if (s6 == SPECIAL3_DEXTM)
4839  msbd += 32;
4840  if (s6 == SPECIAL3_DEXTU)
4841  lsb += 32;
4842  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4843  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
4844  ic->arg[2] = (msbd << 6) + lsb;
4845  ic->f = instr(dext);
4846  if (rt == MIPS_GPR_ZERO)
4847  ic->f = instr(nop);
4848  }
4849  break;
4850 
4851  case SPECIAL3_INS:
4852  {
4853  int msb = rd, lsb = (iword >> 6) & 0x1f;
4854  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4855  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs];
4856  ic->arg[2] = (msb << 5) + lsb;
4857  ic->f = instr(ins);
4858  if (rt == MIPS_GPR_ZERO)
4859  ic->f = instr(nop);
4860  }
4861  break;
4862 
4863  case SPECIAL3_BSHFL:
4864  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4865  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rd];
4866  switch (s10) {
4867  case BSHFL_WSBH:
4868  ic->f = instr(wsbh);
4869  break;
4870  case BSHFL_SEB:
4871  ic->f = instr(seb);
4872  break;
4873  case BSHFL_SEH:
4874  ic->f = instr(seh);
4875  break;
4876  default:goto bad;
4877  }
4878  break;
4879 
4880  case SPECIAL3_DBSHFL:
4881  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4882  ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rd];
4883  switch (s10) {
4884  case BSHFL_DSBH:
4885  ic->f = instr(dsbh);
4886  break;
4887  case BSHFL_DSHD:
4888  ic->f = instr(dshd);
4889  break;
4890  default:goto bad;
4891  }
4892  break;
4893 
4894  case SPECIAL3_RDHWR:
4895  ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt];
4896 
4897  switch (rd) {
4898 
4899  case 0: ic->f = instr(rdhwr_cpunum);
4900  if (rt == MIPS_GPR_ZERO)
4901  ic->f = instr(nop);
4902  break;
4903 
4904  case 2: ic->f = instr(rdhwr_cc);
4905  if (rt == MIPS_GPR_ZERO)
4906  ic->f = instr(nop);
4907  break;
4908 
4909  case 29: ic->f = instr(reserved);
4910  break;
4911 
4912  default:if (!cpu->translation_readahead)
4913  fatal("unimplemented rdhwr "
4914  "register rd=%i\n", rd);
4915  goto bad;
4916  }
4917  break;
4918 
4919  default:goto bad;
4920  }
4921  break;
4922 
4923  case HI6_CACHE:
4924  /* TODO: rt and op etc... */
4925  ic->f = instr(cache);
4926  break;
4927 
4928  default:goto bad;
4929  }
4930 
4931 
4932 #ifdef MODE32
4933  if (x64) {
4934  static int has_warned = 0;
4935  if (!has_warned && !cpu->translation_readahead) {
4936  fatal("[ WARNING/NOTE: attempt to execute a 64-bit"
4937  " instruction on an emulated 32-bit processor; "
4938  "pc=0x%08" PRIx32" ]\n", (uint32_t)cpu->pc);
4939  has_warned = 1;
4940  }
4942  goto bad;
4943  else
4944  ic->f = instr(reserved);
4945  }
4946 #else
4947  (void)x64; // avoid compiler warning
4948 #endif
4949 
4950 
4951 #define DYNTRANS_TO_BE_TRANSLATED_TAIL
4952 #include "cpu_dyntrans.cc"
4953 #undef DYNTRANS_TO_BE_TRANSLATED_TAIL
4954 }
4955 
SPECIAL_MFLO
#define SPECIAL_MFLO
Definition: opcodes_mips.h:187
coproc_tlbwri
void coproc_tlbwri(struct cpu *cpu, int randomflag)
Definition: cpu_mips_coproc.cc:1634
mips_cpu::gpr_quadhi
uint64_t gpr_quadhi[N_MIPS_GPRS]
Definition: cpu_mips.h:248
COP0_EI
#define COP0_EI
Definition: opcodes_mips.h:300
mips_cpu::rmw_addr
uint64_t rmw_addr
Definition: cpu_mips.h:234
mips_cpu::cpu_type
struct mips_cpu_type_def cpu_type
Definition: cpu_mips.h:206
mips_coproc::reg
uint64_t reg[N_MIPS_COPROC_REGS]
Definition: cpu_mips.h:102
mips_cpu::cache_linesize
int cache_linesize[2]
Definition: cpu_mips.h:271
instr
#define instr(n)
Definition: tmp_alpha_head.cc:43
HI6_SW
#define HI6_SW
Definition: opcodes_mips.h:459
mips_cpu::coproc
struct mips_coproc * coproc[N_MIPS_COPROCS]
Definition: cpu_mips.h:219
cpu::has_been_idling
char has_been_idling
Definition: cpu.h:401
SPECIAL_TEQ
#define SPECIAL_TEQ
Definition: opcodes_mips.h:221
HI6_SWL
#define HI6_SWL
Definition: opcodes_mips.h:458
mips_cpu::hi
uint64_t hi
Definition: cpu_mips.h:215
f
void f(int s, int func, int only_name)
Definition: generate_arm_r.c:45
SPECIAL_MOVN
#define SPECIAL_MOVN
Definition: opcodes_mips.h:180
mips_unaligned_loadstore
void mips_unaligned_loadstore(struct cpu *cpu, struct mips_instr_call *ic, int is_left, int wlen, int store)
Definition: cpu_mips_instr_unaligned.cc:44
mips_loadstore
void(* mips_loadstore[32])(struct cpu *, struct mips_instr_call *)
Definition: tmp_mips_loadstore.cc:713
cpu_dyntrans.cc
mips_cpu::rmw_len
uint64_t rmw_len
Definition: cpu_mips.h:233
mips_cpu_type_def::isa_revision
char isa_revision
Definition: cpu_mips.h:54
STATUS_ERL
#define STATUS_ERL
Definition: cop0.h:124
cpu::cpu_id
int cpu_id
Definition: cpu.h:359
MMI3_POR
#define MMI3_POR
Definition: opcodes_mips.h:415
HI6_BLEZ
#define HI6_BLEZ
Definition: opcodes_mips.h:258
cpu::running
uint8_t running
Definition: cpu.h:353
COP0_SUSPEND
#define COP0_SUSPEND
Definition: opcodes_mips.h:298
HI6_LQ_MDMX
#define HI6_LQ_MDMX
Definition: opcodes_mips.h:429
COP0_EPC
#define COP0_EPC
Definition: cop0.h:140
EXC3K
#define EXC3K
Definition: mips_cpu_types.h:39
HI6_LH
#define HI6_LH
Definition: opcodes_mips.h:449
BSHFL_WSBH
#define BSHFL_WSBH
Definition: opcodes_mips.h:441
MIPS_FCSR_FCC1_SHIFT
#define MIPS_FCSR_FCC1_SHIFT
Definition: cpu_mips.h:96
STATUS_KSU_SHIFT
#define STATUS_KSU_SHIFT
Definition: cop0.h:123
REGIMM_TLTIU
#define REGIMM_TLTIU
Definition: opcodes_mips.h:242
SPECIAL_DMULT
#define SPECIAL_DMULT
Definition: opcodes_mips.h:197
HI6_LWC1
#define HI6_LWC1
Definition: opcodes_mips.h:465
COPz_BCzc
#define COPz_BCzc
Definition: opcodes_mips.h:281
REGIMM_TGEI
#define REGIMM_TGEI
Definition: opcodes_mips.h:239
SPECIAL_TLTU
#define SPECIAL_TLTU
Definition: opcodes_mips.h:220
addu
void COMBINE() addu(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
Definition: cpu_mips_instr.cc:3480
machine::cpus
struct cpu ** cpus
Definition: machine.h:140
HI6_SDR
#define HI6_SDR
Definition: opcodes_mips.h:461
SPECIAL2_DCLZ
#define SPECIAL2_DCLZ
Definition: opcodes_mips.h:321
MMU10K
#define MMU10K
Definition: mips_cpu_types.h:47
SPECIAL_SRAV
#define SPECIAL_SRAV
Definition: opcodes_mips.h:176
HI6_ORI
#define HI6_ORI
Definition: opcodes_mips.h:265
HI6_BNEL
#define HI6_BNEL
Definition: opcodes_mips.h:306
SPECIAL_DSUBU
#define SPECIAL_DSUBU
Definition: opcodes_mips.h:216
HI6_ADDIU
#define HI6_ADDIU
Definition: opcodes_mips.h:261
NOT_DELAYED
#define NOT_DELAYED
Definition: cpu.h:305
COP0_TLBR
#define COP0_TLBR
Definition: opcodes_mips.h:289
SPECIAL3_RDHWR
#define SPECIAL3_RDHWR
Definition: opcodes_mips.h:447
cpu_functioncall_trace_return
void cpu_functioncall_trace_return(struct cpu *cpu)
Definition: cpu.cc:284
cpu::n_translated_instrs
int n_translated_instrs
Definition: cpu.h:430
REGIMM_TLTI
#define REGIMM_TLTI
Definition: opcodes_mips.h:241
COPz_MTCz
#define COPz_MTCz
Definition: opcodes_mips.h:271
SPECIAL_DSRA32
#define SPECIAL_DSRA32
Definition: opcodes_mips.h:232
sw_loop
void COMBINE() sw_loop(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
Definition: cpu_mips_instr.cc:3176
COPz_MFMCz
#define COPz_MFMCz
Definition: opcodes_mips.h:282
machine::show_trace_tree
int show_trace_tree
Definition: machine.h:164
REGIMM_BGEZ
#define REGIMM_BGEZ
Definition: opcodes_mips.h:236
HI6_LL
#define HI6_LL
Definition: opcodes_mips.h:464
REGIMM_BLTZL
#define REGIMM_BLTZL
Definition: opcodes_mips.h:237
if
addr & if(addr >=0x24 &&page !=NULL)
Definition: tmp_arm_multi.cc:56
mips_cpu_type_def::name
const char * name
Definition: cpu_mips.h:47
HI6_JAL
#define HI6_JAL
Definition: opcodes_mips.h:255
coproc_function
void coproc_function(struct cpu *cpu, struct mips_coproc *cp, int cpnr, uint32_t function, int unassemble_only, int running)
Definition: cpu_mips_coproc.cc:1995
SPECIAL2_DCLO
#define SPECIAL2_DCLO
Definition: opcodes_mips.h:322
DYNTRANS_L1N
#define DYNTRANS_L1N
Definition: cpu.h:222
HI6_ANDI
#define HI6_ANDI
Definition: opcodes_mips.h:264
HI6_COP0
#define HI6_COP0
Definition: opcodes_mips.h:268
COPz_CFCz
#define COPz_CFCz
Definition: opcodes_mips.h:279
N_SAFE_DYNTRANS_LIMIT
#define N_SAFE_DYNTRANS_LIMIT
Definition: cpu.h:311
STATUS_EXL
#define STATUS_EXL
Definition: cop0.h:125
SPECIAL_SUBU
#define SPECIAL_SUBU
Definition: opcodes_mips.h:204
HI6_SLTI
#define HI6_SLTI
Definition: opcodes_mips.h:262
COP1_FMT_S
#define COP1_FMT_S
Definition: opcodes_mips.h:283
MEM_READ
#define MEM_READ
Definition: memory.h:116
EXCEPTION_CPU
#define EXCEPTION_CPU
Definition: cop0.h:194
SPECIAL_DADD
#define SPECIAL_DADD
Definition: opcodes_mips.h:213
cpu::byte_order
uint8_t byte_order
Definition: cpu.h:347
COP0_DEPC
#define COP0_DEPC
Definition: cop0.h:154
cpu_functioncall_trace
void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)
Definition: cpu.cc:228
COP0_CAUSE
#define COP0_CAUSE
Definition: cop0.h:129
cop0_availability_check
int cop0_availability_check(struct cpu *cpu, struct mips_instr_call *ic)
Definition: cpu_mips_instr.cc:69
COP0_DERET
#define COP0_DERET
Definition: opcodes_mips.h:295
coproc_tlbpr
void coproc_tlbpr(struct cpu *cpu, int readflag)
Definition: cpu_mips_coproc.cc:1515
MIPS_GPR_RA
#define MIPS_GPR_RA
Definition: cpu_mips.h:165
LE32_TO_HOST
#define LE32_TO_HOST(x)
Definition: misc.h:180
addr
uint32_t addr
Definition: tmp_arm_multi.cc:52
COP0_ERET
#define COP0_ERET
Definition: opcodes_mips.h:294
COP1_FMT_D
#define COP1_FMT_D
Definition: opcodes_mips.h:284
COP0_WAIT
#define COP0_WAIT
Definition: opcodes_mips.h:296
MIPS1_ISOL_CACHES
#define MIPS1_ISOL_CACHES
Definition: mips_cpuregs.h:180
SPECIAL2_CLO
#define SPECIAL2_CLO
Definition: opcodes_mips.h:320
cpu::mips
struct mips_cpu mips
Definition: cpu.h:446
SPECIAL_DIVU
#define SPECIAL_DIVU
Definition: opcodes_mips.h:196
HI6_BGTZL
#define HI6_BGTZL
Definition: opcodes_mips.h:308
MIPS_FCSR_FCC0_SHIFT
#define MIPS_FCSR_FCC0_SHIFT
Definition: cpu_mips.h:95
SPECIAL3_DEXTU
#define SPECIAL3_DEXTU
Definition: opcodes_mips.h:434
SPECIAL3_DEXT
#define SPECIAL3_DEXT
Definition: opcodes_mips.h:435
BSHFL_DSBH
#define BSHFL_DSBH
Definition: opcodes_mips.h:445
HI6_LWL
#define HI6_LWL
Definition: opcodes_mips.h:450
MIPS_R5900
#define MIPS_R5900
Definition: mips_cpuregs.h:723
BE32_TO_HOST
#define BE32_TO_HOST(x)
Definition: misc.h:181
b_daddiu
void COMBINE() b_daddiu(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
Definition: cpu_mips_instr.cc:3551
mips_cpu_type_def::isa_level
char isa_level
Definition: cpu_mips.h:53
REGIMM_BGEZALL
#define REGIMM_BGEZALL
Definition: opcodes_mips.h:248
SPECIAL_MTHI
#define SPECIAL_MTHI
Definition: opcodes_mips.h:186
SPECIAL_SLTU
#define SPECIAL_SLTU
Definition: opcodes_mips.h:212
HI6_LDR
#define HI6_LDR
Definition: opcodes_mips.h:312
HI6_LWU
#define HI6_LWU
Definition: opcodes_mips.h:455
SPECIAL_DSRL32
#define SPECIAL_DSRL32
Definition: opcodes_mips.h:231
COP0_LLADDR
#define COP0_LLADDR
Definition: cop0.h:143
SPECIAL_JALR
#define SPECIAL_JALR
Definition: opcodes_mips.h:178
MEM_WRITE
#define MEM_WRITE
Definition: memory.h:117
COP1_FMT_PS
#define COP1_FMT_PS
Definition: opcodes_mips.h:287
HI6_SWC1
#define HI6_SWC1
Definition: opcodes_mips.h:473
HI6_SWR
#define HI6_SWR
Definition: opcodes_mips.h:462
MIPS_FPU_FCSR
#define MIPS_FPU_FCSR
Definition: cpu_mips.h:94
SPECIAL_MTLO
#define SPECIAL_MTLO
Definition: opcodes_mips.h:188
REGIMM_TGEIU
#define REGIMM_TGEIU
Definition: opcodes_mips.h:240
HI6_LHU
#define HI6_LHU
Definition: opcodes_mips.h:453
HI6_LW
#define HI6_LW
Definition: opcodes_mips.h:451
HI6_LLD
#define HI6_LLD
Definition: opcodes_mips.h:468
SPECIAL_TGE
#define SPECIAL_TGE
Definition: opcodes_mips.h:217
STATUS_IM_MASK
#define STATUS_IM_MASK
Definition: cop0.h:117
KSU_KERNEL
#define KSU_KERNEL
Definition: cop0.h:172
SPECIAL_DMULTU
#define SPECIAL_DMULTU
Definition: opcodes_mips.h:198
HI6_SC
#define HI6_SC
Definition: opcodes_mips.h:472
BSHFL_SEB
#define BSHFL_SEB
Definition: opcodes_mips.h:442
SPECIAL3_DBSHFL
#define SPECIAL3_DBSHFL
Definition: opcodes_mips.h:444
HI6_BNE
#define HI6_BNE
Definition: opcodes_mips.h:257
MIPS_RM5200
#define MIPS_RM5200
Definition: mips_cpuregs.h:721
mips_coproc::fcr
uint64_t fcr[N_MIPS_FCRS]
Definition: cpu_mips.h:110
STATUS_KSU_MASK
#define STATUS_KSU_MASK
Definition: cop0.h:122
fatal
void fatal(const char *fmt,...)
Definition: main.cc:152
MMI_MMI3
#define MMI_MMI3
Definition: opcodes_mips.h:406
multi_lw
void COMBINE() multi_lw(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
Definition: cpu_mips_instr.cc:3266
tmp_mips_loadstore_multi.cc
STATUS_IE
#define STATUS_IE
Definition: cop0.h:126
MMI0_PEXTLW
#define MMI0_PEXTLW
Definition: opcodes_mips.h:342
BSHFL_SEH
#define BSHFL_SEH
Definition: opcodes_mips.h:443
COP0_STANDBY
#define COP0_STANDBY
Definition: opcodes_mips.h:297
HI6_REGIMM
#define HI6_REGIMM
Definition: opcodes_mips.h:234
HI6_LWC3
#define HI6_LWC3
Definition: opcodes_mips.h:467
HI6_DADDIU
#define HI6_DADDIU
Definition: opcodes_mips.h:310
yamon_emul
int yamon_emul(struct cpu *)
Definition: yamon.cc:139
SPECIAL_MFHI
#define SPECIAL_MFHI
Definition: opcodes_mips.h:185
COPz_DMTCz
#define COPz_DMTCz
Definition: opcodes_mips.h:272
SPECIAL_BREAK
#define SPECIAL_BREAK
Definition: opcodes_mips.h:182
HI6_SCD
#define HI6_SCD
Definition: opcodes_mips.h:476
EXCEPTION_OV
#define EXCEPTION_OV
Definition: cop0.h:195
cpu::cd
union cpu::@1 cd
page
page
Definition: tmp_arm_multi.cc:54
SPECIAL_SYSCALL
#define SPECIAL_SYSCALL
Definition: opcodes_mips.h:181
HI6_CACHE
#define HI6_CACHE
Definition: opcodes_mips.h:463
COPROC_AVAILABILITY_CHECK
#define COPROC_AVAILABILITY_CHECK(x)
Definition: cpu_mips_instr.cc:43
HI6_LB
#define HI6_LB
Definition: opcodes_mips.h:448
SPECIAL_NOR
#define SPECIAL_NOR
Definition: opcodes_mips.h:208
COP0_TLBWI
#define COP0_TLBWI
Definition: opcodes_mips.h:290
COP1_FMT_W
#define COP1_FMT_W
Definition: opcodes_mips.h:285
SPECIAL_MULT
#define SPECIAL_MULT
Definition: opcodes_mips.h:193
ic
struct arm_instr_call * ic
Definition: tmp_arm_multi.cc:50
CACHE_INSTRUCTION
#define CACHE_INSTRUCTION
Definition: memory.h:122
SPECIAL3_INS
#define SPECIAL3_INS
Definition: opcodes_mips.h:436
REGIMM_BGEZAL
#define REGIMM_BGEZAL
Definition: opcodes_mips.h:246
CACHE_DATA
#define CACHE_DATA
Definition: memory.h:121
STATUS_CU_SHIFT
#define STATUS_CU_SHIFT
Definition: cop0.h:111
MIPS_R4100
#define MIPS_R4100
Definition: mips_cpuregs.h:707
SPECIAL2_CLZ
#define SPECIAL2_CLZ
Definition: opcodes_mips.h:319
MMI_MMI0
#define MMI_MMI0
Definition: opcodes_mips.h:328
SPECIAL_DSUB
#define SPECIAL_DSUB
Definition: opcodes_mips.h:215
SPECIAL_SUB
#define SPECIAL_SUB
Definition: opcodes_mips.h:203
mips_cpu_type_def::rev
int rev
Definition: cpu_mips.h:48
SPECIAL_SRLV
#define SPECIAL_SRLV
Definition: opcodes_mips.h:175
decstation_prom_emul
int decstation_prom_emul(struct cpu *cpu)
Definition: dec_prom.cc:229
SPECIAL_TGEU
#define SPECIAL_TGEU
Definition: opcodes_mips.h:218
HI6_ADDI
#define HI6_ADDI
Definition: opcodes_mips.h:260
idle
void COMBINE() idle(struct cpu *cpu, struct m88k_instr_call *ic, int low_addr)
Definition: cpu_m88k_instr.cc:1873
cpu::is_32bit
uint8_t is_32bit
Definition: cpu.h:350
MACHINE_SGI
#define MACHINE_SGI
Definition: machine.h:217
tmp_mips_loadstore.cc
SPECIAL_ADD
#define SPECIAL_ADD
Definition: opcodes_mips.h:201
mips_cpu_type_def::exc_model
char exc_model
Definition: cpu_mips.h:51
MMI_MADDU
#define MMI_MADDU
Definition: opcodes_mips.h:326
SPECIAL_DDIVU
#define SPECIAL_DDIVU
Definition: opcodes_mips.h:200
DYNTRANS_L2N
#define DYNTRANS_L2N
Definition: tmp_alpha_head.cc:10
SPECIAL_SRA
#define SPECIAL_SRA
Definition: opcodes_mips.h:172
HI6_COP2
#define HI6_COP2
Definition: opcodes_mips.h:303
SPECIAL3_EXT
#define SPECIAL3_EXT
Definition: opcodes_mips.h:432
SPECIAL_DSLL32
#define SPECIAL_DSLL32
Definition: opcodes_mips.h:229
SPECIAL_JR
#define SPECIAL_JR
Definition: opcodes_mips.h:177
SPECIAL_DSRA
#define SPECIAL_DSRA
Definition: opcodes_mips.h:228
SPECIAL2_MUL
#define SPECIAL2_MUL
Definition: opcodes_mips.h:316
SPECIAL_AND
#define SPECIAL_AND
Definition: opcodes_mips.h:205
TO_BE_DELAYED
#define TO_BE_DELAYED
Definition: cpu.h:307
HI6_LWR
#define HI6_LWR
Definition: opcodes_mips.h:454
HI6_XORI
#define HI6_XORI
Definition: opcodes_mips.h:266
SPECIAL_DSLL
#define SPECIAL_DSLL
Definition: opcodes_mips.h:225
cpu::mem
struct memory * mem
Definition: cpu.h:362
COPz_CTCz
#define COPz_CTCz
Definition: opcodes_mips.h:280
SPECIAL2_MADDU
#define SPECIAL2_MADDU
Definition: opcodes_mips.h:315
debugger_n_steps_left_before_interaction
int debugger_n_steps_left_before_interaction
Definition: debugger.cc:73
MODE_int_t
#define MODE_int_t
Definition: tmp_alpha_tail.cc:55
SPECIAL_DADDU
#define SPECIAL_DADDU
Definition: opcodes_mips.h:214
REGIMM_TNEI
#define REGIMM_TNEI
Definition: opcodes_mips.h:244
mips_cpu::rmw
int rmw
Definition: cpu_mips.h:232
EMUL_LITTLE_ENDIAN
#define EMUL_LITTLE_ENDIAN
Definition: misc.h:164
DYNTRANS_L3N
#define DYNTRANS_L3N
Definition: tmp_alpha_head.cc:11
MIPS_INSTR_ALIGNMENT_SHIFT
#define MIPS_INSTR_ALIGNMENT_SHIFT
Definition: cpu_mips.h:189
SPECIAL_DSRAV
#define SPECIAL_DSRAV
Definition: opcodes_mips.h:192
MIPS_IC_ENTRIES_PER_PAGE
#define MIPS_IC_ENTRIES_PER_PAGE
Definition: cpu_mips.h:190
cpu::machine
struct machine * machine
Definition: cpu.h:328
EXCEPTION_INT
#define EXCEPTION_INT
Definition: cop0.h:183
cpu::delay_slot
uint8_t delay_slot
Definition: cpu.h:356
SPECIAL_MULTU
#define SPECIAL_MULTU
Definition: opcodes_mips.h:194
reg
#define reg(x)
Definition: tmp_alpha_tail.cc:53
COP0_HIBERNATE
#define COP0_HIBERNATE
Definition: opcodes_mips.h:299
ori
void COMBINE() ori(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
Definition: cpu_mips_instr.cc:3462
SPECIAL_DDIV
#define SPECIAL_DDIV
Definition: opcodes_mips.h:199
cpu::is_halted
char is_halted
Definition: cpu.h:400
HI6_SQ_SPECIAL3
#define HI6_SQ_SPECIAL3
Definition: opcodes_mips.h:431
coproc_register_write
void coproc_register_write(struct cpu *cpu, struct mips_coproc *cp, int reg_nr, uint64_t *ptr, int flag64, int select)
Definition: cpu_mips_coproc.cc:653
SPECIAL_DSRL
#define SPECIAL_DSRL
Definition: opcodes_mips.h:227
MMI_MADD
#define MMI_MADD
Definition: opcodes_mips.h:325
REGIMM_TEQI
#define REGIMM_TEQI
Definition: opcodes_mips.h:243
nop
void COMBINE() nop(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
Definition: cpu_mips_instr.cc:3365
HI6_COP3
#define HI6_COP3
Definition: opcodes_mips.h:304
DYNTRANS_L3_64_TABLE
#define DYNTRANS_L3_64_TABLE
Definition: tmp_alpha_head.cc:16
mips_cpu_exception
void mips_cpu_exception(struct cpu *cpu, int exccode, int tlb, uint64_t vaddr, int coproc_nr, uint64_t vaddr_vpn2, int vaddr_asid, int x_64)
Definition: cpu_mips.cc:1740
EXCEPTION_RI
#define EXCEPTION_RI
Definition: cop0.h:193
HI6_COP1
#define HI6_COP1
Definition: opcodes_mips.h:302
SPECIAL_OR
#define SPECIAL_OR
Definition: opcodes_mips.h:206
SPECIAL_SYNC
#define SPECIAL_SYNC
Definition: opcodes_mips.h:184
addiu
void COMBINE() addiu(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
Definition: cpu_mips_instr.cc:3505
mips_cpu_type_def::flags
char flags
Definition: cpu_mips.h:50
SPECIAL2_MADD
#define SPECIAL2_MADD
Definition: opcodes_mips.h:314
REGIMM_BGEZL
#define REGIMM_BGEZL
Definition: opcodes_mips.h:238
HI6_BLEZL
#define HI6_BLEZL
Definition: opcodes_mips.h:307
R5900_STATUS_EIE
#define R5900_STATUS_EIE
Definition: cop0.h:128
COPz_MFCz
#define COPz_MFCz
Definition: opcodes_mips.h:269
EXCEPTION_SYS
#define EXCEPTION_SYS
Definition: cop0.h:191
HI6_BEQ
#define HI6_BEQ
Definition: opcodes_mips.h:256
HI6_BEQL
#define HI6_BEQL
Definition: opcodes_mips.h:305
SPECIAL_XOR
#define SPECIAL_XOR
Definition: opcodes_mips.h:207
SPECIAL3_DEXTM
#define SPECIAL3_DEXTM
Definition: opcodes_mips.h:433
SPECIAL_SLT
#define SPECIAL_SLT
Definition: opcodes_mips.h:211
SPECIAL_MOVZ
#define SPECIAL_MOVZ
Definition: opcodes_mips.h:179
SPECIAL2_MSUB
#define SPECIAL2_MSUB
Definition: opcodes_mips.h:317
HI6_LUI
#define HI6_LUI
Definition: opcodes_mips.h:267
COP0_TLBP
#define COP0_TLBP
Definition: opcodes_mips.h:292
HI6_LDL
#define HI6_LDL
Definition: opcodes_mips.h:311
SPECIAL3_BSHFL
#define SPECIAL3_BSHFL
Definition: opcodes_mips.h:440
REGIMM_BLTZAL
#define REGIMM_BLTZAL
Definition: opcodes_mips.h:245
HI6_SPECIAL
#define HI6_SPECIAL
Definition: opcodes_mips.h:168
mips_cpu::gpr
uint64_t gpr[N_MIPS_GPRS]
Definition: cpu_mips.h:209
MACHINE_PMAX
#define MACHINE_PMAX
Definition: machine.h:213
SPECIAL_ADDU
#define SPECIAL_ADDU
Definition: opcodes_mips.h:202
HI6_LBU
#define HI6_LBU
Definition: opcodes_mips.h:452
SPECIAL_SLL
#define SPECIAL_SLL
Definition: opcodes_mips.h:169
arcbios_emul
int arcbios_emul(struct cpu *cpu)
Definition: arcbios.cc:1164
machine::machine_type
int machine_type
Definition: machine.h:111
HI6_SH
#define HI6_SH
Definition: opcodes_mips.h:457
HI6_BGTZ
#define HI6_BGTZ
Definition: opcodes_mips.h:259
COPz_DMFCz
#define COPz_DMFCz
Definition: opcodes_mips.h:270
HI6_SD
#define HI6_SD
Definition: opcodes_mips.h:479
MACHINE_PS2
#define MACHINE_PS2
Definition: machine.h:216
HI6_SLTIU
#define HI6_SLTIU
Definition: opcodes_mips.h:263
quick_pc_to_pointers
#define quick_pc_to_pointers(cpu)
Definition: quick_pc_to_pointers.h:29
COP0_DI
#define COP0_DI
Definition: opcodes_mips.h:301
HI6_SDL
#define HI6_SDL
Definition: opcodes_mips.h:460
EXCEPTION_BP
#define EXCEPTION_BP
Definition: cop0.h:192
cpu::translation_readahead
int translation_readahead
Definition: cpu.h:427
mips_coproc
Definition: cpu_mips.h:100
mips_cpu::scratch
uint64_t scratch
Definition: cpu_mips.h:212
HI6_J
#define HI6_J
Definition: opcodes_mips.h:254
mips_cpu::lo
uint64_t lo
Definition: cpu_mips.h:216
SPECIAL_DSRLV
#define SPECIAL_DSRLV
Definition: opcodes_mips.h:191
cpu
Definition: cpu.h:326
netbsd_r3k_cache_inv
void COMBINE() netbsd_r3k_cache_inv(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
Definition: cpu_mips_instr.cc:3335
HI6_LD
#define HI6_LD
Definition: opcodes_mips.h:471
COP0_RFE
#define COP0_RFE
Definition: opcodes_mips.h:293
REGIMM_BLTZ
#define REGIMM_BLTZ
Definition: opcodes_mips.h:235
sll
void COMBINE() sll(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
Definition: cpu_mips_instr.cc:3439
SPECIAL_SRL
#define SPECIAL_SRL
Definition: opcodes_mips.h:171
MIPS_GPR_ZERO
#define MIPS_GPR_ZERO
Definition: cpu_mips.h:134
coproc_register_read
void coproc_register_read(struct cpu *cpu, struct mips_coproc *cp, int reg_nr, uint64_t *ptr, int select)
Definition: cpu_mips_coproc.cc:577
MACHINE_ARC
#define MACHINE_ARC
Definition: machine.h:218
EXCEPTION_TR
#define EXCEPTION_TR
Definition: cop0.h:196
HI6_SDC1
#define HI6_SDC1
Definition: opcodes_mips.h:477
DYNTRANS_L2_64_TABLE
#define DYNTRANS_L2_64_TABLE
Definition: tmp_alpha_head.cc:15
EXCEPTION_IN_DELAY_SLOT
#define EXCEPTION_IN_DELAY_SLOT
Definition: cpu.h:308
COP0_COUNT
#define COP0_COUNT
Definition: cop0.h:92
SPECIAL_TLT
#define SPECIAL_TLT
Definition: opcodes_mips.h:219
HI6_SPECIAL2
#define HI6_SPECIAL2
Definition: opcodes_mips.h:313
HI6_SB
#define HI6_SB
Definition: opcodes_mips.h:456
COMBINE
#define COMBINE(n)
Definition: tmp_alpha_tail.cc:61
SPECIAL2_MSUBU
#define SPECIAL2_MSUBU
Definition: opcodes_mips.h:318
cpu::memory_rw
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
Definition: cpu.h:368
SPECIAL_TNE
#define SPECIAL_TNE
Definition: opcodes_mips.h:223
HI6_DADDI
#define HI6_DADDI
Definition: opcodes_mips.h:309
SPECIAL_DIV
#define SPECIAL_DIV
Definition: opcodes_mips.h:195
SPECIAL_DSLLV
#define SPECIAL_DSLLV
Definition: opcodes_mips.h:189
multi_sw
void COMBINE() multi_sw(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
Definition: cpu_mips_instr.cc:3210
cpu::pc
uint64_t pc
Definition: cpu.h:386
HI6_LDC1
#define HI6_LDC1
Definition: opcodes_mips.h:469
X
X(invalid)
Definition: cpu_mips_instr.cc:118
playstation2_sifbios_emul
int playstation2_sifbios_emul(struct cpu *cpu)
Definition: ps2_bios.cc:51
COP1_FMT_L
#define COP1_FMT_L
Definition: opcodes_mips.h:286
BSHFL_DSHD
#define BSHFL_DSHD
Definition: opcodes_mips.h:446
REGIMM_BLTZALL
#define REGIMM_BLTZALL
Definition: opcodes_mips.h:247
SPECIAL_SLLV
#define SPECIAL_SLLV
Definition: opcodes_mips.h:173
COP0_ERROREPC
#define COP0_ERROREPC
Definition: cop0.h:160
MODE_uint_t
#define MODE_uint_t
Definition: tmp_alpha_tail.cc:54
COP0_TLBWR
#define COP0_TLBWR
Definition: opcodes_mips.h:291
MACHINE_EVBMIPS
#define MACHINE_EVBMIPS
Definition: machine.h:219
NOFPU
#define NOFPU
Definition: mips_cpu_types.h:54
COP0_STATUS
#define COP0_STATUS
Definition: cop0.h:109
machine::ncpus
int ncpus
Definition: machine.h:139
STATUS_FR
#define STATUS_FR
Definition: cop0.h:113

Generated on Tue Aug 25 2020 19:25:06 for GXemul by doxygen 1.8.18