Re: [Qemu-devel] [PATCH v1 1/5] target-ppc: add vector insert instructions

2016-08-08 Thread David Gibson
On Thu, Aug 04, 2016 at 10:08:17PM +0530, Richard Henderson wrote:
> On 08/04/2016 06:33 PM, Rajalakshmi Srinivasaraghavan wrote:
> > +#if defined(HOST_WORDS_BIGENDIAN)
> > +#define VINSERT(suffix, element, index)
> >  \
> > +void helper_vinsert##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t 
> > splat) \
> > +{  
> >  \
> > +memcpy(>u8[SPLAT_ELEMENT(u8)], >element[index],  
> >  \

It seems odd to use SPLAT_ELEMENT() here but not in the LE case, given
that SPLAT_ELEMENT() is already a macro whose definition is
conditional on endianness.  It might actually be clearer to open code it.

> > +   sizeof(r->element[0])); 
> >  \
> > +}
> > +#else
> > +#define VINSERT(suffix, element, index)
> >  \
> > +void helper_vinsert##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t 
> > splat) \
> > +{  
> >  \
> > +memcpy(>u8[(16 - splat) - sizeof(r->element[0])],   
> >  \
> > +   >element[(ARRAY_SIZE(r->element) - index) - 1],  
> >  \
> > +   sizeof(r->element[0])); 
> >  \
> > +}
> 
> Something somewhere needs to check for out of bounds SPLAT, for evil guests.
> 
> The spec says it's undefined; I don't recall if that gives you the latitude
> to generate an illegal instruction trap during translate.

splat is an immediate argument, so that should be done on the
generator side, rather than the helper side.  It's already partially
done by the way it's extracted from the instruction.

But, AFAICT that just limits splat to 5 bits, and I'm not sure that's
enough for all forms of this instruction.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v1 1/5] target-ppc: add vector insert instructions

2016-08-04 Thread Richard Henderson

On 08/04/2016 06:33 PM, Rajalakshmi Srinivasaraghavan wrote:

+#if defined(HOST_WORDS_BIGENDIAN)
+#define VINSERT(suffix, element, index) \
+void helper_vinsert##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t splat) \
+{   \
+memcpy(>u8[SPLAT_ELEMENT(u8)], >element[index],   \
+   sizeof(r->element[0]));  \
+}
+#else
+#define VINSERT(suffix, element, index) \
+void helper_vinsert##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t splat) \
+{   \
+memcpy(>u8[(16 - splat) - sizeof(r->element[0])],\
+   >element[(ARRAY_SIZE(r->element) - index) - 1],   \
+   sizeof(r->element[0]));  \
+}


Something somewhere needs to check for out of bounds SPLAT, for evil guests.

The spec says it's undefined; I don't recall if that gives you the latitude to 
generate an illegal instruction trap during translate.



r~



[Qemu-devel] [PATCH v1 1/5] target-ppc: add vector insert instructions

2016-08-04 Thread Rajalakshmi Srinivasaraghavan
The following vector insert instructions are added from ISA 3.0.

vinsertb - Vector Insert Byte
vinserth - Vector Insert Halfword
vinsertw - Vector Insert Word
vinsertd - Vector Insert Doubleword

Signed-off-by: Rajalakshmi Srinivasaraghavan 
---
 target-ppc/helper.h |4 
 target-ppc/int_helper.c |   21 +
 target-ppc/translate/vmx-impl.c |   10 ++
 target-ppc/translate/vmx-ops.c  |   18 +-
 4 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 93ac9e1..0923779 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -250,6 +250,10 @@ 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_3(vinsertb, void, avr, avr, i32)
+DEF_HELPER_3(vinserth, void, avr, avr, i32)
+DEF_HELPER_3(vinsertw, void, avr, avr, i32)
+DEF_HELPER_3(vinsertd, 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)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 552b2e0..637f0b1 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1790,6 +1790,27 @@ VSPLT(b, u8)
 VSPLT(h, u16)
 VSPLT(w, u32)
 #undef VSPLT
+#if defined(HOST_WORDS_BIGENDIAN)
+#define VINSERT(suffix, element, index) \
+void helper_vinsert##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t splat) \
+{   \
+memcpy(>u8[SPLAT_ELEMENT(u8)], >element[index],   \
+   sizeof(r->element[0]));  \
+}
+#else
+#define VINSERT(suffix, element, index) \
+void helper_vinsert##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t splat) \
+{   \
+memcpy(>u8[(16 - splat) - sizeof(r->element[0])],\
+   >element[(ARRAY_SIZE(r->element) - index) - 1],   \
+   sizeof(r->element[0]));  \
+}
+#endif
+VINSERT(b, u8, 7)
+VINSERT(h, u16, 3)
+VINSERT(w, u32, 1)
+VINSERT(d, u64, 0)
+#undef VINSERT
 #undef SPLAT_ELEMENT
 #undef _SPLAT_MASKED
 
diff --git a/target-ppc/translate/vmx-impl.c b/target-ppc/translate/vmx-impl.c
index ac78caf..4940ae3 100644
--- a/target-ppc/translate/vmx-impl.c
+++ b/target-ppc/translate/vmx-impl.c
@@ -626,10 +626,20 @@ static void glue(gen_, name)(DisasContext *ctx)   
  \
 GEN_VXFORM_UIMM(vspltb, 6, 8);
 GEN_VXFORM_UIMM(vsplth, 6, 9);
 GEN_VXFORM_UIMM(vspltw, 6, 10);
+GEN_VXFORM_UIMM(vinsertb, 6, 12);
+GEN_VXFORM_UIMM(vinserth, 6, 13);
+GEN_VXFORM_UIMM(vinsertw, 6, 14);
+GEN_VXFORM_UIMM(vinsertd, 6, 15);
 GEN_VXFORM_UIMM_ENV(vcfux, 5, 12);
 GEN_VXFORM_UIMM_ENV(vcfsx, 5, 13);
 GEN_VXFORM_UIMM_ENV(vctuxs, 5, 14);
 GEN_VXFORM_UIMM_ENV(vctsxs, 5, 15);
+GEN_VXFORM_DUAL(vspltisb, PPC_NONE, PPC2_ALTIVEC_207,
+  vinsertb, PPC_NONE, PPC2_ISA300);
+GEN_VXFORM_DUAL(vspltish, PPC_NONE, PPC2_ALTIVEC_207,
+  vinserth, PPC_NONE, PPC2_ISA300);
+GEN_VXFORM_DUAL(vspltisw, PPC_NONE, PPC2_ALTIVEC_207,
+  vinsertw, PPC_NONE, PPC2_ISA300);
 
 static void gen_vsldoi(DisasContext *ctx)
 {
diff --git a/target-ppc/translate/vmx-ops.c b/target-ppc/translate/vmx-ops.c
index 7449396..ca69e56 100644
--- a/target-ppc/translate/vmx-ops.c
+++ b/target-ppc/translate/vmx-ops.c
@@ -41,6 +41,9 @@ GEN_HANDLER_E(name, 0x04, opc2, opc3, 0x, PPC_NONE, 
PPC2_ALTIVEC_207)
 #define GEN_VXFORM_300(name, opc2, opc3)\
 GEN_HANDLER_E(name, 0x04, opc2, opc3, 0x, PPC_NONE, PPC2_ISA300)
 
+#define GEN_VXFORM_300_EXT(name, opc2, opc3, inval) \
+GEN_HANDLER_E(name, 0x04, opc2, opc3, inval, PPC_NONE, PPC2_ISA300)
+
 #define GEN_VXFORM_DUAL(name0, name1, opc2, opc3, type0, type1) \
 GEN_HANDLER_E(name0##_##name1, 0x4, opc2, opc3, 0x, type0, type1)
 
@@ -191,11 +194,16 @@ GEN_VXRFORM(vcmpgefp, 3, 7)
 GEN_VXRFORM_DUAL(vcmpgtfp, vcmpgtud, 3, 11, PPC_ALTIVEC, PPC_NONE)
 GEN_VXRFORM_DUAL(vcmpbfp, vcmpgtsd, 3, 15, PPC_ALTIVEC, PPC_NONE)
 
-#define GEN_VXFORM_SIMM(name, opc2, opc3)   \
-GEN_HANDLER(name, 0x04, opc2, opc3, 0x, PPC_ALTIVEC)
-GEN_VXFORM_SIMM(vspltisb, 6, 12),
-GEN_VXFORM_SIMM(vspltish, 6, 13),
-GEN_VXFORM_SIMM(vspltisw, 6, 14),
+#define GEN_VXFORM_DUAL_INV(name0, name1, opc2, opc3, inval0, inval1, type) \
+GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, \
+   PPC_NONE)
+GEN_VXFORM_DUAL_INV(vspltisb, vinsertb, 6, 12, 0x, 0x10,
+