From 4004c1dbca3ac2399d51ba636b4de032448adc9f Mon Sep 17 00:00:00 2001 From: Vivek Andrew Sha Date: Thu, 28 Jul 2016 23:44:17 +0530 Subject: target-ppc: add vsrv instruction Adds Vector Shift Right Variable instruction. Signed-off-by: Vivek Andrew Sha [ reverse the order of computation to avoid temporary array ] Signed-off-by: Nikunj A Dadhania Reviewed-by: Richard Henderson Signed-off-by: David Gibson --- target-ppc/int_helper.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'target-ppc/int_helper.c') diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c index 12fe144..552b2e0 100644 --- a/target-ppc/int_helper.c +++ b/target-ppc/int_helper.c @@ -1710,6 +1710,23 @@ void helper_vslv(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) } } +void helper_vsrv(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) +{ + int i; + unsigned int shift, bytes; + + /* Use reverse order, as destination and source register can be same. Its + * being modified in place saving temporary, reverse order will guarantee + * that computed result is not fed back. + */ + for (i = ARRAY_SIZE(r->u8) - 1; i >= 0; i--) { + shift = b->u8[i] & 0x7; /* extract shift value */ + bytes = ((i ? a->u8[i - 1] : 0) << 8) + a->u8[i]; + /* extract adjacent bytes */ + r->u8[i] = (bytes >> shift) & 0xFF; /* shift and store result */ + } +} + void helper_vsldoi(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t shift) { int sh = shift & 0xf; -- cgit v1.1