summaryrefslogtreecommitdiff
path: root/sim/mips/mips3264r6.igen
diff options
context:
space:
mode:
Diffstat (limited to 'sim/mips/mips3264r6.igen')
-rw-r--r--sim/mips/mips3264r6.igen1226
1 files changed, 1226 insertions, 0 deletions
diff --git a/sim/mips/mips3264r6.igen b/sim/mips/mips3264r6.igen
new file mode 100644
index 00000000000..b83c3098077
--- /dev/null
+++ b/sim/mips/mips3264r6.igen
@@ -0,0 +1,1226 @@
+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]);
+}