4 // <insn-word> { "+" <insn-word> }
11 // { <insn-mnemonic> }
16 // IGEN config - mips16
17 // :option:16::insn-bit-size:16
18 // :option:16::hi-bit-nr:15
19 :option:16::insn-specifying-widths:true
20 :option:16::gen-delayed-branch:false
22 // IGEN config - mips32/64..
23 // :option:32::insn-bit-size:32
24 // :option:32::hi-bit-nr:31
25 :option:32::insn-specifying-widths:true
26 :option:32::gen-delayed-branch:false
29 // Generate separate simulators for each target
30 // :option:::multi-sim:true
33 // Models known by this simulator are defined below.
35 // When placing models in the instruction descriptions, please place
36 // them one per line, in the order given here.
40 // Instructions and related functions for these models are included in
42 :model:::mipsI:mips3000:
43 :model:::mipsII:mips6000:
44 :model:::mipsIII:mips4000:
45 :model:::mipsIV:mips8000:
46 :model:::mipsV:mipsisaV:
47 :model:::mips32:mipsisa32:
48 :model:::mips32r2:mipsisa32r2:
49 :model:::mips64:mipsisa64:
50 :model:::mips64r2:mipsisa64r2:
54 // Standard MIPS ISA instructions used for these models are listed here,
55 // as are functions needed by those standard instructions. Instructions
56 // which are model-dependent and which are not in the standard MIPS ISAs
57 // (or which pre-date or use different encodings than the standard
58 // instructions) are (for the most part) in separate .igen files.
59 :model:::vr4100:mips4100: // vr.igen
60 :model:::vr4120:mips4120:
61 :model:::vr5000:mips5000:
62 :model:::vr5400:mips5400:
63 :model:::vr5500:mips5500:
64 :model:::r3900:mips3900: // tx.igen
66 // MIPS Application Specific Extensions (ASEs)
68 // Instructions for the ASEs are in separate .igen files.
69 // ASEs add instructions on to a base ISA.
70 :model:::mips16:mips16: // m16.igen (and m16.dc)
71 :model:::mips16e:mips16e: // m16e.igen
72 :model:::mips3d:mips3d: // mips3d.igen
73 :model:::mdmx:mdmx: // mdmx.igen
74 :model:::dsp:dsp: // dsp.igen
75 :model:::dsp2:dsp2: // dsp2.igen
76 :model:::smartmips:smartmips: // smartmips.igen
77 :model:::micromips32:micromips64: // micromips.igen
78 :model:::micromips64:micromips64: // micromips.igen
79 :model:::micromipsdsp:micromipsdsp: // micromipsdsp.igen
83 // Instructions specific to these extensions are in separate .igen files.
84 // Extensions add instructions on to a base ISA.
85 :model:::sb1:sb1: // sb1.igen
88 // Pseudo instructions known by IGEN
91 SignalException (ReservedInstruction, 0);
95 // Pseudo instructions known by interp.c
96 // For grep - RSVD_INSTRUCTION, RSVD_INSTRUCTION_MASK
97 000000,5.*,5.*,5.*,5.OP,111001:SPECIAL:32::RSVD
100 SignalException (ReservedInstruction, instruction_0);
107 // Simulate a 32 bit delayslot instruction
110 :function:::address_word:delayslot32:address_word target
112 instruction_word delay_insn;
113 sim_events_slip (SD, 1);
115 CIA = CIA + 4; /* NOTE not mips16 */
116 STATE |= simDELAYSLOT;
117 delay_insn = IMEM32 (CIA); /* NOTE not mips16 */
118 ENGINE_ISSUE_PREFIX_HOOK();
119 idecode_issue (CPU_, delay_insn, (CIA));
120 STATE &= ~simDELAYSLOT;
124 :function:::address_word:nullify_next_insn32:
126 sim_events_slip (SD, 1);
127 dotrace (SD, CPU, tracefh, 2, CIA + 4, 4, "load instruction");
134 // Calculate an effective address given a base and an offset.
137 :function:::address_word:loadstore_ea:address_word base, address_word offset
150 return base + offset;
153 :function:::address_word:loadstore_ea:address_word base, address_word offset
158 #if 0 /* XXX FIXME: enable this only after some additional testing. */
159 /* If in user mode and UX is not set, use 32-bit compatibility effective
160 address computations as defined in the MIPS64 Architecture for
161 Programmers Volume III, Revision 0.95, section 4.9. */
162 if ((SR & (status_KSU_mask|status_EXL|status_ERL|status_UX))
163 == (ksu_user << status_KSU_shift))
164 return (address_word)((signed32)base + (signed32)offset);
166 return base + offset;
172 // Check that a 32-bit register value is properly sign-extended.
173 // (See NotWordValue in ISA spec.)
176 :function:::int:not_word_value:unsigned_word value
192 #if WITH_TARGET_WORD_BITSIZE == 64
193 return value != (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
201 // Handle UNPREDICTABLE operation behaviour. The goal here is to prevent
202 // theoretically portable code which invokes non-portable behaviour from
203 // running with no indication of the portability issue.
204 // (See definition of UNPREDICTABLE in ISA spec.)
207 :function:::void:unpredictable:
219 :function:::void:unpredictable:
227 unpredictable_action (CPU, CIA);
233 // Check that an access to a HI/LO register meets timing requirements
237 // OP {HI and LO} followed by MT{LO or HI} (and not MT{HI or LO})
238 // makes subsequent MF{HI or LO} UNPREDICTABLE. (1)
240 // The following restrictions exist for MIPS I - MIPS III:
242 // MF{HI or LO} followed by MT{HI or LO} w/ less than 2 instructions
243 // in between makes MF UNPREDICTABLE. (2)
245 // MF{HI or LO} followed by OP {HI and LO} w/ less than 2 instructions
246 // in between makes MF UNPREDICTABLE. (3)
248 // On the r3900, restriction (2) is not present, and restriction (3) is not
249 // present for multiplication.
251 // Unfortunately, there seems to be some confusion about whether the last
252 // two restrictions should apply to "MIPS IV" as well. One edition of
253 // the MIPS IV ISA says they do, but references in later ISA documents
254 // suggest they don't.
256 // In reality, some MIPS IV parts, such as the VR5000 and VR5400, do have
257 // these restrictions, while others, like the VR5500, don't. To accomodate
258 // such differences, the MIPS IV and MIPS V version of these helper functions
259 // use auxillary routines to determine whether the restriction applies.
263 // Helper used by check_mt_hilo, check_mult_hilo, and check_div_hilo
264 // to check for restrictions (2) and (3) above.
266 :function:::int:check_mf_cycles:hilo_history *history, signed64 time, const char *new
268 if (history->mf.timestamp + 3 > time)
270 sim_engine_abort (SD, CPU, CIA, "HILO: %s: %s at 0x%08lx too close to MF at 0x%08lx\n",
271 itable[MY_INDEX].name,
273 (long) history->mf.cia);
282 // Check for restriction (2) above (for ISAs/processors that have it),
283 // and record timestamps for restriction (1) above.
285 :function:::int:check_mt_hilo:hilo_history *history
292 signed64 time = sim_events_time (SD);
293 int ok = check_mf_cycles (SD_, history, time, "MT");
294 history->mt.timestamp = time;
295 history->mt.cia = CIA;
299 :function:::int:check_mt_hilo:hilo_history *history
303 signed64 time = sim_events_time (SD);
304 int ok = (! MIPS_MACH_HAS_MT_HILO_HAZARD (SD)
305 || check_mf_cycles (SD_, history, time, "MT"));
306 history->mt.timestamp = time;
307 history->mt.cia = CIA;
311 :function:::int:check_mt_hilo:hilo_history *history
320 signed64 time = sim_events_time (SD);
321 history->mt.timestamp = time;
322 history->mt.cia = CIA;
329 // Check for restriction (1) above, and record timestamps for
330 // restriction (2) and (3) above.
332 :function:::int:check_mf_hilo:hilo_history *history, hilo_history *peer
348 signed64 time = sim_events_time (SD);
351 && peer->mt.timestamp > history->op.timestamp
352 && history->mt.timestamp < history->op.timestamp
353 && ! (history->mf.timestamp > history->op.timestamp
354 && history->mf.timestamp < peer->mt.timestamp)
355 && ! (peer->mf.timestamp > history->op.timestamp
356 && peer->mf.timestamp < peer->mt.timestamp))
358 /* The peer has been written to since the last OP yet we have
360 sim_engine_abort (SD, CPU, CIA, "HILO: %s: MF at 0x%08lx following OP at 0x%08lx corrupted by MT at 0x%08lx\n",
361 itable[MY_INDEX].name,
363 (long) history->op.cia,
364 (long) peer->mt.cia);
367 history->mf.timestamp = time;
368 history->mf.cia = CIA;
376 // Check for restriction (3) above (for ISAs/processors that have it)
377 // for MULT ops, and record timestamps for restriction (1) above.
379 :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
386 signed64 time = sim_events_time (SD);
387 int ok = (check_mf_cycles (SD_, hi, time, "OP")
388 && check_mf_cycles (SD_, lo, time, "OP"));
389 hi->op.timestamp = time;
390 lo->op.timestamp = time;
396 :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
400 signed64 time = sim_events_time (SD);
401 int ok = (! MIPS_MACH_HAS_MULT_HILO_HAZARD (SD)
402 || (check_mf_cycles (SD_, hi, time, "OP")
403 && check_mf_cycles (SD_, lo, time, "OP")));
404 hi->op.timestamp = time;
405 lo->op.timestamp = time;
411 :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
420 /* FIXME: could record the fact that a stall occured if we want */
421 signed64 time = sim_events_time (SD);
422 hi->op.timestamp = time;
423 lo->op.timestamp = time;
432 // Check for restriction (3) above (for ISAs/processors that have it)
433 // for DIV ops, and record timestamps for restriction (1) above.
435 :function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo
443 signed64 time = sim_events_time (SD);
444 int ok = (check_mf_cycles (SD_, hi, time, "OP")
445 && check_mf_cycles (SD_, lo, time, "OP"));
446 hi->op.timestamp = time;
447 lo->op.timestamp = time;
453 :function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo
457 signed64 time = sim_events_time (SD);
458 int ok = (! MIPS_MACH_HAS_DIV_HILO_HAZARD (SD)
459 || (check_mf_cycles (SD_, hi, time, "OP")
460 && check_mf_cycles (SD_, lo, time, "OP")));
461 hi->op.timestamp = time;
462 lo->op.timestamp = time;
468 :function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo
476 signed64 time = sim_events_time (SD);
477 hi->op.timestamp = time;
478 lo->op.timestamp = time;
487 // Check that the 64-bit instruction can currently be used, and signal
488 // a ReservedInstruction exception if not.
491 :function:::void:check_u64:instruction_word insn
500 // The check should be similar to mips64 for any with PX/UX bit equivalents.
503 :function:::void:check_u64:instruction_word insn
512 #if 0 /* XXX FIXME: enable this only after some additional testing. */
513 if (UserMode && (SR & (status_UX|status_PX)) == 0)
514 SignalException (ReservedInstruction, insn);
521 // MIPS Architecture:
523 // CPU Instruction Set (mipsI - mipsV, mips32/r2, mips64/r2)
527 :function:::void:do_add:int rs, int rt, int rd
529 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
531 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
533 ALU32_BEGIN (GPR[rs]);
535 ALU32_END (GPR[rd]); /* This checks for overflow. */
537 TRACE_ALU_RESULT (GPR[rd]);
540 :function:::void:do_addi:int rs, int rt, unsigned16 immediate
542 if (NotWordValue (GPR[rs]))
544 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
546 ALU32_BEGIN (GPR[rs]);
547 ALU32_ADD (EXTEND16 (immediate));
548 ALU32_END (GPR[rt]); /* This checks for overflow. */
550 TRACE_ALU_RESULT (GPR[rt]);
553 :function:::void:do_andi:int rs, int rt, unsigned int immediate
555 TRACE_ALU_INPUT2 (GPR[rs], immediate);
556 GPR[rt] = GPR[rs] & immediate;
557 TRACE_ALU_RESULT (GPR[rt]);
560 :function:::void:do_dadd:int rd, int rs, int rt
562 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
564 ALU64_BEGIN (GPR[rs]);
566 ALU64_END (GPR[rd]); /* This checks for overflow. */
568 TRACE_ALU_RESULT (GPR[rd]);
571 :function:::void:do_daddi:int rt, int rs, int immediate
573 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
575 ALU64_BEGIN (GPR[rs]);
576 ALU64_ADD (EXTEND16 (immediate));
577 ALU64_END (GPR[rt]); /* This checks for overflow. */
579 TRACE_ALU_RESULT (GPR[rt]);
582 :function:::void:do_dsll32:int rd, int rt, int shift
585 TRACE_ALU_INPUT2 (GPR[rt], s);
586 GPR[rd] = GPR[rt] << s;
587 TRACE_ALU_RESULT (GPR[rd]);
590 :function:::void:do_dsra32:int rd, int rt, int shift
593 TRACE_ALU_INPUT2 (GPR[rt], s);
594 GPR[rd] = ((signed64) GPR[rt]) >> s;
595 TRACE_ALU_RESULT (GPR[rd]);
598 :function:::void:do_dsrl32:int rd, int rt, int shift
601 TRACE_ALU_INPUT2 (GPR[rt], s);
602 GPR[rd] = (unsigned64) GPR[rt] >> s;
603 TRACE_ALU_RESULT (GPR[rd]);
606 :function:::void:do_dsub:int rd, int rs, int rt
608 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
610 ALU64_BEGIN (GPR[rs]);
612 ALU64_END (GPR[rd]); /* This checks for overflow. */
614 TRACE_ALU_RESULT (GPR[rd]);
617 :function:::void:do_break:address_word instruction_0
619 /* Check for some break instruction which are reserved for use by the
621 unsigned int break_code = instruction_0 & HALT_INSTRUCTION_MASK;
622 if (break_code == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
623 break_code == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
625 sim_engine_halt (SD, CPU, NULL, cia,
626 sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
628 else if (break_code == (BREAKPOINT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
629 break_code == (BREAKPOINT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
631 if (STATE & simDELAYSLOT)
632 PC = cia - 4; /* reference the branch instruction */
635 SignalException (BreakPoint, instruction_0);
640 /* If we get this far, we're not an instruction reserved by the sim. Raise
642 SignalException (BreakPoint, instruction_0);
646 :function:::void:do_break16:address_word instruction_0
648 if (STATE & simDELAYSLOT)
649 PC = cia - 2; /* reference the branch instruction */
652 SignalException (BreakPoint, instruction_0);
655 :function:::void:do_clo:int rd, int rs
657 unsigned32 temp = GPR[rs];
659 if (NotWordValue (GPR[rs]))
661 TRACE_ALU_INPUT1 (GPR[rs]);
662 for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
664 if ((temp & mask) == 0)
668 GPR[rd] = EXTEND32 (i);
669 TRACE_ALU_RESULT (GPR[rd]);
672 :function:::void:do_clz:int rd, int rs
674 unsigned32 temp = GPR[rs];
676 if (NotWordValue (GPR[rs]))
678 TRACE_ALU_INPUT1 (GPR[rs]);
679 for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
681 if ((temp & mask) != 0)
685 GPR[rd] = EXTEND32 (i);
686 TRACE_ALU_RESULT (GPR[rd]);
689 :function:::void:do_dclo:int rd, int rs
691 unsigned64 temp = GPR[rs];
694 TRACE_ALU_INPUT1 (GPR[rs]);
695 for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
697 if ((temp & mask) == 0)
701 GPR[rd] = EXTEND32 (i);
702 TRACE_ALU_RESULT (GPR[rd]);
705 :function:::void:do_dclz:int rd, int rs
707 unsigned64 temp = GPR[rs];
710 TRACE_ALU_INPUT1 (GPR[rs]);
711 for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
713 if ((temp & mask) != 0)
717 GPR[rd] = EXTEND32 (i);
718 TRACE_ALU_RESULT (GPR[rd]);
721 :function:::void:do_lb:int rt, int offset, int base
723 GPR[rt] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[base],
727 :function:::void:do_lh:int rt, int offset, int base
729 GPR[rt] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[base],
733 :function:::void:do_lwr:int rt, int offset, int base
735 GPR[rt] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, GPR[base],
736 EXTEND16 (offset), GPR[rt]));
739 :function:::void:do_lwl:int rt, int offset, int base
741 GPR[rt] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, GPR[base],
742 EXTEND16 (offset), GPR[rt]));
745 :function:::void:do_lwc:int num, int rt, int offset, int base
747 COP_LW (num, rt, do_load (SD_, AccessLength_WORD, GPR[base],
751 :function:::void:do_lw:int rt, int offset, int base
753 GPR[rt] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[base],
757 :function:::void:do_lwu:int rt, int offset, int base, address_word instruction_0
759 check_u64 (SD_, instruction_0);
760 GPR[rt] = do_load (SD_, AccessLength_WORD, GPR[base], EXTEND16 (offset));
763 :function:::void:do_lhu:int rt, int offset, int base
765 GPR[rt] = do_load (SD_, AccessLength_HALFWORD, GPR[base], EXTEND16 (offset));
768 :function:::void:do_ldc:int num, int rt, int offset, int base
770 COP_LD (num, rt, do_load (SD_, AccessLength_DOUBLEWORD, GPR[base],
774 :function:::void:do_lbu:int rt, int offset, int base
776 GPR[rt] = do_load (SD_, AccessLength_BYTE, GPR[base], EXTEND16 (offset));
779 :function:::void:do_ll:int rt, int insn_offset, int basereg
781 address_word base = GPR[basereg];
782 address_word offset = EXTEND16 (insn_offset);
784 address_word vaddr = loadstore_ea (SD_, base, offset);
787 if ((vaddr & 3) != 0)
789 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer,
790 sim_core_unaligned_signal);
794 if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
797 unsigned64 memval = 0;
798 unsigned64 memval1 = 0;
799 unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
800 unsigned int shift = 2;
801 unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
802 unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
804 paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
805 LoadMemory (&memval, &memval1, uncached, AccessLength_WORD, paddr,
806 vaddr, isDATA, isREAL);
807 byte = ((vaddr & mask) ^ (bigend << shift));
808 GPR[rt] = EXTEND32 (memval >> (8 * byte));
815 :function:::void:do_lld:int rt, int roffset, int rbase
817 address_word base = GPR[rbase];
818 address_word offset = EXTEND16 (roffset);
820 address_word vaddr = loadstore_ea (SD_, base, offset);
823 if ((vaddr & 7) != 0)
825 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer,
826 sim_core_unaligned_signal);
830 if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
833 unsigned64 memval = 0;
834 unsigned64 memval1 = 0;
835 LoadMemory (&memval, &memval1, uncached, AccessLength_DOUBLEWORD,
836 paddr, vaddr, isDATA, isREAL);
844 :function:::void:do_lui:int rt, int immediate
846 TRACE_ALU_INPUT1 (immediate);
847 GPR[rt] = EXTEND32 (immediate << 16);
848 TRACE_ALU_RESULT (GPR[rt]);
851 :function:::void:do_madd:int rs, int rt
854 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
855 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
857 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
858 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
859 + ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
860 LO = EXTEND32 (temp);
861 HI = EXTEND32 (VH4_8 (temp));
862 TRACE_ALU_RESULT2 (HI, LO);
865 :function:::void:do_dsp_madd:int ac, int rs, int rt
869 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
870 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
872 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
873 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
874 + ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
875 DSPLO(ac) = EXTEND32 (temp);
876 DSPHI(ac) = EXTEND32 (VH4_8 (temp));
878 TRACE_ALU_RESULT2 (HI, LO);
881 :function:::void:do_maddu:int rs, int rt
884 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
885 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
887 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
888 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
889 + ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
890 ACX += U8_4 (VL4_8 (HI), VL4_8 (LO)) < temp; /* SmartMIPS */
891 LO = EXTEND32 (temp);
892 HI = EXTEND32 (VH4_8 (temp));
893 TRACE_ALU_RESULT2 (HI, LO);
896 :function:::void:do_dsp_maddu:int ac, int rs, int rt
900 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
901 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
903 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
904 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
905 + ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
907 ACX += U8_4 (VL4_8 (HI), VL4_8 (LO)) < temp; /* SmartMIPS */
908 DSPLO(ac) = EXTEND32 (temp);
909 DSPHI(ac) = EXTEND32 (VH4_8 (temp));
911 TRACE_ALU_RESULT2 (HI, LO);
914 :function:::void:do_dsp_mfhi:int ac, int rd
922 :function:::void:do_dsp_mflo:int ac, int rd
930 :function:::void:do_movn:int rd, int rs, int rt
935 TRACE_ALU_RESULT (GPR[rd]);
939 :function:::void:do_movz:int rd, int rs, int rt
944 TRACE_ALU_RESULT (GPR[rd]);
948 :function:::void:do_msub:int rs, int rt
951 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
952 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
954 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
955 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
956 - ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
957 LO = EXTEND32 (temp);
958 HI = EXTEND32 (VH4_8 (temp));
959 TRACE_ALU_RESULT2 (HI, LO);
962 :function:::void:do_dsp_msub:int ac, int rs, int rt
966 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
967 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
969 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
970 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
971 - ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
972 DSPLO(ac) = EXTEND32 (temp);
973 DSPHI(ac) = EXTEND32 (VH4_8 (temp));
975 TRACE_ALU_RESULT2 (HI, LO);
978 :function:::void:do_msubu:int rs, int rt
981 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
982 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
984 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
985 temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
986 - ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
987 LO = EXTEND32 (temp);
988 HI = EXTEND32 (VH4_8 (temp));
989 TRACE_ALU_RESULT2 (HI, LO);
992 :function:::void:do_dsp_msubu:int ac, int rs, int rt
996 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
997 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
999 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1000 temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
1001 - ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
1002 DSPLO(ac) = EXTEND32 (temp);
1003 DSPHI(ac) = EXTEND32 (VH4_8 (temp));
1005 TRACE_ALU_RESULT2 (HI, LO);
1008 :function:::void:do_mthi:int rs
1010 check_mt_hilo (SD_, HIHISTORY);
1014 :function:::void:do_dsp_mthi:int ac, int rs
1017 check_mt_hilo (SD_, HIHISTORY);
1018 DSPHI(ac) = GPR[rs];
1021 :function:::void:do_mtlo:int rs
1023 check_mt_hilo (SD_, LOHISTORY);
1027 :function:::void:do_dsp_mtlo:int ac, int rs
1030 check_mt_hilo (SD_, LOHISTORY);
1031 DSPLO(ac) = GPR[rs];
1034 :function:::void:do_mul:int rd, int rs, int rt
1037 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
1039 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1040 prod = (((signed64)(signed32) GPR[rs])
1041 * ((signed64)(signed32) GPR[rt]));
1042 GPR[rd] = EXTEND32 (VL4_8 (prod));
1043 TRACE_ALU_RESULT (GPR[rd]);
1046 :function:::void:do_dsp_mult:int ac, int rs, int rt
1050 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
1051 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
1053 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1054 prod = ((signed64)(signed32) GPR[rs])
1055 * ((signed64)(signed32) GPR[rt]);
1056 DSPLO(ac) = EXTEND32 (VL4_8 (prod));
1057 DSPHI(ac) = EXTEND32 (VH4_8 (prod));
1060 ACX = 0; /* SmartMIPS */
1061 TRACE_ALU_RESULT2 (HI, LO);
1065 :function:::void:do_dsp_multu:int ac, int rs, int rt
1069 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
1070 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
1072 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1073 prod = ((unsigned64)(unsigned32) GPR[rs])
1074 * ((unsigned64)(unsigned32) GPR[rt]);
1075 DSPLO(ac) = EXTEND32 (VL4_8 (prod));
1076 DSPHI(ac) = EXTEND32 (VH4_8 (prod));
1078 TRACE_ALU_RESULT2 (HI, LO);
1081 :function:::void:do_pref:int hint, int insn_offset, int insn_base
1083 address_word base = GPR[insn_base];
1084 address_word offset = EXTEND16 (insn_offset);
1086 address_word vaddr = loadstore_ea (SD_, base, offset);
1090 if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
1092 Prefetch (uncached, paddr, vaddr, isDATA, hint);
1097 :function:::void:do_sc:int rt, int offsetarg, int basereg, address_word instruction_0
1099 unsigned32 instruction = instruction_0;
1100 address_word base = GPR[basereg];
1101 address_word offset = EXTEND16 (offsetarg);
1103 address_word vaddr = loadstore_ea (SD_, base, offset);
1106 if ((vaddr & 3) != 0)
1108 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer,
1109 sim_core_unaligned_signal);
1113 if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
1116 unsigned64 memval = 0;
1117 unsigned64 memval1 = 0;
1118 unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1119 address_word reverseendian =
1120 (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
1121 address_word bigendiancpu =
1122 (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
1124 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
1125 byte = ((vaddr & mask) ^ bigendiancpu);
1126 memval = ((unsigned64) GPR[rt] << (8 * byte));
1129 StoreMemory (uncached, AccessLength_WORD, memval, memval1,
1130 paddr, vaddr, isREAL);
1138 :function:::void:do_scd:int rt, int roffset, int rbase
1140 address_word base = GPR[rbase];
1141 address_word offset = EXTEND16 (roffset);
1143 address_word vaddr = loadstore_ea (SD_, base, offset);
1146 if ((vaddr & 7) != 0)
1148 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer,
1149 sim_core_unaligned_signal);
1153 if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
1156 unsigned64 memval = 0;
1157 unsigned64 memval1 = 0;
1161 StoreMemory (uncached, AccessLength_DOUBLEWORD, memval, memval1,
1162 paddr, vaddr, isREAL);
1170 :function:::void:do_sub:int rs, int rt, int rd
1172 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
1174 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1176 ALU32_BEGIN (GPR[rs]);
1177 ALU32_SUB (GPR[rt]);
1178 ALU32_END (GPR[rd]); /* This checks for overflow. */
1180 TRACE_ALU_RESULT (GPR[rd]);
1183 :function:::void:do_sw:int rt, int offset, int base
1185 do_store (SD_, AccessLength_WORD, GPR[base], EXTEND16 (offset), GPR[rt]);
1188 :function:::void:do_teq:int rs, int rt, address_word instruction_0
1190 if ((signed_word) GPR[rs] == (signed_word) GPR[rt])
1191 SignalException (Trap, instruction_0);
1194 :function:::void:do_teqi:int rs, int immediate, address_word instruction_0
1196 if ((signed_word) GPR[rs] == (signed_word) EXTEND16 (immediate))
1197 SignalException (Trap, instruction_0);
1200 :function:::void:do_tge:int rs, int rt, address_word instruction_0
1202 if ((signed_word) GPR[rs] >= (signed_word) GPR[rt])
1203 SignalException (Trap, instruction_0);
1206 :function:::void:do_tgei:int rs, int immediate, address_word instruction_0
1208 if ((signed_word) GPR[rs] >= (signed_word) EXTEND16 (immediate))
1209 SignalException (Trap, instruction_0);
1212 :function:::void:do_tgeiu:int rs, int immediate, address_word instruction_0
1214 if ((unsigned_word) GPR[rs] >= (unsigned_word) EXTEND16 (immediate))
1215 SignalException (Trap, instruction_0);
1218 :function:::void:do_tgeu:int rs ,int rt, address_word instruction_0
1220 if ((unsigned_word) GPR[rs] >= (unsigned_word) GPR[rt])
1221 SignalException (Trap, instruction_0);
1224 :function:::void:do_tlt:int rs, int rt, address_word instruction_0
1226 if ((signed_word) GPR[rs] < (signed_word) GPR[rt])
1227 SignalException (Trap, instruction_0);
1230 :function:::void:do_tlti:int rs, int immediate, address_word instruction_0
1232 if ((signed_word) GPR[rs] < (signed_word) EXTEND16 (immediate))
1233 SignalException (Trap, instruction_0);
1236 :function:::void:do_tltiu:int rs, int immediate, address_word instruction_0
1238 if ((unsigned_word) GPR[rs] < (unsigned_word) EXTEND16 (immediate))
1239 SignalException (Trap, instruction_0);
1242 :function:::void:do_tltu:int rs, int rt, address_word instruction_0
1244 if ((unsigned_word) GPR[rs] < (unsigned_word) GPR[rt])
1245 SignalException (Trap, instruction_0);
1248 :function:::void:do_tne:int rs, int rt, address_word instruction_0
1250 if ((signed_word) GPR[rs] != (signed_word) GPR[rt])
1251 SignalException (Trap, instruction_0);
1254 :function:::void:do_tnei:int rs, int immediate, address_word instruction_0
1256 if ((signed_word) GPR[rs] != (signed_word) EXTEND16 (immediate))
1257 SignalException (Trap, instruction_0);
1260 :function:::void:do_abs_fmt:int fmt, int fd, int fs, address_word instruction_0
1263 check_fmt_p (SD_, fmt, instruction_0);
1264 StoreFPR (fd, fmt, AbsoluteValue (ValueFPR (fs, fmt), fmt));
1267 :function:::void:do_add_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
1270 check_fmt_p (SD_, fmt, instruction_0);
1271 StoreFPR (fd, fmt, Add (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
1274 :function:::void:do_alnv_ps:int fd, int fs, int ft, int rs, address_word instruction_0
1280 check_u64 (SD_, instruction_0);
1281 fsx = ValueFPR (fs, fmt_ps);
1282 if ((GPR[rs] & 0x3) != 0)
1284 if ((GPR[rs] & 0x4) == 0)
1288 ftx = ValueFPR (ft, fmt_ps);
1290 fdx = PackPS (PSLower (fsx), PSUpper (ftx));
1292 fdx = PackPS (PSLower (ftx), PSUpper (fsx));
1294 StoreFPR (fd, fmt_ps, fdx);
1297 :function:::void:do_c_cond_fmt:int cond, int fmt, int cc, int fs, int ft, address_word instruction_0
1300 check_fmt_p (SD_, fmt, instruction_0);
1301 Compare (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt, cond, cc);
1302 TRACE_ALU_RESULT (ValueFCR (31));
1305 :function:::void:do_ceil_fmt:int type, int fmt, int fd, int fs, address_word instruction_0
1308 check_fmt_p (SD_, fmt, instruction_0);
1309 StoreFPR (fd, type, Convert (FP_RM_TOPINF, ValueFPR (fs, fmt), fmt,
1313 :function:::void:do_cfc1:int rt, int fs
1316 if (fs == 0 || fs == 25 || fs == 26 || fs == 28 || fs == 31)
1318 unsigned_word fcr = ValueFCR (fs);
1319 TRACE_ALU_INPUT1 (fcr);
1323 TRACE_ALU_RESULT (GPR[rt]);
1326 :function:::void:do_ctc1:int rt, int fs
1329 TRACE_ALU_INPUT1 (GPR[rt]);
1330 if (fs == 25 || fs == 26 || fs == 28 || fs == 31)
1331 StoreFCR (fs, GPR[rt]);
1335 :function:::void:do_cvt_d_fmt:int fmt, int fd, int fs, address_word instruction_0
1338 if ((fmt == fmt_double) | 0)
1339 SignalException (ReservedInstruction, instruction_0);
1340 StoreFPR (fd, fmt_double, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
1344 :function:::void:do_cvt_l_fmt:int fmt, int fd, int fs, address_word instruction_0
1347 if ((fmt == fmt_long) | ((fmt == fmt_long) || (fmt == fmt_word)))
1348 SignalException (ReservedInstruction, instruction_0);
1349 StoreFPR (fd, fmt_long, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
1353 :function:::void:do_cvt_ps_s:int fd, int fs, int ft, address_word instruction_0
1356 check_u64 (SD_, instruction_0);
1357 StoreFPR (fd, fmt_ps, PackPS (ValueFPR (fs, fmt_single),
1358 ValueFPR (ft, fmt_single)));
1361 :function:::void:do_cvt_s_fmt:int fmt, int fd, int fs, address_word instruction_0
1364 if ((fmt == fmt_single) | 0)
1365 SignalException (ReservedInstruction, instruction_0);
1366 StoreFPR (fd, fmt_single, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
1370 :function:::void:do_cvt_s_pl:int fd, int fs, address_word instruction_0
1373 check_u64 (SD_, instruction_0);
1374 StoreFPR (fd, fmt_single, PSLower (ValueFPR (fs, fmt_ps)));
1377 :function:::void:do_cvt_s_pu:int fd, int fs, address_word instruction_0
1380 check_u64 (SD_, instruction_0);
1381 StoreFPR (fd, fmt_single, PSUpper (ValueFPR (fs, fmt_ps)));
1384 :function:::void:do_cvt_w_fmt:int fmt, int fd, int fs, address_word instruction_0
1387 if ((fmt == fmt_word) | ((fmt == fmt_long) || (fmt == fmt_word)))
1388 SignalException (ReservedInstruction, instruction_0);
1389 StoreFPR (fd, fmt_word, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
1393 :function:::void:do_div_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
1396 StoreFPR (fd, fmt, Divide (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
1399 :function:::void:do_dmfc1b:int rt, int fs
1409 if (SizeFGR () == 64)
1411 else if ((fs & 0x1) == 0)
1412 GPR[rt] = SET64HI (FGR[fs+1]) | FGR[fs];
1414 GPR[rt] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
1415 TRACE_ALU_RESULT (GPR[rt]);
1418 :function:::void:do_dmtc1b:int rt, int fs
1420 if (SizeFGR () == 64)
1421 StoreFPR (fs, fmt_uninterpreted_64, GPR[rt]);
1422 else if ((fs & 0x1) == 0)
1423 StoreFPR (fs, fmt_uninterpreted_64, GPR[rt]);
1428 :function:::void:do_floor_fmt:int type, int fmt, int fd, int fs
1431 StoreFPR (fd, type, Convert (FP_RM_TOMINF, ValueFPR (fs, fmt), fmt,
1435 :function:::void:do_luxc1_32:int fd, int rindex, int rbase
1439 address_word base = GPR[rbase];
1440 address_word index = GPR[rindex];
1441 address_word vaddr = base + index;
1443 if (SizeFGR () != 64)
1445 /* Arrange for the bottom 3 bits of (base + index) to be 0. */
1446 if ((vaddr & 0x7) != 0)
1447 index -= (vaddr & 0x7);
1448 COP_LD (1, fd, do_load_double (SD_, base, index));
1451 :function:::void:do_luxc1_64:int fd, int rindex, int rbase
1453 address_word base = GPR[rbase];
1454 address_word index = GPR[rindex];
1455 address_word vaddr = base + index;
1456 if (SizeFGR () != 64)
1458 /* Arrange for the bottom 3 bits of (base + index) to be 0. */
1459 if ((vaddr & 0x7) != 0)
1460 index -= (vaddr & 0x7);
1461 COP_LD (1, fd, do_load (SD_, AccessLength_DOUBLEWORD, base, index));
1465 :function:::void:do_lwc1:int ft, int offset, int base
1468 COP_LW (1, ft, do_load (SD_, AccessLength_WORD, GPR[base],
1469 EXTEND16 (offset)));
1472 :function:::void:do_lwxc1:int fd, int index, int base, address_word instruction_0
1475 check_u64 (SD_, instruction_0);
1476 COP_LW (1, fd, do_load (SD_, AccessLength_WORD, GPR[base], GPR[index]));
1479 :function:::void:do_madd_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
1482 check_u64 (SD_, instruction_0);
1483 check_fmt_p (SD_, fmt, instruction_0);
1484 StoreFPR (fd, fmt, MultiplyAdd (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
1485 ValueFPR (fr, fmt), fmt));
1488 :function:::void:do_mfc1b:int rt, int fs
1491 GPR[rt] = EXTEND32 (FGR[fs]);
1492 TRACE_ALU_RESULT (GPR[rt]);
1495 :function:::void:do_mov_fmt:int fmt, int fd, int fs, address_word instruction_0
1498 check_fmt_p (SD_, fmt, instruction_0);
1499 StoreFPR (fd, fmt, ValueFPR (fs, fmt));
1502 :function:::void:do_movtf:int tf, int rd, int rs, int cc
1505 if (GETFCC(cc) == tf)
1509 :function:::void:do_movtf_fmt:int tf, int fmt, int fd, int fs, int cc
1514 if (GETFCC(cc) == tf)
1515 StoreFPR (fd, fmt, ValueFPR (fs, fmt));
1517 StoreFPR (fd, fmt, ValueFPR (fd, fmt)); /* set fmt */
1522 fdx = PackPS (PSUpper (ValueFPR ((GETFCC (cc+1) == tf) ? fs : fd,
1524 PSLower (ValueFPR ((GETFCC (cc+0) == tf) ? fs : fd,
1526 StoreFPR (fd, fmt_ps, fdx);
1530 :function:::void:do_movn_fmt:int fmt, int fd, int fs, int rt
1534 StoreFPR (fd, fmt, ValueFPR (fs, fmt));
1536 StoreFPR (fd, fmt, ValueFPR (fd, fmt));
1539 :function:::void:do_movz_fmt:int fmt, int fd, int fs, int rt
1543 StoreFPR (fd, fmt, ValueFPR (fs, fmt));
1545 StoreFPR (fd, fmt, ValueFPR (fd, fmt));
1548 :function:::void:do_msub_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
1551 check_u64 (SD_, instruction_0);
1552 check_fmt_p (SD_, fmt, instruction_0);
1553 StoreFPR (fd, fmt, MultiplySub (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
1554 ValueFPR (fr, fmt), fmt));
1557 :function:::void:do_mtc1b:int rt, int fs
1560 StoreFPR (fs, fmt_uninterpreted_32, VL4_8 (GPR[rt]));
1563 :function:::void:do_mul_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
1566 check_fmt_p (SD_, fmt, instruction_0);
1567 StoreFPR (fd, fmt, Multiply (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
1570 :function:::void:do_neg_fmt:int fmt, int fd, int fs, address_word instruction_0
1573 check_fmt_p (SD_, fmt, instruction_0);
1574 StoreFPR (fd, fmt, Negate (ValueFPR (fs, fmt), fmt));
1577 :function:::void:do_nmadd_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
1580 check_u64 (SD_, instruction_0);
1581 check_fmt_p (SD_, fmt, instruction_0);
1582 StoreFPR (fd, fmt, NegMultiplyAdd (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
1583 ValueFPR (fr, fmt), fmt));
1586 :function:::void:do_nmsub_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
1589 check_u64 (SD_, instruction_0);
1590 check_fmt_p (SD_, fmt, instruction_0);
1591 StoreFPR (fd, fmt, NegMultiplySub (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
1592 ValueFPR (fr, fmt), fmt));
1595 :function:::void:do_pll_ps:int fd, int fs, int ft, address_word instruction_0
1598 check_u64 (SD_, instruction_0);
1599 StoreFPR (fd, fmt_ps, PackPS (PSLower (ValueFPR (fs, fmt_ps)),
1600 PSLower (ValueFPR (ft, fmt_ps))));
1603 :function:::void:do_plu_ps:int fd, int fs, int ft, address_word instruction_0
1606 check_u64 (SD_, instruction_0);
1607 StoreFPR (fd, fmt_ps, PackPS (PSLower (ValueFPR (fs, fmt_ps)),
1608 PSUpper (ValueFPR (ft, fmt_ps))));
1611 :function:::void:do_pul_ps:int fd, int fs, int ft, address_word instruction_0
1614 check_u64 (SD_, instruction_0);
1615 StoreFPR (fd, fmt_ps, PackPS (PSUpper (ValueFPR (fs, fmt_ps)),
1616 PSLower (ValueFPR (ft, fmt_ps))));
1619 :function:::void:do_puu_ps:int fd, int fs, int ft, address_word instruction_0
1622 check_u64 (SD_, instruction_0);
1623 StoreFPR (fd, fmt_ps, PackPS (PSUpper (ValueFPR (fs, fmt_ps)),
1624 PSUpper (ValueFPR (ft, fmt_ps))));
1627 :function:::void:do_recip_fmt:int fmt, int fd, int fs
1630 StoreFPR (fd, fmt, Recip (ValueFPR (fs, fmt), fmt));
1633 :function:::void:do_round_fmt:int type, int fmt, int fd, int fs
1636 StoreFPR (fd, type, Convert (FP_RM_NEAREST, ValueFPR (fs, fmt), fmt,
1640 :function:::void:do_rsqrt_fmt:int fmt, int fd, int fs
1643 StoreFPR (fd, fmt, RSquareRoot (ValueFPR (fs, fmt), fmt));
1646 :function:::void:do_prefx:int hint, int rindex, int rbase
1648 address_word base = GPR[rbase];
1649 address_word index = GPR[rindex];
1651 address_word vaddr = loadstore_ea (SD_, base, index);
1654 if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET,
1656 Prefetch (uncached, paddr, vaddr, isDATA, hint);
1660 :function:::void:do_sdc1:int ft, int offset, int base
1667 do_store_double (SD_, GPR[base], EXTEND16 (offset), COP_SD (1, ft));
1670 :function:::void:do_suxc1_32:int fs, int rindex, int rbase
1674 address_word base = GPR[rbase];
1675 address_word index = GPR[rindex];
1676 address_word vaddr = base + index;
1678 if (SizeFGR () != 64)
1680 /* Arrange for the bottom 3 bits of (base + index) to be 0. */
1681 if ((vaddr & 0x7) != 0)
1682 index -= (vaddr & 0x7);
1683 do_store_double (SD_, base, index, COP_SD (1, fs));
1686 :function:::void:do_suxc1_64:int fs, int rindex, int rbase
1688 address_word base = GPR[rbase];
1689 address_word index = GPR[rindex];
1690 address_word vaddr = base + index;
1691 if (SizeFGR () != 64)
1693 /* Arrange for the bottom 3 bits of (base + index) to be 0. */
1694 if ((vaddr & 0x7) != 0)
1695 index -= (vaddr & 0x7);
1696 do_store (SD_, AccessLength_DOUBLEWORD, base, index, COP_SD (1, fs));
1699 :function:::void:do_sqrt_fmt:int fmt, int fd, int fs
1702 StoreFPR (fd, fmt, (SquareRoot (ValueFPR (fs, fmt), fmt)));
1705 :function:::void:do_sub_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
1708 check_fmt_p (SD_, fmt, instruction_0);
1709 StoreFPR (fd, fmt, Sub (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
1712 :function:::void:do_swc1:int ft, int roffset, int rbase, address_word instruction_0
1714 address_word base = GPR[rbase];
1715 address_word offset = EXTEND16 (roffset);
1718 address_word vaddr = loadstore_ea (SD_, base, offset);
1721 if ((vaddr & 3) != 0)
1723 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr,
1724 write_transfer, sim_core_unaligned_signal);
1728 if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
1732 uword64 memval1 = 0;
1733 uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1734 address_word reverseendian =
1735 (ReverseEndian ?(mask ^ AccessLength_WORD): 0);
1736 address_word bigendiancpu =
1737 (BigEndianCPU ?(mask ^ AccessLength_WORD): 0);
1739 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
1740 byte = ((vaddr & mask) ^ bigendiancpu);
1741 memval = (((uword64)COP_SW(1, ft)) << (8 * byte));
1742 StoreMemory (uncached, AccessLength_WORD, memval, memval1, paddr,
1749 :function:::void:do_swxc1:int fs, int rindex, int rbase, address_word instruction_0
1751 address_word base = GPR[rbase];
1752 address_word index = GPR[rindex];
1754 check_u64 (SD_, instruction_0);
1756 address_word vaddr = loadstore_ea (SD_, base, index);
1759 if ((vaddr & 3) != 0)
1761 SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer,
1762 sim_core_unaligned_signal);
1766 if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
1769 unsigned64 memval = 0;
1770 unsigned64 memval1 = 0;
1771 unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
1772 address_word reverseendian =
1773 (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
1774 address_word bigendiancpu =
1775 (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
1777 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
1778 byte = ((vaddr & mask) ^ bigendiancpu);
1779 memval = (((unsigned64)COP_SW(1,fs)) << (8 * byte));
1780 StoreMemory (uncached, AccessLength_WORD, memval, memval1, paddr,
1787 :function:::void:do_trunc_fmt:int type, int fmt, int fd, int fs
1790 StoreFPR (fd, type, Convert (FP_RM_TOZERO, ValueFPR (fs, fmt), fmt,
1794 000000,5.RS,5.RT,5.RD,00000,100000:SPECIAL:32::ADD
1795 "add r<RD>, r<RS>, r<RT>"
1809 do_add (SD_, RS, RT, RD);
1814 001000,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDI
1815 "addi r<RT>, r<RS>, <IMMEDIATE>"
1829 do_addi (SD_, RS, RT, IMMEDIATE);
1834 :function:::void:do_addiu:int rs, int rt, unsigned16 immediate
1836 if (NotWordValue (GPR[rs]))
1838 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
1839 GPR[rt] = EXTEND32 (GPR[rs] + EXTEND16 (immediate));
1840 TRACE_ALU_RESULT (GPR[rt]);
1843 001001,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDIU
1844 "addiu r<RT>, r<RS>, <IMMEDIATE>"
1858 do_addiu (SD_, RS, RT, IMMEDIATE);
1863 :function:::void:do_addu:int rs, int rt, int rd
1865 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
1867 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1868 GPR[rd] = EXTEND32 (GPR[rs] + GPR[rt]);
1869 TRACE_ALU_RESULT (GPR[rd]);
1872 000000,5.RS,5.RT,5.RD,00000,100001:SPECIAL:32::ADDU
1873 "addu r<RD>, r<RS>, r<RT>"
1887 do_addu (SD_, RS, RT, RD);
1892 :function:::void:do_and:int rs, int rt, int rd
1894 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
1895 GPR[rd] = GPR[rs] & GPR[rt];
1896 TRACE_ALU_RESULT (GPR[rd]);
1899 000000,5.RS,5.RT,5.RD,00000,100100:SPECIAL:32::AND
1900 "and r<RD>, r<RS>, r<RT>"
1914 do_and (SD_, RS, RT, RD);
1919 001100,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ANDI
1920 "andi r<RT>, r<RS>, %#lx<IMMEDIATE>"
1934 do_andi (SD_,RS, RT, IMMEDIATE);
1939 000100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQ
1940 "beq r<RS>, r<RT>, <OFFSET>"
1954 address_word offset = EXTEND16 (OFFSET) << 2;
1955 if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
1957 DELAY_SLOT (NIA + offset);
1963 010100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQL
1964 "beql r<RS>, r<RT>, <OFFSET>"
1977 address_word offset = EXTEND16 (OFFSET) << 2;
1978 if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
1980 DELAY_SLOT (NIA + offset);
1983 NULLIFY_NEXT_INSTRUCTION ();
1988 000001,5.RS,00001,16.OFFSET:REGIMM:32::BGEZ
1989 "bgez r<RS>, <OFFSET>"
2003 address_word offset = EXTEND16 (OFFSET) << 2;
2004 if ((signed_word) GPR[RS] >= 0)
2006 DELAY_SLOT (NIA + offset);
2012 000001,5.RS!31,10001,16.OFFSET:REGIMM:32::BGEZAL
2013 "bgezal r<RS>, <OFFSET>"
2027 address_word offset = EXTEND16 (OFFSET) << 2;
2031 if ((signed_word) GPR[RS] >= 0)
2033 DELAY_SLOT (NIA + offset);
2039 000001,5.RS!31,10011,16.OFFSET:REGIMM:32::BGEZALL
2040 "bgezall r<RS>, <OFFSET>"
2053 address_word offset = EXTEND16 (OFFSET) << 2;
2057 /* NOTE: The branch occurs AFTER the next instruction has been
2059 if ((signed_word) GPR[RS] >= 0)
2061 DELAY_SLOT (NIA + offset);
2064 NULLIFY_NEXT_INSTRUCTION ();
2069 000001,5.RS,00011,16.OFFSET:REGIMM:32::BGEZL
2070 "bgezl r<RS>, <OFFSET>"
2083 address_word offset = EXTEND16 (OFFSET) << 2;
2084 if ((signed_word) GPR[RS] >= 0)
2086 DELAY_SLOT (NIA + offset);
2089 NULLIFY_NEXT_INSTRUCTION ();
2094 000111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZ
2095 "bgtz r<RS>, <OFFSET>"
2109 address_word offset = EXTEND16 (OFFSET) << 2;
2110 if ((signed_word) GPR[RS] > 0)
2112 DELAY_SLOT (NIA + offset);
2118 010111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZL
2119 "bgtzl r<RS>, <OFFSET>"
2132 address_word offset = EXTEND16 (OFFSET) << 2;
2133 /* NOTE: The branch occurs AFTER the next instruction has been
2135 if ((signed_word) GPR[RS] > 0)
2137 DELAY_SLOT (NIA + offset);
2140 NULLIFY_NEXT_INSTRUCTION ();
2145 000110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZ
2146 "blez r<RS>, <OFFSET>"
2160 address_word offset = EXTEND16 (OFFSET) << 2;
2161 /* NOTE: The branch occurs AFTER the next instruction has been
2163 if ((signed_word) GPR[RS] <= 0)
2165 DELAY_SLOT (NIA + offset);
2171 010110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZL
2172 "bgezl r<RS>, <OFFSET>"
2185 address_word offset = EXTEND16 (OFFSET) << 2;
2186 if ((signed_word) GPR[RS] <= 0)
2188 DELAY_SLOT (NIA + offset);
2191 NULLIFY_NEXT_INSTRUCTION ();
2196 000001,5.RS,00000,16.OFFSET:REGIMM:32::BLTZ
2197 "bltz r<RS>, <OFFSET>"
2211 address_word offset = EXTEND16 (OFFSET) << 2;
2212 if ((signed_word) GPR[RS] < 0)
2214 DELAY_SLOT (NIA + offset);
2220 000001,5.RS!31,10000,16.OFFSET:REGIMM:32::BLTZAL
2221 "bltzal r<RS>, <OFFSET>"
2235 address_word offset = EXTEND16 (OFFSET) << 2;
2239 /* NOTE: The branch occurs AFTER the next instruction has been
2241 if ((signed_word) GPR[RS] < 0)
2243 DELAY_SLOT (NIA + offset);
2249 000001,5.RS!31,10010,16.OFFSET:REGIMM:32::BLTZALL
2250 "bltzall r<RS>, <OFFSET>"
2263 address_word offset = EXTEND16 (OFFSET) << 2;
2267 if ((signed_word) GPR[RS] < 0)
2269 DELAY_SLOT (NIA + offset);
2272 NULLIFY_NEXT_INSTRUCTION ();
2277 000001,5.RS,00010,16.OFFSET:REGIMM:32::BLTZL
2278 "bltzl r<RS>, <OFFSET>"
2291 address_word offset = EXTEND16 (OFFSET) << 2;
2292 /* NOTE: The branch occurs AFTER the next instruction has been
2294 if ((signed_word) GPR[RS] < 0)
2296 DELAY_SLOT (NIA + offset);
2299 NULLIFY_NEXT_INSTRUCTION ();
2304 000101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNE
2305 "bne r<RS>, r<RT>, <OFFSET>"
2319 address_word offset = EXTEND16 (OFFSET) << 2;
2320 if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
2322 DELAY_SLOT (NIA + offset);
2328 010101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNEL
2329 "bnel r<RS>, r<RT>, <OFFSET>"
2342 address_word offset = EXTEND16 (OFFSET) << 2;
2343 if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
2345 DELAY_SLOT (NIA + offset);
2348 NULLIFY_NEXT_INSTRUCTION ();
2353 000000,20.CODE,001101:SPECIAL:32::BREAK
2368 do_break (SD_, instruction_0);
2373 011100,5.RS,5.RT,5.RD,00000,100001:SPECIAL2:32::CLO
2383 do_clo (SD_, RD, RS);
2388 011100,5.RS,5.RT,5.RD,00000,100000:SPECIAL2:32::CLZ
2398 do_clz (SD_, RD, RS);
2403 000000,5.RS,5.RT,5.RD,00000,101100:SPECIAL:64::DADD
2404 "dadd r<RD>, r<RS>, r<RT>"
2413 check_u64 (SD_, instruction_0);
2414 do_dadd (SD_, RD, RS, RT);
2419 011000,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDI
2420 "daddi r<RT>, r<RS>, <IMMEDIATE>"
2429 check_u64 (SD_, instruction_0);
2430 do_daddi (SD_, RT, RS, IMMEDIATE);
2435 :function:::void:do_daddiu:int rs, int rt, unsigned16 immediate
2437 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
2438 GPR[rt] = GPR[rs] + EXTEND16 (immediate);
2439 TRACE_ALU_RESULT (GPR[rt]);
2442 011001,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDIU
2443 "daddiu r<RT>, r<RS>, <IMMEDIATE>"
2452 check_u64 (SD_, instruction_0);
2453 do_daddiu (SD_, RS, RT, IMMEDIATE);
2458 :function:::void:do_daddu:int rs, int rt, int rd
2460 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2461 GPR[rd] = GPR[rs] + GPR[rt];
2462 TRACE_ALU_RESULT (GPR[rd]);
2465 000000,5.RS,5.RT,5.RD,00000,101101:SPECIAL:64::DADDU
2466 "daddu r<RD>, r<RS>, r<RT>"
2475 check_u64 (SD_, instruction_0);
2476 do_daddu (SD_, RS, RT, RD);
2481 011100,5.RS,5.RT,5.RD,00000,100101:SPECIAL2:64::DCLO
2489 check_u64 (SD_, instruction_0);
2490 do_dclo (SD_, RD, RS);
2495 011100,5.RS,5.RT,5.RD,00000,100100:SPECIAL2:64::DCLZ
2503 check_u64 (SD_, instruction_0);
2504 do_dclz (SD_, RD, RS);
2509 :function:::void:do_ddiv:int rs, int rt
2511 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
2512 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2514 signed64 n = GPR[rs];
2515 signed64 d = GPR[rt];
2520 lo = SIGNED64 (0x8000000000000000);
2523 else if (d == -1 && n == SIGNED64 (0x8000000000000000))
2525 lo = SIGNED64 (0x8000000000000000);
2536 TRACE_ALU_RESULT2 (HI, LO);
2539 000000,5.RS,5.RT,0000000000,011110:SPECIAL:64::DDIV
2549 check_u64 (SD_, instruction_0);
2550 do_ddiv (SD_, RS, RT);
2555 :function:::void:do_ddivu:int rs, int rt
2557 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
2558 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2560 unsigned64 n = GPR[rs];
2561 unsigned64 d = GPR[rt];
2566 lo = SIGNED64 (0x8000000000000000);
2577 TRACE_ALU_RESULT2 (HI, LO);
2580 000000,5.RS,5.RT,0000000000,011111:SPECIAL:64::DDIVU
2581 "ddivu r<RS>, r<RT>"
2590 check_u64 (SD_, instruction_0);
2591 do_ddivu (SD_, RS, RT);
2594 :function:::void:do_div:int rs, int rt
2596 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
2597 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2599 signed32 n = GPR[rs];
2600 signed32 d = GPR[rt];
2603 LO = EXTEND32 (0x80000000);
2606 else if (n == SIGNED32 (0x80000000) && d == -1)
2608 LO = EXTEND32 (0x80000000);
2613 LO = EXTEND32 (n / d);
2614 HI = EXTEND32 (n % d);
2617 TRACE_ALU_RESULT2 (HI, LO);
2620 000000,5.RS,5.RT,0000000000,011010:SPECIAL:32::DIV
2635 do_div (SD_, RS, RT);
2640 :function:::void:do_divu:int rs, int rt
2642 check_div_hilo (SD_, HIHISTORY, LOHISTORY);
2643 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2645 unsigned32 n = GPR[rs];
2646 unsigned32 d = GPR[rt];
2649 LO = EXTEND32 (0x80000000);
2654 LO = EXTEND32 (n / d);
2655 HI = EXTEND32 (n % d);
2658 TRACE_ALU_RESULT2 (HI, LO);
2661 000000,5.RS,5.RT,0000000000,011011:SPECIAL:32::DIVU
2676 do_divu (SD_, RS, RT);
2680 :function:::void:do_dmultx:int rs, int rt, int rd, int signed_p
2690 unsigned64 op1 = GPR[rs];
2691 unsigned64 op2 = GPR[rt];
2692 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
2693 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
2694 /* make signed multiply unsigned */
2698 if ((signed64) op1 < 0)
2703 if ((signed64) op2 < 0)
2709 /* multiply out the 4 sub products */
2710 m00 = ((unsigned64) VL4_8 (op1) * (unsigned64) VL4_8 (op2));
2711 m10 = ((unsigned64) VH4_8 (op1) * (unsigned64) VL4_8 (op2));
2712 m01 = ((unsigned64) VL4_8 (op1) * (unsigned64) VH4_8 (op2));
2713 m11 = ((unsigned64) VH4_8 (op1) * (unsigned64) VH4_8 (op2));
2714 /* add the products */
2715 mid = ((unsigned64) VH4_8 (m00)
2716 + (unsigned64) VL4_8 (m10)
2717 + (unsigned64) VL4_8 (m01));
2718 lo = U8_4 (mid, m00);
2720 + (unsigned64) VH4_8 (mid)
2721 + (unsigned64) VH4_8 (m01)
2722 + (unsigned64) VH4_8 (m10));
2732 /* save the result HI/LO (and a gpr) */
2737 TRACE_ALU_RESULT2 (HI, LO);
2740 :function:::void:do_dmult:int rs, int rt, int rd
2742 do_dmultx (SD_, rs, rt, rd, 1);
2745 000000,5.RS,5.RT,0000000000,011100:SPECIAL:64::DMULT
2746 "dmult r<RS>, r<RT>"
2754 check_u64 (SD_, instruction_0);
2755 do_dmult (SD_, RS, RT, 0);
2758 000000,5.RS,5.RT,5.RD,00000,011100:SPECIAL:64::DMULT
2759 "dmult r<RS>, r<RT>":RD == 0
2760 "dmult r<RD>, r<RS>, r<RT>"
2763 check_u64 (SD_, instruction_0);
2764 do_dmult (SD_, RS, RT, RD);
2769 :function:::void:do_dmultu:int rs, int rt, int rd
2771 do_dmultx (SD_, rs, rt, rd, 0);
2774 000000,5.RS,5.RT,0000000000,011101:SPECIAL:64::DMULTU
2775 "dmultu r<RS>, r<RT>"
2783 check_u64 (SD_, instruction_0);
2784 do_dmultu (SD_, RS, RT, 0);
2787 000000,5.RS,5.RT,5.RD,00000,011101:SPECIAL:64::DMULTU
2788 "dmultu r<RD>, r<RS>, r<RT>":RD == 0
2789 "dmultu r<RS>, r<RT>"
2792 check_u64 (SD_, instruction_0);
2793 do_dmultu (SD_, RS, RT, RD);
2797 :function:::unsigned64:do_dror:unsigned64 x,unsigned64 y
2802 TRACE_ALU_INPUT2 (x, y);
2803 result = ROTR64 (x, y);
2804 TRACE_ALU_RESULT (result);
2808 000000,00001,5.RT,5.RD,5.SHIFT,111010::64::DROR
2809 "dror r<RD>, r<RT>, <SHIFT>"
2814 check_u64 (SD_, instruction_0);
2815 GPR[RD] = do_dror (SD_, GPR[RT], SHIFT);
2818 000000,00001,5.RT,5.RD,5.SHIFT,111110::64::DROR32
2819 "dror32 r<RD>, r<RT>, <SHIFT>"
2824 check_u64 (SD_, instruction_0);
2825 GPR[RD] = do_dror (SD_, GPR[RT], SHIFT + 32);
2828 000000,5.RS,5.RT,5.RD,00001,010110::64::DRORV
2829 "drorv r<RD>, r<RT>, r<RS>"
2834 check_u64 (SD_, instruction_0);
2835 GPR[RD] = do_dror (SD_, GPR[RT], GPR[RS]);
2839 :function:::void:do_dsll:int rt, int rd, int shift
2841 TRACE_ALU_INPUT2 (GPR[rt], shift);
2842 GPR[rd] = GPR[rt] << shift;
2843 TRACE_ALU_RESULT (GPR[rd]);
2846 000000,00000,5.RT,5.RD,5.SHIFT,111000:SPECIAL:64::DSLL
2847 "dsll r<RD>, r<RT>, <SHIFT>"
2856 check_u64 (SD_, instruction_0);
2857 do_dsll (SD_, RT, RD, SHIFT);
2861 000000,00000,5.RT,5.RD,5.SHIFT,111100:SPECIAL:64::DSLL32
2862 "dsll32 r<RD>, r<RT>, <SHIFT>"
2871 check_u64 (SD_, instruction_0);
2872 do_dsll32 (SD_, RD, RT, SHIFT);
2875 :function:::void:do_dsllv:int rs, int rt, int rd
2877 int s = MASKED64 (GPR[rs], 5, 0);
2878 TRACE_ALU_INPUT2 (GPR[rt], s);
2879 GPR[rd] = GPR[rt] << s;
2880 TRACE_ALU_RESULT (GPR[rd]);
2883 000000,5.RS,5.RT,5.RD,00000,010100:SPECIAL:64::DSLLV
2884 "dsllv r<RD>, r<RT>, r<RS>"
2893 check_u64 (SD_, instruction_0);
2894 do_dsllv (SD_, RS, RT, RD);
2897 :function:::void:do_dsra:int rt, int rd, int shift
2899 TRACE_ALU_INPUT2 (GPR[rt], shift);
2900 GPR[rd] = ((signed64) GPR[rt]) >> shift;
2901 TRACE_ALU_RESULT (GPR[rd]);
2905 000000,00000,5.RT,5.RD,5.SHIFT,111011:SPECIAL:64::DSRA
2906 "dsra r<RD>, r<RT>, <SHIFT>"
2915 check_u64 (SD_, instruction_0);
2916 do_dsra (SD_, RT, RD, SHIFT);
2920 000000,00000,5.RT,5.RD,5.SHIFT,111111:SPECIAL:64::DSRA32
2921 "dsra32 r<RD>, r<RT>, <SHIFT>"
2930 check_u64 (SD_, instruction_0);
2931 do_dsra32 (SD_, RD, RT, SHIFT);
2935 :function:::void:do_dsrav:int rs, int rt, int rd
2937 int s = MASKED64 (GPR[rs], 5, 0);
2938 TRACE_ALU_INPUT2 (GPR[rt], s);
2939 GPR[rd] = ((signed64) GPR[rt]) >> s;
2940 TRACE_ALU_RESULT (GPR[rd]);
2943 000000,5.RS,5.RT,5.RD,00000,010111:SPECIAL:64::DSRAV
2944 "dsrav r<RD>, r<RT>, r<RS>"
2953 check_u64 (SD_, instruction_0);
2954 do_dsrav (SD_, RS, RT, RD);
2957 :function:::void:do_dsrl:int rt, int rd, int shift
2959 TRACE_ALU_INPUT2 (GPR[rt], shift);
2960 GPR[rd] = (unsigned64) GPR[rt] >> shift;
2961 TRACE_ALU_RESULT (GPR[rd]);
2965 000000,00000,5.RT,5.RD,5.SHIFT,111010:SPECIAL:64::DSRL
2966 "dsrl r<RD>, r<RT>, <SHIFT>"
2975 check_u64 (SD_, instruction_0);
2976 do_dsrl (SD_, RT, RD, SHIFT);
2980 000000,00000,5.RT,5.RD,5.SHIFT,111110:SPECIAL:64::DSRL32
2981 "dsrl32 r<RD>, r<RT>, <SHIFT>"
2990 check_u64 (SD_, instruction_0);
2991 do_dsrl32 (SD_, RD, RT, SHIFT);
2995 :function:::void:do_dsrlv:int rs, int rt, int rd
2997 int s = MASKED64 (GPR[rs], 5, 0);
2998 TRACE_ALU_INPUT2 (GPR[rt], s);
2999 GPR[rd] = (unsigned64) GPR[rt] >> s;
3000 TRACE_ALU_RESULT (GPR[rd]);
3005 000000,5.RS,5.RT,5.RD,00000,010110:SPECIAL:64::DSRLV
3006 "dsrlv r<RD>, r<RT>, r<RS>"
3015 check_u64 (SD_, instruction_0);
3016 do_dsrlv (SD_, RS, RT, RD);
3020 000000,5.RS,5.RT,5.RD,00000,101110:SPECIAL:64::DSUB
3021 "dsub r<RD>, r<RS>, r<RT>"
3030 check_u64 (SD_, instruction_0);
3031 do_dsub (SD_, RD, RS, RT);
3035 :function:::void:do_dsubu:int rs, int rt, int rd
3037 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3038 GPR[rd] = GPR[rs] - GPR[rt];
3039 TRACE_ALU_RESULT (GPR[rd]);
3042 000000,5.RS,5.RT,5.RD,00000,101111:SPECIAL:64::DSUBU
3043 "dsubu r<RD>, r<RS>, r<RT>"
3052 check_u64 (SD_, instruction_0);
3053 do_dsubu (SD_, RS, RT, RD);
3057 000010,26.INSTR_INDEX:NORMAL:32::J
3072 /* NOTE: The region used is that of the delay slot NIA and NOT the
3073 current instruction */
3074 address_word region = (NIA & MASK (63, 28));
3075 DELAY_SLOT (region | (INSTR_INDEX << 2));
3079 000011,26.INSTR_INDEX:NORMAL:32::JAL
3094 /* NOTE: The region used is that of the delay slot and NOT the
3095 current instruction */
3096 address_word region = (NIA & MASK (63, 28));
3098 DELAY_SLOT (region | (INSTR_INDEX << 2));
3101 000000,5.RS,00000,5.RD,00000,001001:SPECIAL:32::JALR
3102 "jalr r<RS>":RD == 31
3117 address_word temp = GPR[RS];
3122 000000,5.RS,00000,5.RD,10000,001001:SPECIAL:32::JALR_HB
3123 "jalr.hb r<RS>":RD == 31
3124 "jalr.hb r<RD>, r<RS>"
3128 address_word temp = GPR[RS];
3133 000000,5.RS,0000000000,00000,001000:SPECIAL:32::JR
3148 DELAY_SLOT (GPR[RS]);
3151 000000,5.RS,0000000000,10000,001000:SPECIAL:32::JR_HB
3156 DELAY_SLOT (GPR[RS]);
3159 :function:::unsigned_word:do_load:unsigned access, address_word base, address_word offset
3161 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
3162 address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
3163 address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
3170 vaddr = loadstore_ea (SD_, base, offset);
3171 if ((vaddr & access) != 0)
3173 SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map, access+1, vaddr, read_transfer, sim_core_unaligned_signal);
3175 AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
3176 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
3177 LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isDATA, isREAL);
3178 byte = ((vaddr & mask) ^ bigendiancpu);
3179 return (memval >> (8 * byte));
3182 :function:::unsigned_word:do_load_left:unsigned access, address_word base, address_word offset, unsigned_word rt
3184 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
3185 address_word reverseendian = (ReverseEndian ? -1 : 0);
3186 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
3195 unsigned_word lhs_mask;
3198 vaddr = loadstore_ea (SD_, base, offset);
3199 AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
3200 paddr = (paddr ^ (reverseendian & mask));
3201 if (BigEndianMem == 0)
3202 paddr = paddr & ~access;
3204 /* compute where within the word/mem we are */
3205 byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
3206 word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
3207 nr_lhs_bits = 8 * byte + 8;
3208 nr_rhs_bits = 8 * access - 8 * byte;
3209 /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
3211 /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
3212 (long) ((unsigned64) vaddr >> 32), (long) vaddr,
3213 (long) ((unsigned64) paddr >> 32), (long) paddr,
3214 word, byte, nr_lhs_bits, nr_rhs_bits); */
3216 LoadMemory (&memval, NULL, uncached, byte, paddr, vaddr, isDATA, isREAL);
3219 /* GPR{31..32-NR_LHS_BITS} = memval{NR_LHS_BITS-1..0} */
3220 temp = (memval << nr_rhs_bits);
3224 /* GPR{31..32-NR_LHS_BITS = memval{32+NR_LHS_BITS..32} */
3225 temp = (memval >> nr_lhs_bits);
3227 lhs_mask = LSMASK (nr_lhs_bits + nr_rhs_bits - 1, nr_rhs_bits);
3228 rt = (rt & ~lhs_mask) | (temp & lhs_mask);
3230 /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx & 0x%08lx%08lx -> 0x%08lx%08lx\n",
3231 (long) ((unsigned64) memval >> 32), (long) memval,
3232 (long) ((unsigned64) temp >> 32), (long) temp,
3233 (long) ((unsigned64) lhs_mask >> 32), (long) lhs_mask,
3234 (long) (rt >> 32), (long) rt); */
3238 :function:::unsigned_word:do_load_right:unsigned access, address_word base, address_word offset, unsigned_word rt
3240 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
3241 address_word reverseendian = (ReverseEndian ? -1 : 0);
3242 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
3249 vaddr = loadstore_ea (SD_, base, offset);
3250 AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
3251 /* NOTE: SPEC is wrong, has `BigEndianMem == 0' not `BigEndianMem != 0' */
3252 paddr = (paddr ^ (reverseendian & mask));
3253 if (BigEndianMem != 0)
3254 paddr = paddr & ~access;
3255 byte = ((vaddr & mask) ^ (bigendiancpu & mask));
3256 /* NOTE: SPEC is wrong, had `byte' not `access - byte'. See SW. */
3257 LoadMemory (&memval, NULL, uncached, access - (access & byte), paddr, vaddr, isDATA, isREAL);
3258 /* printf ("lr: 0x%08lx %d@0x%08lx 0x%08lx\n",
3259 (long) paddr, byte, (long) paddr, (long) memval); */
3261 unsigned_word screen = LSMASK (8 * (access - (byte & access) + 1) - 1, 0);
3263 rt |= (memval >> (8 * byte)) & screen;
3269 100000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LB
3270 "lb r<RT>, <OFFSET>(r<BASE>)"
3284 do_lb (SD_,RT,OFFSET,BASE);
3288 100100,5.BASE,5.RT,16.OFFSET:NORMAL:32::LBU
3289 "lbu r<RT>, <OFFSET>(r<BASE>)"
3303 do_lbu (SD_, RT,OFFSET,BASE);
3307 110111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LD
3308 "ld r<RT>, <OFFSET>(r<BASE>)"
3317 check_u64 (SD_, instruction_0);
3318 GPR[RT] = EXTEND64 (do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
3322 1101,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDCz
3323 "ldc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
3336 do_ldc (SD_, ZZ, RT, OFFSET, BASE);
3342 011010,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDL
3343 "ldl r<RT>, <OFFSET>(r<BASE>)"
3352 check_u64 (SD_, instruction_0);
3353 GPR[RT] = do_load_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
3357 011011,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDR
3358 "ldr r<RT>, <OFFSET>(r<BASE>)"
3367 check_u64 (SD_, instruction_0);
3368 GPR[RT] = do_load_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
3372 100001,5.BASE,5.RT,16.OFFSET:NORMAL:32::LH
3373 "lh r<RT>, <OFFSET>(r<BASE>)"
3387 do_lh (SD_,RT,OFFSET,BASE);
3391 100101,5.BASE,5.RT,16.OFFSET:NORMAL:32::LHU
3392 "lhu r<RT>, <OFFSET>(r<BASE>)"
3406 do_lhu (SD_,RT,OFFSET,BASE);
3410 110000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LL
3411 "ll r<RT>, <OFFSET>(r<BASE>)"
3423 do_ll (SD_, RT, OFFSET, BASE);
3427 110100,5.BASE,5.RT,16.OFFSET:NORMAL:64::LLD
3428 "lld r<RT>, <OFFSET>(r<BASE>)"
3437 check_u64 (SD_, instruction_0);
3438 do_lld (SD_, RT, OFFSET, BASE);
3442 001111,00000,5.RT,16.IMMEDIATE:NORMAL:32::LUI
3443 "lui r<RT>, %#lx<IMMEDIATE>"
3457 do_lui (SD_, RT, IMMEDIATE);
3461 100011,5.BASE,5.RT,16.OFFSET:NORMAL:32::LW
3462 "lw r<RT>, <OFFSET>(r<BASE>)"
3476 do_lw (SD_,RT,OFFSET,BASE);
3480 1100,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWCz
3481 "lwc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
3495 do_lwc (SD_, ZZ, RT, OFFSET, BASE);
3499 100010,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWL
3500 "lwl r<RT>, <OFFSET>(r<BASE>)"
3514 do_lwl (SD_, RT, OFFSET, BASE);
3518 100110,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWR
3519 "lwr r<RT>, <OFFSET>(r<BASE>)"
3533 do_lwr (SD_, RT, OFFSET, BASE);
3537 100111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LWU
3538 "lwu r<RT>, <OFFSET>(r<BASE>)"
3547 do_lwu (SD_, RT, OFFSET, BASE, instruction_0);
3552 011100,5.RS,5.RT,00000,00000,000000:SPECIAL2:32::MADD
3558 do_madd (SD_, RS, RT);
3562 011100,5.RS,5.RT,000,2.AC,00000,000000:SPECIAL2:32::MADD
3563 "madd r<RS>, r<RT>":AC == 0
3564 "madd ac<AC>, r<RS>, r<RT>"
3569 do_dsp_madd (SD_, AC, RS, RT);
3573 011100,5.RS,5.RT,00000,00000,000001:SPECIAL2:32::MADDU
3574 "maddu r<RS>, r<RT>"
3579 do_maddu (SD_, RS, RT);
3583 011100,5.RS,5.RT,000,2.AC,00000,000001:SPECIAL2:32::MADDU
3584 "maddu r<RS>, r<RT>":AC == 0
3585 "maddu ac<AC>, r<RS>, r<RT>"
3590 do_dsp_maddu (SD_, AC, RS, RT);
3594 :function:::void:do_mfhi:int rd
3596 check_mf_hilo (SD_, HIHISTORY, LOHISTORY);
3597 TRACE_ALU_INPUT1 (HI);
3599 TRACE_ALU_RESULT (GPR[rd]);
3602 000000,0000000000,5.RD,00000,010000:SPECIAL:32::MFHI
3619 000000,000,2.AC,00000,5.RD,00000,010000:SPECIAL:32::MFHI
3620 "mfhi r<RD>":AC == 0
3621 "mfhi r<RD>, ac<AC>"
3626 do_dsp_mfhi (SD_, AC, RD);
3630 :function:::void:do_mflo:int rd
3632 check_mf_hilo (SD_, LOHISTORY, HIHISTORY);
3633 TRACE_ALU_INPUT1 (LO);
3635 TRACE_ALU_RESULT (GPR[rd]);
3638 000000,0000000000,5.RD,00000,010010:SPECIAL:32::MFLO
3655 000000,000,2.AC,00000,5.RD,00000,010010:SPECIAL:32::MFLO
3656 "mflo r<RD>":AC == 0
3657 "mflo r<RD>, ac<AC>"
3662 do_dsp_mflo (SD_, AC, RD);
3666 000000,5.RS,5.RT,5.RD,00000,001011:SPECIAL:32::MOVN
3667 "movn r<RD>, r<RS>, r<RT>"
3676 do_movn (SD_, RD, RS, RT);
3681 000000,5.RS,5.RT,5.RD,00000,001010:SPECIAL:32::MOVZ
3682 "movz r<RD>, r<RS>, r<RT>"
3691 do_movz (SD_, RD, RS, RT);
3696 011100,5.RS,5.RT,00000,00000,000100:SPECIAL2:32::MSUB
3702 do_msub (SD_, RS, RT);
3706 011100,5.RS,5.RT,000,2.AC,00000,000100:SPECIAL2:32::MSUB
3707 "msub r<RS>, r<RT>":AC == 0
3708 "msub ac<AC>, r<RS>, r<RT>"
3713 do_dsp_msub (SD_, AC, RS, RT);
3717 011100,5.RS,5.RT,00000,00000,000101:SPECIAL2:32::MSUBU
3718 "msubu r<RS>, r<RT>"
3723 do_msubu (SD_, RS, RT);
3727 011100,5.RS,5.RT,000,2.AC,00000,000101:SPECIAL2:32::MSUBU
3728 "msubu r<RS>, r<RT>":AC == 0
3729 "msubu ac<AC>, r<RS>, r<RT>"
3734 do_dsp_msubu (SD_, AC, RS, RT);
3738 000000,5.RS,000000000000000,010001:SPECIAL:32::MTHI
3755 000000,5.RS,00000,000,2.AC,00000,010001:SPECIAL:32::MTHI
3756 "mthi r<RS>":AC == 0
3757 "mthi r<RS>, ac<AC>"
3762 do_dsp_mthi (SD_, AC, RS);
3766 000000,5.RS,000000000000000,010011:SPECIAL:32::MTLO
3783 000000,5.RS,00000,000,2.AC,00000,010011:SPECIAL:32::MTLO
3784 "mtlo r<RS>":AC == 0
3785 "mtlo r<RS>, ac<AC>"
3790 do_dsp_mtlo (SD_, AC, RS);
3794 011100,5.RS,5.RT,5.RD,00000,000010:SPECIAL2:32::MUL
3795 "mul r<RD>, r<RS>, r<RT>"
3802 do_mul (SD_, RD, RS, RT);
3807 :function:::void:do_mult:int rs, int rt, int rd
3810 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
3811 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
3813 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3814 prod = (((signed64)(signed32) GPR[rs])
3815 * ((signed64)(signed32) GPR[rt]));
3816 LO = EXTEND32 (VL4_8 (prod));
3817 HI = EXTEND32 (VH4_8 (prod));
3818 ACX = 0; /* SmartMIPS */
3821 TRACE_ALU_RESULT2 (HI, LO);
3824 000000,5.RS,5.RT,0000000000,011000:SPECIAL:32::MULT
3835 do_mult (SD_, RS, RT, 0);
3839 000000,5.RS,5.RT,000,2.AC,00000,011000:SPECIAL:32::MULT
3840 "mult r<RS>, r<RT>":AC == 0
3841 "mult ac<AC>, r<RS>, r<RT>"
3846 do_dsp_mult (SD_, AC, RS, RT);
3850 000000,5.RS,5.RT,5.RD,00000,011000:SPECIAL:32::MULT
3851 "mult r<RS>, r<RT>":RD == 0
3852 "mult r<RD>, r<RS>, r<RT>"
3856 do_mult (SD_, RS, RT, RD);
3860 :function:::void:do_multu:int rs, int rt, int rd
3863 check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
3864 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
3866 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3867 prod = (((unsigned64)(unsigned32) GPR[rs])
3868 * ((unsigned64)(unsigned32) GPR[rt]));
3869 LO = EXTEND32 (VL4_8 (prod));
3870 HI = EXTEND32 (VH4_8 (prod));
3873 TRACE_ALU_RESULT2 (HI, LO);
3876 000000,5.RS,5.RT,0000000000,011001:SPECIAL:32::MULTU
3877 "multu r<RS>, r<RT>"
3887 do_multu (SD_, RS, RT, 0);
3891 000000,5.RS,5.RT,000,2.AC,00000,011001:SPECIAL:32::MULTU
3892 "multu r<RS>, r<RT>":AC == 0
3893 "multu r<RS>, r<RT>"
3898 do_dsp_multu (SD_, AC, RS, RT);
3902 000000,5.RS,5.RT,5.RD,00000,011001:SPECIAL:32::MULTU
3903 "multu r<RS>, r<RT>":RD == 0
3904 "multu r<RD>, r<RS>, r<RT>"
3908 do_multu (SD_, RS, RT, RD);
3912 :function:::void:do_nor:int rs, int rt, int rd
3914 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3915 GPR[rd] = ~ (GPR[rs] | GPR[rt]);
3916 TRACE_ALU_RESULT (GPR[rd]);
3919 000000,5.RS,5.RT,5.RD,00000,100111:SPECIAL:32::NOR
3920 "nor r<RD>, r<RS>, r<RT>"
3934 do_nor (SD_, RS, RT, RD);
3938 :function:::void:do_or:int rs, int rt, int rd
3940 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
3941 GPR[rd] = (GPR[rs] | GPR[rt]);
3942 TRACE_ALU_RESULT (GPR[rd]);
3945 000000,5.RS,5.RT,5.RD,00000,100101:SPECIAL:32::OR
3946 "or r<RD>, r<RS>, r<RT>"
3960 do_or (SD_, RS, RT, RD);
3965 :function:::void:do_ori:int rs, int rt, unsigned immediate
3967 TRACE_ALU_INPUT2 (GPR[rs], immediate);
3968 GPR[rt] = (GPR[rs] | immediate);
3969 TRACE_ALU_RESULT (GPR[rt]);
3972 001101,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ORI
3973 "ori r<RT>, r<RS>, %#lx<IMMEDIATE>"
3987 do_ori (SD_, RS, RT, IMMEDIATE);
3991 110011,5.BASE,5.HINT,16.OFFSET:NORMAL:32::PREF
3992 "pref <HINT>, <OFFSET>(r<BASE>)"
4001 do_pref (SD_, HINT, OFFSET, BASE);
4005 :function:::unsigned64:do_ror:unsigned32 x,unsigned32 y
4010 TRACE_ALU_INPUT2 (x, y);
4011 result = EXTEND32 (ROTR32 (x, y));
4012 TRACE_ALU_RESULT (result);
4016 000000,00001,5.RT,5.RD,5.SHIFT,000010::32::ROR
4017 "ror r<RD>, r<RT>, <SHIFT>"
4024 GPR[RD] = do_ror (SD_, GPR[RT], SHIFT);
4027 000000,5.RS,5.RT,5.RD,00001,000110::32::RORV
4028 "rorv r<RD>, r<RT>, r<RS>"
4035 GPR[RD] = do_ror (SD_, GPR[RT], GPR[RS]);
4039 :function:::void:do_store:unsigned access, address_word base, address_word offset, unsigned_word word
4041 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
4042 address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
4043 address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
4050 vaddr = loadstore_ea (SD_, base, offset);
4051 if ((vaddr & access) != 0)
4053 SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map, access+1, vaddr, write_transfer, sim_core_unaligned_signal);
4055 AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
4056 paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
4057 byte = ((vaddr & mask) ^ bigendiancpu);
4058 memval = (word << (8 * byte));
4059 StoreMemory (uncached, access, memval, 0, paddr, vaddr, isREAL);
4062 :function:::void:do_store_left:unsigned access, address_word base, address_word offset, unsigned_word rt
4064 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
4065 address_word reverseendian = (ReverseEndian ? -1 : 0);
4066 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
4076 vaddr = loadstore_ea (SD_, base, offset);
4077 AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
4078 paddr = (paddr ^ (reverseendian & mask));
4079 if (BigEndianMem == 0)
4080 paddr = paddr & ~access;
4082 /* compute where within the word/mem we are */
4083 byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
4084 word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
4085 nr_lhs_bits = 8 * byte + 8;
4086 nr_rhs_bits = 8 * access - 8 * byte;
4087 /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
4088 /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
4089 (long) ((unsigned64) vaddr >> 32), (long) vaddr,
4090 (long) ((unsigned64) paddr >> 32), (long) paddr,
4091 word, byte, nr_lhs_bits, nr_rhs_bits); */
4095 memval = (rt >> nr_rhs_bits);
4099 memval = (rt << nr_lhs_bits);
4101 /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx\n",
4102 (long) ((unsigned64) rt >> 32), (long) rt,
4103 (long) ((unsigned64) memval >> 32), (long) memval); */
4104 StoreMemory (uncached, byte, memval, 0, paddr, vaddr, isREAL);
4107 :function:::void:do_store_right:unsigned access, address_word base, address_word offset, unsigned_word rt
4109 address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
4110 address_word reverseendian = (ReverseEndian ? -1 : 0);
4111 address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
4118 vaddr = loadstore_ea (SD_, base, offset);
4119 AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
4120 paddr = (paddr ^ (reverseendian & mask));
4121 if (BigEndianMem != 0)
4123 byte = ((vaddr & mask) ^ (bigendiancpu & mask));
4124 memval = (rt << (byte * 8));
4125 StoreMemory (uncached, access - (access & byte), memval, 0, paddr, vaddr, isREAL);
4129 101000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SB
4130 "sb r<RT>, <OFFSET>(r<BASE>)"
4144 do_store (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4148 111000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SC
4149 "sc r<RT>, <OFFSET>(r<BASE>)"
4161 do_sc (SD_, RT, OFFSET, BASE, instruction_0);
4165 111100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SCD
4166 "scd r<RT>, <OFFSET>(r<BASE>)"
4175 check_u64 (SD_, instruction_0);
4176 do_scd (SD_, RT, OFFSET, BASE);
4180 111111,5.BASE,5.RT,16.OFFSET:NORMAL:64::SD
4181 "sd r<RT>, <OFFSET>(r<BASE>)"
4190 check_u64 (SD_, instruction_0);
4191 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4195 1111,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDCz
4196 "sdc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
4208 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (ZZ, RT));
4212 101100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDL
4213 "sdl r<RT>, <OFFSET>(r<BASE>)"
4222 check_u64 (SD_, instruction_0);
4223 do_store_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4227 101101,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDR
4228 "sdr r<RT>, <OFFSET>(r<BASE>)"
4237 check_u64 (SD_, instruction_0);
4238 do_store_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4243 101001,5.BASE,5.RT,16.OFFSET:NORMAL:32::SH
4244 "sh r<RT>, <OFFSET>(r<BASE>)"
4258 do_store (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4262 :function:::void:do_sll:int rt, int rd, int shift
4264 unsigned32 temp = (GPR[rt] << shift);
4265 TRACE_ALU_INPUT2 (GPR[rt], shift);
4266 GPR[rd] = EXTEND32 (temp);
4267 TRACE_ALU_RESULT (GPR[rd]);
4270 000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLLa
4271 "nop":RD == 0 && RT == 0 && SHIFT == 0
4272 "sll r<RD>, r<RT>, <SHIFT>"
4282 /* Skip shift for NOP, so that there won't be lots of extraneous
4284 if (RD != 0 || RT != 0 || SHIFT != 0)
4285 do_sll (SD_, RT, RD, SHIFT);
4288 000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLLb
4289 "nop":RD == 0 && RT == 0 && SHIFT == 0
4290 "ssnop":RD == 0 && RT == 0 && SHIFT == 1
4291 "sll r<RD>, r<RT>, <SHIFT>"
4297 /* Skip shift for NOP and SSNOP, so that there won't be lots of
4298 extraneous trace output. */
4299 if (RD != 0 || RT != 0 || (SHIFT != 0 && SHIFT != 1))
4300 do_sll (SD_, RT, RD, SHIFT);
4304 :function:::void:do_sllv:int rs, int rt, int rd
4306 int s = MASKED (GPR[rs], 4, 0);
4307 unsigned32 temp = (GPR[rt] << s);
4308 TRACE_ALU_INPUT2 (GPR[rt], s);
4309 GPR[rd] = EXTEND32 (temp);
4310 TRACE_ALU_RESULT (GPR[rd]);
4313 000000,5.RS,5.RT,5.RD,00000,000100:SPECIAL:32::SLLV
4314 "sllv r<RD>, r<RT>, r<RS>"
4328 do_sllv (SD_, RS, RT, RD);
4332 :function:::void:do_slt:int rs, int rt, int rd
4334 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
4335 GPR[rd] = ((signed_word) GPR[rs] < (signed_word) GPR[rt]);
4336 TRACE_ALU_RESULT (GPR[rd]);
4339 000000,5.RS,5.RT,5.RD,00000,101010:SPECIAL:32::SLT
4340 "slt r<RD>, r<RS>, r<RT>"
4354 do_slt (SD_, RS, RT, RD);
4358 :function:::void:do_slti:int rs, int rt, unsigned16 immediate
4360 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
4361 GPR[rt] = ((signed_word) GPR[rs] < (signed_word) EXTEND16 (immediate));
4362 TRACE_ALU_RESULT (GPR[rt]);
4365 001010,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTI
4366 "slti r<RT>, r<RS>, <IMMEDIATE>"
4380 do_slti (SD_, RS, RT, IMMEDIATE);
4384 :function:::void:do_sltiu:int rs, int rt, unsigned16 immediate
4386 TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
4387 GPR[rt] = ((unsigned_word) GPR[rs] < (unsigned_word) EXTEND16 (immediate));
4388 TRACE_ALU_RESULT (GPR[rt]);
4391 001011,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTIU
4392 "sltiu r<RT>, r<RS>, <IMMEDIATE>"
4406 do_sltiu (SD_, RS, RT, IMMEDIATE);
4411 :function:::void:do_sltu:int rs, int rt, int rd
4413 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
4414 GPR[rd] = ((unsigned_word) GPR[rs] < (unsigned_word) GPR[rt]);
4415 TRACE_ALU_RESULT (GPR[rd]);
4418 000000,5.RS,5.RT,5.RD,00000,101011:SPECIAL:32::SLTU
4419 "sltu r<RD>, r<RS>, r<RT>"
4433 do_sltu (SD_, RS, RT, RD);
4437 :function:::void:do_sra:int rt, int rd, int shift
4439 signed32 temp = (signed32) GPR[rt] >> shift;
4440 if (NotWordValue (GPR[rt]))
4442 TRACE_ALU_INPUT2 (GPR[rt], shift);
4443 GPR[rd] = EXTEND32 (temp);
4444 TRACE_ALU_RESULT (GPR[rd]);
4447 000000,00000,5.RT,5.RD,5.SHIFT,000011:SPECIAL:32::SRA
4448 "sra r<RD>, r<RT>, <SHIFT>"
4462 do_sra (SD_, RT, RD, SHIFT);
4467 :function:::void:do_srav:int rs, int rt, int rd
4469 int s = MASKED (GPR[rs], 4, 0);
4470 signed32 temp = (signed32) GPR[rt] >> s;
4471 if (NotWordValue (GPR[rt]))
4473 TRACE_ALU_INPUT2 (GPR[rt], s);
4474 GPR[rd] = EXTEND32 (temp);
4475 TRACE_ALU_RESULT (GPR[rd]);
4478 000000,5.RS,5.RT,5.RD,00000,000111:SPECIAL:32::SRAV
4479 "srav r<RD>, r<RT>, r<RS>"
4493 do_srav (SD_, RS, RT, RD);
4498 :function:::void:do_srl:int rt, int rd, int shift
4500 unsigned32 temp = (unsigned32) GPR[rt] >> shift;
4501 if (NotWordValue (GPR[rt]))
4503 TRACE_ALU_INPUT2 (GPR[rt], shift);
4504 GPR[rd] = EXTEND32 (temp);
4505 TRACE_ALU_RESULT (GPR[rd]);
4508 000000,00000,5.RT,5.RD,5.SHIFT,000010:SPECIAL:32::SRL
4509 "srl r<RD>, r<RT>, <SHIFT>"
4523 do_srl (SD_, RT, RD, SHIFT);
4527 :function:::void:do_srlv:int rs, int rt, int rd
4529 int s = MASKED (GPR[rs], 4, 0);
4530 unsigned32 temp = (unsigned32) GPR[rt] >> s;
4531 if (NotWordValue (GPR[rt]))
4533 TRACE_ALU_INPUT2 (GPR[rt], s);
4534 GPR[rd] = EXTEND32 (temp);
4535 TRACE_ALU_RESULT (GPR[rd]);
4538 000000,5.RS,5.RT,5.RD,00000,000110:SPECIAL:32::SRLV
4539 "srlv r<RD>, r<RT>, r<RS>"
4553 do_srlv (SD_, RS, RT, RD);
4557 000000,5.RS,5.RT,5.RD,00000,100010:SPECIAL:32::SUB
4558 "sub r<RD>, r<RS>, r<RT>"
4572 do_sub (SD_, RD, RS, RT);
4576 :function:::void:do_subu:int rs, int rt, int rd
4578 if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
4580 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
4581 GPR[rd] = EXTEND32 (GPR[rs] - GPR[rt]);
4582 TRACE_ALU_RESULT (GPR[rd]);
4585 000000,5.RS,5.RT,5.RD,00000,100011:SPECIAL:32::SUBU
4586 "subu r<RD>, r<RS>, r<RT>"
4600 do_subu (SD_, RS, RT, RD);
4604 101011,5.BASE,5.RT,16.OFFSET:NORMAL:32::SW
4605 "sw r<RT>, <OFFSET>(r<BASE>)"
4619 do_sw (SD_, RT, OFFSET, BASE);
4623 1110,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWCz
4624 "swc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
4638 do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), COP_SW (ZZ, RT));
4642 101010,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWL
4643 "swl r<RT>, <OFFSET>(r<BASE>)"
4657 do_store_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4661 101110,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWR
4662 "swr r<RT>, <OFFSET>(r<BASE>)"
4676 do_store_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
4680 000000,000000000000000,5.STYPE,001111:SPECIAL:32::SYNC
4695 SyncOperation (STYPE);
4699 000000,20.CODE,001100:SPECIAL:32::SYSCALL
4700 "syscall %#lx<CODE>"
4714 SignalException (SystemCall, instruction_0);
4718 000000,5.RS,5.RT,10.CODE,110100:SPECIAL:32::TEQ
4731 do_teq (SD_, RS, RT, instruction_0);
4735 000001,5.RS,01100,16.IMMEDIATE:REGIMM:32::TEQI
4736 "teqi r<RS>, <IMMEDIATE>"
4748 do_teqi (SD_, RS, IMMEDIATE, instruction_0);
4752 000000,5.RS,5.RT,10.CODE,110000:SPECIAL:32::TGE
4765 do_tge (SD_, RS, RT, instruction_0);
4769 000001,5.RS,01000,16.IMMEDIATE:REGIMM:32::TGEI
4770 "tgei r<RS>, <IMMEDIATE>"
4782 do_tgei (SD_, RS, IMMEDIATE, instruction_0);
4786 000001,5.RS,01001,16.IMMEDIATE:REGIMM:32::TGEIU
4787 "tgeiu r<RS>, <IMMEDIATE>"
4799 do_tgeiu (SD_, RS, IMMEDIATE, instruction_0);
4803 000000,5.RS,5.RT,10.CODE,110001:SPECIAL:32::TGEU
4816 do_tgeu (SD_, RS, RT, instruction_0);
4820 000000,5.RS,5.RT,10.CODE,110010:SPECIAL:32::TLT
4833 do_tlt (SD_, RS, RT, instruction_0);
4837 000001,5.RS,01010,16.IMMEDIATE:REGIMM:32::TLTI
4838 "tlti r<RS>, <IMMEDIATE>"
4850 do_tlti (SD_, RS, IMMEDIATE, instruction_0);
4854 000001,5.RS,01011,16.IMMEDIATE:REGIMM:32::TLTIU
4855 "tltiu r<RS>, <IMMEDIATE>"
4867 do_tltiu (SD_, RS, IMMEDIATE, instruction_0);
4871 000000,5.RS,5.RT,10.CODE,110011:SPECIAL:32::TLTU
4884 do_tltu (SD_, RS, RT, instruction_0);
4888 000000,5.RS,5.RT,10.CODE,110110:SPECIAL:32::TNE
4901 do_tne (SD_, RS, RT, instruction_0);
4905 000001,5.RS,01110,16.IMMEDIATE:REGIMM:32::TNEI
4906 "tnei r<RS>, <IMMEDIATE>"
4918 do_tnei (SD_, RS, IMMEDIATE, instruction_0);
4922 :function:::void:do_xor:int rs, int rt, int rd
4924 TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
4925 GPR[rd] = GPR[rs] ^ GPR[rt];
4926 TRACE_ALU_RESULT (GPR[rd]);
4929 000000,5.RS,5.RT,5.RD,00000,100110:SPECIAL:32::XOR
4930 "xor r<RD>, r<RS>, r<RT>"
4944 do_xor (SD_, RS, RT, RD);
4948 :function:::void:do_xori:int rs, int rt, unsigned16 immediate
4950 TRACE_ALU_INPUT2 (GPR[rs], immediate);
4951 GPR[rt] = GPR[rs] ^ immediate;
4952 TRACE_ALU_RESULT (GPR[rt]);
4955 001110,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::XORI
4956 "xori r<RT>, r<RS>, %#lx<IMMEDIATE>"
4970 do_xori (SD_, RS, RT, IMMEDIATE);
4975 // MIPS Architecture:
4977 // FPU Instruction Set (COP1 & COP1X)
4985 case fmt_single: return "s";
4986 case fmt_double: return "d";
4987 case fmt_word: return "w";
4988 case fmt_long: return "l";
4989 case fmt_ps: return "ps";
4990 default: return "?";
5010 :%s::::COND:int cond
5014 case 00: return "f";
5015 case 01: return "un";
5016 case 02: return "eq";
5017 case 03: return "ueq";
5018 case 04: return "olt";
5019 case 05: return "ult";
5020 case 06: return "ole";
5021 case 07: return "ule";
5022 case 010: return "sf";
5023 case 011: return "ngle";
5024 case 012: return "seq";
5025 case 013: return "ngl";
5026 case 014: return "lt";
5027 case 015: return "nge";
5028 case 016: return "le";
5029 case 017: return "ngt";
5030 default: return "?";
5037 // Check that the given FPU format is usable, and signal a
5038 // ReservedInstruction exception if not.
5041 // check_fmt_p checks that the format is single, double, or paired single.
5042 :function:::void:check_fmt_p:int fmt, instruction_word insn
5052 /* None of these ISAs support Paired Single, so just fall back to
5053 the single/double check. */
5054 if ((fmt != fmt_single) && (fmt != fmt_double))
5055 SignalException (ReservedInstruction, insn);
5058 :function:::void:check_fmt_p:int fmt, instruction_word insn
5062 if ((fmt != fmt_single) && (fmt != fmt_double) && (fmt != fmt_ps))
5063 SignalException (ReservedInstruction, insn);
5066 :function:::void:check_fmt_p:int fmt, instruction_word insn
5072 if ((fmt != fmt_single) && (fmt != fmt_double)
5073 && (fmt != fmt_ps || (UserMode && (SR & (status_UX|status_PX)) == 0)))
5074 SignalException (ReservedInstruction, insn);
5080 // Check that the FPU is currently usable, and signal a CoProcessorUnusable
5081 // exception if not.
5084 :function:::void:check_fpu:
5100 if (! COP_Usable (1))
5101 SignalExceptionCoProcessorUnusable (1);
5107 // Load a double word FP value using 2 32-bit memory cycles a la MIPS II
5108 // or MIPS32. do_load cannot be used instead because it returns an
5109 // unsigned_word, which is limited to the size of the machine's registers.
5112 :function:::unsigned64:do_load_double:address_word base, address_word offset
5118 int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
5125 vaddr = loadstore_ea (SD_, base, offset);
5126 if ((vaddr & AccessLength_DOUBLEWORD) != 0)
5128 SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map,
5129 AccessLength_DOUBLEWORD + 1, vaddr, read_transfer,
5130 sim_core_unaligned_signal);
5132 AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET,
5134 LoadMemory (&memval, NULL, uncached, AccessLength_WORD, paddr, vaddr,
5136 v = (unsigned64)memval;
5137 LoadMemory (&memval, NULL, uncached, AccessLength_WORD, paddr + 4, vaddr + 4,
5139 return (bigendian ? ((v << 32) | memval) : (v | (memval << 32)));
5145 // Store a double word FP value using 2 32-bit memory cycles a la MIPS II
5146 // or MIPS32. do_load cannot be used instead because it returns an
5147 // unsigned_word, which is limited to the size of the machine's registers.
5150 :function:::void:do_store_double:address_word base, address_word offset, unsigned64 v
5156 int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
5162 vaddr = loadstore_ea (SD_, base, offset);
5163 if ((vaddr & AccessLength_DOUBLEWORD) != 0)
5165 SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map,
5166 AccessLength_DOUBLEWORD + 1, vaddr, write_transfer,
5167 sim_core_unaligned_signal);
5169 AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET,
5171 memval = (bigendian ? (v >> 32) : (v & 0xFFFFFFFF));
5172 StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
5174 memval = (bigendian ? (v & 0xFFFFFFFF) : (v >> 32));
5175 StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr + 4, vaddr + 4,
5180 010001,10,3.FMT!2!3!4!5!7,00000,5.FS,5.FD,000101:COP1:32,f::ABS.fmt
5181 "abs.%s<FMT> f<FD>, f<FS>"
5195 do_abs_fmt (SD_, FMT, FD, FS, instruction_0);
5200 010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,5.FD,000000:COP1:32,f::ADD.fmt
5201 "add.%s<FMT> f<FD>, f<FS>, f<FT>"
5215 do_add_fmt (SD_, FMT, FD, FS, FT, instruction_0);
5219 010011,5.RS,5.FT,5.FS,5.FD,011,110:COP1X:32,f::ALNV.PS
5220 "alnv.ps f<FD>, f<FS>, f<FT>, r<RS>"
5226 do_alnv_ps (SD_, FD, FS, FT, RS, instruction_0);
5235 010001,01000,3.0,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1a
5236 "bc1%s<TF>%s<ND> <OFFSET>"
5242 TRACE_BRANCH_INPUT (PREVCOC1());
5243 if (PREVCOC1() == TF)
5245 address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
5246 TRACE_BRANCH_RESULT (dest);
5251 TRACE_BRANCH_RESULT (0);
5252 NULLIFY_NEXT_INSTRUCTION ();
5256 TRACE_BRANCH_RESULT (NIA);
5260 010001,01000,3.CC,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1b
5261 "bc1%s<TF>%s<ND> <OFFSET>":CC == 0
5262 "bc1%s<TF>%s<ND> <CC>, <OFFSET>"
5274 if (GETFCC(CC) == TF)
5276 address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
5281 NULLIFY_NEXT_INSTRUCTION ();
5286 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
5287 "c.%s<COND>.%s<FMT> f<FS>, f<FT>"
5294 Compare (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt, COND, 0);
5295 TRACE_ALU_RESULT (ValueFCR (31));
5298 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
5299 "c.%s<COND>.%s<FMT> f<FS>, f<FT>":CC == 0
5300 "c.%s<COND>.%s<FMT> <CC>, f<FS>, f<FT>"
5311 do_c_cond_fmt (SD_, COND, FMT, CC, FS, FT, instruction_0);
5315 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001010:COP1:32,f::CEIL.L.fmt
5316 "ceil.l.%s<FMT> f<FD>, f<FS>"
5327 do_ceil_fmt (SD_, fmt_long, FMT, FD, FS, instruction_0);
5331 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001110:COP1:32,f::CEIL.W
5332 "ceil.w.%s<FMT> f<FD>, f<FS>"
5345 do_ceil_fmt (SD_, fmt_word, FMT, FD, FS, instruction_0);
5349 010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1a
5357 PENDING_FILL (RT, EXTEND32 (FCR0));
5359 PENDING_FILL (RT, EXTEND32 (FCR31));
5363 010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1b
5371 if (FS == 0 || FS == 31)
5373 unsigned_word fcr = ValueFCR (FS);
5374 TRACE_ALU_INPUT1 (fcr);
5378 TRACE_ALU_RESULT (GPR[RT]);
5381 010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1c
5389 do_cfc1 (SD_, RT, FS);
5392 010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1a
5400 PENDING_FILL (FCRCS_REGNUM, VL4_8 (GPR[RT]));
5404 010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1b
5412 TRACE_ALU_INPUT1 (GPR[RT]);
5414 StoreFCR (FS, GPR[RT]);
5418 010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1c
5426 do_ctc1 (SD_, RT, FS);
5431 // FIXME: Does not correctly differentiate between mips*
5433 010001,10,3.FMT!1!2!3!6!7,00000,5.FS,5.FD,100001:COP1:32,f::CVT.D.fmt
5434 "cvt.d.%s<FMT> f<FD>, f<FS>"
5448 do_cvt_d_fmt (SD_, FMT, FD, FS, instruction_0);
5452 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,100101:COP1:32,f::CVT.L.fmt
5453 "cvt.l.%s<FMT> f<FD>, f<FS>"
5464 do_cvt_l_fmt (SD_, FMT, FD, FS, instruction_0);
5468 010001,10,000,5.FT,5.FS,5.FD,100110:COP1:32,f::CVT.PS.S
5469 "cvt.ps.s f<FD>, f<FS>, f<FT>"
5475 do_cvt_ps_s (SD_, FD, FS, FT, instruction_0);
5480 // FIXME: Does not correctly differentiate between mips*
5482 010001,10,3.FMT!0!2!3!6!7,00000,5.FS,5.FD,100000:COP1:32,f::CVT.S.fmt
5483 "cvt.s.%s<FMT> f<FD>, f<FS>"
5497 do_cvt_s_fmt (SD_, FMT, FD, FS, instruction_0);
5501 010001,10,110,00000,5.FS,5.FD,101000:COP1:32,f::CVT.S.PL
5502 "cvt.s.pl f<FD>, f<FS>"
5508 do_cvt_s_pl (SD_, FD, FS, instruction_0);
5512 010001,10,110,00000,5.FS,5.FD,100000:COP1:32,f::CVT.S.PU
5513 "cvt.s.pu f<FD>, f<FS>"
5519 do_cvt_s_pu (SD_, FD, FS, instruction_0);
5523 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,100100:COP1:32,f::CVT.W.fmt
5524 "cvt.w.%s<FMT> f<FD>, f<FS>"
5538 do_cvt_w_fmt (SD_, FMT, FD, FS, instruction_0);
5542 010001,10,3.FMT!2!3!4!5!6!7,5.FT,5.FS,5.FD,000011:COP1:32,f::DIV.fmt
5543 "div.%s<FMT> f<FD>, f<FS>, f<FT>"
5557 do_div_fmt (SD_, FMT, FD, FS, FT, instruction_0);
5561 010001,00001,5.RT,5.FS,00000000000:COP1:64,f::DMFC1a
5562 "dmfc1 r<RT>, f<FS>"
5567 check_u64 (SD_, instruction_0);
5568 if (SizeFGR () == 64)
5570 else if ((FS & 0x1) == 0)
5571 v = SET64HI (FGR[FS+1]) | FGR[FS];
5573 v = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
5574 PENDING_FILL (RT, v);
5575 TRACE_ALU_RESULT (v);
5578 010001,00001,5.RT,5.FS,00000000000:COP1:64,f::DMFC1b
5579 "dmfc1 r<RT>, f<FS>"
5589 check_u64 (SD_, instruction_0);
5590 do_dmfc1b (SD_, RT, FS);
5594 010001,00101,5.RT,5.FS,00000000000:COP1:64,f::DMTC1a
5595 "dmtc1 r<RT>, f<FS>"
5600 check_u64 (SD_, instruction_0);
5601 if (SizeFGR () == 64)
5602 PENDING_FILL ((FS + FGR_BASE), GPR[RT]);
5603 else if ((FS & 0x1) == 0)
5605 PENDING_FILL (((FS + 1) + FGR_BASE), VH4_8 (GPR[RT]));
5606 PENDING_FILL ((FS + FGR_BASE), VL4_8 (GPR[RT]));
5610 TRACE_FP_RESULT (GPR[RT]);
5613 010001,00101,5.RT,5.FS,00000000000:COP1:64,f::DMTC1b
5614 "dmtc1 r<RT>, f<FS>"
5624 check_u64 (SD_, instruction_0);
5625 do_dmtc1b (SD_, RT, FS);
5629 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001011:COP1:32,f::FLOOR.L.fmt
5630 "floor.l.%s<FMT> f<FD>, f<FS>"
5641 do_floor_fmt (SD_, fmt_long, FMT, FD, FS);
5645 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001111:COP1:32,f::FLOOR.W.fmt
5646 "floor.w.%s<FMT> f<FD>, f<FS>"
5659 do_floor_fmt (SD_, fmt_word, FMT, FD, FS);
5663 110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1a
5664 "ldc1 f<FT>, <OFFSET>(r<BASE>)"
5670 COP_LD (1, FT, do_load_double (SD_, GPR[BASE], EXTEND16 (OFFSET)));
5674 110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1b
5675 "ldc1 f<FT>, <OFFSET>(r<BASE>)"
5686 COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
5690 010011,5.BASE,5.INDEX,5.0,5.FD,000001:COP1X:32,f::LDXC1
5691 "ldxc1 f<FD>, r<INDEX>(r<BASE>)"
5695 COP_LD (1, FD, do_load_double (SD_, GPR[BASE], GPR[INDEX]));
5699 010011,5.BASE,5.INDEX,5.0,5.FD,000001:COP1X:64,f::LDXC1
5700 "ldxc1 f<FD>, r<INDEX>(r<BASE>)"
5708 check_u64 (SD_, instruction_0);
5709 COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX]));
5713 010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:32,f::LUXC1
5714 "luxc1 f<FD>, r<INDEX>(r<BASE>)"
5717 do_luxc1_32 (SD_, FD, INDEX, BASE);
5721 010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:64,f::LUXC1
5722 "luxc1 f<FD>, r<INDEX>(r<BASE>)"
5728 check_u64 (SD_, instruction_0);
5729 do_luxc1_64 (SD_, FD, INDEX, BASE);
5733 110001,5.BASE,5.FT,16.OFFSET:COP1:32,f::LWC1
5734 "lwc1 f<FT>, <OFFSET>(r<BASE>)"
5748 do_lwc1 (SD_, FT, OFFSET, BASE);
5752 010011,5.BASE,5.INDEX,5.0,5.FD,000000:COP1X:32,f::LWXC1
5753 "lwxc1 f<FD>, r<INDEX>(r<BASE>)"
5761 do_lwxc1 (SD_, FD, INDEX, BASE, instruction_0);
5766 010011,5.FR,5.FT,5.FS,5.FD,100,3.FMT!2!3!4!5!7:COP1X:32,f::MADD.fmt
5767 "madd.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
5775 do_madd_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
5779 010001,00000,5.RT,5.FS,00000000000:COP1:32,f::MFC1a
5787 v = EXTEND32 (FGR[FS]);
5788 PENDING_FILL (RT, v);
5789 TRACE_ALU_RESULT (v);
5792 010001,00000,5.RT,5.FS,00000000000:COP1:32,f::MFC1b
5804 do_mfc1b (SD_, RT, FS);
5808 010001,10,3.FMT!2!3!4!5!7,00000,5.FS,5.FD,000110:COP1:32,f::MOV.fmt
5809 "mov.%s<FMT> f<FD>, f<FS>"
5823 do_mov_fmt (SD_, FMT, FD, FS, instruction_0);
5829 000000,5.RS,3.CC,0,1.TF,5.RD,00000,000001:SPECIAL:32,f::MOVtf
5830 "mov%s<TF> r<RD>, r<RS>, <CC>"
5839 do_movtf (SD_, TF, RD, RS, CC);
5845 010001,10,3.FMT!2!3!4!5!7,3.CC,0,1.TF,5.FS,5.FD,010001:COP1:32,f::MOVtf.fmt
5846 "mov%s<TF>.%s<FMT> f<FD>, f<FS>, <CC>"
5855 do_movtf_fmt (SD_, TF, FMT, FD, FS, CC);
5859 010001,10,3.FMT!2!3!4!5!7,5.RT,5.FS,5.FD,010011:COP1:32,f::MOVN.fmt
5860 "movn.%s<FMT> f<FD>, f<FS>, r<RT>"
5869 do_movn_fmt (SD_, FMT, FD, FS, RT);
5876 // MOVT.fmt see MOVtf.fmt
5880 010001,10,3.FMT!2!3!4!5!7,5.RT,5.FS,5.FD,010010:COP1:32,f::MOVZ.fmt
5881 "movz.%s<FMT> f<FD>, f<FS>, r<RT>"
5890 do_movz_fmt (SD_, FMT, FD, FS, RT);
5894 010011,5.FR,5.FT,5.FS,5.FD,101,3.FMT!2!3!4!5!7:COP1X:32,f::MSUB.fmt
5895 "msub.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
5903 do_msub_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
5907 010001,00100,5.RT,5.FS,00000000000:COP1:32,f::MTC1a
5914 if (SizeFGR () == 64)
5915 PENDING_FILL ((FS + FGR_BASE), (SET64HI (0xDEADC0DE) | VL4_8 (GPR[RT])));
5917 PENDING_FILL ((FS + FGR_BASE), VL4_8 (GPR[RT]));
5918 TRACE_FP_RESULT (GPR[RT]);
5921 010001,00100,5.RT,5.FS,00000000000:COP1:32,f::MTC1b
5933 do_mtc1b (SD_, RT, FS);
5937 010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,5.FD,000010:COP1:32,f::MUL.fmt
5938 "mul.%s<FMT> f<FD>, f<FS>, f<FT>"
5952 do_mul_fmt (SD_, FMT, FD, FS, FT, instruction_0);
5956 010001,10,3.FMT!2!3!4!5!7,00000,5.FS,5.FD,000111:COP1:32,f::NEG.fmt
5957 "neg.%s<FMT> f<FD>, f<FS>"
5971 do_neg_fmt (SD_, FMT, FD, FS, instruction_0);
5975 010011,5.FR,5.FT,5.FS,5.FD,110,3.FMT!2!3!4!5!7:COP1X:32,f::NMADD.fmt
5976 "nmadd.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
5984 do_nmadd_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
5988 010011,5.FR,5.FT,5.FS,5.FD,111,3.FMT!2!3!4!5!7:COP1X:32,f::NMSUB.fmt
5989 "nmsub.%s<FMT> f<FD>, f<FR>, f<FS>, f<FT>"
5997 do_nmsub_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
6001 010001,10,110,5.FT,5.FS,5.FD,101100:COP1:32,f::PLL.PS
6002 "pll.ps f<FD>, f<FS>, f<FT>"
6008 do_pll_ps (SD_, FD, FS, FT, instruction_0);
6012 010001,10,110,5.FT,5.FS,5.FD,101101:COP1:32,f::PLU.PS
6013 "plu.ps f<FD>, f<FS>, f<FT>"
6019 do_plu_ps (SD_, FD, FS, FT, instruction_0);
6023 010011,5.BASE,5.INDEX,5.HINT,00000,001111:COP1X:32::PREFX
6024 "prefx <HINT>, r<INDEX>(r<BASE>)"
6032 do_prefx (SD_, HINT, INDEX, BASE);
6036 010001,10,110,5.FT,5.FS,5.FD,101110:COP1:32,f::PUL.PS
6037 "pul.ps f<FD>, f<FS>, f<FT>"
6043 do_pul_ps (SD_, FD, FS, FT, instruction_0);
6047 010001,10,110,5.FT,5.FS,5.FD,101111:COP1:32,f::PUU.PS
6048 "puu.ps f<FD>, f<FS>, f<FT>"
6054 do_puu_ps (SD_, FD, FS, FT, instruction_0);
6058 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,010101:COP1:32,f::RECIP.fmt
6059 "recip.%s<FMT> f<FD>, f<FS>"
6067 do_recip_fmt (SD_, FMT, FD, FS);
6071 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001000:COP1:32,f::ROUND.L.fmt
6072 "round.l.%s<FMT> f<FD>, f<FS>"
6083 do_round_fmt (SD_, fmt_long, FMT, FD, FS);
6087 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001100:COP1:32,f::ROUND.W.fmt
6088 "round.w.%s<FMT> f<FD>, f<FS>"
6101 do_round_fmt (SD_, fmt_word, FMT, FD, FS);
6105 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,010110:COP1:32,f::RSQRT.fmt
6106 "rsqrt.%s<FMT> f<FD>, f<FS>"
6114 do_rsqrt_fmt (SD_, FMT, FD, FS);
6118 111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1a
6119 "sdc1 f<FT>, <OFFSET>(r<BASE>)"
6124 do_sdc1 (SD_, FT, OFFSET, BASE);
6128 111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1b
6129 "sdc1 f<FT>, <OFFSET>(r<BASE>)"
6140 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT));
6144 010011,5.BASE,5.INDEX,5.FS,00000001001:COP1X:32,f::SDXC1
6145 "sdxc1 f<FS>, r<INDEX>(r<BASE>)"
6149 do_store_double (SD_, GPR[BASE], GPR[INDEX], COP_SD (1, FS));
6153 010011,5.BASE,5.INDEX,5.FS,00000001001:COP1X:64,f::SDXC1
6154 "sdxc1 f<FS>, r<INDEX>(r<BASE>)"
6162 check_u64 (SD_, instruction_0);
6163 do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX], COP_SD (1, FS));
6167 010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:32,f::SUXC1
6168 "suxc1 f<FS>, r<INDEX>(r<BASE>)"
6171 do_suxc1_32 (SD_, FS, INDEX, BASE);
6175 010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:64,f::SUXC1
6176 "suxc1 f<FS>, r<INDEX>(r<BASE>)"
6182 check_u64 (SD_, instruction_0);
6183 do_suxc1_64 (SD_, FS, INDEX, BASE);
6187 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,000100:COP1:32,f::SQRT.fmt
6188 "sqrt.%s<FMT> f<FD>, f<FS>"
6201 do_sqrt_fmt (SD_, FMT, FD, FS);
6205 010001,10,3.FMT!2!3!4!5!7,5.FT,5.FS,5.FD,000001:COP1:32,f::SUB.fmt
6206 "sub.%s<FMT> f<FD>, f<FS>, f<FT>"
6220 do_sub_fmt (SD_, FMT, FD, FS, FT, instruction_0);
6225 111001,5.BASE,5.FT,16.OFFSET:COP1:32,f::SWC1
6226 "swc1 f<FT>, <OFFSET>(r<BASE>)"
6240 do_swc1 (SD_, FT, OFFSET, BASE, instruction_0);
6244 010011,5.BASE,5.INDEX,5.FS,00000,001000:COP1X:32,f::SWXC1
6245 "swxc1 f<FS>, r<INDEX>(r<BASE>)"
6253 do_swxc1 (SD_, FS, INDEX, BASE, instruction_0);
6257 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001001:COP1:32,f::TRUNC.L.fmt
6258 "trunc.l.%s<FMT> f<FD>, f<FS>"
6269 do_trunc_fmt (SD_, fmt_long, FMT, FD, FS);
6273 010001,10,3.FMT!2!3!4!5!6!7,00000,5.FS,5.FD,001101:COP1:32,f::TRUNC.W
6274 "trunc.w.%s<FMT> f<FD>, f<FS>"
6287 do_trunc_fmt (SD_, fmt_word, FMT, FD, FS);
6292 // MIPS Architecture:
6294 // System Control Instruction Set (COP0)
6298 010000,01000,00000,16.OFFSET:COP0:32::BC0F
6312 010000,01000,00000,16.OFFSET:COP0:32::BC0F
6314 // stub needed for eCos as tx39 hardware bug workaround
6321 010000,01000,00010,16.OFFSET:COP0:32::BC0FL
6336 010000,01000,00001,16.OFFSET:COP0:32::BC0T
6350 010000,01000,00011,16.OFFSET:COP0:32::BC0TL
6365 101111,5.BASE,5.OP,16.OFFSET:NORMAL:32::CACHE
6366 "cache <OP>, <OFFSET>(r<BASE>)"
6378 address_word base = GPR[BASE];
6379 address_word offset = EXTEND16 (OFFSET);
6381 address_word vaddr = loadstore_ea (SD_, base, offset);
6384 if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
6385 CacheOp(OP,vaddr,paddr,instruction_0);
6390 010000,00001,5.RT,5.RD,00000000,3.SEL:COP0:64::DMFC0
6391 "dmfc0 r<RT>, r<RD>"
6398 check_u64 (SD_, instruction_0);
6399 DecodeCoproc (instruction_0, 0, cp0_dmfc0, RT, RD, SEL);
6403 010000,00101,5.RT,5.RD,00000000,3.SEL:COP0:64::DMTC0
6404 "dmtc0 r<RT>, r<RD>"
6411 check_u64 (SD_, instruction_0);
6412 DecodeCoproc (instruction_0, 0, cp0_dmtc0, RT, RD, SEL);
6416 010000,1,0000000000000000000,011000:COP0:32::ERET
6428 if (SR & status_ERL)
6430 /* Oops, not yet available */
6431 sim_io_printf (SD, "Warning: ERET when SR[ERL] set not supported");
6443 010000,00000,5.RT,5.RD,00000000,3.SEL:COP0:32::MFC0
6444 "mfc0 r<RT>, r<RD> # <SEL>"
6458 TRACE_ALU_INPUT0 ();
6459 DecodeCoproc (instruction_0, 0, cp0_mfc0, RT, RD, SEL);
6460 TRACE_ALU_RESULT (GPR[RT]);
6463 010000,00100,5.RT,5.RD,00000000,3.SEL:COP0:32::MTC0
6464 "mtc0 r<RT>, r<RD> # <SEL>"
6478 DecodeCoproc (instruction_0, 0, cp0_mtc0, RT, RD, SEL);
6482 010000,1,0000000000000000000,010000:COP0:32::RFE
6493 DecodeCoproc (instruction_0, 0, cp0_rfe, 0, 0, 0x10);
6497 0100,ZZ!0!1!3,5.COP_FUN0!8,5.COP_FUN1,16.COP_FUN2:NORMAL:32::COPz
6498 "cop<ZZ> <COP_FUN0><COP_FUN1><COP_FUN2>"
6511 DecodeCoproc (instruction_0, 2, 0, 0, 0, 0);
6516 010000,1,0000000000000000000,001000:COP0:32::TLBP
6531 010000,1,0000000000000000000,000001:COP0:32::TLBR
6546 010000,1,0000000000000000000,000010:COP0:32::TLBWI
6561 010000,1,0000000000000000000,000110:COP0:32::TLBWR
6576 :include:::mips3264r2.igen
6578 :include:::m16e.igen
6579 :include:::mdmx.igen
6580 :include:::mips3d.igen
6585 :include:::dsp2.igen
6586 :include:::smartmips.igen
6587 :include:::micromips.igen
6588 :include:::micromipsdsp.igen