4 // <insn-word> { "+" <insn-word> }
11 // { <insn-mnemonic> }
16 // IGEN config - mips16
17 // :option:16::insn-bit-size:16
18 // :option:16::hi-bit-nr:15
19 :option:16::insn-specifying-widths:true
20 :option:16::gen-delayed-branch:false
22 // IGEN config - mips32/64..
23 // :option:32::insn-bit-size:32
24 // :option:32::hi-bit-nr:31
25 :option:32::insn-specifying-widths:true
26 :option:32::gen-delayed-branch:false
29 // Generate separate simulators for each target
30 // :option:::multi-sim:true
33 // Models known by this simulator are defined below.
35 // When placing models in the instruction descriptions, please place
36 // them one per line, in the order given here.
40 // Instructions and related functions for these models are included in
42 :model:::mipsI:mips3000:
43 :model:::mipsII:mips6000:
44 :model:::mipsIII:mips4000:
45 :model:::mipsIV:mips8000:
46 :model:::mipsV:mipsisaV:
47 :model:::mips32:mipsisa32:
48 :model:::mips32r2:mipsisa32r2:
49 :model:::mips64:mipsisa64:
50 :model:::mips64r2:mipsisa64r2:
54 // Standard MIPS ISA instructions used for these models are listed here,
55 // as are functions needed by those standard instructions. Instructions
56 // which are model-dependent and which are not in the standard MIPS ISAs
57 // (or which pre-date or use different encodings than the standard
58 // instructions) are (for the most part) in separate .igen files.
59 :model:::vr4100:mips4100: // vr.igen
60 :model:::vr4120:mips4120:
61 :model:::vr5000:mips5000:
62 :model:::vr5400:mips5400:
63 :model:::vr5500:mips5500:
64 :model:::r3900:mips3900: // tx.igen
66 // MIPS Application Specific Extensions (ASEs)
68 // Instructions for the ASEs are in separate .igen files.
69 // ASEs add instructions on to a base ISA.
70 :model:::mips16:mips16: // m16.igen (and m16.dc)
71 :model:::mips16e:mips16e: // m16e.igen
72 :model:::mips3d:mips3d: // mips3d.igen
73 :model:::mdmx:mdmx: // mdmx.igen
74 :model:::dsp:dsp: // dsp.igen
75 :model:::dsp2:dsp2: // dsp2.igen
76 :model:::smartmips:smartmips: // smartmips.igen
77 :model:::micromips32:micromips64: // micromips.igen
78 :model:::micromips64:micromips64: // micromips.igen
79 :model:::micromipsdsp:micromipsdsp: // micromipsdsp.igen
83 // Instructions specific to these extensions are in separate .igen files.
84 // Extensions add instructions on to a base ISA.
85 :model:::sb1:sb1: // sb1.igen
88 // Pseudo instructions known by IGEN
91 SignalException (ReservedInstruction, 0);
95 // Pseudo instructions known by interp.c
96 // For grep - RSVD_INSTRUCTION, RSVD_INSTRUCTION_MASK
97 000000,5.*,5.*,5.*,5.OP,111001:SPECIAL:32::RSVD
100 SignalException (ReservedInstruction, instruction_0);
107 // Simulate a 32 bit delayslot instruction
110 :function:::address_word:delayslot32:address_word target
112 instruction_word delay_insn;
113 sim_events_slip (SD, 1);
115 CIA = CIA + 4; /* NOTE not mips16 */
116 STATE |= simDELAYSLOT;
117 delay_insn = IMEM32 (CIA); /* NOTE not mips16 */
118 ENGINE_ISSUE_PREFIX_HOOK();
119 idecode_issue (CPU_, delay_insn, (CIA));
120 STATE &= ~simDELAYSLOT;
124 :function:::address_word:nullify_next_insn32:
126 sim_events_slip (SD, 1);
127 dotrace (SD, CPU, tracefh, 2, CIA + 4, 4, "load instruction");
134 // Calculate an effective address given a base and an offset.
137 :function:::address_word:loadstore_ea:address_word base, address_word offset
150 return base + offset;
153 :function:::address_word:loadstore_ea:address_word base, address_word offset
158 #if 0 /* XXX FIXME: enable this only after some additional testing. */
159 /* If in user mode and UX is not set, use 32-bit compatibility effective
160 address computations as defined in the MIPS64 Architecture for
161 Programmers Volume III, Revision 0.95, section 4.9. */
162 if ((SR & (status_KSU_mask|status_EXL|status_ERL|status_UX))
163 == (ksu_user << status_KSU_shift))
164 return (address_word)((signed32)base + (signed32)offset);
166 return base + offset;
172 // Check that a 32-bit register value is properly sign-extended.
173 // (See NotWordValue in ISA spec.)
176 :function:::int:not_word_value:unsigned_word value
192 #if WITH_TARGET_WORD_BITSIZE == 64
193 return value != (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
201 // Handle UNPREDICTABLE operation behaviour. The goal here is to prevent
202 // theoretically portable code which invokes non-portable behaviour from
203 // running with no indication of the portability issue.
204 // (See definition of UNPREDICTABLE in ISA spec.)
207 :function:::void:unpredictable:
219 :function:::void:unpredictable:
227 unpredictable_action (CPU, CIA);
233 // Check that an access to a HI/LO register meets timing requirements
237 // OP {HI and LO} followed by MT{LO or HI} (and not MT{HI or LO})
238 // makes subsequent MF{HI or LO} UNPREDICTABLE. (1)
240 // The following restrictions exist for MIPS I - MIPS III:
242 // MF{HI or LO} followed by MT{HI or LO} w/ less than 2 instructions
243 // in between makes MF UNPREDICTABLE. (2)
245 // MF{HI or LO} followed by OP {HI and LO} w/ less than 2 instructions
246 // in between makes MF UNPREDICTABLE. (3)
248 // On the r3900, restriction (2) is not present, and restriction (3) is not
249 // present for multiplication.
251 // Unfortunately, there seems to be some confusion about whether the last
252 // two restrictions should apply to "MIPS IV" as well. One edition of
253 // the MIPS IV ISA says they do, but references in later ISA documents
254 // suggest they don't.
256 // In reality, some MIPS IV parts, such as the VR5000 and VR5400, do have
257 // these restrictions, while others, like the VR5500, don't. To accomodate
258 // such differences, the MIPS IV and MIPS V version of these helper functions
259 // use auxillary routines to determine whether the restriction applies.
263 // Helper used by check_mt_hilo, check_mult_hilo, and check_div_hilo
264 // to check for restrictions (2) and (3) above.
266 :function:::int:check_mf_cycles:hilo_history *history, signed64 time, const char *new
268 if (history->mf.timestamp + 3 > time)
270 sim_engine_abort (SD, CPU, CIA, "HILO: %s: %s at 0x%08lx too close to MF at 0x%08lx\n",
271 itable[MY_INDEX].name,
273 (long) history->mf.cia);
282 // Check for restriction (2) above (for ISAs/processors that have it),
283 // and record timestamps for restriction (1) above.
285 :function:::int:check_mt_hilo:hilo_history *history
292 signed64 time = sim_events_time (SD);
293 int ok = check_mf_cycles (SD_, history, time, "MT");
294 history->mt.timestamp = time;
295 history->mt.cia = CIA;
299 :function:::int:check_mt_hilo:hilo_history *history
303 signed64 time = sim_events_time (SD);
304 int ok = (! MIPS_MACH_HAS_MT_HILO_HAZARD (SD)
305 || check_mf_cycles (SD_, history, time, "MT"));
306 history->mt.timestamp = time;
307 history->mt.cia = CIA;
311 :function:::int:check_mt_hilo:hilo_history *history
320 signed64 time = sim_events_time (SD);
321 history->mt.timestamp = time;
322 history->mt.cia = CIA;
329 // Check for restriction (1) above, and record timestamps for
330 // restriction (2) and (3) above.
332 :function:::int:check_mf_hilo:hilo_history *history, hilo_history *peer
348 signed64 time = sim_events_time (SD);
351 && peer->mt.timestamp > history->op.timestamp
352 && history->mt.timestamp < history->op.timestamp
353 && ! (history->mf.timestamp > history->op.timestamp
354 && history->mf.timestamp < peer->mt.timestamp)
355 && ! (peer->mf.timestamp > history->op.timestamp
356 && peer->mf.timestamp < peer->mt.timestamp))
358 /* The peer has been written to since the last OP yet we have
360 sim_engine_abort (SD, CPU, CIA, "HILO: %s: MF at 0x%08lx following OP at 0x%08lx corrupted by MT at 0x%08lx\n",
361 itable[MY_INDEX].name,
363 (long) history->op.cia,
364 (long) peer->mt.cia);
367 history->mf.timestamp = time;
368 history->mf.cia = CIA;
376 // Check for restriction (3) above (for ISAs/processors that have it)
377 // for MULT ops, and record timestamps for restriction (1) above.
379 :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
386 signed64 time = sim_events_time (SD);
387 int ok = (check_mf_cycles (SD_, hi, time, "OP")
388 && check_mf_cycles (SD_, lo, time, "OP"));
389 hi->op.timestamp = time;
390 lo->op.timestamp = time;
396 :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
400 signed64 time = sim_events_time (SD);
401 int ok = (! MIPS_MACH_HAS_MULT_HILO_HAZARD (SD)
402 || (check_mf_cycles (SD_, hi, time, "OP")
403 && check_mf_cycles (SD_, lo, time, "OP")));
404 hi->op.timestamp = time;
405 lo->op.timestamp = time;
411 :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
420 /* FIXME: could record the fact that a stall occured if we want */
421 signed64 time = sim_events_time (SD);
422 hi->op.timestamp = time;
423 lo->op.timestamp = time;
432 // Check for restriction (3) above (for ISAs/processors that have it)
433 // for DIV ops, and record timestamps for restriction (1) above.
435 :function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo
443 signed64 time = sim_events_time (SD);
444 int ok = (check_mf_cycles (SD_, hi, time, "OP")
445 && check_mf_cycles (SD_, lo, time, "OP"));
446 hi->op.timestamp = time;
447 lo->op.timestamp = time;
453 :function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo
457 signed64 time = sim_events_time (SD);
458 int ok = (! MIPS_MACH_HAS_DIV_HILO_HAZARD (SD)
459 || (check_mf_cycles (SD_, hi, time, "OP")
460 && check_mf_cycles (SD_, lo, time, "OP")));
461 hi->op.timestamp = time;
462 lo->op.timestamp = time;
468 :function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo
476 signed64 time = sim_events_time (SD);
477 hi->op.timestamp = time;
478 lo->op.timestamp = time;
487 // Check that the 64-bit instruction can currently be used, and signal
488 // a ReservedInstruction exception if not.
491 :function:::void:check_u64:instruction_word insn
500 // The check should be similar to mips64 for any with PX/UX bit equivalents.
503 :function:::void:check_u64:instruction_word insn
512 #if 0 /* XXX FIXME: enable this only after some additional testing. */
513 if (UserMode && (SR & (status_UX|status_PX)) == 0)
514 SignalException (ReservedInstruction, insn);
521 // MIPS Architecture:
523 // CPU Instruction Set (mipsI - mipsV, mips32/r2, mips64/r2)
527 :function:::void:do_add:int rs, int rt, int rd
529 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
531 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
533 ALU32_BEGIN (GPR[rs]);
535 ALU32_END (GPR[rd]); /* This checks for overflow. */
537 TRACE_ALU_RESULT (GPR[rd]);
540 :function:::void:do_addi:int rs, int rt, unsigned16 immediate
542 if (NotWordValue (GPR[rs]))
544 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
546 ALU32_BEGIN (GPR[rs]);
547 ALU32_ADD (EXTEND16 (immediate));
548 ALU32_END (GPR[rt]); /* This checks for overflow. */
550 TRACE_ALU_RESULT (GPR[rt]);
553 :function:::void:do_andi:int rs, int rt, unsigned int immediate
555 TRACE_ALU_INPUT2 (GPR[rs], immediate);
556 GPR[rt] = GPR[rs] & immediate;
557 TRACE_ALU_RESULT (GPR[rt]);
560 :function:::void:do_dadd:int rd, int rs, int rt
562 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
564 ALU64_BEGIN (GPR[rs]);
566 ALU64_END (GPR[rd]); /* This checks for overflow. */
568 TRACE_ALU_RESULT (GPR[rd]);
571 :function:::void:do_daddi:int rt, int rs, int immediate
573 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
575 ALU64_BEGIN (GPR[rs]);
576 ALU64_ADD (EXTEND16 (immediate));
577 ALU64_END (GPR[rt]); /* This checks for overflow. */
579 TRACE_ALU_RESULT (GPR[rt]);
582 :function:::void:do_dsll32:int rd, int rt, int shift
585 TRACE_ALU_INPUT2 (GPR[rt], s);
586 GPR[rd] = GPR[rt] << s;
587 TRACE_ALU_RESULT (GPR[rd]);
590 :function:::void:do_dsra32:int rd, int rt, int shift
593 TRACE_ALU_INPUT2 (GPR[rt], s);
594 GPR[rd] = ((signed64) GPR[rt]) >> s;
595 TRACE_ALU_RESULT (GPR[rd]);
598 :function:::void:do_dsrl32:int rd, int rt, int shift
601 TRACE_ALU_INPUT2 (GPR[rt], s);
602 GPR[rd] = (unsigned64) GPR[rt] >> s;
603 TRACE_ALU_RESULT (GPR[rd]);
606 :function:::void:do_dsub:int rd, int rs, int rt
608 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
610 ALU64_BEGIN (GPR[rs]);
612 ALU64_END (GPR[rd]); /* This checks for overflow. */
614 TRACE_ALU_RESULT (GPR[rd]);
617 :function:::void:do_break:address_word instruction_0
619 /* Check for some break instruction which are reserved for use by the
621 unsigned int break_code = instruction_0 & HALT_INSTRUCTION_MASK;
622 if (break_code == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
623 break_code == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
625 sim_engine_halt (SD, CPU, NULL, cia,
626 sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
628 else if (break_code == (BREAKPOINT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
629 break_code == (BREAKPOINT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
631 if (STATE & simDELAYSLOT)
632 PC = cia - 4; /* reference the branch instruction */
635 SignalException (BreakPoint, instruction_0);
640 /* If we get this far, we're not an instruction reserved by the sim. Raise
642 SignalException (BreakPoint, instruction_0);
646 :function:::void:do_break16:address_word instruction_0
648 if (STATE & simDELAYSLOT)
649 PC = cia - 2; /* reference the branch instruction */
652 SignalException (BreakPoint, instruction_0);
655 :function:::void:do_clo:int rd, int rs
657 unsigned32 temp = GPR[rs];
659 if (NotWordValue (GPR[rs]))
661 TRACE_ALU_INPUT1 (GPR[rs]);
662 for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
664 if ((temp & mask) == 0)
668 GPR[rd] = EXTEND32 (i);
669 TRACE_ALU_RESULT (GPR[rd]);
672 :function:::void:do_clz:int rd, int rs
674 unsigned32 temp = GPR[rs];
676 if (NotWordValue (GPR[rs]))
678 TRACE_ALU_INPUT1 (GPR[rs]);
679 for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
681 if ((temp & mask) != 0)
685 GPR[rd] = EXTEND32 (i);
686 TRACE_ALU_RESULT (GPR[rd]);
689 :function:::void:do_dclo:int rd, int rs
691 unsigned64 temp = GPR[rs];
694 TRACE_ALU_INPUT1 (GPR[rs]);
695 for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
697 if ((temp & mask) == 0)
701 GPR[rd] = EXTEND32 (i);
702 TRACE_ALU_RESULT (GPR[rd]);
705 :function:::void:do_dclz:int rd, int rs
707 unsigned64 temp = GPR[rs];
710 TRACE_ALU_INPUT1 (GPR[rs]);
711 for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
713 if ((temp & mask) != 0)
717 GPR[rd] = EXTEND32 (i);
718 TRACE_ALU_RESULT (GPR[rd]);
721 :function:::void:do_lb:int rt, int offset, int base
723 GPR[rt] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[base],
727 :function:::void:do_lh:int rt, int offset, int base
729 GPR[rt] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[base],
733 :function:::void:do_lwr:int rt, int offset, int base
735 GPR[rt] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, GPR[base],
736 EXTEND16 (offset), GPR[rt]));
739 :function:::void:do_lwl:int rt, int offset, int base
741 GPR[rt] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, GPR[base],
742 EXTEND16 (offset), GPR[rt]));
745 :function:::void:do_lwc:int num, int rt, int offset, int base
747 COP_LW (num, rt, do_load (SD_, AccessLength_WORD, GPR[base],
751 :function:::void:do_lw:int rt, int offset, int base
753 GPR[rt] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[base],
757 :function:::void:do_lwu:int rt, int offset, int base, address_word instruction_0
759 check_u64 (SD_, instruction_0);
760 GPR[rt] = do_load (SD_, AccessLength_WORD, GPR[base], EXTEND16 (offset));
763 :function:::void:do_lhu:int rt, int offset, int base
765 GPR[rt] = do_load (SD_, AccessLength_HALFWORD, GPR[base], EXTEND16 (offset));
768 :function:::void:do_ldc:int num, int rt, int offset, int base
770 COP_LD (num, rt, do_load (SD_, AccessLength_DOUBLEWORD, GPR[base],
774 :function:::void:do_lbu:int rt, int offset, int base
776 GPR[rt] = do_load (SD_, AccessLength_BYTE, GPR[base], EXTEND16 (offset));
779 :function:::void:do_ll:int rt, int insn_offset, int basereg
781 address_word base = GPR[basereg];
782 address_word offset = EXTEND16 (insn_offset);
784 address_word vaddr = loadstore_ea (SD_, base, offset);
785 address_word paddr = vaddr;
786 if ((vaddr & 3) != 0)
788 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer,
789 sim_core_unaligned_signal);
793 unsigned64 memval = 0;
794 unsigned64 memval1 = 0;
795 unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
796 unsigned int shift = 2;
797 unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
798 unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
800 paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
801 LoadMemory (&memval, &memval1, AccessLength_WORD, paddr, vaddr,
803 byte = ((vaddr & mask) ^ (bigend << shift));
804 GPR[rt] = EXTEND32 (memval >> (8 * byte));
810 :function:::void:do_lld:int rt, int roffset, int rbase
812 address_word base = GPR[rbase];
813 address_word offset = EXTEND16 (roffset);
815 address_word vaddr = loadstore_ea (SD_, base, offset);
816 address_word paddr = vaddr;
818 if ((vaddr & 7) != 0)
820 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer,
821 sim_core_unaligned_signal);
825 unsigned64 memval = 0;
826 unsigned64 memval1 = 0;
827 LoadMemory (&memval, &memval1, AccessLength_DOUBLEWORD, paddr, vaddr,
835 :function:::void:do_lui:int rt, int immediate
837 TRACE_ALU_INPUT1 (immediate);
838 GPR[rt] = EXTEND32 (immediate << 16);
839 TRACE_ALU_RESULT (GPR[rt]);
842 :function:::void:do_madd:int rs, int rt
845 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
846 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
848 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
849 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
850 + ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
851 LO = EXTEND32 (temp);
852 HI = EXTEND32 (VH4_8 (temp));
853 TRACE_ALU_RESULT2 (HI, LO);
856 :function:::void:do_dsp_madd:int ac, int rs, int rt
860 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
861 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
863 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
864 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
865 + ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
866 DSPLO(ac) = EXTEND32 (temp);
867 DSPHI(ac) = EXTEND32 (VH4_8 (temp));
869 TRACE_ALU_RESULT2 (HI, LO);
872 :function:::void:do_maddu:int rs, int rt
875 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
876 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
878 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
879 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
880 + ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
881 ACX += U8_4 (VL4_8 (HI), VL4_8 (LO)) < temp; /* SmartMIPS */
882 LO = EXTEND32 (temp);
883 HI = EXTEND32 (VH4_8 (temp));
884 TRACE_ALU_RESULT2 (HI, LO);
887 :function:::void:do_dsp_maddu:int ac, int rs, int rt
891 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
892 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
894 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
895 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
896 + ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
898 ACX += U8_4 (VL4_8 (HI), VL4_8 (LO)) < temp; /* SmartMIPS */
899 DSPLO(ac) = EXTEND32 (temp);
900 DSPHI(ac) = EXTEND32 (VH4_8 (temp));
902 TRACE_ALU_RESULT2 (HI, LO);
905 :function:::void:do_dsp_mfhi:int ac, int rd
913 :function:::void:do_dsp_mflo:int ac, int rd
921 :function:::void:do_movn:int rd, int rs, int rt
926 TRACE_ALU_RESULT (GPR[rd]);
930 :function:::void:do_movz:int rd, int rs, int rt
935 TRACE_ALU_RESULT (GPR[rd]);
939 :function:::void:do_msub:int rs, int rt
942 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
943 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
945 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
946 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
947 - ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
948 LO = EXTEND32 (temp);
949 HI = EXTEND32 (VH4_8 (temp));
950 TRACE_ALU_RESULT2 (HI, LO);
953 :function:::void:do_dsp_msub:int ac, int rs, int rt
957 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
958 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
960 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
961 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
962 - ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
963 DSPLO(ac) = EXTEND32 (temp);
964 DSPHI(ac) = EXTEND32 (VH4_8 (temp));
966 TRACE_ALU_RESULT2 (HI, LO);
969 :function:::void:do_msubu:int rs, int rt
972 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
973 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
975 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
976 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
977 - ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
978 LO = EXTEND32 (temp);
979 HI = EXTEND32 (VH4_8 (temp));
980 TRACE_ALU_RESULT2 (HI, LO);
983 :function:::void:do_dsp_msubu:int ac, int rs, int rt
987 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
988 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
990 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
991 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
992 - ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
993 DSPLO(ac) = EXTEND32 (temp);
994 DSPHI(ac) = EXTEND32 (VH4_8 (temp));
996 TRACE_ALU_RESULT2 (HI, LO);
999 :function:::void:do_mthi:int rs
1001 check_mt_hilo (SD_, HIHISTORY);
1005 :function:::void:do_dsp_mthi:int ac, int rs
1008 check_mt_hilo (SD_, HIHISTORY);
1009 DSPHI(ac) = GPR[rs];
1012 :function:::void:do_mtlo:int rs
1014 check_mt_hilo (SD_, LOHISTORY);
1018 :function:::void:do_dsp_mtlo:int ac, int rs
1021 check_mt_hilo (SD_, LOHISTORY);
1022 DSPLO(ac) = GPR[rs];
1025 :function:::void:do_mul:int rd, int rs, int rt
1028 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
1030 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1031 prod = (((signed64)(signed32) GPR[rs])
1032 * ((signed64)(signed32) GPR[rt]));
1033 GPR[rd] = EXTEND32 (VL4_8 (prod));
1034 TRACE_ALU_RESULT (GPR[rd]);
1037 :function:::void:do_dsp_mult:int ac, int rs, int rt
1041 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
1042 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
1044 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1045 prod = ((signed64)(signed32) GPR[rs])
1046 * ((signed64)(signed32) GPR[rt]);
1047 DSPLO(ac) = EXTEND32 (VL4_8 (prod));
1048 DSPHI(ac) = EXTEND32 (VH4_8 (prod));
1051 ACX = 0; /* SmartMIPS */
1052 TRACE_ALU_RESULT2 (HI, LO);
1056 :function:::void:do_dsp_multu:int ac, int rs, int rt
1060 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
1061 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
1063 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1064 prod = ((unsigned64)(unsigned32) GPR[rs])
1065 * ((unsigned64)(unsigned32) GPR[rt]);
1066 DSPLO(ac) = EXTEND32 (VL4_8 (prod));
1067 DSPHI(ac) = EXTEND32 (VH4_8 (prod));
1069 TRACE_ALU_RESULT2 (HI, LO);
1072 :function:::void:do_pref:int hint, int insn_offset, int insn_base
1074 address_word base = GPR[insn_base];
1075 address_word offset = EXTEND16 (insn_offset);
1077 address_word vaddr = loadstore_ea (SD_, base, offset);
1078 address_word paddr = vaddr;
1079 /* Prefetch (paddr, vaddr, isDATA, hint); */
1083 :function:::void:do_sc:int rt, int offsetarg, int basereg, address_word instruction_0
1085 unsigned32 instruction = instruction_0;
1086 address_word base = GPR[basereg];
1087 address_word offset = EXTEND16 (offsetarg);
1089 address_word vaddr = loadstore_ea (SD_, base, offset);
1090 address_word paddr = vaddr;
1092 if ((vaddr & 3) != 0)
1094 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer,
1095 sim_core_unaligned_signal);
1099 unsigned64 memval = 0;
1100 unsigned64 memval1 = 0;
1101 unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1102 address_word reverseendian =
1103 (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
1104 address_word bigendiancpu =
1105 (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
1107 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
1108 byte = ((vaddr & mask) ^ bigendiancpu);
1109 memval = ((unsigned64) GPR[rt] << (8 * byte));
1111 StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr,
1118 :function:::void:do_scd:int rt, int roffset, int rbase
1120 address_word base = GPR[rbase];
1121 address_word offset = EXTEND16 (roffset);
1123 address_word vaddr = loadstore_ea (SD_, base, offset);
1124 address_word paddr = vaddr;
1126 if ((vaddr & 7) != 0)
1128 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer,
1129 sim_core_unaligned_signal);
1133 unsigned64 memval = 0;
1134 unsigned64 memval1 = 0;
1137 StoreMemory (AccessLength_DOUBLEWORD, memval, memval1, paddr, vaddr,
1144 :function:::void:do_sub:int rs, int rt, int rd
1146 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
1148 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1150 ALU32_BEGIN (GPR[rs]);
1151 ALU32_SUB (GPR[rt]);
1152 ALU32_END (GPR[rd]); /* This checks for overflow. */
1154 TRACE_ALU_RESULT (GPR[rd]);
1157 :function:::void:do_sw:int rt, int offset, int base
1159 do_store (SD_, AccessLength_WORD, GPR[base], EXTEND16 (offset), GPR[rt]);
1162 :function:::void:do_teq:int rs, int rt, address_word instruction_0
1164 if ((signed_word) GPR[rs] == (signed_word) GPR[rt])
1165 SignalException (Trap, instruction_0);
1168 :function:::void:do_teqi:int rs, int immediate, address_word instruction_0
1170 if ((signed_word) GPR[rs] == (signed_word) EXTEND16 (immediate))
1171 SignalException (Trap, instruction_0);
1174 :function:::void:do_tge:int rs, int rt, address_word instruction_0
1176 if ((signed_word) GPR[rs] >= (signed_word) GPR[rt])
1177 SignalException (Trap, instruction_0);
1180 :function:::void:do_tgei:int rs, int immediate, address_word instruction_0
1182 if ((signed_word) GPR[rs] >= (signed_word) EXTEND16 (immediate))
1183 SignalException (Trap, instruction_0);
1186 :function:::void:do_tgeiu:int rs, int immediate, address_word instruction_0
1188 if ((unsigned_word) GPR[rs] >= (unsigned_word) EXTEND16 (immediate))
1189 SignalException (Trap, instruction_0);
1192 :function:::void:do_tgeu:int rs ,int rt, address_word instruction_0
1194 if ((unsigned_word) GPR[rs] >= (unsigned_word) GPR[rt])
1195 SignalException (Trap, instruction_0);
1198 :function:::void:do_tlt:int rs, int rt, address_word instruction_0
1200 if ((signed_word) GPR[rs] < (signed_word) GPR[rt])
1201 SignalException (Trap, instruction_0);
1204 :function:::void:do_tlti:int rs, int immediate, address_word instruction_0
1206 if ((signed_word) GPR[rs] < (signed_word) EXTEND16 (immediate))
1207 SignalException (Trap, instruction_0);
1210 :function:::void:do_tltiu:int rs, int immediate, address_word instruction_0
1212 if ((unsigned_word) GPR[rs] < (unsigned_word) EXTEND16 (immediate))
1213 SignalException (Trap, instruction_0);
1216 :function:::void:do_tltu:int rs, int rt, address_word instruction_0
1218 if ((unsigned_word) GPR[rs] < (unsigned_word) GPR[rt])
1219 SignalException (Trap, instruction_0);
1222 :function:::void:do_tne:int rs, int rt, address_word instruction_0
1224 if ((signed_word) GPR[rs] != (signed_word) GPR[rt])
1225 SignalException (Trap, instruction_0);
1228 :function:::void:do_tnei:int rs, int immediate, address_word instruction_0
1230 if ((signed_word) GPR[rs] != (signed_word) EXTEND16 (immediate))
1231 SignalException (Trap, instruction_0);
1234 :function:::void:do_abs_fmt:int fmt, int fd, int fs, address_word instruction_0
1237 check_fmt_p (SD_, fmt, instruction_0);
1238 StoreFPR (fd, fmt, AbsoluteValue (ValueFPR (fs, fmt), fmt));
1241 :function:::void:do_add_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
1244 check_fmt_p (SD_, fmt, instruction_0);
1245 StoreFPR (fd, fmt, Add (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
1248 :function:::void:do_alnv_ps:int fd, int fs, int ft, int rs, address_word instruction_0
1254 check_u64 (SD_, instruction_0);
1255 fsx = ValueFPR (fs, fmt_ps);
1256 if ((GPR[rs] & 0x3) != 0)
1258 if ((GPR[rs] & 0x4) == 0)
1262 ftx = ValueFPR (ft, fmt_ps);
1264 fdx = PackPS (PSLower (fsx), PSUpper (ftx));
1266 fdx = PackPS (PSLower (ftx), PSUpper (fsx));
1268 StoreFPR (fd, fmt_ps, fdx);
1271 :function:::void:do_c_cond_fmt:int cond, int fmt, int cc, int fs, int ft, address_word instruction_0
1274 check_fmt_p (SD_, fmt, instruction_0);
1275 Compare (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt, cond, cc);
1276 TRACE_ALU_RESULT (ValueFCR (31));
1279 :function:::void:do_ceil_fmt:int type, int fmt, int fd, int fs, address_word instruction_0
1282 check_fmt_p (SD_, fmt, instruction_0);
1283 StoreFPR (fd, type, Convert (FP_RM_TOPINF, ValueFPR (fs, fmt), fmt,
1287 :function:::void:do_cfc1:int rt, int fs
1290 if (fs == 0 || fs == 25 || fs == 26 || fs == 28 || fs == 31)
1292 unsigned_word fcr = ValueFCR (fs);
1293 TRACE_ALU_INPUT1 (fcr);
1297 TRACE_ALU_RESULT (GPR[rt]);
1300 :function:::void:do_ctc1:int rt, int fs
1303 TRACE_ALU_INPUT1 (GPR[rt]);
1304 if (fs == 25 || fs == 26 || fs == 28 || fs == 31)
1305 StoreFCR (fs, GPR[rt]);
1309 :function:::void:do_cvt_d_fmt:int fmt, int fd, int fs, address_word instruction_0
1312 if ((fmt == fmt_double) | 0)
1313 SignalException (ReservedInstruction, instruction_0);
1314 StoreFPR (fd, fmt_double, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
1318 :function:::void:do_cvt_l_fmt:int fmt, int fd, int fs, address_word instruction_0
1321 if ((fmt == fmt_long) | ((fmt == fmt_long) || (fmt == fmt_word)))
1322 SignalException (ReservedInstruction, instruction_0);
1323 StoreFPR (fd, fmt_long, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
1327 :function:::void:do_cvt_ps_s:int fd, int fs, int ft, address_word instruction_0
1330 check_u64 (SD_, instruction_0);
1331 StoreFPR (fd, fmt_ps, PackPS (ValueFPR (fs, fmt_single),
1332 ValueFPR (ft, fmt_single)));
1335 :function:::void:do_cvt_s_fmt:int fmt, int fd, int fs, address_word instruction_0
1338 if ((fmt == fmt_single) | 0)
1339 SignalException (ReservedInstruction, instruction_0);
1340 StoreFPR (fd, fmt_single, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
1344 :function:::void:do_cvt_s_pl:int fd, int fs, address_word instruction_0
1347 check_u64 (SD_, instruction_0);
1348 StoreFPR (fd, fmt_single, PSLower (ValueFPR (fs, fmt_ps)));
1351 :function:::void:do_cvt_s_pu:int fd, int fs, address_word instruction_0
1354 check_u64 (SD_, instruction_0);
1355 StoreFPR (fd, fmt_single, PSUpper (ValueFPR (fs, fmt_ps)));
1358 :function:::void:do_cvt_w_fmt:int fmt, int fd, int fs, address_word instruction_0
1361 if ((fmt == fmt_word) | ((fmt == fmt_long) || (fmt == fmt_word)))
1362 SignalException (ReservedInstruction, instruction_0);
1363 StoreFPR (fd, fmt_word, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
1367 :function:::void:do_div_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
1370 StoreFPR (fd, fmt, Divide (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
1373 :function:::void:do_dmfc1b:int rt, int fs
1383 if (SizeFGR () == 64)
1385 else if ((fs & 0x1) == 0)
1386 GPR[rt] = SET64HI (FGR[fs+1]) | FGR[fs];
1388 GPR[rt] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
1389 TRACE_ALU_RESULT (GPR[rt]);
1392 :function:::void:do_dmtc1b:int rt, int fs
1394 if (SizeFGR () == 64)
1395 StoreFPR (fs, fmt_uninterpreted_64, GPR[rt]);
1396 else if ((fs & 0x1) == 0)
1397 StoreFPR (fs, fmt_uninterpreted_64, GPR[rt]);
1402 :function:::void:do_floor_fmt:int type, int fmt, int fd, int fs
1405 StoreFPR (fd, type, Convert (FP_RM_TOMINF, ValueFPR (fs, fmt), fmt,
1409 :function:::void:do_luxc1_32:int fd, int rindex, int rbase
1413 address_word base = GPR[rbase];
1414 address_word index = GPR[rindex];
1415 address_word vaddr = base + index;
1417 if (SizeFGR () != 64)
1419 /* Arrange for the bottom 3 bits of (base + index) to be 0. */
1420 if ((vaddr & 0x7) != 0)
1421 index -= (vaddr & 0x7);
1422 COP_LD (1, fd, do_load_double (SD_, base, index));
1425 :function:::void:do_luxc1_64:int fd, int rindex, int rbase
1427 address_word base = GPR[rbase];
1428 address_word index = GPR[rindex];
1429 address_word vaddr = base + index;
1430 if (SizeFGR () != 64)
1432 /* Arrange for the bottom 3 bits of (base + index) to be 0. */
1433 if ((vaddr & 0x7) != 0)
1434 index -= (vaddr & 0x7);
1435 COP_LD (1, fd, do_load (SD_, AccessLength_DOUBLEWORD, base, index));
1439 :function:::void:do_lwc1:int ft, int offset, int base
1442 COP_LW (1, ft, do_load (SD_, AccessLength_WORD, GPR[base],
1443 EXTEND16 (offset)));
1446 :function:::void:do_lwxc1:int fd, int index, int base, address_word instruction_0
1449 check_u64 (SD_, instruction_0);
1450 COP_LW (1, fd, do_load (SD_, AccessLength_WORD, GPR[base], GPR[index]));
1453 :function:::void:do_madd_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
1456 check_u64 (SD_, instruction_0);
1457 check_fmt_p (SD_, fmt, instruction_0);
1458 StoreFPR (fd, fmt, MultiplyAdd (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
1459 ValueFPR (fr, fmt), fmt));
1462 :function:::void:do_mfc1b:int rt, int fs
1465 GPR[rt] = EXTEND32 (FGR[fs]);
1466 TRACE_ALU_RESULT (GPR[rt]);
1469 :function:::void:do_mov_fmt:int fmt, int fd, int fs, address_word instruction_0
1472 check_fmt_p (SD_, fmt, instruction_0);
1473 StoreFPR (fd, fmt, ValueFPR (fs, fmt));
1476 :function:::void:do_movtf:int tf, int rd, int rs, int cc
1479 if (GETFCC(cc) == tf)
1483 :function:::void:do_movtf_fmt:int tf, int fmt, int fd, int fs, int cc
1488 if (GETFCC(cc) == tf)
1489 StoreFPR (fd, fmt, ValueFPR (fs, fmt));
1491 StoreFPR (fd, fmt, ValueFPR (fd, fmt)); /* set fmt */
1496 fdx = PackPS (PSUpper (ValueFPR ((GETFCC (cc+1) == tf) ? fs : fd,
1498 PSLower (ValueFPR ((GETFCC (cc+0) == tf) ? fs : fd,
1500 StoreFPR (fd, fmt_ps, fdx);
1504 :function:::void:do_movn_fmt:int fmt, int fd, int fs, int rt
1508 StoreFPR (fd, fmt, ValueFPR (fs, fmt));
1510 StoreFPR (fd, fmt, ValueFPR (fd, fmt));
1513 :function:::void:do_movz_fmt:int fmt, int fd, int fs, int rt
1517 StoreFPR (fd, fmt, ValueFPR (fs, fmt));
1519 StoreFPR (fd, fmt, ValueFPR (fd, fmt));
1522 :function:::void:do_msub_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
1525 check_u64 (SD_, instruction_0);
1526 check_fmt_p (SD_, fmt, instruction_0);
1527 StoreFPR (fd, fmt, MultiplySub (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
1528 ValueFPR (fr, fmt), fmt));
1531 :function:::void:do_mtc1b:int rt, int fs
1534 StoreFPR (fs, fmt_uninterpreted_32, VL4_8 (GPR[rt]));
1537 :function:::void:do_mul_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
1540 check_fmt_p (SD_, fmt, instruction_0);
1541 StoreFPR (fd, fmt, Multiply (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
1544 :function:::void:do_neg_fmt:int fmt, int fd, int fs, address_word instruction_0
1547 check_fmt_p (SD_, fmt, instruction_0);
1548 StoreFPR (fd, fmt, Negate (ValueFPR (fs, fmt), fmt));
1551 :function:::void:do_nmadd_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
1554 check_u64 (SD_, instruction_0);
1555 check_fmt_p (SD_, fmt, instruction_0);
1556 StoreFPR (fd, fmt, NegMultiplyAdd (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
1557 ValueFPR (fr, fmt), fmt));
1560 :function:::void:do_nmsub_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
1563 check_u64 (SD_, instruction_0);
1564 check_fmt_p (SD_, fmt, instruction_0);
1565 StoreFPR (fd, fmt, NegMultiplySub (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
1566 ValueFPR (fr, fmt), fmt));
1569 :function:::void:do_pll_ps:int fd, int fs, int ft, address_word instruction_0
1572 check_u64 (SD_, instruction_0);
1573 StoreFPR (fd, fmt_ps, PackPS (PSLower (ValueFPR (fs, fmt_ps)),
1574 PSLower (ValueFPR (ft, fmt_ps))));
1577 :function:::void:do_plu_ps:int fd, int fs, int ft, address_word instruction_0
1580 check_u64 (SD_, instruction_0);
1581 StoreFPR (fd, fmt_ps, PackPS (PSLower (ValueFPR (fs, fmt_ps)),
1582 PSUpper (ValueFPR (ft, fmt_ps))));
1585 :function:::void:do_pul_ps:int fd, int fs, int ft, address_word instruction_0
1588 check_u64 (SD_, instruction_0);
1589 StoreFPR (fd, fmt_ps, PackPS (PSUpper (ValueFPR (fs, fmt_ps)),
1590 PSLower (ValueFPR (ft, fmt_ps))));
1593 :function:::void:do_puu_ps:int fd, int fs, int ft, address_word instruction_0
1596 check_u64 (SD_, instruction_0);
1597 StoreFPR (fd, fmt_ps, PackPS (PSUpper (ValueFPR (fs, fmt_ps)),
1598 PSUpper (ValueFPR (ft, fmt_ps))));
1601 :function:::void:do_recip_fmt:int fmt, int fd, int fs
1604 StoreFPR (fd, fmt, Recip (ValueFPR (fs, fmt), fmt));
1607 :function:::void:do_round_fmt:int type, int fmt, int fd, int fs
1610 StoreFPR (fd, type, Convert (FP_RM_NEAREST, ValueFPR (fs, fmt), fmt,
1614 :function:::void:do_rsqrt_fmt:int fmt, int fd, int fs
1617 StoreFPR (fd, fmt, RSquareRoot (ValueFPR (fs, fmt), fmt));
1620 :function:::void:do_prefx:int hint, int rindex, int rbase
1622 address_word base = GPR[rbase];
1623 address_word index = GPR[rindex];
1625 address_word vaddr = loadstore_ea (SD_, base, index);
1626 address_word paddr = vaddr;
1627 /* Prefetch (paddr, vaddr, isDATA, hint); */
1631 :function:::void:do_sdc1:int ft, int offset, int base
1638 do_store_double (SD_, GPR[base], EXTEND16 (offset), COP_SD (1, ft));
1641 :function:::void:do_suxc1_32:int fs, int rindex, int rbase
1645 address_word base = GPR[rbase];
1646 address_word index = GPR[rindex];
1647 address_word vaddr = base + index;
1649 if (SizeFGR () != 64)
1651 /* Arrange for the bottom 3 bits of (base + index) to be 0. */
1652 if ((vaddr & 0x7) != 0)
1653 index -= (vaddr & 0x7);
1654 do_store_double (SD_, base, index, COP_SD (1, fs));
1657 :function:::void:do_suxc1_64:int fs, int rindex, int rbase
1659 address_word base = GPR[rbase];
1660 address_word index = GPR[rindex];
1661 address_word vaddr = base + index;
1662 if (SizeFGR () != 64)
1664 /* Arrange for the bottom 3 bits of (base + index) to be 0. */
1665 if ((vaddr & 0x7) != 0)
1666 index -= (vaddr & 0x7);
1667 do_store (SD_, AccessLength_DOUBLEWORD, base, index, COP_SD (1, fs));
1670 :function:::void:do_sqrt_fmt:int fmt, int fd, int fs
1673 StoreFPR (fd, fmt, (SquareRoot (ValueFPR (fs, fmt), fmt)));
1676 :function:::void:do_sub_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
1679 check_fmt_p (SD_, fmt, instruction_0);
1680 StoreFPR (fd, fmt, Sub (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
1683 :function:::void:do_swc1:int ft, int roffset, int rbase, address_word instruction_0
1685 address_word base = GPR[rbase];
1686 address_word offset = EXTEND16 (roffset);
1689 address_word vaddr = loadstore_ea (SD_, base, offset);
1690 address_word paddr = vaddr;
1692 if ((vaddr & 3) != 0)
1694 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr,
1695 write_transfer, sim_core_unaligned_signal);
1700 uword64 memval1 = 0;
1701 uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1702 address_word reverseendian =
1703 (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
1704 address_word bigendiancpu =
1705 (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
1707 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
1708 byte = ((vaddr & mask) ^ bigendiancpu);
1709 memval = (((uword64)COP_SW(1, ft)) << (8 * byte));
1710 StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr, isREAL);
1715 :function:::void:do_swxc1:int fs, int rindex, int rbase, address_word instruction_0
1717 address_word base = GPR[rbase];
1718 address_word index = GPR[rindex];
1720 check_u64 (SD_, instruction_0);
1722 address_word vaddr = loadstore_ea (SD_, base, index);
1723 address_word paddr = vaddr;
1725 if ((vaddr & 3) != 0)
1727 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer,
1728 sim_core_unaligned_signal);
1732 unsigned64 memval = 0;
1733 unsigned64 memval1 = 0;
1734 unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1735 address_word reverseendian =
1736 (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
1737 address_word bigendiancpu =
1738 (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
1740 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
1741 byte = ((vaddr & mask) ^ bigendiancpu);
1742 memval = (((unsigned64)COP_SW(1,fs)) << (8 * byte));
1743 StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr,
1749 :function:::void:do_trunc_fmt:int type, int fmt, int fd, int fs
1752 StoreFPR (fd, type, Convert (FP_RM_TOZERO, ValueFPR (fs, fmt), fmt,
1756 000000,5.RS,5.RT,5.RD,00000,100000:SPECIAL:32::ADD
1757 "add r<RD>, r<RS>, r<RT>"
1771 do_add (SD_, RS, RT, RD);
1776 001000,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDI
1777 "addi r<RT>, r<RS>, <IMMEDIATE>"
1791 do_addi (SD_, RS, RT, IMMEDIATE);
1796 :function:::void:do_addiu:int rs, int rt, unsigned16 immediate
1798 if (NotWordValue (GPR[rs]))
1800 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
1801 GPR[rt] = EXTEND32 (GPR[rs] + EXTEND16 (immediate));
1802 TRACE_ALU_RESULT (GPR[rt]);
1805 001001,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDIU
1806 "addiu r<RT>, r<RS>, <IMMEDIATE>"
1820 do_addiu (SD_, RS, RT, IMMEDIATE);
1825 :function:::void:do_addu:int rs, int rt, int rd
1827 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
1829 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1830 GPR[rd] = EXTEND32 (GPR[rs] + GPR[rt]);
1831 TRACE_ALU_RESULT (GPR[rd]);
1834 000000,5.RS,5.RT,5.RD,00000,100001:SPECIAL:32::ADDU
1835 "addu r<RD>, r<RS>, r<RT>"
1849 do_addu (SD_, RS, RT, RD);
1854 :function:::void:do_and:int rs, int rt, int rd
1856 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1857 GPR[rd] = GPR[rs] & GPR[rt];
1858 TRACE_ALU_RESULT (GPR[rd]);
1861 000000,5.RS,5.RT,5.RD,00000,100100:SPECIAL:32::AND
1862 "and r<RD>, r<RS>, r<RT>"
1876 do_and (SD_, RS, RT, RD);
1881 001100,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ANDI
1882 "andi r<RT>, r<RS>, %#lx<IMMEDIATE>"
1896 do_andi (SD_,RS, RT, IMMEDIATE);
1901 000100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQ
1902 "beq r<RS>, r<RT>, <OFFSET>"
1916 address_word offset = EXTEND16 (OFFSET) << 2;
1917 if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
1919 DELAY_SLOT (NIA + offset);
1925 010100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQL
1926 "beql r<RS>, r<RT>, <OFFSET>"
1939 address_word offset = EXTEND16 (OFFSET) << 2;
1940 if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
1942 DELAY_SLOT (NIA + offset);
1945 NULLIFY_NEXT_INSTRUCTION ();
1950 000001,5.RS,00001,16.OFFSET:REGIMM:32::BGEZ
1951 "bgez r<RS>, <OFFSET>"
1965 address_word offset = EXTEND16 (OFFSET) << 2;
1966 if ((signed_word) GPR[RS] >= 0)
1968 DELAY_SLOT (NIA + offset);
1974 000001,5.RS!31,10001,16.OFFSET:REGIMM:32::BGEZAL
1975 "bgezal r<RS>, <OFFSET>"
1989 address_word offset = EXTEND16 (OFFSET) << 2;
1993 if ((signed_word) GPR[RS] >= 0)
1995 DELAY_SLOT (NIA + offset);
2001 000001,5.RS!31,10011,16.OFFSET:REGIMM:32::BGEZALL
2002 "bgezall r<RS>, <OFFSET>"
2015 address_word offset = EXTEND16 (OFFSET) << 2;
2019 /* NOTE: The branch occurs AFTER the next instruction has been
2021 if ((signed_word) GPR[RS] >= 0)
2023 DELAY_SLOT (NIA + offset);
2026 NULLIFY_NEXT_INSTRUCTION ();
2031 000001,5.RS,00011,16.OFFSET:REGIMM:32::BGEZL
2032 "bgezl r<RS>, <OFFSET>"
2045 address_word offset = EXTEND16 (OFFSET) << 2;
2046 if ((signed_word) GPR[RS] >= 0)
2048 DELAY_SLOT (NIA + offset);
2051 NULLIFY_NEXT_INSTRUCTION ();
2056 000111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZ
2057 "bgtz r<RS>, <OFFSET>"
2071 address_word offset = EXTEND16 (OFFSET) << 2;
2072 if ((signed_word) GPR[RS] > 0)
2074 DELAY_SLOT (NIA + offset);
2080 010111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZL
2081 "bgtzl r<RS>, <OFFSET>"
2094 address_word offset = EXTEND16 (OFFSET) << 2;
2095 /* NOTE: The branch occurs AFTER the next instruction has been
2097 if ((signed_word) GPR[RS] > 0)
2099 DELAY_SLOT (NIA + offset);
2102 NULLIFY_NEXT_INSTRUCTION ();
2107 000110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZ
2108 "blez r<RS>, <OFFSET>"
2122 address_word offset = EXTEND16 (OFFSET) << 2;
2123 /* NOTE: The branch occurs AFTER the next instruction has been
2125 if ((signed_word) GPR[RS] <= 0)
2127 DELAY_SLOT (NIA + offset);
2133 010110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZL
2134 "bgezl r<RS>, <OFFSET>"
2147 address_word offset = EXTEND16 (OFFSET) << 2;
2148 if ((signed_word) GPR[RS] <= 0)
2150 DELAY_SLOT (NIA + offset);
2153 NULLIFY_NEXT_INSTRUCTION ();
2158 000001,5.RS,00000,16.OFFSET:REGIMM:32::BLTZ
2159 "bltz r<RS>, <OFFSET>"
2173 address_word offset = EXTEND16 (OFFSET) << 2;
2174 if ((signed_word) GPR[RS] < 0)
2176 DELAY_SLOT (NIA + offset);
2182 000001,5.RS!31,10000,16.OFFSET:REGIMM:32::BLTZAL
2183 "bltzal r<RS>, <OFFSET>"
2197 address_word offset = EXTEND16 (OFFSET) << 2;
2201 /* NOTE: The branch occurs AFTER the next instruction has been
2203 if ((signed_word) GPR[RS] < 0)
2205 DELAY_SLOT (NIA + offset);
2211 000001,5.RS!31,10010,16.OFFSET:REGIMM:32::BLTZALL
2212 "bltzall r<RS>, <OFFSET>"
2225 address_word offset = EXTEND16 (OFFSET) << 2;
2229 if ((signed_word) GPR[RS] < 0)
2231 DELAY_SLOT (NIA + offset);
2234 NULLIFY_NEXT_INSTRUCTION ();
2239 000001,5.RS,00010,16.OFFSET:REGIMM:32::BLTZL
2240 "bltzl r<RS>, <OFFSET>"
2253 address_word offset = EXTEND16 (OFFSET) << 2;
2254 /* NOTE: The branch occurs AFTER the next instruction has been
2256 if ((signed_word) GPR[RS] < 0)
2258 DELAY_SLOT (NIA + offset);
2261 NULLIFY_NEXT_INSTRUCTION ();
2266 000101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNE
2267 "bne r<RS>, r<RT>, <OFFSET>"
2281 address_word offset = EXTEND16 (OFFSET) << 2;
2282 if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
2284 DELAY_SLOT (NIA + offset);
2290 010101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNEL
2291 "bnel r<RS>, r<RT>, <OFFSET>"
2304 address_word offset = EXTEND16 (OFFSET) << 2;
2305 if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
2307 DELAY_SLOT (NIA + offset);
2310 NULLIFY_NEXT_INSTRUCTION ();
2315 000000,20.CODE,001101:SPECIAL:32::BREAK
2330 do_break (SD_, instruction_0);
2335 011100,5.RS,5.RT,5.RD,00000,100001:SPECIAL2:32::CLO
2345 do_clo (SD_, RD, RS);
2350 011100,5.RS,5.RT,5.RD,00000,100000:SPECIAL2:32::CLZ
2360 do_clz (SD_, RD, RS);
2365 000000,5.RS,5.RT,5.RD,00000,101100:SPECIAL:64::DADD
2366 "dadd r<RD>, r<RS>, r<RT>"
2375 check_u64 (SD_, instruction_0);
2376 do_dadd (SD_, RD, RS, RT);
2381 011000,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDI
2382 "daddi r<RT>, r<RS>, <IMMEDIATE>"
2391 check_u64 (SD_, instruction_0);
2392 do_daddi (SD_, RT, RS, IMMEDIATE);
2397 :function:::void:do_daddiu:int rs, int rt, unsigned16 immediate
2399 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
2400 GPR[rt] = GPR[rs] + EXTEND16 (immediate);
2401 TRACE_ALU_RESULT (GPR[rt]);
2404 011001,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDIU
2405 "daddiu r<RT>, r<RS>, <IMMEDIATE>"
2414 check_u64 (SD_, instruction_0);
2415 do_daddiu (SD_, RS, RT, IMMEDIATE);
2420 :function:::void:do_daddu:int rs, int rt, int rd
2422 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2423 GPR[rd] = GPR[rs] + GPR[rt];
2424 TRACE_ALU_RESULT (GPR[rd]);
2427 000000,5.RS,5.RT,5.RD,00000,101101:SPECIAL:64::DADDU
2428 "daddu r<RD>, r<RS>, r<RT>"
2437 check_u64 (SD_, instruction_0);
2438 do_daddu (SD_, RS, RT, RD);
2443 011100,5.RS,5.RT,5.RD,00000,100101:SPECIAL2:64::DCLO
2451 check_u64 (SD_, instruction_0);
2452 do_dclo (SD_, RD, RS);
2457 011100,5.RS,5.RT,5.RD,00000,100100:SPECIAL2:64::DCLZ
2465 check_u64 (SD_, instruction_0);
2466 do_dclz (SD_, RD, RS);
2471 :function:::void:do_ddiv:int rs, int rt
2473 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
2474 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2476 signed64 n = GPR[rs];
2477 signed64 d = GPR[rt];
2482 lo = SIGNED64 (0x8000000000000000);
2485 else if (d == -1 && n == SIGNED64 (0x8000000000000000))
2487 lo = SIGNED64 (0x8000000000000000);
2498 TRACE_ALU_RESULT2 (HI, LO);
2501 000000,5.RS,5.RT,0000000000,011110:SPECIAL:64::DDIV
2511 check_u64 (SD_, instruction_0);
2512 do_ddiv (SD_, RS, RT);
2517 :function:::void:do_ddivu:int rs, int rt
2519 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
2520 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2522 unsigned64 n = GPR[rs];
2523 unsigned64 d = GPR[rt];
2528 lo = SIGNED64 (0x8000000000000000);
2539 TRACE_ALU_RESULT2 (HI, LO);
2542 000000,5.RS,5.RT,0000000000,011111:SPECIAL:64::DDIVU
2543 "ddivu r<RS>, r<RT>"
2552 check_u64 (SD_, instruction_0);
2553 do_ddivu (SD_, RS, RT);
2556 :function:::void:do_div:int rs, int rt
2558 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
2559 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2561 signed32 n = GPR[rs];
2562 signed32 d = GPR[rt];
2565 LO = EXTEND32 (0x80000000);
2568 else if (n == SIGNED32 (0x80000000) && d == -1)
2570 LO = EXTEND32 (0x80000000);
2575 LO = EXTEND32 (n / d);
2576 HI = EXTEND32 (n % d);
2579 TRACE_ALU_RESULT2 (HI, LO);
2582 000000,5.RS,5.RT,0000000000,011010:SPECIAL:32::DIV
2597 do_div (SD_, RS, RT);
2602 :function:::void:do_divu:int rs, int rt
2604 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
2605 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2607 unsigned32 n = GPR[rs];
2608 unsigned32 d = GPR[rt];
2611 LO = EXTEND32 (0x80000000);
2616 LO = EXTEND32 (n / d);
2617 HI = EXTEND32 (n % d);
2620 TRACE_ALU_RESULT2 (HI, LO);
2623 000000,5.RS,5.RT,0000000000,011011:SPECIAL:32::DIVU
2638 do_divu (SD_, RS, RT);
2642 :function:::void:do_dmultx:int rs, int rt, int rd, int signed_p
2652 unsigned64 op1 = GPR[rs];
2653 unsigned64 op2 = GPR[rt];
2654 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
2655 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2656 /* make signed multiply unsigned */
2660 if ((signed64) op1 < 0)
2665 if ((signed64) op2 < 0)
2671 /* multiply out the 4 sub products */
2672 m00 = ((unsigned64) VL4_8 (op1) * (unsigned64) VL4_8 (op2));
2673 m10 = ((unsigned64) VH4_8 (op1) * (unsigned64) VL4_8 (op2));
2674 m01 = ((unsigned64) VL4_8 (op1) * (unsigned64) VH4_8 (op2));
2675 m11 = ((unsigned64) VH4_8 (op1) * (unsigned64) VH4_8 (op2));
2676 /* add the products */
2677 mid = ((unsigned64) VH4_8 (m00)
2678 + (unsigned64) VL4_8 (m10)
2679 + (unsigned64) VL4_8 (m01));
2680 lo = U8_4 (mid, m00);
2682 + (unsigned64) VH4_8 (mid)
2683 + (unsigned64) VH4_8 (m01)
2684 + (unsigned64) VH4_8 (m10));
2694 /* save the result HI/LO (and a gpr) */
2699 TRACE_ALU_RESULT2 (HI, LO);
2702 :function:::void:do_dmult:int rs, int rt, int rd
2704 do_dmultx (SD_, rs, rt, rd, 1);
2707 000000,5.RS,5.RT,0000000000,011100:SPECIAL:64::DMULT
2708 "dmult r<RS>, r<RT>"
2716 check_u64 (SD_, instruction_0);
2717 do_dmult (SD_, RS, RT, 0);
2720 000000,5.RS,5.RT,5.RD,00000,011100:SPECIAL:64::DMULT
2721 "dmult r<RS>, r<RT>":RD == 0
2722 "dmult r<RD>, r<RS>, r<RT>"
2725 check_u64 (SD_, instruction_0);
2726 do_dmult (SD_, RS, RT, RD);
2731 :function:::void:do_dmultu:int rs, int rt, int rd
2733 do_dmultx (SD_, rs, rt, rd, 0);
2736 000000,5.RS,5.RT,0000000000,011101:SPECIAL:64::DMULTU
2737 "dmultu r<RS>, r<RT>"
2745 check_u64 (SD_, instruction_0);
2746 do_dmultu (SD_, RS, RT, 0);
2749 000000,5.RS,5.RT,5.RD,00000,011101:SPECIAL:64::DMULTU
2750 "dmultu r<RD>, r<RS>, r<RT>":RD == 0
2751 "dmultu r<RS>, r<RT>"
2754 check_u64 (SD_, instruction_0);
2755 do_dmultu (SD_, RS, RT, RD);
2759 :function:::unsigned64:do_dror:unsigned64 x,unsigned64 y
2764 TRACE_ALU_INPUT2 (x, y);
2765 result = ROTR64 (x, y);
2766 TRACE_ALU_RESULT (result);
2770 000000,00001,5.RT,5.RD,5.SHIFT,111010::64::DROR
2771 "dror r<RD>, r<RT>, <SHIFT>"
2776 check_u64 (SD_, instruction_0);
2777 GPR[RD] = do_dror (SD_, GPR[RT], SHIFT);
2780 000000,00001,5.RT,5.RD,5.SHIFT,111110::64::DROR32
2781 "dror32 r<RD>, r<RT>, <SHIFT>"
2786 check_u64 (SD_, instruction_0);
2787 GPR[RD] = do_dror (SD_, GPR[RT], SHIFT + 32);
2790 000000,5.RS,5.RT,5.RD,00001,010110::64::DRORV
2791 "drorv r<RD>, r<RT>, r<RS>"
2796 check_u64 (SD_, instruction_0);
2797 GPR[RD] = do_dror (SD_, GPR[RT], GPR[RS]);
2801 :function:::void:do_dsll:int rt, int rd, int shift
2803 TRACE_ALU_INPUT2 (GPR[rt], shift);
2804 GPR[rd] = GPR[rt] << shift;
2805 TRACE_ALU_RESULT (GPR[rd]);
2808 000000,00000,5.RT,5.RD,5.SHIFT,111000:SPECIAL:64::DSLL
2809 "dsll r<RD>, r<RT>, <SHIFT>"
2818 check_u64 (SD_, instruction_0);
2819 do_dsll (SD_, RT, RD, SHIFT);
2823 000000,00000,5.RT,5.RD,5.SHIFT,111100:SPECIAL:64::DSLL32
2824 "dsll32 r<RD>, r<RT>, <SHIFT>"
2833 check_u64 (SD_, instruction_0);
2834 do_dsll32 (SD_, RD, RT, SHIFT);
2837 :function:::void:do_dsllv:int rs, int rt, int rd
2839 int s = MASKED64 (GPR[rs], 5, 0);
2840 TRACE_ALU_INPUT2 (GPR[rt], s);
2841 GPR[rd] = GPR[rt] << s;
2842 TRACE_ALU_RESULT (GPR[rd]);
2845 000000,5.RS,5.RT,5.RD,00000,010100:SPECIAL:64::DSLLV
2846 "dsllv r<RD>, r<RT>, r<RS>"
2855 check_u64 (SD_, instruction_0);
2856 do_dsllv (SD_, RS, RT, RD);
2859 :function:::void:do_dsra:int rt, int rd, int shift
2861 TRACE_ALU_INPUT2 (GPR[rt], shift);
2862 GPR[rd] = ((signed64) GPR[rt]) >> shift;
2863 TRACE_ALU_RESULT (GPR[rd]);
2867 000000,00000,5.RT,5.RD,5.SHIFT,111011:SPECIAL:64::DSRA
2868 "dsra r<RD>, r<RT>, <SHIFT>"
2877 check_u64 (SD_, instruction_0);
2878 do_dsra (SD_, RT, RD, SHIFT);
2882 000000,00000,5.RT,5.RD,5.SHIFT,111111:SPECIAL:64::DSRA32
2883 "dsra32 r<RD>, r<RT>, <SHIFT>"
2892 check_u64 (SD_, instruction_0);
2893 do_dsra32 (SD_, RD, RT, SHIFT);
2897 :function:::void:do_dsrav:int rs, int rt, int rd
2899 int s = MASKED64 (GPR[rs], 5, 0);
2900 TRACE_ALU_INPUT2 (GPR[rt], s);
2901 GPR[rd] = ((signed64) GPR[rt]) >> s;
2902 TRACE_ALU_RESULT (GPR[rd]);
2905 000000,5.RS,5.RT,5.RD,00000,010111:SPECIAL:64::DSRAV
2906 "dsrav r<RD>, r<RT>, r<RS>"
2915 check_u64 (SD_, instruction_0);
2916 do_dsrav (SD_, RS, RT, RD);
2919 :function:::void:do_dsrl:int rt, int rd, int shift
2921 TRACE_ALU_INPUT2 (GPR[rt], shift);
2922 GPR[rd] = (unsigned64) GPR[rt] >> shift;
2923 TRACE_ALU_RESULT (GPR[rd]);
2927 000000,00000,5.RT,5.RD,5.SHIFT,111010:SPECIAL:64::DSRL
2928 "dsrl r<RD>, r<RT>, <SHIFT>"
2937 check_u64 (SD_, instruction_0);
2938 do_dsrl (SD_, RT, RD, SHIFT);
2942 000000,00000,5.RT,5.RD,5.SHIFT,111110:SPECIAL:64::DSRL32
2943 "dsrl32 r<RD>, r<RT>, <SHIFT>"
2952 check_u64 (SD_, instruction_0);
2953 do_dsrl32 (SD_, RD, RT, SHIFT);
2957 :function:::void:do_dsrlv:int rs, int rt, int rd
2959 int s = MASKED64 (GPR[rs], 5, 0);
2960 TRACE_ALU_INPUT2 (GPR[rt], s);
2961 GPR[rd] = (unsigned64) GPR[rt] >> s;
2962 TRACE_ALU_RESULT (GPR[rd]);
2967 000000,5.RS,5.RT,5.RD,00000,010110:SPECIAL:64::DSRLV
2968 "dsrlv r<RD>, r<RT>, r<RS>"
2977 check_u64 (SD_, instruction_0);
2978 do_dsrlv (SD_, RS, RT, RD);
2982 000000,5.RS,5.RT,5.RD,00000,101110:SPECIAL:64::DSUB
2983 "dsub r<RD>, r<RS>, r<RT>"
2992 check_u64 (SD_, instruction_0);
2993 do_dsub (SD_, RD, RS, RT);
2997 :function:::void:do_dsubu:int rs, int rt, int rd
2999 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3000 GPR[rd] = GPR[rs] - GPR[rt];
3001 TRACE_ALU_RESULT (GPR[rd]);
3004 000000,5.RS,5.RT,5.RD,00000,101111:SPECIAL:64::DSUBU
3005 "dsubu r<RD>, r<RS>, r<RT>"
3014 check_u64 (SD_, instruction_0);
3015 do_dsubu (SD_, RS, RT, RD);
3019 000010,26.INSTR_INDEX:NORMAL:32::J
3034 /* NOTE: The region used is that of the delay slot NIA and NOT the
3035 current instruction */
3036 address_word region = (NIA & MASK (63, 28));
3037 DELAY_SLOT (region | (INSTR_INDEX << 2));
3041 000011,26.INSTR_INDEX:NORMAL:32::JAL
3056 /* NOTE: The region used is that of the delay slot and NOT the
3057 current instruction */
3058 address_word region = (NIA & MASK (63, 28));
3060 DELAY_SLOT (region | (INSTR_INDEX << 2));
3063 000000,5.RS,00000,5.RD,00000,001001:SPECIAL:32::JALR
3064 "jalr r<RS>":RD == 31
3079 address_word temp = GPR[RS];
3084 000000,5.RS,00000,5.RD,10000,001001:SPECIAL:32::JALR_HB
3085 "jalr.hb r<RS>":RD == 31
3086 "jalr.hb r<RD>, r<RS>"
3090 address_word temp = GPR[RS];
3095 000000,5.RS,0000000000,00000,001000:SPECIAL:32::JR
3110 DELAY_SLOT (GPR[RS]);
3113 000000,5.RS,0000000000,10000,001000:SPECIAL:32::JR_HB
3118 DELAY_SLOT (GPR[RS]);
3121 :function:::unsigned_word:do_load:unsigned access, address_word base, address_word offset
3123 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
3124 address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
3125 address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
3131 paddr = vaddr = loadstore_ea (SD_, base, offset);
3132 if ((vaddr & access) != 0)
3134 SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map, access+1, vaddr, read_transfer, sim_core_unaligned_signal);
3136 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
3137 LoadMemory (&memval, NULL, access, paddr, vaddr, isDATA, isREAL);
3138 byte = ((vaddr & mask) ^ bigendiancpu);
3139 return (memval >> (8 * byte));
3142 :function:::unsigned_word:do_load_left:unsigned access, address_word base, address_word offset, unsigned_word rt
3144 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
3145 address_word reverseendian = (ReverseEndian ? -1 : 0);
3146 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
3154 unsigned_word lhs_mask;
3157 paddr = vaddr = loadstore_ea (SD_, base, offset);
3158 paddr = (paddr ^ (reverseendian & mask));
3159 if (BigEndianMem == 0)
3160 paddr = paddr & ~access;
3162 /* compute where within the word/mem we are */
3163 byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
3164 word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
3165 nr_lhs_bits = 8 * byte + 8;
3166 nr_rhs_bits = 8 * access - 8 * byte;
3167 /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
3169 /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
3170 (long) ((unsigned64) vaddr >> 32), (long) vaddr,
3171 (long) ((unsigned64) paddr >> 32), (long) paddr,
3172 word, byte, nr_lhs_bits, nr_rhs_bits); */
3174 LoadMemory (&memval, NULL, byte, paddr, vaddr, isDATA, isREAL);
3177 /* GPR{31..32-NR_LHS_BITS} = memval{NR_LHS_BITS-1..0} */
3178 temp = (memval << nr_rhs_bits);
3182 /* GPR{31..32-NR_LHS_BITS = memval{32+NR_LHS_BITS..32} */
3183 temp = (memval >> nr_lhs_bits);
3185 lhs_mask = LSMASK (nr_lhs_bits + nr_rhs_bits - 1, nr_rhs_bits);
3186 rt = (rt & ~lhs_mask) | (temp & lhs_mask);
3188 /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx & 0x%08lx%08lx -> 0x%08lx%08lx\n",
3189 (long) ((unsigned64) memval >> 32), (long) memval,
3190 (long) ((unsigned64) temp >> 32), (long) temp,
3191 (long) ((unsigned64) lhs_mask >> 32), (long) lhs_mask,
3192 (long) (rt >> 32), (long) rt); */
3196 :function:::unsigned_word:do_load_right:unsigned access, address_word base, address_word offset, unsigned_word rt
3198 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
3199 address_word reverseendian = (ReverseEndian ? -1 : 0);
3200 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
3206 paddr = vaddr = loadstore_ea (SD_, base, offset);
3207 /* NOTE: SPEC is wrong, has `BigEndianMem == 0' not `BigEndianMem != 0' */
3208 paddr = (paddr ^ (reverseendian & mask));
3209 if (BigEndianMem != 0)
3210 paddr = paddr & ~access;
3211 byte = ((vaddr & mask) ^ (bigendiancpu & mask));
3212 /* NOTE: SPEC is wrong, had `byte' not `access - byte'. See SW. */
3213 LoadMemory (&memval, NULL, access - (access & byte), paddr, vaddr, isDATA, isREAL);
3214 /* printf ("lr: 0x%08lx %d@0x%08lx 0x%08lx\n",
3215 (long) paddr, byte, (long) paddr, (long) memval); */
3217 unsigned_word screen = LSMASK (8 * (access - (byte & access) + 1) - 1, 0);
3219 rt |= (memval >> (8 * byte)) & screen;
3225 100000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LB
3226 "lb r<RT>, <OFFSET>(r<BASE>)"
3240 do_lb (SD_,RT,OFFSET,BASE);
3244 100100,5.BASE,5.RT,16.OFFSET:NORMAL:32::LBU
3245 "lbu r<RT>, <OFFSET>(r<BASE>)"
3259 do_lbu (SD_, RT,OFFSET,BASE);
3263 110111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LD
3264 "ld r<RT>, <OFFSET>(r<BASE>)"
3273 check_u64 (SD_, instruction_0);
3274 GPR[RT] = EXTEND64 (do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
3278 1101,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDCz
3279 "ldc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
3292 do_ldc (SD_, ZZ, RT, OFFSET, BASE);
3298 011010,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDL
3299 "ldl r<RT>, <OFFSET>(r<BASE>)"
3308 check_u64 (SD_, instruction_0);
3309 GPR[RT] = do_load_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
3313 011011,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDR
3314 "ldr r<RT>, <OFFSET>(r<BASE>)"
3323 check_u64 (SD_, instruction_0);
3324 GPR[RT] = do_load_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
3328 100001,5.BASE,5.RT,16.OFFSET:NORMAL:32::LH
3329 "lh r<RT>, <OFFSET>(r<BASE>)"
3343 do_lh (SD_,RT,OFFSET,BASE);
3347 100101,5.BASE,5.RT,16.OFFSET:NORMAL:32::LHU
3348 "lhu r<RT>, <OFFSET>(r<BASE>)"
3362 do_lhu (SD_,RT,OFFSET,BASE);
3366 110000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LL
3367 "ll r<RT>, <OFFSET>(r<BASE>)"
3379 do_ll (SD_, RT, OFFSET, BASE);
3383 110100,5.BASE,5.RT,16.OFFSET:NORMAL:64::LLD
3384 "lld r<RT>, <OFFSET>(r<BASE>)"
3393 check_u64 (SD_, instruction_0);
3394 do_lld (SD_, RT, OFFSET, BASE);
3398 001111,00000,5.RT,16.IMMEDIATE:NORMAL:32::LUI
3399 "lui r<RT>, %#lx<IMMEDIATE>"
3413 do_lui (SD_, RT, IMMEDIATE);
3417 100011,5.BASE,5.RT,16.OFFSET:NORMAL:32::LW
3418 "lw r<RT>, <OFFSET>(r<BASE>)"
3432 do_lw (SD_,RT,OFFSET,BASE);
3436 1100,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWCz
3437 "lwc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
3451 do_lwc (SD_, ZZ, RT, OFFSET, BASE);
3455 100010,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWL
3456 "lwl r<RT>, <OFFSET>(r<BASE>)"
3470 do_lwl (SD_, RT, OFFSET, BASE);
3474 100110,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWR
3475 "lwr r<RT>, <OFFSET>(r<BASE>)"
3489 do_lwr (SD_, RT, OFFSET, BASE);
3493 100111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LWU
3494 "lwu r<RT>, <OFFSET>(r<BASE>)"
3503 do_lwu (SD_, RT, OFFSET, BASE, instruction_0);
3508 011100,5.RS,5.RT,00000,00000,000000:SPECIAL2:32::MADD
3514 do_madd (SD_, RS, RT);
3518 011100,5.RS,5.RT,000,2.AC,00000,000000:SPECIAL2:32::MADD
3519 "madd r<RS>, r<RT>":AC == 0
3520 "madd ac<AC>, r<RS>, r<RT>"
3525 do_dsp_madd (SD_, AC, RS, RT);
3529 011100,5.RS,5.RT,00000,00000,000001:SPECIAL2:32::MADDU
3530 "maddu r<RS>, r<RT>"
3535 do_maddu (SD_, RS, RT);
3539 011100,5.RS,5.RT,000,2.AC,00000,000001:SPECIAL2:32::MADDU
3540 "maddu r<RS>, r<RT>":AC == 0
3541 "maddu ac<AC>, r<RS>, r<RT>"
3546 do_dsp_maddu (SD_, AC, RS, RT);
3550 :function:::void:do_mfhi:int rd
3552 check_mf_hilo (SD_, HIHISTORY, LOHISTORY);
3553 TRACE_ALU_INPUT1 (HI);
3555 TRACE_ALU_RESULT (GPR[rd]);
3558 000000,0000000000,5.RD,00000,010000:SPECIAL:32::MFHI
3575 000000,000,2.AC,00000,5.RD,00000,010000:SPECIAL:32::MFHI
3576 "mfhi r<RD>":AC == 0
3577 "mfhi r<RD>, ac<AC>"
3582 do_dsp_mfhi (SD_, AC, RD);
3586 :function:::void:do_mflo:int rd
3588 check_mf_hilo (SD_, LOHISTORY, HIHISTORY);
3589 TRACE_ALU_INPUT1 (LO);
3591 TRACE_ALU_RESULT (GPR[rd]);
3594 000000,0000000000,5.RD,00000,010010:SPECIAL:32::MFLO
3611 000000,000,2.AC,00000,5.RD,00000,010010:SPECIAL:32::MFLO
3612 "mflo r<RD>":AC == 0
3613 "mflo r<RD>, ac<AC>"
3618 do_dsp_mflo (SD_, AC, RD);
3622 000000,5.RS,5.RT,5.RD,00000,001011:SPECIAL:32::MOVN
3623 "movn r<RD>, r<RS>, r<RT>"
3632 do_movn (SD_, RD, RS, RT);
3637 000000,5.RS,5.RT,5.RD,00000,001010:SPECIAL:32::MOVZ
3638 "movz r<RD>, r<RS>, r<RT>"
3647 do_movz (SD_, RD, RS, RT);
3652 011100,5.RS,5.RT,00000,00000,000100:SPECIAL2:32::MSUB
3658 do_msub (SD_, RS, RT);
3662 011100,5.RS,5.RT,000,2.AC,00000,000100:SPECIAL2:32::MSUB
3663 "msub r<RS>, r<RT>":AC == 0
3664 "msub ac<AC>, r<RS>, r<RT>"
3669 do_dsp_msub (SD_, AC, RS, RT);
3673 011100,5.RS,5.RT,00000,00000,000101:SPECIAL2:32::MSUBU
3674 "msubu r<RS>, r<RT>"
3679 do_msubu (SD_, RS, RT);
3683 011100,5.RS,5.RT,000,2.AC,00000,000101:SPECIAL2:32::MSUBU
3684 "msubu r<RS>, r<RT>":AC == 0
3685 "msubu ac<AC>, r<RS>, r<RT>"
3690 do_dsp_msubu (SD_, AC, RS, RT);
3694 000000,5.RS,000000000000000,010001:SPECIAL:32::MTHI
3711 000000,5.RS,00000,000,2.AC,00000,010001:SPECIAL:32::MTHI
3712 "mthi r<RS>":AC == 0
3713 "mthi r<RS>, ac<AC>"
3718 do_dsp_mthi (SD_, AC, RS);
3722 000000,5.RS,000000000000000,010011:SPECIAL:32::MTLO
3739 000000,5.RS,00000,000,2.AC,00000,010011:SPECIAL:32::MTLO
3740 "mtlo r<RS>":AC == 0
3741 "mtlo r<RS>, ac<AC>"
3746 do_dsp_mtlo (SD_, AC, RS);
3750 011100,5.RS,5.RT,5.RD,00000,000010:SPECIAL2:32::MUL
3751 "mul r<RD>, r<RS>, r<RT>"
3758 do_mul (SD_, RD, RS, RT);
3763 :function:::void:do_mult:int rs, int rt, int rd
3766 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
3767 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
3769 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3770 prod = (((signed64)(signed32) GPR[rs])
3771 * ((signed64)(signed32) GPR[rt]));
3772 LO = EXTEND32 (VL4_8 (prod));
3773 HI = EXTEND32 (VH4_8 (prod));
3774 ACX = 0; /* SmartMIPS */
3777 TRACE_ALU_RESULT2 (HI, LO);
3780 000000,5.RS,5.RT,0000000000,011000:SPECIAL:32::MULT
3791 do_mult (SD_, RS, RT, 0);
3795 000000,5.RS,5.RT,000,2.AC,00000,011000:SPECIAL:32::MULT
3796 "mult r<RS>, r<RT>":AC == 0
3797 "mult ac<AC>, r<RS>, r<RT>"
3802 do_dsp_mult (SD_, AC, RS, RT);
3806 000000,5.RS,5.RT,5.RD,00000,011000:SPECIAL:32::MULT
3807 "mult r<RS>, r<RT>":RD == 0
3808 "mult r<RD>, r<RS>, r<RT>"
3812 do_mult (SD_, RS, RT, RD);
3816 :function:::void:do_multu:int rs, int rt, int rd
3819 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
3820 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
3822 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3823 prod = (((unsigned64)(unsigned32) GPR[rs])
3824 * ((unsigned64)(unsigned32) GPR[rt]));
3825 LO = EXTEND32 (VL4_8 (prod));
3826 HI = EXTEND32 (VH4_8 (prod));
3829 TRACE_ALU_RESULT2 (HI, LO);
3832 000000,5.RS,5.RT,0000000000,011001:SPECIAL:32::MULTU
3833 "multu r<RS>, r<RT>"
3843 do_multu (SD_, RS, RT, 0);
3847 000000,5.RS,5.RT,000,2.AC,00000,011001:SPECIAL:32::MULTU
3848 "multu r<RS>, r<RT>":AC == 0
3849 "multu r<RS>, r<RT>"
3854 do_dsp_multu (SD_, AC, RS, RT);
3858 000000,5.RS,5.RT,5.RD,00000,011001:SPECIAL:32::MULTU
3859 "multu r<RS>, r<RT>":RD == 0
3860 "multu r<RD>, r<RS>, r<RT>"
3864 do_multu (SD_, RS, RT, RD);
3868 :function:::void:do_nor:int rs, int rt, int rd
3870 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3871 GPR[rd] = ~ (GPR[rs] | GPR[rt]);
3872 TRACE_ALU_RESULT (GPR[rd]);
3875 000000,5.RS,5.RT,5.RD,00000,100111:SPECIAL:32::NOR
3876 "nor r<RD>, r<RS>, r<RT>"
3890 do_nor (SD_, RS, RT, RD);
3894 :function:::void:do_or:int rs, int rt, int rd
3896 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3897 GPR[rd] = (GPR[rs] | GPR[rt]);
3898 TRACE_ALU_RESULT (GPR[rd]);
3901 000000,5.RS,5.RT,5.RD,00000,100101:SPECIAL:32::OR
3902 "or r<RD>, r<RS>, r<RT>"
3916 do_or (SD_, RS, RT, RD);
3921 :function:::void:do_ori:int rs, int rt, unsigned immediate
3923 TRACE_ALU_INPUT2 (GPR[rs], immediate);
3924 GPR[rt] = (GPR[rs] | immediate);
3925 TRACE_ALU_RESULT (GPR[rt]);
3928 001101,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ORI
3929 "ori r<RT>, r<RS>, %#lx<IMMEDIATE>"
3943 do_ori (SD_, RS, RT, IMMEDIATE);
3947 110011,5.BASE,5.HINT,16.OFFSET:NORMAL:32::PREF
3948 "pref <HINT>, <OFFSET>(r<BASE>)"
3957 do_pref (SD_, HINT, OFFSET, BASE);
3961 :function:::unsigned64:do_ror:unsigned32 x,unsigned32 y
3966 TRACE_ALU_INPUT2 (x, y);
3967 result = EXTEND32 (ROTR32 (x, y));
3968 TRACE_ALU_RESULT (result);
3972 000000,00001,5.RT,5.RD,5.SHIFT,000010::32::ROR
3973 "ror r<RD>, r<RT>, <SHIFT>"
3980 GPR[RD] = do_ror (SD_, GPR[RT], SHIFT);
3983 000000,5.RS,5.RT,5.RD,00001,000110::32::RORV
3984 "rorv r<RD>, r<RT>, r<RS>"
3991 GPR[RD] = do_ror (SD_, GPR[RT], GPR[RS]);
3995 :function:::void:do_store:unsigned access, address_word base, address_word offset, unsigned_word word
3997 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
3998 address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
3999 address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
4005 paddr = vaddr = loadstore_ea (SD_, base, offset);
4006 if ((vaddr & access) != 0)
4008 SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map, access+1, vaddr, write_transfer, sim_core_unaligned_signal);
4010 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
4011 byte = ((vaddr & mask) ^ bigendiancpu);
4012 memval = (word << (8 * byte));
4013 StoreMemory (access, memval, 0, paddr, vaddr, isREAL);
4016 :function:::void:do_store_left:unsigned access, address_word base, address_word offset, unsigned_word rt
4018 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
4019 address_word reverseendian = (ReverseEndian ? -1 : 0);
4020 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
4029 paddr = vaddr = loadstore_ea (SD_, base, offset);
4030 paddr = (paddr ^ (reverseendian & mask));
4031 if (BigEndianMem == 0)
4032 paddr = paddr & ~access;
4034 /* compute where within the word/mem we are */
4035 byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
4036 word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
4037 nr_lhs_bits = 8 * byte + 8;
4038 nr_rhs_bits = 8 * access - 8 * byte;
4039 /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
4040 /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
4041 (long) ((unsigned64) vaddr >> 32), (long) vaddr,
4042 (long) ((unsigned64) paddr >> 32), (long) paddr,
4043 word, byte, nr_lhs_bits, nr_rhs_bits); */
4047 memval = (rt >> nr_rhs_bits);
4051 memval = (rt << nr_lhs_bits);
4053 /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx\n",
4054 (long) ((unsigned64) rt >> 32), (long) rt,
4055 (long) ((unsigned64) memval >> 32), (long) memval); */
4056 StoreMemory (byte, memval, 0, paddr, vaddr, isREAL);
4059 :function:::void:do_store_right:unsigned access, address_word base, address_word offset, unsigned_word rt
4061 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
4062 address_word reverseendian = (ReverseEndian ? -1 : 0);
4063 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
4069 paddr = vaddr = loadstore_ea (SD_, base, offset);
4070 paddr = (paddr ^ (reverseendian & mask));
4071 if (BigEndianMem != 0)
4073 byte = ((vaddr & mask) ^ (bigendiancpu & mask));
4074 memval = (rt << (byte * 8));
4075 StoreMemory (access - (access & byte), memval, 0, paddr, vaddr, isREAL);
4079 101000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SB
4080 "sb r<RT>, <OFFSET>(r<BASE>)"
4094 do_store (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4098 111000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SC
4099 "sc r<RT>, <OFFSET>(r<BASE>)"
4111 do_sc (SD_, RT, OFFSET, BASE, instruction_0);
4115 111100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SCD
4116 "scd r<RT>, <OFFSET>(r<BASE>)"
4125 check_u64 (SD_, instruction_0);
4126 do_scd (SD_, RT, OFFSET, BASE);
4130 111111,5.BASE,5.RT,16.OFFSET:NORMAL:64::SD
4131 "sd r<RT>, <OFFSET>(r<BASE>)"
4140 check_u64 (SD_, instruction_0);
4141 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4145 1111,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDCz
4146 "sdc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
4158 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (ZZ, RT));
4162 101100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDL
4163 "sdl r<RT>, <OFFSET>(r<BASE>)"
4172 check_u64 (SD_, instruction_0);
4173 do_store_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4177 101101,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDR
4178 "sdr r<RT>, <OFFSET>(r<BASE>)"
4187 check_u64 (SD_, instruction_0);
4188 do_store_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4193 101001,5.BASE,5.RT,16.OFFSET:NORMAL:32::SH
4194 "sh r<RT>, <OFFSET>(r<BASE>)"
4208 do_store (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4212 :function:::void:do_sll:int rt, int rd, int shift
4214 unsigned32 temp = (GPR[rt] << shift);
4215 TRACE_ALU_INPUT2 (GPR[rt], shift);
4216 GPR[rd] = EXTEND32 (temp);
4217 TRACE_ALU_RESULT (GPR[rd]);
4220 000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLLa
4221 "nop":RD == 0 && RT == 0 && SHIFT == 0
4222 "sll r<RD>, r<RT>, <SHIFT>"
4232 /* Skip shift for NOP, so that there won't be lots of extraneous
4234 if (RD != 0 || RT != 0 || SHIFT != 0)
4235 do_sll (SD_, RT, RD, SHIFT);
4238 000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLLb
4239 "nop":RD == 0 && RT == 0 && SHIFT == 0
4240 "ssnop":RD == 0 && RT == 0 && SHIFT == 1
4241 "sll r<RD>, r<RT>, <SHIFT>"
4247 /* Skip shift for NOP and SSNOP, so that there won't be lots of
4248 extraneous trace output. */
4249 if (RD != 0 || RT != 0 || (SHIFT != 0 && SHIFT != 1))
4250 do_sll (SD_, RT, RD, SHIFT);
4254 :function:::void:do_sllv:int rs, int rt, int rd
4256 int s = MASKED (GPR[rs], 4, 0);
4257 unsigned32 temp = (GPR[rt] << s);
4258 TRACE_ALU_INPUT2 (GPR[rt], s);
4259 GPR[rd] = EXTEND32 (temp);
4260 TRACE_ALU_RESULT (GPR[rd]);
4263 000000,5.RS,5.RT,5.RD,00000,000100:SPECIAL:32::SLLV
4264 "sllv r<RD>, r<RT>, r<RS>"
4278 do_sllv (SD_, RS, RT, RD);
4282 :function:::void:do_slt:int rs, int rt, int rd
4284 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
4285 GPR[rd] = ((signed_word) GPR[rs] < (signed_word) GPR[rt]);
4286 TRACE_ALU_RESULT (GPR[rd]);
4289 000000,5.RS,5.RT,5.RD,00000,101010:SPECIAL:32::SLT
4290 "slt r<RD>, r<RS>, r<RT>"
4304 do_slt (SD_, RS, RT, RD);
4308 :function:::void:do_slti:int rs, int rt, unsigned16 immediate
4310 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
4311 GPR[rt] = ((signed_word) GPR[rs] < (signed_word) EXTEND16 (immediate));
4312 TRACE_ALU_RESULT (GPR[rt]);
4315 001010,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTI
4316 "slti r<RT>, r<RS>, <IMMEDIATE>"
4330 do_slti (SD_, RS, RT, IMMEDIATE);
4334 :function:::void:do_sltiu:int rs, int rt, unsigned16 immediate
4336 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
4337 GPR[rt] = ((unsigned_word) GPR[rs] < (unsigned_word) EXTEND16 (immediate));
4338 TRACE_ALU_RESULT (GPR[rt]);
4341 001011,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTIU
4342 "sltiu r<RT>, r<RS>, <IMMEDIATE>"
4356 do_sltiu (SD_, RS, RT, IMMEDIATE);
4361 :function:::void:do_sltu:int rs, int rt, int rd
4363 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
4364 GPR[rd] = ((unsigned_word) GPR[rs] < (unsigned_word) GPR[rt]);
4365 TRACE_ALU_RESULT (GPR[rd]);
4368 000000,5.RS,5.RT,5.RD,00000,101011:SPECIAL:32::SLTU
4369 "sltu r<RD>, r<RS>, r<RT>"
4383 do_sltu (SD_, RS, RT, RD);
4387 :function:::void:do_sra:int rt, int rd, int shift
4389 signed32 temp = (signed32) GPR[rt] >> shift;
4390 if (NotWordValue (GPR[rt]))
4392 TRACE_ALU_INPUT2 (GPR[rt], shift);
4393 GPR[rd] = EXTEND32 (temp);
4394 TRACE_ALU_RESULT (GPR[rd]);
4397 000000,00000,5.RT,5.RD,5.SHIFT,000011:SPECIAL:32::SRA
4398 "sra r<RD>, r<RT>, <SHIFT>"
4412 do_sra (SD_, RT, RD, SHIFT);
4417 :function:::void:do_srav:int rs, int rt, int rd
4419 int s = MASKED (GPR[rs], 4, 0);
4420 signed32 temp = (signed32) GPR[rt] >> s;
4421 if (NotWordValue (GPR[rt]))
4423 TRACE_ALU_INPUT2 (GPR[rt], s);
4424 GPR[rd] = EXTEND32 (temp);
4425 TRACE_ALU_RESULT (GPR[rd]);
4428 000000,5.RS,5.RT,5.RD,00000,000111:SPECIAL:32::SRAV
4429 "srav r<RD>, r<RT>, r<RS>"
4443 do_srav (SD_, RS, RT, RD);
4448 :function:::void:do_srl:int rt, int rd, int shift
4450 unsigned32 temp = (unsigned32) GPR[rt] >> shift;
4451 if (NotWordValue (GPR[rt]))
4453 TRACE_ALU_INPUT2 (GPR[rt], shift);
4454 GPR[rd] = EXTEND32 (temp);
4455 TRACE_ALU_RESULT (GPR[rd]);
4458 000000,00000,5.RT,5.RD,5.SHIFT,000010:SPECIAL:32::SRL
4459 "srl r<RD>, r<RT>, <SHIFT>"
4473 do_srl (SD_, RT, RD, SHIFT);
4477 :function:::void:do_srlv:int rs, int rt, int rd
4479 int s = MASKED (GPR[rs], 4, 0);
4480 unsigned32 temp = (unsigned32) GPR[rt] >> s;
4481 if (NotWordValue (GPR[rt]))
4483 TRACE_ALU_INPUT2 (GPR[rt], s);
4484 GPR[rd] = EXTEND32 (temp);
4485 TRACE_ALU_RESULT (GPR[rd]);
4488 000000,5.RS,5.RT,5.RD,00000,000110:SPECIAL:32::SRLV
4489 "srlv r<RD>, r<RT>, r<RS>"
4503 do_srlv (SD_, RS, RT, RD);
4507 000000,5.RS,5.RT,5.RD,00000,100010:SPECIAL:32::SUB
4508 "sub r<RD>, r<RS>, r<RT>"
4522 do_sub (SD_, RD, RS, RT);
4526 :function:::void:do_subu:int rs, int rt, int rd
4528 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
4530 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
4531 GPR[rd] = EXTEND32 (GPR[rs] - GPR[rt]);
4532 TRACE_ALU_RESULT (GPR[rd]);
4535 000000,5.RS,5.RT,5.RD,00000,100011:SPECIAL:32::SUBU
4536 "subu r<RD>, r<RS>, r<RT>"
4550 do_subu (SD_, RS, RT, RD);
4554 101011,5.BASE,5.RT,16.OFFSET:NORMAL:32::SW
4555 "sw r<RT>, <OFFSET>(r<BASE>)"
4569 do_sw (SD_, RT, OFFSET, BASE);
4573 1110,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWCz
4574 "swc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
4588 do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), COP_SW (ZZ, RT));
4592 101010,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWL
4593 "swl r<RT>, <OFFSET>(r<BASE>)"
4607 do_store_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4611 101110,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWR
4612 "swr r<RT>, <OFFSET>(r<BASE>)"
4626 do_store_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4630 000000,000000000000000,5.STYPE,001111:SPECIAL:32::SYNC
4645 SyncOperation (STYPE);
4649 000000,20.CODE,001100:SPECIAL:32::SYSCALL
4650 "syscall %#lx<CODE>"
4664 SignalException (SystemCall, instruction_0);
4668 000000,5.RS,5.RT,10.CODE,110100:SPECIAL:32::TEQ
4681 do_teq (SD_, RS, RT, instruction_0);
4685 000001,5.RS,01100,16.IMMEDIATE:REGIMM:32::TEQI
4686 "teqi r<RS>, <IMMEDIATE>"
4698 do_teqi (SD_, RS, IMMEDIATE, instruction_0);
4702 000000,5.RS,5.RT,10.CODE,110000:SPECIAL:32::TGE
4715 do_tge (SD_, RS, RT, instruction_0);
4719 000001,5.RS,01000,16.IMMEDIATE:REGIMM:32::TGEI
4720 "tgei r<RS>, <IMMEDIATE>"
4732 do_tgei (SD_, RS, IMMEDIATE, instruction_0);
4736 000001,5.RS,01001,16.IMMEDIATE:REGIMM:32::TGEIU
4737 "tgeiu r<RS>, <IMMEDIATE>"
4749 do_tgeiu (SD_, RS, IMMEDIATE, instruction_0);
4753 000000,5.RS,5.RT,10.CODE,110001:SPECIAL:32::TGEU
4766 do_tgeu (SD_, RS, RT, instruction_0);
4770 000000,5.RS,5.RT,10.CODE,110010:SPECIAL:32::TLT
4783 do_tlt (SD_, RS, RT, instruction_0);
4787 000001,5.RS,01010,16.IMMEDIATE:REGIMM:32::TLTI
4788 "tlti r<RS>, <IMMEDIATE>"
4800 do_tlti (SD_, RS, IMMEDIATE, instruction_0);
4804 000001,5.RS,01011,16.IMMEDIATE:REGIMM:32::TLTIU
4805 "tltiu r<RS>, <IMMEDIATE>"
4817 do_tltiu (SD_, RS, IMMEDIATE, instruction_0);
4821 000000,5.RS,5.RT,10.CODE,110011:SPECIAL:32::TLTU
4834 do_tltu (SD_, RS, RT, instruction_0);
4838 000000,5.RS,5.RT,10.CODE,110110:SPECIAL:32::TNE
4851 do_tne (SD_, RS, RT, instruction_0);
4855 000001,5.RS,01110,16.IMMEDIATE:REGIMM:32::TNEI
4856 "tnei r<RS>, <IMMEDIATE>"
4868 do_tnei (SD_, RS, IMMEDIATE, instruction_0);
4872 :function:::void:do_xor:int rs, int rt, int rd
4874 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
4875 GPR[rd] = GPR[rs] ^ GPR[rt];
4876 TRACE_ALU_RESULT (GPR[rd]);
4879 000000,5.RS,5.RT,5.RD,00000,100110:SPECIAL:32::XOR
4880 "xor r<RD>, r<RS>, r<RT>"
4894 do_xor (SD_, RS, RT, RD);
4898 :function:::void:do_xori:int rs, int rt, unsigned16 immediate
4900 TRACE_ALU_INPUT2 (GPR[rs], immediate);
4901 GPR[rt] = GPR[rs] ^ immediate;
4902 TRACE_ALU_RESULT (GPR[rt]);
4905 001110,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::XORI
4906 "xori r<RT>, r<RS>, %#lx<IMMEDIATE>"
4920 do_xori (SD_, RS, RT, IMMEDIATE);
4925 // MIPS Architecture:
4927 // FPU Instruction Set (COP1 & COP1X)
4935 case fmt_single: return "s";
4936 case fmt_double: return "d";
4937 case fmt_word: return "w";
4938 case fmt_long: return "l";
4939 case fmt_ps: return "ps";
4940 default: return "?";
4960 :%s::::COND:int cond
4964 case 00: return "f";
4965 case 01: return "un";
4966 case 02: return "eq";
4967 case 03: return "ueq";
4968 case 04: return "olt";
4969 case 05: return "ult";
4970 case 06: return "ole";
4971 case 07: return "ule";
4972 case 010: return "sf";
4973 case 011: return "ngle";
4974 case 012: return "seq";
4975 case 013: return "ngl";
4976 case 014: return "lt";
4977 case 015: return "nge";
4978 case 016: return "le";
4979 case 017: return "ngt";
4980 default: return "?";
4987 // Check that the given FPU format is usable, and signal a
4988 // ReservedInstruction exception if not.
4991 // check_fmt_p checks that the format is single, double, or paired single.
4992 :function:::void:check_fmt_p:int fmt, instruction_word insn
5002 /* None of these ISAs support Paired Single, so just fall back to
5003 the single/double check. */
5004 if ((fmt != fmt_single) && (fmt != fmt_double))
5005 SignalException (ReservedInstruction, insn);
5008 :function:::void:check_fmt_p:int fmt, instruction_word insn
5012 if ((fmt != fmt_single) && (fmt != fmt_double) && (fmt != fmt_ps))
5013 SignalException (ReservedInstruction, insn);
5016 :function:::void:check_fmt_p:int fmt, instruction_word insn
5022 if ((fmt != fmt_single) && (fmt != fmt_double)
5023 && (fmt != fmt_ps || (UserMode && (SR & (status_UX|status_PX)) == 0)))
5024 SignalException (ReservedInstruction, insn);
5030 // Check that the FPU is currently usable, and signal a CoProcessorUnusable
5031 // exception if not.
5034 :function:::void:check_fpu:
5050 if (! COP_Usable (1))
5051 SignalExceptionCoProcessorUnusable (1);
5057 // Load a double word FP value using 2 32-bit memory cycles a la MIPS II
5058 // or MIPS32. do_load cannot be used instead because it returns an
5059 // unsigned_word, which is limited to the size of the machine's registers.
5062 :function:::unsigned64:do_load_double:address_word base, address_word offset
5068 int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
5074 paddr = vaddr = loadstore_ea (SD_, base, offset);
5075 if ((vaddr & AccessLength_DOUBLEWORD) != 0)
5077 SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map,
5078 AccessLength_DOUBLEWORD + 1, vaddr, read_transfer,
5079 sim_core_unaligned_signal);
5081 LoadMemory (&memval, NULL, AccessLength_WORD, paddr, vaddr, isDATA, isREAL);
5082 v = (unsigned64)memval;
5083 LoadMemory (&memval, NULL, AccessLength_WORD, paddr + 4, vaddr + 4, isDATA,
5085 return (bigendian ? ((v << 32) | memval) : (v | (memval << 32)));
5091 // Store a double word FP value using 2 32-bit memory cycles a la MIPS II
5092 // or MIPS32. do_load cannot be used instead because it returns an
5093 // unsigned_word, which is limited to the size of the machine's registers.
5096 :function:::void:do_store_double:address_word base, address_word offset, unsigned64 v
5102 int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
5107 paddr = vaddr = loadstore_ea (SD_, base, offset);
5108 if ((vaddr & AccessLength_DOUBLEWORD) != 0)
5110 SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map,
5111 AccessLength_DOUBLEWORD + 1, vaddr, write_transfer,
5112 sim_core_unaligned_signal);
5114 memval = (bigendian ? (v >> 32) : (v & 0xFFFFFFFF));
5115 StoreMemory (AccessLength_WORD, memval, 0, paddr, vaddr, isREAL);
5116 memval = (bigendian ? (v & 0xFFFFFFFF) : (v >> 32));
5117 StoreMemory (AccessLength_WORD, memval, 0, paddr + 4, vaddr + 4, isREAL);
5121 010001,10,3.FMT!2!3!4!5!7,00000,5.FS,5.FD,000101:COP1:32,f::ABS.fmt
5122 "abs.%s<FMT> f<FD>, f<FS>"
5136 do_abs_fmt (SD_, FMT, FD, FS, instruction_0);
5141 010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,5.FD,000000:COP1:32,f::ADD.fmt
5142 "add.%s<FMT> f<FD>, f<FS>, f<FT>"
5156 do_add_fmt (SD_, FMT, FD, FS, FT, instruction_0);
5160 010011,5.RS,5.FT,5.FS,5.FD,011,110:COP1X:32,f::ALNV.PS
5161 "alnv.ps f<FD>, f<FS>, f<FT>, r<RS>"
5167 do_alnv_ps (SD_, FD, FS, FT, RS, instruction_0);
5176 010001,01000,3.0,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1a
5177 "bc1%s<TF>%s<ND> <OFFSET>"
5183 TRACE_BRANCH_INPUT (PREVCOC1());
5184 if (PREVCOC1() == TF)
5186 address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
5187 TRACE_BRANCH_RESULT (dest);
5192 TRACE_BRANCH_RESULT (0);
5193 NULLIFY_NEXT_INSTRUCTION ();
5197 TRACE_BRANCH_RESULT (NIA);
5201 010001,01000,3.CC,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1b
5202 "bc1%s<TF>%s<ND> <OFFSET>":CC == 0
5203 "bc1%s<TF>%s<ND> <CC>, <OFFSET>"
5215 if (GETFCC(CC) == TF)
5217 address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
5222 NULLIFY_NEXT_INSTRUCTION ();
5227 010001,10,3.FMT!2!3!4!5!6!7,5.FT,5.FS,3.0,00,11,4.COND:COP1:32,f::C.cond.fmta
5228 "c.%s<COND>.%s<FMT> f<FS>, f<FT>"
5235 Compare (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt, COND, 0);
5236 TRACE_ALU_RESULT (ValueFCR (31));
5239 010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,3.CC,00,11,4.COND:COP1:32,f::C.cond.fmtb
5240 "c.%s<COND>.%s<FMT> f<FS>, f<FT>":CC == 0
5241 "c.%s<COND>.%s<FMT> <CC>, f<FS>, f<FT>"
5252 do_c_cond_fmt (SD_, COND, FMT, CC, FS, FT, instruction_0);
5256 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001010:COP1:32,f::CEIL.L.fmt
5257 "ceil.l.%s<FMT> f<FD>, f<FS>"
5268 do_ceil_fmt (SD_, fmt_long, FMT, FD, FS, instruction_0);
5272 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001110:COP1:32,f::CEIL.W
5273 "ceil.w.%s<FMT> f<FD>, f<FS>"
5286 do_ceil_fmt (SD_, fmt_word, FMT, FD, FS, instruction_0);
5290 010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1a
5298 PENDING_FILL (RT, EXTEND32 (FCR0));
5300 PENDING_FILL (RT, EXTEND32 (FCR31));
5304 010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1b
5312 if (FS == 0 || FS == 31)
5314 unsigned_word fcr = ValueFCR (FS);
5315 TRACE_ALU_INPUT1 (fcr);
5319 TRACE_ALU_RESULT (GPR[RT]);
5322 010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1c
5330 do_cfc1 (SD_, RT, FS);
5333 010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1a
5341 PENDING_FILL (FCRCS_REGNUM, VL4_8 (GPR[RT]));
5345 010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1b
5353 TRACE_ALU_INPUT1 (GPR[RT]);
5355 StoreFCR (FS, GPR[RT]);
5359 010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1c
5367 do_ctc1 (SD_, RT, FS);
5372 // FIXME: Does not correctly differentiate between mips*
5374 010001,10,3.FMT!1!2!3!6!7,00000,5.FS,5.FD,100001:COP1:32,f::CVT.D.fmt
5375 "cvt.d.%s<FMT> f<FD>, f<FS>"
5389 do_cvt_d_fmt (SD_, FMT, FD, FS, instruction_0);
5393 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,100101:COP1:32,f::CVT.L.fmt
5394 "cvt.l.%s<FMT> f<FD>, f<FS>"
5405 do_cvt_l_fmt (SD_, FMT, FD, FS, instruction_0);
5409 010001,10,000,5.FT,5.FS,5.FD,100110:COP1:32,f::CVT.PS.S
5410 "cvt.ps.s f<FD>, f<FS>, f<FT>"
5416 do_cvt_ps_s (SD_, FD, FS, FT, instruction_0);
5421 // FIXME: Does not correctly differentiate between mips*
5423 010001,10,3.FMT!0!2!3!6!7,00000,5.FS,5.FD,100000:COP1:32,f::CVT.S.fmt
5424 "cvt.s.%s<FMT> f<FD>, f<FS>"
5438 do_cvt_s_fmt (SD_, FMT, FD, FS, instruction_0);
5442 010001,10,110,00000,5.FS,5.FD,101000:COP1:32,f::CVT.S.PL
5443 "cvt.s.pl f<FD>, f<FS>"
5449 do_cvt_s_pl (SD_, FD, FS, instruction_0);
5453 010001,10,110,00000,5.FS,5.FD,100000:COP1:32,f::CVT.S.PU
5454 "cvt.s.pu f<FD>, f<FS>"
5460 do_cvt_s_pu (SD_, FD, FS, instruction_0);
5464 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,100100:COP1:32,f::CVT.W.fmt
5465 "cvt.w.%s<FMT> f<FD>, f<FS>"
5479 do_cvt_w_fmt (SD_, FMT, FD, FS, instruction_0);
5483 010001,10,3.FMT!2!3!4!5!6!7,5.FT,5.FS,5.FD,000011:COP1:32,f::DIV.fmt
5484 "div.%s<FMT> f<FD>, f<FS>, f<FT>"
5498 do_div_fmt (SD_, FMT, FD, FS, FT, instruction_0);
5502 010001,00001,5.RT,5.FS,00000000000:COP1:64,f::DMFC1a
5503 "dmfc1 r<RT>, f<FS>"
5508 check_u64 (SD_, instruction_0);
5509 if (SizeFGR () == 64)
5511 else if ((FS & 0x1) == 0)
5512 v = SET64HI (FGR[FS+1]) | FGR[FS];
5514 v = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
5515 PENDING_FILL (RT, v);
5516 TRACE_ALU_RESULT (v);
5519 010001,00001,5.RT,5.FS,00000000000:COP1:64,f::DMFC1b
5520 "dmfc1 r<RT>, f<FS>"
5530 check_u64 (SD_, instruction_0);
5531 do_dmfc1b (SD_, RT, FS);
5535 010001,00101,5.RT,5.FS,00000000000:COP1:64,f::DMTC1a
5536 "dmtc1 r<RT>, f<FS>"
5541 check_u64 (SD_, instruction_0);
5542 if (SizeFGR () == 64)
5543 PENDING_FILL ((FS + FGR_BASE), GPR[RT]);
5544 else if ((FS & 0x1) == 0)
5546 PENDING_FILL (((FS + 1) + FGR_BASE), VH4_8 (GPR[RT]));
5547 PENDING_FILL ((FS + FGR_BASE), VL4_8 (GPR[RT]));
5551 TRACE_FP_RESULT (GPR[RT]);
5554 010001,00101,5.RT,5.FS,00000000000:COP1:64,f::DMTC1b
5555 "dmtc1 r<RT>, f<FS>"
5565 check_u64 (SD_, instruction_0);
5566 do_dmtc1b (SD_, RT, FS);
5570 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001011:COP1:32,f::FLOOR.L.fmt
5571 "floor.l.%s<FMT> f<FD>, f<FS>"
5582 do_floor_fmt (SD_, fmt_long, FMT, FD, FS);
5586 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001111:COP1:32,f::FLOOR.W.fmt
5587 "floor.w.%s<FMT> f<FD>, f<FS>"
5600 do_floor_fmt (SD_, fmt_word, FMT, FD, FS);
5604 110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1a
5605 "ldc1 f<FT>, <OFFSET>(r<BASE>)"
5611 COP_LD (1, FT, do_load_double (SD_, GPR[BASE], EXTEND16 (OFFSET)));
5615 110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1b
5616 "ldc1 f<FT>, <OFFSET>(r<BASE>)"
5627 COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
5631 010011,5.BASE,5.INDEX,5.0,5.FD,000001:COP1X:32,f::LDXC1
5632 "ldxc1 f<FD>, r<INDEX>(r<BASE>)"
5636 COP_LD (1, FD, do_load_double (SD_, GPR[BASE], GPR[INDEX]));
5640 010011,5.BASE,5.INDEX,5.0,5.FD,000001:COP1X:64,f::LDXC1
5641 "ldxc1 f<FD>, r<INDEX>(r<BASE>)"
5649 check_u64 (SD_, instruction_0);
5650 COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX]));
5654 010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:32,f::LUXC1
5655 "luxc1 f<FD>, r<INDEX>(r<BASE>)"
5658 do_luxc1_32 (SD_, FD, INDEX, BASE);
5662 010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:64,f::LUXC1
5663 "luxc1 f<FD>, r<INDEX>(r<BASE>)"
5669 check_u64 (SD_, instruction_0);
5670 do_luxc1_64 (SD_, FD, INDEX, BASE);
5674 110001,5.BASE,5.FT,16.OFFSET:COP1:32,f::LWC1
5675 "lwc1 f<FT>, <OFFSET>(r<BASE>)"
5689 do_lwc1 (SD_, FT, OFFSET, BASE);
5693 010011,5.BASE,5.INDEX,5.0,5.FD,000000:COP1X:32,f::LWXC1
5694 "lwxc1 f<FD>, r<INDEX>(r<BASE>)"
5702 do_lwxc1 (SD_, FD, INDEX, BASE, instruction_0);
5707 010011,5.FR,5.FT,5.FS,5.FD,100,3.FMT!2!3!4!5!7:COP1X:32,f::MADD.fmt
5708 "madd.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
5716 do_madd_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
5720 010001,00000,5.RT,5.FS,00000000000:COP1:32,f::MFC1a
5728 v = EXTEND32 (FGR[FS]);
5729 PENDING_FILL (RT, v);
5730 TRACE_ALU_RESULT (v);
5733 010001,00000,5.RT,5.FS,00000000000:COP1:32,f::MFC1b
5745 do_mfc1b (SD_, RT, FS);
5749 010001,10,3.FMT!2!3!4!5!7,00000,5.FS,5.FD,000110:COP1:32,f::MOV.fmt
5750 "mov.%s<FMT> f<FD>, f<FS>"
5764 do_mov_fmt (SD_, FMT, FD, FS, instruction_0);
5770 000000,5.RS,3.CC,0,1.TF,5.RD,00000,000001:SPECIAL:32,f::MOVtf
5771 "mov%s<TF> r<RD>, r<RS>, <CC>"
5780 do_movtf (SD_, TF, RD, RS, CC);
5786 010001,10,3.FMT!2!3!4!5!7,3.CC,0,1.TF,5.FS,5.FD,010001:COP1:32,f::MOVtf.fmt
5787 "mov%s<TF>.%s<FMT> f<FD>, f<FS>, <CC>"
5796 do_movtf_fmt (SD_, TF, FMT, FD, FS, CC);
5800 010001,10,3.FMT!2!3!4!5!7,5.RT,5.FS,5.FD,010011:COP1:32,f::MOVN.fmt
5801 "movn.%s<FMT> f<FD>, f<FS>, r<RT>"
5810 do_movn_fmt (SD_, FMT, FD, FS, RT);
5817 // MOVT.fmt see MOVtf.fmt
5821 010001,10,3.FMT!2!3!4!5!7,5.RT,5.FS,5.FD,010010:COP1:32,f::MOVZ.fmt
5822 "movz.%s<FMT> f<FD>, f<FS>, r<RT>"
5831 do_movz_fmt (SD_, FMT, FD, FS, RT);
5835 010011,5.FR,5.FT,5.FS,5.FD,101,3.FMT!2!3!4!5!7:COP1X:32,f::MSUB.fmt
5836 "msub.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
5844 do_msub_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
5848 010001,00100,5.RT,5.FS,00000000000:COP1:32,f::MTC1a
5855 if (SizeFGR () == 64)
5856 PENDING_FILL ((FS + FGR_BASE), (SET64HI (0xDEADC0DE) | VL4_8 (GPR[RT])));
5858 PENDING_FILL ((FS + FGR_BASE), VL4_8 (GPR[RT]));
5859 TRACE_FP_RESULT (GPR[RT]);
5862 010001,00100,5.RT,5.FS,00000000000:COP1:32,f::MTC1b
5874 do_mtc1b (SD_, RT, FS);
5878 010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,5.FD,000010:COP1:32,f::MUL.fmt
5879 "mul.%s<FMT> f<FD>, f<FS>, f<FT>"
5893 do_mul_fmt (SD_, FMT, FD, FS, FT, instruction_0);
5897 010001,10,3.FMT!2!3!4!5!7,00000,5.FS,5.FD,000111:COP1:32,f::NEG.fmt
5898 "neg.%s<FMT> f<FD>, f<FS>"
5912 do_neg_fmt (SD_, FMT, FD, FS, instruction_0);
5916 010011,5.FR,5.FT,5.FS,5.FD,110,3.FMT!2!3!4!5!7:COP1X:32,f::NMADD.fmt
5917 "nmadd.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
5925 do_nmadd_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
5929 010011,5.FR,5.FT,5.FS,5.FD,111,3.FMT!2!3!4!5!7:COP1X:32,f::NMSUB.fmt
5930 "nmsub.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
5938 do_nmsub_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
5942 010001,10,110,5.FT,5.FS,5.FD,101100:COP1:32,f::PLL.PS
5943 "pll.ps f<FD>, f<FS>, f<FT>"
5949 do_pll_ps (SD_, FD, FS, FT, instruction_0);
5953 010001,10,110,5.FT,5.FS,5.FD,101101:COP1:32,f::PLU.PS
5954 "plu.ps f<FD>, f<FS>, f<FT>"
5960 do_plu_ps (SD_, FD, FS, FT, instruction_0);
5964 010011,5.BASE,5.INDEX,5.HINT,00000,001111:COP1X:32::PREFX
5965 "prefx <HINT>, r<INDEX>(r<BASE>)"
5973 do_prefx (SD_, HINT, INDEX, BASE);
5977 010001,10,110,5.FT,5.FS,5.FD,101110:COP1:32,f::PUL.PS
5978 "pul.ps f<FD>, f<FS>, f<FT>"
5984 do_pul_ps (SD_, FD, FS, FT, instruction_0);
5988 010001,10,110,5.FT,5.FS,5.FD,101111:COP1:32,f::PUU.PS
5989 "puu.ps f<FD>, f<FS>, f<FT>"
5995 do_puu_ps (SD_, FD, FS, FT, instruction_0);
5999 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,010101:COP1:32,f::RECIP.fmt
6000 "recip.%s<FMT> f<FD>, f<FS>"
6008 do_recip_fmt (SD_, FMT, FD, FS);
6012 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001000:COP1:32,f::ROUND.L.fmt
6013 "round.l.%s<FMT> f<FD>, f<FS>"
6024 do_round_fmt (SD_, fmt_long, FMT, FD, FS);
6028 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001100:COP1:32,f::ROUND.W.fmt
6029 "round.w.%s<FMT> f<FD>, f<FS>"
6042 do_round_fmt (SD_, fmt_word, FMT, FD, FS);
6046 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,010110:COP1:32,f::RSQRT.fmt
6047 "rsqrt.%s<FMT> f<FD>, f<FS>"
6055 do_rsqrt_fmt (SD_, FMT, FD, FS);
6059 111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1a
6060 "sdc1 f<FT>, <OFFSET>(r<BASE>)"
6065 do_sdc1 (SD_, FT, OFFSET, BASE);
6069 111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1b
6070 "sdc1 f<FT>, <OFFSET>(r<BASE>)"
6081 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT));
6085 010011,5.BASE,5.INDEX,5.FS,00000001001:COP1X:32,f::SDXC1
6086 "sdxc1 f<FS>, r<INDEX>(r<BASE>)"
6090 do_store_double (SD_, GPR[BASE], GPR[INDEX], COP_SD (1, FS));
6094 010011,5.BASE,5.INDEX,5.FS,00000001001:COP1X:64,f::SDXC1
6095 "sdxc1 f<FS>, r<INDEX>(r<BASE>)"
6103 check_u64 (SD_, instruction_0);
6104 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX], COP_SD (1, FS));
6108 010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:32,f::SUXC1
6109 "suxc1 f<FS>, r<INDEX>(r<BASE>)"
6112 do_suxc1_32 (SD_, FS, INDEX, BASE);
6116 010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:64,f::SUXC1
6117 "suxc1 f<FS>, r<INDEX>(r<BASE>)"
6123 check_u64 (SD_, instruction_0);
6124 do_suxc1_64 (SD_, FS, INDEX, BASE);
6128 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,000100:COP1:32,f::SQRT.fmt
6129 "sqrt.%s<FMT> f<FD>, f<FS>"
6142 do_sqrt_fmt (SD_, FMT, FD, FS);
6146 010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,5.FD,000001:COP1:32,f::SUB.fmt
6147 "sub.%s<FMT> f<FD>, f<FS>, f<FT>"
6161 do_sub_fmt (SD_, FMT, FD, FS, FT, instruction_0);
6166 111001,5.BASE,5.FT,16.OFFSET:COP1:32,f::SWC1
6167 "swc1 f<FT>, <OFFSET>(r<BASE>)"
6181 do_swc1 (SD_, FT, OFFSET, BASE, instruction_0);
6185 010011,5.BASE,5.INDEX,5.FS,00000,001000:COP1X:32,f::SWXC1
6186 "swxc1 f<FS>, r<INDEX>(r<BASE>)"
6194 do_swxc1 (SD_, FS, INDEX, BASE, instruction_0);
6198 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001001:COP1:32,f::TRUNC.L.fmt
6199 "trunc.l.%s<FMT> f<FD>, f<FS>"
6210 do_trunc_fmt (SD_, fmt_long, FMT, FD, FS);
6214 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001101:COP1:32,f::TRUNC.W
6215 "trunc.w.%s<FMT> f<FD>, f<FS>"
6228 do_trunc_fmt (SD_, fmt_word, FMT, FD, FS);
6233 // MIPS Architecture:
6235 // System Control Instruction Set (COP0)
6239 010000,01000,00000,16.OFFSET:COP0:32::BC0F
6253 010000,01000,00000,16.OFFSET:COP0:32::BC0F
6255 // stub needed for eCos as tx39 hardware bug workaround
6262 010000,01000,00010,16.OFFSET:COP0:32::BC0FL
6277 010000,01000,00001,16.OFFSET:COP0:32::BC0T
6291 010000,01000,00011,16.OFFSET:COP0:32::BC0TL
6306 101111,5.BASE,5.OP,16.OFFSET:NORMAL:32::CACHE
6307 "cache <OP>, <OFFSET>(r<BASE>)"
6319 address_word base = GPR[BASE];
6320 address_word offset = EXTEND16 (OFFSET);
6322 address_word vaddr = loadstore_ea (SD_, base, offset);
6323 address_word paddr = vaddr;
6324 CacheOp(OP, vaddr, paddr, instruction_0);
6329 010000,00001,5.RT,5.RD,00000000,3.SEL:COP0:64::DMFC0
6330 "dmfc0 r<RT>, r<RD>"
6337 check_u64 (SD_, instruction_0);
6338 DecodeCoproc (instruction_0, 0, cp0_dmfc0, RT, RD, SEL);
6342 010000,00101,5.RT,5.RD,00000000,3.SEL:COP0:64::DMTC0
6343 "dmtc0 r<RT>, r<RD>"
6350 check_u64 (SD_, instruction_0);
6351 DecodeCoproc (instruction_0, 0, cp0_dmtc0, RT, RD, SEL);
6355 010000,1,0000000000000000000,011000:COP0:32::ERET
6367 if (SR & status_ERL)
6369 /* Oops, not yet available */
6370 sim_io_printf (SD, "Warning: ERET when SR[ERL] set not supported");
6382 010000,00000,5.RT,5.RD,00000000,3.SEL:COP0:32::MFC0
6383 "mfc0 r<RT>, r<RD> # <SEL>"
6397 TRACE_ALU_INPUT0 ();
6398 DecodeCoproc (instruction_0, 0, cp0_mfc0, RT, RD, SEL);
6399 TRACE_ALU_RESULT (GPR[RT]);
6402 010000,00100,5.RT,5.RD,00000000,3.SEL:COP0:32::MTC0
6403 "mtc0 r<RT>, r<RD> # <SEL>"
6417 DecodeCoproc (instruction_0, 0, cp0_mtc0, RT, RD, SEL);
6421 010000,1,0000000000000000000,010000:COP0:32::RFE
6432 DecodeCoproc (instruction_0, 0, cp0_rfe, 0, 0, 0x10);
6436 0100,ZZ!0!1!3,5.COP_FUN0!8,5.COP_FUN1,16.COP_FUN2:NORMAL:32::COPz
6437 "cop<ZZ> <COP_FUN0><COP_FUN1><COP_FUN2>"
6450 DecodeCoproc (instruction_0, 2, 0, 0, 0, 0);
6455 010000,1,0000000000000000000,001000:COP0:32::TLBP
6470 010000,1,0000000000000000000,000001:COP0:32::TLBR
6485 010000,1,0000000000000000000,000010:COP0:32::TLBWI
6500 010000,1,0000000000000000000,000110:COP0:32::TLBWR
6515 :include:::mips3264r2.igen
6517 :include:::m16e.igen
6518 :include:::mdmx.igen
6519 :include:::mips3d.igen
6524 :include:::dsp2.igen
6525 :include:::smartmips.igen
6526 :include:::micromips.igen
6527 :include:::micromipsdsp.igen