[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 18/72] target/ppc: Move logical fixed-point instructions to decode
|
From: |
Nicholas Piggin |
|
Subject: |
[PULL 18/72] target/ppc: Move logical fixed-point instructions to decodetree. |
|
Date: |
Fri, 24 May 2024 09:06:51 +1000 |
From: Chinmay Rath <rathc@linux.ibm.com>
Moving the below instructions to decodetree specification :
andi[s]., {ori, xori}[s] : D-form
{and, andc, nand, or, orc, nor, xor, eqv}[.],
exts{b, h, w}[.], cnt{l, t}z{w, d}[.],
popcnt{b, w, d}, prty{w, d}, cmp, bpermd : X-form
With this patch, all the fixed-point logical instructions have been
moved to decodetree.
The changes were verified by validating that the tcg ops generated by those
instructions remain the same, which were captured with the '-d in_asm,op' flag.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Chinmay Rath <rathc@linux.ibm.com>
[np: 32-bit compile fix]
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/helper.h | 8 +-
target/ppc/insn32.decode | 38 +++
target/ppc/int_helper.c | 10 +-
target/ppc/translate.c | 359 ---------------------
target/ppc/translate/fixedpoint-impl.c.inc | 300 +++++++++++++++++
5 files changed, 347 insertions(+), 368 deletions(-)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index b8af2cf878..4267917615 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -58,8 +58,8 @@ DEF_HELPER_4(DIVDE, i64, env, i64, i64, i32)
DEF_HELPER_4(DIVWEU, tl, env, tl, tl, i32)
DEF_HELPER_4(DIVWE, tl, env, tl, tl, i32)
-DEF_HELPER_FLAGS_1(popcntb, TCG_CALL_NO_RWG_SE, tl, tl)
-DEF_HELPER_FLAGS_2(cmpb, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_1(POPCNTB, TCG_CALL_NO_RWG_SE, tl, tl)
+DEF_HELPER_FLAGS_2(CMPB, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_3(sraw, tl, env, tl, tl)
DEF_HELPER_FLAGS_2(CFUGED, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(PDEPD, TCG_CALL_NO_RWG_SE, i64, i64, i64)
@@ -68,8 +68,8 @@ DEF_HELPER_FLAGS_1(CDTBCD, TCG_CALL_NO_RWG_SE, tl, tl)
DEF_HELPER_FLAGS_1(CBCDTD, TCG_CALL_NO_RWG_SE, tl, tl)
#if defined(TARGET_PPC64)
DEF_HELPER_FLAGS_2(CMPEQB, TCG_CALL_NO_RWG_SE, i32, tl, tl)
-DEF_HELPER_FLAGS_1(popcntw, TCG_CALL_NO_RWG_SE, tl, tl)
-DEF_HELPER_FLAGS_2(bpermd, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+DEF_HELPER_FLAGS_1(POPCNTW, TCG_CALL_NO_RWG_SE, tl, tl)
+DEF_HELPER_FLAGS_2(BPERMD, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_3(srad, tl, env, tl, tl)
DEF_HELPER_FLAGS_0(DARN32, TCG_CALL_NO_RWG, tl)
DEF_HELPER_FLAGS_0(DARN64, TCG_CALL_NO_RWG, tl)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index cb1e4bd307..dc62bc90aa 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -35,6 +35,9 @@
&D rt ra si:int64_t
@D ...... rt:5 ra:5 si:s16 &D
+&D_ui rt ra ui:uint64_t
+@D_ui ...... rt:5 ra:5 ui:16 &D_ui
+
&D_bf bf l:bool ra imm
@D_bfs ...... bf:3 . l:1 ra:5 imm:s16 &D_bf
@D_bfu ...... bf:3 . l:1 ra:5 imm:16 &D_bf
@@ -102,6 +105,9 @@
&X_sa rs ra
@X_sa ...... rs:5 ra:5 ..... .......... . &X_sa
+&X_sa_rc rs ra rc
+@X_sa_rc ...... rs:5 ra:5 ..... .......... rc:1 &X_sa_rc
+
%x_frtp 22:4 !function=times_2
%x_frap 17:4 !function=times_2
%x_frbp 12:4 !function=times_2
@@ -419,6 +425,38 @@ MODUD 011111 ..... ..... ..... 0100001001 - @X
## Fixed-Point Logical Instructions
+ANDI_ 011100 ..... ..... ................ @D_ui
+ANDIS_ 011101 ..... ..... ................ @D_ui
+ORI 011000 ..... ..... ................ @D_ui
+ORIS 011001 ..... ..... ................ @D_ui
+XORI 011010 ..... ..... ................ @D_ui
+XORIS 011011 ..... ..... ................ @D_ui
+
+AND 011111 ..... ..... ..... 0000011100 . @X_rc
+ANDC 011111 ..... ..... ..... 0000111100 . @X_rc
+NAND 011111 ..... ..... ..... 0111011100 . @X_rc
+OR 011111 ..... ..... ..... 0110111100 . @X_rc
+ORC 011111 ..... ..... ..... 0110011100 . @X_rc
+NOR 011111 ..... ..... ..... 0001111100 . @X_rc
+XOR 011111 ..... ..... ..... 0100111100 . @X_rc
+EQV 011111 ..... ..... ..... 0100011100 . @X_rc
+CMPB 011111 ..... ..... ..... 0111111100 . @X_rc
+
+EXTSB 011111 ..... ..... ----- 1110111010 . @X_sa_rc
+EXTSH 011111 ..... ..... ----- 1110011010 . @X_sa_rc
+EXTSW 011111 ..... ..... ----- 1111011010 . @X_sa_rc
+CNTLZW 011111 ..... ..... ----- 0000011010 . @X_sa_rc
+CNTTZW 011111 ..... ..... ----- 1000011010 . @X_sa_rc
+CNTLZD 011111 ..... ..... ----- 0000111010 . @X_sa_rc
+CNTTZD 011111 ..... ..... ----- 1000111010 . @X_sa_rc
+POPCNTB 011111 ..... ..... ----- 0001111010 . @X_sa_rc
+
+POPCNTW 011111 ..... ..... ----- 0101111010 - @X_sa
+POPCNTD 011111 ..... ..... ----- 0111111010 - @X_sa
+PRTYW 011111 ..... ..... ----- 0010011010 - @X_sa
+PRTYD 011111 ..... ..... ----- 0010111010 - @X_sa
+
+BPERMD 011111 ..... ..... ..... 0011111100 - @X
CFUGED 011111 ..... ..... ..... 0011011100 - @X
CNTLZDM 011111 ..... ..... ..... 0000111011 - @X
CNTTZDM 011111 ..... ..... ..... 1000111011 - @X
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index d12dcc28e1..2c6b633d65 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -201,7 +201,7 @@ uint64_t helper_DARN64(void)
return ret;
}
-uint64_t helper_bpermd(uint64_t rs, uint64_t rb)
+uint64_t helper_BPERMD(uint64_t rs, uint64_t rb)
{
int i;
uint64_t ra = 0;
@@ -219,7 +219,7 @@ uint64_t helper_bpermd(uint64_t rs, uint64_t rb)
#endif
-target_ulong helper_cmpb(target_ulong rs, target_ulong rb)
+target_ulong helper_CMPB(target_ulong rs, target_ulong rb)
{
target_ulong mask = 0xff;
target_ulong ra = 0;
@@ -288,7 +288,7 @@ target_ulong helper_srad(CPUPPCState *env, target_ulong
value,
#endif
#if defined(TARGET_PPC64)
-target_ulong helper_popcntb(target_ulong val)
+target_ulong helper_POPCNTB(target_ulong val)
{
/* Note that we don't fold past bytes */
val = (val & 0x5555555555555555ULL) + ((val >> 1) &
@@ -300,7 +300,7 @@ target_ulong helper_popcntb(target_ulong val)
return val;
}
-target_ulong helper_popcntw(target_ulong val)
+target_ulong helper_POPCNTW(target_ulong val)
{
/* Note that we don't fold past words. */
val = (val & 0x5555555555555555ULL) + ((val >> 1) &
@@ -316,7 +316,7 @@ target_ulong helper_popcntw(target_ulong val)
return val;
}
#else
-target_ulong helper_popcntb(target_ulong val)
+target_ulong helper_POPCNTB(target_ulong val)
{
/* Note that we don't fold past bytes */
val = (val & 0x55555555) + ((val >> 1) & 0x55555555);
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index e1ccb82f10..2cfa7d37ee 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -1563,13 +1563,6 @@ static inline void gen_set_Rc0(DisasContext *ctx, TCGv
reg)
}
}
-/* cmpb: PowerPC 2.05 specification */
-static void gen_cmpb(DisasContext *ctx)
-{
- gen_helper_cmpb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
- cpu_gpr[rB(ctx->opcode)]);
-}
-
/*** Integer arithmetic ***/
static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
@@ -1888,82 +1881,6 @@ static inline void gen_op_arith_subf(DisasContext *ctx,
TCGv ret, TCGv arg1,
}
/*** Integer logical ***/
-#define GEN_LOGICAL2(name, tcg_op, opc, type) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], \
- cpu_gpr[rB(ctx->opcode)]); \
- if (unlikely(Rc(ctx->opcode) != 0)) \
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); \
-}
-
-#define GEN_LOGICAL1(name, tcg_op, opc, type) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); \
- if (unlikely(Rc(ctx->opcode) != 0)) \
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); \
-}
-
-/* and & and. */
-GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
-/* andc & andc. */
-GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
-
-/* andi. */
-static void gen_andi_(DisasContext *ctx)
-{
- tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
- UIMM(ctx->opcode));
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* andis. */
-static void gen_andis_(DisasContext *ctx)
-{
- tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
- UIMM(ctx->opcode) << 16);
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* cntlzw */
-static void gen_cntlzw(DisasContext *ctx)
-{
- TCGv_i32 t = tcg_temp_new_i32();
-
- tcg_gen_trunc_tl_i32(t, cpu_gpr[rS(ctx->opcode)]);
- tcg_gen_clzi_i32(t, t, 32);
- tcg_gen_extu_i32_tl(cpu_gpr[rA(ctx->opcode)], t);
-
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
- }
-}
-
-/* cnttzw */
-static void gen_cnttzw(DisasContext *ctx)
-{
- TCGv_i32 t = tcg_temp_new_i32();
-
- tcg_gen_trunc_tl_i32(t, cpu_gpr[rS(ctx->opcode)]);
- tcg_gen_ctzi_i32(t, t, 32);
- tcg_gen_extu_i32_tl(cpu_gpr[rA(ctx->opcode)], t);
-
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
- }
-}
-
-/* eqv & eqv. */
-GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
-/* extsb & extsb. */
-GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
-/* extsh & extsh. */
-GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
-/* nand & nand. */
-GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
-/* nor & nor. */
-GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
static void gen_pause(DisasContext *ctx)
@@ -1977,243 +1894,6 @@ static void gen_pause(DisasContext *ctx)
}
#endif /* defined(TARGET_PPC64) */
-/* or & or. */
-static void gen_or(DisasContext *ctx)
-{
- int rs, ra, rb;
-
- rs = rS(ctx->opcode);
- ra = rA(ctx->opcode);
- rb = rB(ctx->opcode);
- /* Optimisation for mr. ri case */
- if (rs != ra || rs != rb) {
- if (rs != rb) {
- tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
- } else {
- tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
- }
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[ra]);
- }
- } else if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rs]);
-#if defined(TARGET_PPC64)
- } else if (rs != 0) { /* 0 is nop */
- int prio = 0;
-
- switch (rs) {
- case 1:
- /* Set process priority to low */
- prio = 2;
- break;
- case 6:
- /* Set process priority to medium-low */
- prio = 3;
- break;
- case 2:
- /* Set process priority to normal */
- prio = 4;
- break;
-#if !defined(CONFIG_USER_ONLY)
- case 31:
- if (!ctx->pr) {
- /* Set process priority to very low */
- prio = 1;
- }
- break;
- case 5:
- if (!ctx->pr) {
- /* Set process priority to medium-hight */
- prio = 5;
- }
- break;
- case 3:
- if (!ctx->pr) {
- /* Set process priority to high */
- prio = 6;
- }
- break;
- case 7:
- if (ctx->hv && !ctx->pr) {
- /* Set process priority to very high */
- prio = 7;
- }
- break;
-#endif
- default:
- break;
- }
- if (prio) {
- TCGv t0 = tcg_temp_new();
- gen_load_spr(t0, SPR_PPR);
- tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
- tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
- gen_store_spr(SPR_PPR, t0);
- }
-#if !defined(CONFIG_USER_ONLY)
- /*
- * Pause out of TCG otherwise spin loops with smt_low eat too
- * much CPU and the kernel hangs. This applies to all
- * encodings other than no-op, e.g., miso(rs=26), yield(27),
- * mdoio(29), mdoom(30), and all currently undefined.
- */
- gen_pause(ctx);
-#endif
-#endif
- }
-}
-/* orc & orc. */
-GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
-
-/* xor & xor. */
-static void gen_xor(DisasContext *ctx)
-{
- /* Optimisation for "set to zero" case */
- if (rS(ctx->opcode) != rB(ctx->opcode)) {
- tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
- cpu_gpr[rB(ctx->opcode)]);
- } else {
- tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
- }
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
- }
-}
-
-/* ori */
-static void gen_ori(DisasContext *ctx)
-{
- target_ulong uimm = UIMM(ctx->opcode);
-
- if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
- return;
- }
- tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
-}
-
-/* oris */
-static void gen_oris(DisasContext *ctx)
-{
- target_ulong uimm = UIMM(ctx->opcode);
-
- if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
- /* NOP */
- return;
- }
- tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
- uimm << 16);
-}
-
-/* xori */
-static void gen_xori(DisasContext *ctx)
-{
- target_ulong uimm = UIMM(ctx->opcode);
-
- if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
- /* NOP */
- return;
- }
- tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
-}
-
-/* xoris */
-static void gen_xoris(DisasContext *ctx)
-{
- target_ulong uimm = UIMM(ctx->opcode);
-
- if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
- /* NOP */
- return;
- }
- tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
- uimm << 16);
-}
-
-/* popcntb : PowerPC 2.03 specification */
-static void gen_popcntb(DisasContext *ctx)
-{
- gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
-}
-
-static void gen_popcntw(DisasContext *ctx)
-{
-#if defined(TARGET_PPC64)
- gen_helper_popcntw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
-#else
- tcg_gen_ctpop_i32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
-#endif
-}
-
-#if defined(TARGET_PPC64)
-/* popcntd: PowerPC 2.06 specification */
-static void gen_popcntd(DisasContext *ctx)
-{
- tcg_gen_ctpop_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
-}
-#endif
-
-/* prtyw: PowerPC 2.05 specification */
-static void gen_prtyw(DisasContext *ctx)
-{
- TCGv ra = cpu_gpr[rA(ctx->opcode)];
- TCGv rs = cpu_gpr[rS(ctx->opcode)];
- TCGv t0 = tcg_temp_new();
- tcg_gen_shri_tl(t0, rs, 16);
- tcg_gen_xor_tl(ra, rs, t0);
- tcg_gen_shri_tl(t0, ra, 8);
- tcg_gen_xor_tl(ra, ra, t0);
- tcg_gen_andi_tl(ra, ra, (target_ulong)0x100000001ULL);
-}
-
-#if defined(TARGET_PPC64)
-/* prtyd: PowerPC 2.05 specification */
-static void gen_prtyd(DisasContext *ctx)
-{
- TCGv ra = cpu_gpr[rA(ctx->opcode)];
- TCGv rs = cpu_gpr[rS(ctx->opcode)];
- TCGv t0 = tcg_temp_new();
- tcg_gen_shri_tl(t0, rs, 32);
- tcg_gen_xor_tl(ra, rs, t0);
- tcg_gen_shri_tl(t0, ra, 16);
- tcg_gen_xor_tl(ra, ra, t0);
- tcg_gen_shri_tl(t0, ra, 8);
- tcg_gen_xor_tl(ra, ra, t0);
- tcg_gen_andi_tl(ra, ra, 1);
-}
-#endif
-
-#if defined(TARGET_PPC64)
-/* bpermd */
-static void gen_bpermd(DisasContext *ctx)
-{
- gen_helper_bpermd(cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
-}
-#endif
-
-#if defined(TARGET_PPC64)
-/* extsw & extsw. */
-GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
-
-/* cntlzd */
-static void gen_cntlzd(DisasContext *ctx)
-{
- tcg_gen_clzi_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 64);
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
- }
-}
-
-/* cnttzd */
-static void gen_cnttzd(DisasContext *ctx)
-{
- tcg_gen_ctzi_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 64);
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
- }
-}
-#endif
-
/*** Integer rotate ***/
/* rlwimi & rlwimi. */
@@ -5942,30 +5622,9 @@ GEN_HANDLER_E(brw, 0x1F, 0x1B, 0x04, 0x0000F801,
PPC_NONE, PPC2_ISA310),
GEN_HANDLER_E(brh, 0x1F, 0x1B, 0x06, 0x0000F801, PPC_NONE, PPC2_ISA310),
#endif
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
-GEN_HANDLER_E(cmpb, 0x1F, 0x1C, 0x0F, 0x00000001, PPC_NONE, PPC2_ISA205),
-GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
-GEN_HANDLER_E(cnttzw, 0x1F, 0x1A, 0x10, 0x00000000, PPC_NONE, PPC2_ISA300),
GEN_HANDLER_E(copy, 0x1F, 0x06, 0x18, 0x03C00001, PPC_NONE, PPC2_ISA300),
GEN_HANDLER_E(cp_abort, 0x1F, 0x06, 0x1A, 0x03FFF801, PPC_NONE, PPC2_ISA300),
GEN_HANDLER_E(paste, 0x1F, 0x06, 0x1C, 0x03C00000, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(popcntb, 0x1F, 0x1A, 0x03, 0x0000F801, PPC_POPCNTB),
-GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD),
-GEN_HANDLER_E(prtyw, 0x1F, 0x1A, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA205),
-#if defined(TARGET_PPC64)
-GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD),
-GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
-GEN_HANDLER_E(cnttzd, 0x1F, 0x1A, 0x11, 0x00000000, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E(prtyd, 0x1F, 0x1A, 0x05, 0x0000F801, PPC_NONE, PPC2_ISA205),
-GEN_HANDLER_E(bpermd, 0x1F, 0x1C, 0x07, 0x00000001, PPC_NONE,
PPC2_PERM_ISA206),
-#endif
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
@@ -6136,24 +5795,6 @@ GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001,
PPC_ALTIVEC),
GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
-#undef GEN_LOGICAL1
-#undef GEN_LOGICAL2
-#define GEN_LOGICAL2(name, tcg_op, opc, type) \
-GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)
-#define GEN_LOGICAL1(name, tcg_op, opc, type) \
-GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)
-GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER),
-GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER),
-GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER),
-GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER),
-GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER),
-GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER),
-GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER),
-GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER),
-#if defined(TARGET_PPC64)
-GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B),
-#endif
-
#if defined(TARGET_PPC64)
#undef GEN_PPC64_R2
#undef GEN_PPC64_R4
diff --git a/target/ppc/translate/fixedpoint-impl.c.inc
b/target/ppc/translate/fixedpoint-impl.c.inc
index 872fed664d..fa0191e866 100644
--- a/target/ppc/translate/fixedpoint-impl.c.inc
+++ b/target/ppc/translate/fixedpoint-impl.c.inc
@@ -856,6 +856,285 @@ TRANS(SETBCR, do_set_bool_cond, false, true)
TRANS(SETNBC, do_set_bool_cond, true, false)
TRANS(SETNBCR, do_set_bool_cond, true, true)
+/*
+ * Fixed-Point Logical Instructions
+ */
+
+static bool do_addi_(DisasContext *ctx, arg_D_ui *a, bool shift)
+{
+ tcg_gen_andi_tl(cpu_gpr[a->ra], cpu_gpr[a->rt], shift ? a->ui << 16 :
a->ui);
+ gen_set_Rc0(ctx, cpu_gpr[a->ra]);
+ return true;
+}
+
+static bool do_ori(DisasContext *ctx, arg_D_ui *a, bool shift)
+{
+ if (a->rt == a->ra && a->ui == 0) {
+ /* NOP */
+ return true;
+ }
+ tcg_gen_ori_tl(cpu_gpr[a->ra], cpu_gpr[a->rt], shift ? a->ui << 16 :
a->ui);
+ return true;
+}
+
+static bool do_xori(DisasContext *ctx, arg_D_ui *a, bool shift)
+{
+ if (a->rt == a->ra && a->ui == 0) {
+ /* NOP */
+ return true;
+ }
+ tcg_gen_xori_tl(cpu_gpr[a->ra], cpu_gpr[a->rt], shift ? a->ui << 16 :
a->ui);
+ return true;
+}
+
+static bool do_logical1(DisasContext *ctx, arg_X_sa_rc *a,
+ void (*helper)(TCGv, TCGv))
+{
+ helper(cpu_gpr[a->ra], cpu_gpr[a->rs]);
+ if (unlikely(a->rc)) {
+ gen_set_Rc0(ctx, cpu_gpr[a->ra]);
+ }
+ return true;
+}
+
+static bool do_logical2(DisasContext *ctx, arg_X_rc *a,
+ void (*helper)(TCGv, TCGv, TCGv))
+{
+ helper(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
+ if (unlikely(a->rc)) {
+ gen_set_Rc0(ctx, cpu_gpr[a->ra]);
+ }
+ return true;
+}
+
+static bool trans_OR(DisasContext *ctx, arg_OR *a)
+{
+ /* Optimisation for mr. ri case */
+ if (a->rt != a->ra || a->rt != a->rb) {
+ if (a->rt != a->rb) {
+ tcg_gen_or_tl(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
+ } else {
+ tcg_gen_mov_tl(cpu_gpr[a->ra], cpu_gpr[a->rt]);
+ }
+ if (unlikely(a->rc)) {
+ gen_set_Rc0(ctx, cpu_gpr[a->ra]);
+ }
+ } else if (unlikely(a->rc)) {
+ gen_set_Rc0(ctx, cpu_gpr[a->rt]);
+#if defined(TARGET_PPC64)
+ } else if (a->rt != 0) { /* 0 is nop */
+ int prio = 0;
+
+ switch (a->rt) {
+ case 1:
+ /* Set process priority to low */
+ prio = 2;
+ break;
+ case 6:
+ /* Set process priority to medium-low */
+ prio = 3;
+ break;
+ case 2:
+ /* Set process priority to normal */
+ prio = 4;
+ break;
+#if !defined(CONFIG_USER_ONLY)
+ case 31:
+ if (!ctx->pr) {
+ /* Set process priority to very low */
+ prio = 1;
+ }
+ break;
+ case 5:
+ if (!ctx->pr) {
+ /* Set process priority to medium-hight */
+ prio = 5;
+ }
+ break;
+ case 3:
+ if (!ctx->pr) {
+ /* Set process priority to high */
+ prio = 6;
+ }
+ break;
+ case 7:
+ if (ctx->hv && !ctx->pr) {
+ /* Set process priority to very high */
+ prio = 7;
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+ if (prio) {
+ TCGv t0 = tcg_temp_new();
+ gen_load_spr(t0, SPR_PPR);
+ tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
+ tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
+ gen_store_spr(SPR_PPR, t0);
+ }
+#if !defined(CONFIG_USER_ONLY)
+ /*
+ * Pause out of TCG otherwise spin loops with smt_low eat too
+ * much CPU and the kernel hangs. This applies to all
+ * encodings other than no-op, e.g., miso(rs=26), yield(27),
+ * mdoio(29), mdoom(30), and all currently undefined.
+ */
+ gen_pause(ctx);
+#endif
+#endif
+ }
+
+ return true;
+}
+
+static bool trans_XOR(DisasContext *ctx, arg_XOR *a)
+{
+ /* Optimisation for "set to zero" case */
+ if (a->rt != a->rb) {
+ tcg_gen_xor_tl(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
+ } else {
+ tcg_gen_movi_tl(cpu_gpr[a->ra], 0);
+ }
+ if (unlikely(a->rc)) {
+ gen_set_Rc0(ctx, cpu_gpr[a->ra]);
+ }
+ return true;
+}
+
+static bool trans_CMPB(DisasContext *ctx, arg_CMPB *a)
+{
+ REQUIRE_INSNS_FLAGS2(ctx, ISA205);
+ gen_helper_CMPB(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
+ return true;
+}
+
+static bool do_cntzw(DisasContext *ctx, arg_X_sa_rc *a,
+ void (*helper)(TCGv_i32, TCGv_i32, uint32_t))
+{
+ TCGv_i32 t = tcg_temp_new_i32();
+
+ tcg_gen_trunc_tl_i32(t, cpu_gpr[a->rs]);
+ helper(t, t, 32);
+ tcg_gen_extu_i32_tl(cpu_gpr[a->ra], t);
+
+ if (unlikely(a->rc)) {
+ gen_set_Rc0(ctx, cpu_gpr[a->ra]);
+ }
+ return true;
+}
+
+#if defined(TARGET_PPC64)
+static bool do_cntzd(DisasContext *ctx, arg_X_sa_rc *a,
+ void (*helper)(TCGv_i64, TCGv_i64, uint64_t))
+{
+ helper(cpu_gpr[a->ra], cpu_gpr[a->rs], 64);
+ if (unlikely(a->rc)) {
+ gen_set_Rc0(ctx, cpu_gpr[a->ra]);
+ }
+ return true;
+}
+#endif
+
+static bool trans_CNTLZD(DisasContext *ctx, arg_CNTLZD *a)
+{
+ REQUIRE_64BIT(ctx);
+#if defined(TARGET_PPC64)
+ do_cntzd(ctx, a, tcg_gen_clzi_i64);
+#else
+ qemu_build_not_reached();
+#endif
+ return true;
+}
+
+static bool trans_CNTTZD(DisasContext *ctx, arg_CNTTZD *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_INSNS_FLAGS2(ctx, ISA300);
+#if defined(TARGET_PPC64)
+ do_cntzd(ctx, a, tcg_gen_ctzi_i64);
+#else
+ qemu_build_not_reached();
+#endif
+ return true;
+}
+
+static bool trans_POPCNTB(DisasContext *ctx, arg_POPCNTB *a)
+{
+ REQUIRE_INSNS_FLAGS(ctx, POPCNTB);
+ gen_helper_POPCNTB(cpu_gpr[a->ra], cpu_gpr[a->rs]);
+ return true;
+}
+
+static bool trans_POPCNTW(DisasContext *ctx, arg_POPCNTW *a)
+{
+ REQUIRE_INSNS_FLAGS(ctx, POPCNTWD);
+#if defined(TARGET_PPC64)
+ gen_helper_POPCNTW(cpu_gpr[a->ra], cpu_gpr[a->rs]);
+#else
+ tcg_gen_ctpop_i32(cpu_gpr[a->ra], cpu_gpr[a->rs]);
+#endif
+ return true;
+}
+
+static bool trans_POPCNTD(DisasContext *ctx, arg_POPCNTD *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_INSNS_FLAGS(ctx, POPCNTWD);
+#if defined(TARGET_PPC64)
+ tcg_gen_ctpop_i64(cpu_gpr[a->ra], cpu_gpr[a->rs]);
+#else
+ qemu_build_not_reached();
+#endif
+ return true;
+}
+
+static bool trans_PRTYW(DisasContext *ctx, arg_PRTYW *a)
+{
+ TCGv ra = cpu_gpr[a->ra];
+ TCGv rs = cpu_gpr[a->rs];
+ TCGv t0 = tcg_temp_new();
+
+ REQUIRE_INSNS_FLAGS2(ctx, ISA205);
+ tcg_gen_shri_tl(t0, rs, 16);
+ tcg_gen_xor_tl(ra, rs, t0);
+ tcg_gen_shri_tl(t0, ra, 8);
+ tcg_gen_xor_tl(ra, ra, t0);
+ tcg_gen_andi_tl(ra, ra, (target_ulong)0x100000001ULL);
+ return true;
+}
+
+static bool trans_PRTYD(DisasContext *ctx, arg_PRTYD *a)
+{
+ TCGv ra = cpu_gpr[a->ra];
+ TCGv rs = cpu_gpr[a->rs];
+ TCGv t0 = tcg_temp_new();
+
+ REQUIRE_64BIT(ctx);
+ REQUIRE_INSNS_FLAGS2(ctx, ISA205);
+ tcg_gen_shri_tl(t0, rs, 32);
+ tcg_gen_xor_tl(ra, rs, t0);
+ tcg_gen_shri_tl(t0, ra, 16);
+ tcg_gen_xor_tl(ra, ra, t0);
+ tcg_gen_shri_tl(t0, ra, 8);
+ tcg_gen_xor_tl(ra, ra, t0);
+ tcg_gen_andi_tl(ra, ra, 1);
+ return true;
+}
+
+static bool trans_BPERMD(DisasContext *ctx, arg_BPERMD *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_INSNS_FLAGS2(ctx, PERM_ISA206);
+#if defined(TARGET_PPC64)
+ gen_helper_BPERMD(cpu_gpr[a->ra], cpu_gpr[a->rt], cpu_gpr[a->rb]);
+#else
+ qemu_build_not_reached();
+#endif
+ return true;
+}
+
static bool trans_CFUGED(DisasContext *ctx, arg_X *a)
{
REQUIRE_64BIT(ctx);
@@ -944,6 +1223,27 @@ static bool trans_PEXTD(DisasContext *ctx, arg_X *a)
return true;
}
+TRANS(ANDI_, do_addi_, false);
+TRANS(ANDIS_, do_addi_, true);
+TRANS(ORI, do_ori, false);
+TRANS(ORIS, do_ori, true);
+TRANS(XORI, do_xori, false);
+TRANS(XORIS, do_xori, true);
+
+TRANS(AND, do_logical2, tcg_gen_and_tl);
+TRANS(ANDC, do_logical2, tcg_gen_andc_tl);
+TRANS(NAND, do_logical2, tcg_gen_nand_tl);
+TRANS(ORC, do_logical2, tcg_gen_orc_tl);
+TRANS(NOR, do_logical2, tcg_gen_nor_tl);
+TRANS(EQV, do_logical2, tcg_gen_eqv_tl);
+TRANS(EXTSB, do_logical1, tcg_gen_ext8s_tl);
+TRANS(EXTSH, do_logical1, tcg_gen_ext16s_tl);
+
+TRANS(CNTLZW, do_cntzw, tcg_gen_clzi_i32);
+TRANS_FLAGS2(ISA300, CNTTZW, do_cntzw, tcg_gen_ctzi_i32);
+
+TRANS64(EXTSW, do_logical1, tcg_gen_ext32s_tl);
+
static bool trans_ADDG6S(DisasContext *ctx, arg_X *a)
{
const target_ulong carry_bits = (target_ulong)-1 / 0xf;
--
2.43.0
- [PULL 07/72] target/ppc: Fix embedded memory barriers, (continued)
- [PULL 07/72] target/ppc: Fix embedded memory barriers, Nicholas Piggin, 2024/05/23
- [PULL 08/72] target/ppc: Add ISA v3.1 variants of sync instruction, Nicholas Piggin, 2024/05/23
- [PULL 11/72] target/ppc: Move mul{li, lw, lwo, hw, hwu} instructions to decodetree., Nicholas Piggin, 2024/05/23
- [PULL 12/72] target/ppc: Make divw[u] handler method decodetree compatible., Nicholas Piggin, 2024/05/23
- [PULL 09/72] target/ppc: Merge various fpu helpers, Nicholas Piggin, 2024/05/23
- [PULL 10/72] target/ppc: Move floating-point arithmetic instructions to decodetree., Nicholas Piggin, 2024/05/23
- [PULL 14/72] target/ppc: Move neg, darn, mod{sw, uw} to decodetree., Nicholas Piggin, 2024/05/23
- [PULL 13/72] target/ppc: Move divw[u, e, eu] instructions to decodetree., Nicholas Piggin, 2024/05/23
- [PULL 15/72] target/ppc: Move multiply fixed-point insns (64-bit operands) to decodetree., Nicholas Piggin, 2024/05/23
- [PULL 16/72] target/ppc: Move div/mod fixed-point insns (64 bits operands) to decodetree., Nicholas Piggin, 2024/05/23
- [PULL 18/72] target/ppc: Move logical fixed-point instructions to decodetree.,
Nicholas Piggin <=
- [PULL 17/72] target/ppc: Move cmp{rb, eqb}, tw[i], td[i], isel instructions to decodetree., Nicholas Piggin, 2024/05/23
- [PULL 20/72] target/ppc: Move VMX integer logical instructions to decodetree., Nicholas Piggin, 2024/05/23
- [PULL 21/72] target/ppc: Move VMX integer max/min instructions to decodetree., Nicholas Piggin, 2024/05/23
- [PULL 19/72] target/ppc: Move VMX storage access instructions to decodetree, Nicholas Piggin, 2024/05/23
- [PULL 24/72] Add support for the clrbhrb and mfbhrbe instructions., Nicholas Piggin, 2024/05/23
- [PULL 26/72] target/ppc: larx/stcx generation need only apply DEF_MEMOP() once, Nicholas Piggin, 2024/05/23
- [PULL 22/72] This commit is preparatory to the addition of Branch History Rolling Buffer (BHRB) functionality, which is being provided today starting with the P8 processor., Nicholas Piggin, 2024/05/23
- [PULL 28/72] target/ppc: Make checkstop actually stop the system, Nicholas Piggin, 2024/05/23
- [PULL 23/72] This commit continues adding support for the Branch History Rolling Buffer (BHRB) as is provided starting with the P8 processor and continuing with its successors. This commit is limited to the recording and filtering of taken branches., Nicholas Piggin, 2024/05/23
- [PULL 29/72] target/ppc: improve checkstop logging, Nicholas Piggin, 2024/05/23