qemu-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]