diff options
author | Edward Nevill edward.nevill@linaro.org <Edward Nevill edward.nevill@linaro.org> | 2014-06-16 21:20:43 +0100 |
---|---|---|
committer | Edward Nevill edward.nevill@linaro.org <Edward Nevill edward.nevill@linaro.org> | 2014-06-16 21:20:43 +0100 |
commit | 3223329ff622c5020b392d1675902c1f8292df40 (patch) | |
tree | 1d7ced65fbe20c83ec061e5e0beef9a2261a9763 | |
parent | 6efe3f0c259d12ed892e3d1be3aa03fbd1ee66d4 (diff) |
Add support for builtin crc32 instructions
-rw-r--r-- | src/cpu/aarch64/vm/assembler_aarch64.hpp | 14 | ||||
-rw-r--r-- | src/cpu/aarch64/vm/globals_aarch64.hpp | 5 | ||||
-rw-r--r-- | src/cpu/aarch64/vm/macroAssembler_aarch64.cpp | 51 | ||||
-rw-r--r-- | src/cpu/aarch64/vm/vm_version_aarch64.cpp | 20 |
4 files changed, 89 insertions, 1 deletions
diff --git a/src/cpu/aarch64/vm/assembler_aarch64.hpp b/src/cpu/aarch64/vm/assembler_aarch64.hpp index 095f22a34..c694cf901 100644 --- a/src/cpu/aarch64/vm/assembler_aarch64.hpp +++ b/src/cpu/aarch64/vm/assembler_aarch64.hpp @@ -2059,6 +2059,20 @@ public: rf(Vm, 16), f(0b000111, 15, 10), rf(Vn, 5), rf(Vd, 0); } + // CRC32 instructions +#define INSN(NAME, sf, sz) \ + void NAME(Register Rd, Register Rn, Register Rm) { \ + starti; \ + f(sf, 31), f(0b0011010110, 30, 21), f(0b0100, 15, 12), f(sz, 11, 10); \ + rf(Rm, 16), rf(Rn, 5), rf(Rd, 0); \ + } + + INSN(crc32b, 0, 0b00); + INSN(crc32h, 0, 0b01); + INSN(crc32w, 0, 0b10); + INSN(crc32x, 1, 0b11); + +#undef INSN /* Simulator extensions to the ISA diff --git a/src/cpu/aarch64/vm/globals_aarch64.hpp b/src/cpu/aarch64/vm/globals_aarch64.hpp index af7a83a5d..b32553e22 100644 --- a/src/cpu/aarch64/vm/globals_aarch64.hpp +++ b/src/cpu/aarch64/vm/globals_aarch64.hpp @@ -102,6 +102,7 @@ define_pd_global(intx, InlineSmallCode, 1000); // Don't attempt to use Neon on builtin sim until builtin sim supports it #define UseNeon false +#define UseCRC32 false #else #define UseBuiltinSim false @@ -119,7 +120,9 @@ define_pd_global(intx, InlineSmallCode, 1000); notproduct(bool, UseAcqRelForVolatileFields, false, \ "Use acquire and release insns for volatile fields") \ product(bool, UseNeon, false, \ - "Use Neon for CRC32 computation") + "Use Neon for CRC32 computation") \ + product(bool, UseCRC32, false, \ + "Use CRC32 instructions for CRC32 computation") #endif diff --git a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp index f7f9cd89c..0b308f2b1 100644 --- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp +++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp @@ -2156,6 +2156,57 @@ void MacroAssembler::kernel_crc32(Register crc, Register buf, Register len, unsigned long offset; ornw(crc, zr, crc); + + if (UseCRC32) { + Label CRC_by64_loop, CRC_by4_loop, CRC_by1_loop; + + subs(len, len, 64); + br(Assembler::GE, CRC_by64_loop); + adds(len, len, 64-4); + br(Assembler::GE, CRC_by4_loop); + adds(len, len, 4); + br(Assembler::GT, CRC_by1_loop); + b(L_exit); + + BIND(CRC_by4_loop); + ldrw(tmp, Address(post(buf, 4))); + subs(len, len, 4); + crc32w(crc, crc, tmp); + br(Assembler::GE, CRC_by4_loop); + adds(len, len, 4); + br(Assembler::LE, L_exit); + BIND(CRC_by1_loop); + ldrb(tmp, Address(post(buf, 1))); + subs(len, len, 1); + crc32b(crc, crc, tmp); + br(Assembler::GT, CRC_by1_loop); + b(L_exit); + + align(CodeEntryAlignment); + BIND(CRC_by64_loop); + subs(len, len, 64); + ldp(tmp, tmp3, Address(post(buf, 16))); + crc32x(crc, crc, tmp); + crc32x(crc, crc, tmp3); + ldp(tmp, tmp3, Address(post(buf, 16))); + crc32x(crc, crc, tmp); + crc32x(crc, crc, tmp3); + ldp(tmp, tmp3, Address(post(buf, 16))); + crc32x(crc, crc, tmp); + crc32x(crc, crc, tmp3); + ldp(tmp, tmp3, Address(post(buf, 16))); + crc32x(crc, crc, tmp); + crc32x(crc, crc, tmp3); + br(Assembler::GE, CRC_by64_loop); + adds(len, len, 64-4); + br(Assembler::GE, CRC_by4_loop); + adds(len, len, 4); + br(Assembler::GT, CRC_by1_loop); + BIND(L_exit); + ornw(crc, zr, crc); + return; + } + adrp(table0, ExternalAddress(StubRoutines::crc_table_addr()), offset); if (offset) add(table0, table0, offset); add(table1, table0, 1*256*sizeof(juint)); diff --git a/src/cpu/aarch64/vm/vm_version_aarch64.cpp b/src/cpu/aarch64/vm/vm_version_aarch64.cpp index 983b85585..26fd62860 100644 --- a/src/cpu/aarch64/vm/vm_version_aarch64.cpp +++ b/src/cpu/aarch64/vm/vm_version_aarch64.cpp @@ -35,6 +35,16 @@ # include "os_linux.inline.hpp" #endif +#ifndef BUILTIN_SIM +#include <sys/auxv.h> +#include <asm/hwcap.h> + +#ifndef HWCAP_CRC32 +#define HWCAP_CRC32 (1<<7) +#endif + +#endif + int VM_Version::_cpu; int VM_Version::_model; int VM_Version::_stepping; @@ -92,6 +102,16 @@ void VM_Version::get_processor_features() { FLAG_SET_DEFAULT(PrefetchFieldsAhead, 256); FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 256); +#ifndef BUILTIN_SIM + unsigned long auxv = getauxval(AT_HWCAP); + if (FLAG_IS_DEFAULT(UseCRC32)) { + UseCRC32 = (auxv & HWCAP_CRC32) != 0; + } + if (UseCRC32 && (auxv & HWCAP_CRC32) == 0) { + warning("UseCRC32 specified, but not supported on this CPU"); + } +#endif + if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) { UseCRC32Intrinsics = true; } |