changeset 7818:bd2ddb52a7a1

Add support for SHA intrinsics
author enevill
date Mon, 17 Nov 2014 23:09:36 +0000
parents f0aa6a97d4e2
children 6fb37d6acb12
files src/cpu/aarch64/vm/assembler_aarch64.hpp src/cpu/aarch64/vm/stubGenerator_aarch64.cpp src/cpu/aarch64/vm/vm_version_aarch64.cpp test/compiler/intrinsics/sha/cli/SHAOptionsBase.java test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnSupportedCPU.java test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnSupportedCPU.java test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnSupportedCPU.java test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnSupportedCPU.java test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedAArch64CPU.java test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedAArch64CPU.java test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java
diffstat 16 files changed, 531 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/aarch64/vm/assembler_aarch64.hpp	Tue Nov 11 09:54:51 2014 +0000
+++ b/src/cpu/aarch64/vm/assembler_aarch64.hpp	Mon Nov 17 23:09:36 2014 +0000
@@ -1187,6 +1187,7 @@
 
   INSN(ldrs, 0b00, 1);
   INSN(ldrd, 0b01, 1);
+  INSN(ldrq, 0x10, 1);
 
 #undef INSN
 
@@ -1248,6 +1249,8 @@
   INSN(ldps, 0b00, 0b101, 1, 1, false);
   INSN(stpd, 0b01, 0b101, 1, 0, false);
   INSN(ldpd, 0b01, 0b101, 1, 1, false);
+  INSN(stpq, 0b10, 0b101, 1, 0, false);
+  INSN(ldpq, 0b10, 0b101, 1, 1, false);
 
 #undef INSN
 
@@ -1320,6 +1323,8 @@
   INSN(strs, 0b10, 0b00);
   INSN(ldrd, 0b11, 0b01);
   INSN(ldrs, 0b10, 0b01);
+  INSN(strq, 0b00, 0b10);
+  INSN(ldrq, 0x00, 0b11);
 
 #undef INSN
 
@@ -1993,6 +1998,49 @@
 
 #undef INSN
 
+#define INSN(NAME, opc)                                                                 \
+  void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \
+    starti;                                                                             \
+    f(0, 31), f((int)T & 1, 30), f(opc, 29), f(0b01110, 28, 24);                        \
+    f((int)T >> 1, 23, 22), f(1, 21), rf(Vm, 16), f(0b100001, 15, 10);                  \
+    rf(Vn, 5), rf(Vd, 0);                                                               \
+  }
+
+  INSN(addv, 0);
+  INSN(subv, 1);
+
+#undef INSN
+
+#define INSN(NAME, opc)                                                                 \
+  void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \
+    starti;                                                                             \
+    assert(T == T4S, "arrangement must be T4S");                                        \
+    f(0b01011110000, 31, 21), rf(Vm, 16), f(opc, 15, 10), rf(Vn, 5), rf(Vd, 0);         \
+  }
+
+  INSN(sha1c,     0b000000);
+  INSN(sha1m,     0b001000);
+  INSN(sha1p,     0b000100);
+  INSN(sha1su0,   0b001100);
+  INSN(sha256h2,  0b010100);
+  INSN(sha256h,   0b010000);
+  INSN(sha256su1, 0b011000);
+
+#undef INSN
+
+#define INSN(NAME, opc)                                                                 \
+  void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn) {                   \
+    starti;                                                                             \
+    assert(T == T4S, "arrangement must be T4S");                                        \
+    f(0b0101111000101000, 31, 16), f(opc, 15, 10), rf(Vn, 5), rf(Vd, 0);                \
+  }
+
+  INSN(sha1h,     0b000010);
+  INSN(sha1su1,   0b000110);
+  INSN(sha256su0, 0b001010);
+
+#undef INSN
+
 #define INSN(NAME, opc)                           \
   void NAME(FloatRegister Vd, FloatRegister Vn) { \
     starti;                                       \
--- a/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Tue Nov 11 09:54:51 2014 +0000
+++ b/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Mon Nov 17 23:09:36 2014 +0000
@@ -2066,6 +2066,212 @@
     return start;
   }
 
+  // Arguments:
+  //
+  // Inputs:
+  //   c_rarg0   - byte[]  source+offset
+  //   c_rarg1   - int[]   SHA.state
+  //   c_rarg2   - int     offset
+  //   c_rarg3   - int     limit
+  //
+  address generate_sha1_implCompress(bool multi_block, const char *name) {
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", name);
+    address start = __ pc();
+
+    Register buf   = c_rarg0;
+    Register state = c_rarg1;
+    Register ofs   = c_rarg2;
+    Register limit = c_rarg3;
+
+    Label keys;
+    Label sha1_loop;
+
+    // load the keys into v0..v3
+    __ adr(rscratch1, keys);
+    __ ld4r(v0, v1, v2, v3, __ T4S, Address(rscratch1));
+    // load 5 words state into v6, v7
+    __ ldrq(v6, Address(state, 0));
+    __ ldrs(v7, Address(state, 16));
+
+
+    __ BIND(sha1_loop);
+    // load 64 bytes of data into v16..v19
+    __ ld1(v16, v17, v18, v19, __ T4S, multi_block ? __ post(buf, 64) : buf);
+    __ rev32(v16, __ T16B, v16);
+    __ rev32(v17, __ T16B, v17);
+    __ rev32(v18, __ T16B, v18);
+    __ rev32(v19, __ T16B, v19);
+
+    // do the sha1
+    __ addv(v4, __ T4S, v16, v0);
+    __ orr(v20, __ T16B, v6, v6);
+
+    FloatRegister d0 = v16;
+    FloatRegister d1 = v17;
+    FloatRegister d2 = v18;
+    FloatRegister d3 = v19;
+
+    for (int round = 0; round < 20; round++) {
+      FloatRegister tmp1 = (round & 1) ? v4 : v5;
+      FloatRegister tmp2 = (round & 1) ? v21 : v22;
+      FloatRegister tmp3 = round ? ((round & 1) ? v22 : v21) : v7;
+      FloatRegister tmp4 = (round & 1) ? v5 : v4;
+      FloatRegister key = (round < 4) ? v0 : ((round < 9) ? v1 : ((round < 14) ? v2 : v3));
+
+      if (round < 16) __ sha1su0(d0, __ T4S, d1, d2);
+      if (round < 19) __ addv(tmp1, __ T4S, d1, key);
+      __ sha1h(tmp2, __ T4S, v20);
+      if (round < 5)
+        __ sha1c(v20, __ T4S, tmp3, tmp4);
+      else if (round < 10 || round >= 15)
+        __ sha1p(v20, __ T4S, tmp3, tmp4);
+      else
+        __ sha1m(v20, __ T4S, tmp3, tmp4);
+      if (round < 16) __ sha1su1(d0, __ T4S, d3);
+
+      tmp1 = d0; d0 = d1; d1 = d2; d2 = d3; d3 = tmp1;
+    }
+
+    __ addv(v7, __ T2S, v7, v21);
+    __ addv(v6, __ T4S, v6, v20);
+
+    if (multi_block) {
+      __ add(ofs, ofs, 64);
+      __ cmp(ofs, limit);
+      __ br(Assembler::LE, sha1_loop);
+      __ mov(c_rarg0, ofs); // return ofs
+    }
+
+    __ strq(v6, Address(state, 0));
+    __ strs(v7, Address(state, 16));
+
+    __ ret(lr);
+
+    __ bind(keys);
+    __ emit_int32(0x5a827999);
+    __ emit_int32(0x6ed9eba1);
+    __ emit_int32(0x8f1bbcdc);
+    __ emit_int32(0xca62c1d6);
+
+    return start;
+  }
+
+
+  // Arguments:
+  //
+  // Inputs:
+  //   c_rarg0   - byte[]  source+offset
+  //   c_rarg1   - int[]   SHA.state
+  //   c_rarg2   - int     offset
+  //   c_rarg3   - int     limit
+  //
+  address generate_sha256_implCompress(bool multi_block, const char *name) {
+    static const uint32_t round_consts[64] = {
+      0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+      0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+      0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+      0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+      0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+      0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+      0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+      0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+      0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+      0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+      0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+      0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+      0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+      0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+      0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+      0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
+    };
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", name);
+    address start = __ pc();
+
+    Register buf   = c_rarg0;
+    Register state = c_rarg1;
+    Register ofs   = c_rarg2;
+    Register limit = c_rarg3;
+
+    Label sha1_loop;
+
+    __ stpd(v8, v9, __ pre(sp, -32));
+    __ stpd(v10, v11, Address(sp, 16));
+
+// dga == v0
+// dgb == v1
+// dg0 == v2
+// dg1 == v3
+// dg2 == v4
+// t0 == v6
+// t1 == v7
+
+    // load 16 keys to v16..v31
+    __ lea(rscratch1, ExternalAddress((address)round_consts));
+    __ ld1(v16, v17, v18, v19, __ T4S, __ post(rscratch1, 64));
+    __ ld1(v20, v21, v22, v23, __ T4S, __ post(rscratch1, 64));
+    __ ld1(v24, v25, v26, v27, __ T4S, __ post(rscratch1, 64));
+    __ ld1(v28, v29, v30, v31, __ T4S, rscratch1);
+
+    // load 8 words (256 bits) state
+    __ ldpq(v0, v1, state);
+
+    __ BIND(sha1_loop);
+    // load 64 bytes of data into v8..v11
+    __ ld1(v8, v9, v10, v11, __ T4S, multi_block ? __ post(buf, 64) : buf);
+    __ rev32(v8, __ T16B, v8);
+    __ rev32(v9, __ T16B, v9);
+    __ rev32(v10, __ T16B, v10);
+    __ rev32(v11, __ T16B, v11);
+
+    __ addv(v6, __ T4S, v8, v16);
+    __ orr(v2, __ T16B, v0, v0);
+    __ orr(v3, __ T16B, v1, v1);
+
+    FloatRegister d0 = v8;
+    FloatRegister d1 = v9;
+    FloatRegister d2 = v10;
+    FloatRegister d3 = v11;
+
+
+    for (int round = 0; round < 16; round++) {
+      FloatRegister tmp1 = (round & 1) ? v6 : v7;
+      FloatRegister tmp2 = (round & 1) ? v7 : v6;
+      FloatRegister tmp3 = (round & 1) ? v2 : v4;
+      FloatRegister tmp4 = (round & 1) ? v4 : v2;
+
+      if (round < 12) __ sha256su0(d0, __ T4S, d1);
+       __ orr(v4, __ T16B, v2, v2);
+      if (round < 15)
+        __ addv(tmp1, __ T4S, d1, as_FloatRegister(round + 17));
+      __ sha256h(v2, __ T4S, v3, tmp2);
+      __ sha256h2(v3, __ T4S, v4, tmp2);
+      if (round < 12) __ sha256su1(d0, __ T4S, d2, d3);
+
+      tmp1 = d0; d0 = d1; d1 = d2; d2 = d3; d3 = tmp1;
+    }
+
+    __ addv(v0, __ T4S, v0, v2);
+    __ addv(v1, __ T4S, v1, v3);
+
+    if (multi_block) {
+      __ add(ofs, ofs, 64);
+      __ cmp(ofs, limit);
+      __ br(Assembler::LE, sha1_loop);
+      __ mov(c_rarg0, ofs); // return ofs
+    }
+
+    __ ldpd(v10, v11, Address(sp, 16));
+    __ ldpd(v8, v9, __ post(sp, 32));
+
+    __ stpq(v0, v1, state);
+
+    __ ret(lr);
+
+    return start;
+  }
+
 #ifndef BUILTIN_SIM
   // Safefetch stubs.
   void generate_safefetch(const char* name, int size, address* entry,
@@ -2322,6 +2528,15 @@
       StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt();
     }
 
+    if (UseSHA1Intrinsics) {
+      StubRoutines::_sha1_implCompress     = generate_sha1_implCompress(false,   "sha1_implCompress");
+      StubRoutines::_sha1_implCompressMB   = generate_sha1_implCompress(true,    "sha1_implCompressMB");
+    }
+    if (UseSHA256Intrinsics) {
+      StubRoutines::_sha256_implCompress   = generate_sha256_implCompress(false, "sha256_implCompress");
+      StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(true,  "sha256_implCompressMB");
+    }
+
     // Safefetch stubs.
     generate_safefetch("SafeFetch32", sizeof(int),     &StubRoutines::_safefetch32_entry,
                                                        &StubRoutines::_safefetch32_fault_pc,
--- a/src/cpu/aarch64/vm/vm_version_aarch64.cpp	Tue Nov 11 09:54:51 2014 +0000
+++ b/src/cpu/aarch64/vm/vm_version_aarch64.cpp	Mon Nov 17 23:09:36 2014 +0000
@@ -43,6 +43,14 @@
 #define HWCAP_AES   (1<<3)
 #endif
 
+#ifndef HWCAP_SHA1
+#define HWCAP_SHA1  (1<<5)
+#endif
+
+#ifndef HWCAP_SHA2
+#define HWCAP_SHA2  (1<<6)
+#endif
+
 #ifndef HWCAP_CRC32
 #define HWCAP_CRC32 (1<<7)
 #endif
@@ -112,6 +120,17 @@
 
 #ifndef BUILTIN_SIM
   unsigned long auxv = getauxval(AT_HWCAP);
+
+  char buf[512];
+
+  strcpy(buf, "simd");
+  if (auxv & HWCAP_CRC32) strcat(buf, ", crc");
+  if (auxv & HWCAP_AES)   strcat(buf, ", aes");
+  if (auxv & HWCAP_SHA1)  strcat(buf, ", sha1");
+  if (auxv & HWCAP_SHA2)  strcat(buf, ", sha256");
+
+  _features_str = strdup(buf);
+
   if (FLAG_IS_DEFAULT(UseCRC32)) {
     UseCRC32 = (auxv & HWCAP_CRC32) != 0;
   }
@@ -140,16 +159,48 @@
     UseCRC32Intrinsics = true;
   }
 
+#ifndef BUILTIN_SIM
+  if (auxv & (HWCAP_SHA1 | HWCAP_SHA2)) {
+    if (FLAG_IS_DEFAULT(UseSHA)) {
+      FLAG_SET_DEFAULT(UseSHA, true);
+    }
+  } else
+#endif
   if (UseSHA) {
-    warning("SHA instructions are not implemented");
+    warning("SHA instructions are not available on this CPU");
     FLAG_SET_DEFAULT(UseSHA, false);
   }
-  if (UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics) {
-    warning("SHA intrinsics are not implemented");
+
+  if (!UseSHA) {
     FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
     FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
     FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
   }
+#ifndef BUILTIN_SIM
+  else {
+    if (auxv & HWCAP_SHA1) {
+      if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
+        FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
+      }
+    } else if (UseSHA1Intrinsics) {
+      warning("SHA1 instruction is not available on this CPU.");
+      FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
+    }
+    if (auxv & HWCAP_SHA2) {
+      if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
+        FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
+      }
+    } else if (UseSHA256Intrinsics) {
+      warning("SHA256 instruction (for SHA-224 and SHA-256) is not available on this CPU.");
+      FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
+    }
+    if (UseSHA512Intrinsics) {
+      warning("SHA512 instruction (for SHA-384 and SHA-512) is not available on this CPU.");
+      FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
+    }
+  }
+#endif
+
 #ifdef COMPILER2
   if (FLAG_IS_DEFAULT(OptoScheduling)) {
     OptoScheduling = true;
--- a/test/compiler/intrinsics/sha/cli/SHAOptionsBase.java	Tue Nov 11 09:54:51 2014 +0000
+++ b/test/compiler/intrinsics/sha/cli/SHAOptionsBase.java	Mon Nov 17 23:09:36 2014 +0000
@@ -95,6 +95,19 @@
                 default:
                     throw new Error("Unexpected option " + optionName);
             }
+        } else if (Platform.isAArch64()) {
+            switch (optionName) {
+                case SHAOptionsBase.USE_SHA_OPTION:
+                    return SHAOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
+                case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
+                    return SHAOptionsBase.SHA1_INSTRUCTION_IS_NOT_AVAILABLE;
+                case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
+                    return SHAOptionsBase.SHA256_INSTRUCTION_IS_NOT_AVAILABLE;
+                case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
+                    return SHAOptionsBase.SHA512_INSTRUCTION_IS_NOT_AVAILABLE;
+                default:
+                    throw new Error("Unexpected option " + optionName);
+            }
         } else {
             throw new Error("Support for CPUs other then X86 or SPARC is not "
                     + "implemented.");
--- a/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnSupportedCPU.java	Tue Nov 11 09:54:51 2014 +0000
+++ b/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnSupportedCPU.java	Mon Nov 17 23:09:36 2014 +0000
@@ -34,7 +34,10 @@
  */
 public class TestUseSHA1IntrinsicsOptionOnSupportedCPU {
     public static void main(String args[]) throws Throwable {
-        new SHAOptionsBase(new GenericTestCaseForSupportedSparcCPU(
-                SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION)).test();
+        new SHAOptionsBase(
+                new GenericTestCaseForSupportedSparcCPU(
+                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
+                new GenericTestCaseForSupportedAArch64CPU(
+                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION)).test();
     }
 }
--- a/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java	Tue Nov 11 09:54:51 2014 +0000
+++ b/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java	Mon Nov 17 23:09:36 2014 +0000
@@ -40,6 +40,8 @@
                         SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
                 new UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU(
                         SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
+                new GenericTestCaseForUnsupportedAArch64CPU(
+                        SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
                 new GenericTestCaseForUnsupportedX86CPU(
                         SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
                 new GenericTestCaseForOtherCPU(
--- a/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnSupportedCPU.java	Tue Nov 11 09:54:51 2014 +0000
+++ b/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnSupportedCPU.java	Mon Nov 17 23:09:36 2014 +0000
@@ -35,7 +35,10 @@
  */
 public class TestUseSHA256IntrinsicsOptionOnSupportedCPU {
     public static void main(String args[]) throws Throwable {
-        new SHAOptionsBase(new GenericTestCaseForSupportedSparcCPU(
-                SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION)).test();
+        new SHAOptionsBase(
+                new GenericTestCaseForSupportedSparcCPU(
+                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
+                new GenericTestCaseForSupportedAArch64CPU(
+                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION)).test();
     }
 }
--- a/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java	Tue Nov 11 09:54:51 2014 +0000
+++ b/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java	Mon Nov 17 23:09:36 2014 +0000
@@ -40,6 +40,8 @@
                         SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
                 new UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU(
                         SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
+                new GenericTestCaseForUnsupportedAArch64CPU(
+                        SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
                 new GenericTestCaseForUnsupportedX86CPU(
                         SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
                 new GenericTestCaseForOtherCPU(
--- a/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnSupportedCPU.java	Tue Nov 11 09:54:51 2014 +0000
+++ b/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnSupportedCPU.java	Mon Nov 17 23:09:36 2014 +0000
@@ -35,7 +35,10 @@
  */
 public class TestUseSHA512IntrinsicsOptionOnSupportedCPU {
     public static void main(String args[]) throws Throwable {
-        new SHAOptionsBase(new GenericTestCaseForSupportedSparcCPU(
-                SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION)).test();
+        new SHAOptionsBase(
+                new GenericTestCaseForSupportedSparcCPU(
+                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
+                new GenericTestCaseForSupportedAArch64CPU(
+                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION)).test();
     }
 }
--- a/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java	Tue Nov 11 09:54:51 2014 +0000
+++ b/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java	Mon Nov 17 23:09:36 2014 +0000
@@ -40,6 +40,8 @@
                         SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
                 new UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU(
                         SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
+                new GenericTestCaseForUnsupportedAArch64CPU(
+                        SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
                 new GenericTestCaseForUnsupportedX86CPU(
                         SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
                 new GenericTestCaseForOtherCPU(
--- a/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnSupportedCPU.java	Tue Nov 11 09:54:51 2014 +0000
+++ b/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnSupportedCPU.java	Mon Nov 17 23:09:36 2014 +0000
@@ -38,6 +38,8 @@
                 new GenericTestCaseForSupportedSparcCPU(
                         SHAOptionsBase.USE_SHA_OPTION),
                 new UseSHASpecificTestCaseForSupportedSparcCPU(
+                        SHAOptionsBase.USE_SHA_OPTION),
+                new GenericTestCaseForSupportedAArch64CPU(
                         SHAOptionsBase.USE_SHA_OPTION)).test();
     }
 }
--- a/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java	Tue Nov 11 09:54:51 2014 +0000
+++ b/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java	Mon Nov 17 23:09:36 2014 +0000
@@ -39,6 +39,8 @@
                         SHAOptionsBase.USE_SHA_OPTION),
                 new UseSHASpecificTestCaseForUnsupportedSparcCPU(
                         SHAOptionsBase.USE_SHA_OPTION),
+                new GenericTestCaseForUnsupportedAArch64CPU(
+                        SHAOptionsBase.USE_SHA_OPTION),
                 new GenericTestCaseForUnsupportedX86CPU(
                         SHAOptionsBase.USE_SHA_OPTION),
                 new GenericTestCaseForOtherCPU(
--- a/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java	Tue Nov 11 09:54:51 2014 +0000
+++ b/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java	Mon Nov 17 23:09:36 2014 +0000
@@ -36,7 +36,8 @@
     public GenericTestCaseForOtherCPU(String optionName) {
         // Execute the test case on any CPU except SPARC and X86
         super(optionName, new NotPredicate(new OrPredicate(Platform::isSparc,
-                new OrPredicate(Platform::isX64, Platform::isX86))));
+                new OrPredicate(Platform::isAArch64,
+                        new OrPredicate(Platform::isX64, Platform::isX86)))));
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedAArch64CPU.java	Mon Nov 17 23:09:36 2014 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.oracle.java.testlibrary.ExitCode;
+import com.oracle.java.testlibrary.Platform;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+
+/**
+ * Generic test case for SHA-related options targeted to AArch64 CPUs which
+ * support instructions required by the tested option.
+ */
+public class GenericTestCaseForSupportedAArch64CPU extends
+        SHAOptionsBase.TestCase {
+    public GenericTestCaseForSupportedAArch64CPU(String optionName) {
+        super(optionName, new AndPredicate(Platform::isAArch64,
+                SHAOptionsBase.getPredicateForOption(optionName)));
+    }
+
+    @Override
+    protected void verifyWarnings() throws Throwable {
+        // Verify that there are no warning when option is explicitly enabled.
+        CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
+                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                }, ExitCode.OK,
+                CommandLineOptionTest.prepareBooleanFlag(optionName, true));
+
+        // Verify that option could be disabled even if +UseSHA was passed to
+        // JVM.
+        CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
+                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                }, ExitCode.OK,
+                CommandLineOptionTest.prepareBooleanFlag(
+                        SHAOptionsBase.USE_SHA_OPTION, true),
+                CommandLineOptionTest.prepareBooleanFlag(optionName, false));
+
+        // Verify that it is possible to enable the tested option and disable
+        // all SHA intrinsics via -UseSHA without any warnings.
+        CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
+                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                }, ExitCode.OK,
+                CommandLineOptionTest.prepareBooleanFlag(
+                        SHAOptionsBase.USE_SHA_OPTION, false),
+                CommandLineOptionTest.prepareBooleanFlag(optionName, true));
+    }
+
+    @Override
+    protected void verifyOptionValues() throws Throwable {
+        // Verify that on supported CPU option is enabled by default.
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true");
+
+        // Verify that it is possible to explicitly enable the option.
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true",
+                CommandLineOptionTest.prepareBooleanFlag(optionName, true));
+
+        // Verify that it is possible to explicitly disable the option.
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                CommandLineOptionTest.prepareBooleanFlag(optionName, false));
+
+        // verify that option is disabled when -UseSHA was passed to JVM.
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                CommandLineOptionTest.prepareBooleanFlag(optionName, true),
+                CommandLineOptionTest.prepareBooleanFlag(
+                        SHAOptionsBase.USE_SHA_OPTION, false));
+
+        // Verify that it is possible to explicitly disable the tested option
+        // even if +UseSHA was passed to JVM.
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                CommandLineOptionTest.prepareBooleanFlag(
+                        SHAOptionsBase.USE_SHA_OPTION, true),
+                CommandLineOptionTest.prepareBooleanFlag(optionName, false));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedAArch64CPU.java	Mon Nov 17 23:09:36 2014 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.oracle.java.testlibrary.ExitCode;
+import com.oracle.java.testlibrary.Platform;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
+
+/**
+ * Generic test case for SHA-related options targeted to AArch64 CPUs which don't
+ * support instruction required by the tested option.
+ */
+public class GenericTestCaseForUnsupportedAArch64CPU extends
+        SHAOptionsBase.TestCase {
+    public GenericTestCaseForUnsupportedAArch64CPU(String optionName) {
+        super(optionName, new AndPredicate(Platform::isAArch64,
+                new NotPredicate(SHAOptionsBase.getPredicateForOption(
+                        optionName))));
+    }
+
+    @Override
+    protected void verifyWarnings() throws Throwable {
+        //Verify that option could be disabled without any warnings.
+        CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
+                        SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
+                }, ExitCode.OK,
+                CommandLineOptionTest.prepareBooleanFlag(optionName, false));
+    }
+
+    @Override
+    protected void verifyOptionValues() throws Throwable {
+        // Verify that option is disabled by default.
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false");
+
+        // Verify that option is disabled even if it was explicitly enabled
+        // using CLI options.
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                CommandLineOptionTest.prepareBooleanFlag(optionName, true));
+
+        // Verify that option is disabled when +UseSHA was passed to JVM.
+        CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
+                CommandLineOptionTest.prepareBooleanFlag(
+                        SHAOptionsBase.USE_SHA_OPTION, true));
+    }
+}
--- a/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java	Tue Nov 11 09:54:51 2014 +0000
+++ b/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java	Mon Nov 17 23:09:36 2014 +0000
@@ -59,16 +59,25 @@
     };
 
     public static final BooleanSupplier SHA1_INSTRUCTION_AVAILABLE
-            = new CPUSpecificPredicate("sparc.*", new String[] { "sha1" },
-                    null);
+            = new OrPredicate(
+                    new CPUSpecificPredicate("sparc.*", new String[] { "sha1" },
+                            null),
+                    new CPUSpecificPredicate("aarch64", new String[] { "sha1" },
+                            null));
 
     public static final BooleanSupplier SHA256_INSTRUCTION_AVAILABLE
-            = new CPUSpecificPredicate("sparc.*", new String[] { "sha256" },
-                    null);
+            = new OrPredicate(
+                    new CPUSpecificPredicate("sparc.*", new String[] { "sha256" },
+                            null),
+                    new CPUSpecificPredicate("aarch64", new String[] { "sha256" },
+                            null));
 
     public static final BooleanSupplier SHA512_INSTRUCTION_AVAILABLE
-            = new CPUSpecificPredicate("sparc.*", new String[] { "sha512" },
-                    null);
+            = new OrPredicate(
+                    new CPUSpecificPredicate("sparc.*", new String[] { "sha512" },
+                            null),
+                    new CPUSpecificPredicate("aarch64", new String[] { "sha512" },
+                            null));
 
     public static final BooleanSupplier ANY_SHA_INSTRUCTION_AVAILABLE
             = new OrPredicate(IntrinsicPredicates.SHA1_INSTRUCTION_AVAILABLE,