| 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 |