aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Nevill edward.nevill@linaro.org <Edward Nevill edward.nevill@linaro.org>2014-06-16 21:20:43 +0100
committerEdward Nevill edward.nevill@linaro.org <Edward Nevill edward.nevill@linaro.org>2014-06-16 21:20:43 +0100
commit3223329ff622c5020b392d1675902c1f8292df40 (patch)
tree1d7ced65fbe20c83ec061e5e0beef9a2261a9763
parent6efe3f0c259d12ed892e3d1be3aa03fbd1ee66d4 (diff)
Add support for builtin crc32 instructions
-rw-r--r--src/cpu/aarch64/vm/assembler_aarch64.hpp14
-rw-r--r--src/cpu/aarch64/vm/globals_aarch64.hpp5
-rw-r--r--src/cpu/aarch64/vm/macroAssembler_aarch64.cpp51
-rw-r--r--src/cpu/aarch64/vm/vm_version_aarch64.cpp20
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;
}