Skip to contentSkip to conversation

target-ppc: add Altivec instructions, patch-bomb version

PATCH In review Nathan Froyd 4 participants 56 messages Dec 15, 2008 – Dec 18, 2008

lore
Share & tools
lore
#0 lore raw

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

#1 lore raw

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
index 4c4f9ef..70047c7 100644
@@ -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
#2 lore raw

Re: [Qemu-devel] [PATCH 01/42] target-ppc: add Altivec logical operations.

Quoted 21 lines · Nathan Froyd
---
 target-ppc/translate.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)
target-ppc/translate.c +7 -0
index 4c4f9ef..70047c7 100644
@@ -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
#3 lore raw

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
index 4c4f9ef..0d1fd57 100644
@@ -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
#4 lore raw

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

---
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
index 4c4f9ef..0d1fd57 100644
@@ -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
#5 lore raw

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
index 2d665e8..c597632 100644
@@ -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
#6 lore raw

Re: [Qemu-devel] [PATCH 02/42] target-ppc: add helper macros for later patches.

Quoted 40 lines · Nathan Froyd
---
 target-ppc/op_helper.c |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)
target-ppc/op_helper.c +26 -0
index 2d665e8..c597632 100644
@@ -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
#7 lore raw

Re: [Qemu-devel] [PATCH 02/42] target-ppc: add helper macros for later patches.

In reply to Nathan Froyd
Quoted 13 lines · Nathan Froyd
---
 target-ppc/op_helper.c |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)
target-ppc/op_helper.c +0 -0
index 2d665e8..c597632 100644
@@ -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
#8 lore raw

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
index 70047c7..41ae158 100644
@@ -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
#9 lore raw

Re: [Qemu-devel] [PATCH 03/42] target-ppc: add gen_avr_ptr function.

Quoted 14 lines · Nathan Froyd
---
 target-ppc/translate.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
target-ppc/translate.c +0 -0
index 70047c7..41ae158 100644
@@ -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
#10 lore raw

Re: [Qemu-devel] [PATCH 03/42] target-ppc: add gen_avr_ptr function.

Quoted 29 lines · Aurelien Jarno
Quoted 14 lines · Nathan Froyd
---
 target-ppc/translate.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
target-ppc/translate.c +0 -0
index 70047c7..41ae158 100644
@@ -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
#11 lore raw

Re: [Qemu-devel] [PATCH 03/42] target-ppc: add gen_avr_ptr function.

In reply to Aurelien Jarno
Quoted 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

#12 lore raw

Re: [Qemu-devel] [PATCH 03/42] target-ppc: add gen_avr_ptr function.

In reply to Nathan Froyd
Quoted 2 lines · Nathan Froyd

Thanks, applied.

Quoted 28 lines
---
 target-ppc/translate.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
target-ppc/translate.c +7 -0
index 70047c7..41ae158 100644
@@ -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
#13 lore raw

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
index 41ae158..51db789 100644
@@ -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
#14 lore raw

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
index 6b5728c..f43556e 100644
@@ -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
index c597632..d59e930 100644
@@ -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
index 51db789..9866c43 100644
@@ -6151,6 +6151,13 @@ GEN_HANDLER(name, 0x04, (xo >> 1) & 0x1f, (xo >> 6) & 0x1f, 0x00000000, PPC_ALTI
     tcg_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
#15 lore raw

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
index de53675..973f50a 100644
@@ -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
#16 lore raw

Re: [Qemu-devel] [PATCH 06/42] target-ppc: add signed fields to ppc_avr_t.

Quoted 2 lines · Nathan Froyd

Thanks, applied.

Quoted 24 lines
---
 target-ppc/cpu.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
target-ppc/cpu.h +3 -0
index de53675..973f50a 100644
@@ -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
#17 lore raw

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
index f43556e..214bbf1 100644
@@ -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
index d59e930..49c7256 100644
@@ -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
index 9866c43..fbc9f9a 100644
@@ -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
#18 lore raw

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
index 214bbf1..196106e 100644
@@ -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
index 49c7256..8f74286 100644
@@ -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
index fbc9f9a..0266942 100644
@@ -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
#19 lore raw

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
index 0266942..53cff59 100644
@@ -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
#20 lore raw

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
index 196106e..efe7a1a 100644
@@ -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
index 8f74286..d36a046 100644
@@ -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
index 53cff59..8b90971 100644
@@ -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
#21 lore raw

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
index 973f50a..5bfa4a0 100644
@@ -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
#22 lore raw

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
index efe7a1a..5a05157 100644
@@ -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
index d36a046..886c1fa 100644
@@ -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
index 8b90971..5b4c5cd 100644
@@ -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
#23 lore raw

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
index 5a05157..6b74c3d 100644
@@ -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
index 886c1fa..252fa4f 100644
@@ -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
index 5b4c5cd..2d4ffbb 100644
@@ -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
#24 lore raw

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
index 6b74c3d..f2e91ca 100644
@@ -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
index 252fa4f..2bd0aef 100644
@@ -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
index 2d4ffbb..d01191b 100644
@@ -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
#25 lore raw

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
index f2e91ca..7f3b011 100644
@@ -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
index 2bd0aef..fcb5aaa 100644
@@ -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
index d01191b..19bf120 100644
@@ -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
#26 lore raw

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
index 7f3b011..8f6f059 100644
@@ -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
index fcb5aaa..61bb432 100644
@@ -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
index 19bf120..4c4b7a3 100644
@@ -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
#27 lore raw

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
index 8f6f059..a784fae 100644
@@ -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
index 61bb432..1a94735 100644
@@ -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
index 4c4b7a3..05912b6 100644
@@ -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
#28 lore raw

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
index a784fae..1d05cb2 100644
@@ -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
index 1a94735..d453a41 100644
@@ -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
index 05912b6..791f76b 100644
@@ -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
#29 lore raw

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
index 791f76b..92ded89 100644
@@ -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
#30 lore raw

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
index 1d05cb2..4e1c307 100644
@@ -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
index 92ded89..eaffe58 100644
@@ -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
#31 lore raw

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
index 4e1c307..cf2a655 100644
@@ -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
index b297052..b44a97d 100644
@@ -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
index eaffe58..5bcbeb0 100644
@@ -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
#32 lore raw

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
index cf2a655..5f94e9f 100644
@@ -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
index b44a97d..7d72767 100644
@@ -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
index 5bcbeb0..c072d54 100644
@@ -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
#33 lore raw

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
index 5f94e9f..02e3c10 100644
@@ -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
index 7d72767..310a46c 100644
@@ -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
index c072d54..33c9c40 100644
@@ -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
#34 lore raw

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
index 33c9c40..20ebb10 100644
@@ -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
#35 lore raw

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
index 02e3c10..9fbcc4a 100644
@@ -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
index 310a46c..ac99324 100644
@@ -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
index 20ebb10..4867f7e 100644
@@ -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
#36 lore raw

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
index 4867f7e..a21b2f5 100644
@@ -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
#37 lore raw

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
index 9fbcc4a..2ca4e26 100644
@@ -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
index ac99324..44af1cc 100644
@@ -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
index a21b2f5..4331548 100644
@@ -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
#38 lore raw

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
index 4331548..f1c621f 100644
@@ -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
#39 lore raw

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
index 2ca4e26..9352a67 100644
@@ -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
index 44af1cc..22d88db 100644
@@ -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
index f1c621f..ca4f10a 100644
@@ -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
#40 lore raw

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
index 9352a67..26ff038 100644
@@ -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
index 22d88db..346ddde 100644
@@ -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
index ca4f10a..0ed504b 100644
@@ -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
#41 lore raw

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
index 0ed504b..d77ddaf 100644
@@ -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
#42 lore raw

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
index 26ff038..dbd00f5 100644
@@ -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
index 346ddde..aa8a563 100644
@@ -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
index d77ddaf..34b1d9e 100644
@@ -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
#43 lore raw

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
index dbd00f5..8bd8cf3 100644
@@ -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
index aa8a563..57182c6 100644
@@ -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
index 34b1d9e..b53edd9 100644
@@ -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
#44 lore raw

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
index 57182c6..4069e9d 100644
@@ -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
#45 lore raw

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
index 8bd8cf3..a1ef4df 100644
@@ -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
index 4069e9d..2d53922 100644
@@ -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
index b53edd9..067c17b 100644
@@ -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
#46 lore raw

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
index a1ef4df..e2ad294 100644
@@ -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
index 2d53922..422600a 100644
@@ -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
index 067c17b..4294148 100644
@@ -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
#47 lore raw

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
index e2ad294..8ea8ddd 100644
@@ -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
index 422600a..994c1af 100644
@@ -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
index 4294148..3a4a3cb 100644
@@ -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
#48 lore raw

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
index 8ea8ddd..ceb7351 100644
@@ -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
index 994c1af..f8d8272 100644
@@ -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
index 3a4a3cb..28edda6 100644
@@ -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
#49 lore raw

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
index ceb7351..b4b9521 100644
@@ -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
index f8d8272..8086ca4 100644
@@ -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
index 28edda6..9a69861 100644
@@ -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
#50 lore raw

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
index b4b9521..f97480e 100644
@@ -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
index 8086ca4..e6e6cb9 100644
@@ -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
index 9a69861..985af3f 100644
@@ -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
#51 lore raw

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
index f97480e..1dd2cf8 100644
@@ -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
index e6e6cb9..0c7473c 100644
@@ -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
#52 lore raw

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
index 1dd2cf8..51760a1 100644
@@ -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
index c7342a5..2cdb920 100644
@@ -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
#53 lore raw
In reply to Nathan Froyd
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
#54 lore raw
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

#55 lore raw
In reply to Aurelien Jarno
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