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

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

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

Powered by Google App Engine
This is Rietveld 408576698