[M94 Dev][Tizen] Fix for errors for generating ninja files
[platform/framework/web/chromium-efl.git] / base / cpu_unittest.cc
1 // Copyright (c) 2012 The Chromium 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 #include "base/cpu.h"
6 #include "base/containers/contains.h"
7 #include "base/logging.h"
8 #include "base/strings/string_util.h"
9 #include "build/build_config.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 // Tests whether we can run extended instructions represented by the CPU
13 // information. This test actually executes some extended instructions (such as
14 // MMX, SSE, etc.) supported by the CPU and sees we can run them without
15 // "undefined instruction" exceptions. That is, this test succeeds when this
16 // test finishes without a crash.
17 TEST(CPU, RunExtendedInstructions) {
18   // Retrieve the CPU information.
19   base::CPU cpu;
20 #if defined(ARCH_CPU_X86_FAMILY)
21
22   ASSERT_TRUE(cpu.has_mmx());
23   ASSERT_TRUE(cpu.has_sse());
24   ASSERT_TRUE(cpu.has_sse2());
25   ASSERT_TRUE(cpu.has_sse3());
26
27 // GCC and clang instruction test.
28 #if defined(COMPILER_GCC)
29   // Execute an MMX instruction.
30   __asm__ __volatile__("emms\n" : : : "mm0");
31
32   // Execute an SSE instruction.
33   __asm__ __volatile__("xorps %%xmm0, %%xmm0\n" : : : "xmm0");
34
35   // Execute an SSE 2 instruction.
36   __asm__ __volatile__("psrldq $0, %%xmm0\n" : : : "xmm0");
37
38   // Execute an SSE 3 instruction.
39   __asm__ __volatile__("addsubpd %%xmm0, %%xmm0\n" : : : "xmm0");
40
41   if (cpu.has_ssse3()) {
42     // Execute a Supplimental SSE 3 instruction.
43     __asm__ __volatile__("psignb %%xmm0, %%xmm0\n" : : : "xmm0");
44   }
45
46   if (cpu.has_sse41()) {
47     // Execute an SSE 4.1 instruction.
48     __asm__ __volatile__("pmuldq %%xmm0, %%xmm0\n" : : : "xmm0");
49   }
50
51   if (cpu.has_sse42()) {
52     // Execute an SSE 4.2 instruction.
53     __asm__ __volatile__("crc32 %%eax, %%eax\n" : : : "eax");
54   }
55
56   if (cpu.has_popcnt()) {
57     // Execute a POPCNT instruction.
58     __asm__ __volatile__("popcnt %%eax, %%eax\n" : : : "eax");
59   }
60
61   if (cpu.has_avx()) {
62     // Execute an AVX instruction.
63     __asm__ __volatile__("vzeroupper\n" : : : "xmm0");
64   }
65
66   if (cpu.has_avx2()) {
67     // Execute an AVX 2 instruction.
68     __asm__ __volatile__("vpunpcklbw %%ymm0, %%ymm0, %%ymm0\n" : : : "xmm0");
69   }
70 // Visual C 32 bit and ClangCL 32/64 bit test.
71 #elif defined(COMPILER_MSVC) && (defined(ARCH_CPU_32_BITS) || \
72       (defined(ARCH_CPU_64_BITS) && defined(__clang__)))
73
74   // Execute an MMX instruction.
75   __asm emms;
76
77   // Execute an SSE instruction.
78   __asm xorps xmm0, xmm0;
79
80   // Execute an SSE 2 instruction.
81   __asm psrldq xmm0, 0;
82
83   // Execute an SSE 3 instruction.
84   __asm addsubpd xmm0, xmm0;
85
86   if (cpu.has_ssse3()) {
87     // Execute a Supplimental SSE 3 instruction.
88     __asm psignb xmm0, xmm0;
89   }
90
91   if (cpu.has_sse41()) {
92     // Execute an SSE 4.1 instruction.
93     __asm pmuldq xmm0, xmm0;
94   }
95
96   if (cpu.has_sse42()) {
97     // Execute an SSE 4.2 instruction.
98     __asm crc32 eax, eax;
99   }
100
101   if (cpu.has_popcnt()) {
102     // Execute a POPCNT instruction.
103     __asm popcnt eax, eax;
104   }
105
106   if (cpu.has_avx()) {
107     // Execute an AVX instruction.
108     __asm vzeroupper;
109   }
110
111   if (cpu.has_avx2()) {
112     // Execute an AVX 2 instruction.
113     __asm vpunpcklbw ymm0, ymm0, ymm0
114   }
115 #endif  // defined(COMPILER_GCC)
116 #endif  // defined(ARCH_CPU_X86_FAMILY)
117
118 #if defined(ARCH_CPU_ARM64)
119   // Check that the CPU is correctly reporting support for the Armv8.5-A memory
120   // tagging extension. The new MTE instructions aren't encoded in NOP space
121   // like BTI/Pointer Authentication and will crash older cores with a SIGILL if
122   // used incorrectly. This test demonstrates how it should be done and that
123   // this approach works.
124   if (cpu.has_mte()) {
125 #if !defined(__ARM_FEATURE_MEMORY_TAGGING)
126     // In this section, we're running on an MTE-compatible core, but we're
127     // building this file without MTE support. Fail this test to indicate that
128     // there's a problem with the base/ build configuration.
129     GTEST_FAIL()
130         << "MTE support detected (but base/ built without MTE support)";
131 #else
132     char ptr[32];
133     uint64_t val;
134     // Execute a trivial MTE instruction. Normally, MTE should be used via the
135     // intrinsics documented at
136     // https://developer.arm.com/documentation/101028/0012/10--Memory-tagging-intrinsics,
137     // this test uses the irg (Insert Random Tag) instruction directly to make
138     // sure that it's not optimized out by the compiler.
139     __asm__ __volatile__("irg %0, %1" : "=r"(val) : "r"(ptr));
140 #endif  // __ARM_FEATURE_MEMORY_TAGGING
141   }
142 #endif  // ARCH_CPU_ARM64
143 }
144
145 // For https://crbug.com/249713
146 TEST(CPU, BrandAndVendorContainsNoNUL) {
147   base::CPU cpu;
148   EXPECT_FALSE(base::Contains(cpu.cpu_brand(), '\0'));
149   EXPECT_FALSE(base::Contains(cpu.vendor_name(), '\0'));
150 }
151
152 #if defined(ARCH_CPU_X86_FAMILY)
153 // Tests that we compute the correct CPU family and model based on the vendor
154 // and CPUID signature.
155 TEST(CPU, X86FamilyAndModel) {
156   base::internal::X86ModelInfo info;
157
158   // Check with an Intel Skylake signature.
159   info = base::internal::ComputeX86FamilyAndModel("GenuineIntel", 0x000406e3);
160   EXPECT_EQ(info.family, 6);
161   EXPECT_EQ(info.model, 78);
162   EXPECT_EQ(info.ext_family, 0);
163   EXPECT_EQ(info.ext_model, 4);
164
165   // Check with an Intel Airmont signature.
166   info = base::internal::ComputeX86FamilyAndModel("GenuineIntel", 0x000406c2);
167   EXPECT_EQ(info.family, 6);
168   EXPECT_EQ(info.model, 76);
169   EXPECT_EQ(info.ext_family, 0);
170   EXPECT_EQ(info.ext_model, 4);
171
172   // Check with an Intel Prescott signature.
173   info = base::internal::ComputeX86FamilyAndModel("GenuineIntel", 0x00000f31);
174   EXPECT_EQ(info.family, 15);
175   EXPECT_EQ(info.model, 3);
176   EXPECT_EQ(info.ext_family, 0);
177   EXPECT_EQ(info.ext_model, 0);
178
179   // Check with an AMD Excavator signature.
180   info = base::internal::ComputeX86FamilyAndModel("AuthenticAMD", 0x00670f00);
181   EXPECT_EQ(info.family, 21);
182   EXPECT_EQ(info.model, 112);
183   EXPECT_EQ(info.ext_family, 6);
184   EXPECT_EQ(info.ext_model, 7);
185 }
186 #endif  // defined(ARCH_CPU_X86_FAMILY)
187
188 #if defined(ARCH_CPU_ARM_FAMILY) && \
189     (defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS))
190 TEST(CPU, ARMImplementerAndPartNumber) {
191   base::CPU cpu;
192
193   const std::string& cpu_brand = cpu.cpu_brand();
194
195   // Some devices, including on the CQ, do not report a cpu_brand
196   // https://crbug.com/1166533 and https://crbug.com/1167123.
197   EXPECT_EQ(cpu_brand, base::TrimWhitespaceASCII(cpu_brand, base::TRIM_ALL));
198   EXPECT_GT(cpu.implementer(), 0u);
199   EXPECT_GT(cpu.part_number(), 0u);
200 }
201 #endif  // defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_LINUX) ||
202         // defined(OS_ANDROID) || defined(OS_CHROMEOS))