// (or which pre-date or use different encodings than the standard
// instructions) are (for the most part) in separate .igen files.
:model:::vr4100:mips4100: // vr.igen
+:model:::vr4120:mips4120:
:model:::vr5000:mips5000:
+:model:::vr5400:mips5400:
+:model:::vr5500:mips5500:
:model:::r3900:mips3900: // tx.igen
// MIPS Application Specific Extensions (ASEs)
// Instructions for the ASEs are in separate .igen files.
// ASEs add instructions on to a base ISA.
:model:::mips16:mips16: // m16.igen (and m16.dc)
+:model:::mips3d:mips3d: // mips3d.igen
:model:::mdmx:mdmx: // mdmx.igen
// Vendor Extensions
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
}
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
else
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
if ((signed_word) GPR[RS] >= 0)
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
}
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
if (RS == 31)
Unpredictable ();
RA = (CIA + 8);
if ((signed_word) GPR[RS] >= 0)
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
}
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
if (RS == 31)
Unpredictable ();
RA = (CIA + 8);
executed */
if ((signed_word) GPR[RS] >= 0)
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
else
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
if ((signed_word) GPR[RS] >= 0)
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
else
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
if ((signed_word) GPR[RS] > 0)
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
}
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
/* NOTE: The branch occurs AFTER the next instruction has been
executed */
if ((signed_word) GPR[RS] > 0)
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
else
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
/* NOTE: The branch occurs AFTER the next instruction has been
executed */
if ((signed_word) GPR[RS] <= 0)
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
}
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
if ((signed_word) GPR[RS] <= 0)
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
else
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
if ((signed_word) GPR[RS] < 0)
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
}
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
if (RS == 31)
Unpredictable ();
RA = (CIA + 8);
executed */
if ((signed_word) GPR[RS] < 0)
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
}
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
if (RS == 31)
Unpredictable ();
RA = (CIA + 8);
if ((signed_word) GPR[RS] < 0)
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
else
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
/* NOTE: The branch occurs AFTER the next instruction has been
executed */
if ((signed_word) GPR[RS] < 0)
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
else
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
}
*r3900:
{
address_word offset = EXTEND16 (OFFSET) << 2;
- check_branch_bug ();
if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
{
- mark_branch_bug (NIA+offset);
DELAY_SLOT (NIA + offset);
}
else
"clo r<RD>, r<RS>"
*mips32:
*mips64:
+*vr5500:
{
unsigned32 temp = GPR[RS];
unsigned32 i, mask;
"clz r<RD>, r<RS>"
*mips32:
*mips64:
+*vr5500:
{
unsigned32 temp = GPR[RS];
unsigned32 i, mask;
011100,5.RS,5.RT,5.RD,00000,100101:SPECIAL2:64::DCLO
"dclo r<RD>, r<RS>"
*mips64:
+*vr5500:
{
unsigned64 temp = GPR[RS];
unsigned32 i;
011100,5.RS,5.RT,5.RD,00000,100100:SPECIAL2:64::DCLZ
"dclz r<RD>, r<RS>"
*mips64:
+*vr5500:
{
unsigned64 temp = GPR[RS];
unsigned32 i;
"madd r<RS>, r<RT>"
*mips32:
*mips64:
+*vr5500:
{
signed64 temp;
check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
"maddu r<RS>, r<RT>"
*mips32:
*mips64:
+*vr5500:
{
unsigned64 temp;
check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
"msub r<RS>, r<RT>"
*mips32:
*mips64:
+*vr5500:
{
signed64 temp;
check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
"msubu r<RS>, r<RT>"
*mips32:
*mips64:
+*vr5500:
{
unsigned64 temp;
check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
"mul r<RD>, r<RS>, r<RT>"
*mips32:
*mips64:
+*vr5500:
{
signed64 prod;
if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
}
+// Helper:
+//
+// Load a double word FP value using 2 32-bit memory cycles a la MIPS II
+// or MIPS32. do_load cannot be used instead because it returns an
+// unsigned_word, which is limited to the size of the machine's registers.
+//
+
+:function:::unsigned64:do_load_double:address_word base, address_word offset
+*mipsII:
+*mips32:
+{
+ int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
+ address_word vaddr;
+ address_word paddr;
+ int uncached;
+ unsigned64 memval;
+ unsigned64 v;
+
+ vaddr = loadstore_ea (SD_, base, offset);
+ if ((vaddr & AccessLength_DOUBLEWORD) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map,
+ AccessLength_DOUBLEWORD + 1, vaddr, read_transfer,
+ sim_core_unaligned_signal);
+ }
+ AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET,
+ isREAL);
+ LoadMemory (&memval, NULL, uncached, AccessLength_WORD, paddr, vaddr,
+ isDATA, isREAL);
+ v = (unsigned64)memval;
+ LoadMemory (&memval, NULL, uncached, AccessLength_WORD, paddr + 4, vaddr + 4,
+ isDATA, isREAL);
+ return (bigendian ? ((v << 32) | memval) : (v | (memval << 32)));
+}
+
+
+// Helper:
+//
+// Store a double word FP value using 2 32-bit memory cycles a la MIPS II
+// or MIPS32. do_load cannot be used instead because it returns an
+// unsigned_word, which is limited to the size of the machine's registers.
+//
+
+:function:::void:do_store_double:address_word base, address_word offset, unsigned64 v
+*mipsII:
+*mips32:
+{
+ int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
+ address_word vaddr;
+ address_word paddr;
+ int uncached;
+ unsigned64 memval;
+
+ vaddr = loadstore_ea (SD_, base, offset);
+ if ((vaddr & AccessLength_DOUBLEWORD) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map,
+ AccessLength_DOUBLEWORD + 1, vaddr, write_transfer,
+ sim_core_unaligned_signal);
+ }
+ AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET,
+ isREAL);
+ memval = (bigendian ? (v >> 32) : (v & 0xFFFFFFFF));
+ StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
+ isREAL);
+ memval = (bigendian ? (v & 0xFFFFFFFF) : (v >> 32));
+ StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr + 4, vaddr + 4,
+ isREAL);
+}
+
+
010001,10,3.FMT,00000,5.FS,5.FD,000101:COP1:32,f::ABS.fmt
"abs.%s<FMT> f<FD>, f<FS>"
*mipsI:
*mipsIII:
{
check_fpu (SD_);
- check_branch_bug ();
TRACE_BRANCH_INPUT (PREVCOC1());
if (PREVCOC1() == TF)
{
address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
TRACE_BRANCH_RESULT (dest);
- mark_branch_bug (dest);
DELAY_SLOT (dest);
}
else if (ND)
*r3900:
{
check_fpu (SD_);
- check_branch_bug ();
if (GETFCC(CC) == TF)
{
address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
- mark_branch_bug (dest);
DELAY_SLOT (dest);
}
else if (ND)
}
-010001,10,3.FMT,00000,5.FS,5.FD,100100:COP1:32,f::CVT.W.fmt
+010001,10,3.FMT!6,00000,5.FS,5.FD,100100:COP1:32,f::CVT.W.fmt
"cvt.w.%s<FMT> f<FD>, f<FS>"
*mipsI:
*mipsII:
}
-110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1
+110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1a
"ldc1 f<FT>, <OFFSET>(r<BASE>)"
*mipsII:
+*mips32:
+{
+ check_fpu (SD_);
+ COP_LD (1, FT, do_load_double (SD_, GPR[BASE], EXTEND16 (OFFSET)));
+}
+
+
+110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1b
+"ldc1 f<FT>, <OFFSET>(r<BASE>)"
*mipsIII:
*mipsIV:
*mipsV:
-*mips32:
*mips64:
*vr4100:
*vr5000:
}
-111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1
+111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1a
"sdc1 f<FT>, <OFFSET>(r<BASE>)"
*mipsII:
+*mips32:
+{
+ check_fpu (SD_);
+ do_store_double (SD_, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT));
+}
+
+
+111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1b
+"sdc1 f<FT>, <OFFSET>(r<BASE>)"
*mipsIII:
*mipsIV:
*mipsV:
-*mips32:
*mips64:
*vr4100:
*vr5000:
\f
:include:::m16.igen
:include:::mdmx.igen
+:include:::mips3d.igen
:include:::sb1.igen
:include:::tx.igen
:include:::vr.igen