[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] This patch implements several Octeon +/II instructions.
From: |
owl129 |
Subject: |
[PATCH] This patch implements several Octeon +/II instructions. |
Date: |
Fri, 19 Jan 2024 04:56:27 +0000 |
From: owl <owl129@126.com>
Octeon+
- SAA
- SAAD
Octeon2
- LAI
- LAID
- LAD
- LADD
- LAS
- LASD
- LAC
- LACD
- LAA
- LAAD
- LAW
- LAWD
- LWX
- LHX
- LDX
- LBUX
- LWUX
- LHUX
- LBX
Signed-off-by: owl <owl129@126.com>
---
target/mips/tcg/octeon.decode | 35 ++++
target/mips/tcg/octeon_translate.c | 281 +++++++++++++++++++++++++++++
2 files changed, 316 insertions(+)
diff --git a/target/mips/tcg/octeon.decode b/target/mips/tcg/octeon.decode
index 0c787cb498..980ed619d0 100644
--- a/target/mips/tcg/octeon.decode
+++ b/target/mips/tcg/octeon.decode
@@ -39,3 +39,38 @@ CINS 011100 ..... ..... ..... ..... 11001 . @bitfield
POP 011100 rs:5 00000 rd:5 00000 10110 dw:1
SEQNE 011100 rs:5 rt:5 rd:5 00000 10101 ne:1
SEQNEI 011100 rs:5 rt:5 imm:s10 10111 ne:1
+
+
+# SAA rt, (base)
+# SAAD rt, (base)
+SAA 011100 base:5 rt:5 00000 00000 011000
+SAAD 011100 base:5 rt:5 00000 00000 011001
+
+LAI 011100 ..... ..... ..... 00010 011111 @r3
+LAID 011100 ..... ..... ..... 00011 011111 @r3
+LAD 011100 ..... ..... ..... 00110 011111 @r3
+LADD 011100 ..... ..... ..... 00111 011111 @r3
+LAS 011100 ..... ..... ..... 01010 011111 @r3
+LASD 011100 ..... ..... ..... 01011 011111 @r3
+LAC 011100 ..... ..... ..... 01110 011111 @r3
+LACD 011100 ..... ..... ..... 01111 011111 @r3
+LAA 011100 ..... ..... ..... 10010 011111 @r3
+LAAD 011100 ..... ..... ..... 10011 011111 @r3
+LAW 011100 ..... ..... ..... 10110 011111 @r3
+LAWD 011100 ..... ..... ..... 10111 011111 @r3
+
+
+# LWX
+# LHX
+# LDX
+# LBUX
+# LWUX
+# LHUX
+# LBX
+LWX 011111 ..... ..... ..... 00000 001010 @r3
+LHX 011111 ..... ..... ..... 00100 001010 @r3
+LDX 011111 ..... ..... ..... 01000 001010 @r3
+LBUX 011111 ..... ..... ..... 00110 001010 @r3
+LWUX 011111 ..... ..... ..... 10000 001010 @r3
+LHUX 011111 ..... ..... ..... 10100 001010 @r3
+LBX 011111 ..... ..... ..... 10110 001010 @r3
\ No newline at end of file
diff --git a/target/mips/tcg/octeon_translate.c
b/target/mips/tcg/octeon_translate.c
index e25c4cbaa0..e9ec372ad3 100644
--- a/target/mips/tcg/octeon_translate.c
+++ b/target/mips/tcg/octeon_translate.c
@@ -174,3 +174,284 @@ static bool trans_SEQNEI(DisasContext *ctx, arg_SEQNEI *a)
}
return true;
}
+
+/*
+ * Octeon+
+ * https://sourceware.org/legacy-ml/binutils/2011-11/msg00085.html
+ */
+static bool trans_SAA(DisasContext *ctx, arg_SAA *a)
+{
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_qemu_ld_tl(t0, cpu_gpr[a->base], ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+ tcg_gen_add_tl(t0, t0, cpu_gpr[a->rt]);
+
+ tcg_gen_qemu_st_tl(t0, cpu_gpr[a->base], ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+ return true;
+}
+
+static bool trans_SAAD(DisasContext *ctx, arg_SAAD *a)
+{
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ tcg_gen_qemu_ld_tl(t0, cpu_gpr[a->base], ctx->mem_idx, MO_TEUQ |
+ ctx->default_tcg_memop_mask);
+ tcg_gen_add_tl(t0, t0, cpu_gpr[a->rt]);
+
+ tcg_gen_qemu_st_tl(t0, cpu_gpr[a->base], ctx->mem_idx, MO_TEUQ |
+ ctx->default_tcg_memop_mask);
+ return true;
+}
+
+/*
+ * Octeon2
+ *
https://chromium.googlesource.com/chromiumos/third_party/gdb/+/refs/heads/master/opcodes/mips-opc.c
+ * https://github.com/MarvellEmbeddedProcessors/Octeon-Toolchain
+ * https://bugs.kde.org/show_bug.cgi?id=326444
+ * https://gcc.gnu.org/legacy-ml/gcc-patches/2011-12/msg01134.html
+ */
+static bool trans_LAI(DisasContext *ctx, arg_LAI *a)
+{
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_qemu_ld_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+ gen_store_gpr(t0, a->rd);
+ tcg_gen_addi_tl(t0, t0, 1);
+
+ tcg_gen_qemu_st_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+ return true;
+}
+
+static bool trans_LAID(DisasContext *ctx, arg_LAID *a)
+{
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ tcg_gen_qemu_ld_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUQ |
+ ctx->default_tcg_memop_mask);
+ gen_store_gpr(t0, a->rd);
+ tcg_gen_addi_tl(t0, t0, 1);
+
+ tcg_gen_qemu_st_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUQ |
+ ctx->default_tcg_memop_mask);
+ return true;
+}
+
+static bool trans_LAD(DisasContext *ctx, arg_LAD *a)
+{
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_qemu_ld_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+ gen_store_gpr(t0, a->rd);
+ tcg_gen_subi_tl(t0, t0, 1);
+
+ tcg_gen_qemu_st_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+ return true;
+}
+
+static bool trans_LADD(DisasContext *ctx, arg_LADD *a)
+{
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ tcg_gen_qemu_ld_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUQ |
+ ctx->default_tcg_memop_mask);
+ gen_store_gpr(t0, a->rd);
+ tcg_gen_subi_tl(t0, t0, 1);
+
+ tcg_gen_qemu_st_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUQ |
+ ctx->default_tcg_memop_mask);
+ return true;
+}
+/* Load Atomic Set Word - LAS; Cavium OCTEON2 */
+static bool trans_LAS(DisasContext *ctx, arg_LAS *a)
+{
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_qemu_ld_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+ gen_store_gpr(t0, a->rd);
+ tcg_gen_movi_tl(t0, 0xffffffff);
+
+ tcg_gen_qemu_st_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+
+ return true;
+}
+/* Load Atomic Set Doubleword - LASD; Cavium OCTEON2 */
+static bool trans_LASD(DisasContext *ctx, arg_LASD *a)
+{
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ tcg_gen_qemu_ld_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUQ |
+ ctx->default_tcg_memop_mask);
+ gen_store_gpr(t0, a->rd);
+ tcg_gen_movi_tl(t0, 0xffffffffffffffffULL);
+
+ tcg_gen_qemu_st_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUQ |
+ ctx->default_tcg_memop_mask);
+ return true;
+}
+/* Load Atomic Clear Word - LAC; Cavium OCTEON2 */
+static bool trans_LAC(DisasContext *ctx, arg_LAC *a)
+{
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_qemu_ld_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+ gen_store_gpr(t0, a->rd);
+ tcg_gen_movi_tl(t0, 0);
+
+ tcg_gen_qemu_st_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+ return true;
+}
+/* Load Atomic Clear Doubleword - LACD; Cavium OCTEON2 */
+static bool trans_LACD(DisasContext *ctx, arg_LACD *a)
+{
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ tcg_gen_qemu_ld_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUQ |
+ ctx->default_tcg_memop_mask);
+ gen_store_gpr(t0, a->rd);
+ tcg_gen_movi_tl(t0, 0xffffffffffffffffULL);
+
+ tcg_gen_qemu_st_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUQ |
+ ctx->default_tcg_memop_mask);
+ return true;
+}
+
+/* Load Atomic Add Word - LAA; Cavium OCTEON2 */
+static bool trans_LAA(DisasContext *ctx, arg_LAA *a)
+{
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_qemu_ld_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+ gen_store_gpr(t0, a->rd);
+ tcg_gen_add_tl(t0, t0, cpu_gpr[a->rt]);
+
+ tcg_gen_qemu_st_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+ return true;
+}
+
+/* Load Atomic Add Doubleword - LAAD; Cavium OCTEON2 */
+static bool trans_LAAD(DisasContext *ctx, arg_LAAD *a)
+{
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ tcg_gen_qemu_ld_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUQ |
+ ctx->default_tcg_memop_mask);
+ gen_store_gpr(t0, a->rd);
+ tcg_gen_add_tl(t0, t0, cpu_gpr[a->rt]);
+
+ tcg_gen_qemu_st_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUQ |
+ ctx->default_tcg_memop_mask);
+ return true;
+}
+/* Load Atomic Swap Word - LAW; Cavium OCTEON2 */
+static bool trans_LAW(DisasContext *ctx, arg_LAW *a)
+{
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_qemu_ld_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+ gen_store_gpr(t0, a->rd);
+ tcg_gen_mov_tl(t0, cpu_gpr[a->rt]);
+
+ tcg_gen_qemu_st_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+ return true;
+}
+
+static bool trans_LAWD(DisasContext *ctx, arg_LAWD *a)
+{
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ tcg_gen_qemu_ld_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUQ |
+ ctx->default_tcg_memop_mask);
+ gen_store_gpr(t0, a->rd);
+ tcg_gen_mov_tl(t0, cpu_gpr[a->rt]);
+
+ tcg_gen_qemu_st_tl(t0, cpu_gpr[a->rs], ctx->mem_idx, MO_TEUQ |
+ ctx->default_tcg_memop_mask);
+ return true;
+}
+
+
+static bool trans_LWX(DisasContext *ctx, arg_LWX *a)
+{
+ TCGv t0 = tcg_temp_new();
+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rs], cpu_gpr[a->rt]);
+
+ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
+ ctx->default_tcg_memop_mask);
+
+ /* on mips64, 32 extend to 64 */
+ tcg_gen_ext32s_tl(cpu_gpr[a->rd], t0);
+ return true;
+}
+
+static bool trans_LHX(DisasContext *ctx, arg_LHX *a)
+{
+ TCGv t0 = tcg_temp_new();
+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rs], cpu_gpr[a->rt]);
+
+ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
+ ctx->default_tcg_memop_mask);
+
+ /* 16 extend to 32/64 */
+ tcg_gen_ext16s_tl(cpu_gpr[a->rd], t0);
+ return true;
+}
+
+static bool trans_LDX(DisasContext *ctx, arg_LDX *a)
+{
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rs], cpu_gpr[a->rt]);
+
+ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESQ |
+ ctx->default_tcg_memop_mask);
+ /* not extend */
+ gen_store_gpr(t0, a->rd);
+ return true;
+}
+
+static bool trans_LBUX(DisasContext *ctx, arg_LBUX *a)
+{
+ TCGv t0 = tcg_temp_new();
+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rs], cpu_gpr[a->rt]);
+
+ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB |
+ ctx->default_tcg_memop_mask);
+
+ tcg_gen_ext8u_tl(cpu_gpr[a->rd], t0);
+ return true;
+}
+
+static bool trans_LWUX(DisasContext *ctx, arg_LWUX *a)
+{
+ TCGv t0 = tcg_temp_new();
+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rs], cpu_gpr[a->rt]);
+
+ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+
+ tcg_gen_ext32u_tl(cpu_gpr[a->rd], t0);
+ return true;
+}
+
+static bool trans_LHUX(DisasContext *ctx, arg_LHUX *a)
+{
+ TCGv t0 = tcg_temp_new();
+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rs], cpu_gpr[a->rt]);
+
+ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
+ ctx->default_tcg_memop_mask);
+
+ tcg_gen_ext16u_tl(cpu_gpr[a->rd], t0);
+ return true;
+}
+
+static bool trans_LBX(DisasContext *ctx, arg_LBX *a)
+{
+ TCGv t0 = tcg_temp_new();
+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rs], cpu_gpr[a->rt]);
+
+ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB |
+ ctx->default_tcg_memop_mask);
+
+ tcg_gen_ext8s_tl(cpu_gpr[a->rd], t0);
+ return true;
+}
--
2.34.1
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] This patch implements several Octeon +/II instructions.,
owl129 <=