From: owl <owl...@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 <owl...@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