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
}