target-ppc: add Altivec instructions, patch-bomb version
PATCH 1/1 target-ppc: add Altivec instructions, patch-bomb version
[Thiemo Seufer asked for a patch-bomb so people can conveniently comment on things and so the mail archive has a record of Signed-off-by.]
This patch series adds support for integer Altivec instructions to QEMU, including element-wise loads and stores. It's a long patch series, since each instruction "family" (element-wise loads/stores, modulo arithmetic instructions, saturating arithmetic instructions, etc.) is separated out into its own patch. Hopefully since the individual patches are so short, they will be more-or-less self-explanatory: the explanation for the patches is generally fairly short, on the order of a single line.
The patch series is slightly cleaned up from the one I originally
posted: there were a few problems with my tcg usage, and I didn't faithfully use some convenience functions.
Why only the integer instructions? I originally wrote support for the whole instructions set, but I did it in the days of dyngen. So a straight forward-port was out of the question. The original patch sloppily used native floats everywhere, rather than the float32 abstraction. It also used C99 math functions to implement some of the more exotic Altivec instructions. Both of these decisions mean that some care has to be taken in porting the floating-point instructions.
I figured it'd be better to push out the integer instructions now and the floating-point instructions later, rather than waiting for some unspecified time for full support.
-Nathan
PATCH 1/42 target-ppc: add Altivec logical operations.
--- target-ppc/translate.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)
target-ppc/translate.c +18 -0
@@ -6109,6 +6109,24 @@ GEN_VR_STX(svx, 0x07, 0x07);/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */ GEN_VR_STX (svxl,0x07 ,0x0F ); +/* Logical operations */ +#define GEN_VX_LOGICAL (name, tcg_op, xo) \ +GEN_HANDLER(name, 0x04, (xo >> 1) & 0x1f, (xo >> 6) & 0x1f, 0x00000000, PPC_ALTIVEC) \ +{ \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \ + } \ + tcg_op(cpu_avrh[rD(ctx->opcode)], cpu_avrh[rA(ctx->opcode)], cpu_avrh[rB(ctx->opcode)]); \ + tcg_op(cpu_avrl[rD(ctx->opcode)], cpu_avrl[rA(ctx->opcode)], cpu_avrl[rB(ctx->opcode)]); \ +} + +GEN_VX_LOGICAL (vand, tcg_gen_and_i64,1028 ); +GEN_VX_LOGICAL (vandc, tcg_gen_andc_i64,1092 ); +GEN_VX_LOGICAL (vor, tcg_gen_or_i64,1156 ); +GEN_VX_LOGICAL (vxor, tcg_gen_xor_i64,1220 ); +GEN_VX_LOGICAL (vnor, tcg_gen_nor_i64,1284 ); +/*** SPE extension ***/ /* Register moves */
Signature · 1 line
1.6.0.5
Re: [Qemu-devel] [PATCH 01/42] target-ppc: add Altivec logical operations.
Quoted 21 lines · Nathan Froyd
Signed-off-by Nathan Froyd <[email protected]>--- target-ppc/translate.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)target-ppc/translate.c +7
-0@@ -6109,6 +6109,24 @@ GEN_VR_STX(svx, 0x07, 0x07);/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */ GEN_VR_STX (svxl,0x07 ,0x0F ); +/* Logical operations */ +#define GEN_VX_LOGICAL (name, tcg_op, xo) \ +GEN_HANDLER(name, 0x04, (xo >> 1) & 0x1f, (xo >> 6) & 0x1f, 0x00000000, PPC_ALTIVEC) \ +{ \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \
target-ppc/translate.c GEN_VR_STX(svx, 0x07, 0x07); · line 6128
Quoted 10 lines
target-ppc/translate.c +10
-0+ } \ +tcg_op (cpu_avrh[rD (ctx->opcode)], cpu_avrh[rA (ctx->opcode)], cpu_avrh[rB (ctx->opcode)]); \ +tcg_op (cpu_avrl[rD (ctx->opcode)], cpu_avrl[rA (ctx->opcode)], cpu_avrl[rB (ctx->opcode)]); \ +} + +GEN_VX_LOGICAL (vand, tcg_gen_and_i64,1028 ); +GEN_VX_LOGICAL (vandc, tcg_gen_andc_i64,1092 ); +GEN_VX_LOGICAL (vor, tcg_gen_or_i64,1156 ); +GEN_VX_LOGICAL (vxor, tcg_gen_xor_i64,1220 ); +GEN_VX_LOGICAL (vnor, tcg_gen_nor_i64,1284 );
I know those decimal value comes from the PowerPC manual, but the whole QEMU code uses hexadecimal values instead. Also it is usually passed directly as opc2 and opc3 values. I guess it is better to continue like that for consistencies.
Otherwise the patch looks good, I'll apply it when that is fixed.
Signature · 4 lines
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [email protected] | [email protected] `- people.debian.org/~aurel32 | www.aurel32.net
Re: [Qemu-devel] [PATCH 01/42] target-ppc: add Altivec logical operations.
Quoted 12 lines · Aurelien Jarno
Review
Quoted 5 lines · Nathan Froyd
(quoted diff) +5
-0+GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 1028); +GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 1092); +GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 1156); +GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 1220); +GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 1284);I know those decimal value comes from the PowerPC manual, but the whole QEMU code uses hexadecimal values instead. Also it is usually passed directly as opc2 and opc3 values. I guess it is better to continue like that for consistencies.
Quoted 1 line
Otherwise the patch looks good, I'll apply it when that is fixed.
Updated patch below. I suppose this means redoing a good chunk of the remainder of the patch series, since the convenience macros use the XO field approach instead of opc2/opc3, eh?
-Nathan
---
Use opc2/opc3 instead of one big xo field. Do this consistency with the rest of translate.c
--- target-ppc/translate.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)
target-ppc/translate.c +18 -0
@@ -6109,6 +6109,24 @@ GEN_VR_STX(svx, 0x07, 0x07);/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */ GEN_VR_STX (svxl,0x07 ,0x0F ); +/* Logical operations */ +#define GEN_VX_LOGICAL (name, tcg_op, opc2, opc3) \ +GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC) \ +{ \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \ + } \ + tcg_op(cpu_avrh[rD(ctx->opcode)], cpu_avrh[rA(ctx->opcode)], cpu_avrh[rB(ctx->opcode)]); \ + tcg_op(cpu_avrl[rD(ctx->opcode)], cpu_avrl[rA(ctx->opcode)], cpu_avrl[rB(ctx->opcode)]); \ +} + +GEN_VX_LOGICAL (vand, tcg_gen_and_i64,2 ,16 ); +GEN_VX_LOGICAL (vandc, tcg_gen_andc_i64,2 ,17 ); +GEN_VX_LOGICAL (vor, tcg_gen_or_i64,2 ,18 ); +GEN_VX_LOGICAL (vxor, tcg_gen_xor_i64,2 ,19 ); +GEN_VX_LOGICAL (vnor, tcg_gen_nor_i64,2 ,20 ); +/*** SPE extension ***/ /* Register moves */
Signature · 1 line
1.6.0.5
Re: [Qemu-devel] [PATCH 01/42] target-ppc: add Altivec logical operations.
Quoted 13 lines · Nathan Froyd
Quoted 12 lines · Aurelien Jarno
Review
Quoted 5 lines · Nathan Froyd
(quoted diff) +5
-0+GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 1028); +GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 1092); +GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 1156); +GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 1220); +GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 1284);I know those decimal value comes from the PowerPC manual, but the whole QEMU code uses hexadecimal values instead. Also it is usually passed directly as opc2 and opc3 values. I guess it is better to continue like that for consistencies.
Quoted 3 lines
Quoted 1 line
Otherwise the patch looks good, I'll apply it when that is fixed.
Updated patch below. I suppose this means redoing a good chunk of the
Thanks, I have just applied it.
Quoted 2 lines
remainder of the patch series, since the convenience macros use the XO field approach instead of opc2/opc3, eh?
Yes, I also think this is the way to go.
Quoted 44 lines
Signed-off-by Nathan Froyd <[email protected]>---
Use opc2/opc3 instead of one big xo field. Do this consistency with the rest oftranslate.c--- target-ppc/translate.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)target-ppc/translate.c +18
-0@@ -6109,6 +6109,24 @@ GEN_VR_STX(svx, 0x07, 0x07);/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */ GEN_VR_STX (svxl,0x07 ,0x0F ); +/* Logical operations */ +#define GEN_VX_LOGICAL (name, tcg_op, opc2, opc3) \ +GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC) \ +{ \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \ + } \ + tcg_op(cpu_avrh[rD(ctx->opcode)], cpu_avrh[rA(ctx->opcode)], cpu_avrh[rB(ctx->opcode)]); \ + tcg_op(cpu_avrl[rD(ctx->opcode)], cpu_avrl[rA(ctx->opcode)], cpu_avrl[rB(ctx->opcode)]); \ +} + +GEN_VX_LOGICAL (vand, tcg_gen_and_i64,2 ,16 ); +GEN_VX_LOGICAL (vandc, tcg_gen_andc_i64,2 ,17 ); +GEN_VX_LOGICAL (vor, tcg_gen_or_i64,2 ,18 ); +GEN_VX_LOGICAL (vxor, tcg_gen_xor_i64,2 ,19 ); +GEN_VX_LOGICAL (vnor, tcg_gen_nor_i64,2 ,20 ); +/*** SPE extension ***/ /* Register moves */ Signature · 1 line
1.6.0.5
Signature · 4 lines
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [email protected] | [email protected] `- people.debian.org/~aurel32 | www.aurel32.net
PATCH 2/42 target-ppc: add helper macros for later patches.
In reply to Nathan Froyd--- target-ppc/op_helper.c | 33 +++++++++++++++++++++++++++++++++ 1 files changed, 33 insertions(+), 0 deletions(-)
target-ppc/op_helper.c +33 -0
@@ -2007,6 +2007,39 @@ target_ulong helper_dlmzb (target_ulong high, target_ulong low, uint32_t update_ }/*****************************************************************************/ +/* Altivec extension helpers */ +#if defined(WORDS_BIGENDIAN ) +#define HI_IDX 0 +#define LO_IDX 1 +#else +#define HI_IDX 1 +#define LO_IDX 0 +#endif + +#define N_ELEMS (element) (sizeof (r->element) / sizeof (r->element[0])) + +#define VECTOR_FOR (element) \ + int i; \ + VECTOR_FOR_I(i, element) + +#define VECTOR_FOR_I (index, element) \ + for (index = 0; index < N_ELEMS(element); index++) + +#if defined(WORDS_BIGENDIAN ) +#define VECTOR_FOR_INORDER_I (index, element) VECTOR_FOR_I(index, element) +#else +#define VECTOR_FOR_INORDER_I (index, element) \ + for (index = N_ELEMS(element)-1; index >= 0; index--) +#endif + +#undef VECTOR_FOR +#undef VECTOR_FOR_I +#undef VECTOR_FOR_INORDER_I +#undef N_ELEMS +#undef HI_IDX +#undef LO_IDX + +/*****************************************************************************/ /* SPE extension helpers */ /* Use a table to make this quicker */ static uint8_t hbrev[16 ] = {
Signature · 1 line
1.6.0.5
Re: [Qemu-devel] [PATCH 02/42] target-ppc: add helper macros for later patches.
Quoted 40 lines · Nathan Froyd
Signed-off-by Nathan Froyd <[email protected]>--- target-ppc/op_helper.c | 33 +++++++++++++++++++++++++++++++++ 1 files changed, 33 insertions(+), 0 deletions(-)target-ppc/op_helper.c +26
-0@@ -2007,6 +2007,39 @@ target_ulong helper_dlmzb (target_ulong high, target_ulong low, uint32_t update_ }/*****************************************************************************/ +/* Altivec extension helpers */ +#if defined(WORDS_BIGENDIAN ) +#define HI_IDX 0 +#define LO_IDX 1 +#else +#define HI_IDX 1 +#define LO_IDX 0 +#endif + +#define N_ELEMS (element) (sizeof (r->element) / sizeof (r->element[0])) + +#define VECTOR_FOR (element) \ + int i; \ + VECTOR_FOR_I(i, element) + +#define VECTOR_FOR_I (index, element) \ + for (index = 0; index < N_ELEMS(element); index++) + +#if defined(WORDS_BIGENDIAN ) +#define VECTOR_FOR_INORDER_I (index, element) VECTOR_FOR_I(index, element) +#else +#define VECTOR_FOR_INORDER_I (index, element) \ + for (index = N_ELEMS(element)-1; index >= 0; index--) +#endif + +#undef VECTOR_FOR
target-ppc/op_helper.c target_ulong helper_dlmzb (target_ulong high, target_ulong low, uint32_t update_ · line 2045
Quoted 10 lines
target-ppc/op_helper.c +7
-0+#undef VECTOR_FOR_I +#undef VECTOR_FOR_INORDER_I +#undef N_ELEMS +#undef HI_IDX +#undef LO_IDX + +/*****************************************************************************/ /* SPE extension helpers */ /* Use a table to make this quicker */ static uint8_t hbrev[16 ] = {
While I have nothing against those macros, I know some code like that has already been rejected in the past.
If someone disagrees with this code, please shout *now* before I apply it to the SVN.
Signature · 4 lines
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [email protected] | [email protected] `- people.debian.org/~aurel32 | www.aurel32.net
Re: [Qemu-devel] [PATCH 02/42] target-ppc: add helper macros for later patches.
In reply to Nathan FroydQuoted 13 lines · Nathan Froyd
Signed-off-by Nathan Froyd <[email protected]>--- target-ppc/op_helper.c | 33 +++++++++++++++++++++++++++++++++ 1 files changed, 33 insertions(+), 0 deletions(-)target-ppc/op_helper.c +0
-0@@ -2007,6 +2007,39 @@ target_ulong helper_dlmzb (target_ulong high, target_ulong low, uint32_t update_ }/*****************************************************************************/
target-ppc/op_helper.c target_ulong helper_dlmzb (target_ulong high, target_ulong low, uint32_t update_ · line 2019
Quoted 10 lines
target-ppc/op_helper.c +10
-0+/* Altivec extension helpers */ +#if defined(WORDS_BIGENDIAN ) +#define HI_IDX 0 +#define LO_IDX 1 +#else +#define HI_IDX 1 +#define LO_IDX 0 +#endif + +#define N_ELEMS (element) (sizeof (r->element) / sizeof (r->element[0]))
Note that the ARRAY_SIZE macro from osdep.h does almost the same.
Quoted 25 lines
target-ppc/op_helper.c +22
-0+#define VECTOR_FOR (element) \ + int i; \ + VECTOR_FOR_I(i, element) + +#define VECTOR_FOR_I (index, element) \ + for (index = 0; index < N_ELEMS(element); index++) + +#if defined(WORDS_BIGENDIAN ) +#define VECTOR_FOR_INORDER_I (index, element) VECTOR_FOR_I(index, element) +#else +#define VECTOR_FOR_INORDER_I (index, element) \ + for (index = N_ELEMS(element)-1; index >= 0; index--) +#endif + +#undef VECTOR_FOR +#undef VECTOR_FOR_I +#undef VECTOR_FOR_INORDER_I +#undef N_ELEMS +#undef HI_IDX +#undef LO_IDX + +/*****************************************************************************/ /* SPE extension helpers */ /* Use a table to make this quicker */ static uint8_t hbrev[16 ] = {
Signature · 4 lines
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [email protected] | [email protected] `- people.debian.org/~aurel32 | www.aurel32.net
PATCH 3/42 target-ppc: add gen_avr_ptr function.
In reply to Nathan Froyd--- target-ppc/translate.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
target-ppc/translate.c +7 -0
@@ -6053,6 +6053,13 @@ GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)/*** Altivec vector extension ***/ /* Altivec registers moves */ +static always_inline TCGv_ptr gen_avr_ptr(int reg) +{ +TCGv_ptr r =tcg_temp_new (); + tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg])); +return r; +} +#define GEN_VR_LDX (name, opc2, opc3) \ GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC) \ { \
Signature · 1 line
1.6.0.5
Re: [Qemu-devel] [PATCH 03/42] target-ppc: add gen_avr_ptr function.
Quoted 14 lines · Nathan Froyd
Signed-off-by Nathan Froyd <[email protected]>--- target-ppc/translate.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)target-ppc/translate.c +0
-0@@ -6053,6 +6053,13 @@ GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)/*** Altivec vector extension ***/ /* Altivec registers moves */
target-ppc/translate.c GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE) · line 6065
Quoted 10 lines
target-ppc/translate.c +7
-0+static always_inline TCGv_ptr gen_avr_ptr(int reg) +{ +TCGv_ptr r =tcg_temp_new (); + tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg])); +return r; +} +#define GEN_VR_LDX (name, opc2, opc3) \ GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC) \ { \
I am still pondering what is the better solution between passing a pointer to an avr register or the avr register number.
Does someone has an opinion about that?
Signature · 4 lines
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [email protected] | [email protected] `- people.debian.org/~aurel32 | www.aurel32.net
Re: [Qemu-devel] [PATCH 03/42] target-ppc: add gen_avr_ptr function.
Quoted 29 lines · Aurelien Jarno
Quoted 14 lines · Nathan Froyd
Signed-off-by Nathan Froyd <[email protected]>--- target-ppc/translate.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)target-ppc/translate.c +0
-0@@ -6053,6 +6053,13 @@ GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)/*** Altivec vector extension ***/ /* Altivec registers moves */ target-ppc/translate.c GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE) · line 6065
Quoted 10 lines
target-ppc/translate.c +7
-0+static always_inline TCGv_ptr gen_avr_ptr(int reg) +{ +TCGv_ptr r =tcg_temp_new (); + tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg])); +return r; +} +#define GEN_VR_LDX (name, opc2, opc3) \ GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC) \ { \I am still pondering what is the better solution between passing a pointer to an avr register or the avr register number.
Quoted 2 lines
Does someone has an opinion about that?
Note that SSE helpers are also using pointers.
Signature · 4 lines
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [email protected] | [email protected] `- people.debian.org/~aurel32 | www.aurel32.net
Re: [Qemu-devel] [PATCH 03/42] target-ppc: add gen_avr_ptr function.
In reply to Aurelien JarnoQuoted 4 lines
I am still pondering what is the better solution between passing a pointer to an avr register or the avr register number.
Does someone has an opinion about that?
FWIW it was probably me recommended passing things by value.
It feels cleaner because with pointers it's pretty much impossible to TCG to tell what's going on.
I was also hoping that it would mean many of the helpers could be shared between AltiVec and SPE. On closer inspection it looks like there aren't really that many interesting opportunities for this.
On ARM NEON there are two different vector lengths, and registers overlap in interesting ways, so we need most of the splitting and iteration stuff anyway. AltiVec and SSE are more restricted instruction sets, so I guess there's probably less benefit.
Paul
Aurelien Jarno
AppliedRe: [Qemu-devel] [PATCH 03/42] target-ppc: add gen_avr_ptr function.
In reply to Nathan FroydQuoted 2 lines · Nathan Froyd
Signed-off-by Nathan Froyd <[email protected]>
Thanks, applied.
Quoted 28 lines
--- target-ppc/translate.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)target-ppc/translate.c +7
-0@@ -6053,6 +6053,13 @@ GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)/*** Altivec vector extension ***/ /* Altivec registers moves */ +static always_inline TCGv_ptr gen_avr_ptr(int reg) +{ +TCGv_ptr r =tcg_temp_new (); + tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg])); +return r; +} +#define GEN_VR_LDX (name, opc2, opc3) \ GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC) \ { \Signature · 1 line
1.6.0.5
Signature · 4 lines
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [email protected] | [email protected] `- people.debian.org/~aurel32 | www.aurel32.net
PATCH 4/42 target-ppc: add GEN_VXFORM macro for subsequent instructions.
In reply to Nathan Froyd--- target-ppc/translate.c | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-)
target-ppc/translate.c +17 -0
@@ -6134,6 +6134,23 @@ GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 1156);GEN_VX_LOGICAL (vxor, tcg_gen_xor_i64,1220 );GEN_VX_LOGICAL (vnor, tcg_gen_nor_i64,1284 ); +#define GEN_VXFORM (name, xo) \ +GEN_HANDLER(name, 0x04, (xo >> 1) & 0x1f, (xo >> 6) & 0x1f, 0x00000000, PPC_ALTIVEC) \ +{ \ + TCGv_ptr ra, rb, rd; \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \ + } \ + ra = gen_avr_ptr(rA(ctx->opcode)); \ + rb = gen_avr_ptr(rB(ctx->opcode)); \ + rd = gen_avr_ptr(rD(ctx->opcode)); \ + gen_helper_##name (rd, ra, rb); \ + tcg_temp_free (ra); \ + tcg_temp_free (rb); \ + tcg_temp_free (rd); \ +} +/*** SPE extension ***/ /* Register moves */
Signature · 1 line
1.6.0.5
PATCH 5/42 target-ppc: add v{add, sub}u{b, h, w}m instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 10 ++++++++++ target-ppc/op_helper.c | 16 ++++++++++++++++ target-ppc/translate.c | 7 +++++++ 3 files changed, 33 insertions(+), 0 deletions(-)
target-ppc/helper.h +10 -0
@@ -96,6 +96,16 @@ DEF_HELPER_1(fres, i64, i64) DEF_HELPER_1(frsqrte, i64, i64) DEF_HELPER_3(fsel, i64, i64, i64, i64) +#define dh_alias_avr ptr +#define dh_ctype_avr ppc_avr_t * + +DEF_HELPER_3(vaddubm, void, avr, avr, avr) +DEF_HELPER_3(vadduhm, void, avr, avr, avr) +DEF_HELPER_3(vadduwm, void, avr, avr, avr) +DEF_HELPER_3(vsububm, void, avr, avr, avr) +DEF_HELPER_3(vsubuhm, void, avr, avr, avr) +DEF_HELPER_3(vsubuwm, void, avr, avr, avr) + DEF_HELPER_1(efscfsi, i32, i32) DEF_HELPER_1(efscfui, i32, i32)DEF_HELPER_1 (efscfuf, i32, i32)
target-ppc/op_helper.c +16 -0
@@ -2032,6 +2032,22 @@ target_ulong helper_dlmzb (target_ulong high, target_ulong low, uint32_t update_ for (index = N_ELEMS(element)-1; index >= 0; index--)#endif +#define VARITH_DO (name, op, element) \ +void helper_v##name (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ +{ \ + VECTOR_FOR (element) { \ + r->element[i] = a->element[i] op b->element[i]; \ + } \ +} +#define VARITH (suffix, element) \ + VARITH_DO(add##suffix, +, element) \ + VARITH_DO(sub##suffix, -, element) +VARITH(ubm, u8) +VARITH(uhm, u16) +VARITH(uwm, u32) +#undef VARITH_DO +#undef VARITH +#undef VECTOR_FOR#undef VECTOR_FOR_I#undef VECTOR_FOR_INORDER_I
target-ppc/translate.c +7 -0
@@ -6151,6 +6151,13 @@ GEN_HANDLER(name, 0x04, (xo >> 1) & 0x1f, (xo >> 6) & 0x1f, 0x00000000, PPC_ALTItcg_temp_free (rd); \ } +GEN_VXFORM (vaddubm,0 ); +GEN_VXFORM (vadduhm,64 ); +GEN_VXFORM (vadduwm,128 ); +GEN_VXFORM (vsububm,1024 ); +GEN_VXFORM (vsubuhm,1088 ); +GEN_VXFORM (vsubuwm,1152 ); +/*** SPE extension ***/ /* Register moves */
Signature · 1 line
1.6.0.5
PATCH 6/42 target-ppc: add signed fields to ppc_avr_t.
In reply to Nathan Froyd--- target-ppc/cpu.h | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
target-ppc/cpu.h +3 -0
@@ -311,6 +311,9 @@ union ppc_avr_t {uint8_t u8[16 ];uint16_t u16[8 ];uint32_t u32[4 ]; +int8_t s8[16 ]; +int16_t s16[8 ]; +int32_t s32[4 ];uint64_t u64[2 ]; };
Signature · 1 line
1.6.0.5
Aurelien Jarno
AppliedRe: [Qemu-devel] [PATCH 06/42] target-ppc: add signed fields to ppc_avr_t.
Quoted 2 lines · Nathan Froyd
Signed-off-by Nathan Froyd <[email protected]>
Thanks, applied.
Quoted 24 lines
--- target-ppc/cpu.h | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)target-ppc/cpu.h +3
-0@@ -311,6 +311,9 @@ union ppc_avr_t {uint8_t u8[16 ];uint16_t u16[8 ];uint32_t u32[4 ]; +int8_t s8[16 ]; +int16_t s16[8 ]; +int32_t s32[4 ];uint64_t u64[2 ]; };Signature · 1 line
1.6.0.5
Signature · 4 lines
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [email protected] | [email protected] `- people.debian.org/~aurel32 | www.aurel32.net
PATCH 7/42 target-ppc: add vavg{s, u}{b, h, w} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 6 ++++++ target-ppc/op_helper.c | 18 ++++++++++++++++++ target-ppc/translate.c | 6 ++++++ 3 files changed, 30 insertions(+), 0 deletions(-)
target-ppc/helper.h +6 -0
@@ -105,6 +105,12 @@ DEF_HELPER_3(vadduwm, void, avr, avr, avr) DEF_HELPER_3(vsububm, void, avr, avr, avr) DEF_HELPER_3(vsubuhm, void, avr, avr, avr) DEF_HELPER_3(vsubuwm, void, avr, avr, avr) +DEF_HELPER_3(vavgub, void, avr, avr, avr) +DEF_HELPER_3(vavguh, void, avr, avr, avr) +DEF_HELPER_3(vavguw, void, avr, avr, avr) +DEF_HELPER_3(vavgsb, void, avr, avr, avr) +DEF_HELPER_3(vavgsh, void, avr, avr, avr) +DEF_HELPER_3(vavgsw, void, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +18 -0
@@ -2048,6 +2048,24 @@ VARITH(uwm, u32)#undef VARITH_DO#undef VARITH +#define VAVG_DO (name, element, etype) \ + void helper_v##name (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ + { \ + VECTOR_FOR (element) { \ + etype x = (etype)a->element[i] + (etype)b->element[i] + 1; \ + r->element[i] = x >> 1; \ + } \ + } + +#define VAVG (type, signed_element, signed_type, unsigned_element, unsigned_type) \ + VAVG_DO(avgs##type, signed_element, signed_type) \ + VAVG_DO(avgu##type, unsigned_element, unsigned_type) +VAVG(b, s8, int16_t, u8, uint16_t) +VAVG(h, s16, int32_t, u16, uint32_t) +VAVG(w, s32, int64_t, u32, uint64_t) +#undef VAVG_DO +#undef VAVG +#undef VECTOR_FOR#undef VECTOR_FOR_I#undef VECTOR_FOR_INORDER_I
target-ppc/translate.c +6 -0
@@ -6157,6 +6157,12 @@ GEN_VXFORM(vadduwm, 128);GEN_VXFORM (vsububm,1024 );GEN_VXFORM (vsubuhm,1088 );GEN_VXFORM (vsubuwm,1152 ); +GEN_VXFORM (vavgub,1026 ); +GEN_VXFORM (vavguh,1090 ); +GEN_VXFORM (vavguw,1154 ); +GEN_VXFORM (vavgsb,1282 ); +GEN_VXFORM (vavgsh,1346 ); +GEN_VXFORM (vavgsw,1410 );/*** SPE extension ***/ /* Register moves */
Signature · 1 line
1.6.0.5
PATCH 8/42 target-ppc: add v{min, max}{s, u}{b, h, w} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 12 ++++++++++++ target-ppc/op_helper.c | 23 +++++++++++++++++++++++ target-ppc/translate.c | 12 ++++++++++++ 3 files changed, 47 insertions(+), 0 deletions(-)
target-ppc/helper.h +12 -0
@@ -111,6 +111,18 @@ DEF_HELPER_3(vavguw, void, avr, avr, avr) DEF_HELPER_3(vavgsb, void, avr, avr, avr) DEF_HELPER_3(vavgsh, void, avr, avr, avr) DEF_HELPER_3(vavgsw, void, avr, avr, avr) +DEF_HELPER_3(vminsb, void, avr, avr, avr) +DEF_HELPER_3(vminsh, void, avr, avr, avr) +DEF_HELPER_3(vminsw, void, avr, avr, avr) +DEF_HELPER_3(vmaxsb, void, avr, avr, avr) +DEF_HELPER_3(vmaxsh, void, avr, avr, avr) +DEF_HELPER_3(vmaxsw, void, avr, avr, avr) +DEF_HELPER_3(vminub, void, avr, avr, avr) +DEF_HELPER_3(vminuh, void, avr, avr, avr) +DEF_HELPER_3(vminuw, void, avr, avr, avr) +DEF_HELPER_3(vmaxub, void, avr, avr, avr) +DEF_HELPER_3(vmaxuh, void, avr, avr, avr) +DEF_HELPER_3(vmaxuw, void, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +23 -0
@@ -2066,6 +2066,29 @@ VAVG(w, s32, int64_t, u32, uint64_t)#undef VAVG_DO#undef VAVG +#define VMINMAX_DO (name, compare, element) \ + void helper_v##name (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ + { \ + VECTOR_FOR (element) { \ + if (a->element[i] compare b->element[i]) { \ + r->element[i] = b->element[i]; \ + } else { \ + r->element[i] = a->element[i]; \ + } \ + } \ + } +#define VMINMAX (suffix, element) \ + VMINMAX_DO(min##suffix, >, element) \ + VMINMAX_DO(max##suffix, <, element) +VMINMAX(sb, s8) +VMINMAX(sh, s16) +VMINMAX(sw, s32) +VMINMAX(ub, u8) +VMINMAX(uh, u16) +VMINMAX(uw, u32) +#undef VMINMAX_DO +#undef VMINMAX +#undef VECTOR_FOR#undef VECTOR_FOR_I#undef VECTOR_FOR_INORDER_I
target-ppc/translate.c +12 -0
@@ -6157,6 +6157,18 @@ GEN_VXFORM(vadduwm, 128);GEN_VXFORM (vsububm,1024 );GEN_VXFORM (vsubuhm,1088 );GEN_VXFORM (vsubuwm,1152 ); +GEN_VXFORM (vmaxub,2 ); +GEN_VXFORM (vmaxuh,66 ); +GEN_VXFORM (vmaxuw,130 ); +GEN_VXFORM (vmaxsb,258 ); +GEN_VXFORM (vmaxsh,322 ); +GEN_VXFORM (vmaxsw,386 ); +GEN_VXFORM (vminub,514 ); +GEN_VXFORM (vminuh,578 ); +GEN_VXFORM (vminuw,642 ); +GEN_VXFORM (vminsb,770 ); +GEN_VXFORM (vminsh,834 ); +GEN_VXFORM (vminsw,898 );GEN_VXFORM (vavgub,1026 );GEN_VXFORM (vavguh,1090 );GEN_VXFORM (vavguw,1154 );
Signature · 1 line
1.6.0.5
PATCH 9/42 target-ppc: add GEN_VXRFORM{, 1} macros for subsequent instructions.
In reply to Nathan Froyd--- target-ppc/translate.c | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+), 0 deletions(-)
target-ppc/translate.c +27 -0
@@ -6176,6 +6176,33 @@ GEN_VXFORM(vavgsb, 1282);GEN_VXFORM (vavgsh,1346 );GEN_VXFORM (vavgsw,1410 ); +#define GEN_VXRFORM1 (opname, name, str, xo, rc) \ + GEN_HANDLER2(name, str, 0x4, (xo >> 1) & 0x1f, ((xo >> 6) & 0x1f) | (rc << 4), 0x00000000, PPC_ALTIVEC) \ + { \ + TCGv_ptr ra, rb, rd; \ + TCGv_i32 result; \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \ + } \ + ra = gen_avr_ptr(rA(ctx->opcode)); \ + rb = gen_avr_ptr(rB(ctx->opcode)); \ + rd = gen_avr_ptr(rD(ctx->opcode)); \ + result = tcg_temp_new_i32(); \ + gen_helper_##opname (result, rd, ra, rb); \ + if (rc) { \ + tcg_gen_mov_i32(cpu_crf[6], result); \ + } \ + tcg_temp_free(ra); \ + tcg_temp_free(rb); \ + tcg_temp_free(rd); \ + tcg_temp_free_i32(result); \ + } + +#define GEN_VXRFORM (name, xo) \ + GEN_VXRFORM1(name, name, #name, xo, 0) \ + GEN_VXRFORM1(name, name##_, #name ".", xo, 1) +/*** SPE extension ***/ /* Register moves */
Signature · 1 line
1.6.0.5
PATCH 10/42 target-ppc: add vcmpequ{b, h, w} and vcmpgt{s, u}{b, h, w} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 9 +++++++++ target-ppc/op_helper.c | 33 +++++++++++++++++++++++++++++++++ target-ppc/translate.c | 10 ++++++++++ 3 files changed, 52 insertions(+), 0 deletions(-)
target-ppc/helper.h +9 -0
@@ -123,6 +123,15 @@ DEF_HELPER_3(vminuw, void, avr, avr, avr) DEF_HELPER_3(vmaxub, void, avr, avr, avr) DEF_HELPER_3(vmaxuh, void, avr, avr, avr) DEF_HELPER_3(vmaxuw, void, avr, avr, avr) +DEF_HELPER_3(vcmpequb, i32, avr, avr, avr) +DEF_HELPER_3(vcmpequh, i32, avr, avr, avr) +DEF_HELPER_3(vcmpequw, i32, avr, avr, avr) +DEF_HELPER_3(vcmpgtub, i32, avr, avr, avr) +DEF_HELPER_3(vcmpgtuh, i32, avr, avr, avr) +DEF_HELPER_3(vcmpgtuw, i32, avr, avr, avr) +DEF_HELPER_3(vcmpgtsb, i32, avr, avr, avr) +DEF_HELPER_3(vcmpgtsh, i32, avr, avr, avr) +DEF_HELPER_3(vcmpgtsw, i32, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +33 -0
@@ -2066,6 +2066,39 @@ VAVG(w, s32, int64_t, u32, uint64_t)#undef VAVG_DO#undef VAVG +#define VCMP (suffix, compare, element) \ + uint32_t helper_vcmp##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ + { \ + uint32_t ones = (sizeof (a->element[0]) == 4 \ + ? 0xffffffff \ + : (sizeof (a->element[0]) == 2 \ + ? 0xffff \ + : 0xff)); \ + uint32_t all = ones; \ + uint32_t none = 0; \ + VECTOR_FOR (element) { \ + uint32_t result = (a->element[i] compare b->element[i] ? ones : 0x0); \ + switch (sizeof (a->element[0])) { \ + case 4: r->u32[i] = result; break; \ + case 2: r->u16[i] = result; break; \ + case 1: r->u8[i] = result; break; \ + } \ + all &= result; \ + none |= result; \ + } \ + return ((all != 0) << 3) | ((none == 0) << 1); \ + } +VCMP(equb, ==, u8) +VCMP(equh, ==, u16) +VCMP(equw, ==, u32) +VCMP(gtub, >, u8) +VCMP(gtuh, >, u16) +VCMP(gtuw, >, u32) +VCMP(gtsb, >, s8) +VCMP(gtsh, >, s16) +VCMP(gtsw, >, s32) +#undef VCMP +#define VMINMAX_DO (name, compare, element) \ void helper_v##name (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \
target-ppc/translate.c +10 -0
@@ -6203,6 +6203,16 @@ GEN_VXFORM(vavgsw, 1410); GEN_VXRFORM1(name, name, #name, xo, 0) \ GEN_VXRFORM1(name, name##_, #name ".", xo, 1) +GEN_VXRFORM(vcmpequb, 6) +GEN_VXRFORM(vcmpequh, 70) +GEN_VXRFORM(vcmpequw, 134) +GEN_VXRFORM(vcmpgtsb, 774) +GEN_VXRFORM(vcmpgtsh, 838) +GEN_VXRFORM(vcmpgtsw, 902) +GEN_VXRFORM(vcmpgtub, 518) +GEN_VXRFORM(vcmpgtuh, 582) +GEN_VXRFORM (vcmpgtuw,646 ) +/*** SPE extension ***/ /* Register moves */
Signature · 1 line
1.6.0.5
PATCH 11/42 target-ppc: add vscr access macros.
In reply to Nathan Froyd--- target-ppc/cpu.h | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
target-ppc/cpu.h +7 -0
@@ -525,6 +525,13 @@ enum { 0x1F)/*****************************************************************************/ +/* Vector status and control register */ +#define VSCR_NJ 16/* Vector non-java */ +#define VSCR_SAT 0/* Vector saturation */ +#define vscr_nj (((env->vscr) >> VSCR_NJ) & 0x1) +#define vscr_sat (((env->vscr) >> VSCR_SAT) & 0x1) + +/*****************************************************************************/ /* The whole PowerPC CPU context */ #define NB_MMU_MODES 3
Signature · 1 line
1.6.0.5
PATCH 12/42 target-ppc: add vmrg{l, h}{b, h, w} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 6 ++++++ target-ppc/op_helper.c | 35 +++++++++++++++++++++++++++++++++++ target-ppc/translate.c | 6 ++++++ 3 files changed, 47 insertions(+), 0 deletions(-)
target-ppc/helper.h +6 -0
@@ -123,6 +123,12 @@ DEF_HELPER_3(vminuw, void, avr, avr, avr) DEF_HELPER_3(vmaxub, void, avr, avr, avr) DEF_HELPER_3(vmaxuh, void, avr, avr, avr) DEF_HELPER_3(vmaxuw, void, avr, avr, avr) +DEF_HELPER_3(vmrglb, void, avr, avr, avr) +DEF_HELPER_3(vmrglh, void, avr, avr, avr) +DEF_HELPER_3(vmrglw, void, avr, avr, avr) +DEF_HELPER_3(vmrghb, void, avr, avr, avr) +DEF_HELPER_3(vmrghh, void, avr, avr, avr) +DEF_HELPER_3(vmrghw, void, avr, avr, avr) DEF_HELPER_3(vcmpequb, i32, avr, avr, avr) DEF_HELPER_3(vcmpequh, i32, avr, avr, avr)DEF_HELPER_3 (vcmpequw, i32, avr, avr, avr)
target-ppc/op_helper.c +35 -0
@@ -2122,6 +2122,41 @@ VMINMAX(uw, u32)#undef VMINMAX_DO#undef VMINMAX +#define VMRG_DO (name, element, highp) \ + void helper_v##name (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ + { \ + ppc_avr_t result; \ + int i; \ + size_t n_elems = N_ELEMS(element); \ + for (i = 0; i < n_elems/2; i++) { \ + if (highp) { \ + result.element[i*2+HI_IDX] = a->element[i]; \ + result.element[i*2+LO_IDX] = b->element[i]; \ + } else { \ + result.element[n_elems - i*2 - (1+HI_IDX)] = b->element[n_elems - i - 1]; \ + result.element[n_elems - i*2 - (1+LO_IDX)] = a->element[n_elems - i - 1]; \ + } \ + } \ + *r = result; \ + } +#if defined(WORDS_BIGENDIAN ) +#define MRGHI 0 +#define MRGL0 1 +#else +#define MRGHI 1 +#define MRGLO 0 +#endif +#define VMRG (suffix, element) \ + VMRG_DO(mrgl##suffix, element, MRGHI) \ + VMRG_DO(mrgh##suffix, element, MRGLO) +VMRG(b, u8) +VMRG(h, u16) +VMRG(w, u32) +#undef VMRG_DO +#undef VMRG +#undef MRGHI +#undef MRGLO +#undef VECTOR_FOR#undef VECTOR_FOR_I#undef VECTOR_FOR_INORDER_I
target-ppc/translate.c +6 -0
@@ -6175,6 +6175,12 @@ GEN_VXFORM(vavguw, 1154);GEN_VXFORM (vavgsb,1282 );GEN_VXFORM (vavgsh,1346 );GEN_VXFORM (vavgsw,1410 ); +GEN_VXFORM (vmrghb,12 ); +GEN_VXFORM (vmrghh,76 ); +GEN_VXFORM (vmrghw,140 ); +GEN_VXFORM (vmrglb,268 ); +GEN_VXFORM (vmrglh,332 ); +GEN_VXFORM (vmrglw,396 );#define GEN_VXRFORM1 (opname, name, str, xo, rc) \ GEN_HANDLER2(name, str, 0x4, (xo >> 1) & 0x1f, ((xo >> 6) & 0x1f) | (rc << 4), 0x00000000, PPC_ALTIVEC) \
Signature · 1 line
1.6.0.5
PATCH 13/42 target-ppc: add vmul{e, o}{s, u}{b, h} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 8 ++++++++ target-ppc/op_helper.c | 22 ++++++++++++++++++++++ target-ppc/translate.c | 8 ++++++++ 3 files changed, 38 insertions(+), 0 deletions(-)
target-ppc/helper.h +8 -0
@@ -138,6 +138,14 @@ DEF_HELPER_3(vcmpgtuw, i32, avr, avr, avr) DEF_HELPER_3(vcmpgtsb, i32, avr, avr, avr) DEF_HELPER_3(vcmpgtsh, i32, avr, avr, avr) DEF_HELPER_3(vcmpgtsw, i32, avr, avr, avr) +DEF_HELPER_3(vmulesb, void, avr, avr, avr) +DEF_HELPER_3(vmulesh, void, avr, avr, avr) +DEF_HELPER_3(vmuleub, void, avr, avr, avr) +DEF_HELPER_3(vmuleuh, void, avr, avr, avr) +DEF_HELPER_3(vmulosb, void, avr, avr, avr) +DEF_HELPER_3(vmulosh, void, avr, avr, avr) +DEF_HELPER_3(vmuloub, void, avr, avr, avr) +DEF_HELPER_3(vmulouh, void, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +22 -0
@@ -2157,6 +2157,28 @@ VMRG(w, u32)#undef MRGHI#undef MRGLO +#define VMUL_DO (name, mul_element, prod_element, evenp) \ + void helper_v##name (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ + { \ + int i; \ + VECTOR_FOR_INORDER_I(i, prod_element) { \ + if (evenp) { \ + r->prod_element[i] = b->mul_element[i*2+HI_IDX] * b->mul_element[i*2+HI_IDX]; \ + } else { \ + r->prod_element[i] = a->mul_element[i*2+LO_IDX] * b->mul_element[i*2+LO_IDX]; \ + } \ + } \ + } +#define VMUL (suffix, mul_element, prod_element) \ + VMUL_DO(mule##suffix, mul_element, prod_element, 1) \ + VMUL_DO(mulo##suffix, mul_element, prod_element, 0) +VMUL(sb, s8, s16) +VMUL(sh, s16, s32) +VMUL(ub, u8, u16) +VMUL(uh, u16, u32) +#undef VMUL_DO +#undef VMUL +#undef VECTOR_FOR#undef VECTOR_FOR_I#undef VECTOR_FOR_INORDER_I
target-ppc/translate.c +8 -0
@@ -6181,6 +6181,14 @@ GEN_VXFORM(vmrghw, 140);GEN_VXFORM (vmrglb,268 );GEN_VXFORM (vmrglh,332 );GEN_VXFORM (vmrglw,396 ); +GEN_VXFORM (vmuloub,8 ); +GEN_VXFORM (vmulouh,72 ); +GEN_VXFORM (vmulosb,264 ); +GEN_VXFORM (vmulosh,328 ); +GEN_VXFORM (vmuleub,520 ); +GEN_VXFORM (vmuleuh,584 ); +GEN_VXFORM (vmulesb,776 ); +GEN_VXFORM (vmulesh,840 );#define GEN_VXRFORM1 (opname, name, str, xo, rc) \ GEN_HANDLER2(name, str, 0x4, (xo >> 1) & 0x1f, ((xo >> 6) & 0x1f) | (rc << 4), 0x00000000, PPC_ALTIVEC) \
Signature · 1 line
1.6.0.5
PATCH 14/42 target-ppc: add vsr{, a}{b, h, w} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 6 ++++++ target-ppc/op_helper.c | 17 +++++++++++++++++ target-ppc/translate.c | 6 ++++++ 3 files changed, 29 insertions(+), 0 deletions(-)
target-ppc/helper.h +6 -0
@@ -146,6 +146,12 @@ DEF_HELPER_3(vmulosb, void, avr, avr, avr) DEF_HELPER_3(vmulosh, void, avr, avr, avr) DEF_HELPER_3(vmuloub, void, avr, avr, avr) DEF_HELPER_3(vmulouh, void, avr, avr, avr) +DEF_HELPER_3(vsrab, void, avr, avr, avr) +DEF_HELPER_3(vsrah, void, avr, avr, avr) +DEF_HELPER_3(vsraw, void, avr, avr, avr) +DEF_HELPER_3(vsrb, void, avr, avr, avr) +DEF_HELPER_3(vsrh, void, avr, avr, avr) +DEF_HELPER_3(vsrw, void, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +17 -0
@@ -2179,6 +2179,23 @@ VMUL(uh, u16, u32)#undef VMUL_DO#undef VMUL +#define VSR (suffix, element) \ + void helper_vsr##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ + { \ + VECTOR_FOR (element) { \ + unsigned int mask = ((1 << (3 + (sizeof (a->element[0]) >> 1))) - 1); \ + unsigned int shift = b->element[i] & mask; \ + r->element[i] = a->element[i] >> shift; \ + } \ + } +VSR(ab, s8) +VSR(ah, s16) +VSR(aw, s32) +VSR(b, u8) +VSR(h, u16) +VSR(w, u32) +#undef VSR +#undef VECTOR_FOR#undef VECTOR_FOR_I#undef VECTOR_FOR_INORDER_I
target-ppc/translate.c +6 -0
@@ -6189,6 +6189,12 @@ GEN_VXFORM(vmuleub, 520);GEN_VXFORM (vmuleuh,584 );GEN_VXFORM (vmulesb,776 );GEN_VXFORM (vmulesh,840 ); +GEN_VXFORM (vsrb,516 ); +GEN_VXFORM (vsrh,580 ); +GEN_VXFORM (vsrw,644 ); +GEN_VXFORM (vsrab,772 ); +GEN_VXFORM (vsrah,836 ); +GEN_VXFORM (vsraw,900 );#define GEN_VXRFORM1 (opname, name, str, xo, rc) \ GEN_HANDLER2(name, str, 0x4, (xo >> 1) & 0x1f, ((xo >> 6) & 0x1f) | (rc << 4), 0x00000000, PPC_ALTIVEC) \
Signature · 1 line
1.6.0.5
PATCH 15/42 target-ppc: add vsl{b, h, w} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 3 +++ target-ppc/op_helper.c | 14 ++++++++++++++ target-ppc/translate.c | 3 +++ 3 files changed, 20 insertions(+), 0 deletions(-)
target-ppc/helper.h +3 -0
@@ -152,6 +152,9 @@ DEF_HELPER_3(vsraw, void, avr, avr, avr) DEF_HELPER_3(vsrb, void, avr, avr, avr) DEF_HELPER_3(vsrh, void, avr, avr, avr) DEF_HELPER_3(vsrw, void, avr, avr, avr) +DEF_HELPER_3(vslb, void, avr, avr, avr) +DEF_HELPER_3(vslh, void, avr, avr, avr) +DEF_HELPER_3(vslw, void, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +14 -0
@@ -2179,6 +2179,20 @@ VMUL(uh, u16, u32)#undef VMUL_DO#undef VMUL +#define VSL (suffix, element) \ + void helper_vsl##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ + { \ + VECTOR_FOR (element) { \ + unsigned int mask = ((1 << (3 + (sizeof (a->element[0]) >> 1))) - 1); \ + unsigned int shift = b->element[i] & mask; \ + r->element[i] = a->element[i] << shift; \ + } \ + } +VSL(b, u8) +VSL(h, u16) +VSL(w, u32) +#undef VSL +#define VSR (suffix, element) \ void helper_vsr##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \
target-ppc/translate.c +3 -0
@@ -6189,6 +6189,9 @@ GEN_VXFORM(vmuleub, 520);GEN_VXFORM (vmuleuh,584 );GEN_VXFORM (vmulesb,776 );GEN_VXFORM (vmulesh,840 ); +GEN_VXFORM (vslb,260 ); +GEN_VXFORM (vslh,324 ); +GEN_VXFORM (vslw,388 );GEN_VXFORM (vsrb,516 );GEN_VXFORM (vsrh,580 );GEN_VXFORM (vsrw,644 );
Signature · 1 line
1.6.0.5
PATCH 16/42 target-ppc: add vs{l,r}o instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 2 ++ target-ppc/op_helper.c | 27 +++++++++++++++++++++++++++ target-ppc/translate.c | 2 ++ 3 files changed, 31 insertions(+), 0 deletions(-)
target-ppc/helper.h +2 -0
@@ -155,6 +155,8 @@ DEF_HELPER_3(vsrw, void, avr, avr, avr) DEF_HELPER_3(vslb, void, avr, avr, avr) DEF_HELPER_3(vslh, void, avr, avr, avr) DEF_HELPER_3(vslw, void, avr, avr, avr) +DEF_HELPER_3(vslo, void, avr, avr, avr) +DEF_HELPER_3(vsro, void, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +27 -0
@@ -17,6 +17,7 @@* License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <string.h> #include "exec.h" #include "host-utils.h" #include "helper.h"
@@ -2193,6 +2194,19 @@ VSL(h, u16) VSL(w, u32)#undef VSL +void helper_vslo (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b) +{ +int sh = (b->u8[LO_IDX *0xf ] >>3 ) &0xf ; + +#if defined (WORDS_BIGENDIAN ) +memmove (&r->u8[0 ], &a->u8[sh],0x10 -sh); +memset (&r->u8[16 -sh],0 , sh); +#else +memmove (&r->u8[sh], &a->u8[0 ],0x10 -sh); +memset (&r->u8[0 ],0 , sh); +#endif +} +#define VSR (suffix, element) \ void helper_vsr##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \
@@ -2210,6 +2224,19 @@ VSR(h, u16) VSR(w, u32)#undef VSR +void helper_vsro (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b) +{ +int sh = (b->u8[LO_IDX *0xf ] >>3 ) &0xf ; + +#if defined (WORDS_BIGENDIAN ) +memmove (&r->u8[sh], &a->u8[0 ],0x10 -sh); +memset (&r->u8[0 ],0 , sh); +#else +memmove (&r->u8[0 ], &a->u8[sh],0x10 -sh); +memset (&r->u8[0x10 -sh],0 , sh); +#endif +} +#undef VECTOR_FOR#undef VECTOR_FOR_I#undef VECTOR_FOR_INORDER_I
target-ppc/translate.c +2 -0
@@ -6198,6 +6198,8 @@ GEN_VXFORM(vsrw, 644);GEN_VXFORM (vsrab,772 );GEN_VXFORM (vsrah,836 );GEN_VXFORM (vsraw,900 ); +GEN_VXFORM (vslo,1036 ); +GEN_VXFORM (vsro,1100 );#define GEN_VXRFORM1 (opname, name, str, xo, rc) \ GEN_HANDLER2(name, str, 0x4, (xo >> 1) & 0x1f, ((xo >> 6) & 0x1f) | (rc << 4), 0x00000000, PPC_ALTIVEC) \
Signature · 1 line
1.6.0.5
PATCH 17/42 target-ppc: add v{add, sub}cuw instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 2 ++ target-ppc/op_helper.c | 14 ++++++++++++++ target-ppc/translate.c | 2 ++ 3 files changed, 18 insertions(+), 0 deletions(-)
target-ppc/helper.h +2 -0
@@ -157,6 +157,8 @@ DEF_HELPER_3(vslh, void, avr, avr, avr) DEF_HELPER_3(vslw, void, avr, avr, avr) DEF_HELPER_3(vslo, void, avr, avr, avr) DEF_HELPER_3(vsro, void, avr, avr, avr) +DEF_HELPER_3(vaddcuw, void, avr, avr, avr) +DEF_HELPER_3(vsubcuw, void, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +14 -0
@@ -2033,6 +2033,13 @@ target_ulong helper_dlmzb (target_ulong high, target_ulong low, uint32_t update_ for (index = N_ELEMS(element)-1; index >= 0; index--)#endif +void helper_vaddcuw (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b) +{ +VECTOR_FOR (u32) { + r->u32[i] = ~a->u32[i] < b->u32[i]; + } +} +#define VARITH_DO (name, op, element) \ void helper_v##name (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \
@@ -2237,6 +2244,13 @@ void helper_vsro (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)#endif } +void helper_vsubcuw (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b) +{ +VECTOR_FOR (u32) { + r->u32[i] = a->u32[i] >= b->u32[i]; + } +} +#undef VECTOR_FOR#undef VECTOR_FOR_I#undef VECTOR_FOR_INORDER_I
target-ppc/translate.c +2 -0
@@ -6200,6 +6200,8 @@ GEN_VXFORM(vsrah, 836);GEN_VXFORM (vsraw,900 );GEN_VXFORM (vslo,1036 );GEN_VXFORM (vsro,1100 ); +GEN_VXFORM (vaddcuw,384 ); +GEN_VXFORM (vsubcuw,1408 );#define GEN_VXRFORM1 (opname, name, str, xo, rc) \ GEN_HANDLER2(name, str, 0x4, (xo >> 1) & 0x1f, ((xo >> 6) & 0x1f) | (rc << 4), 0x00000000, PPC_ALTIVEC) \
Signature · 1 line
1.6.0.5
PATCH 18/42 target-ppc: add lvs{l,r} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 2 ++ target-ppc/op_helper.c | 18 ++++++++++++++++++ target-ppc/translate.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 0 deletions(-)
target-ppc/helper.h +2 -0
@@ -159,6 +159,8 @@ DEF_HELPER_3(vslo, void, avr, avr, avr) DEF_HELPER_3(vsro, void, avr, avr, avr) DEF_HELPER_3(vaddcuw, void, avr, avr, avr) DEF_HELPER_3(vsubcuw, void, avr, avr, avr) +DEF_HELPER_2 (lvsl, void, avr, tl); +DEF_HELPER_2 (lvsr, void, avr, tl); DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +18 -0
@@ -2033,6 +2033,24 @@ target_ulong helper_dlmzb (target_ulong high, target_ulong low, uint32_t update_ for (index = N_ELEMS(element)-1; index >= 0; index--)#endif +void helper_lvsl (ppc_avr_t *r,target_ulong sh) +{ +int i, j = (sh &0xf ); + + VECTOR_FOR_INORDER_I (i, u8) { + r->u8[i] = j++; + } +} + +void helper_lvsr (ppc_avr_t *r,target_ulong sh) +{ +int i, j =0x10 - (sh &0xf ); + + VECTOR_FOR_INORDER_I (i, u8) { + r->u8[i] = j++; + } +} +void helper_vaddcuw (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b) {VECTOR_FOR (u32) {
target-ppc/translate.c +32 -0
@@ -6116,6 +6116,38 @@ GEN_VR_STX(svx, 0x07, 0x07);/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */ GEN_VR_STX (svxl,0x07 ,0x0F ); +GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC) +{ +TCGv_ptr rd; +TCGv EA ; +if (unlikely (!ctx->altivec_enabled)) { +gen_exception (ctx,POWERPC_EXCP_VPU ); +return ; + } +EA =tcg_temp_new (); +gen_addr_reg_index (ctx,EA ); + rd =gen_avr_ptr (rD (ctx->opcode)); +gen_helper_lvsl (rd,EA ); +tcg_temp_free (EA ); +tcg_temp_free (rd); +} + +GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC) +{ +TCGv_ptr rd; +TCGv EA ; +if (unlikely (!ctx->altivec_enabled)) { +gen_exception (ctx,POWERPC_EXCP_VPU ); +return ; + } +EA =tcg_temp_new (); +gen_addr_reg_index (ctx,EA ); + rd =gen_avr_ptr (rD (ctx->opcode)); +gen_helper_lvsr (rd,EA ); +tcg_temp_free (EA ); +tcg_temp_free (rd); +} +/* Logical operations */ #define GEN_VX_LOGICAL (name, tcg_op, xo) \ GEN_HANDLER(name, 0x04, (xo >> 1) & 0x1f, (xo >> 6) & 0x1f, 0x00000000, PPC_ALTIVEC) \
Signature · 1 line
1.6.0.5
PATCH 19/42 target-ppc: add m{f, t}vscr instructions.
In reply to Nathan Froyd--- target-ppc/translate.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 41 insertions(+), 0 deletions(-)
target-ppc/translate.c +41 -0
@@ -68,6 +68,7 @@ static TCGv cpu_lr;static TCGv cpu_xer;static TCGv cpu_reserve;static TCGv_i32 cpu_fpscr; +static TCGv_i32 cpu_vscr;static TCGv_i32 cpu_access_type;#include "gen-icount.h"
@@ -151,6 +152,9 @@ void ppc_translate_init(void) cpu_fpscr =tcg_global_mem_new_i32 (TCG_AREG0 , offsetof(CPUState , fpscr),"fpscr" ); + cpu_vscr =tcg_global_mem_new_i32 (TCG_AREG0 , + offsetof(CPUState , vscr),"vscr" ); + cpu_access_type =tcg_global_mem_new_i32 (TCG_AREG0 , offsetof(CPUState , access_type),"access_type" );
@@ -6148,6 +6152,43 @@ GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC)tcg_temp_free (rd); } +static always_inline void gen_vscr_ptr (TCGv_ptr p, int r) +{ +#if defined(WORDS_BIGENDIAN ) + tcg_gen_addi_ptr(p, cpu_env, offsetof(CPUPPCState, avr[r].u32[3])); +#else + tcg_gen_addi_ptr(p, cpu_env, offsetof(CPUPPCState, avr[r].u32[0])); +#endif +} + +GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC) +{ +TCGv_ptr p; +if (unlikely (!ctx->altivec_enabled)) { +gen_exception (ctx,POWERPC_EXCP_VPU ); +return ; + } + p =tcg_temp_new (); +tcg_gen_movi_i64 (cpu_avrh[rD (ctx->opcode)],0 ); +tcg_gen_movi_i64 (cpu_avrl[rD (ctx->opcode)],0 ); +gen_vscr_ptr (p,rD (ctx->opcode)); +tcg_gen_mov_i32 (p, cpu_vscr); +tcg_temp_free (p); +} + +GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC) +{ +TCGv_ptr p; +if (unlikely (!ctx->altivec_enabled)) { +gen_exception (ctx,POWERPC_EXCP_VPU ); +return ; + } + p =tcg_temp_new (); +gen_vscr_ptr (p,rB (ctx->opcode)); +tcg_gen_mov_i32 (cpu_vscr, p); +tcg_temp_free (p); +} +/* Logical operations */ #define GEN_VX_LOGICAL (name, tcg_op, xo) \ GEN_HANDLER(name, 0x04, (xo >> 1) & 0x1f, (xo >> 6) & 0x1f, 0x00000000, PPC_ALTIVEC) \
Signature · 1 line
1.6.0.5
PATCH 20/42 target-ppc: add v{add, sub}{s, u}{b, h, w}s instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 12 ++++++++++++ target-ppc/op_helper.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ target-ppc/translate.c | 12 ++++++++++++ 3 files changed, 69 insertions(+), 0 deletions(-)
target-ppc/helper.h +12 -0
@@ -161,6 +161,18 @@ DEF_HELPER_3(vaddcuw, void, avr, avr, avr) DEF_HELPER_3(vsubcuw, void, avr, avr, avr)DEF_HELPER_2 (lvsl, void, avr, tl);DEF_HELPER_2 (lvsr, void, avr, tl); +DEF_HELPER_3(vaddsbs, void, avr, avr, avr) +DEF_HELPER_3(vaddshs, void, avr, avr, avr) +DEF_HELPER_3(vaddsws, void, avr, avr, avr) +DEF_HELPER_3(vsubsbs, void, avr, avr, avr) +DEF_HELPER_3(vsubshs, void, avr, avr, avr) +DEF_HELPER_3(vsubsws, void, avr, avr, avr) +DEF_HELPER_3(vaddubs, void, avr, avr, avr) +DEF_HELPER_3(vadduhs, void, avr, avr, avr) +DEF_HELPER_3(vadduws, void, avr, avr, avr) +DEF_HELPER_3(vsububs, void, avr, avr, avr) +DEF_HELPER_3(vsubuhs, void, avr, avr, avr) +DEF_HELPER_3(vsubuws, void, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +45 -0
51 lines not on this page · raw message
target-ppc/translate.c +12 -0
@@ -6275,6 +6275,18 @@ GEN_VXFORM(vslo, 1036);GEN_VXFORM (vsro,1100 );GEN_VXFORM (vaddcuw,384 );GEN_VXFORM (vsubcuw,1408 ); +GEN_VXFORM (vaddubs,512 ); +GEN_VXFORM (vadduhs,576 ); +GEN_VXFORM (vadduws,640 ); +GEN_VXFORM (vaddsbs,768 ); +GEN_VXFORM (vaddshs,832 ); +GEN_VXFORM (vaddsws,896 ); +GEN_VXFORM (vsububs,1536 ); +GEN_VXFORM (vsubuhs,1600 ); +GEN_VXFORM (vsubuws,1664 ); +GEN_VXFORM (vsubsbs,1792 ); +GEN_VXFORM (vsubshs,1856 ); +GEN_VXFORM (vsubsws,1920 );#define GEN_VXRFORM1 (opname, name, str, xo, rc) \ GEN_HANDLER2(name, str, 0x4, (xo >> 1) & 0x1f, ((xo >> 6) & 0x1f) | (rc << 4), 0x00000000, PPC_ALTIVEC) \
Signature · 1 line
1.6.0.5
PATCH 21/42 target-ppc: add vrl{b, h, w} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 3 +++ target-ppc/op_helper.c | 14 ++++++++++++++ target-ppc/translate.c | 3 +++ 3 files changed, 20 insertions(+), 0 deletions(-)
target-ppc/helper.h +3 -0
@@ -173,6 +173,9 @@ DEF_HELPER_3(vadduws, void, avr, avr, avr) DEF_HELPER_3(vsububs, void, avr, avr, avr) DEF_HELPER_3(vsubuhs, void, avr, avr, avr) DEF_HELPER_3(vsubuws, void, avr, avr, avr) +DEF_HELPER_3(vrlb, void, avr, avr, avr) +DEF_HELPER_3(vrlh, void, avr, avr, avr) +DEF_HELPER_3(vrlw, void, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +14 -0
@@ -2250,6 +2250,20 @@ VMUL(uh, u16, u32)#undef VMUL_DO#undef VMUL +#define VROTATE (suffix, element) \ + void helper_vrl##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ + { \ + VECTOR_FOR (element) { \ + unsigned int mask = ((1 << (3 + (sizeof (a->element[0]) >> 1))) - 1); \ + unsigned int shift = b->element[i] & mask; \ + r->element[i] = (a->element[i] << shift) | (a->element[i] >> (sizeof(a->element[0]) * 8 - shift)); \ + } \ + } +VROTATE(b, u8) +VROTATE(h, u16) +VROTATE(w, u32) +#undef VROTATE +#define VSL (suffix, element) \ void helper_vsl##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \
target-ppc/translate.c +3 -0
@@ -6287,6 +6287,9 @@ GEN_VXFORM(vsubuws, 1664);GEN_VXFORM (vsubsbs,1792 );GEN_VXFORM (vsubshs,1856 );GEN_VXFORM (vsubsws,1920 ); +GEN_VXFORM (vrlb,4 ); +GEN_VXFORM (vrlh,68 ); +GEN_VXFORM (vrlw,132 );#define GEN_VXRFORM1 (opname, name, str, xo, rc) \ GEN_HANDLER2(name, str, 0x4, (xo >> 1) & 0x1f, ((xo >> 6) & 0x1f) | (rc << 4), 0x00000000, PPC_ALTIVEC) \
Signature · 1 line
1.6.0.5
PATCH 22/42 target-ppc: add vs{l,r} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 2 ++ target-ppc/op_helper.c | 35 +++++++++++++++++++++++++++++++++++ target-ppc/translate.c | 2 ++ 3 files changed, 39 insertions(+), 0 deletions(-)
target-ppc/helper.h +2 -0
@@ -176,6 +176,8 @@ DEF_HELPER_3(vsubuws, void, avr, avr, avr) DEF_HELPER_3(vrlb, void, avr, avr, avr) DEF_HELPER_3(vrlh, void, avr, avr, avr) DEF_HELPER_3(vrlw, void, avr, avr, avr) +DEF_HELPER_3(vsl, void, avr, avr, avr) +DEF_HELPER_3(vsr, void, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +35 -0
@@ -2264,6 +2264,41 @@ VROTATE(h, u16) VROTATE(w, u32)#undef VROTATE +#if defined(WORDS_BIGENDIAN ) +#define LEFT 0 +#define RIGHT 1 +#else +#define LEFT 1 +#define RIGHT 0 +#endif +#define VSHIFT (suffix, leftp) \ + void helper_vs##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ + { \ + int shift = b->u8[LO_IDX*0x15] & 0x7; \ + int doit = 1; \ + VECTOR_FOR (u8) { \ + doit = doit && ((b->u8[i] & 0x7) == shift); \ + } \ + if (doit) { \ + if (shift == 0) { \ + return; \ + } else if (leftp) { \ + uint64_t carry = a->u64[LO_IDX] >> (64 - shift); \ + r->u64[HI_IDX] = (a->u64[HI_IDX] << shift) | carry; \ + r->u64[LO_IDX] <<= shift; \ + } else { \ + uint64_t carry = a->u64[HI_IDX] << (64 - shift); \ + r->u64[LO_IDX] = (a->u64[LO_IDX] >> shift) | carry; \ + r->u64[HI_IDX] >>= shift; \ + } \ + } \ + } +VSHIFT(l, LEFT) +VSHIFT(r, RIGHT) +#undef VSHIFT +#undef LEFT +#undef RIGHT +#define VSL (suffix, element) \ void helper_vsl##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \
target-ppc/translate.c +2 -0
@@ -6290,6 +6290,8 @@ GEN_VXFORM(vsubsws, 1920);GEN_VXFORM (vrlb,4 );GEN_VXFORM (vrlh,68 );GEN_VXFORM (vrlw,132 ); +GEN_VXFORM (vsl,452 ); +GEN_VXFORM (vsr,708 );#define GEN_VXRFORM1 (opname, name, str, xo, rc) \ GEN_HANDLER2(name, str, 0x4, (xo >> 1) & 0x1f, ((xo >> 6) & 0x1f) | (rc << 4), 0x00000000, PPC_ALTIVEC) \
Signature · 1 line
1.6.0.5
PATCH 23/42 target-ppc: add vsldoi instruction.
In reply to Nathan Froyd--- target-ppc/helper.h | 1 + target-ppc/op_helper.c | 28 ++++++++++++++++++++++++++++ target-ppc/translate.c | 21 +++++++++++++++++++++ 3 files changed, 50 insertions(+), 0 deletions(-)
target-ppc/helper.h +1 -0
@@ -178,6 +178,7 @@ DEF_HELPER_3(vrlh, void, avr, avr, avr) DEF_HELPER_3(vrlw, void, avr, avr, avr) DEF_HELPER_3(vsl, void, avr, avr, avr) DEF_HELPER_3(vsr, void, avr, avr, avr) +DEF_HELPER_4(vsldoi, void, avr, avr, avr, i32) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +28 -0
@@ -2313,6 +2313,34 @@ VSL(h, u16) VSL(w, u32)#undef VSL +void helper_vsldoi (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b,uint32_t shift) +{ +int sh = shift &0xf ; +int i; +ppc_avr_t result; + +#if defined(WORDS_BIGENDIAN ) + VECTOR_FOR_I (i, u8) { +int index = sh + i; +if (index >0xf ) { + result.u8[i] = b->u8[index-0x10 ]; + }else { + result.u8[i] = a->u8[index]; + } + } +#else + VECTOR_FOR_I (i, u8) { +int index = (16 - sh) + i; +if (index >0xf ) { + result.u8[i] = a->u8[index-0x10 ]; + }else { + result.u8[i] = b->u8[index]; + } + } +#endif + *r = result; +} +void helper_vslo (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b) {int sh = (b->u8[LO_IDX *0xf ] >>3 ) &0xf ;
target-ppc/translate.c +21 -0
@@ -378,6 +378,8 @@ EXTRACT_HELPER(UIMM, 0, 16);EXTRACT_HELPER (NB ,11 ,5 );/* Shift count */ EXTRACT_HELPER (SH ,11 ,5 ); +/* Vector shift count */ +EXTRACT_HELPER (VSH ,6 ,4 );/* Mask start */ EXTRACT_HELPER (MB ,6 ,5 );/* Mask end */
@@ -6330,6 +6332,25 @@ GEN_VXRFORM(vcmpgtub, 518) GEN_VXRFORM(vcmpgtuh, 582) GEN_VXRFORM(vcmpgtuw, 646) +GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC) +{ +TCGv_ptr ra, rb, rd; +TCGv sh; +if (unlikely (!ctx->altivec_enabled)) { +gen_exception (ctx,POWERPC_EXCP_VPU ); +return ; + } + ra =gen_avr_ptr (rA (ctx->opcode)); + rb =gen_avr_ptr (rB (ctx->opcode)); + rd =gen_avr_ptr (rD (ctx->opcode)); + sh =tcg_const_i32 (VSH (ctx->opcode)); +gen_helper_vsldoi (rd, ra, rb, sh); +tcg_temp_free (ra); +tcg_temp_free (rb); +tcg_temp_free (rd); +tcg_temp_free (sh); +} +/*** SPE extension ***/ /* Register moves */
Signature · 1 line
1.6.0.5
PATCH 24/42 target-ppc: add GEN_VXFORM_SIMM macro for subsequent instructions.
In reply to Nathan Froyd--- target-ppc/translate.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)
target-ppc/translate.c +18 -0
@@ -374,6 +374,8 @@ EXTRACT_HELPER(IMM, 12, 8);EXTRACT_SHELPER (SIMM ,0 ,16 );/* 16 bits unsigned immediate value */ EXTRACT_HELPER (UIMM ,0 ,16 ); +/* 5 bits signed immediate value */ +EXTRACT_HELPER (SIMM5 ,16 ,5 );/* Bit count */ EXTRACT_HELPER (NB ,11 ,5 );/* Shift count */
@@ -6295,6 +6297,22 @@ GEN_VXFORM(vrlw, 132);GEN_VXFORM (vsl,452 );GEN_VXFORM (vsr,708 ); +#define GEN_VXFORM_SIMM (name, xo) \ + GEN_HANDLER(name, 0x04, (xo >> 1) & 0x1f, (xo >> 6) & 0x1f, 0x00000000, PPC_ALTIVEC) \ + { \ + TCGv_ptr rd; \ + TCGv_i32 simm; \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \ + } \ + simm = tcg_const_i32(SIMM5(ctx->opcode)); \ + rd = gen_avr_ptr(rD(ctx->opcode)); \ + gen_helper_##name (rd, simm); \ + tcg_temp_free_i32(simm); \ + tcg_temp_free(rd); \ + } +#define GEN_VXRFORM1 (opname, name, str, xo, rc) \ GEN_HANDLER2(name, str, 0x4, (xo >> 1) & 0x1f, ((xo >> 6) & 0x1f) | (rc << 4), 0x00000000, PPC_ALTIVEC) \ { \
Signature · 1 line
1.6.0.5
PATCH 25/42 target-ppc: add vspltis{b, h, w} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 3 +++ target-ppc/op_helper.c | 16 ++++++++++++++++ target-ppc/translate.c | 4 ++++ 3 files changed, 23 insertions(+), 0 deletions(-)
target-ppc/helper.h +3 -0
@@ -179,6 +179,9 @@ DEF_HELPER_3(vrlw, void, avr, avr, avr) DEF_HELPER_3(vsl, void, avr, avr, avr) DEF_HELPER_3(vsr, void, avr, avr, avr) DEF_HELPER_4(vsldoi, void, avr, avr, avr, i32) +DEF_HELPER_2(vspltisb, void, avr, i32) +DEF_HELPER_2(vspltish, void, avr, i32) +DEF_HELPER_2(vspltisw, void, avr, i32) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +16 -0
@@ -2354,6 +2354,22 @@ void helper_vslo (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)#endif } +#define VSPLTI (suffix, element, splat_type) \ + void helper_vspltis##suffix (ppc_avr_t *r, uint32_t splat) \ + { \ + splat_type x = (splat_type)splat; \ +/* 5-bit sign extension. */ \ +if (x &0x10 ) \ + x -=0x20 ; \ +VECTOR_FOR (element) { \ + r->element[i] = x; \ + } \ + } +VSPLTI(b, s8, int8_t) +VSPLTI(h, s16, int16_t) +VSPLTI(w, s32, int32_t) +#undef VSPLTI +#define VSR (suffix, element) \ void helper_vsr##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \
target-ppc/translate.c +4 -0
@@ -6313,6 +6313,10 @@ GEN_VXFORM(vsr, 708);tcg_temp_free (rd); \ } +GEN_VXFORM_SIMM (vspltisb,780 ); +GEN_VXFORM_SIMM (vspltish,844 ); +GEN_VXFORM_SIMM (vspltisw,908 ); +#define GEN_VXRFORM1 (opname, name, str, xo, rc) \ GEN_HANDLER2(name, str, 0x4, (xo >> 1) & 0x1f, ((xo >> 6) & 0x1f) | (rc << 4), 0x00000000, PPC_ALTIVEC) \ { \
Signature · 1 line
1.6.0.5
PATCH 26/42 target-ppc: add GEN_VXFORM_UIMM macro for subsequent instructions.
In reply to Nathan Froyd--- target-ppc/translate.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-)
target-ppc/translate.c +20 -0
@@ -376,6 +376,8 @@ EXTRACT_SHELPER(SIMM, 0, 16);EXTRACT_HELPER (UIMM ,0 ,16 );/* 5 bits signed immediate value */ EXTRACT_HELPER (SIMM5 ,16 ,5 ); +/* 5 bits signed immediate value */ +EXTRACT_HELPER (UIMM5 ,16 ,5 );/* Bit count */ EXTRACT_HELPER (NB ,11 ,5 );/* Shift count */
@@ -6317,6 +6319,24 @@ GEN_VXFORM_SIMM(vspltisb, 780);GEN_VXFORM_SIMM (vspltish,844 );GEN_VXFORM_SIMM (vspltisw,908 ); +#define GEN_VXFORM_UIMM (name, xo) \ + GEN_HANDLER(name, 0x04, (xo >> 1) & 0x1f, (xo >> 6) & 0x1f, 0x00000000, PPC_ALTIVEC) \ + { \ + TCGv_ptr rb, rd; \ + TCGv_i32 uimm; \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \ + } \ + uimm = tcg_const_i32(UIMM5(ctx->opcode)); \ + rb = gen_avr_ptr(rB(ctx->opcode)); \ + rd = gen_avr_ptr(rD(ctx->opcode)); \ + gen_helper_##name (rd, rb, uimm); \ + tcg_temp_free_i32(uimm); \ + tcg_temp_free(rb); \ + tcg_temp_free(rd); \ + } +#define GEN_VXRFORM1 (opname, name, str, xo, rc) \ GEN_HANDLER2(name, str, 0x4, (xo >> 1) & 0x1f, ((xo >> 6) & 0x1f) | (rc << 4), 0x00000000, PPC_ALTIVEC) \ { \
Signature · 1 line
1.6.0.5
PATCH 27/42 target-ppc: add vsplt{b, h, w} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 3 +++ target-ppc/op_helper.c | 22 ++++++++++++++++++++++ target-ppc/translate.c | 4 ++++ 3 files changed, 29 insertions(+), 0 deletions(-)
target-ppc/helper.h +3 -0
@@ -182,6 +182,9 @@ DEF_HELPER_4(vsldoi, void, avr, avr, avr, i32) DEF_HELPER_2(vspltisb, void, avr, i32) DEF_HELPER_2(vspltish, void, avr, i32) DEF_HELPER_2(vspltisw, void, avr, i32) +DEF_HELPER_3(vspltb, void, avr, avr, i32) +DEF_HELPER_3(vsplth, void, avr, avr, i32) +DEF_HELPER_3(vspltw, void, avr, avr, i32) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +22 -0
@@ -2354,6 +2354,28 @@ void helper_vslo (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)#endif } +/* Experimental testing shows that hardware masks the immediate. */ +#define _SPLAT_MASKED (element) (splat & (N_ELEMS(element) - 1)) +#if defined(WORDS_BIGENDIAN ) +#define SPLAT_ELEMENT (element) _SPLAT_MASKED(element) +#else +#define SPLAT_ELEMENT (element) (N_ELEMS(element)-1 - _SPLAT_MASKED(element)) +#endif +#define VSPLT (suffix, element) \ + void helper_vsplt##suffix (ppc_avr_t *r, ppc_avr_t *b, uint32_t splat) \ + { \ + uint32_t s = b->element[SPLAT_ELEMENT(element)]; \ + VECTOR_FOR (element) { \ + r->element[i] = s; \ + } \ + } +VSPLT(b, u8) +VSPLT(h, u16) +VSPLT(w, u32) +#undef VSPLT +#undef SPLAT_ELEMENT +#undef _SPLAT_MASKED +#define VSPLTI (suffix, element, splat_type) \ void helper_vspltis##suffix (ppc_avr_t *r, uint32_t splat) \ { \
target-ppc/translate.c +4 -0
@@ -6337,6 +6337,10 @@ GEN_VXFORM_SIMM(vspltisw, 908);tcg_temp_free (rd); \ } +GEN_VXFORM_UIMM (vspltb,524 ); +GEN_VXFORM_UIMM (vsplth,588 ); +GEN_VXFORM_UIMM (vspltw,652 ); +#define GEN_VXRFORM1 (opname, name, str, xo, rc) \ GEN_HANDLER2(name, str, 0x4, (xo >> 1) & 0x1f, ((xo >> 6) & 0x1f) | (rc << 4), 0x00000000, PPC_ALTIVEC) \ { \
Signature · 1 line
1.6.0.5
PATCH 28/42 target-ppc: add GEN_VXFORM_NOA macro for subsequent instructions.
In reply to Nathan Froyd--- target-ppc/translate.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-)
target-ppc/translate.c +15 -0
@@ -6299,6 +6299,21 @@ GEN_VXFORM(vrlw, 132);GEN_VXFORM (vsl,452 );GEN_VXFORM (vsr,708 ); +#define GEN_VXFORM_NOA (name, xo) \ + GEN_HANDLER(name, 0x04, (xo >> 1) & 0x1f, (xo >> 6) & 0x1f, 0x001f0000, PPC_ALTIVEC) \ + { \ + TCGv_ptr rb, rd; \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \ + } \ + rb = gen_avr_ptr(rB(ctx->opcode)); \ + rd = gen_avr_ptr(rD(ctx->opcode)); \ + gen_helper_##name (rd, rb); \ + tcg_temp_free (rb); \ + tcg_temp_free (rd); \ + } +#define GEN_VXFORM_SIMM (name, xo) \ GEN_HANDLER(name, 0x04, (xo >> 1) & 0x1f, (xo >> 6) & 0x1f, 0x00000000, PPC_ALTIVEC) \ { \
Signature · 1 line
1.6.0.5
PATCH 29/42 target-ppc: add vupk{h, l}px instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 2 ++ target-ppc/op_helper.c | 27 +++++++++++++++++++++++++++ target-ppc/translate.c | 3 +++ 3 files changed, 32 insertions(+), 0 deletions(-)
target-ppc/helper.h +2 -0
@@ -185,6 +185,8 @@ DEF_HELPER_2(vspltisw, void, avr, i32) DEF_HELPER_3(vspltb, void, avr, avr, i32) DEF_HELPER_3(vsplth, void, avr, avr, i32) DEF_HELPER_3(vspltw, void, avr, avr, i32) +DEF_HELPER_2(vupkhpx, void, avr, avr) +DEF_HELPER_2(vupklpx, void, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +27 -0
@@ -2429,6 +2429,33 @@ void helper_vsubcuw (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) } } +#if defined(WORDS_BIGENDIAN ) +#define UPKHI 1 +#define UPKLO 0 +#else +#define UPKHI 0 +#define UPKLO 1 +#endif +#define VUPKPX (suffix, hi) \ + void helper_vupk##suffix (ppc_avr_t *r, ppc_avr_t *b) \ + { \ + int i; \ + ppc_avr_t result; \ + VECTOR_FOR_I (i, u32) { \ + uint16_t e = b->u16[hi ? i : i+4]; \ + uint8_t a = (e >> 15) ? 0xff : 0; \ + uint8_t r = (e >> 10) & 0x1f; \ + uint8_t g = (e >> 5) & 0x1f; \ + uint8_t b = e & 0x1f; \ + result.u32[i] = (a << 24) | (r << 16) | (g << 8) | b; \ + } \ + *r = result; \ + } +VUPKPX(lpx, UPKLO) +VUPKPX(hpx, UPKHI) +#undef UPKHI +#undef UPKLO +#undef VECTOR_FOR#undef VECTOR_FOR_I#undef VECTOR_FOR_INORDER_I
target-ppc/translate.c +3 -0
@@ -6314,6 +6314,9 @@ GEN_VXFORM(vsr, 708);tcg_temp_free (rd); \ } +GEN_VXFORM_NOA (vupkhpx,846 ); +GEN_VXFORM_NOA (vupklpx,974 ); +#define GEN_VXFORM_SIMM (name, xo) \ GEN_HANDLER(name, 0x04, (xo >> 1) & 0x1f, (xo >> 6) & 0x1f, 0x00000000, PPC_ALTIVEC) \ { \
Signature · 1 line
1.6.0.5
PATCH 30/42 target-ppc: add vupk{h, l}s{b, h} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 4 ++++ target-ppc/op_helper.c | 22 ++++++++++++++++++++++ target-ppc/translate.c | 4 ++++ 3 files changed, 30 insertions(+), 0 deletions(-)
target-ppc/helper.h +4 -0
@@ -187,6 +187,10 @@ DEF_HELPER_3(vsplth, void, avr, avr, i32) DEF_HELPER_3(vspltw, void, avr, avr, i32) DEF_HELPER_2(vupkhpx, void, avr, avr) DEF_HELPER_2(vupklpx, void, avr, avr) +DEF_HELPER_2(vupkhsb, void, avr, avr) +DEF_HELPER_2(vupkhsh, void, avr, avr) +DEF_HELPER_2(vupklsb, void, avr, avr) +DEF_HELPER_2(vupklsh, void, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +22 -0
@@ -2453,6 +2453,28 @@ void helper_vsubcuw (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) } VUPKPX(lpx, UPKLO) VUPKPX(hpx, UPKHI) + +#define VUPK (suffix, unpacked, packee, hi) \ + void helper_vupk##suffix (ppc_avr_t *r, ppc_avr_t *b) \ + { \ + int i; \ + ppc_avr_t result; \ + if (hi) { \ + for (i = 0; i < N_ELEMS(unpacked); i++) { \ + result.unpacked[i] = b->packee[i]; \ + } \ + } else { \ + for (i = N_ELEMS(unpacked); i < N_ELEMS(packee); i++) { \ + result.unpacked[i-N_ELEMS(unpacked)] = b->packee[i]; \ + } \ + } \ + *r = result; \ + } +VUPK(hsb, s16, s8, UPKHI) +VUPK(hsh, s32, s16, UPKHI) +VUPK(lsb, s16, s8, UPKLO) +VUPK(lsh, s32, s16, UPKLO) +#undef VUPK#undef UPKHI#undef UPKLO
target-ppc/translate.c +4 -0
@@ -6314,6 +6314,10 @@ GEN_VXFORM(vsr, 708);tcg_temp_free (rd); \ } +GEN_VXFORM_NOA (vupkhsb,526 ); +GEN_VXFORM_NOA (vupkhsh,590 ); +GEN_VXFORM_NOA (vupklsb,654 ); +GEN_VXFORM_NOA (vupklsh,718 );GEN_VXFORM_NOA (vupkhpx,846 );GEN_VXFORM_NOA (vupklpx,974 );
Signature · 1 line
1.6.0.5
PATCH 31/42 target-ppc: add GEN_VAFORM_PAIRED macro for subsequent instructions.
In reply to Nathan Froyd--- target-ppc/translate.c | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+), 0 deletions(-)
target-ppc/translate.c +23 -0
@@ -6419,6 +6419,29 @@ GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC)tcg_temp_free (sh); } +#define GEN_VAFORM_PAIRED (name0, name1, xo) \ + GEN_HANDLER(name0##_##name1, 0x04, xo>>1, 0xFF, 0x00000000, PPC_ALTIVEC) \ + { \ + TCGv_ptr ra, rb, rc, rd; \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \ + } \ + ra = gen_avr_ptr(rA(ctx->opcode)); \ + rb = gen_avr_ptr(rB(ctx->opcode)); \ + rc = gen_avr_ptr(rC(ctx->opcode)); \ + rd = gen_avr_ptr(rD(ctx->opcode)); \ + if (Rc(ctx->opcode)) { \ + gen_helper_##name1 (rd, ra, rb, rc); \ + } else { \ + gen_helper_##name0 (rd, ra, rb, rc); \ + } \ + tcg_temp_free (ra); \ + tcg_temp_free (rb); \ + tcg_temp_free (rc); \ + tcg_temp_free (rd); \ + } +/*** SPE extension ***/ /* Register moves */
Signature · 1 line
1.6.0.5
PATCH 32/42 target-ppc: add vmsum{u, m}bm instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 2 ++ target-ppc/op_helper.c | 28 ++++++++++++++++++++++++++++ target-ppc/translate.c | 2 ++ 3 files changed, 32 insertions(+), 0 deletions(-)
target-ppc/helper.h +2 -0
@@ -191,6 +191,8 @@ DEF_HELPER_2(vupkhsb, void, avr, avr) DEF_HELPER_2(vupkhsh, void, avr, avr) DEF_HELPER_2(vupklsb, void, avr, avr) DEF_HELPER_2(vupklsh, void, avr, avr) +DEF_HELPER_4(vmsumubm, void, avr, avr, avr, avr) +DEF_HELPER_4(vmsummbm, void, avr, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +28 -0
@@ -2228,6 +2228,34 @@ VMRG(w, u32)#undef MRGHI#undef MRGLO +void helper_vmsummbm (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b,ppc_avr_t *c) +{ +int32_t prod[16 ]; +int i; + + VECTOR_FOR_I(i, s8) { + prod[i] = (int32_t )a->s8[i] * b->u8[i]; + } + + VECTOR_FOR_INORDER_I(i, s32) { + r->s32[i] = c->s32[i] + prod[4 *i] + prod[4 *i+1 ] + prod[4 *i+2 ] + prod[4 *i+3 ]; + } +} + +void helper_vmsumubm (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b,ppc_avr_t *c) +{ +uint16_t prod[16 ]; +int i; + + VECTOR_FOR_I(i, u8) { + prod[i] = a->u8[i] * b->u8[i]; + } + + VECTOR_FOR_INORDER_I(i, u32) { + r->u32[i] = c->u32[i] + prod[4 *i] + prod[4 *i+1 ] + prod[4 *i+2 ] + prod[4 *i+3 ]; + } +} +#define VMUL_DO (name, mul_element, prod_element, evenp) \ void helper_v##name (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \
target-ppc/translate.c +2 -0
@@ -6442,6 +6442,8 @@ GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC)tcg_temp_free (rd); \ } +GEN_VAFORM_PAIRED (vmsumubm, vmsummbm,36 ) +/*** SPE extension ***/ /* Register moves */
Signature · 1 line
1.6.0.5
PATCH 33/42 target-ppc: add vsel and vperm instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 2 ++ target-ppc/op_helper.c | 26 ++++++++++++++++++++++++++ target-ppc/translate.c | 1 + 3 files changed, 29 insertions(+), 0 deletions(-)
target-ppc/helper.h +2 -0
@@ -193,6 +193,8 @@ DEF_HELPER_2(vupklsb, void, avr, avr) DEF_HELPER_2(vupklsh, void, avr, avr) DEF_HELPER_4(vmsumubm, void, avr, avr, avr, avr) DEF_HELPER_4(vmsummbm, void, avr, avr, avr, avr) +DEF_HELPER_4(vsel, void, avr, avr, avr, avr) +DEF_HELPER_4(vperm, void, avr, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +26 -0
@@ -2278,6 +2278,26 @@ VMUL(uh, u16, u32)#undef VMUL_DO#undef VMUL +void helper_vperm (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b,ppc_avr_t *c) +{ +ppc_avr_t result; +int i; + VECTOR_FOR_INORDER_I (i, u8) { +int s = c->u8[i] &0x1f ; +#if defined(WORDS_BIGENDIAN ) +int index = s &0xf ; +#else +int index =15 - (s &0xf ); +#endif +if (s &0x10 ) { + result.u8[i] = b->u8[index]; + }else { + result.u8[i] = a->u8[index]; + } + } + *r = result; +} +#define VROTATE (suffix, element) \ void helper_vrl##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \
@@ -2292,6 +2312,12 @@ VROTATE(h, u16) VROTATE(w, u32)#undef VROTATE +void helper_vsel (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b,ppc_avr_t *c) +{ + r->u64[0 ] = (a->u64[0 ] & ~c->u64[0 ]) | (b->u64[0 ] & c->u64[0 ]); + r->u64[1 ] = (a->u64[1 ] & ~c->u64[1 ]) | (b->u64[1 ] & c->u64[1 ]); +} +#if defined(WORDS_BIGENDIAN )#define LEFT 0#define RIGHT 1
target-ppc/translate.c +1 -0
@@ -6443,6 +6443,7 @@ GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC) } GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 36) +GEN_VAFORM_PAIRED (vsel, vperm,42 )/*** SPE extension ***/ /* Register moves */
Signature · 1 line
1.6.0.5
PATCH 34/42 target-ppc: add saturating arithmetic conversion functions for subsequent instructions.
In reply to Nathan Froyd--- target-ppc/op_helper.c | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+), 0 deletions(-)
target-ppc/op_helper.c +27 -0
@@ -2033,6 +2033,33 @@ target_ulong helper_dlmzb (target_ulong high, target_ulong low, uint32_t update_ for (index = N_ELEMS(element)-1; index >= 0; index--)#endif +/* Saturating arithmetic helpers. */ +#define SATCVT (from, to, from_type, to_type, min, max, use_min, use_max) \ + static always_inline to_type cvt##from##to (from_type x, int *sat) \ + { \ + to_type r; \ + if (use_min && x < min) { \ + r = min; \ + *sat = 1; \ + } else if (use_max && x > max) { \ + r = max; \ + *sat = 1; \ + } else { \ + r = x; \ + } \ + return r; \ + } +SATCVT(sh, sb, int16_t, int8_t, INT8_MIN, INT8_MAX, 1, 1) +SATCVT(sw, sh, int32_t, int16_t, INT16_MIN, INT16_MAX, 1, 1) +SATCVT(sd, sw, int64_t, int32_t, INT32_MIN, INT32_MAX, 1, 1) +SATCVT(uh, ub, uint16_t, uint8_t, 0, UINT8_MAX, 0, 1) +SATCVT(uw, uh, uint32_t, uint16_t, 0, UINT16_MAX, 0, 1) +SATCVT(ud, uw, uint64_t, uint32_t, 0, UINT32_MAX, 0, 1) +SATCVT(sh, ub, int16_t, uint8_t, 0, UINT8_MAX, 1, 1) +SATCVT(sw, uh, int32_t, uint16_t, 0, UINT16_MAX, 1, 1) +SATCVT(sd, uw, int64_t, uint32_t, 0, UINT32_MAX, 1, 1) +#undef SATCVT +void helper_lvsl (ppc_avr_t *r,target_ulong sh) {int i, j = (sh &0xf );
Signature · 1 line
1.6.0.5
PATCH 35/42 target-ppc: add vpks{h, w}{s, u}s, vpku{h, w}us, and vpku{h, w}um instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 8 ++++++++ target-ppc/op_helper.c | 35 +++++++++++++++++++++++++++++++++++ target-ppc/translate.c | 8 ++++++++ 3 files changed, 51 insertions(+), 0 deletions(-)
target-ppc/helper.h +8 -0
@@ -195,6 +195,14 @@ DEF_HELPER_4(vmsumubm, void, avr, avr, avr, avr) DEF_HELPER_4(vmsummbm, void, avr, avr, avr, avr) DEF_HELPER_4(vsel, void, avr, avr, avr, avr) DEF_HELPER_4(vperm, void, avr, avr, avr, avr) +DEF_HELPER_3(vpkshss, void, avr, avr, avr) +DEF_HELPER_3(vpkshus, void, avr, avr, avr) +DEF_HELPER_3(vpkswss, void, avr, avr, avr) +DEF_HELPER_3(vpkswus, void, avr, avr, avr) +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_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +35 -0
@@ -2325,6 +2325,41 @@ void helper_vperm (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) *r = result; } +#if defined(WORDS_BIGENDIAN ) +#define PKBIG 1 +#else +#define PKBIG 0 +#endif +#define VPK (suffix, from, to, cvt, dosat) \ + void helper_vpk##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ + { \ + int i; \ + int sat = 0; \ + ppc_avr_t result; \ + ppc_avr_t *a0 = PKBIG ? a : b; \ + ppc_avr_t *a1 = PKBIG ? b : a; \ + VECTOR_FOR_INORDER_I (i, from) { \ + result.to[i] = cvt(a0->from[i], &sat); \ + result.to[i+N_ELEMS(from)] = cvt(a1->from[i], &sat); \ + } \ + *r = result; \ + if (dosat && sat) { \ + env->vscr |= (1 << VSCR_SAT); \ + } \ + } +#define I (x, y) (x) +VPK(shss, s16, s8, cvtshsb, 1) +VPK(shus, s16, u8, cvtshub, 1) +VPK(swss, s32, s16, cvtswsh, 1) +VPK(swus, s32, u16, cvtswuh, 1) +VPK(uhus, u16, u8, cvtuhub, 1) +VPK(uwus, u32, u16, cvtuwuh, 1) +VPK(uhum, u16, u8, I, 0) +VPK(uwum, u32, u16, I, 0) +#undef I +#undef VPK +#undef PKBIG +#define VROTATE (suffix, element) \ void helper_vrl##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \
target-ppc/translate.c +8 -0
@@ -6298,6 +6298,14 @@ GEN_VXFORM(vrlh, 68);GEN_VXFORM (vrlw,132 );GEN_VXFORM (vsl,452 );GEN_VXFORM (vsr,708 ); +GEN_VXFORM (vpkuhum,14 ); +GEN_VXFORM (vpkuwum,78 ); +GEN_VXFORM (vpkuhus,142 ); +GEN_VXFORM (vpkuwus,206 ); +GEN_VXFORM (vpkshus,270 ); +GEN_VXFORM (vpkswus,334 ); +GEN_VXFORM (vpkshss,398 ); +GEN_VXFORM (vpkswss,462 );#define GEN_VXFORM_NOA (name, xo) \ GEN_HANDLER(name, 0x04, (xo >> 1) & 0x1f, (xo >> 6) & 0x1f, 0x001f0000, PPC_ALTIVEC) \
Signature · 1 line
1.6.0.5
PATCH 36/42 target-ppc: add vpkpx instruction.
In reply to Nathan Froyd--- target-ppc/helper.h | 1 + target-ppc/op_helper.c | 19 +++++++++++++++++++ target-ppc/translate.c | 1 + 3 files changed, 21 insertions(+), 0 deletions(-)
target-ppc/helper.h +1 -0
@@ -203,6 +203,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)
target-ppc/op_helper.c +19 -0
@@ -2330,6 +2330,25 @@ 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) \ { \
target-ppc/translate.c +1 -0
@@ -6306,6 +6306,7 @@ GEN_VXFORM(vpkshus, 270);GEN_VXFORM (vpkswus,334 );GEN_VXFORM (vpkshss,398 );GEN_VXFORM (vpkswss,462 ); +GEN_VXFORM (vpkpx,782 );#define GEN_VXFORM_NOA (name, xo) \ GEN_HANDLER(name, 0x04, (xo >> 1) & 0x1f, (xo >> 6) & 0x1f, 0x001f0000, PPC_ALTIVEC) \
Signature · 1 line
1.6.0.5
PATCH 37/42 target-ppc: add vmh{, r}addshs instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 2 ++ target-ppc/op_helper.c | 30 ++++++++++++++++++++++++++++++ target-ppc/translate.c | 1 + 3 files changed, 33 insertions(+), 0 deletions(-)
target-ppc/helper.h +2 -0
@@ -204,6 +204,8 @@ 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_4(vmhaddshs, void, avr, avr, avr, avr) +DEF_HELPER_4(vmhraddshs, void, avr, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +30 -0
@@ -2197,6 +2197,36 @@ VCMP(gtsh, >, s16) VCMP(gtsw, >, s32)#undef VCMP +void helper_vmhaddshs (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b,ppc_avr_t *c) +{ +int sat =0 ; + +VECTOR_FOR (s16) { +int32_t prod = a->s16[i] * b->s16[i]; +int32_t t = (int32_t )c->s16[i] + (prod >>15 ); + r->s16[i] =cvtswsh (t, &sat); + } + +if (sat) { + env->vscr |= (1 <<VSCR_SAT ); + } +} + +void helper_vmhraddshs (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b,ppc_avr_t *c) +{ +int sat =0 ; + +VECTOR_FOR (s16) { +int32_t prod = a->s16[i] * b->s16[i] +0x00004000 ; +int32_t t = (int32_t )c->s16[i] + (prod >>15 ); + r->s16[i] =cvtswsh (t, &sat); + } + +if (sat) { + env->vscr |= (1 <<VSCR_SAT ); + } +} +#define VMINMAX_DO (name, compare, element) \ void helper_v##name (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \
target-ppc/translate.c +1 -0
@@ -6451,6 +6451,7 @@ GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC)tcg_temp_free (rd); \ } +GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 32) GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 36)GEN_VAFORM_PAIRED (vsel, vperm,42 )
Signature · 1 line
1.6.0.5
PATCH 38/42 target-ppc: add vmsumuh{m, s} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 2 ++ target-ppc/op_helper.c | 34 ++++++++++++++++++++++++++++++++++ target-ppc/translate.c | 1 + 3 files changed, 37 insertions(+), 0 deletions(-)
target-ppc/helper.h +2 -0
@@ -206,6 +206,8 @@ DEF_HELPER_3(vpkuwum, void, avr, avr, avr) DEF_HELPER_3(vpkpx, void, avr, avr, avr) DEF_HELPER_4(vmhaddshs, void, avr, avr, avr, avr) DEF_HELPER_4(vmhraddshs, void, avr, avr, avr, avr) +DEF_HELPER_4(vmsumuhm, void, avr, avr, avr, avr) +DEF_HELPER_4(vmsumuhs, void, avr, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +34 -0
@@ -2313,6 +2313,40 @@ void helper_vmsumubm (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) } } +void helper_vmsumuhm (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b,ppc_avr_t *c) +{ +uint32_t prod[8 ]; +int i; + + VECTOR_FOR_I(i, u16) { + prod[i] = a->u16[i] * b->u16[i]; + } + + VECTOR_FOR_INORDER_I(i, u32) { + r->u32[i] = c->u32[i] + prod[2 *i] + prod[2 *i+1 ]; + } +} + +void helper_vmsumuhs (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b,ppc_avr_t *c) +{ +uint32_t prod[8 ]; +int i; +int sat =0 ; + + VECTOR_FOR_I (i, u16) { + prod[i] = a->u16[i] * b->u16[i]; + } + + VECTOR_FOR_INORDER_I (i, s32) { +uint64_t t = (uint64_t )c->u32[i] + prod[2 *i] + prod[2 *i+1 ]; + r->u32[i] =cvtuduw (t, &sat); + } + +if (sat) { + env->vscr |= (1 <<VSCR_SAT ); + } +} +#define VMUL_DO (name, mul_element, prod_element, evenp) \ void helper_v##name (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \
target-ppc/translate.c +1 -0
@@ -6453,6 +6453,7 @@ GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC) GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 32) GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 36) +GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 38)GEN_VAFORM_PAIRED (vsel, vperm,42 )/*** SPE extension ***/
Signature · 1 line
1.6.0.5
PATCH 39/42 target-ppc: add vmsumsh{m, s} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 2 ++ target-ppc/op_helper.c | 34 ++++++++++++++++++++++++++++++++++ target-ppc/translate.c | 1 + 3 files changed, 37 insertions(+), 0 deletions(-)
target-ppc/helper.h +2 -0
@@ -208,6 +208,8 @@ DEF_HELPER_4(vmhaddshs, void, avr, avr, avr, avr) DEF_HELPER_4(vmhraddshs, void, avr, avr, avr, avr) DEF_HELPER_4(vmsumuhm, void, avr, avr, avr, avr) DEF_HELPER_4(vmsumuhs, void, avr, avr, avr, avr) +DEF_HELPER_4(vmsumshm, void, avr, avr, avr, avr) +DEF_HELPER_4(vmsumshs, void, avr, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +34 -0
@@ -2299,6 +2299,40 @@ void helper_vmsummbm (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) } } +void helper_vmsumshm (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b,ppc_avr_t *c) +{ +int32_t prod[8 ]; +int i; + + VECTOR_FOR_I(i, s16) { + prod[i] = a->s16[i] * b->s16[i]; + } + + VECTOR_FOR_INORDER_I(i, s32) { + r->s32[i] = c->s32[i] + prod[2 *i] + prod[2 *i+1 ]; + } +} + +void helper_vmsumshs (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b,ppc_avr_t *c) +{ +int32_t prod[8 ]; +int i; +int sat =0 ; + + VECTOR_FOR_I (i, s16) { + prod[i] = (int32_t )a->s16[i] * b->s16[i]; + } + + VECTOR_FOR_INORDER_I (i, s32) { +int64_t t = (int64_t )c->s32[i] + prod[2 *i] + prod[2 *i+1 ]; + r->u32[i] =cvtsdsw (t, &sat); + } + +if (sat) { + env->vscr |= (1 <<VSCR_SAT ); + } +} +void helper_vmsumubm (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b,ppc_avr_t *c) {uint16_t prod[16 ];
target-ppc/translate.c +1 -0
@@ -6454,6 +6454,7 @@ GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC) GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 32) GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 36) GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 38) +GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 40)GEN_VAFORM_PAIRED (vsel, vperm,42 )/*** SPE extension ***/
Signature · 1 line
1.6.0.5
PATCH 40/42 target-ppc: add vmladduhm instruction.
In reply to Nathan Froyd--- target-ppc/helper.h | 1 + target-ppc/op_helper.c | 8 ++++++++ target-ppc/translate.c | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 0 deletions(-)
target-ppc/helper.h +1 -0
@@ -210,6 +210,7 @@ DEF_HELPER_4(vmsumuhm, void, avr, avr, avr, avr) DEF_HELPER_4(vmsumuhs, void, avr, avr, avr, avr) DEF_HELPER_4(vmsumshm, void, avr, avr, avr, avr) DEF_HELPER_4(vmsumshs, void, avr, avr, avr, avr) +DEF_HELPER_4(vmladduhm, void, avr, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +8 -0
@@ -2250,6 +2250,14 @@ VMINMAX(uw, u32)#undef VMINMAX_DO#undef VMINMAX +void helper_vmladduhm (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b,ppc_avr_t *c) +{ +VECTOR_FOR (s16) { +int32_t prod = a->s16[i] * b->s16[i]; + r->s16[i] = (int16_t ) (prod + c->s16[i]); + } +} +#define VMRG_DO (name, element, highp) \ void helper_v##name (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \
target-ppc/translate.c +19 -0
@@ -6452,6 +6452,25 @@ GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC) } GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 32) + +GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC) +{ +TCGv_ptr ra, rb, rc, rd; +if (unlikely (!ctx->altivec_enabled)) { +gen_exception (ctx,POWERPC_EXCP_VPU ); +return ; + } + ra =gen_avr_ptr (rA (ctx->opcode)); + rb =gen_avr_ptr (rB (ctx->opcode)); + rc =gen_avr_ptr (rC (ctx->opcode)); + rd =gen_avr_ptr (rD (ctx->opcode)); +gen_helper_vmladduhm (rd, ra, rb, rc); +tcg_temp_free (ra); +tcg_temp_free (rb); +tcg_temp_free (rc); +tcg_temp_free (rd); +} + GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 36) GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 38)GEN_VAFORM_PAIRED (vmsumshm, vmsumshs,40 )
Signature · 1 line
1.6.0.5
PATCH 41/42 target-ppc: add {l, st}ve{b, h, w}x instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 6 ++++++ target-ppc/op_helper.c | 40 ++++++++++++++++++++++++++++++++++++++++ target-ppc/translate.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 0 deletions(-)
target-ppc/helper.h +6 -0
@@ -211,6 +211,12 @@ DEF_HELPER_4(vmsumuhs, void, avr, avr, avr, avr) DEF_HELPER_4(vmsumshm, void, avr, avr, avr, avr) DEF_HELPER_4(vmsumshs, void, avr, avr, avr, avr) DEF_HELPER_4(vmladduhm, void, avr, avr, avr, avr) +DEF_HELPER_2(lvebx, void, avr, tl) +DEF_HELPER_2(lvehx, void, avr, tl) +DEF_HELPER_2(lvewx, void, avr, tl) +DEF_HELPER_2(stvebx, void, avr, tl) +DEF_HELPER_2(stvehx, void, avr, tl) +DEF_HELPER_2(stvewx, void, avr, tl) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +40 -0
@@ -2060,6 +2060,26 @@ SATCVT(sw, uh, int32_t, uint16_t, 0, UINT16_MAX, 1, 1) SATCVT(sd, uw, int64_t, uint32_t, 0, UINT32_MAX, 1, 1)#undef SATCVT +#define LVE (name, access, swap, element) \ + void helper_##name (ppc_avr_t *r, target_ulong addr) \ + { \ + size_t n_elems = N_ELEMS(element); \ + int adjust = HI_IDX*(n_elems-1); \ + int sh = sizeof(r->element[0]) >> 1; \ + int index = (addr & 0xf) >> sh; \ + if(msr_le) { \ + r->element[LO_IDX ? index : (adjust - index)] = swap(access(addr)); \ + } else { \ + r->element[LO_IDX ? index : (adjust - index)] = access(addr); \ + } \ + } +#define I (x) (x) +LVE(lvebx, ldub, I, u8) +LVE(lvehx, lduw, bswap16, u16) +LVE(lvewx, ldl, bswap32, u32) +#undef I +#undef LVE +void helper_lvsl (ppc_avr_t *r,target_ulong sh) {int i, j = (sh &0xf );
@@ -2078,6 +2098,26 @@ void helper_lvsr (ppc_avr_t *r, target_ulong sh) } } +#define STVE (name, access, swap, element) \ + void helper_##name (ppc_avr_t *r, target_ulong addr) \ + { \ + size_t n_elems = N_ELEMS(element); \ + int adjust = HI_IDX*(n_elems-1); \ + int sh = sizeof(r->element[0]) >> 1; \ + int index = (addr & 0xf) >> sh; \ + if(msr_le) { \ + access(addr, swap(r->element[LO_IDX ? index : (adjust - index)])); \ + } else { \ + access(addr, r->element[LO_IDX ? index : (adjust - index)]); \ + } \ + } +#define I (x) (x) +STVE(stvebx, stb, I, u8) +STVE(stvehx, stw, bswap16, u16) +STVE(stvewx, stl, bswap32, u32) +#undef I +#undef LVE +void helper_vaddcuw (ppc_avr_t *r,ppc_avr_t *a,ppc_avr_t *b) {VECTOR_FOR (u32) {
target-ppc/translate.c +42 -0
56 lines not on this page · raw message
Signature · 1 line
1.6.0.5
PATCH 42/42 target-ppc: add vsumsws, vsum2sws, and vsum4{sbs, shs, ubs} instructions.
In reply to Nathan Froyd--- target-ppc/helper.h | 5 ++ target-ppc/op_helper.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++ target-ppc/translate.c | 5 ++ 3 files changed, 112 insertions(+), 0 deletions(-)
target-ppc/helper.h +5 -0
@@ -217,6 +217,11 @@ DEF_HELPER_2(lvewx, void, avr, tl) DEF_HELPER_2(stvebx, void, avr, tl) DEF_HELPER_2(stvehx, void, avr, tl) DEF_HELPER_2(stvewx, void, avr, tl) +DEF_HELPER_3(vsumsws, void, avr, avr, avr) +DEF_HELPER_3(vsum2sws, void, avr, avr, avr) +DEF_HELPER_3(vsum4sbs, void, avr, avr, avr) +DEF_HELPER_3(vsum4shs, void, avr, avr, avr) +DEF_HELPER_3(vsum4ubs, void, avr, avr, avr) DEF_HELPER_1(efscfsi, i32, i32)DEF_HELPER_1 (efscfui, i32, i32)
target-ppc/op_helper.c +102 -0
108 lines not on this page · raw message
target-ppc/translate.c +5 -0
@@ -6349,6 +6349,11 @@ GEN_VXFORM(vpkswus, 334);GEN_VXFORM (vpkshss,398 );GEN_VXFORM (vpkswss,462 );GEN_VXFORM (vpkpx,782 ); +GEN_VXFORM (vsum4ubs,1544 ); +GEN_VXFORM (vsum4sbs,1800 ); +GEN_VXFORM (vsum4shs,1608 ); +GEN_VXFORM (vsum2sws,1672 ); +GEN_VXFORM (vsumsws,1928 );#define GEN_VXFORM_NOA (name, xo) \ GEN_HANDLER(name, 0x04, (xo >> 1) & 0x1f, (xo >> 6) & 0x1f, 0x001f0000, PPC_ALTIVEC) \
Signature · 1 line
1.6.0.5
Quoted 2 lines · Nathan Froyd
[Thiemo Seufer asked for a patch-bomb so people can conveniently comment on things and so the mail archive has a record of Signed-off-by.]
Yes, that's a good idea, it makes them a lot easier for comments.
Quoted 8 lines
This patch series adds support for integer Altivec instructions to QEMU, including element-wise loads and stores. It's a long patch series, since each instruction "family" (element-wise loads/stores, modulo arithmetic instructions, saturating arithmetic instructions, etc.) is separated out into its own patch. Hopefully since the individual patches are so short, they will be more-or-less self-explanatory: the explanation for the patches is generally fairly short, on the order of a single line.
Very nice work :)
Quoted 12 lines
The patch series is slightly cleaned up from the one I originally
posted: there were a few problems with my tcg usage, and I didn't faithfully use some convenience functions.Why only the integer instructions? I originally wrote support for the whole instructions set, but I did it in the days of dyngen. So a straight forward-port was out of the question. The original patch sloppily used native floats everywhere, rather than the float32 abstraction. It also used C99 math functions to implement some of the more exotic Altivec instructions. Both of these decisions mean that some care has to be taken in porting the floating-point instructions.
Quoted 3 lines
I figured it'd be better to push out the integer instructions now and the floating-point instructions later, rather than waiting for some unspecified time for full support.
Good idea.
Given the series is very long, don't expect me to comment all the patches now. I'll comment them one by one and it make takes a few days...
Don't hesitate to resend only one patch after I send a comment, this way we can merge the series part by part as soon as we agree.
And a question for the whole series: how have you tested those instructions?
Signature · 4 lines
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [email protected] | [email protected] `- people.debian.org/~aurel32 | www.aurel32.net
Quoted 2 lines · Aurelien Jarno
And a question for the whole series: how have you tested those instructions?
I was ready to ask the same question given how large the series is :-)
For ARM NEON instructions (the ARM SIMD), my experience is that ffmpeg can help test some instructions as it contains assembly routines that use instructions no compiler generates. And it looks like ffmpeg has many Altivec routines. Of course, it's not enough, but it's a good start.
Laurent
Quoted 2 lines · Aurelien Jarno
And a question for the whole series: how have you tested those instructions?
The instructions from the original (dyngen) patch were tested using a modified version of:
* test-powerpc.cpp - PowerPC regression testing
*
* Kheperix (C) 2003-2005 Gwenole Beauchesne
that didn't require poking around in the guts of QEMU. I turned it into a standalone application that could be run in Linux. I then ran it on a 74xx machine and under usermode emulation with QEMU and compared the results.
I assumed that porting it over would show no difference in functionality, but I see from running it this morning that m{f,t}vscr, vmul{e,o}*, and vs{l,r} are broken. Everything else works OK. I will poke at the failing instructions and submit updated patches for them.
-Nathan