+:function:::void:do_clz:int rd, int rs
+{
+ unsigned32 temp = GPR[rs];
+ unsigned32 i, mask;
+ if (NotWordValue (GPR[rs]))
+ Unpredictable ();
+ TRACE_ALU_INPUT1 (GPR[rs]);
+ for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
+ {
+ if ((temp & mask) != 0)
+ break;
+ mask >>= 1;
+ }
+ GPR[rd] = EXTEND32 (i);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_dclo:int rd, int rs
+{
+ unsigned64 temp = GPR[rs];
+ unsigned32 i;
+ unsigned64 mask;
+ TRACE_ALU_INPUT1 (GPR[rs]);
+ for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
+ {
+ if ((temp & mask) == 0)
+ break;
+ mask >>= 1;
+ }
+ GPR[rd] = EXTEND32 (i);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_dclz:int rd, int rs
+{
+ unsigned64 temp = GPR[rs];
+ unsigned32 i;
+ unsigned64 mask;
+ TRACE_ALU_INPUT1 (GPR[rs]);
+ for (mask = ((unsigned64)1<<63), i = 0; i < 64; ++i)
+ {
+ if ((temp & mask) != 0)
+ break;
+ mask >>= 1;
+ }
+ GPR[rd] = EXTEND32 (i);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_lb:int rt, int offset, int base
+{
+ GPR[rt] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[base],
+ EXTEND16 (offset)));
+}
+
+:function:::void:do_lh:int rt, int offset, int base
+{
+ GPR[rt] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[base],
+ EXTEND16 (offset)));
+}
+
+:function:::void:do_lwr:int rt, int offset, int base
+{
+ GPR[rt] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, GPR[base],
+ EXTEND16 (offset), GPR[rt]));
+}
+
+:function:::void:do_lwl:int rt, int offset, int base
+{
+ GPR[rt] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, GPR[base],
+ EXTEND16 (offset), GPR[rt]));
+}
+
+:function:::void:do_lwc:int num, int rt, int offset, int base
+{
+ COP_LW (num, rt, do_load (SD_, AccessLength_WORD, GPR[base],
+ EXTEND16 (offset)));
+}
+
+:function:::void:do_lw:int rt, int offset, int base
+{
+ GPR[rt] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[base],
+ EXTEND16 (offset)));
+}
+
+:function:::void:do_lwu:int rt, int offset, int base, address_word instruction_0
+{
+ check_u64 (SD_, instruction_0);
+ GPR[rt] = do_load (SD_, AccessLength_WORD, GPR[base], EXTEND16 (offset));
+}
+
+:function:::void:do_lhu:int rt, int offset, int base
+{
+ GPR[rt] = do_load (SD_, AccessLength_HALFWORD, GPR[base], EXTEND16 (offset));
+}
+
+:function:::void:do_ldc:int num, int rt, int offset, int base
+{
+ COP_LD (num, rt, do_load (SD_, AccessLength_DOUBLEWORD, GPR[base],
+ EXTEND16 (offset)));
+}
+
+:function:::void:do_lbu:int rt, int offset, int base
+{
+ GPR[rt] = do_load (SD_, AccessLength_BYTE, GPR[base], EXTEND16 (offset));
+}
+
+:function:::void:do_ll:int rt, int insn_offset, int basereg
+{
+ address_word base = GPR[basereg];
+ address_word offset = EXTEND16 (insn_offset);
+ {
+ address_word vaddr = loadstore_ea (SD_, base, offset);
+ address_word paddr = vaddr;
+ if ((vaddr & 3) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer,
+ sim_core_unaligned_signal);
+ }
+ else
+ {
+ unsigned64 memval = 0;
+ unsigned64 memval1 = 0;
+ unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+ unsigned int shift = 2;
+ unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+ unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+ unsigned int byte;
+ paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+ LoadMemory (&memval, &memval1, AccessLength_WORD, paddr, vaddr,
+ isDATA, isREAL);
+ byte = ((vaddr & mask) ^ (bigend << shift));
+ GPR[rt] = EXTEND32 (memval >> (8 * byte));
+ LLBIT = 1;
+ }
+ }
+}
+
+:function:::void:do_lld:int rt, int roffset, int rbase
+{
+ address_word base = GPR[rbase];
+ address_word offset = EXTEND16 (roffset);
+ {
+ address_word vaddr = loadstore_ea (SD_, base, offset);
+ address_word paddr = vaddr;
+
+ if ((vaddr & 7) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer,
+ sim_core_unaligned_signal);
+ }
+ else
+ {
+ unsigned64 memval = 0;
+ unsigned64 memval1 = 0;
+ LoadMemory (&memval, &memval1, AccessLength_DOUBLEWORD, paddr, vaddr,
+ isDATA, isREAL);
+ GPR[rt] = memval;
+ LLBIT = 1;
+ }
+ }
+}
+
+:function:::void:do_lui:int rt, int immediate
+{
+ TRACE_ALU_INPUT1 (immediate);
+ GPR[rt] = EXTEND32 (immediate << 16);
+ TRACE_ALU_RESULT (GPR[rt]);
+}
+
+:function:::void:do_madd:int rs, int rt
+{
+ signed64 temp;
+ check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+ if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+ Unpredictable ();
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
+ + ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
+ LO = EXTEND32 (temp);
+ HI = EXTEND32 (VH4_8 (temp));
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_dsp_madd:int ac, int rs, int rt
+{
+ signed64 temp;
+ if (ac == 0)
+ check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+ if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+ Unpredictable ();
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
+ + ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
+ DSPLO(ac) = EXTEND32 (temp);
+ DSPHI(ac) = EXTEND32 (VH4_8 (temp));
+ if (ac == 0)
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_maddu:int rs, int rt
+{
+ unsigned64 temp;
+ check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+ if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+ Unpredictable ();
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
+ + ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
+ ACX += U8_4 (VL4_8 (HI), VL4_8 (LO)) < temp; /* SmartMIPS */
+ LO = EXTEND32 (temp);
+ HI = EXTEND32 (VH4_8 (temp));
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_dsp_maddu:int ac, int rs, int rt
+{
+ unsigned64 temp;
+ if (ac == 0)
+ check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+ if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+ Unpredictable ();
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
+ + ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
+ if (ac == 0)
+ ACX += U8_4 (VL4_8 (HI), VL4_8 (LO)) < temp; /* SmartMIPS */
+ DSPLO(ac) = EXTEND32 (temp);
+ DSPHI(ac) = EXTEND32 (VH4_8 (temp));
+ if (ac == 0)
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_dsp_mfhi:int ac, int rd
+{
+ if (ac == 0)
+ do_mfhi (SD_, rd);
+ else
+ GPR[rd] = DSPHI(ac);
+}
+
+:function:::void:do_dsp_mflo:int ac, int rd
+{
+ if (ac == 0)
+ do_mflo (SD_, rd);
+ else
+ GPR[rd] = DSPLO(ac);
+}
+
+:function:::void:do_movn:int rd, int rs, int rt
+{
+ if (GPR[rt] != 0)
+ {
+ GPR[rd] = GPR[rs];
+ TRACE_ALU_RESULT (GPR[rd]);
+ }
+}
+
+:function:::void:do_movz:int rd, int rs, int rt
+{
+ if (GPR[rt] == 0)
+ {
+ GPR[rd] = GPR[rs];
+ TRACE_ALU_RESULT (GPR[rd]);
+ }
+}
+
+:function:::void:do_msub:int rs, int rt
+{
+ signed64 temp;
+ check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+ if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+ Unpredictable ();
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
+ - ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
+ LO = EXTEND32 (temp);
+ HI = EXTEND32 (VH4_8 (temp));
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_dsp_msub:int ac, int rs, int rt
+{
+ signed64 temp;
+ if (ac == 0)
+ check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+ if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+ Unpredictable ();
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
+ - ((signed64) EXTEND32 (GPR[rt]) * (signed64) EXTEND32 (GPR[rs])));
+ DSPLO(ac) = EXTEND32 (temp);
+ DSPHI(ac) = EXTEND32 (VH4_8 (temp));
+ if (ac == 0)
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_msubu:int rs, int rt
+{
+ unsigned64 temp;
+ check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+ if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+ Unpredictable ();
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
+ - ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
+ LO = EXTEND32 (temp);
+ HI = EXTEND32 (VH4_8 (temp));
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_dsp_msubu:int ac, int rs, int rt
+{
+ unsigned64 temp;
+ if (ac == 0)
+ check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+ if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+ Unpredictable ();
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ temp = (U8_4 (VL4_8 (DSPHI(ac)), VL4_8 (DSPLO(ac)))
+ - ((unsigned64) VL4_8 (GPR[rs]) * (unsigned64) VL4_8 (GPR[rt])));
+ DSPLO(ac) = EXTEND32 (temp);
+ DSPHI(ac) = EXTEND32 (VH4_8 (temp));
+ if (ac == 0)
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_mthi:int rs
+{
+ check_mt_hilo (SD_, HIHISTORY);
+ HI = GPR[rs];
+}
+
+:function:::void:do_dsp_mthi:int ac, int rs
+{
+ if (ac == 0)
+ check_mt_hilo (SD_, HIHISTORY);
+ DSPHI(ac) = GPR[rs];
+}
+
+:function:::void:do_mtlo:int rs
+{
+ check_mt_hilo (SD_, LOHISTORY);
+ LO = GPR[rs];
+}
+
+:function:::void:do_dsp_mtlo:int ac, int rs
+{
+ if (ac == 0)
+ check_mt_hilo (SD_, LOHISTORY);
+ DSPLO(ac) = GPR[rs];
+}
+
+:function:::void:do_mul:int rd, int rs, int rt
+{
+ signed64 prod;
+ if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+ Unpredictable ();
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ prod = (((signed64)(signed32) GPR[rs])
+ * ((signed64)(signed32) GPR[rt]));
+ GPR[rd] = EXTEND32 (VL4_8 (prod));
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_dsp_mult:int ac, int rs, int rt
+{
+ signed64 prod;
+ if (ac == 0)
+ check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+ if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+ Unpredictable ();
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ prod = ((signed64)(signed32) GPR[rs])
+ * ((signed64)(signed32) GPR[rt]);
+ DSPLO(ac) = EXTEND32 (VL4_8 (prod));
+ DSPHI(ac) = EXTEND32 (VH4_8 (prod));
+ if (ac == 0)
+ {
+ ACX = 0; /* SmartMIPS */
+ TRACE_ALU_RESULT2 (HI, LO);
+ }
+}
+
+:function:::void:do_dsp_multu:int ac, int rs, int rt
+{
+ unsigned64 prod;
+ if (ac == 0)
+ check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+ if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+ Unpredictable ();
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ prod = ((unsigned64)(unsigned32) GPR[rs])
+ * ((unsigned64)(unsigned32) GPR[rt]);
+ DSPLO(ac) = EXTEND32 (VL4_8 (prod));
+ DSPHI(ac) = EXTEND32 (VH4_8 (prod));
+ if (ac == 0)
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_pref:int hint, int insn_offset, int insn_base
+{
+ address_word base = GPR[insn_base];
+ address_word offset = EXTEND16 (insn_offset);
+ {
+ address_word vaddr = loadstore_ea (SD_, base, offset);
+ address_word paddr = vaddr;
+ /* Prefetch (paddr, vaddr, isDATA, hint); */
+ }
+}
+
+:function:::void:do_sc:int rt, int offsetarg, int basereg, address_word instruction_0
+{
+ unsigned32 instruction = instruction_0;
+ address_word base = GPR[basereg];
+ address_word offset = EXTEND16 (offsetarg);
+ {
+ address_word vaddr = loadstore_ea (SD_, base, offset);
+ address_word paddr = vaddr;
+
+ if ((vaddr & 3) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer,
+ sim_core_unaligned_signal);
+ }
+ else
+ {
+ unsigned64 memval = 0;
+ unsigned64 memval1 = 0;
+ unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+ address_word reverseendian =
+ (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
+ address_word bigendiancpu =
+ (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
+ unsigned int byte;
+ paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
+ byte = ((vaddr & mask) ^ bigendiancpu);
+ memval = ((unsigned64) GPR[rt] << (8 * byte));
+ if (LLBIT)
+ StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr,
+ isREAL);
+ GPR[rt] = LLBIT;
+ }
+ }
+}
+
+:function:::void:do_scd:int rt, int roffset, int rbase
+{
+ address_word base = GPR[rbase];
+ address_word offset = EXTEND16 (roffset);
+ {
+ address_word vaddr = loadstore_ea (SD_, base, offset);
+ address_word paddr = vaddr;
+
+ if ((vaddr & 7) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer,
+ sim_core_unaligned_signal);
+ }
+ else
+ {
+ unsigned64 memval = 0;
+ unsigned64 memval1 = 0;
+ memval = GPR[rt];
+ if (LLBIT)
+ StoreMemory (AccessLength_DOUBLEWORD, memval, memval1, paddr, vaddr,
+ isREAL);
+ GPR[rt] = LLBIT;
+ }
+ }
+}
+
+:function:::void:do_sub:int rs, int rt, int rd
+{
+ if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+ Unpredictable ();
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ {
+ ALU32_BEGIN (GPR[rs]);
+ ALU32_SUB (GPR[rt]);
+ ALU32_END (GPR[rd]); /* This checks for overflow. */
+ }
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_sw:int rt, int offset, int base
+{
+ do_store (SD_, AccessLength_WORD, GPR[base], EXTEND16 (offset), GPR[rt]);
+}
+
+:function:::void:do_teq:int rs, int rt, address_word instruction_0
+{
+ if ((signed_word) GPR[rs] == (signed_word) GPR[rt])
+ SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_teqi:int rs, int immediate, address_word instruction_0
+{
+ if ((signed_word) GPR[rs] == (signed_word) EXTEND16 (immediate))
+ SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tge:int rs, int rt, address_word instruction_0
+{
+ if ((signed_word) GPR[rs] >= (signed_word) GPR[rt])
+ SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tgei:int rs, int immediate, address_word instruction_0
+{
+ if ((signed_word) GPR[rs] >= (signed_word) EXTEND16 (immediate))
+ SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tgeiu:int rs, int immediate, address_word instruction_0
+{
+ if ((unsigned_word) GPR[rs] >= (unsigned_word) EXTEND16 (immediate))
+ SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tgeu:int rs ,int rt, address_word instruction_0
+{
+ if ((unsigned_word) GPR[rs] >= (unsigned_word) GPR[rt])
+ SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tlt:int rs, int rt, address_word instruction_0
+{
+ if ((signed_word) GPR[rs] < (signed_word) GPR[rt])
+ SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tlti:int rs, int immediate, address_word instruction_0
+{
+ if ((signed_word) GPR[rs] < (signed_word) EXTEND16 (immediate))
+ SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tltiu:int rs, int immediate, address_word instruction_0
+{
+ if ((unsigned_word) GPR[rs] < (unsigned_word) EXTEND16 (immediate))
+ SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tltu:int rs, int rt, address_word instruction_0
+{
+ if ((unsigned_word) GPR[rs] < (unsigned_word) GPR[rt])
+ SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tne:int rs, int rt, address_word instruction_0
+{
+ if ((signed_word) GPR[rs] != (signed_word) GPR[rt])
+ SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_tnei:int rs, int immediate, address_word instruction_0
+{
+ if ((signed_word) GPR[rs] != (signed_word) EXTEND16 (immediate))
+ SignalException (Trap, instruction_0);
+}
+
+:function:::void:do_abs_fmt:int fmt, int fd, int fs, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_fmt_p (SD_, fmt, instruction_0);
+ StoreFPR (fd, fmt, AbsoluteValue (ValueFPR (fs, fmt), fmt));
+}
+
+:function:::void:do_add_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_fmt_p (SD_, fmt, instruction_0);
+ StoreFPR (fd, fmt, Add (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
+}
+
+:function:::void:do_alnv_ps:int fd, int fs, int ft, int rs, address_word instruction_0
+{
+ unsigned64 fsx;
+ unsigned64 ftx;
+ unsigned64 fdx;
+ check_fpu (SD_);
+ check_u64 (SD_, instruction_0);
+ fsx = ValueFPR (fs, fmt_ps);
+ if ((GPR[rs] & 0x3) != 0)
+ Unpredictable ();
+ if ((GPR[rs] & 0x4) == 0)
+ fdx = fsx;
+ else
+ {
+ ftx = ValueFPR (ft, fmt_ps);
+ if (BigEndianCPU)
+ fdx = PackPS (PSLower (fsx), PSUpper (ftx));
+ else
+ fdx = PackPS (PSLower (ftx), PSUpper (fsx));
+ }
+ StoreFPR (fd, fmt_ps, fdx);
+}
+
+:function:::void:do_c_cond_fmt:int cond, int fmt, int cc, int fs, int ft, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_fmt_p (SD_, fmt, instruction_0);
+ Compare (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt, cond, cc);
+ TRACE_ALU_RESULT (ValueFCR (31));
+}
+
+:function:::void:do_ceil_fmt:int type, int fmt, int fd, int fs, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_fmt_p (SD_, fmt, instruction_0);
+ StoreFPR (fd, type, Convert (FP_RM_TOPINF, ValueFPR (fs, fmt), fmt,
+ type));
+}
+
+:function:::void:do_cfc1:int rt, int fs
+{
+ check_fpu (SD_);
+ if (fs == 0 || fs == 25 || fs == 26 || fs == 28 || fs == 31)
+ {
+ unsigned_word fcr = ValueFCR (fs);
+ TRACE_ALU_INPUT1 (fcr);
+ GPR[rt] = fcr;
+ }
+ /* else NOP */
+ TRACE_ALU_RESULT (GPR[rt]);
+}
+
+:function:::void:do_ctc1:int rt, int fs
+{
+ check_fpu (SD_);
+ TRACE_ALU_INPUT1 (GPR[rt]);
+ if (fs == 25 || fs == 26 || fs == 28 || fs == 31)
+ StoreFCR (fs, GPR[rt]);
+ /* else NOP */
+}
+
+:function:::void:do_cvt_d_fmt:int fmt, int fd, int fs, address_word instruction_0
+{
+ check_fpu (SD_);
+ if ((fmt == fmt_double) | 0)
+ SignalException (ReservedInstruction, instruction_0);
+ StoreFPR (fd, fmt_double, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
+ fmt_double));
+}
+
+:function:::void:do_cvt_l_fmt:int fmt, int fd, int fs, address_word instruction_0
+{
+ check_fpu (SD_);
+ if ((fmt == fmt_long) | ((fmt == fmt_long) || (fmt == fmt_word)))
+ SignalException (ReservedInstruction, instruction_0);
+ StoreFPR (fd, fmt_long, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
+ fmt_long));
+}
+
+:function:::void:do_cvt_ps_s:int fd, int fs, int ft, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_u64 (SD_, instruction_0);
+ StoreFPR (fd, fmt_ps, PackPS (ValueFPR (fs, fmt_single),
+ ValueFPR (ft, fmt_single)));
+}
+
+:function:::void:do_cvt_s_fmt:int fmt, int fd, int fs, address_word instruction_0
+{
+ check_fpu (SD_);
+ if ((fmt == fmt_single) | 0)
+ SignalException (ReservedInstruction, instruction_0);
+ StoreFPR (fd, fmt_single, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
+ fmt_single));
+}
+
+:function:::void:do_cvt_s_pl:int fd, int fs, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_u64 (SD_, instruction_0);
+ StoreFPR (fd, fmt_single, PSLower (ValueFPR (fs, fmt_ps)));
+}
+
+:function:::void:do_cvt_s_pu:int fd, int fs, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_u64 (SD_, instruction_0);
+ StoreFPR (fd, fmt_single, PSUpper (ValueFPR (fs, fmt_ps)));
+}
+
+:function:::void:do_cvt_w_fmt:int fmt, int fd, int fs, address_word instruction_0
+{
+ check_fpu (SD_);
+ if ((fmt == fmt_word) | ((fmt == fmt_long) || (fmt == fmt_word)))
+ SignalException (ReservedInstruction, instruction_0);
+ StoreFPR (fd, fmt_word, Convert (GETRM (), ValueFPR (fs, fmt), fmt,
+ fmt_word));
+}
+
+:function:::void:do_div_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
+{
+ check_fpu (SD_);
+ StoreFPR (fd, fmt, Divide (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
+}
+
+:function:::void:do_dmfc1b:int rt, int fs
+*mipsIV:
+*mipsV:
+*mips64:
+*mips64r2:
+*vr4100:
+*vr5000:
+*r3900:
+*micromips64:
+{
+ if (SizeFGR () == 64)
+ GPR[rt] = FGR[fs];
+ else if ((fs & 0x1) == 0)
+ GPR[rt] = SET64HI (FGR[fs+1]) | FGR[fs];
+ else
+ GPR[rt] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
+ TRACE_ALU_RESULT (GPR[rt]);
+}
+
+:function:::void:do_dmtc1b:int rt, int fs
+{
+ if (SizeFGR () == 64)
+ StoreFPR (fs, fmt_uninterpreted_64, GPR[rt]);
+ else if ((fs & 0x1) == 0)
+ StoreFPR (fs, fmt_uninterpreted_64, GPR[rt]);
+ else
+ Unpredictable ();
+}
+
+:function:::void:do_floor_fmt:int type, int fmt, int fd, int fs
+{
+ check_fpu (SD_);
+ StoreFPR (fd, type, Convert (FP_RM_TOMINF, ValueFPR (fs, fmt), fmt,
+ type));
+}
+
+:function:::void:do_luxc1_32:int fd, int rindex, int rbase
+*mips32r2:
+*micromips32:
+{
+ address_word base = GPR[rbase];
+ address_word index = GPR[rindex];
+ address_word vaddr = base + index;
+ check_fpu (SD_);
+ if (SizeFGR () != 64)
+ Unpredictable ();
+ /* Arrange for the bottom 3 bits of (base + index) to be 0. */
+ if ((vaddr & 0x7) != 0)
+ index -= (vaddr & 0x7);
+ COP_LD (1, fd, do_load_double (SD_, base, index));
+}
+
+:function:::void:do_luxc1_64:int fd, int rindex, int rbase
+{
+ address_word base = GPR[rbase];
+ address_word index = GPR[rindex];
+ address_word vaddr = base + index;
+ if (SizeFGR () != 64)
+ Unpredictable ();
+ /* Arrange for the bottom 3 bits of (base + index) to be 0. */
+ if ((vaddr & 0x7) != 0)
+ index -= (vaddr & 0x7);
+ COP_LD (1, fd, do_load (SD_, AccessLength_DOUBLEWORD, base, index));
+
+}
+
+:function:::void:do_lwc1:int ft, int offset, int base
+{
+ check_fpu (SD_);
+ COP_LW (1, ft, do_load (SD_, AccessLength_WORD, GPR[base],
+ EXTEND16 (offset)));
+}
+
+:function:::void:do_lwxc1:int fd, int index, int base, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_u64 (SD_, instruction_0);
+ COP_LW (1, fd, do_load (SD_, AccessLength_WORD, GPR[base], GPR[index]));
+}
+
+:function:::void:do_madd_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_u64 (SD_, instruction_0);
+ check_fmt_p (SD_, fmt, instruction_0);
+ StoreFPR (fd, fmt, MultiplyAdd (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
+ ValueFPR (fr, fmt), fmt));
+}
+
+:function:::void:do_mfc1b:int rt, int fs
+{
+ check_fpu (SD_);
+ GPR[rt] = EXTEND32 (FGR[fs]);
+ TRACE_ALU_RESULT (GPR[rt]);
+}
+
+:function:::void:do_mov_fmt:int fmt, int fd, int fs, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_fmt_p (SD_, fmt, instruction_0);
+ StoreFPR (fd, fmt, ValueFPR (fs, fmt));
+}
+
+:function:::void:do_movtf:int tf, int rd, int rs, int cc
+{
+ check_fpu (SD_);
+ if (GETFCC(cc) == tf)
+ GPR[rd] = GPR[rs];
+}
+
+:function:::void:do_movtf_fmt:int tf, int fmt, int fd, int fs, int cc
+{
+ check_fpu (SD_);
+ if (fmt != fmt_ps)
+ {
+ if (GETFCC(cc) == tf)
+ StoreFPR (fd, fmt, ValueFPR (fs, fmt));
+ else
+ StoreFPR (fd, fmt, ValueFPR (fd, fmt)); /* set fmt */
+ }
+ else
+ {
+ unsigned64 fdx;
+ fdx = PackPS (PSUpper (ValueFPR ((GETFCC (cc+1) == tf) ? fs : fd,
+ fmt_ps)),
+ PSLower (ValueFPR ((GETFCC (cc+0) == tf) ? fs : fd,
+ fmt_ps)));
+ StoreFPR (fd, fmt_ps, fdx);
+ }
+}
+
+:function:::void:do_movn_fmt:int fmt, int fd, int fs, int rt
+{
+ check_fpu (SD_);
+ if (GPR[rt] != 0)
+ StoreFPR (fd, fmt, ValueFPR (fs, fmt));
+ else
+ StoreFPR (fd, fmt, ValueFPR (fd, fmt));
+}
+
+:function:::void:do_movz_fmt:int fmt, int fd, int fs, int rt
+{
+ check_fpu (SD_);
+ if (GPR[rt] == 0)
+ StoreFPR (fd, fmt, ValueFPR (fs, fmt));
+ else
+ StoreFPR (fd, fmt, ValueFPR (fd, fmt));
+}
+
+:function:::void:do_msub_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_u64 (SD_, instruction_0);
+ check_fmt_p (SD_, fmt, instruction_0);
+ StoreFPR (fd, fmt, MultiplySub (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
+ ValueFPR (fr, fmt), fmt));
+}
+
+:function:::void:do_mtc1b:int rt, int fs
+{
+ check_fpu (SD_);
+ StoreFPR (fs, fmt_uninterpreted_32, VL4_8 (GPR[rt]));
+}
+
+:function:::void:do_mul_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_fmt_p (SD_, fmt, instruction_0);
+ StoreFPR (fd, fmt, Multiply (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
+}
+
+:function:::void:do_neg_fmt:int fmt, int fd, int fs, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_fmt_p (SD_, fmt, instruction_0);
+ StoreFPR (fd, fmt, Negate (ValueFPR (fs, fmt), fmt));
+}
+
+:function:::void:do_nmadd_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_u64 (SD_, instruction_0);
+ check_fmt_p (SD_, fmt, instruction_0);
+ StoreFPR (fd, fmt, NegMultiplyAdd (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
+ ValueFPR (fr, fmt), fmt));
+}
+
+:function:::void:do_nmsub_fmt:int fmt, int fd, int fr, int fs, int ft, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_u64 (SD_, instruction_0);
+ check_fmt_p (SD_, fmt, instruction_0);
+ StoreFPR (fd, fmt, NegMultiplySub (ValueFPR (fs, fmt), ValueFPR (ft, fmt),
+ ValueFPR (fr, fmt), fmt));
+}
+
+:function:::void:do_pll_ps:int fd, int fs, int ft, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_u64 (SD_, instruction_0);
+ StoreFPR (fd, fmt_ps, PackPS (PSLower (ValueFPR (fs, fmt_ps)),
+ PSLower (ValueFPR (ft, fmt_ps))));
+}
+
+:function:::void:do_plu_ps:int fd, int fs, int ft, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_u64 (SD_, instruction_0);
+ StoreFPR (fd, fmt_ps, PackPS (PSLower (ValueFPR (fs, fmt_ps)),
+ PSUpper (ValueFPR (ft, fmt_ps))));
+}
+
+:function:::void:do_pul_ps:int fd, int fs, int ft, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_u64 (SD_, instruction_0);
+ StoreFPR (fd, fmt_ps, PackPS (PSUpper (ValueFPR (fs, fmt_ps)),
+ PSLower (ValueFPR (ft, fmt_ps))));
+}
+
+:function:::void:do_puu_ps:int fd, int fs, int ft, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_u64 (SD_, instruction_0);
+ StoreFPR (fd, fmt_ps, PackPS (PSUpper (ValueFPR (fs, fmt_ps)),
+ PSUpper (ValueFPR (ft, fmt_ps))));
+}
+
+:function:::void:do_recip_fmt:int fmt, int fd, int fs
+{
+ check_fpu (SD_);
+ StoreFPR (fd, fmt, Recip (ValueFPR (fs, fmt), fmt));
+}
+
+:function:::void:do_round_fmt:int type, int fmt, int fd, int fs
+{
+ check_fpu (SD_);
+ StoreFPR (fd, type, Convert (FP_RM_NEAREST, ValueFPR (fs, fmt), fmt,
+ type));
+}
+
+:function:::void:do_rsqrt_fmt:int fmt, int fd, int fs
+{
+ check_fpu (SD_);
+ StoreFPR (fd, fmt, RSquareRoot (ValueFPR (fs, fmt), fmt));
+}
+
+:function:::void:do_prefx:int hint, int rindex, int rbase
+{
+ address_word base = GPR[rbase];
+ address_word index = GPR[rindex];
+ {
+ address_word vaddr = loadstore_ea (SD_, base, index);
+ address_word paddr = vaddr;
+ /* Prefetch (paddr, vaddr, isDATA, hint); */
+ }
+}
+
+:function:::void:do_sdc1:int ft, int offset, int base
+*mipsII:
+*mips32:
+*mips32r2:
+*micromips32:
+{
+ check_fpu (SD_);
+ do_store_double (SD_, GPR[base], EXTEND16 (offset), COP_SD (1, ft));
+}
+
+:function:::void:do_suxc1_32:int fs, int rindex, int rbase
+*mips32r2:
+*micromips32:
+{
+ address_word base = GPR[rbase];
+ address_word index = GPR[rindex];
+ address_word vaddr = base + index;
+ check_fpu (SD_);
+ if (SizeFGR () != 64)
+ Unpredictable ();
+ /* Arrange for the bottom 3 bits of (base + index) to be 0. */
+ if ((vaddr & 0x7) != 0)
+ index -= (vaddr & 0x7);
+ do_store_double (SD_, base, index, COP_SD (1, fs));
+}
+
+:function:::void:do_suxc1_64:int fs, int rindex, int rbase
+{
+ address_word base = GPR[rbase];
+ address_word index = GPR[rindex];
+ address_word vaddr = base + index;
+ if (SizeFGR () != 64)
+ Unpredictable ();
+ /* Arrange for the bottom 3 bits of (base + index) to be 0. */
+ if ((vaddr & 0x7) != 0)
+ index -= (vaddr & 0x7);
+ do_store (SD_, AccessLength_DOUBLEWORD, base, index, COP_SD (1, fs));
+}
+
+:function:::void:do_sqrt_fmt:int fmt, int fd, int fs
+{
+ check_fpu (SD_);
+ StoreFPR (fd, fmt, (SquareRoot (ValueFPR (fs, fmt), fmt)));
+}
+
+:function:::void:do_sub_fmt:int fmt, int fd, int fs, int ft, address_word instruction_0
+{
+ check_fpu (SD_);
+ check_fmt_p (SD_, fmt, instruction_0);
+ StoreFPR (fd, fmt, Sub (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
+}
+
+:function:::void:do_swc1:int ft, int roffset, int rbase, address_word instruction_0
+{
+ address_word base = GPR[rbase];
+ address_word offset = EXTEND16 (roffset);
+ check_fpu (SD_);
+ {
+ address_word vaddr = loadstore_ea (SD_, base, offset);
+ address_word paddr = vaddr;
+
+ if ((vaddr & 3) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr,
+ write_transfer, sim_core_unaligned_signal);
+ }
+ else
+ {
+ uword64 memval = 0;
+ uword64 memval1 = 0;
+ uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+ address_word reverseendian =
+ (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
+ address_word bigendiancpu =
+ (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
+ unsigned int byte;
+ paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
+ byte = ((vaddr & mask) ^ bigendiancpu);
+ memval = (((uword64)COP_SW(1, ft)) << (8 * byte));
+ StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr, isREAL);
+ }
+ }
+}
+
+:function:::void:do_swxc1:int fs, int rindex, int rbase, address_word instruction_0
+{
+ address_word base = GPR[rbase];
+ address_word index = GPR[rindex];
+ check_fpu (SD_);
+ check_u64 (SD_, instruction_0);
+ {
+ address_word vaddr = loadstore_ea (SD_, base, index);
+ address_word paddr = vaddr;
+
+ if ((vaddr & 3) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer,
+ sim_core_unaligned_signal);
+ }
+ else
+ {
+ unsigned64 memval = 0;
+ unsigned64 memval1 = 0;
+ unsigned64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+ address_word reverseendian =
+ (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
+ address_word bigendiancpu =
+ (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
+ unsigned int byte;
+ paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
+ byte = ((vaddr & mask) ^ bigendiancpu);
+ memval = (((unsigned64)COP_SW(1,fs)) << (8 * byte));
+ StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr,
+ isREAL);
+ }
+ }
+}
+
+:function:::void:do_trunc_fmt:int type, int fmt, int fd, int fs
+{
+ check_fpu (SD_);
+ StoreFPR (fd, type, Convert (FP_RM_TOZERO, ValueFPR (fs, fmt), fmt,
+ type));
+}
+
+000000,5.RS,5.RT,5.RD,00000,100000:SPECIAL:32::ADD
+"add r<RD>, r<RS>, r<RT>"
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips32:
+*mips32r2:
+*mips64:
+*mips64r2:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_add (SD_, RS, RT, RD);
+}
+
+
+
+001000,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDI
+"addi r<RT>, r<RS>, <IMMEDIATE>"
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips32:
+*mips32r2:
+*mips64:
+*mips64r2:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_addi (SD_, RS, RT, IMMEDIATE);
+}
+
+
+
+:function:::void:do_addiu:int rs, int rt, unsigned16 immediate
+{
+ if (NotWordValue (GPR[rs]))
+ Unpredictable ();
+ TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
+ GPR[rt] = EXTEND32 (GPR[rs] + EXTEND16 (immediate));
+ TRACE_ALU_RESULT (GPR[rt]);
+}
+
+001001,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDIU
+"addiu r<RT>, r<RS>, <IMMEDIATE>"
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips32:
+*mips32r2:
+*mips64:
+*mips64r2:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_addiu (SD_, RS, RT, IMMEDIATE);
+}
+
+
+
+:function:::void:do_addu:int rs, int rt, int rd
+{
+ if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+ Unpredictable ();
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ GPR[rd] = EXTEND32 (GPR[rs] + GPR[rt]);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000,100001:SPECIAL:32::ADDU
+"addu r<RD>, r<RS>, r<RT>"
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips32:
+*mips32r2:
+*mips64:
+*mips64r2:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_addu (SD_, RS, RT, RD);
+}
+
+
+
+:function:::void:do_and:int rs, int rt, int rd
+{
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ GPR[rd] = GPR[rs] & GPR[rt];
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000,100100:SPECIAL:32::AND
+"and r<RD>, r<RS>, r<RT>"
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips32:
+*mips32r2:
+*mips64:
+*mips64r2:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_and (SD_, RS, RT, RD);
+}
+
+
+
+001100,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ANDI
+"andi r<RT>, r<RS>, %#lx<IMMEDIATE>"
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips32:
+*mips32r2:
+*mips64:
+*mips64r2:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_andi (SD_,RS, RT, IMMEDIATE);
+}
+
+
+
+000100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQ
+"beq r<RS>, r<RT>, <OFFSET>"
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips32:
+*mips32r2:
+*mips64:
+*mips64r2:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
+ {
+ DELAY_SLOT (NIA + offset);
+ }
+}
+
+