Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / v8 / src / arm64 / cpu-arm64.cc
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // CPU specific code for arm independent of OS goes here.
6
7 #include "v8.h"
8
9 #if V8_TARGET_ARCH_ARM64
10
11 #include "arm64/cpu-arm64.h"
12 #include "arm64/utils-arm64.h"
13
14 namespace v8 {
15 namespace internal {
16
17 #ifdef DEBUG
18 bool CpuFeatures::initialized_ = false;
19 #endif
20 unsigned CpuFeatures::supported_ = 0;
21 unsigned CpuFeatures::cross_compile_ = 0;
22
23
24 class CacheLineSizes {
25  public:
26   CacheLineSizes() {
27 #ifdef USE_SIMULATOR
28     cache_type_register_ = 0;
29 #else
30     // Copy the content of the cache type register to a core register.
31     __asm__ __volatile__ ("mrs %[ctr], ctr_el0"  // NOLINT
32                           : [ctr] "=r" (cache_type_register_));
33 #endif
34   };
35
36   uint32_t icache_line_size() const { return ExtractCacheLineSize(0); }
37   uint32_t dcache_line_size() const { return ExtractCacheLineSize(16); }
38
39  private:
40   uint32_t ExtractCacheLineSize(int cache_line_size_shift) const {
41     // The cache type register holds the size of the caches as a power of two.
42     return 1 << ((cache_type_register_ >> cache_line_size_shift) & 0xf);
43   }
44
45   uint32_t cache_type_register_;
46 };
47
48
49 void CPU::FlushICache(void* address, size_t length) {
50   if (length == 0) return;
51
52 #ifdef USE_SIMULATOR
53   // TODO(all): consider doing some cache simulation to ensure every address
54   // run has been synced.
55   USE(address);
56   USE(length);
57 #else
58   // The code below assumes user space cache operations are allowed. The goal
59   // of this routine is to make sure the code generated is visible to the I
60   // side of the CPU.
61
62   uintptr_t start = reinterpret_cast<uintptr_t>(address);
63   // Sizes will be used to generate a mask big enough to cover a pointer.
64   CacheLineSizes sizes;
65   uintptr_t dsize = sizes.dcache_line_size();
66   uintptr_t isize = sizes.icache_line_size();
67   // Cache line sizes are always a power of 2.
68   ASSERT(CountSetBits(dsize, 64) == 1);
69   ASSERT(CountSetBits(isize, 64) == 1);
70   uintptr_t dstart = start & ~(dsize - 1);
71   uintptr_t istart = start & ~(isize - 1);
72   uintptr_t end = start + length;
73
74   __asm__ __volatile__ (  // NOLINT
75     // Clean every line of the D cache containing the target data.
76     "0:                                \n\t"
77     // dc      : Data Cache maintenance
78     //    c    : Clean
79     //     va  : by (Virtual) Address
80     //       u : to the point of Unification
81     // The point of unification for a processor is the point by which the
82     // instruction and data caches are guaranteed to see the same copy of a
83     // memory location. See ARM DDI 0406B page B2-12 for more information.
84     "dc   cvau, %[dline]                \n\t"
85     "add  %[dline], %[dline], %[dsize]  \n\t"
86     "cmp  %[dline], %[end]              \n\t"
87     "b.lt 0b                            \n\t"
88     // Barrier to make sure the effect of the code above is visible to the rest
89     // of the world.
90     // dsb    : Data Synchronisation Barrier
91     //    ish : Inner SHareable domain
92     // The point of unification for an Inner Shareable shareability domain is
93     // the point by which the instruction and data caches of all the processors
94     // in that Inner Shareable shareability domain are guaranteed to see the
95     // same copy of a memory location.  See ARM DDI 0406B page B2-12 for more
96     // information.
97     "dsb  ish                           \n\t"
98     // Invalidate every line of the I cache containing the target data.
99     "1:                                 \n\t"
100     // ic      : instruction cache maintenance
101     //    i    : invalidate
102     //     va  : by address
103     //       u : to the point of unification
104     "ic   ivau, %[iline]                \n\t"
105     "add  %[iline], %[iline], %[isize]  \n\t"
106     "cmp  %[iline], %[end]              \n\t"
107     "b.lt 1b                            \n\t"
108     // Barrier to make sure the effect of the code above is visible to the rest
109     // of the world.
110     "dsb  ish                           \n\t"
111     // Barrier to ensure any prefetching which happened before this code is
112     // discarded.
113     // isb : Instruction Synchronisation Barrier
114     "isb                                \n\t"
115     : [dline] "+r" (dstart),
116       [iline] "+r" (istart)
117     : [dsize] "r"  (dsize),
118       [isize] "r"  (isize),
119       [end]   "r"  (end)
120     // This code does not write to memory but without the dependency gcc might
121     // move this code before the code is generated.
122     : "cc", "memory"
123   );  // NOLINT
124 #endif
125 }
126
127
128 void CpuFeatures::Probe(bool serializer_enabled) {
129   // AArch64 has no configuration options, no further probing is required.
130   supported_ = 0;
131
132 #ifdef DEBUG
133   initialized_ = true;
134 #endif
135 }
136
137
138 } }  // namespace v8::internal
139
140 #endif  // V8_TARGET_ARCH_ARM64