diff options
-rw-r--r-- | target-ppc/helper.h | 1 | ||||
-rw-r--r-- | target-ppc/op_helper.c | 21 | ||||
-rw-r--r-- | target-ppc/translate.c | 1 |
3 files changed, 23 insertions, 0 deletions
diff --git a/target-ppc/helper.h b/target-ppc/helper.h index f5f5282..81f2dea 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -177,6 +177,7 @@ DEF_HELPER_3(vpkuhus, void, avr, avr, avr) DEF_HELPER_3(vpkuwus, void, avr, avr, avr) DEF_HELPER_3(vpkuhum, void, avr, avr, avr) DEF_HELPER_3(vpkuwum, void, avr, avr, avr) +DEF_HELPER_3(vpkpx, void, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32) DEF_HELPER_1(efscfui, i32, i32) diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 1c82088..dcf1aef 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -2195,6 +2195,27 @@ void helper_vperm (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) #else #define PKBIG 0 #endif +void helper_vpkpx (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) +{ + int i, j; + ppc_avr_t result; +#if defined(WORDS_BIGENDIAN) + const ppc_avr_t *x[2] = { a, b }; +#else + const ppc_avr_t *x[2] = { b, a }; +#endif + + VECTOR_FOR_INORDER_I (i, u64) { + VECTOR_FOR_INORDER_I (j, u32){ + uint32_t e = x[i]->u32[j]; + result.u16[4*i+j] = (((e >> 9) & 0xfc00) | + ((e >> 6) & 0x3e0) | + ((e >> 3) & 0x1f)); + } + } + *r = result; +} + #define VPK(suffix, from, to, cvt, dosat) \ void helper_vpk##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \ diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 2b814fe..e0f2557 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -6281,6 +6281,7 @@ GEN_VXFORM(vpkshus, 7, 4); GEN_VXFORM(vpkswus, 7, 5); GEN_VXFORM(vpkshss, 7, 6); GEN_VXFORM(vpkswss, 7, 7); +GEN_VXFORM(vpkpx, 7, 12); #define GEN_VXFORM_NOA(name, opc2, opc3) \ GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC) \ |