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

Side by Side Diff: test/cctest/test-utils-arm64.cc

Issue 2622643005: ARM64: Add NEON support (Closed)
Patch Set: Fix Math.abs properly Created 3 years, 8 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 unified diff | Download patch
« no previous file with comments | « test/cctest/test-utils-arm64.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 52
53 bool Equal64(uint64_t expected, const RegisterDump*, uint64_t result) { 53 bool Equal64(uint64_t expected, const RegisterDump*, uint64_t result) {
54 if (result != expected) { 54 if (result != expected) {
55 printf("Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n", 55 printf("Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n",
56 expected, result); 56 expected, result);
57 } 57 }
58 58
59 return expected == result; 59 return expected == result;
60 } 60 }
61 61
62 bool Equal128(vec128_t expected, const RegisterDump*, vec128_t result) {
63 if ((result.h != expected.h) || (result.l != expected.l)) {
64 printf("Expected 0x%016" PRIx64 "%016" PRIx64
65 "\t "
66 "Found 0x%016" PRIx64 "%016" PRIx64 "\n",
67 expected.h, expected.l, result.h, result.l);
68 }
69
70 return ((expected.h == result.h) && (expected.l == result.l));
71 }
62 72
63 bool EqualFP32(float expected, const RegisterDump*, float result) { 73 bool EqualFP32(float expected, const RegisterDump*, float result) {
64 if (float_to_rawbits(expected) == float_to_rawbits(result)) { 74 if (bit_cast<uint32_t>(expected) == bit_cast<uint32_t>(result)) {
65 return true; 75 return true;
66 } else { 76 } else {
67 if (std::isnan(expected) || (expected == 0.0)) { 77 if (std::isnan(expected) || (expected == 0.0)) {
68 printf("Expected 0x%08" PRIx32 "\t Found 0x%08" PRIx32 "\n", 78 printf("Expected 0x%08" PRIx32 "\t Found 0x%08" PRIx32 "\n",
69 float_to_rawbits(expected), float_to_rawbits(result)); 79 bit_cast<uint32_t>(expected), bit_cast<uint32_t>(result));
70 } else { 80 } else {
71 printf("Expected %.9f (0x%08" PRIx32 ")\t " 81 printf("Expected %.9f (0x%08" PRIx32
82 ")\t "
72 "Found %.9f (0x%08" PRIx32 ")\n", 83 "Found %.9f (0x%08" PRIx32 ")\n",
73 expected, float_to_rawbits(expected), 84 expected, bit_cast<uint32_t>(expected), result,
74 result, float_to_rawbits(result)); 85 bit_cast<uint32_t>(result));
75 } 86 }
76 return false; 87 return false;
77 } 88 }
78 } 89 }
79 90
80 91
81 bool EqualFP64(double expected, const RegisterDump*, double result) { 92 bool EqualFP64(double expected, const RegisterDump*, double result) {
82 if (double_to_rawbits(expected) == double_to_rawbits(result)) { 93 if (bit_cast<uint64_t>(expected) == bit_cast<uint64_t>(result)) {
83 return true; 94 return true;
84 } 95 }
85 96
86 if (std::isnan(expected) || (expected == 0.0)) { 97 if (std::isnan(expected) || (expected == 0.0)) {
87 printf("Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n", 98 printf("Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n",
88 double_to_rawbits(expected), double_to_rawbits(result)); 99 bit_cast<uint64_t>(expected), bit_cast<uint64_t>(result));
89 } else { 100 } else {
90 printf("Expected %.17f (0x%016" PRIx64 ")\t " 101 printf("Expected %.17f (0x%016" PRIx64
102 ")\t "
91 "Found %.17f (0x%016" PRIx64 ")\n", 103 "Found %.17f (0x%016" PRIx64 ")\n",
92 expected, double_to_rawbits(expected), 104 expected, bit_cast<uint64_t>(expected), result,
93 result, double_to_rawbits(result)); 105 bit_cast<uint64_t>(result));
94 } 106 }
95 return false; 107 return false;
96 } 108 }
97 109
98 110
99 bool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg) { 111 bool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg) {
100 CHECK(reg.Is32Bits()); 112 CHECK(reg.Is32Bits());
101 // Retrieve the corresponding X register so we can check that the upper part 113 // Retrieve the corresponding X register so we can check that the upper part
102 // was properly cleared. 114 // was properly cleared.
103 int64_t result_x = core->xreg(reg.code()); 115 int64_t result_x = core->xreg(reg.code());
104 if ((result_x & 0xffffffff00000000L) != 0) { 116 if ((result_x & 0xffffffff00000000L) != 0) {
105 printf("Expected 0x%08" PRIx32 "\t Found 0x%016" PRIx64 "\n", 117 printf("Expected 0x%08" PRIx32 "\t Found 0x%016" PRIx64 "\n",
106 expected, result_x); 118 expected, result_x);
107 return false; 119 return false;
108 } 120 }
109 uint32_t result_w = core->wreg(reg.code()); 121 uint32_t result_w = core->wreg(reg.code());
110 return Equal32(expected, core, result_w); 122 return Equal32(expected, core, result_w);
111 } 123 }
112 124
113 125
114 bool Equal64(uint64_t expected, 126 bool Equal64(uint64_t expected,
115 const RegisterDump* core, 127 const RegisterDump* core,
116 const Register& reg) { 128 const Register& reg) {
117 CHECK(reg.Is64Bits()); 129 CHECK(reg.Is64Bits());
118 uint64_t result = core->xreg(reg.code()); 130 uint64_t result = core->xreg(reg.code());
119 return Equal64(expected, core, result); 131 return Equal64(expected, core, result);
120 } 132 }
121 133
134 bool Equal128(uint64_t expected_h, uint64_t expected_l,
135 const RegisterDump* core, const VRegister& vreg) {
136 CHECK(vreg.Is128Bits());
137 vec128_t expected = {expected_l, expected_h};
138 vec128_t result = core->qreg(vreg.code());
139 return Equal128(expected, core, result);
140 }
122 141
123 bool EqualFP32(float expected, 142 bool EqualFP32(float expected, const RegisterDump* core,
124 const RegisterDump* core, 143 const VRegister& fpreg) {
125 const FPRegister& fpreg) {
126 CHECK(fpreg.Is32Bits()); 144 CHECK(fpreg.Is32Bits());
127 // Retrieve the corresponding D register so we can check that the upper part 145 // Retrieve the corresponding D register so we can check that the upper part
128 // was properly cleared. 146 // was properly cleared.
129 uint64_t result_64 = core->dreg_bits(fpreg.code()); 147 uint64_t result_64 = core->dreg_bits(fpreg.code());
130 if ((result_64 & 0xffffffff00000000L) != 0) { 148 if ((result_64 & 0xffffffff00000000L) != 0) {
131 printf("Expected 0x%08" PRIx32 " (%f)\t Found 0x%016" PRIx64 "\n", 149 printf("Expected 0x%08" PRIx32 " (%f)\t Found 0x%016" PRIx64 "\n",
132 float_to_rawbits(expected), expected, result_64); 150 bit_cast<uint32_t>(expected), expected, result_64);
133 return false; 151 return false;
134 } 152 }
135 153
136 return EqualFP32(expected, core, core->sreg(fpreg.code())); 154 return EqualFP32(expected, core, core->sreg(fpreg.code()));
137 } 155 }
138 156
139 157 bool EqualFP64(double expected, const RegisterDump* core,
140 bool EqualFP64(double expected, 158 const VRegister& fpreg) {
141 const RegisterDump* core,
142 const FPRegister& fpreg) {
143 CHECK(fpreg.Is64Bits()); 159 CHECK(fpreg.Is64Bits());
144 return EqualFP64(expected, core, core->dreg(fpreg.code())); 160 return EqualFP64(expected, core, core->dreg(fpreg.code()));
145 } 161 }
146 162
147 163
148 bool Equal64(const Register& reg0, 164 bool Equal64(const Register& reg0,
149 const RegisterDump* core, 165 const RegisterDump* core,
150 const Register& reg1) { 166 const Register& reg1) {
151 CHECK(reg0.Is64Bits() && reg1.Is64Bits()); 167 CHECK(reg0.Is64Bits() && reg1.Is64Bits());
152 int64_t expected = core->xreg(reg0.code()); 168 int64_t expected = core->xreg(reg0.code());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 207
192 bool EqualRegisters(const RegisterDump* a, const RegisterDump* b) { 208 bool EqualRegisters(const RegisterDump* a, const RegisterDump* b) {
193 for (unsigned i = 0; i < kNumberOfRegisters; i++) { 209 for (unsigned i = 0; i < kNumberOfRegisters; i++) {
194 if (a->xreg(i) != b->xreg(i)) { 210 if (a->xreg(i) != b->xreg(i)) {
195 printf("x%d\t Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n", 211 printf("x%d\t Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n",
196 i, a->xreg(i), b->xreg(i)); 212 i, a->xreg(i), b->xreg(i));
197 return false; 213 return false;
198 } 214 }
199 } 215 }
200 216
201 for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { 217 for (unsigned i = 0; i < kNumberOfVRegisters; i++) {
202 uint64_t a_bits = a->dreg_bits(i); 218 uint64_t a_bits = a->dreg_bits(i);
203 uint64_t b_bits = b->dreg_bits(i); 219 uint64_t b_bits = b->dreg_bits(i);
204 if (a_bits != b_bits) { 220 if (a_bits != b_bits) {
205 printf("d%d\t Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n", 221 printf("d%d\t Expected 0x%016" PRIx64 "\t Found 0x%016" PRIx64 "\n",
206 i, a_bits, b_bits); 222 i, a_bits, b_bits);
207 return false; 223 return false;
208 } 224 }
209 } 225 }
210 226
211 return true; 227 return true;
(...skipping 19 matching lines...) Expand all
231 list |= (1UL << n); 247 list |= (1UL << n);
232 i++; 248 i++;
233 } 249 }
234 } 250 }
235 // Check that we got enough registers. 251 // Check that we got enough registers.
236 CHECK(CountSetBits(list, kNumberOfRegisters) == reg_count); 252 CHECK(CountSetBits(list, kNumberOfRegisters) == reg_count);
237 253
238 return list; 254 return list;
239 } 255 }
240 256
241 257 RegList PopulateVRegisterArray(VRegister* s, VRegister* d, VRegister* v,
242 RegList PopulateFPRegisterArray(FPRegister* s, FPRegister* d, FPRegister* v, 258 int reg_size, int reg_count, RegList allowed) {
243 int reg_size, int reg_count, RegList allowed) {
244 RegList list = 0; 259 RegList list = 0;
245 int i = 0; 260 int i = 0;
246 for (unsigned n = 0; (n < kNumberOfFPRegisters) && (i < reg_count); n++) { 261 for (unsigned n = 0; (n < kNumberOfVRegisters) && (i < reg_count); n++) {
247 if (((1UL << n) & allowed) != 0) { 262 if (((1UL << n) & allowed) != 0) {
248 // Only assigned allowed registers. 263 // Only assigned allowed registers.
249 if (v) { 264 if (v) {
250 v[i] = FPRegister::Create(n, reg_size); 265 v[i] = VRegister::Create(n, reg_size);
251 } 266 }
252 if (d) { 267 if (d) {
253 d[i] = FPRegister::Create(n, kDRegSizeInBits); 268 d[i] = VRegister::Create(n, kDRegSizeInBits);
254 } 269 }
255 if (s) { 270 if (s) {
256 s[i] = FPRegister::Create(n, kSRegSizeInBits); 271 s[i] = VRegister::Create(n, kSRegSizeInBits);
257 } 272 }
258 list |= (1UL << n); 273 list |= (1UL << n);
259 i++; 274 i++;
260 } 275 }
261 } 276 }
262 // Check that we got enough registers. 277 // Check that we got enough registers.
263 CHECK(CountSetBits(list, kNumberOfFPRegisters) == reg_count); 278 CHECK(CountSetBits(list, kNumberOfVRegisters) == reg_count);
264 279
265 return list; 280 return list;
266 } 281 }
267 282
268 283
269 void Clobber(MacroAssembler* masm, RegList reg_list, uint64_t const value) { 284 void Clobber(MacroAssembler* masm, RegList reg_list, uint64_t const value) {
270 Register first = NoReg; 285 Register first = NoReg;
271 for (unsigned i = 0; i < kNumberOfRegisters; i++) { 286 for (unsigned i = 0; i < kNumberOfRegisters; i++) {
272 if (reg_list & (1UL << i)) { 287 if (reg_list & (1UL << i)) {
273 Register xn = Register::Create(i, kXRegSizeInBits); 288 Register xn = Register::Create(i, kXRegSizeInBits);
274 // We should never write into csp here. 289 // We should never write into csp here.
275 CHECK(!xn.Is(csp)); 290 CHECK(!xn.Is(csp));
276 if (!xn.IsZero()) { 291 if (!xn.IsZero()) {
277 if (!first.IsValid()) { 292 if (!first.IsValid()) {
278 // This is the first register we've hit, so construct the literal. 293 // This is the first register we've hit, so construct the literal.
279 __ Mov(xn, value); 294 __ Mov(xn, value);
280 first = xn; 295 first = xn;
281 } else { 296 } else {
282 // We've already loaded the literal, so re-use the value already 297 // We've already loaded the literal, so re-use the value already
283 // loaded into the first register we hit. 298 // loaded into the first register we hit.
284 __ Mov(xn, first); 299 __ Mov(xn, first);
285 } 300 }
286 } 301 }
287 } 302 }
288 } 303 }
289 } 304 }
290 305
291 306
292 void ClobberFP(MacroAssembler* masm, RegList reg_list, double const value) { 307 void ClobberFP(MacroAssembler* masm, RegList reg_list, double const value) {
293 FPRegister first = NoFPReg; 308 VRegister first = NoVReg;
294 for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { 309 for (unsigned i = 0; i < kNumberOfVRegisters; i++) {
295 if (reg_list & (1UL << i)) { 310 if (reg_list & (1UL << i)) {
296 FPRegister dn = FPRegister::Create(i, kDRegSizeInBits); 311 VRegister dn = VRegister::Create(i, kDRegSizeInBits);
297 if (!first.IsValid()) { 312 if (!first.IsValid()) {
298 // This is the first register we've hit, so construct the literal. 313 // This is the first register we've hit, so construct the literal.
299 __ Fmov(dn, value); 314 __ Fmov(dn, value);
300 first = dn; 315 first = dn;
301 } else { 316 } else {
302 // We've already loaded the literal, so re-use the value already loaded 317 // We've already loaded the literal, so re-use the value already loaded
303 // into the first register we hit. 318 // into the first register we hit.
304 __ Fmov(dn, first); 319 __ Fmov(dn, first);
305 } 320 }
306 } 321 }
307 } 322 }
308 } 323 }
309 324
310 325
311 void Clobber(MacroAssembler* masm, CPURegList reg_list) { 326 void Clobber(MacroAssembler* masm, CPURegList reg_list) {
312 if (reg_list.type() == CPURegister::kRegister) { 327 if (reg_list.type() == CPURegister::kRegister) {
313 // This will always clobber X registers. 328 // This will always clobber X registers.
314 Clobber(masm, reg_list.list()); 329 Clobber(masm, reg_list.list());
315 } else if (reg_list.type() == CPURegister::kFPRegister) { 330 } else if (reg_list.type() == CPURegister::kVRegister) {
316 // This will always clobber D registers. 331 // This will always clobber D registers.
317 ClobberFP(masm, reg_list.list()); 332 ClobberFP(masm, reg_list.list());
318 } else { 333 } else {
319 UNREACHABLE(); 334 UNREACHABLE();
320 } 335 }
321 } 336 }
322 337
323 338
324 void RegisterDump::Dump(MacroAssembler* masm) { 339 void RegisterDump::Dump(MacroAssembler* masm) {
325 CHECK(__ StackPointer().Is(csp)); 340 CHECK(__ StackPointer().Is(csp));
(...skipping 10 matching lines...) Expand all
336 Register tmp = x2; 351 Register tmp = x2;
337 Register dump_base_w = dump_base.W(); 352 Register dump_base_w = dump_base.W();
338 Register dump_w = dump.W(); 353 Register dump_w = dump.W();
339 Register tmp_w = tmp.W(); 354 Register tmp_w = tmp.W();
340 355
341 // Offsets into the dump_ structure. 356 // Offsets into the dump_ structure.
342 const int x_offset = offsetof(dump_t, x_); 357 const int x_offset = offsetof(dump_t, x_);
343 const int w_offset = offsetof(dump_t, w_); 358 const int w_offset = offsetof(dump_t, w_);
344 const int d_offset = offsetof(dump_t, d_); 359 const int d_offset = offsetof(dump_t, d_);
345 const int s_offset = offsetof(dump_t, s_); 360 const int s_offset = offsetof(dump_t, s_);
361 const int q_offset = offsetof(dump_t, q_);
346 const int sp_offset = offsetof(dump_t, sp_); 362 const int sp_offset = offsetof(dump_t, sp_);
347 const int wsp_offset = offsetof(dump_t, wsp_); 363 const int wsp_offset = offsetof(dump_t, wsp_);
348 const int flags_offset = offsetof(dump_t, flags_); 364 const int flags_offset = offsetof(dump_t, flags_);
349 365
350 __ Push(xzr, dump_base, dump, tmp); 366 __ Push(xzr, dump_base, dump, tmp);
351 367
352 // Load the address where we will dump the state. 368 // Load the address where we will dump the state.
353 __ Mov(dump_base, reinterpret_cast<uint64_t>(&dump_)); 369 __ Mov(dump_base, reinterpret_cast<uint64_t>(&dump_));
354 370
355 // Dump the stack pointer (csp and wcsp). 371 // Dump the stack pointer (csp and wcsp).
(...skipping 14 matching lines...) Expand all
370 386
371 // Dump W registers. 387 // Dump W registers.
372 __ Add(dump, dump_base, w_offset); 388 __ Add(dump, dump_base, w_offset);
373 for (unsigned i = 0; i < kNumberOfRegisters; i += 2) { 389 for (unsigned i = 0; i < kNumberOfRegisters; i += 2) {
374 __ Stp(Register::WRegFromCode(i), Register::WRegFromCode(i + 1), 390 __ Stp(Register::WRegFromCode(i), Register::WRegFromCode(i + 1),
375 MemOperand(dump, i * kWRegSize)); 391 MemOperand(dump, i * kWRegSize));
376 } 392 }
377 393
378 // Dump D registers. 394 // Dump D registers.
379 __ Add(dump, dump_base, d_offset); 395 __ Add(dump, dump_base, d_offset);
380 for (unsigned i = 0; i < kNumberOfFPRegisters; i += 2) { 396 for (unsigned i = 0; i < kNumberOfVRegisters; i += 2) {
381 __ Stp(FPRegister::DRegFromCode(i), FPRegister::DRegFromCode(i + 1), 397 __ Stp(VRegister::DRegFromCode(i), VRegister::DRegFromCode(i + 1),
382 MemOperand(dump, i * kDRegSize)); 398 MemOperand(dump, i * kDRegSize));
383 } 399 }
384 400
385 // Dump S registers. 401 // Dump S registers.
386 __ Add(dump, dump_base, s_offset); 402 __ Add(dump, dump_base, s_offset);
387 for (unsigned i = 0; i < kNumberOfFPRegisters; i += 2) { 403 for (unsigned i = 0; i < kNumberOfVRegisters; i += 2) {
388 __ Stp(FPRegister::SRegFromCode(i), FPRegister::SRegFromCode(i + 1), 404 __ Stp(VRegister::SRegFromCode(i), VRegister::SRegFromCode(i + 1),
389 MemOperand(dump, i * kSRegSize)); 405 MemOperand(dump, i * kSRegSize));
390 } 406 }
391 407
408 // Dump Q registers.
409 __ Add(dump, dump_base, q_offset);
410 for (unsigned i = 0; i < kNumberOfVRegisters; i += 2) {
411 __ Stp(VRegister::QRegFromCode(i), VRegister::QRegFromCode(i + 1),
412 MemOperand(dump, i * kQRegSize));
413 }
414
392 // Dump the flags. 415 // Dump the flags.
393 __ Mrs(tmp, NZCV); 416 __ Mrs(tmp, NZCV);
394 __ Str(tmp, MemOperand(dump_base, flags_offset)); 417 __ Str(tmp, MemOperand(dump_base, flags_offset));
395 418
396 // To dump the values that were in tmp amd dump, we need a new scratch 419 // To dump the values that were in tmp amd dump, we need a new scratch
397 // register. We can use any of the already dumped registers since we can 420 // register. We can use any of the already dumped registers since we can
398 // easily restore them. 421 // easily restore them.
399 Register dump2_base = x10; 422 Register dump2_base = x10;
400 Register dump2 = x11; 423 Register dump2 = x11;
401 CHECK(!AreAliased(dump_base, dump, tmp, dump2_base, dump2)); 424 CHECK(!AreAliased(dump_base, dump, tmp, dump2_base, dump2));
(...skipping 19 matching lines...) Expand all
421 444
422 // Restore the MacroAssembler's scratch registers. 445 // Restore the MacroAssembler's scratch registers.
423 masm->TmpList()->set_list(old_tmp_list); 446 masm->TmpList()->set_list(old_tmp_list);
424 masm->FPTmpList()->set_list(old_fptmp_list); 447 masm->FPTmpList()->set_list(old_fptmp_list);
425 448
426 completed_ = true; 449 completed_ = true;
427 } 450 }
428 451
429 } // namespace internal 452 } // namespace internal
430 } // namespace v8 453 } // namespace v8
OLDNEW
« no previous file with comments | « test/cctest/test-utils-arm64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698