Changeset 194062 in webkit
- Timestamp:
- Dec 14, 2015 2:44:22 PM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r194057 r194062 1 2015-12-14 Benjamin Poulain <bpoulain@apple.com> 2 3 [JSC] Add ceil() support for x86 and expose it to B3 4 https://bugs.webkit.org/show_bug.cgi?id=152231 5 6 Reviewed by Geoffrey Garen. 7 8 Most x86 CPUs we care about support ceil() natively 9 with the round instruction. 10 11 This patch expose that behind a runtime flag, use it 12 in the Math.ceil() thunk and expose it to B3. 13 14 * assembler/MacroAssemblerARM64.h: 15 (JSC::MacroAssemblerARM64::supportsFloatingPointCeil): 16 * assembler/MacroAssemblerARMv7.h: 17 (JSC::MacroAssemblerARMv7::supportsFloatingPointCeil): 18 * assembler/MacroAssemblerMIPS.h: 19 (JSC::MacroAssemblerMIPS::supportsFloatingPointCeil): 20 * assembler/MacroAssemblerSH4.h: 21 (JSC::MacroAssemblerSH4::supportsFloatingPointCeil): 22 * assembler/MacroAssemblerX86Common.cpp: 23 * assembler/MacroAssemblerX86Common.h: 24 (JSC::MacroAssemblerX86Common::ceilDouble): 25 (JSC::MacroAssemblerX86Common::ceilFloat): 26 (JSC::MacroAssemblerX86Common::supportsFloatingPointCeil): 27 (JSC::MacroAssemblerX86Common::supportsLZCNT): 28 * assembler/X86Assembler.h: 29 (JSC::X86Assembler::roundss_rr): 30 (JSC::X86Assembler::roundss_mr): 31 (JSC::X86Assembler::roundsd_rr): 32 (JSC::X86Assembler::roundsd_mr): 33 (JSC::X86Assembler::mfence): 34 (JSC::X86Assembler::X86InstructionFormatter::threeByteOp): 35 * b3/B3ConstDoubleValue.cpp: 36 (JSC::B3::ConstDoubleValue::ceilConstant): 37 * b3/B3ConstDoubleValue.h: 38 * b3/B3ConstFloatValue.cpp: 39 (JSC::B3::ConstFloatValue::ceilConstant): 40 * b3/B3ConstFloatValue.h: 41 * b3/B3LowerMacrosAfterOptimizations.cpp: 42 * b3/B3LowerToAir.cpp: 43 (JSC::B3::Air::LowerToAir::lower): 44 * b3/B3Opcode.cpp: 45 (WTF::printInternal): 46 * b3/B3Opcode.h: 47 * b3/B3ReduceDoubleToFloat.cpp: 48 * b3/B3ReduceStrength.cpp: 49 * b3/B3Validate.cpp: 50 * b3/B3Value.cpp: 51 (JSC::B3::Value::ceilConstant): 52 (JSC::B3::Value::effects): 53 (JSC::B3::Value::key): 54 (JSC::B3::Value::typeFor): 55 * b3/B3Value.h: 56 * b3/air/AirOpcode.opcodes: 57 * b3/testb3.cpp: 58 (JSC::B3::testCeilArg): 59 (JSC::B3::testCeilImm): 60 (JSC::B3::testCeilMem): 61 (JSC::B3::testCeilCeilArg): 62 (JSC::B3::testCeilIToD64): 63 (JSC::B3::testCeilIToD32): 64 (JSC::B3::testCeilArgWithUselessDoubleConversion): 65 (JSC::B3::testCeilArgWithEffectfulDoubleConversion): 66 (JSC::B3::populateWithInterestingValues): 67 (JSC::B3::run): 68 * ftl/FTLB3Output.h: 69 (JSC::FTL::Output::ceil64): 70 * jit/ThunkGenerators.cpp: 71 (JSC::ceilThunkGenerator): 72 1 73 2015-12-14 Andreas Kling <akling@apple.com> 2 74 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h
r192535 r194062 1200 1200 static bool supportsFloatingPointSqrt() { return true; } 1201 1201 static bool supportsFloatingPointAbs() { return true; } 1202 static bool supportsFloatingPointCeil() { return true; } 1202 1203 1203 1204 enum BranchTruncateType { BranchIfTruncateFailed, BranchIfTruncateSuccessful }; -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
r192535 r194062 857 857 static bool supportsFloatingPointSqrt() { return true; } 858 858 static bool supportsFloatingPointAbs() { return true; } 859 static bool supportsFloatingPointCeil() { return false; } 859 860 860 861 void loadDouble(ImplicitAddress address, FPRegisterID dest) … … 1045 1046 { 1046 1047 m_assembler.vneg(dest, src); 1048 } 1049 1050 NO_RETURN_DUE_TO_CRASH void ceilDouble(FPRegisterID, FPRegisterID) 1051 { 1052 ASSERT(!supportsFloatingPointCeil()); 1053 CRASH(); 1047 1054 } 1048 1055 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
r192535 r194062 626 626 } 627 627 628 NO_RETURN_DUE_TO_CRASH void ceilDouble(FPRegisterID, FPRegisterID) 629 { 630 ASSERT(!supportsFloatingPointCeil()); 631 CRASH(); 632 } 633 628 634 ConvertibleLoadLabel convertibleLoadPtr(Address address, RegisterID dest) 629 635 { … … 1210 1216 } 1211 1217 static bool supportsFloatingPointAbs() { return false; } 1218 static bool supportsFloatingPointCeil() { return false; } 1212 1219 1213 1220 // Stack manipulation operations: -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
r192535 r194062 1092 1092 static bool supportsFloatingPointSqrt() { return true; } 1093 1093 static bool supportsFloatingPointAbs() { return true; } 1094 static bool supportsFloatingPointCeil() { return false; } 1094 1095 1095 1096 void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2) … … 1573 1574 moveDouble(src, dest); 1574 1575 m_assembler.dabs(dest); 1576 } 1577 1578 NO_RETURN_DUE_TO_CRASH void ceilDouble(FPRegisterID, FPRegisterID) 1579 { 1580 ASSERT(!supportsFloatingPointCeil()); 1581 CRASH(); 1575 1582 } 1576 1583 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.cpp
r193125 r194062 553 553 #endif 554 554 555 MacroAssemblerX86Common::LZCNTCheckState MacroAssemblerX86Common::s_lzcntCheckState = LZCNTCheckState::NotChecked; 555 MacroAssemblerX86Common::CPUIDCheckState MacroAssemblerX86Common::s_sse4_1CheckState = CPUIDCheckState::NotChecked; 556 MacroAssemblerX86Common::CPUIDCheckState MacroAssemblerX86Common::s_lzcntCheckState = CPUIDCheckState::NotChecked; 556 557 557 558 } // namespace JSC -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
r194039 r194062 571 571 } 572 572 573 void ceilDouble(FPRegisterID src, FPRegisterID dst) 574 { 575 m_assembler.roundsd_rr(src, dst, X86Assembler::RoundingType::TowardInfiniti); 576 } 577 578 void ceilDouble(Address src, FPRegisterID dst) 579 { 580 m_assembler.roundsd_mr(src.offset, src.base, dst, X86Assembler::RoundingType::TowardInfiniti); 581 } 582 583 void ceilFloat(FPRegisterID src, FPRegisterID dst) 584 { 585 m_assembler.roundss_rr(src, dst, X86Assembler::RoundingType::TowardInfiniti); 586 } 587 588 void ceilFloat(Address src, FPRegisterID dst) 589 { 590 m_assembler.roundss_mr(src.offset, src.base, dst, X86Assembler::RoundingType::TowardInfiniti); 591 } 573 592 574 593 // Memory access operations: … … 1798 1817 } 1799 1818 1819 static bool supportsFloatingPointCeil() 1820 { 1821 if (s_sse4_1CheckState == CPUIDCheckState::NotChecked) { 1822 int flags = 0; 1823 #if COMPILER(MSVC) 1824 int cpuInfo[4]; 1825 __cpuid(cpuInfo, 0x1); 1826 flags = cpuInfo[2]; 1827 #elif COMPILER(GCC_OR_CLANG) 1828 #if CPU(X86_64) 1829 asm ( 1830 "movl $0x1, %%eax;" 1831 "cpuid;" 1832 "movl %%ecx, %0;" 1833 : "=g" (flags) 1834 : 1835 : "%eax", "%ebx", "%ecx", "%edx" 1836 ); 1837 #else 1838 asm ( 1839 "movl $0x1, %%eax;" 1840 "pushl %%ebx;" 1841 "cpuid;" 1842 "popl %%ebx;" 1843 "movl %%ecx, %0;" 1844 : "=g" (flags) 1845 : 1846 : "%eax", "%ecx", "%edx" 1847 ); 1848 #endif 1849 #endif // COMPILER(GCC_OR_CLANG) 1850 s_sse4_1CheckState = (flags & (1 << 19)) ? CPUIDCheckState::Set : CPUIDCheckState::Clear; 1851 } 1852 return s_sse4_1CheckState == CPUIDCheckState::Set; 1853 } 1854 1800 1855 #if ENABLE(MASM_PROBE) 1801 1856 void probe(ProbeFunction, void* arg1, void* arg2); … … 1838 1893 #endif 1839 1894 } 1840 1895 1841 1896 static bool supportsLZCNT() 1842 1897 { 1843 if (s_lzcntCheckState == LZCNTCheckState::NotChecked) {1898 if (s_lzcntCheckState == CPUIDCheckState::NotChecked) { 1844 1899 int flags = 0; 1845 1900 #if COMPILER(MSVC) … … 1870 1925 #endif 1871 1926 #endif // COMPILER(GCC_OR_CLANG) 1872 s_lzcntCheckState = (flags & 0x20) ? LZCNTCheckState::Set : LZCNTCheckState::Clear;1873 } 1874 return s_lzcntCheckState == LZCNTCheckState::Set;1927 s_lzcntCheckState = (flags & 0x20) ? CPUIDCheckState::Set : CPUIDCheckState::Clear; 1928 } 1929 return s_lzcntCheckState == CPUIDCheckState::Set; 1875 1930 } 1876 1931 … … 2042 2097 #endif 2043 2098 2044 enum class LZCNTCheckState {2099 enum class CPUIDCheckState { 2045 2100 NotChecked, 2046 2101 Clear, 2047 2102 Set 2048 2103 }; 2049 static LZCNTCheckState s_lzcntCheckState; 2104 static CPUIDCheckState s_sse4_1CheckState; 2105 static CPUIDCheckState s_lzcntCheckState; 2050 2106 }; 2051 2107 -
trunk/Source/JavaScriptCore/assembler/X86Assembler.h
r194039 r194062 265 265 OP2_CVTTSD2SI_GdWsd = 0x2C, 266 266 OP2_UCOMISD_VsdWsd = 0x2E, 267 OP2_3BYTE_ESCAPE_3A = 0x3A, 267 268 OP2_CMOVCC = 0x40, 268 269 OP2_ADDSD_VsdWsd = 0x58, … … 281 282 OP2_JCC_rel32 = 0x80, 282 283 OP_SETCC = 0x90, 283 OP2_3BYTE_ESCAPE 284 OP2_3BYTE_ESCAPE_AE = 0xAE, 284 285 OP2_IMUL_GvEv = 0xAF, 285 286 OP2_MOVZX_GvEb = 0xB6, … … 296 297 297 298 typedef enum { 298 OP3_MFENCE = 0xF0, 299 OP3_ROUNDSS_VssWssIb = 0x0A, 300 OP3_ROUNDSD_VsdWsdIb = 0x0B, 301 OP3_MFENCE = 0xF0, 299 302 } ThreeByteOpcodeID; 300 303 … … 2350 2353 } 2351 2354 2355 enum class RoundingType : uint8_t { 2356 ToNearestWithTiesToEven = 0, 2357 TowardNegativeInfiniti = 1, 2358 TowardInfiniti = 2, 2359 TowardZero = 3 2360 }; 2361 2362 void roundss_rr(XMMRegisterID src, XMMRegisterID dst, RoundingType rounding) 2363 { 2364 m_formatter.prefix(PRE_SSE_66); 2365 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_3A, OP3_ROUNDSS_VssWssIb, (RegisterID)dst, (RegisterID)src); 2366 m_formatter.immediate8(static_cast<uint8_t>(rounding)); 2367 } 2368 2369 void roundss_mr(int offset, RegisterID base, XMMRegisterID dst, RoundingType rounding) 2370 { 2371 m_formatter.prefix(PRE_SSE_66); 2372 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_3A, OP3_ROUNDSS_VssWssIb, (RegisterID)dst, base, offset); 2373 m_formatter.immediate8(static_cast<uint8_t>(rounding)); 2374 } 2375 2376 void roundsd_rr(XMMRegisterID src, XMMRegisterID dst, RoundingType rounding) 2377 { 2378 m_formatter.prefix(PRE_SSE_66); 2379 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_3A, OP3_ROUNDSD_VsdWsdIb, (RegisterID)dst, (RegisterID)src); 2380 m_formatter.immediate8(static_cast<uint8_t>(rounding)); 2381 } 2382 2383 void roundsd_mr(int offset, RegisterID base, XMMRegisterID dst, RoundingType rounding) 2384 { 2385 m_formatter.prefix(PRE_SSE_66); 2386 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_3A, OP3_ROUNDSD_VsdWsdIb, (RegisterID)dst, base, offset); 2387 m_formatter.immediate8(static_cast<uint8_t>(rounding)); 2388 } 2389 2352 2390 // Misc instructions: 2353 2391 … … 2369 2407 void mfence() 2370 2408 { 2371 m_formatter.threeByteOp(OP 3_MFENCE);2409 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_AE, OP3_MFENCE); 2372 2410 } 2373 2411 … … 2848 2886 #endif 2849 2887 2850 void threeByteOp(T hreeByteOpcodeID opcode)2888 void threeByteOp(TwoByteOpcodeID twoBytePrefix, ThreeByteOpcodeID opcode) 2851 2889 { 2852 2890 m_buffer.ensureSpace(maxInstructionSize); 2853 2891 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE); 2854 m_buffer.putByteUnchecked( OP2_3BYTE_ESCAPE);2892 m_buffer.putByteUnchecked(twoBytePrefix); 2855 2893 m_buffer.putByteUnchecked(opcode); 2894 } 2895 2896 void threeByteOp(TwoByteOpcodeID twoBytePrefix, ThreeByteOpcodeID opcode, int reg, RegisterID rm) 2897 { 2898 m_buffer.ensureSpace(maxInstructionSize); 2899 emitRexIfNeeded(reg, 0, rm); 2900 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE); 2901 m_buffer.putByteUnchecked(twoBytePrefix); 2902 m_buffer.putByteUnchecked(opcode); 2903 registerModRM(reg, rm); 2904 } 2905 2906 void threeByteOp(TwoByteOpcodeID twoBytePrefix, ThreeByteOpcodeID opcode, int reg, RegisterID base, int displacement) 2907 { 2908 m_buffer.ensureSpace(maxInstructionSize); 2909 emitRexIfNeeded(reg, 0, base); 2910 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE); 2911 m_buffer.putByteUnchecked(twoBytePrefix); 2912 m_buffer.putByteUnchecked(opcode); 2913 memoryModRM(reg, base, displacement); 2856 2914 } 2857 2915 -
trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp
r194003 r194062 93 93 } 94 94 95 Value* ConstDoubleValue::ceilConstant(Procedure& proc) const 96 { 97 return proc.add<ConstDoubleValue>(origin(), ceil(m_value)); 98 } 99 95 100 Value* ConstDoubleValue::sqrtConstant(Procedure& proc) const 96 101 { -
trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h
r194003 r194062 52 52 Value* doubleToFloatConstant(Procedure&) const override; 53 53 Value* absConstant(Procedure&) const override; 54 Value* ceilConstant(Procedure&) const override; 54 55 Value* sqrtConstant(Procedure&) const override; 55 56 -
trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.cpp
r194003 r194062 93 93 } 94 94 95 Value* ConstFloatValue::ceilConstant(Procedure& proc) const 96 { 97 return proc.add<ConstFloatValue>(origin(), ceilf(m_value)); 98 } 99 95 100 Value* ConstFloatValue::sqrtConstant(Procedure& proc) const 96 101 { -
trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.h
r194003 r194062 51 51 Value* floatToDoubleConstant(Procedure&) const override; 52 52 Value* absConstant(Procedure&) const override; 53 Value* ceilConstant(Procedure&) const override; 53 54 Value* sqrtConstant(Procedure&) const override; 54 55 -
trunk/Source/JavaScriptCore/b3/B3LowerMacrosAfterOptimizations.cpp
r194003 r194062 31 31 #include "B3BasicBlockInlines.h" 32 32 #include "B3BlockInsertionSet.h" 33 #include "B3CCallValue.h" 33 34 #include "B3ConstDoubleValue.h" 34 35 #include "B3ConstFloatValue.h" 36 #include "B3ConstPtrValue.h" 35 37 #include "B3InsertionSetInlines.h" 36 38 #include "B3PhaseScope.h" … … 86 88 break; 87 89 } 90 case Ceil: { 91 if (MacroAssembler::supportsFloatingPointCeil()) 92 break; 93 94 Value* functionAddress = nullptr; 95 if (m_value->type() == Double) 96 functionAddress = m_insertionSet.insert<ConstPtrValue>(m_index, m_origin, ceil); 97 else if (m_value->type() == Float) 98 functionAddress = m_insertionSet.insert<ConstPtrValue>(m_index, m_origin, ceilf); 99 else 100 RELEASE_ASSERT_NOT_REACHED(); 101 102 Value* result = m_insertionSet.insert<CCallValue>(m_index, 103 m_value->type(), 104 m_origin, 105 Effects::none(), 106 functionAddress, 107 m_value->child(0)); 108 m_value->replaceWithIdentity(result); 109 break; 110 } 88 111 default: 89 112 break; -
trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp
r194039 r194062 1655 1655 } 1656 1656 1657 case Ceil: { 1658 appendUnOp<Air::Oops, Air::Oops, CeilDouble, CeilFloat>(m_value->child(0)); 1659 return; 1660 } 1661 1657 1662 case Sqrt: { 1658 1663 appendUnOp<Air::Oops, Air::Oops, SqrtDouble, SqrtFloat>(m_value->child(0)); -
trunk/Source/JavaScriptCore/b3/B3Opcode.cpp
r194003 r194062 150 150 out.print("Abs"); 151 151 return; 152 case Ceil: 153 out.print("Ceil"); 154 return; 152 155 case Sqrt: 153 156 out.print("Sqrt"); -
trunk/Source/JavaScriptCore/b3/B3Opcode.h
r194048 r194062 87 87 // Floating point math. 88 88 Abs, 89 Ceil, 89 90 Sqrt, 90 91 -
trunk/Source/JavaScriptCore/b3/B3ReduceDoubleToFloat.cpp
r194003 r194062 50 50 break; 51 51 case Abs: 52 case Ceil: 52 53 case Sqrt: 53 54 if (candidate->child(0)->opcode() == FloatToDouble) { -
trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp
r194039 r194062 565 565 break; 566 566 567 case Ceil: 568 // Turn this: Ceil(constant) 569 // Into this: ceil<value->type()>(constant) 570 if (Value* constant = m_value->child(0)->ceilConstant(m_proc)) { 571 replaceWithNewValue(constant); 572 break; 573 } 574 575 // Turn this: Ceil(Ceil(value)) 576 // Into this: Ceil(value) 577 if (m_value->child(0)->opcode() == Ceil) { 578 m_value->replaceWithIdentity(m_value->child(0)); 579 break; 580 } 581 582 // Turn this: Ceil(IToD(value)) 583 // Into this: IToD(value) 584 // 585 // That works for Int64 because both ARM64 and x86_64 586 // perform rounding when converting a 64bit integer to double. 587 if (m_value->child(0)->opcode() == IToD) { 588 m_value->replaceWithIdentity(m_value->child(0)); 589 break; 590 } 591 break; 592 567 593 case Sqrt: 568 594 // Turn this: Sqrt(constant) -
trunk/Source/JavaScriptCore/b3/B3Validate.cpp
r194003 r194062 211 211 break; 212 212 case Abs: 213 case Ceil: 213 214 case Sqrt: 214 215 VALIDATE(value->numChildren() == 1, ("At ", *value)); -
trunk/Source/JavaScriptCore/b3/B3Value.cpp
r194048 r194062 223 223 224 224 Value* Value::absConstant(Procedure&) const 225 { 226 return nullptr; 227 } 228 229 Value* Value::ceilConstant(Procedure&) const 225 230 { 226 231 return nullptr; … … 364 369 case Clz: 365 370 case Abs: 371 case Ceil: 366 372 case Sqrt: 367 373 case BitwiseCast: … … 443 449 case Identity: 444 450 case Abs: 451 case Ceil: 445 452 case Sqrt: 446 453 case SExt8: … … 550 557 case Clz: 551 558 case Abs: 559 case Ceil: 552 560 case Sqrt: 553 561 case CheckAdd: -
trunk/Source/JavaScriptCore/b3/B3Value.h
r194003 r194062 133 133 virtual Value* floatToDoubleConstant(Procedure&) const; 134 134 virtual Value* absConstant(Procedure&) const; 135 virtual Value* ceilConstant(Procedure&) const; 135 136 virtual Value* sqrtConstant(Procedure&) const; 136 137 -
trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes
r194045 r194062 276 276 x86: Addr 277 277 278 CeilDouble U:F, UD:F 279 Tmp, Tmp 280 Addr, Tmp 281 282 CeilFloat U:F, UD:F 283 Tmp, Tmp 284 Addr, Tmp 285 278 286 SqrtDouble U:F, UD:F 279 287 Tmp, Tmp -
trunk/Source/JavaScriptCore/b3/testb3.cpp
r194050 r194062 3236 3236 } 3237 3237 3238 void testCeilArg(double a) 3239 { 3240 Procedure proc; 3241 BasicBlock* root = proc.addBlock(); 3242 root->appendNew<ControlValue>( 3243 proc, Return, Origin(), 3244 root->appendNew<Value>( 3245 proc, Ceil, Origin(), 3246 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0))); 3247 3248 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a))); 3249 } 3250 3251 void testCeilImm(double a) 3252 { 3253 Procedure proc; 3254 BasicBlock* root = proc.addBlock(); 3255 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a); 3256 root->appendNew<ControlValue>( 3257 proc, Return, Origin(), 3258 root->appendNew<Value>(proc, Ceil, Origin(), argument)); 3259 3260 CHECK(isIdentical(compileAndRun<double>(proc), ceil(a))); 3261 } 3262 3263 void testCeilMem(double a) 3264 { 3265 Procedure proc; 3266 BasicBlock* root = proc.addBlock(); 3267 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0); 3268 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address); 3269 root->appendNew<ControlValue>( 3270 proc, Return, Origin(), 3271 root->appendNew<Value>(proc, Ceil, Origin(), loadDouble)); 3272 3273 CHECK(isIdentical(compileAndRun<double>(proc, &a), ceil(a))); 3274 } 3275 3276 void testCeilCeilArg(double a) 3277 { 3278 Procedure proc; 3279 BasicBlock* root = proc.addBlock(); 3280 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(), 3281 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)); 3282 Value* secondCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstCeil); 3283 root->appendNew<ControlValue>(proc, Return, Origin(), secondCeil); 3284 3285 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a))); 3286 } 3287 3288 void testCeilIToD64(int64_t a) 3289 { 3290 Procedure proc; 3291 BasicBlock* root = proc.addBlock(); 3292 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0); 3293 Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument); 3294 3295 root->appendNew<ControlValue>( 3296 proc, Return, Origin(), 3297 root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble)); 3298 3299 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a)))); 3300 } 3301 3302 void testCeilIToD32(int64_t a) 3303 { 3304 Procedure proc; 3305 BasicBlock* root = proc.addBlock(); 3306 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(), 3307 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)); 3308 Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument); 3309 3310 root->appendNew<ControlValue>( 3311 proc, Return, Origin(), 3312 root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble)); 3313 3314 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a)))); 3315 } 3316 3317 void testCeilArg(float a) 3318 { 3319 Procedure proc; 3320 BasicBlock* root = proc.addBlock(); 3321 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(), 3322 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)); 3323 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32); 3324 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), argument); 3325 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result); 3326 root->appendNew<ControlValue>(proc, Return, Origin(), result32); 3327 3328 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a)))); 3329 } 3330 3331 void testCeilImm(float a) 3332 { 3333 Procedure proc; 3334 BasicBlock* root = proc.addBlock(); 3335 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a); 3336 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), argument); 3337 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result); 3338 root->appendNew<ControlValue>(proc, Return, Origin(), result32); 3339 3340 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a)))); 3341 } 3342 3343 void testCeilMem(float a) 3344 { 3345 Procedure proc; 3346 BasicBlock* root = proc.addBlock(); 3347 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0); 3348 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address); 3349 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), loadFloat); 3350 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result); 3351 root->appendNew<ControlValue>(proc, Return, Origin(), result32); 3352 3353 CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(ceilf(a)))); 3354 } 3355 3356 void testCeilCeilArg(float a) 3357 { 3358 Procedure proc; 3359 BasicBlock* root = proc.addBlock(); 3360 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(), 3361 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)); 3362 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32); 3363 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(), argument); 3364 Value* secondCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstCeil); 3365 root->appendNew<ControlValue>(proc, Return, Origin(), secondCeil); 3366 3367 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), ceilf(a))); 3368 } 3369 3370 void testCeilArgWithUselessDoubleConversion(float a) 3371 { 3372 Procedure proc; 3373 BasicBlock* root = proc.addBlock(); 3374 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(), 3375 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)); 3376 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32); 3377 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue); 3378 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), asDouble); 3379 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result); 3380 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult); 3381 root->appendNew<ControlValue>(proc, Return, Origin(), result32); 3382 3383 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a)))); 3384 } 3385 3386 void testCeilArgWithEffectfulDoubleConversion(float a) 3387 { 3388 Procedure proc; 3389 BasicBlock* root = proc.addBlock(); 3390 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(), 3391 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)); 3392 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32); 3393 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue); 3394 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), asDouble); 3395 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result); 3396 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult); 3397 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1); 3398 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress); 3399 root->appendNew<ControlValue>(proc, Return, Origin(), result32); 3400 3401 double effect = 0; 3402 int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect); 3403 CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(ceilf(a)))); 3404 CHECK(isIdentical(effect, ceilf(a))); 3405 } 3406 3238 3407 void testSqrtArg(double a) 3239 3408 { … … 8009 8178 operands.append({ "0.", static_cast<FloatType>(0.) }); 8010 8179 operands.append({ "-0.", static_cast<FloatType>(-0.) }); 8180 operands.append({ "0.4", static_cast<FloatType>(0.5) }); 8181 operands.append({ "-0.4", static_cast<FloatType>(-0.5) }); 8182 operands.append({ "0.5", static_cast<FloatType>(0.5) }); 8183 operands.append({ "-0.5", static_cast<FloatType>(-0.5) }); 8184 operands.append({ "0.6", static_cast<FloatType>(0.5) }); 8185 operands.append({ "-0.6", static_cast<FloatType>(-0.5) }); 8011 8186 operands.append({ "1.", static_cast<FloatType>(1.) }); 8012 8187 operands.append({ "-1.", static_cast<FloatType>(-1.) }); … … 8638 8813 RUN_UNARY(testAbsArgWithUselessDoubleConversion, floatingPointOperands<float>()); 8639 8814 RUN_UNARY(testAbsArgWithEffectfulDoubleConversion, floatingPointOperands<float>()); 8815 8816 RUN_UNARY(testCeilArg, floatingPointOperands<double>()); 8817 RUN_UNARY(testCeilImm, floatingPointOperands<double>()); 8818 RUN_UNARY(testCeilMem, floatingPointOperands<double>()); 8819 RUN_UNARY(testCeilCeilArg, floatingPointOperands<double>()); 8820 RUN_UNARY(testCeilIToD64, int64Operands()); 8821 RUN_UNARY(testCeilIToD32, int32Operands()); 8822 RUN_UNARY(testCeilArg, floatingPointOperands<float>()); 8823 RUN_UNARY(testCeilImm, floatingPointOperands<float>()); 8824 RUN_UNARY(testCeilMem, floatingPointOperands<float>()); 8825 RUN_UNARY(testCeilCeilArg, floatingPointOperands<float>()); 8826 RUN_UNARY(testCeilArgWithUselessDoubleConversion, floatingPointOperands<float>()); 8827 RUN_UNARY(testCeilArgWithEffectfulDoubleConversion, floatingPointOperands<float>()); 8640 8828 8641 8829 RUN_UNARY(testSqrtArg, floatingPointOperands<double>()); -
trunk/Source/JavaScriptCore/ftl/FTLB3Output.h
r194024 r194062 155 155 LValue bitNot(LValue); 156 156 157 LValue ceil64(LValue operand) { CRASH(); }157 LValue ceil64(LValue operand) { return m_block->appendNew<B3::Value>(m_proc, B3::Ceil, origin(), value); } 158 158 LValue ctlz32(LValue operand) { return m_block->appendNew<B3::Value>(m_proc, B3::Clz, origin(), operand); } 159 159 LValue addWithOverflow32(LValue left, LValue right) { CRASH(); } -
trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp
r191937 r194062 829 829 nonIntJump.link(&jit); 830 830 jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0); 831 #if CPU(ARM64)832 jit.ceilDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT0);833 #else834 jit.callDoubleToDoublePreservingReturn(UnaryDoubleOpWrapper(ceil));835 #endif // CPU(ARM64) 831 if (jit.supportsFloatingPointCeil()) 832 jit.ceilDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT0); 833 else 834 jit.callDoubleToDoublePreservingReturn(UnaryDoubleOpWrapper(ceil)); 835 836 836 SpecializedThunkJIT::JumpList doubleResult; 837 837 jit.branchConvertDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0, doubleResult, SpecializedThunkJIT::fpRegT1);
Note: See TracChangeset
for help on using the changeset viewer.