summaryrefslogtreecommitdiff
path: root/sim/mips/mips.igen
diff options
context:
space:
mode:
authorAndrew Bennett <andrew.bennett@imgtec.com>2015-09-25 15:52:18 +0100
committerAndrew Bennett <andrew.bennett@imgtec.com>2015-09-25 15:52:18 +0100
commit8e394ffc7ab691eafcf276d7ae578454a8c5548f (patch)
tree309466c282f5b0adc8a27e5f8fa3b6a6f2e64ee0 /sim/mips/mips.igen
parent8a9e7a9121490a8c64d8c17f5be510e43104f6d9 (diff)
downloadbinutils-gdb-8e394ffc7ab691eafcf276d7ae578454a8c5548f.tar.gz
[PATCH] Add micromips support to the MIPS simulator
2015-09-25 Andrew Bennett <andrew.bennett@imgtec.com> Ali Lown <ali.lown@imgtec.com> sim/common/ * sim-bits.h (EXTEND6): New macro. (EXTEND12): New macro. (EXTEND25): New macro. sim/mips/ * Makefile.in (tmp-micromips): New rule. (tmp-mach-multi): Add support for micromips. * configure.ac (mips*-sde-elf* | mips*-mti-elf*): Made a multi sim that works for both mips64 and micromips64. (mipsisa32r2*-*-*): Made a multi sim that works for mips32 and micromips32. Add build support for micromips. * dsp.igen (do_ph_s_absq, do_w_s_absq, do_qb_s_absq, do_addsc, do_addwc, do_bitrev, do_extpv, do_extrv, do_extrv_s_h, do_insv, do_lxx do_modsub, do_mthlip, do_mulsaq_s_w_ph, do_ph_packrl, do_qb_pick do_ph_pick, do_qb_ph_precequ, do_qb_ph_preceu, do_w_preceq do_w_ph_precrq, do_ph_qb_precrq, do_w_ph_rs_precrq do_qb_w_raddu, do_rddsp, do_repl, do_shilov, do_ph_shl, do_qb_shl do_w_s_shllv, do_ph_shrlv, do_w_r_shrav, do_wrdsp, do_qb_shrav, do_append, do_balign, do_ph_w_mulsa, do_ph_qb_precr, do_prepend): New functions. Refactored instruction code to use these functions. * dsp2.igen: Refactored instruction code to use the new functions. * interp.c (decode_coproc): Refactored to work with any instruction encoding. (isa_mode): New variable (RSVD_INSTRUCTION): Changed to 0x00000039. * m16.igen (BREAK16): Refactored instruction to use do_break16. (JALX32): Add mips32, mips64, mips32r2 and mips64r2 models. * micromips.dc: New file. * micromips.igen: New file. * micromips16.dc: New file. * micromipsdsp.igen: New file. * micromipsrun.c: New file. * mips.igen (do_swc1): Changed to work with any instruction encoding. (do_add do_addi do_andi do_dadd do_daddi do_dsll32 do_dsra32 do_dsrl32, do_dsub, do_break, do_break16, do_clo, do_clz, do_dclo do_dclz, do_lb, do_lh, do_lwr, do_lwl, do_lwc, do_lw, do_lwu, do_lhu do_ldc, do_lbu, do_ll, do_lld, do_lui, do_madd, do_dsp_madd, do_maddu do_dsp_maddu, do_dsp_mfhi, do_dsp_mflo, do_movn, do_movz, do_msub do_dsp_msub, do_msubu, do_dsp_msubu, do_mthi, do_dsp_mthi, do_mtlo do_dsp_mtlo, do_mul, do_dsp_mult, do_dsp_multu, do_pref, do_sc, do_scd do_sub, do_sw, do_teq, do_teqi, do_tge, do_tgei, do_tgeiu, do_tgeu, do_tlt do_tlti, do_tltiu, do_tltu, do_tne, do_tnei, do_abs_fmt, do_add_fmt do_alnv_ps, do_c_cond_fmt, do_ceil_fmt, do_cfc1, do_ctc1, do_cvt_d_fmt do_cvt_l_fmt, do_cvt_ps_s, do_cvt_s_fmt, do_cvt_s_pl, do_cvt_s_pu do_cvt_w_fmt, do_div_fmt, do_dmfc1b, do_dmtc1b, do_floor_fmt, do_luxc1_32 do_luxc1_64, do_lwc1, do_lwxc1, do_madd_fmt, do_mfc1b, do_mov_fmt, do_movtf do_movtf_fmt, do_movn_fmt, do_movz_fmt, do_msub_fmt, do_mtc1b, do_mul_fmt do_neg_fmt, do_nmadd_fmt, do_nmsub_fmt, do_pll_ps, do_plu_ps, do_pul_ps do_puu_ps, do_recip_fmt, do_round_fmt, do_rsqrt_fmt, do_prefx, do_sdc1 do_suxc1_32, do_suxc1_64, do_sqrt_fmt, do_sub_fmt, do_swc1, do_swxc1 do_trunc_fmt): New functions, refactored from existing instructions. Refactored instruction code to use these functions. (RSVD): Changed to use new reserved instruction. (loadstore_ea, not_word_value, unpredictable, check_mt_hilo, check_mf_hilo, check_mult_hilo, check_div_hilo, check_u64, do_luxc1_32, do_sdc1, do_suxc1_32, check_fmt_p, check_fpu, do_load_double, do_store_double): Added micromips32 and micromips64 models. Added include for micromips.igen and micromipsdsp.igen Add micromips32 and micromips64 models. (DecodeCoproc): Updated to use new macro definition. * mips3264r2.igen (do_dsbh, do_dshd, do_dext, do_dextm, do_dextu, do_di, do_dins, do_dinsm, do_ei, do_ext, do_mfhc1, do_mthc1, do_ins, do_dinsu, do_seb, do_seh do_rdhwr, do_wsbh): New functions. Refactored instruction code to use these functions. * sim-main.h (CP0_operation): New enum. (DecodeCoproc): Updated macro. (IMEM32_MICROMIPS, IMEM16_MICROMIPS, MICROMIPS_MINOR_OPCODE, MICROMIPS_DELAYSLOT_SIZE_ANY, MICROMIPS_DELAYSLOT_SIZE_16, MICROMIPS_DELAYSLOT_SIZE_32, ISA_MODE_MIPS32 and ISA_MODE_MICROMIPS): New defines. (sim_state): Add isa_mode field. sim/testsuite/sim/mips/ * basic.exp (run_micromips_test, run_sim_tests): New functions Add support for micromips tests. * hilo-hazard-4.s: New file. * testutils.inc (_dowrite): Changed reserved instruction encoding. (writemsg): Moved the la and li instructions before the data they are assigned to, which prevents a bug where MIPS32 relocations are used instead of micromips relocations when building for micromips.
Diffstat (limited to 'sim/mips/mips.igen')
-rw-r--r--sim/mips/mips.igen2235
1 files changed, 1428 insertions, 807 deletions
diff --git a/sim/mips/mips.igen b/sim/mips/mips.igen
index 5a6326fed20..2862eeb02ea 100644
--- a/sim/mips/mips.igen
+++ b/sim/mips/mips.igen
@@ -74,6 +74,9 @@
:model:::dsp:dsp: // dsp.igen
:model:::dsp2:dsp2: // dsp2.igen
:model:::smartmips:smartmips: // smartmips.igen
+:model:::micromips32:micromips64: // micromips.igen
+:model:::micromips64:micromips64: // micromips.igen
+:model:::micromipsdsp:micromipsdsp: // micromipsdsp.igen
// Vendor Extensions
//
@@ -91,7 +94,7 @@
// Pseudo instructions known by interp.c
// For grep - RSVD_INSTRUCTION, RSVD_INSTRUCTION_MASK
-000000,5.*,5.*,5.*,5.OP,000101:SPECIAL:32::RSVD
+000000,5.*,5.*,5.*,5.OP,111001:SPECIAL:32::RSVD
"rsvd <OP>"
{
SignalException (ReservedInstruction, instruction_0);
@@ -142,6 +145,7 @@
*vr4100:
*vr5000:
*r3900:
+*micromips32:
{
return base + offset;
}
@@ -149,6 +153,7 @@
:function:::address_word:loadstore_ea:address_word base, address_word offset
*mips64:
*mips64r2:
+*micromips64:
{
#if 0 /* XXX FIXME: enable this only after some additional testing. */
/* If in user mode and UX is not set, use 32-bit compatibility effective
@@ -181,6 +186,8 @@
*mips32r2:
*mips64:
*mips64r2:
+*micromips32:
+*micromips64:
{
#if WITH_TARGET_WORD_BITSIZE == 64
return value != (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
@@ -214,6 +221,8 @@
*mips32r2:
*mips64:
*mips64r2:
+*micromips32:
+*micromips64:
{
unpredictable_action (CPU, CIA);
}
@@ -305,6 +314,8 @@
*mips64:
*mips64r2:
*r3900:
+*micromips32:
+*micromips64:
{
signed64 time = sim_events_time (SD);
history->mt.timestamp = time;
@@ -331,6 +342,8 @@
*vr4100:
*vr5000:
*r3900:
+*micromips32:
+*micromips64:
{
signed64 time = sim_events_time (SD);
int ok = 1;
@@ -401,6 +414,8 @@
*mips64:
*mips64r2:
*r3900:
+*micromips32:
+*micromips64:
{
/* FIXME: could record the fact that a stall occured if we want */
signed64 time = sim_events_time (SD);
@@ -455,6 +470,8 @@
*mips32r2:
*mips64:
*mips64r2:
+*micromips32:
+*micromips64:
{
signed64 time = sim_events_time (SD);
hi->op.timestamp = time;
@@ -487,6 +504,10 @@
*mips16e:
*mips64:
*mips64r2:
+*mips32:
+*mips32r2:
+*micromips64:
+*micromips32:
{
#if 0 /* XXX FIXME: enable this only after some additional testing. */
if (UserMode && (SR & (status_UX|status_PX)) == 0)
@@ -503,6 +524,1272 @@
//
+:function:::void:do_add: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_ADD (GPR[rt]);
+ ALU32_END (GPR[rd]); /* This checks for overflow. */
+ }
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_addi:int rs, int rt, unsigned16 immediate
+{
+ if (NotWordValue (GPR[rs]))
+ Unpredictable ();
+ TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
+ {
+ ALU32_BEGIN (GPR[rs]);
+ ALU32_ADD (EXTEND16 (immediate));
+ ALU32_END (GPR[rt]); /* This checks for overflow. */
+ }
+ TRACE_ALU_RESULT (GPR[rt]);
+}
+
+:function:::void:do_andi:int rs, int rt, unsigned int immediate
+{
+ TRACE_ALU_INPUT2 (GPR[rs], immediate);
+ GPR[rt] = GPR[rs] & immediate;
+ TRACE_ALU_RESULT (GPR[rt]);
+}
+
+:function:::void:do_dadd:int rd, int rs, int rt
+{
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ {
+ ALU64_BEGIN (GPR[rs]);
+ ALU64_ADD (GPR[rt]);
+ ALU64_END (GPR[rd]); /* This checks for overflow. */
+ }
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_daddi:int rt, int rs, int immediate
+{
+ TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
+ {
+ ALU64_BEGIN (GPR[rs]);
+ ALU64_ADD (EXTEND16 (immediate));
+ ALU64_END (GPR[rt]); /* This checks for overflow. */
+ }
+ TRACE_ALU_RESULT (GPR[rt]);
+}
+
+:function:::void:do_dsll32:int rd, int rt, int shift
+{
+ int s = 32 + shift;
+ TRACE_ALU_INPUT2 (GPR[rt], s);
+ GPR[rd] = GPR[rt] << s;
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_dsra32:int rd, int rt, int shift
+{
+ int s = 32 + shift;
+ TRACE_ALU_INPUT2 (GPR[rt], s);
+ GPR[rd] = ((signed64) GPR[rt]) >> s;
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_dsrl32:int rd, int rt, int shift
+{
+ int s = 32 + shift;
+ TRACE_ALU_INPUT2 (GPR[rt], s);
+ GPR[rd] = (unsigned64) GPR[rt] >> s;
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_dsub:int rd, int rs, int rt
+{
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ {
+ ALU64_BEGIN (GPR[rs]);
+ ALU64_SUB (GPR[rt]);
+ ALU64_END (GPR[rd]); /* This checks for overflow. */
+ }
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_break:address_word instruction_0
+{
+ /* Check for some break instruction which are reserved for use by the
+ simulator. */
+ unsigned int break_code = instruction_0 & HALT_INSTRUCTION_MASK;
+ if (break_code == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
+ break_code == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
+ {
+ sim_engine_halt (SD, CPU, NULL, cia,
+ sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
+ }
+ else if (break_code == (BREAKPOINT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
+ break_code == (BREAKPOINT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
+ {
+ if (STATE & simDELAYSLOT)
+ PC = cia - 4; /* reference the branch instruction */
+ else
+ PC = cia;
+ SignalException (BreakPoint, instruction_0);
+ }
+
+ else
+ {
+ /* If we get this far, we're not an instruction reserved by the sim. Raise
+ the exception. */
+ SignalException (BreakPoint, instruction_0);
+ }
+}
+
+:function:::void:do_break16:address_word instruction_0
+{
+ if (STATE & simDELAYSLOT)
+ PC = cia - 2; /* reference the branch instruction */
+ else
+ PC = cia;
+ SignalException (BreakPoint, instruction_0);
+}
+
+:function:::void:do_clo: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_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;
+ int uncached;
+ if ((vaddr & 3) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer,
+ sim_core_unaligned_signal);
+ }
+ else
+ {
+ if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
+ isTARGET, isREAL))
+ {
+ 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, uncached, 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;
+ int uncached;
+ if ((vaddr & 7) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer,
+ sim_core_unaligned_signal);
+ }
+ else
+ {
+ if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
+ isTARGET, isREAL))
+ {
+ unsigned64 memval = 0;
+ unsigned64 memval1 = 0;
+ LoadMemory (&memval, &memval1, uncached, 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;
+ int uncached;
+ {
+ if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
+ isTARGET, isREAL))
+ Prefetch (uncached, 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;
+ int uncached;
+ if ((vaddr & 3) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer,
+ sim_core_unaligned_signal);
+ }
+ else
+ {
+ if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
+ isTARGET, isREAL))
+ {
+ 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 (uncached, 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;
+ int uncached;
+ if ((vaddr & 7) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer,
+ sim_core_unaligned_signal);
+ }
+ else
+ {
+ if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
+ isTARGET, isREAL))
+ {
+ unsigned64 memval = 0;
+ unsigned64 memval1 = 0;
+ memval = GPR[rt];
+ if (LLBIT)
+ {
+ StoreMemory (uncached, 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;
+ int uncached;
+ if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET,
+ isREAL))
+ Prefetch (uncached, 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;
+ int uncached;
+ if ((vaddr & 3) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr,
+ write_transfer, sim_core_unaligned_signal);
+ }
+ else
+ {
+ if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
+ isTARGET, isREAL))
+ {
+ 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 (uncached, 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;
+ int uncached;
+ if ((vaddr & 3) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer,
+ sim_core_unaligned_signal);
+ }
+ else
+ {
+ if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
+ isTARGET, isREAL))
+ {
+ 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 (uncached, 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>"
@@ -519,15 +1806,7 @@
*vr5000:
*r3900:
{
- if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
- Unpredictable ();
- TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
- {
- ALU32_BEGIN (GPR[RS]);
- ALU32_ADD (GPR[RT]);
- ALU32_END (GPR[RD]); /* This checks for overflow. */
- }
- TRACE_ALU_RESULT (GPR[RD]);
+ do_add (SD_, RS, RT, RD);
}
@@ -547,15 +1826,7 @@
*vr5000:
*r3900:
{
- if (NotWordValue (GPR[RS]))
- Unpredictable ();
- TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE));
- {
- ALU32_BEGIN (GPR[RS]);
- ALU32_ADD (EXTEND16 (IMMEDIATE));
- ALU32_END (GPR[RT]); /* This checks for overflow. */
- }
- TRACE_ALU_RESULT (GPR[RT]);
+ do_addi (SD_, RS, RT, IMMEDIATE);
}
@@ -660,9 +1931,7 @@
*vr5000:
*r3900:
{
- TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
- GPR[RT] = GPR[RS] & IMMEDIATE;
- TRACE_ALU_RESULT (GPR[RT]);
+ do_andi (SD_,RS, RT, IMMEDIATE);
}
@@ -1096,30 +2365,7 @@
*vr5000:
*r3900:
{
- /* Check for some break instruction which are reserved for use by the simulator. */
- unsigned int break_code = instruction_0 & HALT_INSTRUCTION_MASK;
- if (break_code == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
- break_code == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
- {
- sim_engine_halt (SD, CPU, NULL, cia,
- sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
- }
- else if (break_code == (BREAKPOINT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
- break_code == (BREAKPOINT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
- {
- if (STATE & simDELAYSLOT)
- PC = cia - 4; /* reference the branch instruction */
- else
- PC = cia;
- SignalException (BreakPoint, instruction_0);
- }
-
- else
- {
- /* If we get this far, we're not an instruction reserved by the sim. Raise
- the exception. */
- SignalException (BreakPoint, instruction_0);
- }
+ do_break (SD_, instruction_0);
}
@@ -1132,21 +2378,9 @@
*mips64r2:
*vr5500:
{
- unsigned32 temp = GPR[RS];
- unsigned32 i, mask;
if (RT != RD)
Unpredictable ();
- 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]);
+ do_clo (SD_, RD, RS);
}
@@ -1159,21 +2393,9 @@
*mips64r2:
*vr5500:
{
- unsigned32 temp = GPR[RS];
- unsigned32 i, mask;
if (RT != RD)
Unpredictable ();
- 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]);
+ do_clz (SD_, RD, RS);
}
@@ -1189,13 +2411,7 @@
*vr5000:
{
check_u64 (SD_, instruction_0);
- TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
- {
- ALU64_BEGIN (GPR[RS]);
- ALU64_ADD (GPR[RT]);
- ALU64_END (GPR[RD]); /* This checks for overflow. */
- }
- TRACE_ALU_RESULT (GPR[RD]);
+ do_dadd (SD_, RD, RS, RT);
}
@@ -1211,13 +2427,7 @@
*vr5000:
{
check_u64 (SD_, instruction_0);
- TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE));
- {
- ALU64_BEGIN (GPR[RS]);
- ALU64_ADD (EXTEND16 (IMMEDIATE));
- ALU64_END (GPR[RT]); /* This checks for overflow. */
- }
- TRACE_ALU_RESULT (GPR[RT]);
+ do_daddi (SD_, RT, RS, IMMEDIATE);
}
@@ -1274,21 +2484,10 @@
*mips64r2:
*vr5500:
{
- unsigned64 temp = GPR[RS];
- unsigned32 i;
- unsigned64 mask;
- check_u64 (SD_, instruction_0);
if (RT != RD)
Unpredictable ();
- 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]);
+ check_u64 (SD_, instruction_0);
+ do_dclo (SD_, RD, RS);
}
@@ -1299,21 +2498,10 @@
*mips64r2:
*vr5500:
{
- unsigned64 temp = GPR[RS];
- unsigned32 i;
- unsigned64 mask;
- check_u64 (SD_, instruction_0);
if (RT != RD)
Unpredictable ();
- 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]);
+ check_u64 (SD_, instruction_0);
+ do_dclz (SD_, RD, RS);
}
@@ -1680,11 +2868,8 @@
*vr4100:
*vr5000:
{
- int s = 32 + SHIFT;
check_u64 (SD_, instruction_0);
- TRACE_ALU_INPUT2 (GPR[RT], s);
- GPR[RD] = GPR[RT] << s;
- TRACE_ALU_RESULT (GPR[RD]);
+ do_dsll32 (SD_, RD, RT, SHIFT);
}
:function:::void:do_dsllv:int rs, int rt, int rd
@@ -1742,11 +2927,8 @@
*vr4100:
*vr5000:
{
- int s = 32 + SHIFT;
check_u64 (SD_, instruction_0);
- TRACE_ALU_INPUT2 (GPR[RT], s);
- GPR[RD] = ((signed64) GPR[RT]) >> s;
- TRACE_ALU_RESULT (GPR[RD]);
+ do_dsra32 (SD_, RD, RT, SHIFT);
}
@@ -1805,11 +2987,8 @@
*vr4100:
*vr5000:
{
- int s = 32 + SHIFT;
check_u64 (SD_, instruction_0);
- TRACE_ALU_INPUT2 (GPR[RT], s);
- GPR[RD] = (unsigned64) GPR[RT] >> s;
- TRACE_ALU_RESULT (GPR[RD]);
+ do_dsrl32 (SD_, RD, RT, SHIFT);
}
@@ -1849,13 +3028,7 @@
*vr5000:
{
check_u64 (SD_, instruction_0);
- TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
- {
- ALU64_BEGIN (GPR[RS]);
- ALU64_SUB (GPR[RT]);
- ALU64_END (GPR[RD]); /* This checks for overflow. */
- }
- TRACE_ALU_RESULT (GPR[RD]);
+ do_dsub (SD_, RD, RS, RT);
}
@@ -2108,7 +3281,7 @@
*vr5000:
*r3900:
{
- GPR[RT] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET)));
+ do_lb (SD_,RT,OFFSET,BASE);
}
@@ -2127,7 +3300,7 @@
*vr5000:
*r3900:
{
- GPR[RT] = do_load (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET));
+ do_lbu (SD_, RT,OFFSET,BASE);
}
@@ -2160,7 +3333,7 @@
*vr5000:
*r3900:
{
- COP_LD (ZZ, RT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
+ do_ldc (SD_, ZZ, RT, OFFSET, BASE);
}
@@ -2211,7 +3384,7 @@
*vr5000:
*r3900:
{
- GPR[RT] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET)));
+ do_lh (SD_,RT,OFFSET,BASE);
}
@@ -2230,7 +3403,7 @@
*vr5000:
*r3900:
{
- GPR[RT] = do_load (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET));
+ do_lhu (SD_,RT,OFFSET,BASE);
}
@@ -2247,35 +3420,7 @@
*vr4100:
*vr5000:
{
- address_word base = GPR[BASE];
- address_word offset = EXTEND16 (OFFSET);
- {
- address_word vaddr = loadstore_ea (SD_, base, offset);
- address_word paddr;
- int uncached;
- if ((vaddr & 3) != 0)
- {
- SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer, sim_core_unaligned_signal);
- }
- else
- {
- if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
- {
- 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,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
- byte = ((vaddr & mask) ^ (bigend << shift));
- GPR[RT] = EXTEND32 (memval >> (8 * byte));
- LLBIT = 1;
- }
- }
- }
+ do_ll (SD_, RT, OFFSET, BASE);
}
@@ -2289,29 +3434,8 @@
*vr4100:
*vr5000:
{
- address_word base = GPR[BASE];
- address_word offset = EXTEND16 (OFFSET);
check_u64 (SD_, instruction_0);
- {
- address_word vaddr = loadstore_ea (SD_, base, offset);
- address_word paddr;
- int uncached;
- if ((vaddr & 7) != 0)
- {
- SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer, sim_core_unaligned_signal);
- }
- else
- {
- if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
- {
- unsigned64 memval = 0;
- unsigned64 memval1 = 0;
- LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL);
- GPR[RT] = memval;
- LLBIT = 1;
- }
- }
- }
+ do_lld (SD_, RT, OFFSET, BASE);
}
@@ -2330,9 +3454,7 @@
*vr5000:
*r3900:
{
- TRACE_ALU_INPUT1 (IMMEDIATE);
- GPR[RT] = EXTEND32 (IMMEDIATE << 16);
- TRACE_ALU_RESULT (GPR[RT]);
+ do_lui (SD_, RT, IMMEDIATE);
}
@@ -2351,7 +3473,7 @@
*vr5000:
*r3900:
{
- GPR[RT] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
+ do_lw (SD_,RT,OFFSET,BASE);
}
@@ -2370,7 +3492,7 @@
*vr5000:
*r3900:
{
- COP_LW (ZZ, RT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
+ do_lwc (SD_, ZZ, RT, OFFSET, BASE);
}
@@ -2389,7 +3511,7 @@
*vr5000:
*r3900:
{
- GPR[RT] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]));
+ do_lwl (SD_, RT, OFFSET, BASE);
}
@@ -2408,7 +3530,7 @@
*vr5000:
*r3900:
{
- GPR[RT] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]));
+ do_lwr (SD_, RT, OFFSET, BASE);
}
@@ -2422,8 +3544,7 @@
*vr4100:
*vr5000:
{
- check_u64 (SD_, instruction_0);
- GPR[RT] = do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET));
+ do_lwu (SD_, RT, OFFSET, BASE, instruction_0);
}
@@ -2434,16 +3555,7 @@
*mips64:
*vr5500:
{
- 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);
+ do_madd (SD_, RS, RT);
}
@@ -2454,18 +3566,7 @@
*mips64r2:
*dsp2:
{
- 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);
+ do_dsp_madd (SD_, AC, RS, RT);
}
@@ -2475,17 +3576,7 @@
*mips64:
*vr5500:
{
- 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);
+ do_maddu (SD_, RS, RT);
}
@@ -2496,20 +3587,7 @@
*mips64r2:
*dsp2:
{
- 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);
+ do_dsp_maddu (SD_, AC, RS, RT);
}
@@ -2545,10 +3623,7 @@
*mips64r2:
*dsp:
{
- if (AC == 0)
- do_mfhi (SD_, RD);
- else
- GPR[RD] = DSPHI(AC);
+ do_dsp_mfhi (SD_, AC, RD);
}
@@ -2584,10 +3659,7 @@
*mips64r2:
*dsp:
{
- if (AC == 0)
- do_mflo (SD_, RD);
- else
- GPR[RD] = DSPLO(AC);
+ do_dsp_mflo (SD_, AC, RD);
}
@@ -2601,11 +3673,7 @@
*mips64r2:
*vr5000:
{
- if (GPR[RT] != 0)
- {
- GPR[RD] = GPR[RS];
- TRACE_ALU_RESULT (GPR[RD]);
- }
+ do_movn (SD_, RD, RS, RT);
}
@@ -2620,11 +3688,7 @@
*mips64r2:
*vr5000:
{
- if (GPR[RT] == 0)
- {
- GPR[RD] = GPR[RS];
- TRACE_ALU_RESULT (GPR[RD]);
- }
+ do_movz (SD_, RD, RS, RT);
}
@@ -2635,16 +3699,7 @@
*mips64:
*vr5500:
{
- 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);
+ do_msub (SD_, RS, RT);
}
@@ -2655,18 +3710,7 @@
*mips64r2:
*dsp2:
{
- 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);
+ do_dsp_msub (SD_, AC, RS, RT);
}
@@ -2676,16 +3720,7 @@
*mips64:
*vr5500:
{
- 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);
+ do_msubu (SD_, RS, RT);
}
@@ -2696,18 +3731,7 @@
*mips64r2:
*dsp2:
{
- 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);
+ do_dsp_msubu (SD_, AC, RS, RT);
}
@@ -2724,8 +3748,7 @@
*mips32:
*mips64:
{
- check_mt_hilo (SD_, HIHISTORY);
- HI = GPR[RS];
+ do_mthi (SD_, RS);
}
@@ -2736,9 +3759,7 @@
*mips64r2:
*dsp:
{
- if (AC == 0)
- check_mt_hilo (SD_, HIHISTORY);
- DSPHI(AC) = GPR[RS];
+ do_dsp_mthi (SD_, AC, RS);
}
@@ -2755,8 +3776,7 @@
*mips32:
*mips64:
{
- check_mt_hilo (SD_, LOHISTORY);
- LO = GPR[RS];
+ do_mtlo (SD_, RS);
}
@@ -2767,9 +3787,7 @@
*mips64r2:
*dsp:
{
- if (AC == 0)
- check_mt_hilo (SD_, LOHISTORY);
- DSPLO(AC) = GPR[RS];
+ do_dsp_mtlo (SD_, AC, RS);
}
@@ -2781,14 +3799,7 @@
*mips64r2:
*vr5500:
{
- 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]);
+ do_mul (SD_, RD, RS, RT);
}
@@ -2832,21 +3843,7 @@
*mips64r2:
*dsp2:
{
- 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);
- }
+ do_dsp_mult (SD_, AC, RS, RT);
}
@@ -2898,18 +3895,7 @@
*mips64r2:
*dsp2:
{
- 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);
+ do_dsp_multu (SD_, AC, RS, RT);
}
@@ -3012,17 +3998,7 @@
*mips64r2:
*vr5000:
{
- address_word base = GPR[BASE];
- address_word offset = EXTEND16 (OFFSET);
- {
- address_word vaddr = loadstore_ea (SD_, base, offset);
- address_word paddr;
- int uncached;
- {
- if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
- Prefetch(uncached,paddr,vaddr,isDATA,HINT);
- }
- }
+ do_pref (SD_, HINT, OFFSET, BASE);
}
@@ -3182,38 +4158,7 @@
*vr4100:
*vr5000:
{
- unsigned32 instruction = instruction_0;
- address_word base = GPR[BASE];
- address_word offset = EXTEND16 (OFFSET);
- {
- address_word vaddr = loadstore_ea (SD_, base, offset);
- address_word paddr;
- int uncached;
- if ((vaddr & 3) != 0)
- {
- SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, sim_core_unaligned_signal);
- }
- else
- {
- if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
- {
- 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(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
- }
- GPR[RT] = LLBIT;
- }
- }
- }
+ do_sc (SD_, RT, OFFSET, BASE, instruction_0);
}
@@ -3227,32 +4172,8 @@
*vr4100:
*vr5000:
{
- address_word base = GPR[BASE];
- address_word offset = EXTEND16 (OFFSET);
check_u64 (SD_, instruction_0);
- {
- address_word vaddr = loadstore_ea (SD_, base, offset);
- address_word paddr;
- int uncached;
- if ((vaddr & 7) != 0)
- {
- SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer, sim_core_unaligned_signal);
- }
- else
- {
- if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
- {
- unsigned64 memval = 0;
- unsigned64 memval1 = 0;
- memval = GPR[RT];
- if (LLBIT)
- {
- StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL);
- }
- GPR[RT] = LLBIT;
- }
- }
- }
+ do_scd (SD_, RT, OFFSET, BASE);
}
@@ -3648,15 +4569,7 @@
*vr5000:
*r3900:
{
- 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]);
+ do_sub (SD_, RD, RS, RT);
}
@@ -3703,7 +4616,7 @@
*r3900:
*vr5000:
{
- do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
+ do_sw (SD_, RT, OFFSET, BASE);
}
@@ -3815,8 +4728,7 @@
*vr4100:
*vr5000:
{
- if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
- SignalException (Trap, instruction_0);
+ do_teq (SD_, RS, RT, instruction_0);
}
@@ -3833,8 +4745,7 @@
*vr4100:
*vr5000:
{
- if ((signed_word) GPR[RS] == (signed_word) EXTEND16 (IMMEDIATE))
- SignalException (Trap, instruction_0);
+ do_teqi (SD_, RS, IMMEDIATE, instruction_0);
}
@@ -3851,8 +4762,7 @@
*vr4100:
*vr5000:
{
- if ((signed_word) GPR[RS] >= (signed_word) GPR[RT])
- SignalException (Trap, instruction_0);
+ do_tge (SD_, RS, RT, instruction_0);
}
@@ -3869,8 +4779,7 @@
*vr4100:
*vr5000:
{
- if ((signed_word) GPR[RS] >= (signed_word) EXTEND16 (IMMEDIATE))
- SignalException (Trap, instruction_0);
+ do_tgei (SD_, RS, IMMEDIATE, instruction_0);
}
@@ -3887,8 +4796,7 @@
*vr4100:
*vr5000:
{
- if ((unsigned_word) GPR[RS] >= (unsigned_word) EXTEND16 (IMMEDIATE))
- SignalException (Trap, instruction_0);
+ do_tgeiu (SD_, RS, IMMEDIATE, instruction_0);
}
@@ -3905,8 +4813,7 @@
*vr4100:
*vr5000:
{
- if ((unsigned_word) GPR[RS] >= (unsigned_word) GPR[RT])
- SignalException (Trap, instruction_0);
+ do_tgeu (SD_, RS, RT, instruction_0);
}
@@ -3923,8 +4830,7 @@
*vr4100:
*vr5000:
{
- if ((signed_word) GPR[RS] < (signed_word) GPR[RT])
- SignalException (Trap, instruction_0);
+ do_tlt (SD_, RS, RT, instruction_0);
}
@@ -3941,8 +4847,7 @@
*vr4100:
*vr5000:
{
- if ((signed_word) GPR[RS] < (signed_word) EXTEND16 (IMMEDIATE))
- SignalException (Trap, instruction_0);
+ do_tlti (SD_, RS, IMMEDIATE, instruction_0);
}
@@ -3959,8 +4864,7 @@
*vr4100:
*vr5000:
{
- if ((unsigned_word) GPR[RS] < (unsigned_word) EXTEND16 (IMMEDIATE))
- SignalException (Trap, instruction_0);
+ do_tltiu (SD_, RS, IMMEDIATE, instruction_0);
}
@@ -3977,8 +4881,7 @@
*vr4100:
*vr5000:
{
- if ((unsigned_word) GPR[RS] < (unsigned_word) GPR[RT])
- SignalException (Trap, instruction_0);
+ do_tltu (SD_, RS, RT, instruction_0);
}
@@ -3995,8 +4898,7 @@
*vr4100:
*vr5000:
{
- if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
- SignalException (Trap, instruction_0);
+ do_tne (SD_, RS, RT, instruction_0);
}
@@ -4013,8 +4915,7 @@
*vr4100:
*vr5000:
{
- if ((signed_word) GPR[RS] != (signed_word) EXTEND16 (IMMEDIATE))
- SignalException (Trap, instruction_0);
+ do_tnei (SD_, RS, IMMEDIATE, instruction_0);
}
@@ -4156,6 +5057,7 @@
:function:::void:check_fmt_p:int fmt, instruction_word insn
*mips32r2:
+*micromips32:
{
if ((fmt != fmt_single) && (fmt != fmt_double) && (fmt != fmt_ps))
SignalException (ReservedInstruction, insn);
@@ -4165,6 +5067,7 @@
*mipsV:
*mips64:
*mips64r2:
+*micromips64:
{
if ((fmt != fmt_single) && (fmt != fmt_double)
&& (fmt != fmt_ps || (UserMode && (SR & (status_UX|status_PX)) == 0)))
@@ -4191,6 +5094,8 @@
*vr4100:
*vr5000:
*r3900:
+*micromips32:
+*micromips64:
{
if (! COP_Usable (1))
SignalExceptionCoProcessorUnusable (1);
@@ -4208,6 +5113,7 @@
*mipsII:
*mips32:
*mips32r2:
+*micromips32:
{
int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
address_word vaddr;
@@ -4245,6 +5151,7 @@
*mipsII:
*mips32:
*mips32r2:
+*micromips32:
{
int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
address_word vaddr;
@@ -4285,10 +5192,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- check_fmt_p (SD_, fmt, instruction_0);
- StoreFPR (FD, fmt, AbsoluteValue (ValueFPR (FS, fmt), fmt));
+ do_abs_fmt (SD_, FMT, FD, FS, instruction_0);
}
@@ -4308,10 +5212,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- check_fmt_p (SD_, fmt, instruction_0);
- StoreFPR (FD, fmt, Add (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
+ do_add_fmt (SD_, FMT, FD, FS, FT, instruction_0);
}
@@ -4322,25 +5223,7 @@
*mips64:
*mips64r2:
{
- unsigned64 fs;
- unsigned64 ft;
- unsigned64 fd;
- check_fpu (SD_);
- check_u64 (SD_, instruction_0);
- fs = ValueFPR (FS, fmt_ps);
- if ((GPR[RS] & 0x3) != 0)
- Unpredictable ();
- if ((GPR[RS] & 0x4) == 0)
- fd = fs;
- else
- {
- ft = ValueFPR (FT, fmt_ps);
- if (BigEndianCPU)
- fd = PackPS (PSLower (fs), PSUpper (ft));
- else
- fd = PackPS (PSLower (ft), PSUpper (fs));
- }
- StoreFPR (FD, fmt_ps, fd);
+ do_alnv_ps (SD_, FD, FS, FT, RS, instruction_0);
}
@@ -4425,11 +5308,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- 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));
+ do_c_cond_fmt (SD_, COND, FMT, CC, FS, FT, instruction_0);
}
@@ -4445,10 +5324,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- StoreFPR (FD, fmt_long, Convert (FP_RM_TOPINF, ValueFPR (FS, fmt), fmt,
- fmt_long));
+ do_ceil_fmt (SD_, fmt_long, FMT, FD, FS, instruction_0);
}
@@ -4466,10 +5342,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- StoreFPR (FD, fmt_word, Convert (FP_RM_TOPINF, ValueFPR (FS, fmt), fmt,
- fmt_word));
+ do_ceil_fmt (SD_, fmt_word, FMT, FD, FS, instruction_0);
}
@@ -4513,15 +5386,7 @@
*mips64:
*mips64r2:
{
- 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]);
+ do_cfc1 (SD_, RT, FS);
}
010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1a
@@ -4558,11 +5423,7 @@
*mips64:
*mips64r2:
{
- check_fpu (SD_);
- TRACE_ALU_INPUT1 (GPR[RT]);
- if (FS == 25 || FS == 26 || FS == 28 || FS == 31)
- StoreFCR (FS, GPR[RT]);
- /* else NOP */
+ do_ctc1 (SD_, RT, FS);
}
@@ -4584,12 +5445,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- if ((fmt == fmt_double) | 0)
- SignalException (ReservedInstruction, instruction_0);
- StoreFPR (FD, fmt_double, Convert (GETRM (), ValueFPR (FS, fmt), fmt,
- fmt_double));
+ do_cvt_d_fmt (SD_, FMT, FD, FS, instruction_0);
}
@@ -4605,12 +5461,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- 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));
+ do_cvt_l_fmt (SD_, FMT, FD, FS, instruction_0);
}
@@ -4621,10 +5472,7 @@
*mips64:
*mips64r2:
{
- check_fpu (SD_);
- check_u64 (SD_, instruction_0);
- StoreFPR (FD, fmt_ps, PackPS (ValueFPR (FS, fmt_single),
- ValueFPR (FT, fmt_single)));
+ do_cvt_ps_s (SD_, FD, FS, FT, instruction_0);
}
@@ -4646,12 +5494,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- if ((fmt == fmt_single) | 0)
- SignalException (ReservedInstruction, instruction_0);
- StoreFPR (FD, fmt_single, Convert (GETRM (), ValueFPR (FS, fmt), fmt,
- fmt_single));
+ do_cvt_s_fmt (SD_, FMT, FD, FS, instruction_0);
}
@@ -4662,9 +5505,7 @@
*mips64:
*mips64r2:
{
- check_fpu (SD_);
- check_u64 (SD_, instruction_0);
- StoreFPR (FD, fmt_single, PSLower (ValueFPR (FS, fmt_ps)));
+ do_cvt_s_pl (SD_, FD, FS, instruction_0);
}
@@ -4675,9 +5516,7 @@
*mips64:
*mips64r2:
{
- check_fpu (SD_);
- check_u64 (SD_, instruction_0);
- StoreFPR (FD, fmt_single, PSUpper (ValueFPR (FS, fmt_ps)));
+ do_cvt_s_pu (SD_, FD, FS, instruction_0);
}
@@ -4696,12 +5535,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- 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));
+ do_cvt_w_fmt (SD_, FMT, FD, FS, instruction_0);
}
@@ -4720,9 +5554,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- StoreFPR (FD, fmt, Divide (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
+ do_div_fmt (SD_, FMT, FD, FS, FT, instruction_0);
}
@@ -4755,13 +5587,7 @@
{
check_fpu (SD_);
check_u64 (SD_, instruction_0);
- 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]);
+ do_dmfc1b (SD_, RT, FS);
}
@@ -4796,12 +5622,7 @@
{
check_fpu (SD_);
check_u64 (SD_, instruction_0);
- if (SizeFGR () == 64)
- StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]);
- else if ((FS & 0x1) == 0)
- StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]);
- else
- Unpredictable ();
+ do_dmtc1b (SD_, RT, FS);
}
@@ -4817,10 +5638,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- StoreFPR (FD, fmt_long, Convert (FP_RM_TOMINF, ValueFPR (FS, fmt), fmt,
- fmt_long));
+ do_floor_fmt (SD_, fmt_long, FMT, FD, FS);
}
@@ -4838,10 +5656,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- StoreFPR (FD, fmt_word, Convert (FP_RM_TOMINF, ValueFPR (FS, fmt), fmt,
- fmt_word));
+ do_floor_fmt (SD_, fmt_word, FMT, FD, FS);
}
@@ -4899,16 +5714,7 @@
"luxc1 f<FD>, r<INDEX>(r<BASE>)"
*mips32r2:
{
- address_word base = GPR[BASE];
- address_word index = GPR[INDEX];
- 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));
+ do_luxc1_32 (SD_, FD, INDEX, BASE);
}
@@ -4918,17 +5724,9 @@
*mips64:
*mips64r2:
{
- address_word base = GPR[BASE];
- address_word index = GPR[INDEX];
- address_word vaddr = base + index;
check_fpu (SD_);
check_u64 (SD_, instruction_0);
- 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));
+ do_luxc1_64 (SD_, FD, INDEX, BASE);
}
@@ -4947,8 +5745,7 @@
*vr5000:
*r3900:
{
- check_fpu (SD_);
- COP_LW (1, FT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
+ do_lwc1 (SD_, FT, OFFSET, BASE);
}
@@ -4961,9 +5758,7 @@
*mips64r2:
*vr5000:
{
- check_fpu (SD_);
- check_u64 (SD_, instruction_0);
- COP_LW (1, FD, do_load (SD_, AccessLength_WORD, GPR[BASE], GPR[INDEX]));
+ do_lwxc1 (SD_, FD, INDEX, BASE, instruction_0);
}
@@ -4977,12 +5772,7 @@
*mips64r2:
*vr5000:
{
- int fmt = FMT;
- 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));
+ do_madd_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
}
@@ -5011,9 +5801,7 @@
*vr5000:
*r3900:
{
- check_fpu (SD_);
- GPR[RT] = EXTEND32 (FGR[FS]);
- TRACE_ALU_RESULT (GPR[RT]);
+ do_mfc1b (SD_, RT, FS);
}
@@ -5032,10 +5820,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- check_fmt_p (SD_, fmt, instruction_0);
- StoreFPR (FD, fmt, ValueFPR (FS, fmt));
+ do_mov_fmt (SD_, FMT, FD, FS, instruction_0);
}
@@ -5051,9 +5836,7 @@
*mips64r2:
*vr5000:
{
- check_fpu (SD_);
- if (GETFCC(CC) == TF)
- GPR[RD] = GPR[RS];
+ do_movtf (SD_, TF, RD, RS, CC);
}
@@ -5069,24 +5852,7 @@
*mips64r2:
*vr5000:
{
- int fmt = FMT;
- 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 fd;
- fd = 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, fd);
- }
+ do_movtf_fmt (SD_, TF, FMT, FD, FS, CC);
}
@@ -5100,11 +5866,7 @@
*mips64r2:
*vr5000:
{
- check_fpu (SD_);
- if (GPR[RT] != 0)
- StoreFPR (FD, FMT, ValueFPR (FS, FMT));
- else
- StoreFPR (FD, FMT, ValueFPR (FD, FMT));
+ do_movn_fmt (SD_, FMT, FD, FS, RT);
}
@@ -5125,11 +5887,7 @@
*mips64r2:
*vr5000:
{
- check_fpu (SD_);
- if (GPR[RT] == 0)
- StoreFPR (FD, FMT, ValueFPR (FS, FMT));
- else
- StoreFPR (FD, FMT, ValueFPR (FD, FMT));
+ do_movz_fmt (SD_, FMT, FD, FS, RT);
}
@@ -5142,12 +5900,7 @@
*mips64r2:
*vr5000:
{
- int fmt = FMT;
- 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));
+ do_msub_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
}
@@ -5177,8 +5930,7 @@
*vr5000:
*r3900:
{
- check_fpu (SD_);
- StoreFPR (FS, fmt_uninterpreted_32, VL4_8 (GPR[RT]));
+ do_mtc1b (SD_, RT, FS);
}
@@ -5197,10 +5949,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- check_fmt_p (SD_, fmt, instruction_0);
- StoreFPR (FD, fmt, Multiply (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
+ do_mul_fmt (SD_, FMT, FD, FS, FT, instruction_0);
}
@@ -5219,10 +5968,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- check_fmt_p (SD_, fmt, instruction_0);
- StoreFPR (FD, fmt, Negate (ValueFPR (FS, fmt), fmt));
+ do_neg_fmt (SD_, FMT, FD, FS, instruction_0);
}
@@ -5235,12 +5981,7 @@
*mips64r2:
*vr5000:
{
- int fmt = FMT;
- 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));
+ do_nmadd_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
}
@@ -5253,12 +5994,7 @@
*mips64r2:
*vr5000:
{
- int fmt = FMT;
- 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));
+ do_nmsub_fmt (SD_, FMT, FD, FR, FS, FT, instruction_0);
}
@@ -5269,10 +6005,7 @@
*mips64:
*mips64r2:
{
- check_fpu (SD_);
- check_u64 (SD_, instruction_0);
- StoreFPR (FD, fmt_ps, PackPS (PSLower (ValueFPR (FS, fmt_ps)),
- PSLower (ValueFPR (FT, fmt_ps))));
+ do_pll_ps (SD_, FD, FS, FT, instruction_0);
}
@@ -5283,10 +6016,7 @@
*mips64:
*mips64r2:
{
- check_fpu (SD_);
- check_u64 (SD_, instruction_0);
- StoreFPR (FD, fmt_ps, PackPS (PSLower (ValueFPR (FS, fmt_ps)),
- PSUpper (ValueFPR (FT, fmt_ps))));
+ do_plu_ps (SD_, FD, FS, FT, instruction_0);
}
@@ -5299,15 +6029,7 @@
*mips64r2:
*vr5000:
{
- address_word base = GPR[BASE];
- address_word index = GPR[INDEX];
- {
- address_word vaddr = loadstore_ea (SD_, base, index);
- address_word paddr;
- int uncached;
- if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
- Prefetch(uncached,paddr,vaddr,isDATA,HINT);
- }
+ do_prefx (SD_, HINT, INDEX, BASE);
}
@@ -5318,10 +6040,7 @@
*mips64:
*mips64r2:
{
- check_fpu (SD_);
- check_u64 (SD_, instruction_0);
- StoreFPR (FD, fmt_ps, PackPS (PSUpper (ValueFPR (FS, fmt_ps)),
- PSLower (ValueFPR (FT, fmt_ps))));
+ do_pul_ps (SD_, FD, FS, FT, instruction_0);
}
@@ -5332,10 +6051,7 @@
*mips64:
*mips64r2:
{
- check_fpu (SD_);
- check_u64 (SD_, instruction_0);
- StoreFPR (FD, fmt_ps, PackPS (PSUpper (ValueFPR (FS, fmt_ps)),
- PSUpper (ValueFPR (FT, fmt_ps))));
+ do_puu_ps (SD_, FD, FS, FT, instruction_0);
}
@@ -5348,9 +6064,7 @@
*mips64r2:
*vr5000:
{
- int fmt = FMT;
- check_fpu (SD_);
- StoreFPR (FD, fmt, Recip (ValueFPR (FS, fmt), fmt));
+ do_recip_fmt (SD_, FMT, FD, FS);
}
@@ -5366,10 +6080,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- StoreFPR (FD, fmt_long, Convert (FP_RM_NEAREST, ValueFPR (FS, fmt), fmt,
- fmt_long));
+ do_round_fmt (SD_, fmt_long, FMT, FD, FS);
}
@@ -5387,10 +6098,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- StoreFPR (FD, fmt_word, Convert (FP_RM_NEAREST, ValueFPR (FS, fmt), fmt,
- fmt_word));
+ do_round_fmt (SD_, fmt_word, FMT, FD, FS);
}
@@ -5403,9 +6111,7 @@
*mips64r2:
*vr5000:
{
- int fmt = FMT;
- check_fpu (SD_);
- StoreFPR (FD, fmt, RSquareRoot (ValueFPR (FS, fmt), fmt));
+ do_rsqrt_fmt (SD_, FMT, FD, FS);
}
@@ -5415,8 +6121,7 @@
*mips32:
*mips32r2:
{
- check_fpu (SD_);
- do_store_double (SD_, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT));
+ do_sdc1 (SD_, FT, OFFSET, BASE);
}
@@ -5463,16 +6168,7 @@
"suxc1 f<FS>, r<INDEX>(r<BASE>)"
*mips32r2:
{
- address_word base = GPR[BASE];
- address_word index = GPR[INDEX];
- 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));
+ do_suxc1_32 (SD_, FS, INDEX, BASE);
}
@@ -5482,17 +6178,9 @@
*mips64:
*mips64r2:
{
- address_word base = GPR[BASE];
- address_word index = GPR[INDEX];
- address_word vaddr = base + index;
check_fpu (SD_);
check_u64 (SD_, instruction_0);
- 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));
+ do_suxc1_64 (SD_, FS, INDEX, BASE);
}
@@ -5510,9 +6198,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- StoreFPR (FD, fmt, (SquareRoot (ValueFPR (FS, fmt), fmt)));
+ do_sqrt_fmt (SD_, FMT, FD, FS);
}
@@ -5531,10 +6217,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- check_fmt_p (SD_, fmt, instruction_0);
- StoreFPR (FD, fmt, Sub (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
+ do_sub_fmt (SD_, FMT, FD, FS, FT, instruction_0);
}
@@ -5554,34 +6237,7 @@
*vr5000:
*r3900:
{
- address_word base = GPR[BASE];
- address_word offset = EXTEND16 (OFFSET);
- check_fpu (SD_);
- {
- address_word vaddr = loadstore_ea (SD_, base, offset);
- address_word paddr;
- int uncached;
- if ((vaddr & 3) != 0)
- {
- SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr, write_transfer, sim_core_unaligned_signal);
- }
- else
- {
- if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
- {
- 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(((instruction_0 >> 26) & 0x3),FT)) << (8 * byte));
- StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
- }
- }
- }
+ do_swc1 (SD_, FT, OFFSET, BASE, instruction_0);
}
@@ -5594,38 +6250,7 @@
*mips64r2:
*vr5000:
{
-
- address_word base = GPR[BASE];
- address_word index = GPR[INDEX];
- check_fpu (SD_);
- check_u64 (SD_, instruction_0);
- {
- address_word vaddr = loadstore_ea (SD_, base, index);
- address_word paddr;
- int uncached;
- if ((vaddr & 3) != 0)
- {
- SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, sim_core_unaligned_signal);
- }
- else
- {
- if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
- {
- 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(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
- }
- }
- }
- }
+ do_swxc1 (SD_, FS, INDEX, BASE, instruction_0);
}
@@ -5641,10 +6266,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- StoreFPR (FD, fmt_long, Convert (FP_RM_TOZERO, ValueFPR (FS, fmt), fmt,
- fmt_long));
+ do_trunc_fmt (SD_, fmt_long, FMT, FD, FS);
}
@@ -5662,10 +6284,7 @@
*vr5000:
*r3900:
{
- int fmt = FMT;
- check_fpu (SD_);
- StoreFPR (FD, fmt_word, Convert (FP_RM_TOZERO, ValueFPR (FS, fmt), fmt,
- fmt_word));
+ do_trunc_fmt (SD_, fmt_word, FMT, FD, FS);
}
@@ -5768,7 +6387,7 @@
}
-010000,00001,5.RT,5.RD,00000000000:COP0:64::DMFC0
+010000,00001,5.RT,5.RD,00000000,3.SEL:COP0:64::DMFC0
"dmfc0 r<RT>, r<RD>"
*mipsIII:
*mipsIV:
@@ -5777,11 +6396,11 @@
*mips64r2:
{
check_u64 (SD_, instruction_0);
- DecodeCoproc (instruction_0);
+ DecodeCoproc (instruction_0, 0, cp0_dmfc0, RT, RD, SEL);
}
-010000,00101,5.RT,5.RD,00000000000:COP0:64::DMTC0
+010000,00101,5.RT,5.RD,00000000,3.SEL:COP0:64::DMTC0
"dmtc0 r<RT>, r<RD>"
*mipsIII:
*mipsIV:
@@ -5790,7 +6409,7 @@
*mips64r2:
{
check_u64 (SD_, instruction_0);
- DecodeCoproc (instruction_0);
+ DecodeCoproc (instruction_0, 0, cp0_dmtc0, RT, RD, SEL);
}
@@ -5821,8 +6440,8 @@
}
-010000,00000,5.RT,5.RD,00000,6.REGX:COP0:32::MFC0
-"mfc0 r<RT>, r<RD> # <REGX>"
+010000,00000,5.RT,5.RD,00000000,3.SEL:COP0:32::MFC0
+"mfc0 r<RT>, r<RD> # <SEL>"
*mipsI:
*mipsII:
*mipsIII:
@@ -5837,12 +6456,12 @@
*r3900:
{
TRACE_ALU_INPUT0 ();
- DecodeCoproc (instruction_0);
+ DecodeCoproc (instruction_0, 0, cp0_mfc0, RT, RD, SEL);
TRACE_ALU_RESULT (GPR[RT]);
}
-010000,00100,5.RT,5.RD,00000,6.REGX:COP0:32::MTC0
-"mtc0 r<RT>, r<RD> # <REGX>"
+010000,00100,5.RT,5.RD,00000000,3.SEL:COP0:32::MTC0
+"mtc0 r<RT>, r<RD> # <SEL>"
*mipsI:
*mipsII:
*mipsIII:
@@ -5856,7 +6475,7 @@
*vr5000:
*r3900:
{
- DecodeCoproc (instruction_0);
+ DecodeCoproc (instruction_0, 0, cp0_mtc0, RT, RD, SEL);
}
@@ -5871,7 +6490,7 @@
*vr5000:
*r3900:
{
- DecodeCoproc (instruction_0);
+ DecodeCoproc (instruction_0, 0, cp0_rfe, 0, 0, 0x10);
}
@@ -5889,7 +6508,7 @@
*vr4100:
*r3900:
{
- DecodeCoproc (instruction_0);
+ DecodeCoproc (instruction_0, 2, 0, 0, 0, 0);
}
@@ -5965,4 +6584,6 @@
:include:::dsp.igen
:include:::dsp2.igen
:include:::smartmips.igen
+:include:::micromips.igen
+:include:::micromipsdsp.igen