diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-10-15 17:00:45 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-10-15 17:00:45 +0000 |
commit | 3d3a6a0a48136117b8cd45dc9b1a88e7e3927d87 (patch) | |
tree | 4ce160a88b82b3667635017b04777d4207d8e753 /target-ppc | |
parent | b61f2753a7239f784b5c2f1d3a0249371cd2e164 (diff) |
PPC: convert SPE logical instructions to TCG
(Nathan Froyd)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5494 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-ppc')
-rw-r--r-- | target-ppc/op.c | 48 | ||||
-rw-r--r-- | target-ppc/translate.c | 78 |
2 files changed, 70 insertions, 56 deletions
diff --git a/target-ppc/op.c b/target-ppc/op.c index c0aa372c61..5887424c53 100644 --- a/target-ppc/op.c +++ b/target-ppc/op.c @@ -2507,54 +2507,6 @@ void OPPROTO op_evcntlsw (void) RETURN(); } -void OPPROTO op_evand (void) -{ - T0_64 &= T1_64; - RETURN(); -} - -void OPPROTO op_evandc (void) -{ - T0_64 &= ~T1_64; - RETURN(); -} - -void OPPROTO op_evor (void) -{ - T0_64 |= T1_64; - RETURN(); -} - -void OPPROTO op_evxor (void) -{ - T0_64 ^= T1_64; - RETURN(); -} - -void OPPROTO op_eveqv (void) -{ - T0_64 = ~(T0_64 ^ T1_64); - RETURN(); -} - -void OPPROTO op_evnor (void) -{ - T0_64 = ~(T0_64 | T1_64); - RETURN(); -} - -void OPPROTO op_evorc (void) -{ - T0_64 |= ~T1_64; - RETURN(); -} - -void OPPROTO op_evnand (void) -{ - T0_64 = ~(T0_64 & T1_64); - RETURN(); -} - void OPPROTO op_evsrws (void) { do_evsrws(); diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 63a3052858..2759eb2d81 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -5723,6 +5723,23 @@ static always_inline void gen_##name (DisasContext *ctx) \ gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \ } +#define GEN_SPEOP_TCG_ARITH2(name) \ +static always_inline void gen_##name (DisasContext *ctx) \ +{ \ + if (unlikely(!ctx->spe_enabled)) { \ + GEN_EXCP_NO_AP(ctx); \ + return; \ + } \ + TCGv t0 = tcg_temp_new(TCG_TYPE_I64); \ + TCGv t1 = tcg_temp_new(TCG_TYPE_I64); \ + gen_load_gpr64(t0, rA(ctx->opcode)); \ + gen_load_gpr64(t1, rB(ctx->opcode)); \ + gen_op_##name(t0, t1); \ + gen_store_gpr64(rD(ctx->opcode), t0); \ + tcg_temp_free(t0); \ + tcg_temp_free(t1); \ +} + #define GEN_SPEOP_ARITH1(name) \ static always_inline void gen_##name (DisasContext *ctx) \ { \ @@ -5749,14 +5766,59 @@ static always_inline void gen_##name (DisasContext *ctx) \ } /* Logical */ -GEN_SPEOP_ARITH2(evand); -GEN_SPEOP_ARITH2(evandc); -GEN_SPEOP_ARITH2(evxor); -GEN_SPEOP_ARITH2(evor); -GEN_SPEOP_ARITH2(evnor); -GEN_SPEOP_ARITH2(eveqv); -GEN_SPEOP_ARITH2(evorc); -GEN_SPEOP_ARITH2(evnand); +static always_inline void gen_op_evand (TCGv t0, TCGv t1) +{ + tcg_gen_and_i64(t0, t0, t1); +} + +static always_inline void gen_op_evandc (TCGv t0, TCGv t1) +{ + tcg_gen_not_i64(t1, t1); + tcg_gen_and_i64(t0, t0, t1); +} + +static always_inline void gen_op_evxor (TCGv t0, TCGv t1) +{ + tcg_gen_xor_i64(t0, t0, t1); +} + +static always_inline void gen_op_evor (TCGv t0, TCGv t1) +{ + tcg_gen_or_i64(t0, t0, t1); +} + +static always_inline void gen_op_evnor (TCGv t0, TCGv t1) +{ + tcg_gen_or_i64(t0, t0, t1); + tcg_gen_not_i64(t0, t0); +} + +static always_inline void gen_op_eveqv (TCGv t0, TCGv t1) +{ + tcg_gen_xor_i64(t0, t0, t1); + tcg_gen_not_i64(t0, t0); +} + +static always_inline void gen_op_evorc (TCGv t0, TCGv t1) +{ + tcg_gen_not_i64(t1, t1); + tcg_gen_or_i64(t0, t0, t1); +} + +static always_inline void gen_op_evnand (TCGv t0, TCGv t1) +{ + tcg_gen_and_i64(t0, t0, t1); + tcg_gen_not_i64(t0, t0); +} + +GEN_SPEOP_TCG_ARITH2(evand); +GEN_SPEOP_TCG_ARITH2(evandc); +GEN_SPEOP_TCG_ARITH2(evxor); +GEN_SPEOP_TCG_ARITH2(evor); +GEN_SPEOP_TCG_ARITH2(evnor); +GEN_SPEOP_TCG_ARITH2(eveqv); +GEN_SPEOP_TCG_ARITH2(evorc); +GEN_SPEOP_TCG_ARITH2(evnand); GEN_SPEOP_ARITH2(evsrwu); GEN_SPEOP_ARITH2(evsrws); GEN_SPEOP_ARITH2(evslw); |