This adds code to analyse_instr() and emulate_step() to handle the
vector element loads and stores:

lvebx, lvehx, lvewx, stvebx, stvehx, stvewx.

Signed-off-by: Paul Mackerras <pau...@ozlabs.org>
---
 arch/powerpc/lib/sstep.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 48 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 5e3afa1..b637496 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -475,7 +475,7 @@ static nokprobe_inline int do_vec_load(int rn, unsigned 
long ea,
                return -EFAULT;
        /* align to multiple of size */
        ea &= ~(size - 1);
-       err = copy_mem_in(u.b, ea, size);
+       err = copy_mem_in(&u.b[ea & 0xf], ea, size);
        if (err)
                return err;
 
@@ -507,7 +507,7 @@ static nokprobe_inline int do_vec_store(int rn, unsigned 
long ea,
        else
                u.v = current->thread.vr_state.vr[rn];
        preempt_enable();
-       return copy_mem_out(u.b, ea, size);
+       return copy_mem_out(&u.b[ea & 0xf], ea, size);
 }
 #endif /* CONFIG_ALTIVEC */
 
@@ -1679,6 +1679,31 @@ int analyse_instr(struct instruction_op *op, const 
struct pt_regs *regs,
                        break;
 
 #ifdef CONFIG_ALTIVEC
+               /*
+                * Note: for the load/store vector element instructions,
+                * bits of the EA say which field of the VMX register to use.
+                */
+               case 7:         /* lvebx */
+                       if (!(regs->msr & MSR_VEC))
+                               goto vecunavail;
+                       op->type = MKOP(LOAD_VMX, 0, 1);
+                       op->element_size = 1;
+                       break;
+
+               case 39:        /* lvehx */
+                       if (!(regs->msr & MSR_VEC))
+                               goto vecunavail;
+                       op->type = MKOP(LOAD_VMX, 0, 2);
+                       op->element_size = 2;
+                       break;
+
+               case 71:        /* lvewx */
+                       if (!(regs->msr & MSR_VEC))
+                               goto vecunavail;
+                       op->type = MKOP(LOAD_VMX, 0, 4);
+                       op->element_size = 4;
+                       break;
+
                case 103:       /* lvx */
                case 359:       /* lvxl */
                        if (!(regs->msr & MSR_VEC))
@@ -1687,6 +1712,27 @@ int analyse_instr(struct instruction_op *op, const 
struct pt_regs *regs,
                        op->element_size = 16;
                        break;
 
+               case 135:       /* stvebx */
+                       if (!(regs->msr & MSR_VEC))
+                               goto vecunavail;
+                       op->type = MKOP(STORE_VMX, 0, 1);
+                       op->element_size = 1;
+                       break;
+
+               case 167:       /* stvehx */
+                       if (!(regs->msr & MSR_VEC))
+                               goto vecunavail;
+                       op->type = MKOP(STORE_VMX, 0, 2);
+                       op->element_size = 2;
+                       break;
+
+               case 199:       /* stvewx */
+                       if (!(regs->msr & MSR_VEC))
+                               goto vecunavail;
+                       op->type = MKOP(STORE_VMX, 0, 4);
+                       op->element_size = 4;
+                       break;
+
                case 231:       /* stvx */
                case 487:       /* stvxl */
                        if (!(regs->msr & MSR_VEC))
-- 
2.7.4

Reply via email to