diff options
author | Tom Musta <tommusta@gmail.com> | 2014-02-12 15:23:18 -0600 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2014-03-05 03:07:00 +0100 |
commit | 57354f8f12d04efc3c38126b967fc178b56885f5 (patch) | |
tree | f102711c5d6955ee4e3ce37582bf63fe9ae07f2b /target-ppc/int_helper.c | |
parent | 557d52fa697c938aeff2784b79df55952c3bfcc1 (diff) |
target-ppc: Altivec 2.07: Vector SHA Sigma Instructions
This patch adds the Vector SHA Sigma instructions introduced in Power
ISA Version 2.07:
- Vector SHA-512 Sigma Doubleword (vshasigmad)
- Vector SHA-256 Sigma Word (vshasigmaw)
Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'target-ppc/int_helper.c')
-rw-r--r-- | target-ppc/int_helper.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c index cd04e8ab71..e6a7ad025c 100644 --- a/target-ppc/int_helper.c +++ b/target-ppc/int_helper.c @@ -2618,6 +2618,88 @@ void helper_vncipherlast(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) r->u64[1] = vtemp2.u64[1] ^ b->u64[1]; } +#define ROTRu32(v, n) (((v) >> (n)) | ((v) << (32-n))) +#if defined(HOST_WORDS_BIGENDIAN) +#define EL_IDX(i) (i) +#else +#define EL_IDX(i) (3 - (i)) +#endif + +void helper_vshasigmaw(ppc_avr_t *r, ppc_avr_t *a, uint32_t st_six) +{ + int st = (st_six & 0x10) != 0; + int six = st_six & 0xF; + int i; + + VECTOR_FOR_INORDER_I(i, u32) { + if (st == 0) { + if ((six & (0x8 >> i)) == 0) { + r->u32[EL_IDX(i)] = ROTRu32(a->u32[EL_IDX(i)], 7) ^ + ROTRu32(a->u32[EL_IDX(i)], 18) ^ + (a->u32[EL_IDX(i)] >> 3); + } else { /* six.bit[i] == 1 */ + r->u32[EL_IDX(i)] = ROTRu32(a->u32[EL_IDX(i)], 17) ^ + ROTRu32(a->u32[EL_IDX(i)], 19) ^ + (a->u32[EL_IDX(i)] >> 10); + } + } else { /* st == 1 */ + if ((six & (0x8 >> i)) == 0) { + r->u32[EL_IDX(i)] = ROTRu32(a->u32[EL_IDX(i)], 2) ^ + ROTRu32(a->u32[EL_IDX(i)], 13) ^ + ROTRu32(a->u32[EL_IDX(i)], 22); + } else { /* six.bit[i] == 1 */ + r->u32[EL_IDX(i)] = ROTRu32(a->u32[EL_IDX(i)], 6) ^ + ROTRu32(a->u32[EL_IDX(i)], 11) ^ + ROTRu32(a->u32[EL_IDX(i)], 25); + } + } + } +} + +#undef ROTRu32 +#undef EL_IDX + +#define ROTRu64(v, n) (((v) >> (n)) | ((v) << (64-n))) +#if defined(HOST_WORDS_BIGENDIAN) +#define EL_IDX(i) (i) +#else +#define EL_IDX(i) (1 - (i)) +#endif + +void helper_vshasigmad(ppc_avr_t *r, ppc_avr_t *a, uint32_t st_six) +{ + int st = (st_six & 0x10) != 0; + int six = st_six & 0xF; + int i; + + VECTOR_FOR_INORDER_I(i, u64) { + if (st == 0) { + if ((six & (0x8 >> (2*i))) == 0) { + r->u64[EL_IDX(i)] = ROTRu64(a->u64[EL_IDX(i)], 1) ^ + ROTRu64(a->u64[EL_IDX(i)], 8) ^ + (a->u64[EL_IDX(i)] >> 7); + } else { /* six.bit[2*i] == 1 */ + r->u64[EL_IDX(i)] = ROTRu64(a->u64[EL_IDX(i)], 19) ^ + ROTRu64(a->u64[EL_IDX(i)], 61) ^ + (a->u64[EL_IDX(i)] >> 6); + } + } else { /* st == 1 */ + if ((six & (0x8 >> (2*i))) == 0) { + r->u64[EL_IDX(i)] = ROTRu64(a->u64[EL_IDX(i)], 28) ^ + ROTRu64(a->u64[EL_IDX(i)], 34) ^ + ROTRu64(a->u64[EL_IDX(i)], 39); + } else { /* six.bit[2*i] == 1 */ + r->u64[EL_IDX(i)] = ROTRu64(a->u64[EL_IDX(i)], 14) ^ + ROTRu64(a->u64[EL_IDX(i)], 18) ^ + ROTRu64(a->u64[EL_IDX(i)], 41); + } + } + } +} + +#undef ROTRu64 +#undef EL_IDX + #undef VECTOR_FOR_INORDER_I #undef HI_IDX #undef LO_IDX |