diff options
Diffstat (limited to 'sim/mips/mips.igen')
-rw-r--r-- | sim/mips/mips.igen | 1426 |
1 files changed, 961 insertions, 465 deletions
diff --git a/sim/mips/mips.igen b/sim/mips/mips.igen index b5930d58c18..cd96766d885 100644 --- a/sim/mips/mips.igen +++ b/sim/mips/mips.igen @@ -1,9 +1,5 @@ // -*- C -*- // -// In mips.igen, the semantics for many of the instructions were created -// using code generated by gencode. Those semantic segments could be -// greatly simplified. -// // <insn> ::= // <insn-word> { "+" <insn-word> } // ":" <format-name> @@ -48,6 +44,8 @@ :model:::mipsIII:mips4000: :model:::mipsIV:mips8000: :model:::mipsV:mipsisaV: +:model:::mips32:mipsisa32: +:model:::mips64:mipsisa64: // Vendor ISAs: // @@ -109,8 +107,107 @@ return CIA + 8; } + +// Helper: +// +// Calculate an effective address given a base and an offset. +// + +:function:::address_word:loadstore_ea:address_word base, address_word offset +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +*mipsV: +*mips32: +*vr4100: +*vr5000: +*r3900: +{ + return base + offset; +} + +:function:::address_word:loadstore_ea:address_word base, address_word offset +*mips64: +{ +#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 + address computations as defined in the MIPS64 Architecture for + Programmers Volume III, Revision 0.95, section 4.9. */ + if ((SR & (status_KSU_mask|status_EXL|status_ERL|status_UX)) + == (ksu_user << status_KSU_shift)) + return (address_word)((signed32)base + (signed32)offset); +#endif + return base + offset; +} + + +// Helper: +// +// Check that a 32-bit register value is properly sign-extended. +// (See NotWordValue in ISA spec.) +// + +:function:::int:not_word_value:unsigned_word value +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +*mipsV: +*vr4100: +*vr5000: +*r3900: +{ + /* For historical simulator compatibility (until documentation is + found that makes these operations unpredictable on some of these + architectures), this check never returns true. */ + return 0; +} + +:function:::int:not_word_value:unsigned_word value +*mips32: +{ + /* On MIPS32, since registers are 32-bits, there's no check to be done. */ + return 0; +} + +:function:::int:not_word_value:unsigned_word value +*mips64: +{ + return ((value >> 32) != (value & 0x80000000 ? 0xFFFFFFFF : 0)); +} + + +// Helper: +// +// Handle UNPREDICTABLE operation behaviour. The goal here is to prevent +// theoretically portable code which invokes non-portable behaviour from +// running with no indication of the portability issue. +// (See definition of UNPREDICTABLE in ISA spec.) +// + +:function:::void:unpredictable: +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +*mipsV: +*vr4100: +*vr5000: +*r3900: +{ +} + +:function:::void:unpredictable: +*mips32: +*mips64: +{ + unpredictable_action (CPU, CIA); +} + + // Helper: -// +// // Check that an access to a HI/LO register meets timing requirements // // The following requirements exist: @@ -128,7 +225,7 @@ sim_engine_abort (SD, CPU, CIA, "HILO: %s: %s at 0x%08lx too close to MF at 0x%08lx\n", itable[MY_INDEX].name, new, (long) CIA, - (long) history->mf.cia); + (long) history->mf.cia); return 0; } return 1; @@ -151,6 +248,8 @@ } :function:::int:check_mt_hilo:hilo_history *history +*mips32: +*mips64: *r3900: { signed64 time = sim_events_time (SD); @@ -166,6 +265,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -186,7 +287,7 @@ itable[MY_INDEX].name, (long) CIA, (long) history->op.cia, - (long) peer->mt.cia); + (long) peer->mt.cia); ok = 0; } history->mf.timestamp = time; @@ -218,6 +319,8 @@ // The r3900 mult and multu insns _can_ be exectuted immediatly after // a mf{hi,lo} :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo +*mips32: +*mips64: *r3900: { /* FIXME: could record the fact that a stall occured if we want */ @@ -236,6 +339,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -252,9 +357,9 @@ // Helper: -// +// // Check that the 64-bit instruction can currently be used, and signal -// an ReservedInstruction exception if not. +// a ReservedInstruction exception if not. // :function:::void:check_u64:instruction_word insn @@ -264,16 +369,24 @@ *vr4100: *vr5000: { - // On mips64, if UserMode check SR:PX & SR:UX bits. // The check should be similar to mips64 for any with PX/UX bit equivalents. } +:function:::void:check_u64:instruction_word insn +*mips64: +{ +#if 0 /* XXX FIXME: enable this only after some additional testing. */ + if (UserMode && (SR & (status_UX|status_PX)) == 0) + SignalException (ReservedInstruction, insn); +#endif +} + // // MIPS Architecture: // -// CPU Instruction Set (mipsI - mipsV) +// CPU Instruction Set (mipsI - mipsV, mips32, mips64) // @@ -285,10 +398,14 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { + if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT])) + Unpredictable (); TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]); { ALU32_BEGIN (GPR[RS]); @@ -307,10 +424,14 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { + if (NotWordValue (GPR[RS])) + Unpredictable (); TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE)); { ALU32_BEGIN (GPR[RS]); @@ -324,6 +445,8 @@ :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]); @@ -336,6 +459,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -347,6 +472,8 @@ :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]); @@ -359,6 +486,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -382,6 +511,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -392,12 +523,14 @@ 001100,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ANDI -"and r<RT>, r<RS>, <IMMEDIATE>" +"andi r<RT>, r<RS>, %#lx<IMMEDIATE>" *mipsI: *mipsII: *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -416,6 +549,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -437,6 +572,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -461,6 +598,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -483,12 +622,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; check_branch_bug (); + if (RS == 31) + Unpredictable (); RA = (CIA + 8); if ((signed_word) GPR[RS] >= 0) { @@ -505,12 +648,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; check_branch_bug (); + if (RS == 31) + Unpredictable (); RA = (CIA + 8); /* NOTE: The branch occurs AFTER the next instruction has been executed */ @@ -531,6 +678,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -555,6 +704,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -576,6 +727,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -602,6 +755,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -625,6 +780,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -649,6 +806,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -671,12 +830,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; check_branch_bug (); + if (RS == 31) + Unpredictable (); RA = (CIA + 8); /* NOTE: The branch occurs AFTER the next instruction has been executed */ @@ -695,12 +858,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; check_branch_bug (); + if (RS == 31) + Unpredictable (); RA = (CIA + 8); if ((signed_word) GPR[RS] < 0) { @@ -719,6 +886,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -745,6 +914,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -766,6 +937,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -784,12 +957,14 @@ 000000,20.CODE,001101:SPECIAL:32::BREAK -"break <CODE>" +"break %#lx<CODE>" *mipsI: *mipsII: *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -809,24 +984,73 @@ PC = cia - 4; /* reference the branch instruction */ else PC = cia; - SignalException(BreakPoint, instruction_0); + SignalException (BreakPoint, instruction_0); } else { - /* If we get this far, we're not an instruction reserved by the sim. Raise + /* If we get this far, we're not an instruction reserved by the sim. Raise the exception. */ - SignalException(BreakPoint, instruction_0); + SignalException (BreakPoint, instruction_0); } } +011100,5.RS,5.RT,5.RD,00000,100001:SPECIAL2:32::CLO +"clo r<RD>, r<RS>" +*mips32: +*mips64: +{ + 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]); +} + + + +011100,5.RS,5.RT,5.RD,00000,100000:SPECIAL2:32::CLZ +"clz r<RD>, r<RS>" +*mips32: +*mips64: +{ + 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]); +} + + + 000000,5.RS,5.RT,5.RD,00000,101100:SPECIAL:64::DADD "dadd r<RD>, r<RS>, r<RT>" *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -847,6 +1071,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -874,6 +1099,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -895,6 +1121,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -904,6 +1131,52 @@ +011100,5.RS,5.RT,5.RD,00000,100101:SPECIAL2:64::DCLO +"dclo r<RD>, r<RS>" +*mips64: +{ + 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]); +} + + + +011100,5.RS,5.RT,5.RD,00000,100100:SPECIAL2:64::DCLZ +"dclz r<RD>, r<RS>" +*mips64: +{ + 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]); +} + + + :function:::void:do_ddiv:int rs, int rt { check_div_hilo (SD_, HIHISTORY, LOHISTORY); @@ -939,6 +1212,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -978,6 +1252,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1020,6 +1295,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1057,6 +1334,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1080,7 +1359,7 @@ unsigned64 op2 = GPR[rt]; check_mult_hilo (SD_, HIHISTORY, LOHISTORY); TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); - /* make signed multiply unsigned */ + /* make signed multiply unsigned */ sign = 0; if (signed_p) { @@ -1136,6 +1415,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: { check_u64 (SD_, instruction_0); @@ -1163,6 +1443,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: { check_u64 (SD_, instruction_0); @@ -1190,6 +1471,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1203,6 +1485,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1226,6 +1509,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1246,6 +1530,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1259,6 +1544,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1283,6 +1569,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1303,6 +1590,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1316,6 +1604,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1342,6 +1631,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1355,6 +1645,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1381,6 +1672,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1396,6 +1688,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1414,6 +1708,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1433,6 +1729,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1450,6 +1748,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1469,7 +1769,7 @@ unsigned64 memval; address_word vaddr; - vaddr = base + offset; + vaddr = loadstore_ea (SD_, base, offset); if ((vaddr & access) != 0) { SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map, access+1, vaddr, read_transfer, sim_core_unaligned_signal); @@ -1497,7 +1797,7 @@ unsigned_word lhs_mask; unsigned_word temp; - vaddr = base + offset; + vaddr = loadstore_ea (SD_, base, offset); AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL); paddr = (paddr ^ (reverseendian & mask)); if (BigEndianMem == 0) @@ -1548,7 +1848,7 @@ unsigned64 memval; address_word vaddr; - vaddr = base + offset; + vaddr = loadstore_ea (SD_, base, offset); AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL); /* NOTE: SPEC is wrong, has `BigEndianMem == 0' not `BigEndianMem != 0' */ paddr = (paddr ^ (reverseendian & mask)); @@ -1575,6 +1875,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1590,6 +1892,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1603,6 +1907,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1617,6 +1922,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1632,6 +1939,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1645,6 +1953,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1660,6 +1969,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1675,6 +1986,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1689,15 +2002,15 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { - unsigned32 instruction = instruction_0; - signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16); - int destreg = ((instruction >> 16) & 0x0000001F); - signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)]; + address_word base = GPR[BASE]; + address_word offset = EXTEND16 (OFFSET); { - address_word vaddr = ((unsigned64)op1 + offset); + address_word vaddr = loadstore_ea (SD_, base, offset); address_word paddr; int uncached; if ((vaddr & 3) != 0) @@ -1718,7 +2031,7 @@ paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL); byte = ((vaddr & mask) ^ (bigend << shift)); - GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0xFFFFFFFF),32)); + GPR[RT] = EXTEND32 (memval >> (8 * byte)); LLBIT = 1; } } @@ -1731,16 +2044,15 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { - unsigned32 instruction = instruction_0; - signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16); - int destreg = ((instruction >> 16) & 0x0000001F); - signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)]; + address_word base = GPR[BASE]; + address_word offset = EXTEND16 (OFFSET); check_u64 (SD_, instruction_0); { - address_word vaddr = ((unsigned64)op1 + offset); + address_word vaddr = loadstore_ea (SD_, base, offset); address_word paddr; int uncached; if ((vaddr & 7) != 0) @@ -1754,7 +2066,7 @@ unsigned64 memval = 0; unsigned64 memval1 = 0; LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL); - GPR[destreg] = memval; + GPR[RT] = memval; LLBIT = 1; } } @@ -1763,12 +2075,14 @@ 001111,00000,5.RT,16.IMMEDIATE:NORMAL:32::LUI -"lui r<RT>, <IMMEDIATE>" +"lui r<RT>, %#lx<IMMEDIATE>" *mipsI: *mipsII: *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1786,6 +2100,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1801,6 +2117,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1816,6 +2134,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1831,6 +2151,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1844,6 +2166,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -1852,6 +2175,44 @@ } + +011100,5.RS,5.RT,00000,00000,000000:SPECIAL2:32::MADD +"madd r<RS>, r<RT>" +*mips32: +*mips64: +{ + 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); +} + + + +011100,5.RS,5.RT,00000,00000,000001:SPECIAL2:32::MADDU +"maddu r<RS>, r<RT>" +*mips32: +*mips64: +{ + 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_mfhi:int rd { check_mf_hilo (SD_, HIHISTORY, LOHISTORY); @@ -1867,6 +2228,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1891,6 +2254,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1904,6 +2269,8 @@ "movn r<RD>, r<RS>, r<RT>" *mipsIV: *mipsV: +*mips32: +*mips64: *vr5000: { if (GPR[RT] != 0) @@ -1916,6 +2283,8 @@ "movz r<RD>, r<RS>, r<RT>" *mipsIV: *mipsV: +*mips32: +*mips64: *vr5000: { if (GPR[RT] == 0) @@ -1924,6 +2293,44 @@ +011100,5.RS,5.RT,00000,00000,000100:SPECIAL2:32::MSUB +"msub r<RS>, r<RT>" +*mips32: +*mips64: +{ + 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); +} + + + +011100,5.RS,5.RT,00000,00000,000101:SPECIAL2:32::MSUBU +"msubu r<RS>, r<RT>" +*mips32: +*mips64: +{ + 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); +} + + + 000000,5.RS,000000000000000,010001:SPECIAL:32::MTHI "mthi r<RS>" *mipsI: @@ -1931,6 +2338,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1948,6 +2357,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -1958,10 +2369,29 @@ +011100,5.RS,5.RT,5.RD,00000,000010:SPECIAL2:32::MUL +"mul r<RD>, r<RS>, r<RT>" +*mips32: +*mips64: +{ + 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_mult:int rs, int rt, int rd { signed64 prod; 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])); @@ -1979,6 +2409,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: { do_mult (SD_, RS, RT, 0); @@ -1999,6 +2431,8 @@ { unsigned64 prod; 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])); @@ -2016,6 +2450,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: { do_multu (SD_, RS, RT, 0); @@ -2045,6 +2481,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2067,6 +2505,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2084,12 +2524,14 @@ } 001101,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ORI -"ori r<RT>, r<RS>, <IMMEDIATE>" +"ori r<RT>, r<RS>, %#lx<IMMEDIATE>" *mipsI: *mipsII: *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2102,19 +2544,19 @@ "pref <HINT>, <OFFSET>(r<BASE>)" *mipsIV: *mipsV: +*mips32: +*mips64: *vr5000: { - unsigned32 instruction = instruction_0; - signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16); - int hint = ((instruction >> 16) & 0x0000001F); - signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)]; + address_word base = GPR[BASE]; + address_word offset = EXTEND16 (OFFSET); { - address_word vaddr = ((unsigned64)op1 + 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); + Prefetch(uncached,paddr,vaddr,isDATA,HINT); } } } @@ -2131,7 +2573,7 @@ unsigned64 memval; address_word vaddr; - vaddr = base + offset; + vaddr = loadstore_ea (SD_, base, offset); if ((vaddr & access) != 0) { SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map, access+1, vaddr, write_transfer, sim_core_unaligned_signal); @@ -2157,7 +2599,7 @@ int nr_lhs_bits; int nr_rhs_bits; - vaddr = base + offset; + vaddr = loadstore_ea (SD_, base, offset); AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL); paddr = (paddr ^ (reverseendian & mask)); if (BigEndianMem == 0) @@ -2199,7 +2641,7 @@ unsigned64 memval; address_word vaddr; - vaddr = base + offset; + vaddr = loadstore_ea (SD_, base, offset); AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL); paddr = (paddr ^ (reverseendian & mask)); if (BigEndianMem != 0) @@ -2217,6 +2659,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2231,15 +2675,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { unsigned32 instruction = instruction_0; - signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16); - signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)]; - signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)]; + address_word base = GPR[BASE]; + address_word offset = EXTEND16 (OFFSET); { - address_word vaddr = ((unsigned64)op1 + offset); + address_word vaddr = loadstore_ea (SD_, base, offset); address_word paddr; int uncached; if ((vaddr & 3) != 0) @@ -2256,12 +2701,12 @@ unsigned int byte; paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2))); byte = ((vaddr & mask) ^ (BigEndianCPU << 2)); - memval = ((unsigned64) op2 << (8 * byte)); + memval = ((unsigned64) GPR[RT] << (8 * byte)); if (LLBIT) { StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL); } - GPR[(instruction >> 16) & 0x0000001F] = LLBIT; + GPR[RT] = LLBIT; } } } @@ -2273,16 +2718,15 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { - unsigned32 instruction = instruction_0; - signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16); - signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)]; - signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)]; + address_word base = GPR[BASE]; + address_word offset = EXTEND16 (OFFSET); check_u64 (SD_, instruction_0); { - address_word vaddr = ((unsigned64)op1 + offset); + address_word vaddr = loadstore_ea (SD_, base, offset); address_word paddr; int uncached; if ((vaddr & 7) != 0) @@ -2295,12 +2739,12 @@ { unsigned64 memval = 0; unsigned64 memval1 = 0; - memval = op2; + memval = GPR[RT]; if (LLBIT) { StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL); } - GPR[(instruction >> 16) & 0x0000001F] = LLBIT; + GPR[RT] = LLBIT; } } } @@ -2312,6 +2756,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -2326,6 +2771,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { @@ -2338,6 +2785,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -2351,6 +2799,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: { @@ -2366,6 +2815,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2382,7 +2833,7 @@ TRACE_ALU_RESULT (GPR[rd]); } -000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLL +000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLLa "nop":RD == 0 && RT == 0 && SHIFT == 0 "sll r<RD>, r<RT>, <SHIFT>" *mipsI: @@ -2400,6 +2851,19 @@ do_sll (SD_, RT, RD, SHIFT); } +000000,00000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLLb +"nop":RD == 0 && RT == 0 && SHIFT == 0 +"ssnop":RD == 0 && RT == 0 && SHIFT == 1 +"sll r<RD>, r<RT>, <SHIFT>" +*mips32: +*mips64: +{ + /* Skip shift for NOP and SSNOP, so that there won't be lots of + extraneous trace output. */ + if (RD != 0 || RT != 0 || (SHIFT != 0 && SHIFT != 1)) + do_sll (SD_, RT, RD, SHIFT); +} + :function:::void:do_sllv:int rs, int rt, int rd { @@ -2417,6 +2881,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2439,6 +2905,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2461,6 +2929,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2483,6 +2953,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2506,6 +2978,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2517,6 +2991,8 @@ :function:::void:do_sra:int rt, int rd, int shift { signed32 temp = (signed32) GPR[rt] >> shift; + if (NotWordValue (GPR[rt])) + Unpredictable (); TRACE_ALU_INPUT2 (GPR[rt], shift); GPR[rd] = EXTEND32 (temp); TRACE_ALU_RESULT (GPR[rd]); @@ -2529,6 +3005,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2542,6 +3020,8 @@ { int s = MASKED (GPR[rs], 4, 0); signed32 temp = (signed32) GPR[rt] >> s; + if (NotWordValue (GPR[rt])) + Unpredictable (); TRACE_ALU_INPUT2 (GPR[rt], s); GPR[rd] = EXTEND32 (temp); TRACE_ALU_RESULT (GPR[rd]); @@ -2554,6 +3034,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2566,6 +3048,8 @@ :function:::void:do_srl:int rt, int rd, int shift { unsigned32 temp = (unsigned32) GPR[rt] >> shift; + if (NotWordValue (GPR[rt])) + Unpredictable (); TRACE_ALU_INPUT2 (GPR[rt], shift); GPR[rd] = EXTEND32 (temp); TRACE_ALU_RESULT (GPR[rd]); @@ -2578,6 +3062,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2590,6 +3076,8 @@ { int s = MASKED (GPR[rs], 4, 0); unsigned32 temp = (unsigned32) GPR[rt] >> s; + if (NotWordValue (GPR[rt])) + Unpredictable (); TRACE_ALU_INPUT2 (GPR[rt], s); GPR[rd] = EXTEND32 (temp); TRACE_ALU_RESULT (GPR[rd]); @@ -2602,6 +3090,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2617,10 +3107,14 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { + if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT])) + Unpredictable (); TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]); { ALU32_BEGIN (GPR[RS]); @@ -2633,6 +3127,8 @@ :function:::void:do_subu: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]); @@ -2645,6 +3141,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2660,6 +3158,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *r3900: *vr5000: @@ -2675,6 +3175,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2690,6 +3192,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2705,6 +3209,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2720,6 +3226,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2729,17 +3237,19 @@ 000000,20.CODE,001100:SPECIAL:32::SYSCALL -"syscall <CODE>" +"syscall %#lx<CODE>" *mipsI: *mipsII: *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - SignalException(SystemCall, instruction_0); + SignalException (SystemCall, instruction_0); } @@ -2749,11 +3259,13 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { if ((signed_word) GPR[RS] == (signed_word) GPR[RT]) - SignalException(Trap, instruction_0); + SignalException (Trap, instruction_0); } @@ -2763,11 +3275,13 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { if ((signed_word) GPR[RS] == (signed_word) EXTEND16 (IMMEDIATE)) - SignalException(Trap, instruction_0); + SignalException (Trap, instruction_0); } @@ -2777,11 +3291,13 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { if ((signed_word) GPR[RS] >= (signed_word) GPR[RT]) - SignalException(Trap, instruction_0); + SignalException (Trap, instruction_0); } @@ -2791,11 +3307,13 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { if ((signed_word) GPR[RS] >= (signed_word) EXTEND16 (IMMEDIATE)) - SignalException(Trap, instruction_0); + SignalException (Trap, instruction_0); } @@ -2805,11 +3323,13 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { if ((unsigned_word) GPR[RS] >= (unsigned_word) EXTEND16 (IMMEDIATE)) - SignalException(Trap, instruction_0); + SignalException (Trap, instruction_0); } @@ -2819,11 +3339,13 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { if ((unsigned_word) GPR[RS] >= (unsigned_word) GPR[RT]) - SignalException(Trap, instruction_0); + SignalException (Trap, instruction_0); } @@ -2833,11 +3355,13 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { if ((signed_word) GPR[RS] < (signed_word) GPR[RT]) - SignalException(Trap, instruction_0); + SignalException (Trap, instruction_0); } @@ -2847,11 +3371,13 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { if ((signed_word) GPR[RS] < (signed_word) EXTEND16 (IMMEDIATE)) - SignalException(Trap, instruction_0); + SignalException (Trap, instruction_0); } @@ -2861,11 +3387,13 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { if ((unsigned_word) GPR[RS] < (unsigned_word) EXTEND16 (IMMEDIATE)) - SignalException(Trap, instruction_0); + SignalException (Trap, instruction_0); } @@ -2875,11 +3403,13 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { if ((unsigned_word) GPR[RS] < (unsigned_word) GPR[RT]) - SignalException(Trap, instruction_0); + SignalException (Trap, instruction_0); } @@ -2889,11 +3419,13 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { if ((signed_word) GPR[RS] != (signed_word) GPR[RT]) - SignalException(Trap, instruction_0); + SignalException (Trap, instruction_0); } @@ -2903,11 +3435,13 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { if ((signed_word) GPR[RS] != (signed_word) EXTEND16 (IMMEDIATE)) - SignalException(Trap, instruction_0); + SignalException (Trap, instruction_0); } @@ -2925,6 +3459,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -2941,12 +3477,14 @@ } 001110,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::XORI -"xori r<RT>, r<RS>, <IMMEDIATE>" +"xori r<RT>, r<RS>, %#lx<IMMEDIATE>" *mipsI: *mipsII: *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -3024,26 +3562,80 @@ } } + +// Helpers: +// +// Check that the given FPU format is usable, and signal a +// ReservedInstruction exception if not. +// + +// check_fmt checks that the format is single or double. +:function:::void:check_fmt:int fmt, instruction_word insn +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +*mipsV: +*mips32: +*mips64: +*vr4100: +*vr5000: +*r3900: +{ + if ((fmt != fmt_single) && (fmt != fmt_double)) + SignalException (ReservedInstruction, insn); +} + +// check_fmt_p checks that the format is single, double, or paired single. +:function:::void:check_fmt_p:int fmt, instruction_word insn +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +*mips32: +*vr4100: +*vr5000: +*r3900: +{ + /* None of these ISAs support Paired Single, so just fall back to + the single/double check. */ + check_fmt (SD_, fmt, insn); +} + +:function:::void:check_fmt_p:int fmt, instruction_word insn +*mipsV: +*mips64: +{ +#if 0 /* XXX FIXME: FP code doesn't yet support paired single ops. */ + if ((fmt != fmt_single) && (fmt != fmt_double) + && (fmt != fmt_ps || (UserMode && (SR & (status_UX|status_PX)) == 0))) + SignalException (ReservedInstruction, insn); +#else + check_fmt (SD_, fmt, insn); +#endif +} + + // Helper: -// +// // Check that the FPU is currently usable, and signal a CoProcessorUnusable // exception if not. // :function:::void:check_fpu: -*mipsI: +*mipsI: *mipsII: *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { -#if 0 /* XXX FIXME: For now, never treat the FPU as disabled. */ if (! COP_Usable (1)) SignalExceptionCoProcessorUnusable (1); -#endif } @@ -3054,21 +3646,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,format,AbsoluteValue(ValueFPR(fs,format),format)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt_p (SD_, fmt, instruction_0); + StoreFPR(FD,fmt,AbsoluteValue(ValueFPR(FS,fmt),fmt)); } @@ -3080,22 +3667,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int ft = ((instruction >> 16) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction, instruction); - else - StoreFPR(destreg,format,Add(ValueFPR(fs,format),ValueFPR(ft,format),format)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt_p (SD_, fmt, instruction_0); + StoreFPR(FD,fmt,Add(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt)); } @@ -3111,7 +3692,7 @@ *mipsII: *mipsIII: { - check_fpu(SD_); + check_fpu (SD_); check_branch_bug (); TRACE_BRANCH_INPUT (PREVCOC1()); if (PREVCOC1() == TF) @@ -3137,11 +3718,13 @@ "bc1%s<TF>%s<ND> <CC>, <OFFSET>" *mipsIV: *mipsV: +*mips32: +*mips64: #*vr4100: *vr5000: *r3900: { - check_fpu(SD_); + check_fpu (SD_); check_branch_bug (); if (GETFCC(CC) == TF) { @@ -3166,38 +3749,33 @@ :function:::void:do_c_cond_fmt:int fmt, int ft, int fs, int cc, int cond, instruction_word insn { - if ((fmt != fmt_single) && (fmt != fmt_double)) - SignalException (ReservedInstruction, insn); - else + int less; + int equal; + int unordered; + int condition; + unsigned64 ofs = ValueFPR (fs, fmt); + unsigned64 oft = ValueFPR (ft, fmt); + if (NaN (ofs, fmt) || NaN (oft, fmt)) { - int less; - int equal; - int unordered; - int condition; - unsigned64 ofs = ValueFPR (fs, fmt); - unsigned64 oft = ValueFPR (ft, fmt); - if (NaN (ofs, fmt) || NaN (oft, fmt)) + if (FCSR & FP_ENABLE (IO)) { - if (FCSR & FP_ENABLE (IO)) - { - FCSR |= FP_CAUSE (IO); - SignalExceptionFPE (); - } - less = 0; - equal = 0; - unordered = 1; + FCSR |= FP_CAUSE (IO); + SignalExceptionFPE (); } - else - { - less = Less (ofs, oft, fmt); - equal = Equal (ofs, oft, fmt); - unordered = 0; - } - condition = (((cond & (1 << 2)) && less) - || ((cond & (1 << 1)) && equal) - || ((cond & (1 << 0)) && unordered)); - SETFCC (cc, condition); + less = 0; + equal = 0; + unordered = 1; + } + else + { + less = Less (ofs, oft, fmt); + equal = Equal (ofs, oft, fmt); + unordered = 0; } + condition = (((cond & (1 << 2)) && less) + || ((cond & (1 << 1)) && equal) + || ((cond & (1 << 0)) && unordered)); + SETFCC (cc, condition); } 010001,10,3.FMT,5.FT,5.FS,3.0,00,11,4.COND:COP1:32,f::C.cond.fmta @@ -3206,8 +3784,10 @@ *mipsII: *mipsIII: { - check_fpu(SD_); - do_c_cond_fmt (SD_, FMT, FT, FS, 0, COND, instruction_0); + int fmt = FMT; + check_fpu (SD_); + check_fmt_p (SD_, fmt, instruction_0); + do_c_cond_fmt (SD_, fmt, FT, FS, 0, COND, instruction_0); } 010001,10,3.FMT,5.FT,5.FS,3.CC,00,11,4.COND:COP1:32,f::C.cond.fmtb @@ -3215,12 +3795,16 @@ "c.%s<COND>.%s<FMT> <CC>, f<FS>, f<FT>" *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - check_fpu(SD_); - do_c_cond_fmt (SD_, FMT, FT, FS, CC, COND, instruction_0); + int fmt = FMT; + check_fpu (SD_); + check_fmt_p (SD_, fmt, instruction_0); + do_c_cond_fmt (SD_, fmt, FT, FS, CC, COND, instruction_0); } @@ -3229,21 +3813,15 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,fmt_long,Convert(FP_RM_TOPINF,ValueFPR(fs,format),format,fmt_long)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt (SD_, fmt, instruction_0); + StoreFPR(FD,fmt_long,Convert(FP_RM_TOPINF,ValueFPR(FS,fmt),fmt,fmt_long)); } @@ -3252,21 +3830,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,fmt_word,Convert(FP_RM_TOPINF,ValueFPR(fs,format),format,fmt_word)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt (SD_, fmt, instruction_0); + StoreFPR(FD,fmt_word,Convert(FP_RM_TOPINF,ValueFPR(FS,fmt),fmt,fmt_word)); } @@ -3278,7 +3851,7 @@ *mipsII: *mipsIII: { - check_fpu(SD_); + check_fpu (SD_); if (X) { if (FS == 0) @@ -3291,9 +3864,9 @@ else { /* control from */ if (FS == 0) - PENDING_FILL(RT,SIGNEXTEND(FCR0,32)); + PENDING_FILL(RT, EXTEND32 (FCR0)); else if (FS == 31) - PENDING_FILL(RT,SIGNEXTEND(FCR31,32)); + PENDING_FILL(RT, EXTEND32 (FCR31)); /* else NOP */ } } @@ -3301,11 +3874,13 @@ "c%s<X>c1 r<RT>, f<FS>" *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - check_fpu(SD_); + check_fpu (SD_); if (X) { /* control to */ @@ -3332,12 +3907,12 @@ if (FS == 0) { TRACE_ALU_INPUT1 (FCR0); - GPR[RT] = SIGNEXTEND (FCR0, 32); + GPR[RT] = EXTEND32 (FCR0); } else if (FS == 31) { TRACE_ALU_INPUT1 (FCR31); - GPR[RT] = SIGNEXTEND (FCR31, 32); + GPR[RT] = EXTEND32 (FCR31); } TRACE_ALU_RESULT (GPR[RT]); /* else NOP */ @@ -3355,20 +3930,19 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); + int fmt = FMT; + check_fpu (SD_); { - if ((format == fmt_double) | 0) - SignalException(ReservedInstruction,instruction); + if ((fmt == fmt_double) | 0) + SignalException (ReservedInstruction, instruction_0); else - StoreFPR(destreg,fmt_double,Convert(GETRM(),ValueFPR(fs,format),format,fmt_double)); + StoreFPR(FD,fmt_double,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_double)); } } @@ -3378,20 +3952,18 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); + int fmt = FMT; + check_fpu (SD_); { - if ((format == fmt_long) | ((format == fmt_long) || (format == fmt_word))) - SignalException(ReservedInstruction,instruction); + if ((fmt == fmt_long) | ((fmt == fmt_long) || (fmt == fmt_word))) + SignalException (ReservedInstruction, instruction_0); else - StoreFPR(destreg,fmt_long,Convert(GETRM(),ValueFPR(fs,format),format,fmt_long)); + StoreFPR(FD,fmt_long,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_long)); } } @@ -3406,20 +3978,19 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); + int fmt = FMT; + check_fpu (SD_); { - if ((format == fmt_single) | 0) - SignalException(ReservedInstruction,instruction); + if ((fmt == fmt_single) | 0) + SignalException (ReservedInstruction, instruction_0); else - StoreFPR(destreg,fmt_single,Convert(GETRM(),ValueFPR(fs,format),format,fmt_single)); + StoreFPR(FD,fmt_single,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_single)); } } @@ -3431,20 +4002,19 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); + int fmt = FMT; + check_fpu (SD_); { - if ((format == fmt_word) | ((format == fmt_long) || (format == fmt_word))) - SignalException(ReservedInstruction,instruction); + if ((fmt == fmt_word) | ((fmt == fmt_long) || (fmt == fmt_word))) + SignalException (ReservedInstruction, instruction_0); else - StoreFPR(destreg,fmt_word,Convert(GETRM(),ValueFPR(fs,format),format,fmt_word)); + StoreFPR(FD,fmt_word,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_word)); } } @@ -3456,22 +4026,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int ft = ((instruction >> 16) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,format,Divide(ValueFPR(fs,format),ValueFPR(ft,format),format)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt (SD_, fmt, instruction_0); + StoreFPR(FD,fmt,Divide(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt)); } @@ -3481,7 +4045,7 @@ "dm%s<X>c1 r<RT>, f<FS>" *mipsIII: { - check_fpu(SD_); + check_fpu (SD_); check_u64 (SD_, instruction_0); if (X) { @@ -3502,7 +4066,7 @@ else { if (STATE_VERBOSE_P(SD)) - sim_io_eprintf (SD, + sim_io_eprintf (SD, "Warning: PC 0x%lx: semantic_DMxC1_COP1Sa 32-bit use of odd FPR number\n", (long) CIA); PENDING_FILL(RT,SET64HI(0xDEADC0DE) | 0xBAD0BAD0); @@ -3513,11 +4077,12 @@ "dm%s<X>c1 r<RT>, f<FS>" *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: *r3900: { - check_fpu(SD_); + check_fpu (SD_); check_u64 (SD_, instruction_0); if (X) { @@ -3535,7 +4100,7 @@ else { if (STATE_VERBOSE_P(SD)) - sim_io_eprintf (SD, + sim_io_eprintf (SD, "Warning: PC 0x%lx: DMxC1 32-bit use of odd FPR number\n", (long) CIA); GPR[RT] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0; @@ -3549,21 +4114,15 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,fmt_long,Convert(FP_RM_TOMINF,ValueFPR(fs,format),format,fmt_long)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt (SD_, fmt, instruction_0); + StoreFPR(FD,fmt_long,Convert(FP_RM_TOMINF,ValueFPR(FS,fmt),fmt,fmt_long)); } @@ -3573,21 +4132,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,fmt_word,Convert(FP_RM_TOMINF,ValueFPR(fs,format),format,fmt_word)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt (SD_, fmt, instruction_0); + StoreFPR(FD,fmt_word,Convert(FP_RM_TOMINF,ValueFPR(FS,fmt),fmt,fmt_word)); } @@ -3597,11 +4151,13 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - check_fpu(SD_); + check_fpu (SD_); COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET))); } @@ -3610,27 +4166,30 @@ "ldxc1 f<FD>, r<INDEX>(r<BASE>)" *mipsIV: *mipsV: +*mips64: *vr5000: { - check_fpu(SD_); + check_fpu (SD_); check_u64 (SD_, instruction_0); COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX])); } -110001,5.BASE,5.FT,16.OFFSET:COP1:32,f::LWC1 +110001,5.BASE,5.FT,16.OFFSET:COP1:32,f::LWC1 "lwc1 f<FT>, <OFFSET>(r<BASE>)" *mipsI: *mipsII: *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - check_fpu(SD_); + check_fpu (SD_); COP_LW (1, FT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET))); } @@ -3639,9 +4198,10 @@ "lwxc1 f<FD>, r<INDEX>(r<BASE>)" *mipsIV: *mipsV: +*mips64: *vr5000: { - check_fpu(SD_); + check_fpu (SD_); check_u64 (SD_, instruction_0); COP_LW (1, FD, do_load (SD_, AccessLength_WORD, GPR[BASE], GPR[INDEX])); } @@ -3655,16 +4215,12 @@ "madd.d f<FD>, f<FR>, f<FS>, f<FT>" *mipsIV: *mipsV: +*mips64: *vr5000: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int ft = ((instruction >> 16) & 0x0000001F); - int fr = ((instruction >> 21) & 0x0000001F); - check_fpu(SD_); + check_fpu (SD_); { - StoreFPR(destreg,fmt_double,Add(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double)); + StoreFPR(FD,fmt_double,Add(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double)); } } @@ -3673,16 +4229,12 @@ "madd.s f<FD>, f<FR>, f<FS>, f<FT>" *mipsIV: *mipsV: +*mips64: *vr5000: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int ft = ((instruction >> 16) & 0x0000001F); - int fr = ((instruction >> 21) & 0x0000001F); - check_fpu(SD_); + check_fpu (SD_); { - StoreFPR(destreg,fmt_single,Add(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single)); + StoreFPR(FD,fmt_single,Add(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single)); } } @@ -3695,13 +4247,13 @@ *mipsII: *mipsIII: { - check_fpu(SD_); + check_fpu (SD_); if (X) { /*MTC1*/ if (SizeFGR() == 64) { if (STATE_VERBOSE_P(SD)) - sim_io_eprintf (SD, + sim_io_eprintf (SD, "Warning: PC 0x%lx: MTC1 not DMTC1 with 64 bit regs\n", (long) CIA); PENDING_FILL ((FS + FGRIDX), (SET64HI(0xDEADC0DE) | VL4_8(GPR[RT]))); @@ -3710,23 +4262,25 @@ PENDING_FILL ((FS + FGRIDX), VL4_8(GPR[RT])); } else /*MFC1*/ - PENDING_FILL (RT, SIGNEXTEND(FGR[FS],32)); + PENDING_FILL (RT, EXTEND32 (FGR[FS])); } 010001,00,X,00,5.RT,5.FS,00000000000:COP1Sb:32,f::MxC1 "m%s<X>c1 r<RT>, f<FS>" *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { int fs = FS; - check_fpu(SD_); + check_fpu (SD_); if (X) /*MTC1*/ StoreFPR (FS, fmt_uninterpreted_32, VL4_8 (GPR[RT])); else /*MFC1*/ - GPR[RT] = SIGNEXTEND(FGR[FS],32); + GPR[RT] = EXTEND32 (FGR[FS]); } @@ -3737,18 +4291,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - StoreFPR(destreg,format,ValueFPR(fs,format)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt_p (SD_, fmt, instruction_0); + StoreFPR(FD,fmt,ValueFPR(FS,fmt)); } @@ -3758,9 +4310,11 @@ "mov%s<TF> r<RD>, r<RS>, <CC>" *mipsIV: *mipsV: +*mips32: +*mips64: *vr5000: { - check_fpu(SD_); + check_fpu (SD_); if (GETFCC(CC) == TF) GPR[RD] = GPR[RS]; } @@ -3772,16 +4326,17 @@ "mov%s<TF>.%s<FMT> f<FD>, f<FS>, <CC>" *mipsIV: *mipsV: +*mips32: +*mips64: *vr5000: { - unsigned32 instruction = instruction_0; - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); + int fmt = FMT; + check_fpu (SD_); { if (GETFCC(CC) == TF) - StoreFPR (FD, format, ValueFPR (FS, format)); + StoreFPR (FD, fmt, ValueFPR (FS, fmt)); else - StoreFPR (FD, format, ValueFPR (FD, format)); + StoreFPR (FD, fmt, ValueFPR (FD, fmt)); } } @@ -3790,9 +4345,11 @@ "movn.%s<FMT> f<FD>, f<FS>, r<RT>" *mipsIV: *mipsV: +*mips32: +*mips64: *vr5000: { - check_fpu(SD_); + check_fpu (SD_); if (GPR[RT] != 0) StoreFPR (FD, FMT, ValueFPR (FS, FMT)); else @@ -3811,9 +4368,11 @@ "movz.%s<FMT> f<FD>, f<FS>, r<RT>" *mipsIV: *mipsV: +*mips32: +*mips64: *vr5000: { - check_fpu(SD_); + check_fpu (SD_); if (GPR[RT] == 0) StoreFPR (FD, FMT, ValueFPR (FS, FMT)); else @@ -3826,17 +4385,11 @@ "msub.d f<FD>, f<FR>, f<FS>, f<FT>" *mipsIV: *mipsV: +*mips64: *vr5000: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int ft = ((instruction >> 16) & 0x0000001F); - int fr = ((instruction >> 21) & 0x0000001F); - check_fpu(SD_); - { - StoreFPR(destreg,fmt_double,Sub(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double)); - } + check_fpu (SD_); + StoreFPR(FD,fmt_double,Sub(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double)); } @@ -3845,17 +4398,11 @@ "msub.s f<FD>, f<FR>, f<FS>, f<FT>" *mipsIV: *mipsV: +*mips64: *vr5000: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int ft = ((instruction >> 16) & 0x0000001F); - int fr = ((instruction >> 21) & 0x0000001F); - check_fpu(SD_); - { - StoreFPR(destreg,fmt_single,Sub(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single)); - } + check_fpu (SD_); + StoreFPR(FD,fmt_single,Sub(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single)); } @@ -3869,22 +4416,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int ft = ((instruction >> 16) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,format,Multiply(ValueFPR(fs,format),ValueFPR(ft,format),format)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt_p (SD_, fmt, instruction_0); + StoreFPR(FD,fmt,Multiply(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt)); } @@ -3895,21 +4436,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,format,Negate(ValueFPR(fs,format),format)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt_p (SD_, fmt, instruction_0); + StoreFPR(FD,fmt,Negate(ValueFPR(FS,fmt),fmt)); } @@ -3918,17 +4454,11 @@ "nmadd.d f<FD>, f<FR>, f<FS>, f<FT>" *mipsIV: *mipsV: +*mips64: *vr5000: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int ft = ((instruction >> 16) & 0x0000001F); - int fr = ((instruction >> 21) & 0x0000001F); - check_fpu(SD_); - { - StoreFPR(destreg,fmt_double,Negate(Add(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double),fmt_double)); - } + check_fpu (SD_); + StoreFPR(FD,fmt_double,Negate(Add(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double),fmt_double)); } @@ -3937,17 +4467,11 @@ "nmadd.s f<FD>, f<FR>, f<FS>, f<FT>" *mipsIV: *mipsV: +*mips64: *vr5000: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int ft = ((instruction >> 16) & 0x0000001F); - int fr = ((instruction >> 21) & 0x0000001F); - check_fpu(SD_); - { - StoreFPR(destreg,fmt_single,Negate(Add(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single),fmt_single)); - } + check_fpu (SD_); + StoreFPR(FD,fmt_single,Negate(Add(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single),fmt_single)); } @@ -3956,17 +4480,11 @@ "nmsub.d f<FD>, f<FR>, f<FS>, f<FT>" *mipsIV: *mipsV: +*mips64: *vr5000: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int ft = ((instruction >> 16) & 0x0000001F); - int fr = ((instruction >> 21) & 0x0000001F); - check_fpu(SD_); - { - StoreFPR(destreg,fmt_double,Negate(Sub(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double),fmt_double)); - } + check_fpu (SD_); + StoreFPR(FD,fmt_double,Negate(Sub(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double),fmt_double)); } @@ -3975,17 +4493,11 @@ "nmsub.s f<FD>, f<FR>, f<FS>, f<FT>" *mipsIV: *mipsV: +*mips64: *vr5000: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int ft = ((instruction >> 16) & 0x0000001F); - int fr = ((instruction >> 21) & 0x0000001F); - check_fpu(SD_); - { - StoreFPR(destreg,fmt_single,Negate(Sub(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single),fmt_single)); - } + check_fpu (SD_); + StoreFPR(FD,fmt_single,Negate(Sub(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single),fmt_single)); } @@ -3993,18 +4505,17 @@ "prefx <HINT>, r<INDEX>(r<BASE>)" *mipsIV: *mipsV: +*mips64: *vr5000: { - unsigned32 instruction = instruction_0; - int fs = ((instruction >> 11) & 0x0000001F); - signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)]; - signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)]; + address_word base = GPR[BASE]; + address_word index = GPR[INDEX]; { - address_word vaddr = ((unsigned64)op1 + (unsigned64)op2); + 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,fs); + Prefetch(uncached,paddr,vaddr,isDATA,HINT); } } @@ -4012,19 +4523,13 @@ "recip.%s<FMT> f<FD>, f<FS>" *mipsIV: *mipsV: +*mips64: *vr5000: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,format,Recip(ValueFPR(fs,format),format)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt (SD_, fmt, instruction_0); + StoreFPR(FD,fmt,Recip(ValueFPR(FS,fmt),fmt)); } @@ -4033,21 +4538,15 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,fmt_long,Convert(FP_RM_NEAREST,ValueFPR(fs,format),format,fmt_long)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt (SD_, fmt, instruction_0); + StoreFPR(FD,fmt_long,Convert(FP_RM_NEAREST,ValueFPR(FS,fmt),fmt,fmt_long)); } @@ -4057,41 +4556,30 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,fmt_word,Convert(FP_RM_NEAREST,ValueFPR(fs,format),format,fmt_word)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt (SD_, fmt, instruction_0); + StoreFPR(FD,fmt_word,Convert(FP_RM_NEAREST,ValueFPR(FS,fmt),fmt,fmt_word)); } 010001,10,3.FMT,00000,5.FS,5.FD,010110:COP1:32,f::RSQRT.fmt *mipsIV: *mipsV: +*mips64: "rsqrt.%s<FMT> f<FD>, f<FS>" *vr5000: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,format,Recip(SquareRoot(ValueFPR(fs,format),format),format)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt (SD_, fmt, instruction_0); + StoreFPR(FD,fmt,Recip(SquareRoot(ValueFPR(FS,fmt),fmt),fmt)); } @@ -4101,11 +4589,13 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - check_fpu(SD_); + check_fpu (SD_); do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT)); } @@ -4114,9 +4604,10 @@ "sdxc1 f<FS>, r<INDEX>(r<BASE>)" *mipsIV: *mipsV: +*mips64: *vr5000: { - check_fpu(SD_); + check_fpu (SD_); check_u64 (SD_, instruction_0); do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX], COP_SD (1, FS)); } @@ -4128,21 +4619,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,format,(SquareRoot(ValueFPR(fs,format),format))); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt (SD_, fmt, instruction_0); + StoreFPR(FD,fmt,(SquareRoot(ValueFPR(FS,fmt),fmt))); } @@ -4153,22 +4639,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int ft = ((instruction >> 16) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,format,Sub(ValueFPR(fs,format),ValueFPR(ft,format),format)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt_p (SD_, fmt, instruction_0); + StoreFPR(FD,fmt,Sub(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt)); } @@ -4180,17 +4660,17 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - signed_word offset = EXTEND16 (OFFSET); - int destreg UNUSED = ((instruction >> 16) & 0x0000001F); - signed_word op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; - check_fpu(SD_); + address_word base = GPR[BASE]; + address_word offset = EXTEND16 (OFFSET); + check_fpu (SD_); { - address_word vaddr = ((uword64)op1 + offset); + address_word vaddr = loadstore_ea (SD_, base, offset); address_word paddr; int uncached; if ((vaddr & 3) != 0) @@ -4209,7 +4689,7 @@ unsigned int byte; paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian)); byte = ((vaddr & mask) ^ bigendiancpu); - memval = (((uword64)COP_SW(((instruction >> 26) & 0x3),destreg)) << (8 * byte)); + memval = (((uword64)COP_SW(((instruction_0 >> 26) & 0x3),FT)) << (8 * byte)); StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL); } } @@ -4221,16 +4701,16 @@ "swxc1 f<FS>, r<INDEX>(r<BASE>)" *mipsIV: *mipsV: +*mips64: *vr5000: { - unsigned32 instruction = instruction_0; - int fs = ((instruction >> 11) & 0x0000001F); - signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)]; - signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)]; - check_fpu(SD_); + + address_word base = GPR[BASE]; + address_word index = GPR[INDEX]; + check_fpu (SD_); check_u64 (SD_, instruction_0); { - address_word vaddr = ((unsigned64)op1 + op2); + address_word vaddr = loadstore_ea (SD_, base, index); address_word paddr; int uncached; if ((vaddr & 3) != 0) @@ -4247,7 +4727,7 @@ unsigned int byte; paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2))); byte = ((vaddr & mask) ^ (BigEndianCPU << 2)); - memval = (((unsigned64)COP_SW(1,fs)) << (8 * byte)); + memval = (((unsigned64)COP_SW(1,FS)) << (8 * byte)); { StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL); } @@ -4262,21 +4742,15 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,fmt_long,Convert(FP_RM_TOZERO,ValueFPR(fs,format),format,fmt_long)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt (SD_, fmt, instruction_0); + StoreFPR(FD,fmt_long,Convert(FP_RM_TOZERO,ValueFPR(FS,fmt),fmt,fmt_long)); } @@ -4286,21 +4760,16 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - int destreg = ((instruction >> 6) & 0x0000001F); - int fs = ((instruction >> 11) & 0x0000001F); - int format = ((instruction >> 21) & 0x00000007); - check_fpu(SD_); - { - if ((format != fmt_single) && (format != fmt_double)) - SignalException(ReservedInstruction,instruction); - else - StoreFPR(destreg,fmt_word,Convert(FP_RM_TOZERO,ValueFPR(fs,format),format,fmt_word)); - } + int fmt = FMT; + check_fpu (SD_); + check_fmt (SD_, fmt, instruction_0); + StoreFPR(FD,fmt_word,Convert(FP_RM_TOZERO,ValueFPR(FS,fmt),fmt,fmt_word)); } @@ -4318,6 +4787,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: @@ -4337,6 +4808,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: @@ -4348,6 +4821,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: @@ -4358,6 +4833,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: @@ -4367,20 +4844,20 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: { - unsigned32 instruction = instruction_0; - signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16); - int hint = ((instruction >> 16) & 0x0000001F); - signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)]; + address_word base = GPR[BASE]; + address_word offset = EXTEND16 (OFFSET); { - address_word vaddr = (op1 + offset); + address_word vaddr = loadstore_ea (SD_, base, offset); address_word paddr; int uncached; if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) - CacheOp(hint,vaddr,paddr,instruction); + CacheOp(OP,vaddr,paddr,instruction_0); } } @@ -4401,6 +4878,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: { check_u64 (SD_, instruction_0); DecodeCoproc (instruction_0); @@ -4412,6 +4890,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: { check_u64 (SD_, instruction_0); DecodeCoproc (instruction_0); @@ -4425,6 +4904,7 @@ *mipsIII: *mipsIV: *mipsV: +*mips64: *vr4100: *vr5000: @@ -4434,6 +4914,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: { @@ -4459,6 +4941,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -4475,6 +4959,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: *r3900: @@ -4505,6 +4991,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *r3900: { @@ -4520,6 +5008,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: @@ -4531,6 +5021,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: @@ -4542,6 +5034,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: @@ -4553,6 +5047,8 @@ *mipsIII: *mipsIV: *mipsV: +*mips32: +*mips64: *vr4100: *vr5000: |