:%s::::MFHI:int hi
{
return hi ? "hi" : "";
}
:%s::::SAT:int s
{
return s ? "s" : "";
}
:%s::::UNS:int u
{
return u ? "u" : "";
}
:function:::void:do_vr_mul_op:int rd, int rs, int rt, int accumulate_p, int store_hi_p, int unsigned_p, int saturate_p, int subtract_p, int short_p, int double_p
{
unsigned64 lhs, x, y, xcut, ycut, product, result;
check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
lhs = (!accumulate_p ? 0 : double_p ? LO : U8_4 (HI, LO));
x = GPR[rs];
y = GPR[rt];
if (!short_p)
{
xcut = EXTEND32 (x);
ycut = EXTEND32 (y);
}
else if (unsigned_p)
{
xcut = x & 0xffff;
ycut = y & 0xffff;
}
else
{
xcut = EXTEND16 (x);
ycut = EXTEND16 (y);
}
if (x != xcut || y != ycut)
sim_engine_abort (SD, CPU, CIA,
"invalid multiplication operand at 0x%08lx\n",
(long) CIA);
TRACE_ALU_INPUT2 (x, y);
product = (unsigned_p ? x * y : EXTEND32 (x) * EXTEND32 (y));
result = (subtract_p ? lhs - product : lhs + product);
if (saturate_p)
{
if (!unsigned_p && (unsigned64) EXTEND32 (result) != result)
result = ((signed64) result < 0 ? -0x7fffffff - 1 : 0x7fffffff);
else if (unsigned_p && (result >> 32) != 0)
result = (unsigned64) 0 - 1;
}
TRACE_ALU_RESULT (result);
if (double_p)
LO = result;
else
{
LO = EXTEND32 (result);
HI = EXTEND32 (VH4_8 (result));
}
if (rd != 0)
GPR[rd] = store_hi_p ? HI : LO;
}
:function:::unsigned64:do_ror:unsigned32 x,unsigned32 y
*vr5400:
*vr5500:
{
unsigned64 result;
y &= 31;
TRACE_ALU_INPUT2 (x, y);
result = EXTEND32 (ROTR32 (x, y));
TRACE_ALU_RESULT (result);
return result;
}
:function:::unsigned64:do_dror:unsigned64 x,unsigned64 y
*vr5400:
*vr5500:
{
unsigned64 result;
y &= 63;
TRACE_ALU_INPUT2 (x, y);
result = ROTR64 (x, y);
TRACE_ALU_RESULT (result);
return result;
}
000000,5.RS,5.RT,00000,00000,101000::32::MADD16
"madd16 r<RS>, r<RT>"
*vr4100:
{
do_vr_mul_op (SD_, 0, RS, RT,
1 ,
0 ,
0 ,
0 ,
0 ,
1 ,
0 );
}
000000,5.RS,5.RT,00000,00000,101001::64::DMADD16
"dmadd16 r<RS>, r<RT>"
*vr4100:
{
do_vr_mul_op (SD_, 0, RS, RT,
1 ,
0 ,
0 ,
0 ,
0 ,
1 ,
1 );
}
000000,5.RS,5.RT,5.RD,1.SAT,1.MFHI,00,1.UNS,101001::64::DMACC
"dmacc%s<MFHI>%s<UNS>%s<SAT> r<RD>, r<RS>, r<RT>"
*vr4120:
{
do_vr_mul_op (SD_, RD, RS, RT,
1 ,
MFHI, UNS, SAT,
0 ,
SAT ,
1 );
}
000000,5.RS,5.RT,5.RD,1.SAT,1.MFHI,00,1.UNS,101000::32::MACC_4120
"macc%s<MFHI>%s<UNS>%s<SAT> r<RD>, r<RS>, r<RT>"
*vr4120:
{
do_vr_mul_op (SD_, RD, RS, RT,
1 ,
MFHI, UNS, SAT,
0 ,
SAT ,
0 );
}
000000,5.RS,5.RT,5.RD,0,1.MFHI,001,01100,1.UNS::32::MUL
"mul%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
*vr5400:
*vr5500:
{
do_vr_mul_op (SD_, RD, RS, RT,
0 ,
MFHI, UNS,
0 ,
0 ,
0 ,
0 );
}
000000,5.RS,5.RT,5.RD,0,1.MFHI,011,01100,1.UNS::32::MULS
"muls%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
*vr5400:
*vr5500:
{
do_vr_mul_op (SD_, RD, RS, RT,
0 ,
MFHI, UNS,
0 ,
1 ,
0 ,
0 );
}
000000,5.RS,5.RT,5.RD,0,1.MFHI,101,01100,1.UNS::32::MACC_5xxx
"macc%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
*vr5400:
*vr5500:
{
do_vr_mul_op (SD_, RD, RS, RT,
1 ,
MFHI, UNS,
0 ,
0 ,
0 ,
0 );
}
000000,5.RS,5.RT,5.RD,0,1.MFHI,111,01100,1.UNS::32::MSAC
"msac%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
*vr5400:
*vr5500:
{
do_vr_mul_op (SD_, RD, RS, RT,
1 ,
MFHI, UNS,
0 ,
1 ,
0 ,
0 );
}
000000,00001,5.RT,5.RD,5.SHIFT,000010::32::ROR
"ror r<RD>, r<RT>, <SHIFT>"
*vr5400:
*vr5500:
{
GPR[RD] = do_ror (SD_, GPR[RT], SHIFT);
}
000000,5.RS,5.RT,5.RD,00001,000110::32::RORV
"rorv r<RD>, r<RT>, r<RS>"
*vr5400:
*vr5500:
{
GPR[RD] = do_ror (SD_, GPR[RT], GPR[RS]);
}
000000,00001,5.RT,5.RD,5.SHIFT,111010::64::DROR
"dror r<RD>, r<RT>, <SHIFT>"
*vr5400:
*vr5500:
{
GPR[RD] = do_dror (SD_, GPR[RT], SHIFT);
}
000000,00001,5.RT,5.RD,5.SHIFT,111110::64::DROR32
"dror32 r<RD>, r<RT>, <SHIFT>"
*vr5400:
*vr5500:
{
GPR[RD] = do_dror (SD_, GPR[RT], SHIFT + 32);
}
000000,5.RS,5.RT,5.RD,00001,010110::64::DRORV
"drorv r<RD>, r<RT>, r<RS>"
*vr5400:
*vr5500:
{
GPR[RD] = do_dror (SD_, GPR[RT], GPR[RS]);
}
010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:64::LUXC1
"luxc1 f<FD>, r<INDEX>(r<BASE>)"
*vr5500:
{
check_fpu (SD_);
COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD,
(GPR[BASE] + GPR[INDEX]) & ~MASK64 (2, 0), 0));
}
010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:64::SUXC1
"suxc1 f<FS>, r<INDEX>(r<BASE>)"
*vr5500:
{
check_fpu (SD_);
do_store (SD_, AccessLength_DOUBLEWORD,
(GPR[BASE] + GPR[INDEX]) & ~MASK64 (2, 0), 0,
COP_SD (1, FS));
}
010000,1,19.*,100000:COP0:32::WAIT
"wait"
*vr5500:
011100,00000,5.RT,5.DR,00000,111101:SPECIAL:64::MFDR
"mfdr r<RT>, r<DR>"
*vr5400:
*vr5500:
011100,00100,5.RT,5.DR,00000,111101:SPECIAL:64::MTDR
"mtdr r<RT>, r<DR>"
*vr5400:
*vr5500:
011100,00000,00000,00000,00000,111110:SPECIAL:64::DRET
"dret"
*vr5400:
*vr5500: