OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 float x; | 237 float x; |
238 float y; | 238 float y; |
239 } T; | 239 } T; |
240 T t; | 240 T t; |
241 | 241 |
242 // Create a function that accepts &t, and loads, manipulates, and stores | 242 // Create a function that accepts &t, and loads, manipulates, and stores |
243 // the doubles and floats. | 243 // the doubles and floats. |
244 Assembler assm(isolate, NULL, 0); | 244 Assembler assm(isolate, NULL, 0); |
245 Label L, C; | 245 Label L, C; |
246 | 246 |
247 | 247 if (CpuFeatures::IsSupported(VFPv3)) { |
248 if (CpuFeatures::IsSupported(VFP3)) { | 248 CpuFeatureScope scope(&assm, VFPv3); |
249 CpuFeatureScope scope(&assm, VFP3); | |
250 | 249 |
251 __ mov(ip, Operand(sp)); | 250 __ mov(ip, Operand(sp)); |
252 __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); | 251 __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); |
253 __ sub(fp, ip, Operand(4)); | 252 __ sub(fp, ip, Operand(4)); |
254 | 253 |
255 __ mov(r4, Operand(r0)); | 254 __ mov(r4, Operand(r0)); |
256 __ vldr(d6, r4, offsetof(T, a)); | 255 __ vldr(d6, r4, offsetof(T, a)); |
257 __ vldr(d7, r4, offsetof(T, b)); | 256 __ vldr(d7, r4, offsetof(T, b)); |
258 __ vadd(d5, d6, d7); | 257 __ vadd(d5, d6, d7); |
259 __ vstr(d5, r4, offsetof(T, c)); | 258 __ vstr(d5, r4, offsetof(T, c)); |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 static void TestRoundingMode(VCVTTypes types, | 442 static void TestRoundingMode(VCVTTypes types, |
444 VFPRoundingMode mode, | 443 VFPRoundingMode mode, |
445 double value, | 444 double value, |
446 int expected, | 445 int expected, |
447 bool expected_exception = false) { | 446 bool expected_exception = false) { |
448 Isolate* isolate = CcTest::i_isolate(); | 447 Isolate* isolate = CcTest::i_isolate(); |
449 HandleScope scope(isolate); | 448 HandleScope scope(isolate); |
450 | 449 |
451 Assembler assm(isolate, NULL, 0); | 450 Assembler assm(isolate, NULL, 0); |
452 | 451 |
453 if (CpuFeatures::IsSupported(VFP3)) { | 452 Label wrong_exception; |
454 CpuFeatureScope scope(&assm, VFP3); | |
455 | 453 |
456 Label wrong_exception; | 454 __ vmrs(r1); |
| 455 // Set custom FPSCR. |
| 456 __ bic(r2, r1, Operand(kVFPRoundingModeMask | kVFPExceptionMask)); |
| 457 __ orr(r2, r2, Operand(mode)); |
| 458 __ vmsr(r2); |
457 | 459 |
458 __ vmrs(r1); | 460 // Load value, convert, and move back result to r0 if everything went well. |
459 // Set custom FPSCR. | 461 __ vmov(d1, value); |
460 __ bic(r2, r1, Operand(kVFPRoundingModeMask | kVFPExceptionMask)); | 462 switch (types) { |
461 __ orr(r2, r2, Operand(mode)); | 463 case s32_f64: |
462 __ vmsr(r2); | 464 __ vcvt_s32_f64(s0, d1, kFPSCRRounding); |
| 465 break; |
463 | 466 |
464 // Load value, convert, and move back result to r0 if everything went well. | 467 case u32_f64: |
465 __ vmov(d1, value); | 468 __ vcvt_u32_f64(s0, d1, kFPSCRRounding); |
466 switch (types) { | 469 break; |
467 case s32_f64: | |
468 __ vcvt_s32_f64(s0, d1, kFPSCRRounding); | |
469 break; | |
470 | 470 |
471 case u32_f64: | 471 default: |
472 __ vcvt_u32_f64(s0, d1, kFPSCRRounding); | 472 UNREACHABLE(); |
473 break; | 473 break; |
| 474 } |
| 475 // Check for vfp exceptions |
| 476 __ vmrs(r2); |
| 477 __ tst(r2, Operand(kVFPExceptionMask)); |
| 478 // Check that we behaved as expected. |
| 479 __ b(&wrong_exception, expected_exception ? eq : ne); |
| 480 // There was no exception. Retrieve the result and return. |
| 481 __ vmov(r0, s0); |
| 482 __ mov(pc, Operand(lr)); |
474 | 483 |
475 default: | 484 // The exception behaviour is not what we expected. |
476 UNREACHABLE(); | 485 // Load a special value and return. |
477 break; | 486 __ bind(&wrong_exception); |
478 } | 487 __ mov(r0, Operand(11223344)); |
479 // Check for vfp exceptions | 488 __ mov(pc, Operand(lr)); |
480 __ vmrs(r2); | |
481 __ tst(r2, Operand(kVFPExceptionMask)); | |
482 // Check that we behaved as expected. | |
483 __ b(&wrong_exception, | |
484 expected_exception ? eq : ne); | |
485 // There was no exception. Retrieve the result and return. | |
486 __ vmov(r0, s0); | |
487 __ mov(pc, Operand(lr)); | |
488 | 489 |
489 // The exception behaviour is not what we expected. | 490 CodeDesc desc; |
490 // Load a special value and return. | 491 assm.GetCode(&desc); |
491 __ bind(&wrong_exception); | 492 Handle<Code> code = isolate->factory()->NewCode( |
492 __ mov(r0, Operand(11223344)); | 493 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
493 __ mov(pc, Operand(lr)); | |
494 | |
495 CodeDesc desc; | |
496 assm.GetCode(&desc); | |
497 Handle<Code> code = isolate->factory()->NewCode( | |
498 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
499 #ifdef DEBUG | 494 #ifdef DEBUG |
500 OFStream os(stdout); | 495 OFStream os(stdout); |
501 code->Print(os); | 496 code->Print(os); |
502 #endif | 497 #endif |
503 F1 f = FUNCTION_CAST<F1>(code->entry()); | 498 F1 f = FUNCTION_CAST<F1>(code->entry()); |
504 int res = | 499 int res = |
505 reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); | 500 reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); |
506 ::printf("res = %d\n", res); | 501 ::printf("res = %d\n", res); |
507 CHECK_EQ(expected, res); | 502 CHECK_EQ(expected, res); |
508 } | |
509 } | 503 } |
510 | 504 |
511 | 505 |
512 TEST(7) { | 506 TEST(7) { |
513 CcTest::InitializeVM(); | 507 CcTest::InitializeVM(); |
514 // Test vfp rounding modes. | 508 // Test vfp rounding modes. |
515 | 509 |
516 // s32_f64 (double to integer). | 510 // s32_f64 (double to integer). |
517 | 511 |
518 TestRoundingMode(s32_f64, RN, 0, 0); | 512 TestRoundingMode(s32_f64, RN, 0, 0); |
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 uint32_t low; | 1038 uint32_t low; |
1045 uint32_t high; | 1039 uint32_t high; |
1046 } T; | 1040 } T; |
1047 T t; | 1041 T t; |
1048 | 1042 |
1049 // Create a function that accepts &t, and loads, manipulates, and stores | 1043 // Create a function that accepts &t, and loads, manipulates, and stores |
1050 // the doubles and floats. | 1044 // the doubles and floats. |
1051 Assembler assm(isolate, NULL, 0); | 1045 Assembler assm(isolate, NULL, 0); |
1052 Label L, C; | 1046 Label L, C; |
1053 | 1047 |
1054 | 1048 if (CpuFeatures::IsSupported(VFPv3)) { |
1055 if (CpuFeatures::IsSupported(VFP3)) { | 1049 CpuFeatureScope scope(&assm, VFPv3); |
1056 CpuFeatureScope scope(&assm, VFP3); | |
1057 | 1050 |
1058 __ stm(db_w, sp, r4.bit() | lr.bit()); | 1051 __ stm(db_w, sp, r4.bit() | lr.bit()); |
1059 | 1052 |
1060 // Load a, b, c into d16, d17, d18. | 1053 // Load a, b, c into d16, d17, d18. |
1061 __ mov(r4, Operand(r0)); | 1054 __ mov(r4, Operand(r0)); |
1062 __ vldr(d16, r4, offsetof(T, a)); | 1055 __ vldr(d16, r4, offsetof(T, a)); |
1063 __ vldr(d17, r4, offsetof(T, b)); | 1056 __ vldr(d17, r4, offsetof(T, b)); |
1064 __ vldr(d18, r4, offsetof(T, c)); | 1057 __ vldr(d18, r4, offsetof(T, c)); |
1065 | 1058 |
1066 __ vneg(d25, d16); | 1059 __ vneg(d25, d16); |
(...skipping 1922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2989 HandleScope scope(isolate); | 2982 HandleScope scope(isolate); |
2990 | 2983 |
2991 Assembler assm(isolate, NULL, 0); | 2984 Assembler assm(isolate, NULL, 0); |
2992 __ mov(r0, Operand(isolate->factory()->infinity_value())); | 2985 __ mov(r0, Operand(isolate->factory()->infinity_value())); |
2993 __ BlockConstPoolFor(1019); | 2986 __ BlockConstPoolFor(1019); |
2994 for (int i = 0; i < 1019; ++i) __ nop(); | 2987 for (int i = 0; i < 1019; ++i) __ nop(); |
2995 __ vldr(d0, MemOperand(r0, 0)); | 2988 __ vldr(d0, MemOperand(r0, 0)); |
2996 } | 2989 } |
2997 | 2990 |
2998 #undef __ | 2991 #undef __ |
OLD | NEW |