@samitouri / QOSamiQemu / commits / fe940ede75

target/mips: split Octeon SEQ/SNE decode

Decode the equality and inequality forms as explicit SEQ/SNE instructions rather than using shared generated SEQNE entries. The explicit decoder names match the architectural mnemonics, which makes the translator entry points and trace/debug output easier to correlate with the instruction set. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: James Hilliard <james.hilliard1@gmail.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> [PMD: Split SEQNE (this patch) vs SEQNEI] Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-Id: <20260520172313.23777-9-philmd@linaro.org>

James Hilliard committed Apr 20, 2026 at 21:27 UTC fe940ede756cc195c55fe6980562b89e565b6c13
3 files changed +52 -12
target/mips/tcg/octeon.decode
+2 -1
@@ -38,7 +38,8 @@ DMUL 011100 ..... ..... ..... 00000 000011 @r3
38 EXTS 011100 ..... ..... ..... ..... 11101 . @bitfield
39 CINS 011100 ..... ..... ..... ..... 11001 . @bitfield
40 POP 011100 rs:5 00000 rd:5 00000 10110 dw:1
41 -SEQNE 011100 rs:5 rt:5 rd:5 00000 10101 ne:1
41 +SEQ 011100 ..... ..... ..... 00000 101010 @r3
42 +SNE 011100 ..... ..... ..... 00000 101011 @r3
43 SEQNEI 011100 rs:5 rt:5 imm:s10 10111 ne:1
44
45 &lx base index rd
target/mips/tcg/octeon_translate.c
+14 -11
@@ -106,29 +106,32 @@ static bool trans_POP(DisasContext *ctx, arg_POP *a)
106 return true;
107 }
108
109 -static bool trans_SEQNE(DisasContext *ctx, arg_SEQNE *a)
109 +static bool do_seq_sne(DisasContext *ctx, const arg_decode_ext_octeon1 *a,
110 + TCGCond cond)
111 {
112 TCGv_i64 t0, t1;
113
113 - if (a->rd == 0) {
114 - /* nop */
115 - return true;
116 - }
117 -
114 t0 = tcg_temp_new_i64();
115 t1 = tcg_temp_new_i64();
116
117 gen_load_gpr(t0, a->rs);
118 gen_load_gpr(t1, a->rt);
119
124 - if (a->ne) {
125 - tcg_gen_setcond_i64(TCG_COND_NE, cpu_gpr[a->rd], t1, t0);
126 - } else {
127 - tcg_gen_setcond_i64(TCG_COND_EQ, cpu_gpr[a->rd], t1, t0);
128 - }
120 + tcg_gen_setcond_i64(cond, t0, t1, t0);
121 + gen_store_gpr(t0, a->rd);
122 return true;
123 }
124
125 +static bool trans_SEQ(DisasContext *ctx, arg_SEQ *a)
126 +{
127 + return do_seq_sne(ctx, a, TCG_COND_EQ);
128 +}
129 +
130 +static bool trans_SNE(DisasContext *ctx, arg_SNE *a)
131 +{
132 + return do_seq_sne(ctx, a, TCG_COND_NE);
133 +}
134 +
135 static bool trans_SEQNEI(DisasContext *ctx, arg_SEQNEI *a)
136 {
137 TCGv_i64 t0;
tests/tcg/mips/user/isa/octeon/octeon-insns.c
+36
@@ -54,11 +54,47 @@ static uint64_t octeon_dpop(uint64_t rs)
54 return rd;
55 }
56
57 +static uint64_t octeon_seq(uint64_t rs, uint64_t rt)
58 +{
59 + uint64_t rd;
60 +
61 + asm volatile(
62 + "move $8, %[rs]\n\t"
63 + "move $9, %[rt]\n\t"
64 + ".word 0x7109502a\n\t" /* seq $10, $8, $9 */
65 + "move %[rd], $10\n\t"
66 + : [rd] "=r" (rd)
67 + : [rs] "r" (rs), [rt] "r" (rt)
68 + : "$8", "$9", "$10");
69 +
70 + return rd;
71 +}
72 +
73 +static uint64_t octeon_sne(uint64_t rs, uint64_t rt)
74 +{
75 + uint64_t rd;
76 +
77 + asm volatile(
78 + "move $8, %[rs]\n\t"
79 + "move $9, %[rt]\n\t"
80 + ".word 0x7109502b\n\t" /* sne $10, $8, $9 */
81 + "move %[rd], $10\n\t"
82 + : [rd] "=r" (rd)
83 + : [rs] "r" (rs), [rt] "r" (rt)
84 + : "$8", "$9", "$10");
85 +
86 + return rd;
87 +}
88 +
89 int main(void)
90 {
91 assert(octeon_baddu(0x123, 0x0f0) == 0x13);
92 assert(octeon_dmul(0x12345678, 0x10) == 0x123456780);
93 assert(octeon_dpop(0xf0f0f0f0f0f0f0f0ULL) == 32);
94 + assert(octeon_seq(0xabc, 0xabc) == 1);
95 + assert(octeon_seq(0xabc, 0xdef) == 0);
96 + assert(octeon_sne(0xabc, 0xabc) == 0);
97 + assert(octeon_sne(0xabc, 0xdef) == 1);
98
99 return 0;
100 }