Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Unified Diff: src/arm/assembler-arm.cc

Issue 12920009: Use generated Neon version of MemCopy() on ARM, if platform supports it. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/arm/assembler-arm.cc
===================================================================
--- src/arm/assembler-arm.cc (revision 14076)
+++ src/arm/assembler-arm.cc (working copy)
@@ -154,6 +154,11 @@
}
#else // __arm__
+ if (!IsSupported(NEON) && OS::ArmCpuHasFeature(NEON)) {
+ found_by_runtime_probing_only_ |=
+ static_cast<uint64_t>(1) << NEON;
+ }
+
// Probe for additional features not already known to be available.
if (!IsSupported(VFP3) && OS::ArmCpuHasFeature(VFP3)) {
// This implementation also sets the VFP flags if runtime
@@ -1597,7 +1602,17 @@
addrmod4(cond | B27 | am, base, src);
}
+void Assembler::pld(Register base, int offset, int write) {
+ int U = (offset >= 0) ? B23 : 0;
+ int R = (write == 0) ? B22 : 0;
+ if (offset < 0)
+ offset = -offset;
+ ASSERT(is_uint12(offset));
+ emit(0xf510f000 | B16 * base.code() | U | R | offset);
+}
+
+
// Exception-generating instructions and debugging support.
// Stops with a non-negative code less than kNumOfWatchedStops support
// enabling/disabling and a counter feature. See simulator-arm.h .
@@ -2650,7 +2665,210 @@
m*B5 | vm);
}
danno 2013/03/27 08:40:07 nit: coding style, 2 empty lines between method de
Nike 2013/03/29 08:48:52 Done.
+static inline int bin_log(int x) {
+ switch (x) {
+ case 1:
+ return 0;
+ case 2:
+ return 1;
+ case 4:
+ return 2;
+ case 8:
+ return 3;
+ case 16:
+ return 4;
+ case 32:
+ return 5;
+ case 64:
+ return 6;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+static inline int count_to_type(int count) {
+ switch (count) {
+ case 1:
+ return 7;
+ case 2:
+ return 10;
+ case 3:
+ return 6;
+ case 4:
+ return 2;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+enum NeonElementType {
danno 2013/03/27 08:40:07 Why is this not in assembler-arm.h?
Nike 2013/03/29 08:48:52 Because those enums are never used by user, only a
+ MultipleElements = 0,
+ SingleElement = 1
+};
+
+enum NeonLoadStoreType {
danno 2013/03/27 08:40:07 same here?
Nike 2013/03/29 08:48:52 Same as above.
+ Store = 0,
+ Load = 1
+};
+
+static uint32_t neon_vector_op(int size,
+ const Register base,
+ const DwVfpRegister first,
+ NeonWritebackType writeback,
+ int align_bytes,
+ NeonLoadStoreType load,
+ NeonElementType single,
+ NeonElementIndex element_index,
+ int type) {
+ ASSERT(type >= 0);
+ ASSERT(!base.is(pc));
+ ASSERT(size == 8 || size == 16 || size == 32);
+
+ int d = (first.code() >> 4) & 1;
+ int Vd = first.code() & 0xf;
+ // we don't need arbitrary Rm so far
+ int rm = (writeback == Writeback) ? 13 : 15;
+ int size_enc = bin_log(size) - 3;
+ uint32_t result =
+ (0xf << 28) | B26 | B22*d | B21*load | B16*base.code() |
+ B12*Vd | rm;
+
+ int index_align = 0;
+ if (single == SingleElement) {
+ switch (align_bytes) {
+ case 16:
+ ASSERT(size == 32);
+ ASSERT(element_index < element_2);
+ index_align = 0x3 | ((element_index & 0x1) << 3);
+ break;
+ case 8:
+ ASSERT(size == 16 || size == 32);
+ ASSERT(element_index < element_4);
+ index_align = 0x1 | ((element_index & 0x3) << 2);
+ break;
+ case 4:
+ ASSERT(size == 8);
+ index_align = (element_index & 0x7) << 1;
+ break;
+ case 1:
+ index_align = 0;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ if (single == SingleElement) {
+ result |= B23 | (1<<10)*size_enc | B9 | B8 | B4*index_align;
+ } else {
+ int align_enc = align_bytes == 1 ? 0 : bin_log(align_bytes / 4);
+ result |= B8*type | B6*size_enc | B4*align_enc;
+ }
+ return result;
+}
+
+void Assembler::vld1(int size,
+ const Register base,
+ const DwVfpRegister first,
+ const DwVfpRegister last,
+ NeonWritebackType writeback,
+ int align_bytes) {
+ ASSERT(IsEnabled(NEON));
+ ASSERT_LE(first.code(), last.code());
+ int count = last.code() - first.code() + 1;
+ ASSERT(count <= 4);
+ emit(neon_vector_op(size, base, first, writeback, align_bytes,
+ Load, MultipleElements, element_0,
+ count_to_type(count)));
+}
+
+void Assembler::vld1(int size,
+ const Register base,
+ const DwVfpRegister first,
+ NeonElementIndex element_index,
+ NeonWritebackType writeback,
+ int align_bytes) {
+ ASSERT(IsEnabled(NEON));
+ emit(neon_vector_op(size, base, first, writeback, align_bytes,
+ Load, SingleElement, element_index, 0));
+}
+
+void Assembler::vst1(int size,
+ const Register base,
+ const DwVfpRegister first,
+ const DwVfpRegister last,
+ NeonWritebackType writeback,
+ int align_bytes) {
+ ASSERT(IsEnabled(NEON));
+ ASSERT_LE(first.code(), last.code());
+ int count = last.code() - first.code() + 1;
+ ASSERT(count <= 4);
+ emit(neon_vector_op(size, base, first, writeback, align_bytes,
+ Store, MultipleElements, element_0,
+ count_to_type(count)));
+}
+
+void Assembler::vst1(int size,
+ const Register base,
+ const DwVfpRegister first,
+ NeonElementIndex element_index,
+ NeonWritebackType writeback,
+ int align_bytes) {
+ ASSERT(IsEnabled(NEON));
+ emit(neon_vector_op(size, base, first, writeback, align_bytes,
+ Store, SingleElement, element_index, 0));
+}
+
+void Assembler::vld4(int size,
+ const Register base,
+ const DwVfpRegister first,
+ const DwVfpRegister last,
+ NeonWritebackType writeback,
+ int align_bytes) {
+ ASSERT(IsEnabled(NEON));
+ // we don't support increment == 2, yet
+ int type = 0;
+ emit(neon_vector_op(size, base, first, writeback, align_bytes,
+ Load, MultipleElements, element_0, type));
+}
+
+void Assembler::vld4(int size,
+ const Register base,
+ const DwVfpRegister first,
+ NeonElementIndex element_index,
+ NeonWritebackType writeback,
+ int align_bytes) {
+ ASSERT(IsEnabled(NEON));
+ emit(neon_vector_op(size, base, first, writeback, align_bytes,
+ Load, SingleElement, element_index, 0));
+}
+
+void Assembler::vst4(int size,
+ const Register base,
+ const DwVfpRegister first,
+ const DwVfpRegister last,
+ NeonWritebackType writeback,
+ int align_bytes) {
+ ASSERT(IsEnabled(NEON));
+ // we don't support increment == 2, yet
+ int type = 0;
+ emit(neon_vector_op(size, base, first, writeback, align_bytes,
+ Store, MultipleElements, element_0, type));
+}
+
+void Assembler::vst4(int size,
+ const Register base,
+ const DwVfpRegister first,
+ NeonElementIndex element_index,
+ NeonWritebackType writeback,
+ int align_bytes) {
+ ASSERT(IsEnabled(NEON));
+ emit(neon_vector_op(size, base, first, writeback, align_bytes,
+ Store, SingleElement, element_index, 0));
+}
+
// Pseudo instructions.
void Assembler::nop(int type) {
// ARMv6{K/T2} and v7 have an actual NOP instruction but it serializes

Powered by Google App Engine
This is Rietveld 408576698