mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:51:15 +08:00
06c441ccef
2022-02-01 Ali Lown <ali.lown@imgtec.com> Andrew Bennett <andrew.bennett@imgtec.com> Dragan Mladjenovic <dragan.mladjenovic@rt-rk.com> Faraz Shahbazker <fshahbazker@wavecomp.com> sim/common/ChangeLog: * sim-bits.h (EXTEND9, EXTEND18 ,EXTEND19, EXTEND21, EXTEND26): New macros. sim/mips/ChangeLog: * Makefile.in (IGEN_INCLUDE): Add mips3264r6.igen. * configure: Regenerate. * configure.ac: Support mipsisa32r6 and mipsisa64r6. (sim_engine_run): Pick simulator model from processor specified in e_flags. * cp1.c (value_fpr): Handle fmt_dc32. (fp_unary, fp_binary): Zero initialize locals. (update_fcsr, fp_classify, fp_rint, fp_r6_cmp, inner_fmac, fp_fmac, fp_min, fp_max, fp_mina, fp_maxa, fp_fmadd, fp_fmsub): New functions. (sim_fpu_class_mips_mapping): New. * cp1.h (fcsr_ABS2008_mask, fcsr_ABS2008_shift): New define. * interp.c (MIPSR6_P): New. (load_word): Allow unaligned memory access for MIPSR6. * micromips.igen (sc, scd): Adapt to new do_sc* helper signature. * mips.igen: Add *r6 models. (signal_if_cti, forbiddenslot32): New helpers. (delayslot32): Use signal_if_cti. (do_sc, do_scd); Add store_ll_bit parameter. (sc, scd): Adapt to previous change. (nal, beq, bal): New definitions for *r6. (sll): Split nop and ssnop cases into ... (nop, ssnop): New definitions. (loadstore_ea): Use the 32-bit compatibility adressing. (cache): Split logic into ... (do_cache): New helper. (check_fpu): Select IEEE 754-2008 mode for R6. (not_word_value, unpredictable, check_mt_hilo, check_mf_hilo, check_multi_hilo, check_div_hilo, check_u64, do_dmfc1b, add, li, addu, and, andi, bgez, bgtz, blez, bltz, bne, break, dadd, daddiu, daddu, dror, dror32, drorv, dsll, dsll32, dsllv, dsra, dsra32, dsrav, dsrl, dsrl32, dsub, dsubu, j, jal, jalr, jalr.hb, lb, lbu, ld, lh, lhu, lui, lw, lwu, nor, or, ori, ror, rorv, sb, sd, sh, sll, sllv, slt, slti, sltiu, sltu, sra, srav, srl, srlv, sub, subu, sw, sync, syscall, teq, tge, tgeu, tlt, tltu, tne, xor, xori, check_fmt_p, do_load_double, do_store_double, abs.FMT, add.FMT, ceil.l.FMT, ceil.w.FMT, cfc1, ctc1, cvt.d.FMT, cvt.l.FMT, cvt.w.FMT, div.FMT, dfmc1, dmtc1, floor.l.FMT, floor.w.FMT, ldc1, lwc1, mfc1, mov.FMT, mtc1, mul.FMT, recip.FMT, round.l.FMT, round.w.FMT, rsqrt.FMT, sdc1, sqrt.FMT, sub.FMT, swc1, trunc.l.FMT, trunc.w.FMT, bc0f, bc0fl, bc0t, bc0tl, dmfc0, dmtc0, eret, mfc0, mtc0, cop, tlbp, tlbr, tlbwi, tlbwr): Enable on *r6 models. * mips3264r2.igen (dext, dextm, dextu, di, dins, dinsm, dinsu, dsbh, dshd, ei, ext, mfhc1, mthc1, ins, seb, seh, synci, rdhwr, wsbh): Likewise. * mips3264r6.igen: New file. * sim-main.h (FP_formats): Add fmt_dc32. (FORBIDDEN_SLOT): New macros. (simFORBIDDENSLOT, FP_R6CMP_*, FP_R6CLASS_*): New defines. (fp_r6_cmp, fp_classify, fp_rint, fp_min, fp_max, fp_mina, fp_maxa, fp_fmadd, fp_fmsub): New declarations. (R6Compare, Classify, RoundToIntegralExact, Min, Max, MinA, MaxA, FusedMultiplyAdd, FusedMultiplySub): New macros. Wrapping previous declarations. sim/testsuite/mips/ChangeLog: * basic.exp: Add r6-*.s tests. (run_r6_removed_test): New function. (run_endian_tests): New function. * hilo-hazard-3.s: Skip for mips*r6. * r2-fpu.s: New test. * r6-64.s: New test. * r6-branch.s: New test. * r6-forbidden.s: New test. * r6-fpu.s: New test. * r6-llsc-dp.s: New test. * r6-llsc-wp.s: New test. * r6-removed.csv: New test. * r6-removed.s: New test. * r6.s: New test. * utils-r6.inc: New inc.
1227 lines
26 KiB
Plaintext
1227 lines
26 KiB
Plaintext
110010,26.OFFSET:POOL32X:32::BC
|
|
"bc <OFFSET>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
NIA = CIA + (EXTEND26 (OFFSET) << 2) + 4;
|
|
}
|
|
|
|
111010,26.OFFSET:POOL32X:32::BALC
|
|
"balc <OFFSET>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
RA = CIA + 4;
|
|
NIA = CIA + (EXTEND26 (OFFSET) << 2) + 4;
|
|
}
|
|
|
|
110110,5.RS!0,21.OFFSET:POOL32X:32::BEQZC
|
|
"beqzc r<RS>, <OFFSET>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
if (GPR[RS] == 0)
|
|
NIA = CIA + (EXTEND21 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
|
|
110110,00000,5.RT,16.OFFSET:POOL32X:32::JIC
|
|
"jic r<RT>, <OFFSET>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
NIA = GPR[RT] + (EXTEND16(OFFSET) << 2);
|
|
}
|
|
|
|
111110,5.RS!0,21.OFFSET:POOL32X:32::BNEZC
|
|
"bnezc r<RS>, <OFFSET>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
if (GPR[RS] != 0)
|
|
NIA = CIA + (EXTEND21 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
|
|
111110,00000,5.RT,16.OFFSET:POOL32X:32::JIALC
|
|
"jialc r<RT>, <OFFSET>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
RA = CIA + 4;
|
|
NIA = GPR[RT] + EXTEND16(OFFSET);
|
|
}
|
|
|
|
010110,5.RS,5.RT,16.OFFSET:POOL32X:32::B1xxC
|
|
"blezc r<RT>, <OFFSET>": RS==0&&RT!=0
|
|
"bgezc r<RT>, <OFFSET>":RS!=0&&RS==RT
|
|
"bgec r<RS>, r<RT>, <OFFSET>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
if (RS == 0 && RT != 0)
|
|
{
|
|
//BLEZC
|
|
if ((signed_word)GPR[RT] <= 0)
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
else if (RS != 0 && RS == RT)
|
|
{
|
|
//BGEZC
|
|
if ((signed_word)GPR[RT] >= 0)
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
else
|
|
{
|
|
//BGEC
|
|
if ((signed_word) GPR[RS] >= (signed_word) GPR[RT])
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
}
|
|
|
|
010111,5.RS,5.RT,16.OFFSET:POOL32X:32::B2xxC
|
|
"bgtzc r<RT>, <OFFSET>":RS==0&&RT!=0
|
|
"bltzc r<RT>, <OFFSET>":RS!=0&&RS==RT
|
|
"bltc r<RS>, r<RT>, <OFFSET>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
if (RS == 0 && RT != 0)
|
|
{
|
|
//BGTZC
|
|
if ((signed_word)GPR[RT] > 0)
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
else if (RS != 0 && RS == RT)
|
|
{
|
|
//BLTZC
|
|
if ((signed_word)GPR[RT] < 0)
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
else
|
|
{
|
|
//BLTC
|
|
if ((signed_word) GPR[RS] < (signed_word) GPR[RT])
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
}
|
|
|
|
000110,5.RS,5.RT!0,16.OFFSET:POOL32X:32::B3xxC
|
|
"blezalc r<RT>, <OFFSET>":RS==0
|
|
"bgezalc r<RT>, <OFFSET>":RS!=0&&RS==RT
|
|
"bgeuc r<RS>, r<RT>, <OFFSET>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
if (RS == 0 && RT != 0)
|
|
{
|
|
//BLEZALC
|
|
RA = CIA + 4;
|
|
if ((signed_word)GPR[RT] <= 0)
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
else if (RS != 0 && RS == RT)
|
|
{
|
|
//BGEZALC
|
|
RA = CIA + 4;
|
|
if ((signed_word)GPR[RT] >= 0)
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
else
|
|
{
|
|
//BGEUC
|
|
if (GPR[RS] >= GPR[RT])
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
}
|
|
|
|
000111,5.RS,5.RT!0,16.OFFSET:POOL32X:32::B4xxC
|
|
"bgtzalc r<RT>, <OFFSET>":RS==0
|
|
"bltzalc r<RT>, <OFFSET>":RS!=0&&RS==RT
|
|
"bltuc r<RS>, r<RT>, <OFFSET>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
if (RS == 0 && RT != 0)
|
|
{
|
|
//BGTZALC
|
|
RA = CIA + 4;
|
|
if ((signed_word)GPR[RT] > 0)
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
else if (RS != 0 && RS == RT)
|
|
{
|
|
//BLTZALC
|
|
RA = CIA + 4;
|
|
if ((signed_word)GPR[RT] < 0)
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
else
|
|
{
|
|
//BLTUC
|
|
if (GPR[RS] < GPR[RT])
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
}
|
|
|
|
001000,5.RS,5.RT,16.OFFSET:POOL32X:32::BxxxC
|
|
"bovc r<RS>, r<RT>, <OFFSET>":RS>=RT
|
|
"beqzalc r<RT>, <OFFSET>":RS==0&&RT>RS
|
|
"beqc r<RS>, r<RT>, <OFFSET>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
if (RS >= RT)
|
|
{
|
|
//BOVC
|
|
ALU32_BEGIN (GPR[RS] & 0x0ffffffff);
|
|
ALU32_ADD (GPR[RT] & 0x0ffffffff);
|
|
|
|
if (ALU32_HAD_OVERFLOW)
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
else if (RS == 0)
|
|
{
|
|
RA = CIA + 4;
|
|
//BEQZALC
|
|
if (GPR[RT] == 0)
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
else
|
|
{
|
|
//BEQC
|
|
if (GPR[RS] == GPR[RT])
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
}
|
|
|
|
011000,5.RS,5.RT,16.OFFSET:POOL32X:32::BNxxxC
|
|
"bnvc r<RS>, r<RT>, <OFFSET>":RS>=RT
|
|
"bnezalc r<RT>, <OFFSET>":RS==0&&RT>RS
|
|
"bnec r<RS>, r<RT>, <OFFSET>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
if (RS >= RT)
|
|
{
|
|
//BNVC
|
|
ALU32_BEGIN (GPR[RS] & 0x0ffffffff);
|
|
ALU32_ADD (GPR[RT] & 0x0ffffffff);
|
|
|
|
if (!ALU32_HAD_OVERFLOW)
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
else if (RS == 0 && RT > RS)
|
|
{
|
|
//BNEZALC
|
|
RA = CIA + 4;
|
|
if (GPR[RT] != 0)
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
else
|
|
{
|
|
//BNEC
|
|
if (GPR[RT] != GPR[RS])
|
|
NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
|
|
else
|
|
FORBIDDEN_SLOT ();
|
|
}
|
|
}
|
|
|
|
:%s::::R6COND:int r6cond
|
|
{
|
|
switch (r6cond)
|
|
{
|
|
case FP_R6CMP_SAF:
|
|
return "SAF";
|
|
case FP_R6CMP_SUN:
|
|
return "SUN";
|
|
case FP_R6CMP_SOR:
|
|
return "SOR";
|
|
case FP_R6CMP_SEQ:
|
|
return "SEQ";
|
|
case FP_R6CMP_SUNE:
|
|
return "SUNE";
|
|
case FP_R6CMP_SUEQ:
|
|
return "SUEQ";
|
|
case FP_R6CMP_SNE:
|
|
return "SNE";
|
|
case FP_R6CMP_SLT:
|
|
return "SLT";
|
|
case FP_R6CMP_SULT:
|
|
return "SULT";
|
|
case FP_R6CMP_SLE:
|
|
return "SLE";
|
|
case FP_R6CMP_SULE:
|
|
return "SULE";
|
|
case FP_R6CMP_AF:
|
|
return "AF";
|
|
case FP_R6CMP_UN:
|
|
return "UN";
|
|
case FP_R6CMP_OR:
|
|
return "OR";
|
|
case FP_R6CMP_EQ:
|
|
return "EQ";
|
|
case FP_R6CMP_UNE:
|
|
return "UNE";
|
|
case FP_R6CMP_UEQ:
|
|
return "UEQ";
|
|
case FP_R6CMP_NE:
|
|
return "NE";
|
|
case FP_R6CMP_LT:
|
|
return "LT";
|
|
case FP_R6CMP_ULT:
|
|
return "ULT";
|
|
case FP_R6CMP_LE:
|
|
return "LE";
|
|
case FP_R6CMP_ULE:
|
|
return "ULE";
|
|
default:
|
|
abort ();
|
|
}
|
|
}
|
|
|
|
010001,1010,1.FMT,5.FT,5.FS,5.FD,0,5.R6COND:POOL32X:32,f::CMP.cond.fmt
|
|
"cmp.%s<R6COND>.%s<FMT> f<FD>, f<FS>, f<FT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
uint64_t result;
|
|
check_fpu (SD_);
|
|
TRACE_ALU_INPUT2 (ValueFPR (FS, FMT), ValueFPR (FT, FMT));
|
|
|
|
result = R6Compare (ValueFPR (FS, FMT), ValueFPR (FT, FMT), FMT, R6COND);
|
|
StoreFPR (FD, FMT, result);
|
|
TRACE_ALU_RESULT (result);
|
|
}
|
|
|
|
010001,01001,5.FT,16.OFFSET:POOL32X:32,f::BC1EQZ
|
|
"bc1eqz f<FT>, <OFFSET>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
address_word offset = EXTEND16 (OFFSET) << 2;
|
|
check_fpu (SD_);
|
|
TRACE_ALU_INPUT1 (FGR[FT]);
|
|
if ((FGR[FT] & 0x01) == 0)
|
|
DELAY_SLOT (NIA + offset);
|
|
}
|
|
|
|
010001,01101,5.FT,16.OFFSET:POOL32X:32,f::BC1NEZ
|
|
"bc1nez f<FT>, <OFFSET>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
address_word offset = EXTEND16 (OFFSET) << 2;
|
|
check_fpu (SD_);
|
|
TRACE_ALU_INPUT1 (FGR[FT]);
|
|
if ((FGR[FT] & 0x01) != 0)
|
|
DELAY_SLOT (NIA + offset);
|
|
}
|
|
010001,1000,1.FMT,5.FT,5.FS,5.FD,011000:POOLX:32,f::MADDF.fmt
|
|
"maddf.%s<FMT> f<FD>, f<FS>, f<FT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
int fmt = FMT;
|
|
check_fpu (SD_);
|
|
check_u64 (SD_, instruction_0);
|
|
check_fmt_p (SD_, fmt, instruction_0);
|
|
TRACE_ALU_INPUT3 (FGR[FD], FGR[FS], FGR[FT]);
|
|
StoreFPR (FD, fmt, FusedMultiplyAdd (ValueFPR (FS, fmt),
|
|
ValueFPR (FT, fmt),
|
|
ValueFPR (FD, fmt), fmt));
|
|
TRACE_ALU_RESULT (FGR[FD]);
|
|
}
|
|
|
|
010001,1000,1.FMT,5.FT,5.FS,5.FD,011001:POOLX:32,f::MSUBF.fmt
|
|
"msubf.%s<FMT> f<FD>, f<FS>, f<FT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
int fmt = FMT;
|
|
check_fpu (SD_);
|
|
check_u64 (SD_, instruction_0);
|
|
check_fmt_p (SD_, fmt, instruction_0);
|
|
TRACE_ALU_INPUT3 (FGR[FD], FGR[FS], FGR[FT]);
|
|
StoreFPR (FD, fmt, FusedMultiplySub (ValueFPR (FS, fmt),
|
|
ValueFPR (FT, fmt),
|
|
ValueFPR (FD, fmt), fmt));
|
|
TRACE_ALU_RESULT (FGR[FD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,000,2.IMM,000101:SPECIAL:32::LSA
|
|
"lsa r<RD>, r<RS>, r<RT>, <IMM + 1>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
uint32_t t = GPR[RS] << (IMM + 1);
|
|
GPR[RD] = EXTEND32(GPR[RT] + t);
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,000,2.IMM,010101:SPECIAL:64::DLSA
|
|
"dlsa r<RD>, r<RS>, r<RT>, <IMM + 1>"
|
|
*mips64r6:
|
|
{
|
|
uint64_t t = GPR[RS] << (IMM + 1);
|
|
GPR[RD] = GPR[RT] + t;
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
001111,5.RS!0,5.RT,16.IMMEDIATE:POOL32X:32::AUI
|
|
"aui r<RS>, r<RT>, <IMMEDIATE>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
|
|
GPR[RT] = EXTEND32 (GPR[RS] + (EXTEND16 (IMMEDIATE) << 16));
|
|
TRACE_ALU_RESULT (GPR[RT]);
|
|
}
|
|
|
|
011101,5.RS!0,5.RT,16.IMMEDIATE:POOL32X:64::DAUI
|
|
"daui r<RS>, r<RT>, <IMMEDIATE>"
|
|
*mips64r6:
|
|
{
|
|
TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
|
|
GPR[RT] = GPR[RS] + (EXTEND16 (IMMEDIATE) << 16);
|
|
TRACE_ALU_RESULT (GPR[RT]);
|
|
}
|
|
|
|
000001,5.RS,00110,16.IMMEDIATE:POOL32X:64::DAHI
|
|
"dahi r<RS>, <IMMEDIATE>"
|
|
*mips64r6:
|
|
{
|
|
TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
|
|
GPR[RS] = GPR[RS] + (EXTEND16 (IMMEDIATE) << 32);
|
|
TRACE_ALU_RESULT (GPR[RS]);
|
|
}
|
|
|
|
000001,5.RS,11110,16.IMMEDIATE:POOL32X:64::DATI
|
|
"dati r<RS>, <IMMEDIATE>"
|
|
*mips64r6:
|
|
{
|
|
TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
|
|
GPR[RS] = GPR[RS] + (EXTEND16 (IMMEDIATE) << 48);
|
|
TRACE_ALU_RESULT (GPR[RS]);
|
|
}
|
|
|
|
011111,5.RS,5.RT,5.RD,010,2.IMMEDIATE,100000:POOL32X:32::ALIGN
|
|
"align r<RD>, r<RS>, r<RT>, <IMMEDIATE>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
uint32_t rs = GPR[RS];
|
|
uint32_t rt = GPR[RT];
|
|
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
|
|
GPR[RD] = EXTEND32 (rs >> 8 * (4 - IMMEDIATE) | rt << 8 * IMMEDIATE);
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
011111,5.RS,5.RT,5.RD,01,3.IMMEDIATE,100100:POOL32X:64::DALIGN
|
|
"dalign r<RD>, r<RS>, r<RT>, <IMMEDIATE>"
|
|
*mips64r6:
|
|
{
|
|
uint64_t rs = GPR[RS];
|
|
uint64_t rt = GPR[RT];
|
|
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
|
|
GPR[RD] = rs >> 8 * (8 - IMMEDIATE) | rt << 8 * IMMEDIATE;
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
011111,00000,5.RT,5.RD,00000,100000:POOL32X:32::BITSWAP
|
|
"bitswap r<RD>, r<RT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
/* Taken from: http://graphics.stanford.edu/~seander/bithacks.html */
|
|
uint32_t v = GPR[RT];
|
|
|
|
TRACE_ALU_INPUT1 (v);
|
|
v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
|
|
v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
|
|
v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
|
|
GPR[RD] = EXTEND32 (v);
|
|
TRACE_ALU_RESULT(GPR[RD]);
|
|
}
|
|
|
|
011111,00000,5.RT,5.RD,00000,100100:POOL32X:64::DBITSWAP
|
|
"dbitswap r<RD>, r<RT>"
|
|
*mips64r6:
|
|
{
|
|
/* Taken from: http://graphics.stanford.edu/~seander/bithacks.html */
|
|
uint64_t v = GPR[RT];
|
|
|
|
TRACE_ALU_INPUT1 (v);
|
|
v = ((v >> 1) & 0x5555555555555555) | ((v & 0x5555555555555555) << 1);
|
|
v = ((v >> 2) & 0x3333333333333333) | ((v & 0x3333333333333333) << 2);
|
|
v = ((v >> 4) & 0x0F0F0F0F0F0F0F0F) | ((v & 0x0F0F0F0F0F0F0F0F) << 4);
|
|
TRACE_ALU_RESULT(v);
|
|
GPR[RD] = v;
|
|
}
|
|
|
|
111011,5.RS,00,19.IMMEDIATE:POOL32X:32::ADDIUPC
|
|
"addiupc r<RS>, <IMMEDIATE>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
TRACE_ALU_INPUT1 (IMMEDIATE);
|
|
GPR[RS] = loadstore_ea (SD_, CIA, EXTEND19 (IMMEDIATE) << 2);
|
|
TRACE_ALU_RESULT (GPR[RS]);
|
|
}
|
|
|
|
111011,5.RS,11110,16.IMMEDIATE:POOL32X:32::AUIPC
|
|
"auipc r<RS>, <IMMEDIATE>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
TRACE_ALU_INPUT1 (IMMEDIATE);
|
|
GPR[RS] = loadstore_ea (SD_, CIA, EXTEND32 (IMMEDIATE << 16));
|
|
TRACE_ALU_RESULT (GPR[RS]);
|
|
}
|
|
|
|
111011,5.RS,11111,16.IMMEDIATE:POOL32X:32::ALUIPC
|
|
"aluipc r<RS>, <IMMEDIATE>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
TRACE_ALU_INPUT1 (IMMEDIATE);
|
|
GPR[RS] = ~0x0FFFF & loadstore_ea (SD_, CIA, EXTEND32 (IMMEDIATE << 16));
|
|
TRACE_ALU_RESULT (GPR[RS]);
|
|
}
|
|
|
|
111011,5.RS,01,19.IMMEDIATE:POOL32X:32::LWPC
|
|
"lwpc r<RS>, <IMMEDIATE>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
uint32_t offset = EXTEND19 (IMMEDIATE) << 2;
|
|
TRACE_ALU_INPUT1 (IMMEDIATE);
|
|
GPR[RS] = EXTEND32 (do_load (SD_, AccessLength_WORD, CIA, offset));
|
|
TRACE_ALU_RESULT (GPR[RS]);
|
|
}
|
|
|
|
111011,5.RS,10,19.IMMEDIATE:POOL32X:64::LWUPC
|
|
"lwupc r<RS>, <IMMEDIATE>"
|
|
*mips64r6:
|
|
{
|
|
uint32_t offset = EXTEND19 (IMMEDIATE) << 2;
|
|
TRACE_ALU_INPUT1 (CIA + offset);
|
|
GPR[RS] = do_load (SD_, AccessLength_WORD, CIA, offset);
|
|
TRACE_ALU_RESULT (GPR[RS]);
|
|
}
|
|
|
|
111011,5.RS,110,18.IMMEDIATE:POOL32X:64::LDPC
|
|
"ldpc r<RS>, <IMMEDIATE>"
|
|
*mips64r6:
|
|
{
|
|
uint32_t offset = EXTEND18 (IMMEDIATE) << 3;
|
|
TRACE_ALU_INPUT1 (IMMEDIATE);
|
|
GPR[RS] = do_load (SD_, AccessLength_DOUBLEWORD, CIA, offset);
|
|
TRACE_ALU_RESULT (GPR[RS]);
|
|
}
|
|
010001,1000,1.FMT,00000,5.FS,5.FD,011010::32,64,f::RINT.fmt
|
|
"rint.%s<FMT> f<FD>, f<FS>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
uint64_t result;
|
|
int fmt = FMT;
|
|
check_fpu (SD_);
|
|
check_u64 (SD_, instruction_0);
|
|
check_fmt_p (SD_, fmt, instruction_0);
|
|
TRACE_ALU_INPUT1 (FGR[FS]);
|
|
RoundToIntegralExact (ValueFPR (FS, fmt), &result, fmt);
|
|
StoreFPR (FD, fmt, result);
|
|
TRACE_ALU_RESULT (FGR[FD]);
|
|
}
|
|
|
|
010001,1000,1.FMT,00000,5.FS,5.FD,011011::32,64,f::CLASS.fmt
|
|
"class.%s<FMT> f<FD>, f<FS>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
int fmt = FMT;
|
|
check_fpu (SD_);
|
|
check_u64 (SD_, instruction_0);
|
|
check_fmt_p (SD_, fmt, instruction_0);
|
|
StoreFPR (FD, fmt, Classify (ValueFPR (FS, fmt), fmt));
|
|
}
|
|
|
|
010001,1000,1.FMT,5.FT,5.FS,5.FD,011100::32,64,f::MIN.fmt
|
|
"min.%s<FMT> f<FD>, f<FS>, f<FT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
int fmt = FMT;
|
|
check_fpu (SD_);
|
|
check_u64 (SD_, instruction_0);
|
|
check_fmt_p (SD_, fmt, instruction_0);
|
|
TRACE_ALU_INPUT2 (FGR[FS], FGR[FT]);
|
|
StoreFPR (FD, fmt, Min (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
|
|
TRACE_ALU_RESULT (FGR[FD]);
|
|
}
|
|
|
|
010001,1000,1.FMT,5.FT,5.FS,5.FD,011110::32,64,f::MAX.fmt
|
|
"max.%s<FMT> f<FD>, f<FS>, f<FT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
int fmt = FMT;
|
|
check_fpu (SD_);
|
|
check_u64 (SD_, instruction_0);
|
|
check_fmt_p (SD_, fmt, instruction_0);
|
|
TRACE_ALU_INPUT2 (FGR[FS], FGR[FT]);
|
|
StoreFPR (FD, fmt, Max (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
|
|
TRACE_ALU_RESULT (FGR[FD]);
|
|
}
|
|
|
|
010001,1000,1.FMT,5.FT,5.FS,5.FD,011101::32,64,f::MINA.fmt
|
|
"mina.%s<FMT> f<FD>, f<FS>, f<FT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
int fmt = FMT;
|
|
check_fpu (SD_);
|
|
check_u64 (SD_, instruction_0);
|
|
check_fmt_p (SD_, fmt, instruction_0);
|
|
TRACE_ALU_INPUT2 (FGR[FS], FGR[FT]);
|
|
StoreFPR (FD, fmt, MinA (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
|
|
TRACE_ALU_RESULT (FGR[FD]);
|
|
}
|
|
|
|
010001,1000,1.FMT,5.FT,5.FS,5.FD,011111::32,64,f::MAXA.fmt
|
|
"maxa.%s<FMT> f<FD>, f<FS>, f<FT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
int fmt = FMT;
|
|
check_fpu (SD_);
|
|
check_u64 (SD_, instruction_0);
|
|
check_fmt_p (SD_, fmt, instruction_0);
|
|
TRACE_ALU_INPUT2 (FGR[FS], FGR[FT]);
|
|
StoreFPR (FD, fmt, MaxA (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
|
|
TRACE_ALU_RESULT (FGR[FD]);
|
|
}
|
|
000000,5.RS,5.RT,5.RD,00010,011000:POOL32X:32::MUL
|
|
"mul r<RD>, r<RS>, r<RT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
int64_t prod;
|
|
if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
|
|
Unpredictable ();
|
|
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
|
|
prod = ((int64_t)(int32_t) GPR[RS])
|
|
* ((int64_t)(int32_t) GPR[RT]);
|
|
GPR[RD] = EXTEND32 (VL4_8 (prod));
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00011,011000:POOL32X:32::MUH
|
|
"muh r<RD>, r<RS>, r<RT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
int64_t prod;
|
|
if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
|
|
Unpredictable ();
|
|
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
|
|
prod = ((int64_t)(int32_t) GPR[RS])
|
|
* ((int64_t)(int32_t) GPR[RT]);
|
|
GPR[RD] = EXTEND32 (VH4_8 (prod));
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00010,011001:POOL32X:32::MULU
|
|
"mulu r<RD>, r<RS>, r<RT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
uint64_t prod;
|
|
if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
|
|
Unpredictable ();
|
|
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
|
|
prod = ((uint64_t)(uint32_t) GPR[RS])
|
|
* ((uint64_t)(uint32_t) GPR[RT]);
|
|
GPR[RD] = EXTEND32 (VL4_8 (prod));
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00011,011001:POOL32X:32::MUHU
|
|
"muhu r<RD>, r<RS>, r<RT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
uint64_t prod;
|
|
if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
|
|
Unpredictable ();
|
|
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
|
|
prod = ((uint64_t)(uint32_t) GPR[RS])
|
|
* ((uint64_t)(uint32_t) GPR[RT]);
|
|
GPR[RD] = EXTEND32 (VH4_8 (prod));
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00010,011010:POOL32X:32::DIV
|
|
"div r<RD>, r<RS>, r<RT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
int32_t n = GPR[RS];
|
|
int32_t d = GPR[RT];
|
|
TRACE_ALU_INPUT2 (n,d);
|
|
if (d == 0)
|
|
GPR[RD] = EXTEND32 (0x80000000);
|
|
else if (n == SIGNED32 (0x80000000) && d == -1)
|
|
GPR[RD] = EXTEND32 (0x80000000);
|
|
else
|
|
GPR[RD] = EXTEND32 (n / d);
|
|
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00011,011010:POOL32X:32::MOD
|
|
"mod r<RD>, r<RS>, r<RT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
int32_t n = GPR[RS];
|
|
int32_t d = GPR[RT];
|
|
TRACE_ALU_INPUT2 (n,d);
|
|
if (d == 0 || (n == SIGNED32 (0x80000000) && d == -1))
|
|
GPR[RD] = EXTEND32 (0);
|
|
else
|
|
GPR[RD] = EXTEND32 (n % d);
|
|
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00010,011011:POOL32X:32::DIVU
|
|
"divu r<RD>, r<RS>, r<RT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
uint32_t n = GPR[RS];
|
|
uint32_t d = GPR[RT];
|
|
TRACE_ALU_INPUT2 (n,d);
|
|
if (d == 0)
|
|
GPR[RD] = EXTEND32 (0x80000000);
|
|
else
|
|
GPR[RD] = EXTEND32 (n / d);
|
|
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00011,011011:POOL32X:32::MODU
|
|
"modu r<RD>, r<RS>, r<RT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
uint32_t n = GPR[RS];
|
|
uint32_t d = GPR[RT];
|
|
TRACE_ALU_INPUT2 (n,d);
|
|
if (d == 0)
|
|
GPR[RD] = EXTEND32 (0);
|
|
else
|
|
GPR[RD] = EXTEND32 (n % d);
|
|
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00010,011100:POOL32X:64::DMUL
|
|
"dmul r<RD>, r<RS>, r<RT>"
|
|
*mips64r6:
|
|
{
|
|
uint64_t lo;
|
|
uint64_t m00;
|
|
uint64_t m01;
|
|
uint64_t m10;
|
|
uint64_t mid;
|
|
int sign;
|
|
uint64_t op1 = GPR[RS];
|
|
uint64_t op2 = GPR[RT];
|
|
|
|
check_u64 (SD_, instruction_0);
|
|
TRACE_ALU_INPUT2 (op1, op2);
|
|
/* make signed multiply unsigned */
|
|
sign = 0;
|
|
if ((int64_t) op1 < 0)
|
|
{
|
|
op1 = - op1;
|
|
++sign;
|
|
}
|
|
if ((int64_t) op2 < 0)
|
|
{
|
|
op2 = - op2;
|
|
++sign;
|
|
}
|
|
/* multiply out the sub products */
|
|
m00 = ((uint64_t) VL4_8 (op1) * (uint64_t) VL4_8 (op2));
|
|
m10 = ((uint64_t) VH4_8 (op1) * (uint64_t) VL4_8 (op2));
|
|
m01 = ((uint64_t) VL4_8 (op1) * (uint64_t) VH4_8 (op2));
|
|
/* add the products */
|
|
mid = ((uint64_t) VH4_8 (m00)
|
|
+ (uint64_t) VL4_8 (m10)
|
|
+ (uint64_t) VL4_8 (m01));
|
|
lo = U8_4 (mid, m00);
|
|
/* fix the sign */
|
|
if (sign & 1)
|
|
lo = -lo;
|
|
|
|
GPR[RD] = lo;
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00011,011100:POOL32X:64::DMUH
|
|
"dmuh r<RD>, r<RS>, r<RT>"
|
|
*mips64r6:
|
|
{
|
|
uint64_t lo;
|
|
uint64_t hi;
|
|
uint64_t m00;
|
|
uint64_t m01;
|
|
uint64_t m10;
|
|
uint64_t m11;
|
|
uint64_t mid;
|
|
int sign;
|
|
uint64_t op1 = GPR[RS];
|
|
uint64_t op2 = GPR[RT];
|
|
|
|
check_u64 (SD_, instruction_0);
|
|
TRACE_ALU_INPUT2 (op1, op2);
|
|
/* make signed multiply unsigned */
|
|
sign = 0;
|
|
if ((int64_t) op1 < 0)
|
|
{
|
|
op1 = - op1;
|
|
++sign;
|
|
}
|
|
if ((int64_t) op2 < 0)
|
|
{
|
|
op2 = - op2;
|
|
++sign;
|
|
}
|
|
/* multiply out the 4 sub products */
|
|
m00 = ((uint64_t) VL4_8 (op1) * (uint64_t) VL4_8 (op2));
|
|
m10 = ((uint64_t) VH4_8 (op1) * (uint64_t) VL4_8 (op2));
|
|
m01 = ((uint64_t) VL4_8 (op1) * (uint64_t) VH4_8 (op2));
|
|
m11 = ((uint64_t) VH4_8 (op1) * (uint64_t) VH4_8 (op2));
|
|
/* add the products */
|
|
mid = ((uint64_t) VH4_8 (m00)
|
|
+ (uint64_t) VL4_8 (m10)
|
|
+ (uint64_t) VL4_8 (m01));
|
|
lo = U8_4 (mid, m00);
|
|
hi = (m11
|
|
+ (uint64_t) VH4_8 (mid)
|
|
+ (uint64_t) VH4_8 (m01)
|
|
+ (uint64_t) VH4_8 (m10));
|
|
/* fix the sign */
|
|
if (sign & 1)
|
|
{
|
|
lo = -lo;
|
|
if (lo == 0)
|
|
hi = -hi;
|
|
else
|
|
hi = -hi - 1;
|
|
}
|
|
|
|
GPR[RD] = hi;
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00010,011101:POOL32X:64::DMULU
|
|
"dmulu r<RD>, r<RS>, r<RT>"
|
|
*mips64r6:
|
|
{
|
|
uint64_t lo;
|
|
uint64_t m00;
|
|
uint64_t m01;
|
|
uint64_t m10;
|
|
uint64_t mid;
|
|
uint64_t op1 = GPR[RS];
|
|
uint64_t op2 = GPR[RT];
|
|
|
|
check_u64 (SD_, instruction_0);
|
|
TRACE_ALU_INPUT2 (op1, op2);
|
|
/* multiply out the sub products */
|
|
m00 = ((uint64_t) VL4_8 (op1) * (uint64_t) VL4_8 (op2));
|
|
m10 = ((uint64_t) VH4_8 (op1) * (uint64_t) VL4_8 (op2));
|
|
m01 = ((uint64_t) VL4_8 (op1) * (uint64_t) VH4_8 (op2));
|
|
/* add the products */
|
|
mid = ((uint64_t) VH4_8 (m00)
|
|
+ (uint64_t) VL4_8 (m10)
|
|
+ (uint64_t) VL4_8 (m01));
|
|
lo = U8_4 (mid, m00);
|
|
|
|
GPR[RD] = lo;
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00011,011101:POOL32X:64::DMUHU
|
|
"dmuhu r<RD>, r<RS>, r<RT>"
|
|
*mips64r6:
|
|
{
|
|
uint64_t lo;
|
|
uint64_t hi;
|
|
uint64_t m00;
|
|
uint64_t m01;
|
|
uint64_t m10;
|
|
uint64_t m11;
|
|
uint64_t mid;
|
|
uint64_t op1 = GPR[RS];
|
|
uint64_t op2 = GPR[RT];
|
|
|
|
check_u64 (SD_, instruction_0);
|
|
TRACE_ALU_INPUT2 (op1, op2);
|
|
/* multiply out the 4 sub products */
|
|
m00 = ((uint64_t) VL4_8 (op1) * (uint64_t) VL4_8 (op2));
|
|
m10 = ((uint64_t) VH4_8 (op1) * (uint64_t) VL4_8 (op2));
|
|
m01 = ((uint64_t) VL4_8 (op1) * (uint64_t) VH4_8 (op2));
|
|
m11 = ((uint64_t) VH4_8 (op1) * (uint64_t) VH4_8 (op2));
|
|
/* add the products */
|
|
mid = ((uint64_t) VH4_8 (m00)
|
|
+ (uint64_t) VL4_8 (m10)
|
|
+ (uint64_t) VL4_8 (m01));
|
|
lo = U8_4 (mid, m00);
|
|
hi = (m11
|
|
+ (uint64_t) VH4_8 (mid)
|
|
+ (uint64_t) VH4_8 (m01)
|
|
+ (uint64_t) VH4_8 (m10));
|
|
|
|
GPR[RD] = hi;
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00010,011110:POOL32X:64::DDIV
|
|
"ddiv r<RD>, r<RS>, r<RT>"
|
|
*mips64r6:
|
|
{
|
|
int64_t n = GPR[RS];
|
|
int64_t d = GPR[RT];
|
|
|
|
check_u64 (SD_, instruction_0);
|
|
TRACE_ALU_INPUT2 (n, d);
|
|
if (d == 0)
|
|
GPR[RD] = SIGNED64 (0x8000000000000000);
|
|
else if (d == -1 && n == SIGNED64 (0x8000000000000000))
|
|
GPR[RD] = SIGNED64 (0x8000000000000000);
|
|
else
|
|
GPR[RD] = (n / d);
|
|
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00011,011110:POOL32X:64::DMOD
|
|
"dmod r<RD>, r<RS>, r<RT>"
|
|
*mips64r6:
|
|
{
|
|
int64_t n = GPR[RS];
|
|
int64_t d = GPR[RT];
|
|
|
|
check_u64 (SD_, instruction_0);
|
|
TRACE_ALU_INPUT2 (n, d);
|
|
if (d == 0 || (d == -1 && n == SIGNED64 (0x8000000000000000)))
|
|
GPR[RD] = SIGNED64 (0);
|
|
else
|
|
GPR[RD] = (n % d);
|
|
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00010,011111:POOL32X:64::DDIVU
|
|
"ddivu r<RD>, r<RS>, r<RT>"
|
|
*mips64r6:
|
|
{
|
|
uint64_t n = GPR[RS];
|
|
uint64_t d = GPR[RT];
|
|
|
|
check_u64 (SD_, instruction_0);
|
|
TRACE_ALU_INPUT2 (n, d);
|
|
if (d == 0)
|
|
GPR[RD] = UNSIGNED64 (0x8000000000000000);
|
|
else
|
|
GPR[RD] = (n / d);
|
|
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00011,011111:POOL32X:64::DMODU
|
|
"dmodu r<RD>, r<RS>, r<RT>"
|
|
*mips64r6:
|
|
{
|
|
uint64_t n = GPR[RS];
|
|
uint64_t d = GPR[RT];
|
|
|
|
check_u64 (SD_, instruction_0);
|
|
TRACE_ALU_INPUT2 (n, d);
|
|
if (d == 0)
|
|
GPR[RD] = UNSIGNED64 (0);
|
|
else
|
|
GPR[RD] = (n % d);
|
|
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
011111,5.BASE,5.RT,9.OFFSET,0,110110:SPECIAL3:32::LL
|
|
"ll r<RT>, <OFFSET>(r<BASE>)"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
do_ll (SD_, RT, EXTEND9 (OFFSET), BASE);
|
|
}
|
|
|
|
011111,5.BASE,5.RT,5.RD,0000,1,110110:SPECIAL3:32::LLWP
|
|
"llwp r<RT>, r<RD>, (r<BASE>)"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
int first, second;
|
|
int offset;
|
|
|
|
if (RT == BASE)
|
|
{
|
|
first = RD;
|
|
second = RT;
|
|
offset = BigEndianCPU ? 0 : 4;
|
|
}
|
|
else
|
|
{
|
|
first = RT;
|
|
second = RD;
|
|
offset = BigEndianCPU ? 4 : 0;
|
|
}
|
|
|
|
do_ll (SD_, first, offset, BASE);
|
|
do_ll (SD_, second, offset ^ 4, BASE);
|
|
}
|
|
|
|
|
|
011111,5.BASE,5.RT,9.OFFSET,0,100110:SPECIAL3:32::SC
|
|
"sc r<RT>, <OFFSET>(r<BASE>)"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
do_sc (SD_, RT, EXTEND9 (OFFSET), BASE, instruction_0, 1);
|
|
}
|
|
|
|
011111,5.BASE,5.RT,9.OFFSET,0,110111:SPECIAL3:64::LLD
|
|
"lld r<RT>, <OFFSET>(r<BASE>)"
|
|
*mips64r6:
|
|
{
|
|
check_u64 (SD_, instruction_0);
|
|
do_lld (SD_, RT, EXTEND9 (OFFSET), BASE);
|
|
}
|
|
|
|
|
|
011111,5.BASE,5.RT,5.RD,0000,1,100110:SPECIAL3:32::SCWP
|
|
"scwp r<RT>, r<RD>, (r<BASE>)"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
int offset = BigEndianCPU ? 0 : 4;
|
|
|
|
do_sc (SD_, RD, offset, BASE, instruction_0, 0);
|
|
do_sc (SD_, RT, offset ^ 4, BASE, instruction_0, 1);
|
|
}
|
|
|
|
011111,5.BASE,5.RT,5.RD,0000,1,110111:SPECIAL3:64::LLDP
|
|
"lldp r<RT>, r<RD>, (r<BASE>)"
|
|
*mips64r6:
|
|
{
|
|
int first, second;
|
|
int offset;
|
|
|
|
check_u64 (SD_, instruction_0);
|
|
|
|
if (RT == BASE)
|
|
{
|
|
first = RD;
|
|
second = RT;
|
|
offset = BigEndianCPU ? 0 : 8;
|
|
}
|
|
else
|
|
{
|
|
first = RT;
|
|
second = RD;
|
|
offset = BigEndianCPU ? 8 : 0;
|
|
}
|
|
|
|
do_lld (SD_, first, offset, BASE);
|
|
do_lld (SD_, second, offset ^ 8, BASE);
|
|
}
|
|
|
|
011111,5.BASE,5.RT,9.OFFSET,0,100111:SPECIAL3:64::SCD
|
|
"scd r<RT>, <OFFSET>(r<BASE>)"
|
|
*mips64r6:
|
|
{
|
|
check_u64 (SD_, instruction_0);
|
|
do_scd (SD_, RT, EXTEND9 (OFFSET), BASE, 1);
|
|
}
|
|
|
|
011111,5.BASE,5.RT,5.RD,0000,1,100111:SPECIAL3:64::SCDP
|
|
"scdp r<RT>, r<RD>, (r<BASE>)"
|
|
*mips64r6:
|
|
{
|
|
int offset = BigEndianCPU ? 0 : 8;
|
|
check_u64 (SD_, instruction_0);
|
|
|
|
do_scd (SD_, RD, offset, BASE, 0);
|
|
do_scd (SD_, RT, offset ^ 8, BASE, 1);
|
|
}
|
|
|
|
011111,5.BASE,5.HINT,9.OFFSET,0,110101:SPECIAL3:32::PREF
|
|
"pref <HINT>, <OFFSET>(r<BASE>)"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
do_pref (SD_, HINT, EXTEND9 (OFFSET), BASE);
|
|
}
|
|
|
|
011111,5.BASE,5.HINT,9.OFFSET,0,100101:SPECIAL3:32::CACHE
|
|
"cache <HINT>, <OFFSET>(r<BASE>)"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
do_cache (SD_, HINT, BASE, EXTEND9 (OFFSET), instruction_0);
|
|
}
|
|
|
|
|
|
000000,5.RS,00000,5.RD,00001,010000:POOL32X:32::CLZ
|
|
"clz r<RD>, r<RS>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
do_clz (SD_, RD, RS);
|
|
}
|
|
|
|
000000,5.RS,00000,5.RD,00001,010001:POOL32X:32::CLO
|
|
"clo r<RD>, r<RS>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
do_clo (SD_, RD, RS);
|
|
}
|
|
|
|
000000,5.RS,00000,5.RD,00001,010010:POOL32X:64::DCLZ
|
|
"dclz r<RD>, r<RS>"
|
|
*mips64r6:
|
|
{
|
|
check_u64 (SD_, instruction_0);
|
|
do_dclz (SD_, RD, RS);
|
|
}
|
|
|
|
000000,5.RS,00000,5.RD,00001,010011:POOL32X:64::DCLO
|
|
"dclo r<RD>, r<RS>"
|
|
*mips64r6:
|
|
{
|
|
check_u64 (SD_, instruction_0);
|
|
do_dclo (SD_, RD, RS);
|
|
}
|
|
010001,1000,1.FMT,5.FT,5.FS,5.FD,010000:POOL32X:32,f::SEL.fmt
|
|
"sel.%s<FMT> f<FD>, f<FS>, f<FT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
check_fpu (SD_);
|
|
check_fmt_p (SD_, FMT, instruction_0);
|
|
TRACE_ALU_INPUT3 (FGR[FD], ValueFPR(FS, FMT), ValueFPR(FT, FMT));
|
|
if ((FGR[FD] & 0x01) != 0)
|
|
StoreFPR (FD, FMT, ValueFPR (FT, FMT));
|
|
else
|
|
StoreFPR (FD, FMT, ValueFPR (FS, FMT));
|
|
TRACE_ALU_RESULT (ValueFPR(FD, FMT));
|
|
}
|
|
|
|
010001,1000,1.FMT,5.FT,5.FS,5.FD,010100:POOL32X:32,f::SELEQZ.fmt
|
|
"seleqz.%s<FMT> f<FD>, f<FS>, f<FT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
check_fpu (SD_);
|
|
check_fmt_p (SD_, FMT, instruction_0);
|
|
TRACE_ALU_INPUT2 (ValueFPR(FS, FMT), FGR[FT]);
|
|
if ((FGR[FT] & 0x01) == 0)
|
|
StoreFPR (FD, FMT, ValueFPR (FS, FMT));
|
|
else
|
|
StoreFPR (FD, FMT, 0);
|
|
TRACE_ALU_RESULT (ValueFPR(FD, FMT));
|
|
}
|
|
|
|
010001,1000,1.FMT,5.FT,5.FS,5.FD,010111:POOL32X:32,f::SELNEZ.fmt
|
|
"selnez.%s<FMT> f<FD>, f<FS>, f<FT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
check_fpu (SD_);
|
|
check_fmt_p (SD_, FMT, instruction_0);
|
|
TRACE_ALU_INPUT2 (ValueFPR(FS, FMT), FGR[FT]);
|
|
if ((FGR[FT] & 0x01) == 0)
|
|
StoreFPR (FD, FMT, 0);
|
|
else
|
|
StoreFPR (FD, FMT, ValueFPR (FS, FMT));
|
|
TRACE_ALU_RESULT (ValueFPR(FD, FMT));
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00000,110101:POOL32X:32::SELEQZ
|
|
"seleqz r<RD>, r<RS>, r<RT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
|
|
if (GPR[RT] != 0)
|
|
GPR[RD] = 0;
|
|
else
|
|
GPR[RD] = GPR[RS];
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|
|
|
|
000000,5.RS,5.RT,5.RD,00000,110111:POOL32X:32::SELNEZ
|
|
"selnez r<RD>, r<RS>, r<RT>"
|
|
*mips32r6:
|
|
*mips64r6:
|
|
{
|
|
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
|
|
if (GPR[RT] != 0)
|
|
GPR[RD] = GPR[RS];
|
|
else
|
|
GPR[RD] = 0;
|
|
TRACE_ALU_RESULT (GPR[RD]);
|
|
}
|