aboutsummaryrefslogtreecommitdiff
path: root/target-ppc/int_helper.c
diff options
context:
space:
mode:
authorTom Musta <tommusta@gmail.com>2014-02-12 15:23:18 -0600
committerAlexander Graf <agraf@suse.de>2014-03-05 03:07:00 +0100
commit57354f8f12d04efc3c38126b967fc178b56885f5 (patch)
treef102711c5d6955ee4e3ce37582bf63fe9ae07f2b /target-ppc/int_helper.c
parent557d52fa697c938aeff2784b79df55952c3bfcc1 (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.c82
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