*
*/
+/*
+ * Documentation used while implementing this component:
+ *
+ * [1] "MIPS® Architecture Base: nanoMIPS32(tm) Instruction Set Technical
+ * Reference Manual", Revision 01.01, April 27, 2018
+ */
+
extern "C" {
#include "qemu/osdep.h"
-#include "disas/bfd.h"
+#include "disas/dis-asm.h"
}
#include <cstring>
/*
- * these functions should be decode functions but the json does not have
- * decode sections so they are based on the encode, the equivalent decode
- * functions need writing eventually.
+ * NMD::decode_gpr_gpr4() - decoder for 'gpr4' gpr encoding type
+ *
+ * Map a 4-bit code to the 5-bit register space according to this pattern:
+ *
+ * 1 0
+ * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * | | | | | | | | | | | | | | | |
+ * | | | | | | | | | | | | | | | |
+ * | | | | | | | | | | | └---------------┐
+ * | | | | | | | | | | └---------------┐ |
+ * | | | | | | | | | └---------------┐ | |
+ * | | | | | | | | └---------------┐ | | |
+ * | | | | | | | | | | | | | | | |
+ * | | | | | | | | | | | | | | | |
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * 3 2 1 0
+ *
+ * Used in handling following instructions:
+ *
+ * - ADDU[4X4]
+ * - LW[4X4]
+ * - MOVEP[REV]
+ * - MUL[4X4]
+ * - SW[4X4]
*/
-uint64 NMD::decode_gpr_gpr3(uint64 d)
+uint64 NMD::decode_gpr_gpr4(uint64 d)
{
- static uint64 register_list[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
+ static uint64 register_list[] = { 8, 9, 10, 11, 4, 5, 6, 7,
+ 16, 17, 18, 19, 20, 21, 22, 23 };
return renumber_registers(d, register_list,
sizeof(register_list) / sizeof(register_list[0]));
}
-uint64 NMD::encode_gpr3_store(uint64 d)
+/*
+ * NMD::decode_gpr_gpr4_zero() - decoder for 'gpr4.zero' gpr encoding type
+ *
+ * Map a 4-bit code to the 5-bit register space according to this pattern:
+ *
+ * 1 0
+ * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * | | | | | | | | | | | | | | | |
+ * | | | | | | | | | | | | └---------------------┐
+ * | | | | | | | | | | | └---------------┐ |
+ * | | | | | | | | | | └---------------┐ | |
+ * | | | | | | | | | └---------------┐ | | |
+ * | | | | | | | | └---------------┐ | | | |
+ * | | | | | | | | | | | | | | | |
+ * | | | | | | | | | | | | | | | |
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * 3 2 1 0
+ *
+ * This pattern is the same one used for 'gpr4' gpr encoding type, except for
+ * the input value 3, that is mapped to the output value 0 instead of 11.
+ *
+ * Used in handling following instructions:
+ *
+ * - MOVE.BALC
+ * - MOVEP
+ * - SW[4X4]
+ */
+uint64 NMD::decode_gpr_gpr4_zero(uint64 d)
{
- static uint64 register_list[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
+ static uint64 register_list[] = { 8, 9, 10, 0, 4, 5, 6, 7,
+ 16, 17, 18, 19, 20, 21, 22, 23 };
return renumber_registers(d, register_list,
sizeof(register_list) / sizeof(register_list[0]));
}
-uint64 NMD::encode_rd1_from_rd(uint64 d)
+/*
+ * NMD::decode_gpr_gpr3() - decoder for 'gpr3' gpr encoding type
+ *
+ * Map a 3-bit code to the 5-bit register space according to this pattern:
+ *
+ * 7 6 5 4 3 2 1 0
+ * | | | | | | | |
+ * | | | | | | | |
+ * | | | └-----------------------┐
+ * | | └-----------------------┐ |
+ * | └-----------------------┐ | |
+ * └-----------------------┐ | | |
+ * | | | | | | | |
+ * ┌-------┘ | | | | | | |
+ * | ┌-------┘ | | | | | |
+ * | | ┌-------┘ | | | | |
+ * | | | ┌-------┘ | | | |
+ * | | | | | | | |
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * 3 2 1 0
+ *
+ * Used in handling following instructions:
+ *
+ * - ADDIU[R1.SP]
+ * - ADDIU[R2]
+ * - ADDU[16]
+ * - AND[16]
+ * - ANDI[16]
+ * - BEQC[16]
+ * - BEQZC[16]
+ * - BNEC[16]
+ * - BNEZC[16]
+ * - LB[16]
+ * - LBU[16]
+ * - LH[16]
+ * - LHU[16]
+ * - LI[16]
+ * - LW[16]
+ * - LW[GP16]
+ * - LWXS[16]
+ * - NOT[16]
+ * - OR[16]
+ * - SB[16]
+ * - SH[16]
+ * - SLL[16]
+ * - SRL[16]
+ * - SUBU[16]
+ * - SW[16]
+ * - XOR[16]
+ */
+uint64 NMD::decode_gpr_gpr3(uint64 d)
{
- static uint64 register_list[] = { 4, 5 };
+ static uint64 register_list[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
return renumber_registers(d, register_list,
sizeof(register_list) / sizeof(register_list[0]));
}
-uint64 NMD::encode_gpr4_zero(uint64 d)
+/*
+ * NMD::decode_gpr_gpr3_src_store() - decoder for 'gpr3.src.store' gpr encoding
+ * type
+ *
+ * Map a 3-bit code to the 5-bit register space according to this pattern:
+ *
+ * 7 6 5 4 3 2 1 0
+ * | | | | | | | |
+ * | | | | | | | └-----------------------┐
+ * | | | └-----------------------┐ |
+ * | | └-----------------------┐ | |
+ * | └-----------------------┐ | | |
+ * └-----------------------┐ | | | |
+ * | | | | | | | |
+ * ┌-------┘ | | | | | | |
+ * | ┌-------┘ | | | | | |
+ * | | ┌-------┘ | | | | |
+ * | | | | | | | |
+ * | | | | | | | |
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * 3 2 1 0
+ *
+ * This pattern is the same one used for 'gpr3' gpr encoding type, except for
+ * the input value 0, that is mapped to the output value 0 instead of 16.
+ *
+ * Used in handling following instructions:
+ *
+ * - SB[16]
+ * - SH[16]
+ * - SW[16]
+ * - SW[GP16]
+ */
+uint64 NMD::decode_gpr_gpr3_src_store(uint64 d)
{
- static uint64 register_list[] = { 8, 9, 10, 0, 4, 5, 6, 7,
- 16, 17, 18, 19, 20, 21, 22, 23 };
+ static uint64 register_list[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
return renumber_registers(d, register_list,
sizeof(register_list) / sizeof(register_list[0]));
}
-uint64 NMD::encode_gpr4(uint64 d)
+/*
+ * NMD::decode_gpr_gpr2_reg1() - decoder for 'gpr2.reg1' gpr encoding type
+ *
+ * Map a 2-bit code to the 5-bit register space according to this pattern:
+ *
+ * 3 2 1 0
+ * | | | |
+ * | | | |
+ * | | | └-------------------┐
+ * | | └-------------------┐ |
+ * | └-------------------┐ | |
+ * └-------------------┐ | | |
+ * | | | |
+ * | | | |
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * 3 2 1 0
+ *
+ * Used in handling following instructions:
+ *
+ * - MOVEP
+ * - MOVEP[REV]
+ */
+uint64 NMD::decode_gpr_gpr2_reg1(uint64 d)
{
- static uint64 register_list[] = { 8, 9, 10, 11, 4, 5, 6, 7,
- 16, 17, 18, 19, 20, 21, 22, 23 };
+ static uint64 register_list[] = { 4, 5, 6, 7 };
return renumber_registers(d, register_list,
sizeof(register_list) / sizeof(register_list[0]));
}
-uint64 NMD::encode_rd2_reg1(uint64 d)
+/*
+ * NMD::decode_gpr_gpr2_reg2() - decoder for 'gpr2.reg2' gpr encoding type
+ *
+ * Map a 2-bit code to the 5-bit register space according to this pattern:
+ *
+ * 3 2 1 0
+ * | | | |
+ * | | | |
+ * | | | └-----------------┐
+ * | | └-----------------┐ |
+ * | └-----------------┐ | |
+ * └-----------------┐ | | |
+ * | | | |
+ * | | | |
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * 3 2 1 0
+ *
+ * Used in handling following instructions:
+ *
+ * - MOVEP
+ * - MOVEP[REV]
+ */
+uint64 NMD::decode_gpr_gpr2_reg2(uint64 d)
{
- static uint64 register_list[] = { 4, 5, 6, 7 };
+ static uint64 register_list[] = { 5, 6, 7, 8 };
return renumber_registers(d, register_list,
sizeof(register_list) / sizeof(register_list[0]));
}
-uint64 NMD::encode_rd2_reg2(uint64 d)
+/*
+ * NMD::decode_gpr_gpr1() - decoder for 'gpr1' gpr encoding type
+ *
+ * Map a 1-bit code to the 5-bit register space according to this pattern:
+ *
+ * 1 0
+ * | |
+ * | |
+ * | └---------------------┐
+ * └---------------------┐ |
+ * | |
+ * | |
+ * | |
+ * | |
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * 3 2 1 0
+ *
+ * Used in handling following instruction:
+ *
+ * - MOVE.BALC
+ */
+uint64 NMD::decode_gpr_gpr1(uint64 d)
{
- static uint64 register_list[] = { 5, 6, 7, 8 };
+ static uint64 register_list[] = { 4, 5 };
return renumber_registers(d, register_list,
sizeof(register_list) / sizeof(register_list[0]));
}
}
-uint64 NMD::extract_ac_13_12(uint64 instruction)
+uint64 NMD::extract_ac_15_14(uint64 instruction)
{
uint64 value = 0;
value |= extract_bits(instruction, 14, 2);
/*
- * ABSQ_S.PH rt, rs - Find Absolute Value of Two Fractional Halfwords
+ * [DSP] ABSQ_S.PH rt, rs - Find absolute value of two fractional halfwords
+ * with 16-bit saturation
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ABSQ_S.QB rt, rs - Find Absolute Value of Four Fractional Byte Values
+ * [DSP] ABSQ_S.QB rt, rs - Find absolute value of four fractional byte values
+ * with 8-bit saturation
*
* 3 2 1
* 10987654321098765432109876543210
/*
- *
+ * [DSP] ABSQ_S.W rt, rs - Find absolute value of fractional word with 32-bit
+ * saturation
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQ.PH rd, rt, rs - Add Fractional Halfword Vectors
+ * [DSP] ADDQ.PH rd, rt, rs - Add fractional halfword vectors
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQ_S.PH rd, rt, rs - Add Fractional Halfword Vectors
+ * [DSP] ADDQ_S.PH rd, rt, rs - Add fractional halfword vectors with 16-bit
+ * saturation
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQ_S.W rd, rt, rs - Add Fractional Words
+ * [DSP] ADDQ_S.W rd, rt, rs - Add fractional words with 32-bit saturation
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH.PH rd, rt, rs - Add Fractional Halfword Vectors And Shift Right
- * to Halve Results
+ * [DSP] ADDQH.PH rd, rt, rs - Add fractional halfword vectors and shift
+ * right to halve results
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH_R.PH rd, rt, rs - Add Fractional Halfword Vectors And Shift Right
- * to Halve Results
+ * [DSP] ADDQH_R.PH rd, rt, rs - Add fractional halfword vectors and shift
+ * right to halve results with rounding
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] ADDQH_R.W rd, rt, rs - Add fractional words and shift right to halve
+ * results with rounding
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] ADDQH.W rd, rt, rs - Add fractional words and shift right to halve
+ * results
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDSC rd, rt, rs - Add Signed Word and Set Carry Bit
+ * [DSP] ADDSC rd, rt, rs - Add two signed words and set carry bit
*
* 3 2 1
* 10987654321098765432109876543210
uint64 rt4_value = extract_rt4_9_7_6_5(instruction);
uint64 rs4_value = extract_rs4_4_2_1_0(instruction);
- std::string rs4 = GPR(encode_gpr4(rs4_value));
- std::string rt4 = GPR(encode_gpr4(rt4_value));
+ std::string rs4 = GPR(decode_gpr_gpr4(rs4_value));
+ std::string rt4 = GPR(decode_gpr_gpr4(rt4_value));
return img::format("ADDU %s, %s", rs4, rt4);
}
/*
- * ADDU.PH rd, rt, rs - Unsigned Add Integer Halfwords
+ * [DSP] ADDU.PH rd, rt, rs - Add two pairs of unsigned halfwords
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDU_S.PH rd, rt, rs - Unsigned Add Integer Halfwords
+ * [DSP] ADDU_S.PH rd, rt, rs - Add two pairs of unsigned halfwords with 16-bit
+ * saturation
*
* 3 2 1
* 10987654321098765432109876543210
/*
- *
+ * [DSP] BPOSGE32C offset - Branch on greater than or equal to value 32 in
+ * DSPControl Pos field
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
- * rt -----
- * rs -----
- * rd -----
+ * 100010xxxxx0010001
+ * s[13:1] -------------
+ * s[14] -
*/
std::string NMD::BPOSGE32C(uint64 instruction)
{
/*
- *
+ * [DSP] CMP.EQ.PH rs, rt - Compare vectors of signed integer halfword values
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 xxxxxx0000000101
* rt -----
* rs -----
- * rd -----
*/
std::string NMD::CMP_EQ_PH(uint64 instruction)
{
/*
- *
+ * [DSP] CMP.LE.PH rs, rt - Compare vectors of signed integer halfword values
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 xxxxxx0010000101
* rt -----
* rs -----
- * rd -----
*/
std::string NMD::CMP_LE_PH(uint64 instruction)
{
/*
- *
+ * [DSP] CMP.LT.PH rs, rt - Compare vectors of signed integer halfword values
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 xxxxxx0001000101
* rt -----
* rs -----
- * rd -----
*/
std::string NMD::CMP_LT_PH(uint64 instruction)
{
/*
- *
+ * [DSP] CMPGDU.EQ.QB rd, rs, rt - Compare unsigned vector of
+ * four bytes and write result to GPR and DSPControl
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 x0110000101
* rt -----
* rs -----
* rd -----
/*
- *
+ * [DSP] CMPGDU.LE.QB rd, rs, rt - Compare unsigned vector of
+ * four bytes and write result to GPR and DSPControl
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 x1000000101
* rt -----
* rs -----
* rd -----
/*
- *
+ * [DSP] CMPGDU.EQ.QB rd, rs, rt - Compare unsigned vector of
+ * four bytes and write result to GPR and DSPControl
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 x0111000101
* rt -----
* rs -----
* rd -----
/*
- *
+ * [DSP] CMPGU.EQ.QB rd, rs, rt - Compare vectors of unsigned
+ * byte values and write result to a GPR
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 x0011000101
* rt -----
* rs -----
* rd -----
/*
- *
+ * [DSP] CMPGU.LE.QB rd, rs, rt - Compare vectors of unsigned
+ * byte values and write result to a GPR
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 x0101000101
* rt -----
* rs -----
* rd -----
/*
- *
+ * [DSP] CMPGU.LT.QB rd, rs, rt - Compare vectors of unsigned
+ * byte values and write result to a GPR
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 x0100000101
* rt -----
* rs -----
* rd -----
/*
- *
+ * [DSP] CMPU.EQ.QB rd, rs, rt - Compare vectors of unsigned
+ * byte values
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 xxxxxx1001000101
* rt -----
* rs -----
- * rd -----
*/
std::string NMD::CMPU_EQ_QB(uint64 instruction)
{
/*
- *
+ * [DSP] CMPU.LE.QB rd, rs, rt - Compare vectors of unsigned
+ * byte values
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 xxxxxx1011000101
* rt -----
* rs -----
- * rd -----
*/
std::string NMD::CMPU_LE_QB(uint64 instruction)
{
/*
- *
+ * [DSP] CMPU.LT.QB rd, rs, rt - Compare vectors of unsigned
+ * byte values
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 xxxxxx1010000101
* rt -----
* rs -----
- * rd -----
*/
std::string NMD::CMPU_LT_QB(uint64 instruction)
{
/*
- *
+ * [DSP] DPA.W.PH ac, rs, rt - Dot product with accumulate on
+ * vector integer halfword elements
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 00000010111111
* rt -----
* rs -----
- * rd -----
+ * ac --
*/
std::string NMD::DPA_W_PH(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 size_value = extract_size_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rt = GPR(copy(rt_value));
std::string ac = AC(copy(ac_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rt = GPR(copy(rt_value));
std::string ac = AC(copy(ac_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 size_value = extract_size_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rt = GPR(copy(rt_value));
std::string ac = AC(copy(ac_value));
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rt = GPR(copy(rt_value));
std::string ac = AC(copy(ac_value));
/*
- *
+ * [DSP] EXTR_RS.W rt, ac, shift - Extract word value from accumulator to GPR
+ * with right shift
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 10111001111111
* rt -----
- * rs -----
- * rd -----
+ * shift -----
+ * ac --
*/
std::string NMD::EXTR_RS_W(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 shift_value = extract_shift_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rt = GPR(copy(rt_value));
std::string ac = AC(copy(ac_value));
/*
- *
+ * [DSP] EXTR_R.W rt, ac, shift - Extract word value from accumulator to GPR
+ * with right shift
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 01111001111111
* rt -----
- * rs -----
- * rd -----
+ * shift -----
+ * ac --
*/
std::string NMD::EXTR_R_W(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 shift_value = extract_shift_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rt = GPR(copy(rt_value));
std::string ac = AC(copy(ac_value));
/*
- *
+ * [DSP] EXTR_S.H rt, ac, shift - Extract halfword value from accumulator
+ * to GPR with right shift and saturate
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 11111001111111
* rt -----
- * rs -----
- * rd -----
+ * shift -----
+ * ac --
*/
std::string NMD::EXTR_S_H(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 shift_value = extract_shift_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rt = GPR(copy(rt_value));
std::string ac = AC(copy(ac_value));
/*
- *
+ * [DSP] EXTR.W rt, ac, shift - Extract word value from accumulator to GPR
+ * with right shift
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 00111001111111
* rt -----
- * rs -----
- * rd -----
+ * shift -----
+ * ac --
*/
std::string NMD::EXTR_W(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 shift_value = extract_shift_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rt = GPR(copy(rt_value));
std::string ac = AC(copy(ac_value));
/*
- *
+ * [DSP] EXTRV_RS.W rt, ac, rs - Extract word value with variable
+ * right shift from accumulator to GPR
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 10111010111111
* rt -----
* rs -----
- * rd -----
+ * ac --
*/
std::string NMD::EXTRV_RS_W(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rt = GPR(copy(rt_value));
std::string ac = AC(copy(ac_value));
/*
- *
+ * [DSP] EXTRV_R.W rt, ac, rs - Extract word value with variable
+ * right shift from accumulator to GPR
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 01111010111111
* rt -----
* rs -----
- * rd -----
+ * ac --
*/
std::string NMD::EXTRV_R_W(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rt = GPR(copy(rt_value));
std::string ac = AC(copy(ac_value));
/*
- *
+ * [DSP] EXTRV_S.H rt, ac, rs - Extract halfword value variable from
+ * accumulator to GPR with right shift and saturate
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 11111010111111
* rt -----
* rs -----
- * rd -----
+ * ac --
*/
std::string NMD::EXTRV_S_H(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rt = GPR(copy(rt_value));
std::string ac = AC(copy(ac_value));
/*
- *
+ * [DSP] EXTRV.W rt, ac, rs - Extract word value with variable
+ * right shift from accumulator to GPR
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 00111010111111
* rt -----
* rs -----
- * rd -----
+ * ac --
*/
std::string NMD::EXTRV_W(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rt = GPR(copy(rt_value));
std::string ac = AC(copy(ac_value));
/*
- *
+ * [DSP] INSV rt, rs - Insert bit field variable
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 0100000100111111
* rt -----
* rs -----
- * rd -----
*/
std::string NMD::INSV(uint64 instruction)
{
uint64 rs4_value = extract_rs4_4_2_1_0(instruction);
uint64 u_value = extract_u_3_8__s2(instruction);
- std::string rt4 = GPR(encode_gpr4(rt4_value));
+ std::string rt4 = GPR(decode_gpr_gpr4(rt4_value));
std::string u = IMMEDIATE(copy(u_value));
- std::string rs4 = GPR(encode_gpr4(rs4_value));
+ std::string rs4 = GPR(decode_gpr_gpr4(rs4_value));
return img::format("LW %s, %s(%s)", rt4, u, rs4);
}
/*
- *
+ * [DSP] MADD ac, rs, rt - Multiply two words and add to the specified
+ * accumulator
*
* 3 2 1
* 10987654321098765432109876543210
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
/*
- *
+ * [DSP] MADDU ac, rs, rt - Multiply two unsigned words and add to the
+ * specified accumulator
*
* 3 2 1
* 10987654321098765432109876543210
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
/*
- *
+ * [DSP] MAQ_S.W.PHL ac, rs, rt - Multiply the left-most single vector
+ * fractional halfword elements with accumulation
*
* 3 2 1
* 10987654321098765432109876543210
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
/*
- *
+ * [DSP] MAQ_S.W.PHR ac, rs, rt - Multiply the right-most single vector
+ * fractional halfword elements with accumulation
*
* 3 2 1
* 10987654321098765432109876543210
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
/*
- *
+ * [DSP] MAQ_SA.W.PHL ac, rs, rt - Multiply the left-most single vector
+ * fractional halfword elements with saturating accumulation
*
* 3 2 1
* 10987654321098765432109876543210
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
/*
- *
+ * [DSP] MAQ_SA.W.PHR ac, rs, rt - Multiply the right-most single vector
+ * fractional halfword elements with saturating accumulation
*
* 3 2 1
* 10987654321098765432109876543210
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
/*
- *
+ * [DSP] MFHI rs, ac - Move from HI register
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 xxxxx 00000001111111
* rt -----
- * rs -----
- * rd -----
+ * ac --
*/
std::string NMD::MFHI_DSP_(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rt = GPR(copy(rt_value));
std::string ac = AC(copy(ac_value));
/*
- *
+ * [DSP] MFLO rs, ac - Move from HI register
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 xxxxx 01000001111111
* rt -----
- * rs -----
- * rd -----
+ * ac --
*/
std::string NMD::MFLO_DSP_(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rt = GPR(copy(rt_value));
std::string ac = AC(copy(ac_value));
/*
- *
+ * [DSP] MODSUB rd, rs, rt - Modular subtraction on an index value
*
* 3 2 1
* 10987654321098765432109876543210
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 x1010010101
* rt -----
* rs -----
* rd -----
uint64 rd1_value = extract_rdl_25_24(instruction);
int64 s_value = extract_s__se21_0_20_to_1_s1(instruction);
- std::string rd1 = GPR(encode_rd1_from_rd(rd1_value));
- std::string rtz4 = GPR(encode_gpr4_zero(rtz4_value));
+ std::string rd1 = GPR(decode_gpr_gpr1(rd1_value));
+ std::string rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value));
std::string s = ADDRESS(encode_s_from_address(s_value), 4);
return img::format("MOVE.BALC %s, %s, %s", rd1, rtz4, s);
uint64 rd2_value = extract_rd2_3_8(instruction);
uint64 rsz4_value = extract_rsz4_4_2_1_0(instruction);
- std::string rd2 = GPR(encode_rd2_reg1(rd2_value));
- std::string re2 = GPR(encode_rd2_reg2(rd2_value));
+ std::string rd2 = GPR(decode_gpr_gpr2_reg1(rd2_value));
+ std::string re2 = GPR(decode_gpr_gpr2_reg2(rd2_value));
/* !!!!!!!!!! - no conversion function */
- std::string rsz4 = GPR(encode_gpr4_zero(rsz4_value));
- std::string rtz4 = GPR(encode_gpr4_zero(rtz4_value));
+ std::string rsz4 = GPR(decode_gpr_gpr4_zero(rsz4_value));
+ std::string rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value));
return img::format("MOVEP %s, %s, %s, %s", rd2, re2, rsz4, rtz4);
/* hand edited */
uint64 rd2_value = extract_rd2_3_8(instruction);
uint64 rs4_value = extract_rs4_4_2_1_0(instruction);
- std::string rs4 = GPR(encode_gpr4(rs4_value));
- std::string rt4 = GPR(encode_gpr4(rt4_value));
- std::string rd2 = GPR(encode_rd2_reg1(rd2_value));
- std::string rs2 = GPR(encode_rd2_reg2(rd2_value));
+ std::string rs4 = GPR(decode_gpr_gpr4(rs4_value));
+ std::string rt4 = GPR(decode_gpr_gpr4(rt4_value));
+ std::string rd2 = GPR(decode_gpr_gpr2_reg1(rd2_value));
+ std::string rs2 = GPR(decode_gpr_gpr2_reg2(rd2_value));
/* !!!!!!!!!! - no conversion function */
return img::format("MOVEP %s, %s, %s, %s", rs4, rt4, rd2, rs2);
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MSUB ac, rs, rt - Multiply word and subtract from accumulator
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 10101010111111
* rt -----
* rs -----
- * rd -----
+ * ac --
*/
std::string NMD::MSUB_DSP_(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MSUBU ac, rs, rt - Multiply word and add to accumulator
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 11101010111111
* rt -----
* rs -----
- * rd -----
+ * ac --
*/
std::string NMD::MSUBU_DSP_(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MTHI rs, ac - Move to HI register
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
- * rt -----
+ * 001000xxxxx 10000001111111
* rs -----
- * rd -----
+ * ac --
*/
std::string NMD::MTHI_DSP_(uint64 instruction)
{
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rs = GPR(copy(rs_value));
std::string ac = AC(copy(ac_value));
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MTHLIP rs, ac - Copy LO to HI and a GPR to LO and increment pos by 32
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
- * rt -----
+ * 001000xxxxx 00001001111111
* rs -----
- * rd -----
+ * ac --
*/
std::string NMD::MTHLIP(uint64 instruction)
{
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rs = GPR(copy(rs_value));
std::string ac = AC(copy(ac_value));
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MTLO rs, ac - Move to LO register
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
- * rt -----
+ * 001000xxxxx 11000001111111
* rs -----
- * rd -----
+ * ac --
*/
std::string NMD::MTLO_DSP_(uint64 instruction)
{
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rs = GPR(copy(rs_value));
std::string ac = AC(copy(ac_value));
uint64 rt4_value = extract_rt4_9_7_6_5(instruction);
uint64 rs4_value = extract_rs4_4_2_1_0(instruction);
- std::string rs4 = GPR(encode_gpr4(rs4_value));
- std::string rt4 = GPR(encode_gpr4(rt4_value));
+ std::string rs4 = GPR(decode_gpr_gpr4(rs4_value));
+ std::string rt4 = GPR(decode_gpr_gpr4(rt4_value));
return img::format("MUL %s, %s", rs4, rt4);
}
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MUL.PH rd, rs, rt - Multiply vector integer half words to same size
+ * products
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 00000101101
* rt -----
* rs -----
* rd -----
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MUL_S.PH rd, rs, rt - Multiply vector integer half words to same size
+ * products (saturated)
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 10000101101
* rt -----
* rs -----
* rd -----
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MULEQ_S.W.PHL rd, rs, rt - Multiply vector fractional left halfwords
+ * to expanded width products
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 x0000100101
* rt -----
* rs -----
* rd -----
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MULEQ_S.W.PHR rd, rs, rt - Multiply vector fractional right halfwords
+ * to expanded width products
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 x0001100101
* rt -----
* rs -----
* rd -----
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MULEU_S.PH.QBL rd, rs, rt - Multiply vector fractional left bytes
+ * by halfwords to halfword products
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 x0010010101
* rt -----
* rs -----
* rd -----
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MULEU_S.PH.QBR rd, rs, rt - Multiply vector fractional right bytes
+ * by halfwords to halfword products
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 x0011010101
* rt -----
* rs -----
* rd -----
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MULQ_RS.PH rd, rs, rt - Multiply vector fractional halfwords
+ * to fractional halfword products
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 x0100010101
* rt -----
* rs -----
* rd -----
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MULQ_RS.W rd, rs, rt - Multiply fractional words to same size
+ * product with saturation and rounding
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 x0110010101
* rt -----
* rs -----
* rd -----
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MULQ_S.PH rd, rs, rt - Multiply fractional halfwords to same size
+ * products
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 x0101010101
* rt -----
* rs -----
* rd -----
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MULQ_S.W rd, rs, rt - Multiply fractional words to same size product
+ * with saturation
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 x0111010101
* rt -----
* rs -----
* rd -----
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MULSA.W.PH ac, rs, rt - Multiply and subtract vector integer halfword
+ * elements and accumulate
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 10110010111111
* rt -----
* rs -----
- * rd -----
+ * ac --
*/
std::string NMD::MULSA_W_PH(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MULSAQ_S.W.PH ac, rs, rt - Multiply and subtract vector fractional
+ * halfwords and accumulate
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 11110010111111
* rt -----
* rs -----
- * rd -----
+ * ac --
*/
std::string NMD::MULSAQ_S_W_PH(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MULT ac, rs, rt - Multiply word
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 00110010111111
* rt -----
* rs -----
- * rd -----
+ * ac --
*/
std::string NMD::MULT_DSP_(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] MULTU ac, rs, rt - Multiply unsigned word
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 01110010111111
* rt -----
* rs -----
- * rd -----
+ * ac --
*/
std::string NMD::MULTU_DSP_(uint64 instruction)
{
uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string ac = AC(copy(ac_value));
std::string rs = GPR(copy(rs_value));
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] PACKRL.PH rd, rs, rt - Pack a word using the right halfword from one
+ * source register and left halfword from another source register
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] PICK.PH rd, rs, rt - Pick a vector of halfwords based on condition
+ * code bits
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] PICK.QB rd, rs, rt - Pick a vector of byte values based on condition
+ * code bits
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] PRECEQ.W.PHL rt, rs - Expand the precision of the left-most element
+ * of a paired halfword
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] PRECEQ.W.PHR rt, rs - Expand the precision of the right-most element
+ * of a paired halfword
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] PRECEQU.PH.QBLA rt, rs - Expand the precision of the two
+ * left-alternate elements of a quad byte vector
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] PRECEQU.PH.QBL rt, rs - Expand the precision of the two left-most
+ * elements of a quad byte vector
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] PRECEQU.PH.QBRA rt, rs - Expand the precision of the two
+ * right-alternate elements of a quad byte vector
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] PRECEQU.PH.QBR rt, rs - Expand the precision of the two right-most
+ * elements of a quad byte vector
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] PRECEU.PH.QBLA rt, rs - Expand the precision of the two
+ * left-alternate elements of a quad byte vector to four unsigned
+ * halfwords
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] PRECEU.PH.QBL rt, rs - Expand the precision of the two left-most
+ * elements of a quad byte vector to form unsigned halfwords
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] PRECEU.PH.QBRA rt, rs - Expand the precision of the two
+ * right-alternate elements of a quad byte vector to form four
+ * unsigned halfwords
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] PRECEU.PH.QBR rt, rs - Expand the precision of the two right-most
+ * elements of a quad byte vector to form unsigned halfwords
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ * [DSP] PRECR.QB.PH rd, rs, rt - Reduce the precision of four integer
+ * halfwords to four bytes
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 00010001101
+ * 001000 x0001101101
* rt -----
* rs -----
* rd -----
/*
- *
+ * [DSP] PRECR_SRA.PH.W rt, rs, sa - Reduce the precision of two integer
+ * words to halfwords after a right shift
*
* 3 2 1
* 10987654321098765432109876543210
/*
- *
+ * [DSP] PRECR_SRA_R.PH.W rt, rs, sa - Reduce the precision of two integer
+ * words to halfwords after a right shift with rounding
*
* 3 2 1
* 10987654321098765432109876543210
/*
- *
+ * [DSP] PRECRQ.PH.W rd, rs, rt - Reduce the precision of fractional
+ * words to fractional halfwords
*
* 3 2 1
* 10987654321098765432109876543210
/*
- *
+ * [DSP] PRECRQ.QB.PH rd, rs, rt - Reduce the precision of four fractional
+ * halfwords to four bytes
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 x0010101101
* rt -----
* rs -----
* rd -----
/*
- *
+ * [DSP] PRECRQ_RS.PH.W rd, rs, rt - Reduce the precision of fractional
+ * words to halfwords with rounding and saturation
*
* 3 2 1
* 10987654321098765432109876543210
/*
- *
+ * [DSP] PRECRQU_S.QB.PH rd, rs, rt - Reduce the precision of fractional
+ * halfwords to unsigned bytes with saturation
*
* 3 2 1
* 10987654321098765432109876543210
/*
- *
+ * [DSP] PREPEND rt, rs, sa - Right shift and prepend bits to the MSB
*
* 3 2 1
* 10987654321098765432109876543210
/*
- *
+ * [DSP] RADDU.W.QB rt, rs - Unsigned reduction add of vector quad bytes
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 1111000100111111
* rt -----
* rs -----
- * rd -----
*/
std::string NMD::RADDU_W_QB(uint64 instruction)
{
/*
- *
+ * [DSP] RDDSP rt, mask - Read DSPControl register fields to a GPR
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 00011001111111
* rt -----
- * rs -----
- * rd -----
+ * mask -------
*/
std::string NMD::RDDSP(uint64 instruction)
{
/*
- *
+ * [DSP] REPL.PH rd, s - Replicate immediate integer into all vector element
+ * positions
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 x0000111101
* rt -----
- * rs -----
- * rd -----
+ * s ----------
*/
std::string NMD::REPL_PH(uint64 instruction)
{
/*
- *
+ * [DSP] REPL.QB rd, u - Replicate immediate integer into all vector element
+ * positions
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 x010111111111
* rt -----
- * rs -----
- * rd -----
+ * u --------
*/
std::string NMD::REPL_QB(uint64 instruction)
{
/*
- *
+ * [DSP] REPLV.PH rt, rs - Replicate a halfword into all vector element
+ * positions
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 0000001100111111
* rt -----
* rs -----
- * rd -----
*/
std::string NMD::REPLV_PH(uint64 instruction)
{
/*
- *
+ * [DSP] REPLV.QB rt, rs - Replicate byte into all vector element positions
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 x1110000101
+ * 001000 0001001100111111
* rt -----
* rs -----
- * rd -----
*/
std::string NMD::REPLV_QB(uint64 instruction)
{
uint64 rs3_value = extract_rs3_6_5_4(instruction);
uint64 u_value = extract_u_1_0(instruction);
- std::string rtz3 = GPR(encode_gpr3_store(rtz3_value));
+ std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value));
std::string u = IMMEDIATE(copy(u_value));
std::string rs3 = GPR(decode_gpr_gpr3(rs3_value));
uint64 rs3_value = extract_rs3_6_5_4(instruction);
uint64 u_value = extract_u_2_1__s1(instruction);
- std::string rtz3 = GPR(encode_gpr3_store(rtz3_value));
+ std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value));
std::string u = IMMEDIATE(copy(u_value));
std::string rs3 = GPR(decode_gpr_gpr3(rs3_value));
/*
- * SHILO ac, shift - Shift an Accumulator Value Leaving the Result in the Same
- * Accumulator
+ * [DSP] SHILO ac, shift - Shift an accumulator value leaving the result in
+ * the same accumulator
*
* 3 2 1
* 10987654321098765432109876543210
std::string NMD::SHILO(uint64 instruction)
{
int64 shift_value = extract_shift__se5_21_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string shift = IMMEDIATE(copy(shift_value));
std::string ac = AC(copy(ac_value));
/*
- * SHILOV ac, rs - Variable Shift of Accumulator Value Leaving the Result in
- * the Same Accumulator
+ * [DSP] SHILOV ac, rs - Variable shift of accumulator value leaving the result
+ * in the same accumulator
*
* 3 2 1
* 10987654321098765432109876543210
std::string NMD::SHILOV(uint64 instruction)
{
uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
- uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 ac_value = extract_ac_15_14(instruction);
std::string rs = GPR(copy(rs_value));
std::string ac = AC(copy(ac_value));
/*
- * SHLL.PH rt, rs, sa - Shift Left Logical Vector Pair Halfwords
+ * [DSP] SHLL.PH rt, rs, sa - Shift left logical vector pair halfwords
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * SHLL.QB rt, rs, sa - Shift Left Logical Vector Quad Bytes
+ * [DSP] SHLL.QB rt, rs, sa - Shift left logical vector quad bytes
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * SHLL_S.PH rt, rs, sa - Shift Left Logical Vector Pair Halfwords (saturated)
+ * [DSP] SHLL_S.PH rt, rs, sa - Shift left logical vector pair halfwords
+ * with saturation
*
* 3 2 1
* 10987654321098765432109876543210
/*
- *
+ * [DSP] SHLL_S.PH rt, rs, sa - Shift left logical word with saturation
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 01001001101
+ * 001000 x1111110101
* rt -----
* rs -----
- * rd -----
+ * sa -----
*/
std::string NMD::SHLL_S_W(uint64 instruction)
{
/*
- *
+ * [DSP] SHLLV.PH rd, rt, rs - Shift left logical variable vector pair
+ * halfwords
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 01001001101
+ * 001000 01110001101
* rt -----
* rs -----
* rd -----
/*
- *
+ * [DSP] SHLLV_S.QB rd, rt, rs - Shift left logical variable vector quad bytes
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 01001001101
+ * 001000 x1110010101
* rt -----
* rs -----
* rd -----
/*
- *
+ * [DSP] SHLLV.PH rd, rt, rs - Shift left logical variable vector pair
+ * halfwords with saturation
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 01001001101
+ * 001000 11110001101
* rt -----
* rs -----
* rd -----
/*
- *
+ * [DSP] SHLLV_S.W rd, rt, rs - Shift left logical variable vector word
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 01001001101
+ * 001000 x1111010101
* rt -----
* rs -----
* rd -----
/*
- *
+ * [DSP] SHRL.PH rt, rs, sa - Shift right logical two halfwords
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 01001001101
+ * 001000 001111111111
* rt -----
* rs -----
- * rd -----
+ * sa ----
*/
std::string NMD::SHRL_PH(uint64 instruction)
{
/*
- *
+ * [DSP] SHRL.QB rt, rs, sa - Shift right logical vector quad bytes
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 01001001101
+ * 001000 1100001111111
* rt -----
* rs -----
- * rd -----
+ * sa ---
*/
std::string NMD::SHRL_QB(uint64 instruction)
{
/*
- *
+ * [DSP] SHLLV.PH rd, rt, rs - Shift right logical variable vector pair of
+ * halfwords
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 01001001101
+ * 001000 x1100010101
* rt -----
* rs -----
* rd -----
/*
- *
+ * [DSP] SHLLV.QB rd, rt, rs - Shift right logical variable vector quad bytes
*
* 3 2 1
* 10987654321098765432109876543210
- * 001000 01001001101
+ * 001000 x1101010101
* rt -----
* rs -----
* rd -----
/*
- * SUBQH.PH rd, rt, rs - Subtract Fractional Halfword Vectors And Shift Right
- * to Halve Results
+ * [DSP] SUBQ.S.PH rd, rt, rs - Subtract fractional halfword vectors and shift
+ * right to halve results
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * SUBQH.PH rd, rt, rs - Subtract Fractional Halfword Vectors And Shift Right
- * to Halve Results
+ * [DSP] SUBQ.S.W rd, rt, rs - Subtract fractional halfword vectors and shift
+ * right to halve results
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * SUBQH.PH rd, rt, rs - Subtract Fractional Halfword Vectors And Shift Right
- * to Halve Results
+ * [DSP] SUBQH.PH rd, rt, rs - Subtract fractional halfword vectors and shift
+ * right to halve results
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * SUBQH.PH rd, rt, rs - Subtract Fractional Halfword Vectors And Shift Right
- * to Halve Results
+ * [DSP] SUBQH_R.PH rd, rt, rs - Subtract fractional halfword vectors and shift
+ * right to halve results
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * SUBQH_R.PH rd, rt, rs - Subtract Fractional Halfword Vectors And Shift Right
- * to Halve Results (rounding)
+ * [DSP] SUBQH_R.W rd, rt, rs - Subtract fractional halfword vectors and shift
+ * right to halve results with rounding
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * SUBQH.W rd, rs, rt - Subtract Fractional Words And Shift Right to Halve
- * Results
+ * [DSP] SUBQH.W rd, rs, rt - Subtract fractional words and shift right to
+ * halve results
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * SUBU.PH rd, rs, rt - Subtract Unsigned Integer Halfwords
+ * [DSP] SUBU.PH rd, rs, rt - Subtract unsigned unsigned halfwords
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * SUBU.QB rd, rs, rt - Subtract Unsigned Quad Byte Vector
+ * [DSP] SUBU.QB rd, rs, rt - Subtract unsigned quad byte vectors
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * SUBU_S.PH rd, rs, rt - Subtract Unsigned Integer Halfwords (saturating)
+ * [DSP] SUBU_S.PH rd, rs, rt - Subtract unsigned unsigned halfwords with
+ * 8-bit saturation
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * SUBU_S.QB rd, rs, rt - Subtract Unsigned Quad Byte Vector (saturating)
+ * [DSP] SUBU_S.QB rd, rs, rt - Subtract unsigned quad byte vectors with
+ * 8-bit saturation
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * SUBUH.QB rd, rs, rt - Subtract Unsigned Bytes And Right Shift to Halve
- * Results
+ * [DSP] SUBUH.QB rd, rs, rt - Subtract unsigned bytes and right shift
+ * to halve results
*
* 3 2 1
* 10987654321098765432109876543210
/*
- * SUBUH_R.QB rd, rs, rt - Subtract Unsigned Bytes And Right Shift to Halve
- * Results (rounding)
+ * [DSP] SUBUH_R.QB rd, rs, rt - Subtract unsigned bytes and right shift
+ * to halve results with rounding
*
* 3 2 1
* 10987654321098765432109876543210
uint64 rs3_value = extract_rs3_6_5_4(instruction);
uint64 u_value = extract_u_3_2_1_0__s2(instruction);
- std::string rtz3 = GPR(encode_gpr3_store(rtz3_value));
+ std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value));
std::string u = IMMEDIATE(copy(u_value));
std::string rs3 = GPR(decode_gpr_gpr3(rs3_value));
uint64 rs4_value = extract_rs4_4_2_1_0(instruction);
uint64 u_value = extract_u_3_8__s2(instruction);
- std::string rtz4 = GPR(encode_gpr4_zero(rtz4_value));
+ std::string rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value));
std::string u = IMMEDIATE(copy(u_value));
- std::string rs4 = GPR(encode_gpr4(rs4_value));
+ std::string rs4 = GPR(decode_gpr_gpr4(rs4_value));
return img::format("SW %s, %s(%s)", rtz4, u, rs4);
}
uint64 u_value = extract_u_6_5_4_3_2_1_0__s2(instruction);
uint64 rtz3_value = extract_rtz3_9_8_7(instruction);
- std::string rtz3 = GPR(encode_gpr3_store(rtz3_value));
+ std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value));
std::string u = IMMEDIATE(copy(u_value));
return img::format("SW %s, %s($%d)", rtz3, u, 28);
/*
- * WRDSP rt, mask - Write Fields to DSPControl Register from a GPR
+ * [DSP] WRDSP rt, mask - Write selected fields from a GPR to the DSPControl
+ * register
*
* 3 2 1
* 10987654321098765432109876543210
+/*
+ * nanoMIPS instruction pool organization
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *
+ * ┌─ P.ADDIU ─── P.RI ─── P.SYSCALL
+ * │
+ * │ ┌─ P.TRAP
+ * │ │
+ * │ ┌─ _POOL32A0_0 ─┼─ P.CMOVE
+ * │ │ │
+ * │ │ └─ P.SLTU
+ * │ ┌─ _POOL32A0 ─┤
+ * │ │ │
+ * │ │ │
+ * │ │ └─ _POOL32A0_1 ─── CRC32
+ * │ │
+ * ├─ P32A ─┤
+ * │ │ ┌─ PP.LSX
+ * │ │ ┌─ P.LSX ─────┤
+ * │ │ │ └─ PP.LSXS
+ * │ └─ _POOL32A7 ─┤
+ * │ │ ┌─ POOL32Axf_4
+ * │ └─ POOL32Axf ─┤
+ * │ └─ POOL32Axf_5
+ * │
+ * ├─ PBAL
+ * │
+ * ├─ P.GP.W ┌─ PP.LSX
+ * ┌─ P32 ─┤ │
+ * │ ├─ P.GP.BH ─┴─ PP.LSXS
+ * │ │
+ * │ ├─ P.J ─────── PP.BALRSC
+ * │ │
+ * │ ├─ P48I
+ * │ │ ┌─ P.SR
+ * │ │ │
+ * │ │ ├─ P.SHIFT
+ * │ │ │
+ * │ ├─ P.U12 ───┼─ P.ROTX
+ * │ │ │
+ * │ │ ├─ P.INS
+ * │ │ │
+ * │ │ └─ P.EXT
+ * │ │
+ * │ ├─ P.LS.U12 ── P.PREF.U12
+ * │ │
+ * │ ├─ P.BR1 ───── P.BR3A
+ * │ │
+ * │ │ ┌─ P.LS.S0 ─── P16.SYSCALL
+ * │ │ │
+ * │ │ │ ┌─ P.LL
+ * │ │ ├─ P.LS.S1 ─┤
+ * │ │ │ └─ P.SC
+ * │ │ │
+ * │ │ │ ┌─ P.PREFE
+ * MAJOR ─┤ ├─ P.LS.S9 ─┤ │
+ * │ │ ├─ P.LS.E0 ─┼─ P.LLE
+ * │ │ │ │
+ * │ │ │ └─ P.SCE
+ * │ │ │
+ * │ │ ├─ P.LS.WM
+ * │ │ │
+ * │ │ └─ P.LS.UAWM
+ * │ │
+ * │ │
+ * │ ├─ P.BR2
+ * │ │
+ * │ ├─ P.BRI
+ * │ │
+ * │ └─ P.LUI
+ * │
+ * │
+ * │ ┌─ P16.MV ──── P16.RI ─── P16.SYSCALL
+ * │ │
+ * │ ├─ P16.SR
+ * │ │
+ * │ ├─ P16.SHIFT
+ * │ │
+ * │ ├─ P16.4x4
+ * │ │
+ * │ ├─ P16C ────── POOL16C_0 ── POOL16C_00
+ * │ │
+ * └─ P16 ─┼─ P16.LB
+ * │
+ * ├─ P16.A1
+ * │
+ * ├─ P16.LH
+ * │
+ * ├─ P16.A2 ──── P.ADDIU[RS5]
+ * │
+ * ├─ P16.ADDU
+ * │
+ * └─ P16.BR ──┬─ P16.JRC
+ * │
+ * └─ P16.BR1
+ *
+ *
+ * (FP, DPS, and some minor instruction pools are omitted from the diagram)
+ *
+ */
+
NMD::Pool NMD::P_SYSCALL[2] = {
{ instruction , 0 , 0 , 32,
0xfffc0000, 0x00080000, &NMD::SYSCALL_32_ , 0,