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
501 // The check should be similar to mips64 for any with PX/UX bit equivalents.
504 :function:::void:check_u64:instruction_word insn
513 #if 0 /* XXX FIXME: enable this only after some additional testing. */
514 if (UserMode && (SR & (status_UX|status_PX)) == 0)
515 SignalException (ReservedInstruction, insn);
522 // MIPS Architecture:
524 // CPU Instruction Set (mipsI - mipsV, mips32/r2, mips64/r2)
528 :function:::void:do_add:int rs, int rt, int rd
530 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
532 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
534 ALU32_BEGIN (GPR[rs]);
536 ALU32_END (GPR[rd]); /* This checks for overflow. */
538 TRACE_ALU_RESULT (GPR[rd]);
541 :function:::void:do_addi:int rs, int rt, unsigned16 immediate
543 if (NotWordValue (GPR[rs]))
545 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
547 ALU32_BEGIN (GPR[rs]);
548 ALU32_ADD (EXTEND16 (immediate));
549 ALU32_END (GPR[rt]); /* This checks for overflow. */
551 TRACE_ALU_RESULT (GPR[rt]);
554 :function:::void:do_andi:int rs, int rt, unsigned int immediate
556 TRACE_ALU_INPUT2 (GPR[rs], immediate);
557 GPR[rt] = GPR[rs] & immediate;
558 TRACE_ALU_RESULT (GPR[rt]);
561 :function:::void:do_dadd:int rd, int rs, int rt
563 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
565 ALU64_BEGIN (GPR[rs]);
567 ALU64_END (GPR[rd]); /* This checks for overflow. */
569 TRACE_ALU_RESULT (GPR[rd]);
572 :function:::void:do_daddi:int rt, int rs, int immediate
574 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
576 ALU64_BEGIN (GPR[rs]);
577 ALU64_ADD (EXTEND16 (immediate));
578 ALU64_END (GPR[rt]); /* This checks for overflow. */
580 TRACE_ALU_RESULT (GPR[rt]);
583 :function:::void:do_dsll32:int rd, int rt, int shift
586 TRACE_ALU_INPUT2 (GPR[rt], s);
587 GPR[rd] = GPR[rt] << s;
588 TRACE_ALU_RESULT (GPR[rd]);
591 :function:::void:do_dsra32:int rd, int rt, int shift
594 TRACE_ALU_INPUT2 (GPR[rt], s);
595 GPR[rd] = ((signed64) GPR[rt]) >> s;
596 TRACE_ALU_RESULT (GPR[rd]);
599 :function:::void:do_dsrl32:int rd, int rt, int shift
602 TRACE_ALU_INPUT2 (GPR[rt], s);
603 GPR[rd] = (unsigned64) GPR[rt] >> s;
604 TRACE_ALU_RESULT (GPR[rd]);
607 :function:::void:do_dsub:int rd, int rs, int rt
609 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
611 ALU64_BEGIN (GPR[rs]);
613 ALU64_END (GPR[rd]); /* This checks for overflow. */
615 TRACE_ALU_RESULT (GPR[rd]);
618 :function:::void:do_break:address_word instruction_0
620 /* Check for some break instruction which are reserved for use by the
622 unsigned int break_code = instruction_0 & HALT_INSTRUCTION_MASK;
623 if (break_code == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
624 break_code == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
626 sim_engine_halt (SD, CPU, NULL, cia,
627 sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
629 else if (break_code == (BREAKPOINT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
630 break_code == (BREAKPOINT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
632 if (STATE & simDELAYSLOT)
633 PC = cia - 4; /* reference the branch instruction */
636 SignalException (BreakPoint, instruction_0);
641 /* If we get this far, we're not an instruction reserved by the sim. Raise
643 SignalException (BreakPoint, instruction_0);
647 :function:::void:do_break16:address_word instruction_0
649 if (STATE & simDELAYSLOT)
650 PC = cia - 2; /* reference the branch instruction */
653 SignalException (BreakPoint, instruction_0);
656 :function:::void:do_clo:int rd, int rs
658 unsigned32 temp = GPR[rs];
660 if (NotWordValue (GPR[rs]))
662 TRACE_ALU_INPUT1 (GPR[rs]);
663 for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
665 if ((temp & mask) == 0)
669 GPR[rd] = EXTEND32 (i);
670 TRACE_ALU_RESULT (GPR[rd]);
673 :function:::void:do_clz:int rd, int rs
675 unsigned32 temp = GPR[rs];
677 if (NotWordValue (GPR[rs]))
679 TRACE_ALU_INPUT1 (GPR[rs]);
680 for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
682 if ((temp & mask) != 0)
686 GPR[rd] = EXTEND32 (i);
687 TRACE_ALU_RESULT (GPR[rd]);
690 :function:::void:do_dclo:int rd, int rs
692 unsigned64 temp = GPR[rs];
695 TRACE_ALU_INPUT1 (GPR[rs]);
696 for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
698 if ((temp & mask) == 0)
702 GPR[rd] = EXTEND32 (i);
703 TRACE_ALU_RESULT (GPR[rd]);
706 :function:::void:do_dclz:int rd, int rs
708 unsigned64 temp = GPR[rs];
711 TRACE_ALU_INPUT1 (GPR[rs]);
712 for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
714 if ((temp & mask) != 0)
718 GPR[rd] = EXTEND32 (i);
719 TRACE_ALU_RESULT (GPR[rd]);
722 :function:::void:do_lb:int rt, int offset, int base
724 GPR[rt] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[base],
728 :function:::void:do_lh:int rt, int offset, int base
730 GPR[rt] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[base],
734 :function:::void:do_lwr:int rt, int offset, int base
736 GPR[rt] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, GPR[base],
737 EXTEND16 (offset), GPR[rt]));
740 :function:::void:do_lwl:int rt, int offset, int base
742 GPR[rt] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, GPR[base],
743 EXTEND16 (offset), GPR[rt]));
746 :function:::void:do_lwc:int num, int rt, int offset, int base
748 COP_LW (num, rt, do_load (SD_, AccessLength_WORD, GPR[base],
752 :function:::void:do_lw:int rt, int offset, int base
754 GPR[rt] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[base],
758 :function:::void:do_lwu:int rt, int offset, int base, address_word instruction_0
760 check_u64 (SD_, instruction_0);
761 GPR[rt] = do_load (SD_, AccessLength_WORD, GPR[base], EXTEND16 (offset));
764 :function:::void:do_lhu:int rt, int offset, int base
766 GPR[rt] = do_load (SD_, AccessLength_HALFWORD, GPR[base], EXTEND16 (offset));
769 :function:::void:do_ldc:int num, int rt, int offset, int base
771 COP_LD (num, rt, do_load (SD_, AccessLength_DOUBLEWORD, GPR[base],
775 :function:::void:do_lbu:int rt, int offset, int base
777 GPR[rt] = do_load (SD_, AccessLength_BYTE, GPR[base], EXTEND16 (offset));
780 :function:::void:do_ll:int rt, int insn_offset, int basereg
782 address_word base = GPR[basereg];
783 address_word offset = EXTEND16 (insn_offset);
785 address_word vaddr = loadstore_ea (SD_, base, offset);
786 address_word paddr = vaddr;
787 if ((vaddr & 3) != 0)
789 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer,
790 sim_core_unaligned_signal);
794 unsigned64 memval = 0;
795 unsigned64 memval1 = 0;
796 unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
797 unsigned int shift = 2;
798 unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
799 unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
801 paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
802 LoadMemory (&memval, &memval1, AccessLength_WORD, paddr, vaddr,
804 byte = ((vaddr & mask) ^ (bigend << shift));
805 GPR[rt] = EXTEND32 (memval >> (8 * byte));
811 :function:::void:do_lld:int rt, int roffset, int rbase
813 address_word base = GPR[rbase];
814 address_word offset = EXTEND16 (roffset);
816 address_word vaddr = loadstore_ea (SD_, base, offset);
817 address_word paddr = vaddr;
819 if ((vaddr & 7) != 0)
821 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer,
822 sim_core_unaligned_signal);
826 unsigned64 memval = 0;
827 unsigned64 memval1 = 0;
828 LoadMemory (&memval, &memval1, AccessLength_DOUBLEWORD, paddr, vaddr,
836 :function:::void:do_lui:int rt, int immediate
838 TRACE_ALU_INPUT1 (immediate);
839 GPR[rt] = EXTEND32 (immediate << 16);
840 TRACE_ALU_RESULT (GPR[rt]);
843 :function:::void:do_madd:int rs, int rt
846 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
847 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
849 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
850 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
851 + ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
852 LO = EXTEND32 (temp);
853 HI = EXTEND32 (VH4_8 (temp));
854 TRACE_ALU_RESULT2 (HI, LO);
857 :function:::void:do_dsp_madd:int ac, int rs, int rt
861 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
862 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
864 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
865 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
866 + ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
867 DSPLO(ac) = EXTEND32 (temp);
868 DSPHI(ac) = EXTEND32 (VH4_8 (temp));
870 TRACE_ALU_RESULT2 (HI, LO);
873 :function:::void:do_maddu:int rs, int rt
876 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
877 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
879 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
880 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
881 + ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
882 ACX += U8_4 (VL4_8 (HI), VL4_8 (LO)) < temp; /* SmartMIPS */
883 LO = EXTEND32 (temp);
884 HI = EXTEND32 (VH4_8 (temp));
885 TRACE_ALU_RESULT2 (HI, LO);
888 :function:::void:do_dsp_maddu:int ac, int rs, int rt
892 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
893 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
895 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
896 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
897 + ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
899 ACX += U8_4 (VL4_8 (HI), VL4_8 (LO)) < temp; /* SmartMIPS */
900 DSPLO(ac) = EXTEND32 (temp);
901 DSPHI(ac) = EXTEND32 (VH4_8 (temp));
903 TRACE_ALU_RESULT2 (HI, LO);
906 :function:::void:do_dsp_mfhi:int ac, int rd
914 :function:::void:do_dsp_mflo:int ac, int rd
922 :function:::void:do_movn:int rd, int rs, int rt
927 TRACE_ALU_RESULT (GPR[rd]);
931 :function:::void:do_movz:int rd, int rs, int rt
936 TRACE_ALU_RESULT (GPR[rd]);
940 :function:::void:do_msub:int rs, int rt
943 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
944 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
946 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
947 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
948 - ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
949 LO = EXTEND32 (temp);
950 HI = EXTEND32 (VH4_8 (temp));
951 TRACE_ALU_RESULT2 (HI, LO);
954 :function:::void:do_dsp_msub:int ac, int rs, int rt
958 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
959 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
961 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
962 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
963 - ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
964 DSPLO(ac) = EXTEND32 (temp);
965 DSPHI(ac) = EXTEND32 (VH4_8 (temp));
967 TRACE_ALU_RESULT2 (HI, LO);
970 :function:::void:do_msubu:int rs, int rt
973 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
974 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
976 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
977 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
978 - ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
979 LO = EXTEND32 (temp);
980 HI = EXTEND32 (VH4_8 (temp));
981 TRACE_ALU_RESULT2 (HI, LO);
984 :function:::void:do_dsp_msubu:int ac, int rs, int rt
988 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
989 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
991 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
992 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
993 - ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
994 DSPLO(ac) = EXTEND32 (temp);
995 DSPHI(ac) = EXTEND32 (VH4_8 (temp));
997 TRACE_ALU_RESULT2 (HI, LO);
1000 :function:::void:do_mthi:int rs
1002 check_mt_hilo (SD_, HIHISTORY);
1006 :function:::void:do_dsp_mthi:int ac, int rs
1009 check_mt_hilo (SD_, HIHISTORY);
1010 DSPHI(ac) = GPR[rs];
1013 :function:::void:do_mtlo:int rs
1015 check_mt_hilo (SD_, LOHISTORY);
1019 :function:::void:do_dsp_mtlo:int ac, int rs
1022 check_mt_hilo (SD_, LOHISTORY);
1023 DSPLO(ac) = GPR[rs];
1026 :function:::void:do_mul:int rd, int rs, int rt
1029 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
1031 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1032 prod = (((signed64)(signed32) GPR[rs])
1033 * ((signed64)(signed32) GPR[rt]));
1034 GPR[rd] = EXTEND32 (VL4_8 (prod));
1035 TRACE_ALU_RESULT (GPR[rd]);
1038 :function:::void:do_dsp_mult:int ac, int rs, int rt
1042 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
1043 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
1045 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1046 prod = ((signed64)(signed32) GPR[rs])
1047 * ((signed64)(signed32) GPR[rt]);
1048 DSPLO(ac) = EXTEND32 (VL4_8 (prod));
1049 DSPHI(ac) = EXTEND32 (VH4_8 (prod));
1052 ACX = 0; /* SmartMIPS */
1053 TRACE_ALU_RESULT2 (HI, LO);
1057 :function:::void:do_dsp_multu:int ac, int rs, int rt
1061 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
1062 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
1064 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1065 prod = ((unsigned64)(unsigned32) GPR[rs])
1066 * ((unsigned64)(unsigned32) GPR[rt]);
1067 DSPLO(ac) = EXTEND32 (VL4_8 (prod));
1068 DSPHI(ac) = EXTEND32 (VH4_8 (prod));
1070 TRACE_ALU_RESULT2 (HI, LO);
1073 :function:::void:do_pref:int hint, int insn_offset, int insn_base
1075 address_word base = GPR[insn_base];
1076 address_word offset = EXTEND16 (insn_offset);
1078 address_word vaddr = loadstore_ea (SD_, base, offset);
1079 address_word paddr = vaddr;
1080 /* Prefetch (paddr, vaddr, isDATA, hint); */
1084 :function:::void:do_sc:int rt, int offsetarg, int basereg, address_word instruction_0
1086 unsigned32 instruction = instruction_0;
1087 address_word base = GPR[basereg];
1088 address_word offset = EXTEND16 (offsetarg);
1090 address_word vaddr = loadstore_ea (SD_, base, offset);
1091 address_word paddr = vaddr;
1093 if ((vaddr & 3) != 0)
1095 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer,
1096 sim_core_unaligned_signal);
1100 unsigned64 memval = 0;
1101 unsigned64 memval1 = 0;
1102 unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1103 address_word reverseendian =
1104 (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
1105 address_word bigendiancpu =
1106 (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
1108 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
1109 byte = ((vaddr & mask) ^ bigendiancpu);
1110 memval = ((unsigned64) GPR[rt] << (8 * byte));
1112 StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr,
1119 :function:::void:do_scd:int rt, int roffset, int rbase
1121 address_word base = GPR[rbase];
1122 address_word offset = EXTEND16 (roffset);
1124 address_word vaddr = loadstore_ea (SD_, base, offset);
1125 address_word paddr = vaddr;
1127 if ((vaddr & 7) != 0)
1129 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer,
1130 sim_core_unaligned_signal);
1134 unsigned64 memval = 0;
1135 unsigned64 memval1 = 0;
1138 StoreMemory (AccessLength_DOUBLEWORD, memval, memval1, paddr, vaddr,
1145 :function:::void:do_sub:int rs, int rt, int rd
1147 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
1149 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1151 ALU32_BEGIN (GPR[rs]);
1152 ALU32_SUB (GPR[rt]);
1153 ALU32_END (GPR[rd]); /* This checks for overflow. */
1155 TRACE_ALU_RESULT (GPR[rd]);
1158 :function:::void:do_sw:int rt, int offset, int base
1160 do_store (SD_, AccessLength_WORD, GPR[base], EXTEND16 (offset), GPR[rt]);
1163 :function:::void:do_teq:int rs, int rt, address_word instruction_0
1165 if ((signed_word) GPR[rs] == (signed_word) GPR[rt])
1166 SignalException (Trap, instruction_0);
1169 :function:::void:do_teqi:int rs, int immediate, address_word instruction_0
1171 if ((signed_word) GPR[rs] == (signed_word) EXTEND16 (immediate))
1172 SignalException (Trap, instruction_0);
1175 :function:::void:do_tge:int rs, int rt, address_word instruction_0
1177 if ((signed_word) GPR[rs] >= (signed_word) GPR[rt])
1178 SignalException (Trap, instruction_0);
1181 :function:::void:do_tgei:int rs, int immediate, address_word instruction_0
1183 if ((signed_word) GPR[rs] >= (signed_word) EXTEND16 (immediate))
1184 SignalException (Trap, instruction_0);
1187 :function:::void:do_tgeiu:int rs, int immediate, address_word instruction_0
1189 if ((unsigned_word) GPR[rs] >= (unsigned_word) EXTEND16 (immediate))
1190 SignalException (Trap, instruction_0);
1193 :function:::void:do_tgeu:int rs ,int rt, address_word instruction_0
1195 if ((unsigned_word) GPR[rs] >= (unsigned_word) GPR[rt])
1196 SignalException (Trap, instruction_0);
1199 :function:::void:do_tlt:int rs, int rt, address_word instruction_0
1201 if ((signed_word) GPR[rs] < (signed_word) GPR[rt])
1202 SignalException (Trap, instruction_0);
1205 :function:::void:do_tlti:int rs, int immediate, address_word instruction_0
1207 if ((signed_word) GPR[rs] < (signed_word) EXTEND16 (immediate))
1208 SignalException (Trap, instruction_0);
1211 :function:::void:do_tltiu:int rs, int immediate, address_word instruction_0
1213 if ((unsigned_word) GPR[rs] < (unsigned_word) EXTEND16 (immediate))
1214 SignalException (Trap, instruction_0);
1217 :function:::void:do_tltu:int rs, int rt, address_word instruction_0
1219 if ((unsigned_word) GPR[rs] < (unsigned_word) GPR[rt])
1220 SignalException (Trap, instruction_0);
1223 :function:::void:do_tne:int rs, int rt, address_word instruction_0
1225 if ((signed_word) GPR[rs] != (signed_word) GPR[rt])
1226 SignalException (Trap, instruction_0);
1229 :function:::void:do_tnei:int rs, int immediate, address_word instruction_0
1231 if ((signed_word) GPR[rs] != (signed_word) EXTEND16 (immediate))
1232 SignalException (Trap, instruction_0);
1235 :function:::void:do_abs_fmt:int fmt, int fd, int fs, address_word instruction_0
1238 check_fmt_p (SD_, fmt, instruction_0);
1239 StoreFPR (fd, fmt, AbsoluteValue (ValueFPR (fs, fmt), fmt));
1242 :function:::void:do_add_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
1245 check_fmt_p (SD_, fmt, instruction_0);
1246 StoreFPR (fd, fmt, Add (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
1249 :function:::void:do_alnv_ps:int fd, int fs, int ft, int rs, address_word instruction_0
1255 check_u64 (SD_, instruction_0);
1256 fsx = ValueFPR (fs, fmt_ps);
1257 if ((GPR[rs] & 0x3) != 0)
1259 if ((GPR[rs] & 0x4) == 0)
1263 ftx = ValueFPR (ft, fmt_ps);
1265 fdx = PackPS (PSLower (fsx), PSUpper (ftx));
1267 fdx = PackPS (PSLower (ftx), PSUpper (fsx));
1269 StoreFPR (fd, fmt_ps, fdx);
1272 :function:::void:do_c_cond_fmt:int cond, int fmt, int cc, int fs, int ft, address_word instruction_0
1275 check_fmt_p (SD_, fmt, instruction_0);
1276 Compare (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt, cond, cc);
1277 TRACE_ALU_RESULT (ValueFCR (31));
1280 :function:::void:do_ceil_fmt:int type, int fmt, int fd, int fs, address_word instruction_0
1283 check_fmt_p (SD_, fmt, instruction_0);
1284 StoreFPR (fd, type, Convert (FP_RM_TOPINF, ValueFPR (fs, fmt), fmt,
1288 :function:::void:do_cfc1:int rt, int fs
1291 if (fs == 0 || fs == 25 || fs == 26 || fs == 28 || fs == 31)
1293 unsigned_word fcr = ValueFCR (fs);
1294 TRACE_ALU_INPUT1 (fcr);
1298 TRACE_ALU_RESULT (GPR[rt]);
1301 :function:::void:do_ctc1:int rt, int fs
1304 TRACE_ALU_INPUT1 (GPR[rt]);
1305 if (fs == 25 || fs == 26 || fs == 28 || fs == 31)
1306 StoreFCR (fs, GPR[rt]);
1310 :function:::void:do_cvt_d_fmt:int fmt, int fd, int fs, address_word instruction_0
1313 if ((fmt == fmt_double) | 0)
1314 SignalException (ReservedInstruction, instruction_0);
1315 StoreFPR (fd, fmt_double, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
1319 :function:::void:do_cvt_l_fmt:int fmt, int fd, int fs, address_word instruction_0
1322 if ((fmt == fmt_long) | ((fmt == fmt_long) || (fmt == fmt_word)))
1323 SignalException (ReservedInstruction, instruction_0);
1324 StoreFPR (fd, fmt_long, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
1328 :function:::void:do_cvt_ps_s:int fd, int fs, int ft, address_word instruction_0
1331 check_u64 (SD_, instruction_0);
1332 StoreFPR (fd, fmt_ps, PackPS (ValueFPR (fs, fmt_single),
1333 ValueFPR (ft, fmt_single)));
1336 :function:::void:do_cvt_s_fmt:int fmt, int fd, int fs, address_word instruction_0
1339 if ((fmt == fmt_single) | 0)
1340 SignalException (ReservedInstruction, instruction_0);
1341 StoreFPR (fd, fmt_single, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
1345 :function:::void:do_cvt_s_pl:int fd, int fs, address_word instruction_0
1348 check_u64 (SD_, instruction_0);
1349 StoreFPR (fd, fmt_single, PSLower (ValueFPR (fs, fmt_ps)));
1352 :function:::void:do_cvt_s_pu:int fd, int fs, address_word instruction_0
1355 check_u64 (SD_, instruction_0);
1356 StoreFPR (fd, fmt_single, PSUpper (ValueFPR (fs, fmt_ps)));
1359 :function:::void:do_cvt_w_fmt:int fmt, int fd, int fs, address_word instruction_0
1362 if ((fmt == fmt_word) | ((fmt == fmt_long) || (fmt == fmt_word)))
1363 SignalException (ReservedInstruction, instruction_0);
1364 StoreFPR (fd, fmt_word, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
1368 :function:::void:do_div_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
1371 StoreFPR (fd, fmt, Divide (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
1374 :function:::void:do_dmfc1b:int rt, int fs
1384 if (SizeFGR () == 64)
1386 else if ((fs & 0x1) == 0)
1387 GPR[rt] = SET64HI (FGR[fs+1]) | FGR[fs];
1389 GPR[rt] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
1390 TRACE_ALU_RESULT (GPR[rt]);
1393 :function:::void:do_dmtc1b:int rt, int fs
1395 if (SizeFGR () == 64)
1396 StoreFPR (fs, fmt_uninterpreted_64, GPR[rt]);
1397 else if ((fs & 0x1) == 0)
1398 StoreFPR (fs, fmt_uninterpreted_64, GPR[rt]);
1403 :function:::void:do_floor_fmt:int type, int fmt, int fd, int fs
1406 StoreFPR (fd, type, Convert (FP_RM_TOMINF, ValueFPR (fs, fmt), fmt,
1410 :function:::void:do_luxc1_32:int fd, int rindex, int rbase
1414 address_word base = GPR[rbase];
1415 address_word index = GPR[rindex];
1416 address_word vaddr = base + index;
1418 if (SizeFGR () != 64)
1420 /* Arrange for the bottom 3 bits of (base + index) to be 0. */
1421 if ((vaddr & 0x7) != 0)
1422 index -= (vaddr & 0x7);
1423 COP_LD (1, fd, do_load_double (SD_, base, index));
1426 :function:::void:do_luxc1_64:int fd, int rindex, int rbase
1428 address_word base = GPR[rbase];
1429 address_word index = GPR[rindex];
1430 address_word vaddr = base + index;
1431 if (SizeFGR () != 64)
1433 /* Arrange for the bottom 3 bits of (base + index) to be 0. */
1434 if ((vaddr & 0x7) != 0)
1435 index -= (vaddr & 0x7);
1436 COP_LD (1, fd, do_load (SD_, AccessLength_DOUBLEWORD, base, index));
1440 :function:::void:do_lwc1:int ft, int offset, int base
1443 COP_LW (1, ft, do_load (SD_, AccessLength_WORD, GPR[base],
1444 EXTEND16 (offset)));
1447 :function:::void:do_lwxc1:int fd, int index, int base, address_word instruction_0
1450 check_u64 (SD_, instruction_0);
1451 COP_LW (1, fd, do_load (SD_, AccessLength_WORD, GPR[base], GPR[index]));
1454 :function:::void:do_madd_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
1457 check_u64 (SD_, instruction_0);
1458 check_fmt_p (SD_, fmt, instruction_0);
1459 StoreFPR (fd, fmt, MultiplyAdd (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
1460 ValueFPR (fr, fmt), fmt));
1463 :function:::void:do_mfc1b:int rt, int fs
1466 GPR[rt] = EXTEND32 (FGR[fs]);
1467 TRACE_ALU_RESULT (GPR[rt]);
1470 :function:::void:do_mov_fmt:int fmt, int fd, int fs, address_word instruction_0
1473 check_fmt_p (SD_, fmt, instruction_0);
1474 StoreFPR (fd, fmt, ValueFPR (fs, fmt));
1477 :function:::void:do_movtf:int tf, int rd, int rs, int cc
1480 if (GETFCC(cc) == tf)
1484 :function:::void:do_movtf_fmt:int tf, int fmt, int fd, int fs, int cc
1489 if (GETFCC(cc) == tf)
1490 StoreFPR (fd, fmt, ValueFPR (fs, fmt));
1492 StoreFPR (fd, fmt, ValueFPR (fd, fmt)); /* set fmt */
1497 fdx = PackPS (PSUpper (ValueFPR ((GETFCC (cc+1) == tf) ? fs : fd,
1499 PSLower (ValueFPR ((GETFCC (cc+0) == tf) ? fs : fd,
1501 StoreFPR (fd, fmt_ps, fdx);
1505 :function:::void:do_movn_fmt:int fmt, int fd, int fs, int rt
1509 StoreFPR (fd, fmt, ValueFPR (fs, fmt));
1511 StoreFPR (fd, fmt, ValueFPR (fd, fmt));
1514 :function:::void:do_movz_fmt:int fmt, int fd, int fs, int rt
1518 StoreFPR (fd, fmt, ValueFPR (fs, fmt));
1520 StoreFPR (fd, fmt, ValueFPR (fd, fmt));
1523 :function:::void:do_msub_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
1526 check_u64 (SD_, instruction_0);
1527 check_fmt_p (SD_, fmt, instruction_0);
1528 StoreFPR (fd, fmt, MultiplySub (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
1529 ValueFPR (fr, fmt), fmt));
1532 :function:::void:do_mtc1b:int rt, int fs
1535 StoreFPR (fs, fmt_uninterpreted_32, VL4_8 (GPR[rt]));
1538 :function:::void:do_mul_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
1541 check_fmt_p (SD_, fmt, instruction_0);
1542 StoreFPR (fd, fmt, Multiply (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
1545 :function:::void:do_neg_fmt:int fmt, int fd, int fs, address_word instruction_0
1548 check_fmt_p (SD_, fmt, instruction_0);
1549 StoreFPR (fd, fmt, Negate (ValueFPR (fs, fmt), fmt));
1552 :function:::void:do_nmadd_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
1555 check_u64 (SD_, instruction_0);
1556 check_fmt_p (SD_, fmt, instruction_0);
1557 StoreFPR (fd, fmt, NegMultiplyAdd (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
1558 ValueFPR (fr, fmt), fmt));
1561 :function:::void:do_nmsub_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
1564 check_u64 (SD_, instruction_0);
1565 check_fmt_p (SD_, fmt, instruction_0);
1566 StoreFPR (fd, fmt, NegMultiplySub (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
1567 ValueFPR (fr, fmt), fmt));
1570 :function:::void:do_pll_ps:int fd, int fs, int ft, address_word instruction_0
1573 check_u64 (SD_, instruction_0);
1574 StoreFPR (fd, fmt_ps, PackPS (PSLower (ValueFPR (fs, fmt_ps)),
1575 PSLower (ValueFPR (ft, fmt_ps))));
1578 :function:::void:do_plu_ps:int fd, int fs, int ft, address_word instruction_0
1581 check_u64 (SD_, instruction_0);
1582 StoreFPR (fd, fmt_ps, PackPS (PSLower (ValueFPR (fs, fmt_ps)),
1583 PSUpper (ValueFPR (ft, fmt_ps))));
1586 :function:::void:do_pul_ps:int fd, int fs, int ft, address_word instruction_0
1589 check_u64 (SD_, instruction_0);
1590 StoreFPR (fd, fmt_ps, PackPS (PSUpper (ValueFPR (fs, fmt_ps)),
1591 PSLower (ValueFPR (ft, fmt_ps))));
1594 :function:::void:do_puu_ps:int fd, int fs, int ft, address_word instruction_0
1597 check_u64 (SD_, instruction_0);
1598 StoreFPR (fd, fmt_ps, PackPS (PSUpper (ValueFPR (fs, fmt_ps)),
1599 PSUpper (ValueFPR (ft, fmt_ps))));
1602 :function:::void:do_recip_fmt:int fmt, int fd, int fs
1605 StoreFPR (fd, fmt, Recip (ValueFPR (fs, fmt), fmt));
1608 :function:::void:do_round_fmt:int type, int fmt, int fd, int fs
1611 StoreFPR (fd, type, Convert (FP_RM_NEAREST, ValueFPR (fs, fmt), fmt,
1615 :function:::void:do_rsqrt_fmt:int fmt, int fd, int fs
1618 StoreFPR (fd, fmt, RSquareRoot (ValueFPR (fs, fmt), fmt));
1621 :function:::void:do_prefx:int hint, int rindex, int rbase
1623 address_word base = GPR[rbase];
1624 address_word index = GPR[rindex];
1626 address_word vaddr = loadstore_ea (SD_, base, index);
1627 address_word paddr = vaddr;
1628 /* Prefetch (paddr, vaddr, isDATA, hint); */
1632 :function:::void:do_sdc1:int ft, int offset, int base
1639 do_store_double (SD_, GPR[base], EXTEND16 (offset), COP_SD (1, ft));
1642 :function:::void:do_suxc1_32:int fs, int rindex, int rbase
1646 address_word base = GPR[rbase];
1647 address_word index = GPR[rindex];
1648 address_word vaddr = base + index;
1650 if (SizeFGR () != 64)
1652 /* Arrange for the bottom 3 bits of (base + index) to be 0. */
1653 if ((vaddr & 0x7) != 0)
1654 index -= (vaddr & 0x7);
1655 do_store_double (SD_, base, index, COP_SD (1, fs));
1658 :function:::void:do_suxc1_64:int fs, int rindex, int rbase
1660 address_word base = GPR[rbase];
1661 address_word index = GPR[rindex];
1662 address_word vaddr = base + index;
1663 if (SizeFGR () != 64)
1665 /* Arrange for the bottom 3 bits of (base + index) to be 0. */
1666 if ((vaddr & 0x7) != 0)
1667 index -= (vaddr & 0x7);
1668 do_store (SD_, AccessLength_DOUBLEWORD, base, index, COP_SD (1, fs));
1671 :function:::void:do_sqrt_fmt:int fmt, int fd, int fs
1674 StoreFPR (fd, fmt, (SquareRoot (ValueFPR (fs, fmt), fmt)));
1677 :function:::void:do_sub_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
1680 check_fmt_p (SD_, fmt, instruction_0);
1681 StoreFPR (fd, fmt, Sub (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
1684 :function:::void:do_swc1:int ft, int roffset, int rbase, address_word instruction_0
1686 address_word base = GPR[rbase];
1687 address_word offset = EXTEND16 (roffset);
1690 address_word vaddr = loadstore_ea (SD_, base, offset);
1691 address_word paddr = vaddr;
1693 if ((vaddr & 3) != 0)
1695 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr,
1696 write_transfer, sim_core_unaligned_signal);
1701 uword64 memval1 = 0;
1702 uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1703 address_word reverseendian =
1704 (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
1705 address_word bigendiancpu =
1706 (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
1708 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
1709 byte = ((vaddr & mask) ^ bigendiancpu);
1710 memval = (((uword64)COP_SW(1, ft)) << (8 * byte));
1711 StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr, isREAL);
1716 :function:::void:do_swxc1:int fs, int rindex, int rbase, address_word instruction_0
1718 address_word base = GPR[rbase];
1719 address_word index = GPR[rindex];
1721 check_u64 (SD_, instruction_0);
1723 address_word vaddr = loadstore_ea (SD_, base, index);
1724 address_word paddr = vaddr;
1726 if ((vaddr & 3) != 0)
1728 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer,
1729 sim_core_unaligned_signal);
1733 unsigned64 memval = 0;
1734 unsigned64 memval1 = 0;
1735 unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1736 address_word reverseendian =
1737 (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
1738 address_word bigendiancpu =
1739 (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
1741 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
1742 byte = ((vaddr & mask) ^ bigendiancpu);
1743 memval = (((unsigned64)COP_SW(1,fs)) << (8 * byte));
1744 StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr,
1750 :function:::void:do_trunc_fmt:int type, int fmt, int fd, int fs
1753 StoreFPR (fd, type, Convert (FP_RM_TOZERO, ValueFPR (fs, fmt), fmt,
1757 000000,5.RS,5.RT,5.RD,00000,100000:SPECIAL:32::ADD
1758 "add r<RD>, r<RS>, r<RT>"
1772 do_add (SD_, RS, RT, RD);
1777 001000,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDI
1778 "addi r<RT>, r<RS>, <IMMEDIATE>"
1792 do_addi (SD_, RS, RT, IMMEDIATE);
1797 :function:::void:do_addiu:int rs, int rt, unsigned16 immediate
1799 if (NotWordValue (GPR[rs]))
1801 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
1802 GPR[rt] = EXTEND32 (GPR[rs] + EXTEND16 (immediate));
1803 TRACE_ALU_RESULT (GPR[rt]);
1806 001001,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDIU
1807 "addiu r<RT>, r<RS>, <IMMEDIATE>"
1821 do_addiu (SD_, RS, RT, IMMEDIATE);
1826 :function:::void:do_addu:int rs, int rt, int rd
1828 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
1830 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1831 GPR[rd] = EXTEND32 (GPR[rs] + GPR[rt]);
1832 TRACE_ALU_RESULT (GPR[rd]);
1835 000000,5.RS,5.RT,5.RD,00000,100001:SPECIAL:32::ADDU
1836 "addu r<RD>, r<RS>, r<RT>"
1850 do_addu (SD_, RS, RT, RD);
1855 :function:::void:do_and:int rs, int rt, int rd
1857 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1858 GPR[rd] = GPR[rs] & GPR[rt];
1859 TRACE_ALU_RESULT (GPR[rd]);
1862 000000,5.RS,5.RT,5.RD,00000,100100:SPECIAL:32::AND
1863 "and r<RD>, r<RS>, r<RT>"
1877 do_and (SD_, RS, RT, RD);
1882 001100,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ANDI
1883 "andi r<RT>, r<RS>, %#lx<IMMEDIATE>"
1897 do_andi (SD_,RS, RT, IMMEDIATE);
1902 000100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQ
1903 "beq r<RS>, r<RT>, <OFFSET>"
1917 address_word offset = EXTEND16 (OFFSET) << 2;
1918 if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
1920 DELAY_SLOT (NIA + offset);
1926 010100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQL
1927 "beql r<RS>, r<RT>, <OFFSET>"
1940 address_word offset = EXTEND16 (OFFSET) << 2;
1941 if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
1943 DELAY_SLOT (NIA + offset);
1946 NULLIFY_NEXT_INSTRUCTION ();
1951 000001,5.RS,00001,16.OFFSET:REGIMM:32::BGEZ
1952 "bgez r<RS>, <OFFSET>"
1966 address_word offset = EXTEND16 (OFFSET) << 2;
1967 if ((signed_word) GPR[RS] >= 0)
1969 DELAY_SLOT (NIA + offset);
1975 000001,5.RS!31,10001,16.OFFSET:REGIMM:32::BGEZAL
1976 "bgezal r<RS>, <OFFSET>"
1990 address_word offset = EXTEND16 (OFFSET) << 2;
1994 if ((signed_word) GPR[RS] >= 0)
1996 DELAY_SLOT (NIA + offset);
2002 000001,5.RS!31,10011,16.OFFSET:REGIMM:32::BGEZALL
2003 "bgezall r<RS>, <OFFSET>"
2016 address_word offset = EXTEND16 (OFFSET) << 2;
2020 /* NOTE: The branch occurs AFTER the next instruction has been
2022 if ((signed_word) GPR[RS] >= 0)
2024 DELAY_SLOT (NIA + offset);
2027 NULLIFY_NEXT_INSTRUCTION ();
2032 000001,5.RS,00011,16.OFFSET:REGIMM:32::BGEZL
2033 "bgezl r<RS>, <OFFSET>"
2046 address_word offset = EXTEND16 (OFFSET) << 2;
2047 if ((signed_word) GPR[RS] >= 0)
2049 DELAY_SLOT (NIA + offset);
2052 NULLIFY_NEXT_INSTRUCTION ();
2057 000111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZ
2058 "bgtz r<RS>, <OFFSET>"
2072 address_word offset = EXTEND16 (OFFSET) << 2;
2073 if ((signed_word) GPR[RS] > 0)
2075 DELAY_SLOT (NIA + offset);
2081 010111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZL
2082 "bgtzl r<RS>, <OFFSET>"
2095 address_word offset = EXTEND16 (OFFSET) << 2;
2096 /* NOTE: The branch occurs AFTER the next instruction has been
2098 if ((signed_word) GPR[RS] > 0)
2100 DELAY_SLOT (NIA + offset);
2103 NULLIFY_NEXT_INSTRUCTION ();
2108 000110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZ
2109 "blez r<RS>, <OFFSET>"
2123 address_word offset = EXTEND16 (OFFSET) << 2;
2124 /* NOTE: The branch occurs AFTER the next instruction has been
2126 if ((signed_word) GPR[RS] <= 0)
2128 DELAY_SLOT (NIA + offset);
2134 010110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZL
2135 "bgezl r<RS>, <OFFSET>"
2148 address_word offset = EXTEND16 (OFFSET) << 2;
2149 if ((signed_word) GPR[RS] <= 0)
2151 DELAY_SLOT (NIA + offset);
2154 NULLIFY_NEXT_INSTRUCTION ();
2159 000001,5.RS,00000,16.OFFSET:REGIMM:32::BLTZ
2160 "bltz r<RS>, <OFFSET>"
2174 address_word offset = EXTEND16 (OFFSET) << 2;
2175 if ((signed_word) GPR[RS] < 0)
2177 DELAY_SLOT (NIA + offset);
2183 000001,5.RS!31,10000,16.OFFSET:REGIMM:32::BLTZAL
2184 "bltzal r<RS>, <OFFSET>"
2198 address_word offset = EXTEND16 (OFFSET) << 2;
2202 /* NOTE: The branch occurs AFTER the next instruction has been
2204 if ((signed_word) GPR[RS] < 0)
2206 DELAY_SLOT (NIA + offset);
2212 000001,5.RS!31,10010,16.OFFSET:REGIMM:32::BLTZALL
2213 "bltzall r<RS>, <OFFSET>"
2226 address_word offset = EXTEND16 (OFFSET) << 2;
2230 if ((signed_word) GPR[RS] < 0)
2232 DELAY_SLOT (NIA + offset);
2235 NULLIFY_NEXT_INSTRUCTION ();
2240 000001,5.RS,00010,16.OFFSET:REGIMM:32::BLTZL
2241 "bltzl r<RS>, <OFFSET>"
2254 address_word offset = EXTEND16 (OFFSET) << 2;
2255 /* NOTE: The branch occurs AFTER the next instruction has been
2257 if ((signed_word) GPR[RS] < 0)
2259 DELAY_SLOT (NIA + offset);
2262 NULLIFY_NEXT_INSTRUCTION ();
2267 000101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNE
2268 "bne r<RS>, r<RT>, <OFFSET>"
2282 address_word offset = EXTEND16 (OFFSET) << 2;
2283 if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
2285 DELAY_SLOT (NIA + offset);
2291 010101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNEL
2292 "bnel r<RS>, r<RT>, <OFFSET>"
2305 address_word offset = EXTEND16 (OFFSET) << 2;
2306 if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
2308 DELAY_SLOT (NIA + offset);
2311 NULLIFY_NEXT_INSTRUCTION ();
2316 000000,20.CODE,001101:SPECIAL:32::BREAK
2331 do_break (SD_, instruction_0);
2336 011100,5.RS,5.RT,5.RD,00000,100001:SPECIAL2:32::CLO
2346 do_clo (SD_, RD, RS);
2351 011100,5.RS,5.RT,5.RD,00000,100000:SPECIAL2:32::CLZ
2361 do_clz (SD_, RD, RS);
2366 000000,5.RS,5.RT,5.RD,00000,101100:SPECIAL:64::DADD
2367 "dadd r<RD>, r<RS>, r<RT>"
2376 check_u64 (SD_, instruction_0);
2377 do_dadd (SD_, RD, RS, RT);
2382 011000,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDI
2383 "daddi r<RT>, r<RS>, <IMMEDIATE>"
2392 check_u64 (SD_, instruction_0);
2393 do_daddi (SD_, RT, RS, IMMEDIATE);
2398 :function:::void:do_daddiu:int rs, int rt, unsigned16 immediate
2400 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
2401 GPR[rt] = GPR[rs] + EXTEND16 (immediate);
2402 TRACE_ALU_RESULT (GPR[rt]);
2405 011001,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDIU
2406 "daddiu r<RT>, r<RS>, <IMMEDIATE>"
2415 check_u64 (SD_, instruction_0);
2416 do_daddiu (SD_, RS, RT, IMMEDIATE);
2421 :function:::void:do_daddu:int rs, int rt, int rd
2423 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2424 GPR[rd] = GPR[rs] + GPR[rt];
2425 TRACE_ALU_RESULT (GPR[rd]);
2428 000000,5.RS,5.RT,5.RD,00000,101101:SPECIAL:64::DADDU
2429 "daddu r<RD>, r<RS>, r<RT>"
2438 check_u64 (SD_, instruction_0);
2439 do_daddu (SD_, RS, RT, RD);
2444 011100,5.RS,5.RT,5.RD,00000,100101:SPECIAL2:64::DCLO
2452 check_u64 (SD_, instruction_0);
2453 do_dclo (SD_, RD, RS);
2458 011100,5.RS,5.RT,5.RD,00000,100100:SPECIAL2:64::DCLZ
2466 check_u64 (SD_, instruction_0);
2467 do_dclz (SD_, RD, RS);
2472 :function:::void:do_ddiv:int rs, int rt
2474 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
2475 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2477 signed64 n = GPR[rs];
2478 signed64 d = GPR[rt];
2483 lo = SIGNED64 (0x8000000000000000);
2486 else if (d == -1 && n == SIGNED64 (0x8000000000000000))
2488 lo = SIGNED64 (0x8000000000000000);
2499 TRACE_ALU_RESULT2 (HI, LO);
2502 000000,5.RS,5.RT,0000000000,011110:SPECIAL:64::DDIV
2512 check_u64 (SD_, instruction_0);
2513 do_ddiv (SD_, RS, RT);
2518 :function:::void:do_ddivu:int rs, int rt
2520 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
2521 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2523 unsigned64 n = GPR[rs];
2524 unsigned64 d = GPR[rt];
2529 lo = SIGNED64 (0x8000000000000000);
2540 TRACE_ALU_RESULT2 (HI, LO);
2543 000000,5.RS,5.RT,0000000000,011111:SPECIAL:64::DDIVU
2544 "ddivu r<RS>, r<RT>"
2553 check_u64 (SD_, instruction_0);
2554 do_ddivu (SD_, RS, RT);
2557 :function:::void:do_div:int rs, int rt
2559 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
2560 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2562 signed32 n = GPR[rs];
2563 signed32 d = GPR[rt];
2566 LO = EXTEND32 (0x80000000);
2569 else if (n == SIGNED32 (0x80000000) && d == -1)
2571 LO = EXTEND32 (0x80000000);
2576 LO = EXTEND32 (n / d);
2577 HI = EXTEND32 (n % d);
2580 TRACE_ALU_RESULT2 (HI, LO);
2583 000000,5.RS,5.RT,0000000000,011010:SPECIAL:32::DIV
2598 do_div (SD_, RS, RT);
2603 :function:::void:do_divu:int rs, int rt
2605 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
2606 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2608 unsigned32 n = GPR[rs];
2609 unsigned32 d = GPR[rt];
2612 LO = EXTEND32 (0x80000000);
2617 LO = EXTEND32 (n / d);
2618 HI = EXTEND32 (n % d);
2621 TRACE_ALU_RESULT2 (HI, LO);
2624 000000,5.RS,5.RT,0000000000,011011:SPECIAL:32::DIVU
2639 do_divu (SD_, RS, RT);
2643 :function:::void:do_dmultx:int rs, int rt, int rd, int signed_p
2653 unsigned64 op1 = GPR[rs];
2654 unsigned64 op2 = GPR[rt];
2655 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
2656 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2657 /* make signed multiply unsigned */
2661 if ((signed64) op1 < 0)
2666 if ((signed64) op2 < 0)
2672 /* multiply out the 4 sub products */
2673 m00 = ((unsigned64) VL4_8 (op1) * (unsigned64) VL4_8 (op2));
2674 m10 = ((unsigned64) VH4_8 (op1) * (unsigned64) VL4_8 (op2));
2675 m01 = ((unsigned64) VL4_8 (op1) * (unsigned64) VH4_8 (op2));
2676 m11 = ((unsigned64) VH4_8 (op1) * (unsigned64) VH4_8 (op2));
2677 /* add the products */
2678 mid = ((unsigned64) VH4_8 (m00)
2679 + (unsigned64) VL4_8 (m10)
2680 + (unsigned64) VL4_8 (m01));
2681 lo = U8_4 (mid, m00);
2683 + (unsigned64) VH4_8 (mid)
2684 + (unsigned64) VH4_8 (m01)
2685 + (unsigned64) VH4_8 (m10));
2695 /* save the result HI/LO (and a gpr) */
2700 TRACE_ALU_RESULT2 (HI, LO);
2703 :function:::void:do_dmult:int rs, int rt, int rd
2705 do_dmultx (SD_, rs, rt, rd, 1);
2708 000000,5.RS,5.RT,0000000000,011100:SPECIAL:64::DMULT
2709 "dmult r<RS>, r<RT>"
2717 check_u64 (SD_, instruction_0);
2718 do_dmult (SD_, RS, RT, 0);
2721 000000,5.RS,5.RT,5.RD,00000,011100:SPECIAL:64::DMULT
2722 "dmult r<RS>, r<RT>":RD == 0
2723 "dmult r<RD>, r<RS>, r<RT>"
2726 check_u64 (SD_, instruction_0);
2727 do_dmult (SD_, RS, RT, RD);
2732 :function:::void:do_dmultu:int rs, int rt, int rd
2734 do_dmultx (SD_, rs, rt, rd, 0);
2737 000000,5.RS,5.RT,0000000000,011101:SPECIAL:64::DMULTU
2738 "dmultu r<RS>, r<RT>"
2746 check_u64 (SD_, instruction_0);
2747 do_dmultu (SD_, RS, RT, 0);
2750 000000,5.RS,5.RT,5.RD,00000,011101:SPECIAL:64::DMULTU
2751 "dmultu r<RD>, r<RS>, r<RT>":RD == 0
2752 "dmultu r<RS>, r<RT>"
2755 check_u64 (SD_, instruction_0);
2756 do_dmultu (SD_, RS, RT, RD);
2760 :function:::unsigned64:do_dror:unsigned64 x,unsigned64 y
2765 TRACE_ALU_INPUT2 (x, y);
2766 result = ROTR64 (x, y);
2767 TRACE_ALU_RESULT (result);
2771 000000,00001,5.RT,5.RD,5.SHIFT,111010::64::DROR
2772 "dror r<RD>, r<RT>, <SHIFT>"
2777 check_u64 (SD_, instruction_0);
2778 GPR[RD] = do_dror (SD_, GPR[RT], SHIFT);
2781 000000,00001,5.RT,5.RD,5.SHIFT,111110::64::DROR32
2782 "dror32 r<RD>, r<RT>, <SHIFT>"
2787 check_u64 (SD_, instruction_0);
2788 GPR[RD] = do_dror (SD_, GPR[RT], SHIFT + 32);
2791 000000,5.RS,5.RT,5.RD,00001,010110::64::DRORV
2792 "drorv r<RD>, r<RT>, r<RS>"
2797 check_u64 (SD_, instruction_0);
2798 GPR[RD] = do_dror (SD_, GPR[RT], GPR[RS]);
2802 :function:::void:do_dsll:int rt, int rd, int shift
2804 TRACE_ALU_INPUT2 (GPR[rt], shift);
2805 GPR[rd] = GPR[rt] << shift;
2806 TRACE_ALU_RESULT (GPR[rd]);
2809 000000,00000,5.RT,5.RD,5.SHIFT,111000:SPECIAL:64::DSLL
2810 "dsll r<RD>, r<RT>, <SHIFT>"
2819 check_u64 (SD_, instruction_0);
2820 do_dsll (SD_, RT, RD, SHIFT);
2824 000000,00000,5.RT,5.RD,5.SHIFT,111100:SPECIAL:64::DSLL32
2825 "dsll32 r<RD>, r<RT>, <SHIFT>"
2834 check_u64 (SD_, instruction_0);
2835 do_dsll32 (SD_, RD, RT, SHIFT);
2838 :function:::void:do_dsllv:int rs, int rt, int rd
2840 int s = MASKED64 (GPR[rs], 5, 0);
2841 TRACE_ALU_INPUT2 (GPR[rt], s);
2842 GPR[rd] = GPR[rt] << s;
2843 TRACE_ALU_RESULT (GPR[rd]);
2846 000000,5.RS,5.RT,5.RD,00000,010100:SPECIAL:64::DSLLV
2847 "dsllv r<RD>, r<RT>, r<RS>"
2856 check_u64 (SD_, instruction_0);
2857 do_dsllv (SD_, RS, RT, RD);
2860 :function:::void:do_dsra:int rt, int rd, int shift
2862 TRACE_ALU_INPUT2 (GPR[rt], shift);
2863 GPR[rd] = ((signed64) GPR[rt]) >> shift;
2864 TRACE_ALU_RESULT (GPR[rd]);
2868 000000,00000,5.RT,5.RD,5.SHIFT,111011:SPECIAL:64::DSRA
2869 "dsra r<RD>, r<RT>, <SHIFT>"
2878 check_u64 (SD_, instruction_0);
2879 do_dsra (SD_, RT, RD, SHIFT);
2883 000000,00000,5.RT,5.RD,5.SHIFT,111111:SPECIAL:64::DSRA32
2884 "dsra32 r<RD>, r<RT>, <SHIFT>"
2893 check_u64 (SD_, instruction_0);
2894 do_dsra32 (SD_, RD, RT, SHIFT);
2898 :function:::void:do_dsrav:int rs, int rt, int rd
2900 int s = MASKED64 (GPR[rs], 5, 0);
2901 TRACE_ALU_INPUT2 (GPR[rt], s);
2902 GPR[rd] = ((signed64) GPR[rt]) >> s;
2903 TRACE_ALU_RESULT (GPR[rd]);
2906 000000,5.RS,5.RT,5.RD,00000,010111:SPECIAL:64::DSRAV
2907 "dsrav r<RD>, r<RT>, r<RS>"
2916 check_u64 (SD_, instruction_0);
2917 do_dsrav (SD_, RS, RT, RD);
2920 :function:::void:do_dsrl:int rt, int rd, int shift
2922 TRACE_ALU_INPUT2 (GPR[rt], shift);
2923 GPR[rd] = (unsigned64) GPR[rt] >> shift;
2924 TRACE_ALU_RESULT (GPR[rd]);
2928 000000,00000,5.RT,5.RD,5.SHIFT,111010:SPECIAL:64::DSRL
2929 "dsrl r<RD>, r<RT>, <SHIFT>"
2938 check_u64 (SD_, instruction_0);
2939 do_dsrl (SD_, RT, RD, SHIFT);
2943 000000,00000,5.RT,5.RD,5.SHIFT,111110:SPECIAL:64::DSRL32
2944 "dsrl32 r<RD>, r<RT>, <SHIFT>"
2953 check_u64 (SD_, instruction_0);
2954 do_dsrl32 (SD_, RD, RT, SHIFT);
2958 :function:::void:do_dsrlv:int rs, int rt, int rd
2960 int s = MASKED64 (GPR[rs], 5, 0);
2961 TRACE_ALU_INPUT2 (GPR[rt], s);
2962 GPR[rd] = (unsigned64) GPR[rt] >> s;
2963 TRACE_ALU_RESULT (GPR[rd]);
2968 000000,5.RS,5.RT,5.RD,00000,010110:SPECIAL:64::DSRLV
2969 "dsrlv r<RD>, r<RT>, r<RS>"
2978 check_u64 (SD_, instruction_0);
2979 do_dsrlv (SD_, RS, RT, RD);
2983 000000,5.RS,5.RT,5.RD,00000,101110:SPECIAL:64::DSUB
2984 "dsub r<RD>, r<RS>, r<RT>"
2993 check_u64 (SD_, instruction_0);
2994 do_dsub (SD_, RD, RS, RT);
2998 :function:::void:do_dsubu:int rs, int rt, int rd
3000 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3001 GPR[rd] = GPR[rs] - GPR[rt];
3002 TRACE_ALU_RESULT (GPR[rd]);
3005 000000,5.RS,5.RT,5.RD,00000,101111:SPECIAL:64::DSUBU
3006 "dsubu r<RD>, r<RS>, r<RT>"
3015 check_u64 (SD_, instruction_0);
3016 do_dsubu (SD_, RS, RT, RD);
3020 000010,26.INSTR_INDEX:NORMAL:32::J
3035 /* NOTE: The region used is that of the delay slot NIA and NOT the
3036 current instruction */
3037 address_word region = (NIA & MASK (63, 28));
3038 DELAY_SLOT (region | (INSTR_INDEX << 2));
3042 000011,26.INSTR_INDEX:NORMAL:32::JAL
3057 /* NOTE: The region used is that of the delay slot and NOT the
3058 current instruction */
3059 address_word region = (NIA & MASK (63, 28));
3061 DELAY_SLOT (region | (INSTR_INDEX << 2));
3064 000000,5.RS,00000,5.RD,00000,001001:SPECIAL:32::JALR
3065 "jalr r<RS>":RD == 31
3080 address_word temp = GPR[RS];
3085 000000,5.RS,00000,5.RD,10000,001001:SPECIAL:32::JALR_HB
3086 "jalr.hb r<RS>":RD == 31
3087 "jalr.hb r<RD>, r<RS>"
3091 address_word temp = GPR[RS];
3096 000000,5.RS,0000000000,00000,001000:SPECIAL:32::JR
3111 DELAY_SLOT (GPR[RS]);
3114 000000,5.RS,0000000000,10000,001000:SPECIAL:32::JR_HB
3119 DELAY_SLOT (GPR[RS]);
3122 :function:::unsigned_word:do_load:unsigned access, address_word base, address_word offset
3124 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
3125 address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
3126 address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
3132 paddr = vaddr = loadstore_ea (SD_, base, offset);
3133 if ((vaddr & access) != 0)
3135 SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map, access+1, vaddr, read_transfer, sim_core_unaligned_signal);
3137 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
3138 LoadMemory (&memval, NULL, access, paddr, vaddr, isDATA, isREAL);
3139 byte = ((vaddr & mask) ^ bigendiancpu);
3140 return (memval >> (8 * byte));
3143 :function:::unsigned_word:do_load_left:unsigned access, address_word base, address_word offset, unsigned_word rt
3145 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
3146 address_word reverseendian = (ReverseEndian ? -1 : 0);
3147 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
3155 unsigned_word lhs_mask;
3158 paddr = vaddr = loadstore_ea (SD_, base, offset);
3159 paddr = (paddr ^ (reverseendian & mask));
3160 if (BigEndianMem == 0)
3161 paddr = paddr & ~access;
3163 /* compute where within the word/mem we are */
3164 byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
3165 word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
3166 nr_lhs_bits = 8 * byte + 8;
3167 nr_rhs_bits = 8 * access - 8 * byte;
3168 /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
3170 /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
3171 (long) ((unsigned64) vaddr >> 32), (long) vaddr,
3172 (long) ((unsigned64) paddr >> 32), (long) paddr,
3173 word, byte, nr_lhs_bits, nr_rhs_bits); */
3175 LoadMemory (&memval, NULL, byte, paddr, vaddr, isDATA, isREAL);
3178 /* GPR{31..32-NR_LHS_BITS} = memval{NR_LHS_BITS-1..0} */
3179 temp = (memval << nr_rhs_bits);
3183 /* GPR{31..32-NR_LHS_BITS = memval{32+NR_LHS_BITS..32} */
3184 temp = (memval >> nr_lhs_bits);
3186 lhs_mask = LSMASK (nr_lhs_bits + nr_rhs_bits - 1, nr_rhs_bits);
3187 rt = (rt & ~lhs_mask) | (temp & lhs_mask);
3189 /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx & 0x%08lx%08lx -> 0x%08lx%08lx\n",
3190 (long) ((unsigned64) memval >> 32), (long) memval,
3191 (long) ((unsigned64) temp >> 32), (long) temp,
3192 (long) ((unsigned64) lhs_mask >> 32), (long) lhs_mask,
3193 (long) (rt >> 32), (long) rt); */
3197 :function:::unsigned_word:do_load_right:unsigned access, address_word base, address_word offset, unsigned_word rt
3199 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
3200 address_word reverseendian = (ReverseEndian ? -1 : 0);
3201 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
3207 paddr = vaddr = loadstore_ea (SD_, base, offset);
3208 /* NOTE: SPEC is wrong, has `BigEndianMem == 0' not `BigEndianMem != 0' */
3209 paddr = (paddr ^ (reverseendian & mask));
3210 if (BigEndianMem != 0)
3211 paddr = paddr & ~access;
3212 byte = ((vaddr & mask) ^ (bigendiancpu & mask));
3213 /* NOTE: SPEC is wrong, had `byte' not `access - byte'. See SW. */
3214 LoadMemory (&memval, NULL, access - (access & byte), paddr, vaddr, isDATA, isREAL);
3215 /* printf ("lr: 0x%08lx %d@0x%08lx 0x%08lx\n",
3216 (long) paddr, byte, (long) paddr, (long) memval); */
3218 unsigned_word screen = LSMASK (8 * (access - (byte & access) + 1) - 1, 0);
3220 rt |= (memval >> (8 * byte)) & screen;
3226 100000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LB
3227 "lb r<RT>, <OFFSET>(r<BASE>)"
3241 do_lb (SD_,RT,OFFSET,BASE);
3245 100100,5.BASE,5.RT,16.OFFSET:NORMAL:32::LBU
3246 "lbu r<RT>, <OFFSET>(r<BASE>)"
3260 do_lbu (SD_, RT,OFFSET,BASE);
3264 110111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LD
3265 "ld r<RT>, <OFFSET>(r<BASE>)"
3274 check_u64 (SD_, instruction_0);
3275 GPR[RT] = EXTEND64 (do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
3279 1101,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDCz
3280 "ldc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
3293 do_ldc (SD_, ZZ, RT, OFFSET, BASE);
3299 011010,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDL
3300 "ldl r<RT>, <OFFSET>(r<BASE>)"
3309 check_u64 (SD_, instruction_0);
3310 GPR[RT] = do_load_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
3314 011011,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDR
3315 "ldr r<RT>, <OFFSET>(r<BASE>)"
3324 check_u64 (SD_, instruction_0);
3325 GPR[RT] = do_load_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
3329 100001,5.BASE,5.RT,16.OFFSET:NORMAL:32::LH
3330 "lh r<RT>, <OFFSET>(r<BASE>)"
3344 do_lh (SD_,RT,OFFSET,BASE);
3348 100101,5.BASE,5.RT,16.OFFSET:NORMAL:32::LHU
3349 "lhu r<RT>, <OFFSET>(r<BASE>)"
3363 do_lhu (SD_,RT,OFFSET,BASE);
3367 110000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LL
3368 "ll r<RT>, <OFFSET>(r<BASE>)"
3380 do_ll (SD_, RT, OFFSET, BASE);
3384 110100,5.BASE,5.RT,16.OFFSET:NORMAL:64::LLD
3385 "lld r<RT>, <OFFSET>(r<BASE>)"
3394 check_u64 (SD_, instruction_0);
3395 do_lld (SD_, RT, OFFSET, BASE);
3399 001111,00000,5.RT,16.IMMEDIATE:NORMAL:32::LUI
3400 "lui r<RT>, %#lx<IMMEDIATE>"
3414 do_lui (SD_, RT, IMMEDIATE);
3418 100011,5.BASE,5.RT,16.OFFSET:NORMAL:32::LW
3419 "lw r<RT>, <OFFSET>(r<BASE>)"
3433 do_lw (SD_,RT,OFFSET,BASE);
3437 1100,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWCz
3438 "lwc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
3452 do_lwc (SD_, ZZ, RT, OFFSET, BASE);
3456 100010,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWL
3457 "lwl r<RT>, <OFFSET>(r<BASE>)"
3471 do_lwl (SD_, RT, OFFSET, BASE);
3475 100110,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWR
3476 "lwr r<RT>, <OFFSET>(r<BASE>)"
3490 do_lwr (SD_, RT, OFFSET, BASE);
3494 100111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LWU
3495 "lwu r<RT>, <OFFSET>(r<BASE>)"
3504 do_lwu (SD_, RT, OFFSET, BASE, instruction_0);
3509 011100,5.RS,5.RT,00000,00000,000000:SPECIAL2:32::MADD
3515 do_madd (SD_, RS, RT);
3519 011100,5.RS,5.RT,000,2.AC,00000,000000:SPECIAL2:32::MADD
3520 "madd r<RS>, r<RT>":AC == 0
3521 "madd ac<AC>, r<RS>, r<RT>"
3526 do_dsp_madd (SD_, AC, RS, RT);
3530 011100,5.RS,5.RT,00000,00000,000001:SPECIAL2:32::MADDU
3531 "maddu r<RS>, r<RT>"
3536 do_maddu (SD_, RS, RT);
3540 011100,5.RS,5.RT,000,2.AC,00000,000001:SPECIAL2:32::MADDU
3541 "maddu r<RS>, r<RT>":AC == 0
3542 "maddu ac<AC>, r<RS>, r<RT>"
3547 do_dsp_maddu (SD_, AC, RS, RT);
3551 :function:::void:do_mfhi:int rd
3553 check_mf_hilo (SD_, HIHISTORY, LOHISTORY);
3554 TRACE_ALU_INPUT1 (HI);
3556 TRACE_ALU_RESULT (GPR[rd]);
3559 000000,0000000000,5.RD,00000,010000:SPECIAL:32::MFHI
3576 000000,000,2.AC,00000,5.RD,00000,010000:SPECIAL:32::MFHI
3577 "mfhi r<RD>":AC == 0
3578 "mfhi r<RD>, ac<AC>"
3583 do_dsp_mfhi (SD_, AC, RD);
3587 :function:::void:do_mflo:int rd
3589 check_mf_hilo (SD_, LOHISTORY, HIHISTORY);
3590 TRACE_ALU_INPUT1 (LO);
3592 TRACE_ALU_RESULT (GPR[rd]);
3595 000000,0000000000,5.RD,00000,010010:SPECIAL:32::MFLO
3612 000000,000,2.AC,00000,5.RD,00000,010010:SPECIAL:32::MFLO
3613 "mflo r<RD>":AC == 0
3614 "mflo r<RD>, ac<AC>"
3619 do_dsp_mflo (SD_, AC, RD);
3623 000000,5.RS,5.RT,5.RD,00000,001011:SPECIAL:32::MOVN
3624 "movn r<RD>, r<RS>, r<RT>"
3633 do_movn (SD_, RD, RS, RT);
3638 000000,5.RS,5.RT,5.RD,00000,001010:SPECIAL:32::MOVZ
3639 "movz r<RD>, r<RS>, r<RT>"
3648 do_movz (SD_, RD, RS, RT);
3653 011100,5.RS,5.RT,00000,00000,000100:SPECIAL2:32::MSUB
3659 do_msub (SD_, RS, RT);
3663 011100,5.RS,5.RT,000,2.AC,00000,000100:SPECIAL2:32::MSUB
3664 "msub r<RS>, r<RT>":AC == 0
3665 "msub ac<AC>, r<RS>, r<RT>"
3670 do_dsp_msub (SD_, AC, RS, RT);
3674 011100,5.RS,5.RT,00000,00000,000101:SPECIAL2:32::MSUBU
3675 "msubu r<RS>, r<RT>"
3680 do_msubu (SD_, RS, RT);
3684 011100,5.RS,5.RT,000,2.AC,00000,000101:SPECIAL2:32::MSUBU
3685 "msubu r<RS>, r<RT>":AC == 0
3686 "msubu ac<AC>, r<RS>, r<RT>"
3691 do_dsp_msubu (SD_, AC, RS, RT);
3695 000000,5.RS,000000000000000,010001:SPECIAL:32::MTHI
3712 000000,5.RS,00000,000,2.AC,00000,010001:SPECIAL:32::MTHI
3713 "mthi r<RS>":AC == 0
3714 "mthi r<RS>, ac<AC>"
3719 do_dsp_mthi (SD_, AC, RS);
3723 000000,5.RS,000000000000000,010011:SPECIAL:32::MTLO
3740 000000,5.RS,00000,000,2.AC,00000,010011:SPECIAL:32::MTLO
3741 "mtlo r<RS>":AC == 0
3742 "mtlo r<RS>, ac<AC>"
3747 do_dsp_mtlo (SD_, AC, RS);
3751 011100,5.RS,5.RT,5.RD,00000,000010:SPECIAL2:32::MUL
3752 "mul r<RD>, r<RS>, r<RT>"
3759 do_mul (SD_, RD, RS, RT);
3764 :function:::void:do_mult:int rs, int rt, int rd
3767 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
3768 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
3770 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3771 prod = (((signed64)(signed32) GPR[rs])
3772 * ((signed64)(signed32) GPR[rt]));
3773 LO = EXTEND32 (VL4_8 (prod));
3774 HI = EXTEND32 (VH4_8 (prod));
3775 ACX = 0; /* SmartMIPS */
3778 TRACE_ALU_RESULT2 (HI, LO);
3781 000000,5.RS,5.RT,0000000000,011000:SPECIAL:32::MULT
3792 do_mult (SD_, RS, RT, 0);
3796 000000,5.RS,5.RT,000,2.AC,00000,011000:SPECIAL:32::MULT
3797 "mult r<RS>, r<RT>":AC == 0
3798 "mult ac<AC>, r<RS>, r<RT>"
3803 do_dsp_mult (SD_, AC, RS, RT);
3807 000000,5.RS,5.RT,5.RD,00000,011000:SPECIAL:32::MULT
3808 "mult r<RS>, r<RT>":RD == 0
3809 "mult r<RD>, r<RS>, r<RT>"
3813 do_mult (SD_, RS, RT, RD);
3817 :function:::void:do_multu:int rs, int rt, int rd
3820 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
3821 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
3823 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3824 prod = (((unsigned64)(unsigned32) GPR[rs])
3825 * ((unsigned64)(unsigned32) GPR[rt]));
3826 LO = EXTEND32 (VL4_8 (prod));
3827 HI = EXTEND32 (VH4_8 (prod));
3830 TRACE_ALU_RESULT2 (HI, LO);
3833 000000,5.RS,5.RT,0000000000,011001:SPECIAL:32::MULTU
3834 "multu r<RS>, r<RT>"
3844 do_multu (SD_, RS, RT, 0);
3848 000000,5.RS,5.RT,000,2.AC,00000,011001:SPECIAL:32::MULTU
3849 "multu r<RS>, r<RT>":AC == 0
3850 "multu r<RS>, r<RT>"
3855 do_dsp_multu (SD_, AC, RS, RT);
3859 000000,5.RS,5.RT,5.RD,00000,011001:SPECIAL:32::MULTU
3860 "multu r<RS>, r<RT>":RD == 0
3861 "multu r<RD>, r<RS>, r<RT>"
3865 do_multu (SD_, RS, RT, RD);
3869 :function:::void:do_nor:int rs, int rt, int rd
3871 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3872 GPR[rd] = ~ (GPR[rs] | GPR[rt]);
3873 TRACE_ALU_RESULT (GPR[rd]);
3876 000000,5.RS,5.RT,5.RD,00000,100111:SPECIAL:32::NOR
3877 "nor r<RD>, r<RS>, r<RT>"
3891 do_nor (SD_, RS, RT, RD);
3895 :function:::void:do_or:int rs, int rt, int rd
3897 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3898 GPR[rd] = (GPR[rs] | GPR[rt]);
3899 TRACE_ALU_RESULT (GPR[rd]);
3902 000000,5.RS,5.RT,5.RD,00000,100101:SPECIAL:32::OR
3903 "or r<RD>, r<RS>, r<RT>"
3917 do_or (SD_, RS, RT, RD);
3922 :function:::void:do_ori:int rs, int rt, unsigned immediate
3924 TRACE_ALU_INPUT2 (GPR[rs], immediate);
3925 GPR[rt] = (GPR[rs] | immediate);
3926 TRACE_ALU_RESULT (GPR[rt]);
3929 001101,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ORI
3930 "ori r<RT>, r<RS>, %#lx<IMMEDIATE>"
3944 do_ori (SD_, RS, RT, IMMEDIATE);
3948 110011,5.BASE,5.HINT,16.OFFSET:NORMAL:32::PREF
3949 "pref <HINT>, <OFFSET>(r<BASE>)"
3958 do_pref (SD_, HINT, OFFSET, BASE);
3962 :function:::unsigned64:do_ror:unsigned32 x,unsigned32 y
3967 TRACE_ALU_INPUT2 (x, y);
3968 result = EXTEND32 (ROTR32 (x, y));
3969 TRACE_ALU_RESULT (result);
3973 000000,00001,5.RT,5.RD,5.SHIFT,000010::32::ROR
3974 "ror r<RD>, r<RT>, <SHIFT>"
3981 GPR[RD] = do_ror (SD_, GPR[RT], SHIFT);
3984 000000,5.RS,5.RT,5.RD,00001,000110::32::RORV
3985 "rorv r<RD>, r<RT>, r<RS>"
3992 GPR[RD] = do_ror (SD_, GPR[RT], GPR[RS]);
3996 :function:::void:do_store:unsigned access, address_word base, address_word offset, unsigned_word word
3998 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
3999 address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
4000 address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
4006 paddr = vaddr = loadstore_ea (SD_, base, offset);
4007 if ((vaddr & access) != 0)
4009 SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map, access+1, vaddr, write_transfer, sim_core_unaligned_signal);
4011 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
4012 byte = ((vaddr & mask) ^ bigendiancpu);
4013 memval = (word << (8 * byte));
4014 StoreMemory (access, memval, 0, paddr, vaddr, isREAL);
4017 :function:::void:do_store_left:unsigned access, address_word base, address_word offset, unsigned_word rt
4019 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
4020 address_word reverseendian = (ReverseEndian ? -1 : 0);
4021 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
4030 paddr = vaddr = loadstore_ea (SD_, base, offset);
4031 paddr = (paddr ^ (reverseendian & mask));
4032 if (BigEndianMem == 0)
4033 paddr = paddr & ~access;
4035 /* compute where within the word/mem we are */
4036 byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
4037 word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
4038 nr_lhs_bits = 8 * byte + 8;
4039 nr_rhs_bits = 8 * access - 8 * byte;
4040 /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
4041 /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
4042 (long) ((unsigned64) vaddr >> 32), (long) vaddr,
4043 (long) ((unsigned64) paddr >> 32), (long) paddr,
4044 word, byte, nr_lhs_bits, nr_rhs_bits); */
4048 memval = (rt >> nr_rhs_bits);
4052 memval = (rt << nr_lhs_bits);
4054 /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx\n",
4055 (long) ((unsigned64) rt >> 32), (long) rt,
4056 (long) ((unsigned64) memval >> 32), (long) memval); */
4057 StoreMemory (byte, memval, 0, paddr, vaddr, isREAL);
4060 :function:::void:do_store_right:unsigned access, address_word base, address_word offset, unsigned_word rt
4062 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
4063 address_word reverseendian = (ReverseEndian ? -1 : 0);
4064 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
4070 paddr = vaddr = loadstore_ea (SD_, base, offset);
4071 paddr = (paddr ^ (reverseendian & mask));
4072 if (BigEndianMem != 0)
4074 byte = ((vaddr & mask) ^ (bigendiancpu & mask));
4075 memval = (rt << (byte * 8));
4076 StoreMemory (access - (access & byte), memval, 0, paddr, vaddr, isREAL);
4080 101000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SB
4081 "sb r<RT>, <OFFSET>(r<BASE>)"
4095 do_store (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4099 111000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SC
4100 "sc r<RT>, <OFFSET>(r<BASE>)"
4112 do_sc (SD_, RT, OFFSET, BASE, instruction_0);
4116 111100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SCD
4117 "scd r<RT>, <OFFSET>(r<BASE>)"
4126 check_u64 (SD_, instruction_0);
4127 do_scd (SD_, RT, OFFSET, BASE);
4131 111111,5.BASE,5.RT,16.OFFSET:NORMAL:64::SD
4132 "sd r<RT>, <OFFSET>(r<BASE>)"
4141 check_u64 (SD_, instruction_0);
4142 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4146 1111,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDCz
4147 "sdc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
4159 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (ZZ, RT));
4163 101100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDL
4164 "sdl r<RT>, <OFFSET>(r<BASE>)"
4173 check_u64 (SD_, instruction_0);
4174 do_store_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4178 101101,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDR
4179 "sdr r<RT>, <OFFSET>(r<BASE>)"
4188 check_u64 (SD_, instruction_0);
4189 do_store_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4194 101001,5.BASE,5.RT,16.OFFSET:NORMAL:32::SH
4195 "sh r<RT>, <OFFSET>(r<BASE>)"
4209 do_store (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4213 :function:::void:do_sll:int rt, int rd, int shift
4215 unsigned32 temp = (GPR[rt] << shift);
4216 TRACE_ALU_INPUT2 (GPR[rt], shift);
4217 GPR[rd] = EXTEND32 (temp);
4218 TRACE_ALU_RESULT (GPR[rd]);
4221 000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLLa
4222 "nop":RD == 0 && RT == 0 && SHIFT == 0
4223 "sll r<RD>, r<RT>, <SHIFT>"
4233 /* Skip shift for NOP, so that there won't be lots of extraneous
4235 if (RD != 0 || RT != 0 || SHIFT != 0)
4236 do_sll (SD_, RT, RD, SHIFT);
4239 000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLLb
4240 "nop":RD == 0 && RT == 0 && SHIFT == 0
4241 "ssnop":RD == 0 && RT == 0 && SHIFT == 1
4242 "sll r<RD>, r<RT>, <SHIFT>"
4248 /* Skip shift for NOP and SSNOP, so that there won't be lots of
4249 extraneous trace output. */
4250 if (RD != 0 || RT != 0 || (SHIFT != 0 && SHIFT != 1))
4251 do_sll (SD_, RT, RD, SHIFT);
4255 :function:::void:do_sllv:int rs, int rt, int rd
4257 int s = MASKED (GPR[rs], 4, 0);
4258 unsigned32 temp = (GPR[rt] << s);
4259 TRACE_ALU_INPUT2 (GPR[rt], s);
4260 GPR[rd] = EXTEND32 (temp);
4261 TRACE_ALU_RESULT (GPR[rd]);
4264 000000,5.RS,5.RT,5.RD,00000,000100:SPECIAL:32::SLLV
4265 "sllv r<RD>, r<RT>, r<RS>"
4279 do_sllv (SD_, RS, RT, RD);
4283 :function:::void:do_slt:int rs, int rt, int rd
4285 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
4286 GPR[rd] = ((signed_word) GPR[rs] < (signed_word) GPR[rt]);
4287 TRACE_ALU_RESULT (GPR[rd]);
4290 000000,5.RS,5.RT,5.RD,00000,101010:SPECIAL:32::SLT
4291 "slt r<RD>, r<RS>, r<RT>"
4305 do_slt (SD_, RS, RT, RD);
4309 :function:::void:do_slti:int rs, int rt, unsigned16 immediate
4311 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
4312 GPR[rt] = ((signed_word) GPR[rs] < (signed_word) EXTEND16 (immediate));
4313 TRACE_ALU_RESULT (GPR[rt]);
4316 001010,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTI
4317 "slti r<RT>, r<RS>, <IMMEDIATE>"
4331 do_slti (SD_, RS, RT, IMMEDIATE);
4335 :function:::void:do_sltiu:int rs, int rt, unsigned16 immediate
4337 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
4338 GPR[rt] = ((unsigned_word) GPR[rs] < (unsigned_word) EXTEND16 (immediate));
4339 TRACE_ALU_RESULT (GPR[rt]);
4342 001011,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTIU
4343 "sltiu r<RT>, r<RS>, <IMMEDIATE>"
4357 do_sltiu (SD_, RS, RT, IMMEDIATE);
4362 :function:::void:do_sltu:int rs, int rt, int rd
4364 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
4365 GPR[rd] = ((unsigned_word) GPR[rs] < (unsigned_word) GPR[rt]);
4366 TRACE_ALU_RESULT (GPR[rd]);
4369 000000,5.RS,5.RT,5.RD,00000,101011:SPECIAL:32::SLTU
4370 "sltu r<RD>, r<RS>, r<RT>"
4384 do_sltu (SD_, RS, RT, RD);
4388 :function:::void:do_sra:int rt, int rd, int shift
4390 signed32 temp = (signed32) GPR[rt] >> shift;
4391 if (NotWordValue (GPR[rt]))
4393 TRACE_ALU_INPUT2 (GPR[rt], shift);
4394 GPR[rd] = EXTEND32 (temp);
4395 TRACE_ALU_RESULT (GPR[rd]);
4398 000000,00000,5.RT,5.RD,5.SHIFT,000011:SPECIAL:32::SRA
4399 "sra r<RD>, r<RT>, <SHIFT>"
4413 do_sra (SD_, RT, RD, SHIFT);
4418 :function:::void:do_srav:int rs, int rt, int rd
4420 int s = MASKED (GPR[rs], 4, 0);
4421 signed32 temp = (signed32) GPR[rt] >> s;
4422 if (NotWordValue (GPR[rt]))
4424 TRACE_ALU_INPUT2 (GPR[rt], s);
4425 GPR[rd] = EXTEND32 (temp);
4426 TRACE_ALU_RESULT (GPR[rd]);
4429 000000,5.RS,5.RT,5.RD,00000,000111:SPECIAL:32::SRAV
4430 "srav r<RD>, r<RT>, r<RS>"
4444 do_srav (SD_, RS, RT, RD);
4449 :function:::void:do_srl:int rt, int rd, int shift
4451 unsigned32 temp = (unsigned32) GPR[rt] >> shift;
4452 if (NotWordValue (GPR[rt]))
4454 TRACE_ALU_INPUT2 (GPR[rt], shift);
4455 GPR[rd] = EXTEND32 (temp);
4456 TRACE_ALU_RESULT (GPR[rd]);
4459 000000,00000,5.RT,5.RD,5.SHIFT,000010:SPECIAL:32::SRL
4460 "srl r<RD>, r<RT>, <SHIFT>"
4474 do_srl (SD_, RT, RD, SHIFT);
4478 :function:::void:do_srlv:int rs, int rt, int rd
4480 int s = MASKED (GPR[rs], 4, 0);
4481 unsigned32 temp = (unsigned32) GPR[rt] >> s;
4482 if (NotWordValue (GPR[rt]))
4484 TRACE_ALU_INPUT2 (GPR[rt], s);
4485 GPR[rd] = EXTEND32 (temp);
4486 TRACE_ALU_RESULT (GPR[rd]);
4489 000000,5.RS,5.RT,5.RD,00000,000110:SPECIAL:32::SRLV
4490 "srlv r<RD>, r<RT>, r<RS>"
4504 do_srlv (SD_, RS, RT, RD);
4508 000000,5.RS,5.RT,5.RD,00000,100010:SPECIAL:32::SUB
4509 "sub r<RD>, r<RS>, r<RT>"
4523 do_sub (SD_, RD, RS, RT);
4527 :function:::void:do_subu:int rs, int rt, int rd
4529 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
4531 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
4532 GPR[rd] = EXTEND32 (GPR[rs] - GPR[rt]);
4533 TRACE_ALU_RESULT (GPR[rd]);
4536 000000,5.RS,5.RT,5.RD,00000,100011:SPECIAL:32::SUBU
4537 "subu r<RD>, r<RS>, r<RT>"
4551 do_subu (SD_, RS, RT, RD);
4555 101011,5.BASE,5.RT,16.OFFSET:NORMAL:32::SW
4556 "sw r<RT>, <OFFSET>(r<BASE>)"
4570 do_sw (SD_, RT, OFFSET, BASE);
4574 1110,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWCz
4575 "swc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
4589 do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), COP_SW (ZZ, RT));
4593 101010,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWL
4594 "swl r<RT>, <OFFSET>(r<BASE>)"
4608 do_store_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4612 101110,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWR
4613 "swr r<RT>, <OFFSET>(r<BASE>)"
4627 do_store_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4631 000000,000000000000000,5.STYPE,001111:SPECIAL:32::SYNC
4646 SyncOperation (STYPE);
4650 000000,20.CODE,001100:SPECIAL:32::SYSCALL
4651 "syscall %#lx<CODE>"
4665 SignalException (SystemCall, instruction_0);
4669 000000,5.RS,5.RT,10.CODE,110100:SPECIAL:32::TEQ
4682 do_teq (SD_, RS, RT, instruction_0);
4686 000001,5.RS,01100,16.IMMEDIATE:REGIMM:32::TEQI
4687 "teqi r<RS>, <IMMEDIATE>"
4699 do_teqi (SD_, RS, IMMEDIATE, instruction_0);
4703 000000,5.RS,5.RT,10.CODE,110000:SPECIAL:32::TGE
4716 do_tge (SD_, RS, RT, instruction_0);
4720 000001,5.RS,01000,16.IMMEDIATE:REGIMM:32::TGEI
4721 "tgei r<RS>, <IMMEDIATE>"
4733 do_tgei (SD_, RS, IMMEDIATE, instruction_0);
4737 000001,5.RS,01001,16.IMMEDIATE:REGIMM:32::TGEIU
4738 "tgeiu r<RS>, <IMMEDIATE>"
4750 do_tgeiu (SD_, RS, IMMEDIATE, instruction_0);
4754 000000,5.RS,5.RT,10.CODE,110001:SPECIAL:32::TGEU
4767 do_tgeu (SD_, RS, RT, instruction_0);
4771 000000,5.RS,5.RT,10.CODE,110010:SPECIAL:32::TLT
4784 do_tlt (SD_, RS, RT, instruction_0);
4788 000001,5.RS,01010,16.IMMEDIATE:REGIMM:32::TLTI
4789 "tlti r<RS>, <IMMEDIATE>"
4801 do_tlti (SD_, RS, IMMEDIATE, instruction_0);
4805 000001,5.RS,01011,16.IMMEDIATE:REGIMM:32::TLTIU
4806 "tltiu r<RS>, <IMMEDIATE>"
4818 do_tltiu (SD_, RS, IMMEDIATE, instruction_0);
4822 000000,5.RS,5.RT,10.CODE,110011:SPECIAL:32::TLTU
4835 do_tltu (SD_, RS, RT, instruction_0);
4839 000000,5.RS,5.RT,10.CODE,110110:SPECIAL:32::TNE
4852 do_tne (SD_, RS, RT, instruction_0);
4856 000001,5.RS,01110,16.IMMEDIATE:REGIMM:32::TNEI
4857 "tnei r<RS>, <IMMEDIATE>"
4869 do_tnei (SD_, RS, IMMEDIATE, instruction_0);
4873 :function:::void:do_xor:int rs, int rt, int rd
4875 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
4876 GPR[rd] = GPR[rs] ^ GPR[rt];
4877 TRACE_ALU_RESULT (GPR[rd]);
4880 000000,5.RS,5.RT,5.RD,00000,100110:SPECIAL:32::XOR
4881 "xor r<RD>, r<RS>, r<RT>"
4895 do_xor (SD_, RS, RT, RD);
4899 :function:::void:do_xori:int rs, int rt, unsigned16 immediate
4901 TRACE_ALU_INPUT2 (GPR[rs], immediate);
4902 GPR[rt] = GPR[rs] ^ immediate;
4903 TRACE_ALU_RESULT (GPR[rt]);
4906 001110,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::XORI
4907 "xori r<RT>, r<RS>, %#lx<IMMEDIATE>"
4921 do_xori (SD_, RS, RT, IMMEDIATE);
4926 // MIPS Architecture:
4928 // FPU Instruction Set (COP1 & COP1X)
4936 case fmt_single: return "s";
4937 case fmt_double: return "d";
4938 case fmt_word: return "w";
4939 case fmt_long: return "l";
4940 case fmt_ps: return "ps";
4941 default: return "?";
4961 :%s::::COND:int cond
4965 case 00: return "f";
4966 case 01: return "un";
4967 case 02: return "eq";
4968 case 03: return "ueq";
4969 case 04: return "olt";
4970 case 05: return "ult";
4971 case 06: return "ole";
4972 case 07: return "ule";
4973 case 010: return "sf";
4974 case 011: return "ngle";
4975 case 012: return "seq";
4976 case 013: return "ngl";
4977 case 014: return "lt";
4978 case 015: return "nge";
4979 case 016: return "le";
4980 case 017: return "ngt";
4981 default: return "?";
4988 // Check that the given FPU format is usable, and signal a
4989 // ReservedInstruction exception if not.
4992 // check_fmt_p checks that the format is single, double, or paired single.
4993 :function:::void:check_fmt_p:int fmt, instruction_word insn
5003 /* None of these ISAs support Paired Single, so just fall back to
5004 the single/double check. */
5005 if ((fmt != fmt_single) && (fmt != fmt_double))
5006 SignalException (ReservedInstruction, insn);
5009 :function:::void:check_fmt_p:int fmt, instruction_word insn
5013 if ((fmt != fmt_single) && (fmt != fmt_double) && (fmt != fmt_ps))
5014 SignalException (ReservedInstruction, insn);
5017 :function:::void:check_fmt_p:int fmt, instruction_word insn
5023 if ((fmt != fmt_single) && (fmt != fmt_double)
5024 && (fmt != fmt_ps || (UserMode && (SR & (status_UX|status_PX)) == 0)))
5025 SignalException (ReservedInstruction, insn);
5031 // Check that the FPU is currently usable, and signal a CoProcessorUnusable
5032 // exception if not.
5035 :function:::void:check_fpu:
5051 if (! COP_Usable (1))
5052 SignalExceptionCoProcessorUnusable (1);
5058 // Load a double word FP value using 2 32-bit memory cycles a la MIPS II
5059 // or MIPS32. do_load cannot be used instead because it returns an
5060 // unsigned_word, which is limited to the size of the machine's registers.
5063 :function:::unsigned64:do_load_double:address_word base, address_word offset
5069 int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
5075 paddr = vaddr = loadstore_ea (SD_, base, offset);
5076 if ((vaddr & AccessLength_DOUBLEWORD) != 0)
5078 SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map,
5079 AccessLength_DOUBLEWORD + 1, vaddr, read_transfer,
5080 sim_core_unaligned_signal);
5082 LoadMemory (&memval, NULL, AccessLength_WORD, paddr, vaddr, isDATA, isREAL);
5083 v = (unsigned64)memval;
5084 LoadMemory (&memval, NULL, AccessLength_WORD, paddr + 4, vaddr + 4, isDATA,
5086 return (bigendian ? ((v << 32) | memval) : (v | (memval << 32)));
5092 // Store a double word FP value using 2 32-bit memory cycles a la MIPS II
5093 // or MIPS32. do_load cannot be used instead because it returns an
5094 // unsigned_word, which is limited to the size of the machine's registers.
5097 :function:::void:do_store_double:address_word base, address_word offset, unsigned64 v
5103 int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
5108 paddr = vaddr = loadstore_ea (SD_, base, offset);
5109 if ((vaddr & AccessLength_DOUBLEWORD) != 0)
5111 SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map,
5112 AccessLength_DOUBLEWORD + 1, vaddr, write_transfer,
5113 sim_core_unaligned_signal);
5115 memval = (bigendian ? (v >> 32) : (v & 0xFFFFFFFF));
5116 StoreMemory (AccessLength_WORD, memval, 0, paddr, vaddr, isREAL);
5117 memval = (bigendian ? (v & 0xFFFFFFFF) : (v >> 32));
5118 StoreMemory (AccessLength_WORD, memval, 0, paddr + 4, vaddr + 4, isREAL);
5122 010001,10,3.FMT!2!3!4!5!7,00000,5.FS,5.FD,000101:COP1:32,f::ABS.fmt
5123 "abs.%s<FMT> f<FD>, f<FS>"
5137 do_abs_fmt (SD_, FMT, FD, FS, instruction_0);
5142 010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,5.FD,000000:COP1:32,f::ADD.fmt
5143 "add.%s<FMT> f<FD>, f<FS>, f<FT>"
5157 do_add_fmt (SD_, FMT, FD, FS, FT, instruction_0);
5161 010011,5.RS,5.FT,5.FS,5.FD,011,110:COP1X:32,f::ALNV.PS
5162 "alnv.ps f<FD>, f<FS>, f<FT>, r<RS>"
5168 do_alnv_ps (SD_, FD, FS, FT, RS, instruction_0);
5177 010001,01000,3.0,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1a
5178 "bc1%s<TF>%s<ND> <OFFSET>"
5184 TRACE_BRANCH_INPUT (PREVCOC1());
5185 if (PREVCOC1() == TF)
5187 address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
5188 TRACE_BRANCH_RESULT (dest);
5193 TRACE_BRANCH_RESULT (0);
5194 NULLIFY_NEXT_INSTRUCTION ();
5198 TRACE_BRANCH_RESULT (NIA);
5202 010001,01000,3.CC,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1b
5203 "bc1%s<TF>%s<ND> <OFFSET>":CC == 0
5204 "bc1%s<TF>%s<ND> <CC>, <OFFSET>"
5216 if (GETFCC(CC) == TF)
5218 address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
5223 NULLIFY_NEXT_INSTRUCTION ();
5228 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
5229 "c.%s<COND>.%s<FMT> f<FS>, f<FT>"
5236 Compare (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt, COND, 0);
5237 TRACE_ALU_RESULT (ValueFCR (31));
5240 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
5241 "c.%s<COND>.%s<FMT> f<FS>, f<FT>":CC == 0
5242 "c.%s<COND>.%s<FMT> <CC>, f<FS>, f<FT>"
5253 do_c_cond_fmt (SD_, COND, FMT, CC, FS, FT, instruction_0);
5257 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001010:COP1:32,f::CEIL.L.fmt
5258 "ceil.l.%s<FMT> f<FD>, f<FS>"
5269 do_ceil_fmt (SD_, fmt_long, FMT, FD, FS, instruction_0);
5273 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001110:COP1:32,f::CEIL.W
5274 "ceil.w.%s<FMT> f<FD>, f<FS>"
5287 do_ceil_fmt (SD_, fmt_word, FMT, FD, FS, instruction_0);
5291 010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1a
5299 PENDING_FILL (RT, EXTEND32 (FCR0));
5301 PENDING_FILL (RT, EXTEND32 (FCR31));
5305 010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1b
5313 if (FS == 0 || FS == 31)
5315 unsigned_word fcr = ValueFCR (FS);
5316 TRACE_ALU_INPUT1 (fcr);
5320 TRACE_ALU_RESULT (GPR[RT]);
5323 010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1c
5331 do_cfc1 (SD_, RT, FS);
5334 010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1a
5342 PENDING_FILL (FCRCS_REGNUM, VL4_8 (GPR[RT]));
5346 010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1b
5354 TRACE_ALU_INPUT1 (GPR[RT]);
5356 StoreFCR (FS, GPR[RT]);
5360 010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1c
5368 do_ctc1 (SD_, RT, FS);
5373 // FIXME: Does not correctly differentiate between mips*
5375 010001,10,3.FMT!1!2!3!6!7,00000,5.FS,5.FD,100001:COP1:32,f::CVT.D.fmt
5376 "cvt.d.%s<FMT> f<FD>, f<FS>"
5390 do_cvt_d_fmt (SD_, FMT, FD, FS, instruction_0);
5394 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,100101:COP1:32,f::CVT.L.fmt
5395 "cvt.l.%s<FMT> f<FD>, f<FS>"
5406 do_cvt_l_fmt (SD_, FMT, FD, FS, instruction_0);
5410 010001,10,000,5.FT,5.FS,5.FD,100110:COP1:32,f::CVT.PS.S
5411 "cvt.ps.s f<FD>, f<FS>, f<FT>"
5417 do_cvt_ps_s (SD_, FD, FS, FT, instruction_0);
5422 // FIXME: Does not correctly differentiate between mips*
5424 010001,10,3.FMT!0!2!3!6!7,00000,5.FS,5.FD,100000:COP1:32,f::CVT.S.fmt
5425 "cvt.s.%s<FMT> f<FD>, f<FS>"
5439 do_cvt_s_fmt (SD_, FMT, FD, FS, instruction_0);
5443 010001,10,110,00000,5.FS,5.FD,101000:COP1:32,f::CVT.S.PL
5444 "cvt.s.pl f<FD>, f<FS>"
5450 do_cvt_s_pl (SD_, FD, FS, instruction_0);
5454 010001,10,110,00000,5.FS,5.FD,100000:COP1:32,f::CVT.S.PU
5455 "cvt.s.pu f<FD>, f<FS>"
5461 do_cvt_s_pu (SD_, FD, FS, instruction_0);
5465 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,100100:COP1:32,f::CVT.W.fmt
5466 "cvt.w.%s<FMT> f<FD>, f<FS>"
5480 do_cvt_w_fmt (SD_, FMT, FD, FS, instruction_0);
5484 010001,10,3.FMT!2!3!4!5!6!7,5.FT,5.FS,5.FD,000011:COP1:32,f::DIV.fmt
5485 "div.%s<FMT> f<FD>, f<FS>, f<FT>"
5499 do_div_fmt (SD_, FMT, FD, FS, FT, instruction_0);
5503 010001,00001,5.RT,5.FS,00000000000:COP1:64,f::DMFC1a
5504 "dmfc1 r<RT>, f<FS>"
5509 check_u64 (SD_, instruction_0);
5510 if (SizeFGR () == 64)
5512 else if ((FS & 0x1) == 0)
5513 v = SET64HI (FGR[FS+1]) | FGR[FS];
5515 v = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
5516 PENDING_FILL (RT, v);
5517 TRACE_ALU_RESULT (v);
5520 010001,00001,5.RT,5.FS,00000000000:COP1:64,f::DMFC1b
5521 "dmfc1 r<RT>, f<FS>"
5531 check_u64 (SD_, instruction_0);
5532 do_dmfc1b (SD_, RT, FS);
5536 010001,00101,5.RT,5.FS,00000000000:COP1:64,f::DMTC1a
5537 "dmtc1 r<RT>, f<FS>"
5542 check_u64 (SD_, instruction_0);
5543 if (SizeFGR () == 64)
5544 PENDING_FILL ((FS + FGR_BASE), GPR[RT]);
5545 else if ((FS & 0x1) == 0)
5547 PENDING_FILL (((FS + 1) + FGR_BASE), VH4_8 (GPR[RT]));
5548 PENDING_FILL ((FS + FGR_BASE), VL4_8 (GPR[RT]));
5552 TRACE_FP_RESULT (GPR[RT]);
5555 010001,00101,5.RT,5.FS,00000000000:COP1:64,f::DMTC1b
5556 "dmtc1 r<RT>, f<FS>"
5566 check_u64 (SD_, instruction_0);
5567 do_dmtc1b (SD_, RT, FS);
5571 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001011:COP1:32,f::FLOOR.L.fmt
5572 "floor.l.%s<FMT> f<FD>, f<FS>"
5583 do_floor_fmt (SD_, fmt_long, FMT, FD, FS);
5587 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001111:COP1:32,f::FLOOR.W.fmt
5588 "floor.w.%s<FMT> f<FD>, f<FS>"
5601 do_floor_fmt (SD_, fmt_word, FMT, FD, FS);
5605 110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1a
5606 "ldc1 f<FT>, <OFFSET>(r<BASE>)"
5612 COP_LD (1, FT, do_load_double (SD_, GPR[BASE], EXTEND16 (OFFSET)));
5616 110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1b
5617 "ldc1 f<FT>, <OFFSET>(r<BASE>)"
5628 COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
5632 010011,5.BASE,5.INDEX,5.0,5.FD,000001:COP1X:32,f::LDXC1
5633 "ldxc1 f<FD>, r<INDEX>(r<BASE>)"
5637 COP_LD (1, FD, do_load_double (SD_, GPR[BASE], GPR[INDEX]));
5641 010011,5.BASE,5.INDEX,5.0,5.FD,000001:COP1X:64,f::LDXC1
5642 "ldxc1 f<FD>, r<INDEX>(r<BASE>)"
5650 check_u64 (SD_, instruction_0);
5651 COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX]));
5655 010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:32,f::LUXC1
5656 "luxc1 f<FD>, r<INDEX>(r<BASE>)"
5659 do_luxc1_32 (SD_, FD, INDEX, BASE);
5663 010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:64,f::LUXC1
5664 "luxc1 f<FD>, r<INDEX>(r<BASE>)"
5670 check_u64 (SD_, instruction_0);
5671 do_luxc1_64 (SD_, FD, INDEX, BASE);
5675 110001,5.BASE,5.FT,16.OFFSET:COP1:32,f::LWC1
5676 "lwc1 f<FT>, <OFFSET>(r<BASE>)"
5690 do_lwc1 (SD_, FT, OFFSET, BASE);
5694 010011,5.BASE,5.INDEX,5.0,5.FD,000000:COP1X:32,f::LWXC1
5695 "lwxc1 f<FD>, r<INDEX>(r<BASE>)"
5703 do_lwxc1 (SD_, FD, INDEX, BASE, instruction_0);
5708 010011,5.FR,5.FT,5.FS,5.FD,100,3.FMT!2!3!4!5!7:COP1X:32,f::MADD.fmt
5709 "madd.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
5717 do_madd_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
5721 010001,00000,5.RT,5.FS,00000000000:COP1:32,f::MFC1a
5729 v = EXTEND32 (FGR[FS]);
5730 PENDING_FILL (RT, v);
5731 TRACE_ALU_RESULT (v);
5734 010001,00000,5.RT,5.FS,00000000000:COP1:32,f::MFC1b
5746 do_mfc1b (SD_, RT, FS);
5750 010001,10,3.FMT!2!3!4!5!7,00000,5.FS,5.FD,000110:COP1:32,f::MOV.fmt
5751 "mov.%s<FMT> f<FD>, f<FS>"
5765 do_mov_fmt (SD_, FMT, FD, FS, instruction_0);
5771 000000,5.RS,3.CC,0,1.TF,5.RD,00000,000001:SPECIAL:32,f::MOVtf
5772 "mov%s<TF> r<RD>, r<RS>, <CC>"
5781 do_movtf (SD_, TF, RD, RS, CC);
5787 010001,10,3.FMT!2!3!4!5!7,3.CC,0,1.TF,5.FS,5.FD,010001:COP1:32,f::MOVtf.fmt
5788 "mov%s<TF>.%s<FMT> f<FD>, f<FS>, <CC>"
5797 do_movtf_fmt (SD_, TF, FMT, FD, FS, CC);
5801 010001,10,3.FMT!2!3!4!5!7,5.RT,5.FS,5.FD,010011:COP1:32,f::MOVN.fmt
5802 "movn.%s<FMT> f<FD>, f<FS>, r<RT>"
5811 do_movn_fmt (SD_, FMT, FD, FS, RT);
5818 // MOVT.fmt see MOVtf.fmt
5822 010001,10,3.FMT!2!3!4!5!7,5.RT,5.FS,5.FD,010010:COP1:32,f::MOVZ.fmt
5823 "movz.%s<FMT> f<FD>, f<FS>, r<RT>"
5832 do_movz_fmt (SD_, FMT, FD, FS, RT);
5836 010011,5.FR,5.FT,5.FS,5.FD,101,3.FMT!2!3!4!5!7:COP1X:32,f::MSUB.fmt
5837 "msub.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
5845 do_msub_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
5849 010001,00100,5.RT,5.FS,00000000000:COP1:32,f::MTC1a
5856 if (SizeFGR () == 64)
5857 PENDING_FILL ((FS + FGR_BASE), (SET64HI (0xDEADC0DE) | VL4_8 (GPR[RT])));
5859 PENDING_FILL ((FS + FGR_BASE), VL4_8 (GPR[RT]));
5860 TRACE_FP_RESULT (GPR[RT]);
5863 010001,00100,5.RT,5.FS,00000000000:COP1:32,f::MTC1b
5875 do_mtc1b (SD_, RT, FS);
5879 010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,5.FD,000010:COP1:32,f::MUL.fmt
5880 "mul.%s<FMT> f<FD>, f<FS>, f<FT>"
5894 do_mul_fmt (SD_, FMT, FD, FS, FT, instruction_0);
5898 010001,10,3.FMT!2!3!4!5!7,00000,5.FS,5.FD,000111:COP1:32,f::NEG.fmt
5899 "neg.%s<FMT> f<FD>, f<FS>"
5913 do_neg_fmt (SD_, FMT, FD, FS, instruction_0);
5917 010011,5.FR,5.FT,5.FS,5.FD,110,3.FMT!2!3!4!5!7:COP1X:32,f::NMADD.fmt
5918 "nmadd.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
5926 do_nmadd_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
5930 010011,5.FR,5.FT,5.FS,5.FD,111,3.FMT!2!3!4!5!7:COP1X:32,f::NMSUB.fmt
5931 "nmsub.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
5939 do_nmsub_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
5943 010001,10,110,5.FT,5.FS,5.FD,101100:COP1:32,f::PLL.PS
5944 "pll.ps f<FD>, f<FS>, f<FT>"
5950 do_pll_ps (SD_, FD, FS, FT, instruction_0);
5954 010001,10,110,5.FT,5.FS,5.FD,101101:COP1:32,f::PLU.PS
5955 "plu.ps f<FD>, f<FS>, f<FT>"
5961 do_plu_ps (SD_, FD, FS, FT, instruction_0);
5965 010011,5.BASE,5.INDEX,5.HINT,00000,001111:COP1X:32::PREFX
5966 "prefx <HINT>, r<INDEX>(r<BASE>)"
5974 do_prefx (SD_, HINT, INDEX, BASE);
5978 010001,10,110,5.FT,5.FS,5.FD,101110:COP1:32,f::PUL.PS
5979 "pul.ps f<FD>, f<FS>, f<FT>"
5985 do_pul_ps (SD_, FD, FS, FT, instruction_0);
5989 010001,10,110,5.FT,5.FS,5.FD,101111:COP1:32,f::PUU.PS
5990 "puu.ps f<FD>, f<FS>, f<FT>"
5996 do_puu_ps (SD_, FD, FS, FT, instruction_0);
6000 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,010101:COP1:32,f::RECIP.fmt
6001 "recip.%s<FMT> f<FD>, f<FS>"
6009 do_recip_fmt (SD_, FMT, FD, FS);
6013 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001000:COP1:32,f::ROUND.L.fmt
6014 "round.l.%s<FMT> f<FD>, f<FS>"
6025 do_round_fmt (SD_, fmt_long, FMT, FD, FS);
6029 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001100:COP1:32,f::ROUND.W.fmt
6030 "round.w.%s<FMT> f<FD>, f<FS>"
6043 do_round_fmt (SD_, fmt_word, FMT, FD, FS);
6047 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,010110:COP1:32,f::RSQRT.fmt
6048 "rsqrt.%s<FMT> f<FD>, f<FS>"
6056 do_rsqrt_fmt (SD_, FMT, FD, FS);
6060 111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1a
6061 "sdc1 f<FT>, <OFFSET>(r<BASE>)"
6066 do_sdc1 (SD_, FT, OFFSET, BASE);
6070 111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1b
6071 "sdc1 f<FT>, <OFFSET>(r<BASE>)"
6082 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT));
6086 010011,5.BASE,5.INDEX,5.FS,00000001001:COP1X:32,f::SDXC1
6087 "sdxc1 f<FS>, r<INDEX>(r<BASE>)"
6091 do_store_double (SD_, GPR[BASE], GPR[INDEX], COP_SD (1, FS));
6095 010011,5.BASE,5.INDEX,5.FS,00000001001:COP1X:64,f::SDXC1
6096 "sdxc1 f<FS>, r<INDEX>(r<BASE>)"
6104 check_u64 (SD_, instruction_0);
6105 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX], COP_SD (1, FS));
6109 010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:32,f::SUXC1
6110 "suxc1 f<FS>, r<INDEX>(r<BASE>)"
6113 do_suxc1_32 (SD_, FS, INDEX, BASE);
6117 010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:64,f::SUXC1
6118 "suxc1 f<FS>, r<INDEX>(r<BASE>)"
6124 check_u64 (SD_, instruction_0);
6125 do_suxc1_64 (SD_, FS, INDEX, BASE);
6129 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,000100:COP1:32,f::SQRT.fmt
6130 "sqrt.%s<FMT> f<FD>, f<FS>"
6143 do_sqrt_fmt (SD_, FMT, FD, FS);
6147 010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,5.FD,000001:COP1:32,f::SUB.fmt
6148 "sub.%s<FMT> f<FD>, f<FS>, f<FT>"
6162 do_sub_fmt (SD_, FMT, FD, FS, FT, instruction_0);
6167 111001,5.BASE,5.FT,16.OFFSET:COP1:32,f::SWC1
6168 "swc1 f<FT>, <OFFSET>(r<BASE>)"
6182 do_swc1 (SD_, FT, OFFSET, BASE, instruction_0);
6186 010011,5.BASE,5.INDEX,5.FS,00000,001000:COP1X:32,f::SWXC1
6187 "swxc1 f<FS>, r<INDEX>(r<BASE>)"
6195 do_swxc1 (SD_, FS, INDEX, BASE, instruction_0);
6199 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001001:COP1:32,f::TRUNC.L.fmt
6200 "trunc.l.%s<FMT> f<FD>, f<FS>"
6211 do_trunc_fmt (SD_, fmt_long, FMT, FD, FS);
6215 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001101:COP1:32,f::TRUNC.W
6216 "trunc.w.%s<FMT> f<FD>, f<FS>"
6229 do_trunc_fmt (SD_, fmt_word, FMT, FD, FS);
6234 // MIPS Architecture:
6236 // System Control Instruction Set (COP0)
6240 010000,01000,00000,16.OFFSET:COP0:32::BC0F
6254 010000,01000,00000,16.OFFSET:COP0:32::BC0F
6256 // stub needed for eCos as tx39 hardware bug workaround
6263 010000,01000,00010,16.OFFSET:COP0:32::BC0FL
6278 010000,01000,00001,16.OFFSET:COP0:32::BC0T
6292 010000,01000,00011,16.OFFSET:COP0:32::BC0TL
6307 101111,5.BASE,5.OP,16.OFFSET:NORMAL:32::CACHE
6308 "cache <OP>, <OFFSET>(r<BASE>)"
6320 address_word base = GPR[BASE];
6321 address_word offset = EXTEND16 (OFFSET);
6323 address_word vaddr = loadstore_ea (SD_, base, offset);
6324 address_word paddr = vaddr;
6325 CacheOp(OP, vaddr, paddr, instruction_0);
6330 010000,00001,5.RT,5.RD,00000000,3.SEL:COP0:64::DMFC0
6331 "dmfc0 r<RT>, r<RD>"
6338 check_u64 (SD_, instruction_0);
6339 DecodeCoproc (instruction_0, 0, cp0_dmfc0, RT, RD, SEL);
6343 010000,00101,5.RT,5.RD,00000000,3.SEL:COP0:64::DMTC0
6344 "dmtc0 r<RT>, r<RD>"
6351 check_u64 (SD_, instruction_0);
6352 DecodeCoproc (instruction_0, 0, cp0_dmtc0, RT, RD, SEL);
6356 010000,1,0000000000000000000,011000:COP0:32::ERET
6368 if (SR & status_ERL)
6370 /* Oops, not yet available */
6371 sim_io_printf (SD, "Warning: ERET when SR[ERL] set not supported");
6383 010000,00000,5.RT,5.RD,00000000,3.SEL:COP0:32::MFC0
6384 "mfc0 r<RT>, r<RD> # <SEL>"
6398 TRACE_ALU_INPUT0 ();
6399 DecodeCoproc (instruction_0, 0, cp0_mfc0, RT, RD, SEL);
6400 TRACE_ALU_RESULT (GPR[RT]);
6403 010000,00100,5.RT,5.RD,00000000,3.SEL:COP0:32::MTC0
6404 "mtc0 r<RT>, r<RD> # <SEL>"
6418 DecodeCoproc (instruction_0, 0, cp0_mtc0, RT, RD, SEL);
6422 010000,1,0000000000000000000,010000:COP0:32::RFE
6433 DecodeCoproc (instruction_0, 0, cp0_rfe, 0, 0, 0x10);
6437 0100,ZZ!0!1!3,5.COP_FUN0!8,5.COP_FUN1,16.COP_FUN2:NORMAL:32::COPz
6438 "cop<ZZ> <COP_FUN0><COP_FUN1><COP_FUN2>"
6451 DecodeCoproc (instruction_0, 2, 0, 0, 0, 0);
6456 010000,1,0000000000000000000,001000:COP0:32::TLBP
6471 010000,1,0000000000000000000,000001:COP0:32::TLBR
6486 010000,1,0000000000000000000,000010:COP0:32::TLBWI
6501 010000,1,0000000000000000000,000110:COP0:32::TLBWR
6516 :include:::mips3264r2.igen
6518 :include:::m16e.igen
6519 :include:::mdmx.igen
6520 :include:::mips3d.igen
6525 :include:::dsp2.igen
6526 :include:::smartmips.igen
6527 :include:::micromips.igen
6528 :include:::micromipsdsp.igen