110010,26.OFFSET:POOL32X:32::BC "bc " *mips32r6: *mips64r6: { NIA = CIA + (EXTEND26 (OFFSET) << 2) + 4; } 111010,26.OFFSET:POOL32X:32::BALC "balc " *mips32r6: *mips64r6: { RA = CIA + 4; NIA = CIA + (EXTEND26 (OFFSET) << 2) + 4; } 110110,5.RS!0,21.OFFSET:POOL32X:32::BEQZC "beqzc r, " *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, " *mips32r6: *mips64r6: { NIA = GPR[RT] + (EXTEND16(OFFSET) << 2); } 111110,5.RS!0,21.OFFSET:POOL32X:32::BNEZC "bnezc r, " *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, " *mips32r6: *mips64r6: { RA = CIA + 4; NIA = GPR[RT] + EXTEND16(OFFSET); } 010110,5.RS,5.RT,16.OFFSET:POOL32X:32::B1xxC "blezc r, ": RS==0&&RT!=0 "bgezc r, ":RS!=0&&RS==RT "bgec r, r, " *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, ":RS==0&&RT!=0 "bltzc r, ":RS!=0&&RS==RT "bltc r, r, " *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, ":RS==0 "bgezalc r, ":RS!=0&&RS==RT "bgeuc r, r, " *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, ":RS==0 "bltzalc r, ":RS!=0&&RS==RT "bltuc r, r, " *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, r, ":RS>=RT "beqzalc r, ":RS==0&&RT>RS "beqc r, r, " *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, r, ":RS>=RT "bnezalc r, ":RS==0&&RT>RS "bnec r, r, " *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.%s f, f, f" *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, " *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, " *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 f, f, f" *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 f, f, f" *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, r, r, " *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, r, r, " *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, r, " *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, r, " *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, " *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, " *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, r, r, " *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, r, r, " *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, r" *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, r" *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, " *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, " *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, " *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, " *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, " *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, " *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 f, f" *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 f, f" *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 f, f, f" *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 f, f, f" *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 f, f, f" *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 f, f, f" *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, r, r" *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, r, r" *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, r, r" *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, r, r" *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, r, r" *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, r, r" *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, r, r" *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, r, r" *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, r, r" *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, r, r" *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, r, r" *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, r, r" *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, r, r" *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, r, r" *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, r, r" *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, r, r" *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, (r)" *mips32r6: *mips64r6: { do_ll (SD_, RT, EXTEND9 (OFFSET), BASE); } 011111,5.BASE,5.RT,5.RD,0000,1,110110:SPECIAL3:32::LLWP "llwp r, r, (r)" *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, (r)" *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, (r)" *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, r, (r)" *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, r, (r)" *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, (r)" *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, r, (r)" *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 , (r)" *mips32r6: *mips64r6: { do_pref (SD_, HINT, EXTEND9 (OFFSET), BASE); } 011111,5.BASE,5.HINT,9.OFFSET,0,100101:SPECIAL3:32::CACHE "cache , (r)" *mips32r6: *mips64r6: { do_cache (SD_, HINT, BASE, EXTEND9 (OFFSET), instruction_0); } 000000,5.RS,00000,5.RD,00001,010000:POOL32X:32::CLZ "clz r, r" *mips32r6: *mips64r6: { do_clz (SD_, RD, RS); } 000000,5.RS,00000,5.RD,00001,010001:POOL32X:32::CLO "clo r, r" *mips32r6: *mips64r6: { do_clo (SD_, RD, RS); } 000000,5.RS,00000,5.RD,00001,010010:POOL32X:64::DCLZ "dclz r, r" *mips64r6: { check_u64 (SD_, instruction_0); do_dclz (SD_, RD, RS); } 000000,5.RS,00000,5.RD,00001,010011:POOL32X:64::DCLO "dclo r, r" *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 f, f, f" *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 f, f, f" *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 f, f, f" *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, r, r" *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, r, r" *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]); }