Changeset 194003 in webkit
- Timestamp:
- Dec 11, 2015 10:10:07 PM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 added
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/CMakeLists.txt
r193989 r194003 115 115 b3/B3InsertionSet.cpp 116 116 b3/B3LowerMacros.cpp 117 b3/B3LowerMacrosAfterOptimizations.cpp 117 118 b3/B3LowerToAir.cpp 118 119 b3/B3MathExtras.cpp -
trunk/Source/JavaScriptCore/ChangeLog
r193998 r194003 1 2015-12-11 Benjamin Poulain <bpoulain@apple.com> 2 3 [JSC] Add Floating Point Abs() to B3 4 https://bugs.webkit.org/show_bug.cgi?id=152176 5 6 Reviewed by Geoffrey Garen. 7 8 This patch adds an Abs() operation for floating point. 9 10 On x86, Abs() is implemented by masking the top bit 11 of the floating point value. On ARM64, there is a builtin 12 abs opcode. 13 14 To account for those differences, B3 use "Abs" as 15 the cannonical operation. When we are about to lower 16 to Air, Abs is extended on x86 to get a clean handling 17 of the mask constants. 18 19 This patch has one cool thing related to FTL. 20 If you do: 21 @1 = unboxDouble(@0) 22 @2 = abs(@1) 23 @3 = boxDouble(@2) 24 25 B3ReduceStrength completely eliminate the Double-Integer 26 conversion. 27 28 The strength reduction of Abs is aware that it can do a bit 29 mask over the bitcast used by unboxing. 30 If even works if you use floats by forcing fround: reduceDoubleToFloat() 31 elminiates the useless conversions, followed by ReduceStrength 32 that removes the switch from GP to FP. 33 34 * CMakeLists.txt: 35 * JavaScriptCore.xcodeproj/project.pbxproj: 36 * assembler/MacroAssemblerX86Common.h: 37 (JSC::MacroAssemblerX86Common::andDouble): 38 (JSC::MacroAssemblerX86Common::andFloat): 39 * assembler/X86Assembler.h: 40 (JSC::X86Assembler::andps_rr): 41 * b3/B3ConstDoubleValue.cpp: 42 (JSC::B3::ConstDoubleValue::bitAndConstant): 43 (JSC::B3::ConstDoubleValue::absConstant): 44 * b3/B3ConstDoubleValue.h: 45 * b3/B3ConstFloatValue.cpp: 46 (JSC::B3::ConstFloatValue::bitAndConstant): 47 (JSC::B3::ConstFloatValue::absConstant): 48 * b3/B3ConstFloatValue.h: 49 * b3/B3Generate.cpp: 50 (JSC::B3::generateToAir): 51 * b3/B3LowerMacrosAfterOptimizations.cpp: Added. 52 (JSC::B3::lowerMacrosAfterOptimizations): 53 * b3/B3LowerMacrosAfterOptimizations.h: Added. 54 * b3/B3LowerToAir.cpp: 55 (JSC::B3::Air::LowerToAir::lower): 56 * b3/B3Opcode.cpp: 57 (WTF::printInternal): 58 * b3/B3Opcode.h: 59 * b3/B3ReduceDoubleToFloat.cpp: 60 * b3/B3ReduceStrength.cpp: 61 * b3/B3Validate.cpp: 62 * b3/B3Value.cpp: 63 (JSC::B3::Value::absConstant): 64 (JSC::B3::Value::effects): 65 (JSC::B3::Value::key): 66 (JSC::B3::Value::typeFor): 67 * b3/B3Value.h: 68 * b3/air/AirOpcode.opcodes: 69 * b3/testb3.cpp: 70 (JSC::B3::bitAndDouble): 71 (JSC::B3::testBitAndArgDouble): 72 (JSC::B3::testBitAndArgsDouble): 73 (JSC::B3::testBitAndArgImmDouble): 74 (JSC::B3::testBitAndImmsDouble): 75 (JSC::B3::bitAndFloat): 76 (JSC::B3::testBitAndArgFloat): 77 (JSC::B3::testBitAndArgsFloat): 78 (JSC::B3::testBitAndArgImmFloat): 79 (JSC::B3::testBitAndImmsFloat): 80 (JSC::B3::testBitAndArgsFloatWithUselessDoubleConversion): 81 (JSC::B3::testAbsArg): 82 (JSC::B3::testAbsImm): 83 (JSC::B3::testAbsMem): 84 (JSC::B3::testAbsAbsArg): 85 (JSC::B3::testAbsBitwiseCastArg): 86 (JSC::B3::testBitwiseCastAbsBitwiseCastArg): 87 (JSC::B3::testAbsArgWithUselessDoubleConversion): 88 (JSC::B3::testAbsArgWithEffectfulDoubleConversion): 89 (JSC::B3::run): 90 * ftl/FTLB3Output.h: 91 (JSC::FTL::Output::doubleAbs): 92 1 93 2015-12-11 Mark Lam <mark.lam@apple.com> 2 94 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r193989 r194003 1130 1130 41359CF30FDD89AD00206180 /* DateConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = D21202290AD4310C00ED79B6 /* DateConversion.h */; }; 1131 1131 41DEA1321B9F3163006D65DD /* BuiltinUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 41DEA1311B9F3154006D65DD /* BuiltinUtils.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1132 4319DA031C1BE40A001D260B /* B3LowerMacrosAfterOptimizations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4319DA011C1BE3C1001D260B /* B3LowerMacrosAfterOptimizations.cpp */; }; 1133 4319DA041C1BE40D001D260B /* B3LowerMacrosAfterOptimizations.h in Headers */ = {isa = PBXBuildFile; fileRef = 4319DA021C1BE3C1001D260B /* B3LowerMacrosAfterOptimizations.h */; }; 1132 1134 4340A4841A9051AF00D73CCA /* MathCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4340A4821A9051AF00D73CCA /* MathCommon.cpp */; }; 1133 1135 4340A4851A9051AF00D73CCA /* MathCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 4340A4831A9051AF00D73CCA /* MathCommon.h */; }; … … 3208 3210 371D842C17C98B6E00ECF994 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; 3209 3211 41DEA1311B9F3154006D65DD /* BuiltinUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BuiltinUtils.h; sourceTree = "<group>"; }; 3212 4319DA011C1BE3C1001D260B /* B3LowerMacrosAfterOptimizations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3LowerMacrosAfterOptimizations.cpp; path = b3/B3LowerMacrosAfterOptimizations.cpp; sourceTree = "<group>"; }; 3213 4319DA021C1BE3C1001D260B /* B3LowerMacrosAfterOptimizations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3LowerMacrosAfterOptimizations.h; path = b3/B3LowerMacrosAfterOptimizations.h; sourceTree = "<group>"; }; 3210 3214 4340A4821A9051AF00D73CCA /* MathCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathCommon.cpp; sourceTree = "<group>"; }; 3211 3215 4340A4831A9051AF00D73CCA /* MathCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathCommon.h; sourceTree = "<group>"; }; … … 4620 4624 0F338E021BF0276C0013C88F /* B3DataSection.h */, 4621 4625 0F33FCFA1C1625BE00323F67 /* B3Dominators.h */, 4622 43422A641C16221E00E2EB98 /* B3ReduceDoubleToFloat.cpp */,4623 43422A651C16221E00E2EB98 /* B3ReduceDoubleToFloat.h */,4624 4626 0FEC85C41BE16F5A0080FF74 /* B3Effects.cpp */, 4625 4627 0FEC85BE1BE167A00080FF74 /* B3Effects.h */, … … 4639 4641 0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */, 4640 4642 0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */, 4643 4319DA011C1BE3C1001D260B /* B3LowerMacrosAfterOptimizations.cpp */, 4644 4319DA021C1BE3C1001D260B /* B3LowerMacrosAfterOptimizations.h */, 4641 4645 0FEC84D31BDACDAC0080FF74 /* B3LowerToAir.cpp */, 4642 4646 0FEC84D41BDACDAC0080FF74 /* B3LowerToAir.h */, … … 4665 4669 0FEC84E21BDACDAC0080FF74 /* B3Procedure.h */, 4666 4670 0FEC84E31BDACDAC0080FF74 /* B3ProcedureInlines.h */, 4671 43422A641C16221E00E2EB98 /* B3ReduceDoubleToFloat.cpp */, 4672 43422A651C16221E00E2EB98 /* B3ReduceDoubleToFloat.h */, 4667 4673 0FEC85B71BE1462F0080FF74 /* B3ReduceStrength.cpp */, 4668 4674 0FEC85B81BE1462F0080FF74 /* B3ReduceStrength.h */, … … 7731 7737 FE3A06B21C10CB8900390FDD /* JITBitAndGenerator.h in Headers */, 7732 7738 0FD3E40E1B618B6600C80E1E /* PropertyCondition.h in Headers */, 7739 4319DA041C1BE40D001D260B /* B3LowerMacrosAfterOptimizations.h in Headers */, 7733 7740 A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */, 7734 7741 BC95437D0EBA70FD0072B6D3 /* PropertyMapHashTable.h in Headers */, … … 8789 8796 0F25F1B3181635F300522F39 /* FTLSlowPathCallKey.cpp in Sources */, 8790 8797 0F9D339A1803ADB70073C2BC /* FTLStackMaps.cpp in Sources */, 8798 4319DA031C1BE40A001D260B /* B3LowerMacrosAfterOptimizations.cpp in Sources */, 8791 8799 0FEA0A161706BB9000BB722C /* FTLState.cpp in Sources */, 8792 8800 0F235BE117178E1C00690C7F /* FTLThunks.cpp in Sources */, -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
r193804 r194003 1012 1012 ASSERT(isSSE2Present()); 1013 1013 m_assembler.mulss_mr(src.offset, src.base, dest); 1014 } 1015 1016 void andDouble(FPRegisterID src, FPRegisterID dst) 1017 { 1018 // ANDPS is defined on 128bits and is shorter than ANDPD. 1019 m_assembler.andps_rr(src, dst); 1020 } 1021 1022 void andFloat(FPRegisterID src, FPRegisterID dst) 1023 { 1024 m_assembler.andps_rr(src, dst); 1014 1025 } 1015 1026 -
trunk/Source/JavaScriptCore/assembler/X86Assembler.h
r193804 r194003 274 274 OP2_MOVMSKPD_VdEd = 0x50, 275 275 OP2_SQRTSD_VsdWsd = 0x51, 276 OP2_ANDPS_VpdWpd = 0x54, 276 277 OP2_ANDNPD_VpdWpd = 0x55, 277 278 OP2_XORPD_VpdWpd = 0x57, … … 2282 2283 m_formatter.prefix(PRE_SSE_F3); 2283 2284 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset); 2285 } 2286 2287 void andps_rr(XMMRegisterID src, XMMRegisterID dst) 2288 { 2289 m_formatter.twoByteOp(OP2_ANDPS_VpdWpd, (RegisterID)dst, (RegisterID)src); 2284 2290 } 2285 2291 -
trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp
r193933 r194003 70 70 } 71 71 72 Value* ConstDoubleValue::bitAndConstant(Procedure& proc, const Value* other) const 73 { 74 if (!other->hasDouble()) 75 return nullptr; 76 double result = bitwise_cast<double>(bitwise_cast<uint64_t>(m_value) & bitwise_cast<uint64_t>(other->asDouble())); 77 return proc.add<ConstDoubleValue>(origin(), result); 78 } 79 72 80 Value* ConstDoubleValue::bitwiseCastConstant(Procedure& proc) const 73 81 { … … 78 86 { 79 87 return proc.add<ConstFloatValue>(origin(), static_cast<float>(m_value)); 88 } 89 90 Value* ConstDoubleValue::absConstant(Procedure& proc) const 91 { 92 return proc.add<ConstDoubleValue>(origin(), fabs(m_value)); 80 93 } 81 94 -
trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h
r193933 r194003 48 48 Value* modConstant(Procedure&, const Value* other) const override; 49 49 Value* mulConstant(Procedure&, const Value* other) const override; 50 Value* bitAndConstant(Procedure&, const Value* other) const override; 50 51 Value* bitwiseCastConstant(Procedure&) const override; 51 52 Value* doubleToFloatConstant(Procedure&) const override; 53 Value* absConstant(Procedure&) const override; 52 54 Value* sqrtConstant(Procedure&) const override; 53 55 -
trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.cpp
r193683 r194003 70 70 } 71 71 72 Value* ConstFloatValue::bitAndConstant(Procedure& proc, const Value* other) const 73 { 74 if (!other->hasFloat()) 75 return nullptr; 76 float result = bitwise_cast<float>(bitwise_cast<uint32_t>(m_value) & bitwise_cast<uint32_t>(other->asFloat())); 77 return proc.add<ConstFloatValue>(origin(), result); 78 } 79 72 80 Value* ConstFloatValue::bitwiseCastConstant(Procedure& proc) const 73 81 { … … 78 86 { 79 87 return proc.add<ConstDoubleValue>(origin(), static_cast<double>(m_value)); 88 } 89 90 Value* ConstFloatValue::absConstant(Procedure& proc) const 91 { 92 return proc.add<ConstFloatValue>(origin(), static_cast<float>(fabs(m_value))); 80 93 } 81 94 -
trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.h
r193683 r194003 47 47 Value* divConstant(Procedure&, const Value* other) const override; 48 48 Value* mulConstant(Procedure&, const Value* other) const override; 49 Value* bitAndConstant(Procedure&, const Value* other) const override; 49 50 Value* bitwiseCastConstant(Procedure&) const override; 50 51 Value* floatToDoubleConstant(Procedure&) const override; 52 Value* absConstant(Procedure&) const override; 51 53 Value* sqrtConstant(Procedure&) const override; 52 54 -
trunk/Source/JavaScriptCore/b3/B3Generate.cpp
r193683 r194003 34 34 #include "B3Common.h" 35 35 #include "B3LowerMacros.h" 36 #include "B3LowerMacrosAfterOptimizations.h" 36 37 #include "B3LowerToAir.h" 37 38 #include "B3MoveConstants.h" … … 83 84 } 84 85 86 lowerMacrosAfterOptimizations(procedure); 87 85 88 moveConstants(procedure); 86 89 -
trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp
r193941 r194003 1460 1460 1461 1461 case BitAnd: { 1462 appendBinOp<And32, And64, Commutative>(1462 appendBinOp<And32, And64, AndDouble, AndFloat, Commutative>( 1463 1463 m_value->child(0), m_value->child(1)); 1464 1464 return; -
trunk/Source/JavaScriptCore/b3/B3Opcode.cpp
r193933 r194003 147 147 out.print("Clz"); 148 148 return; 149 case Abs: 150 out.print("Abs"); 151 return; 149 152 case Sqrt: 150 153 out.print("Sqrt"); -
trunk/Source/JavaScriptCore/b3/B3Opcode.h
r193933 r194003 85 85 Clz, // Count leading zeros. 86 86 87 // Double math. 87 // Floating point math. 88 Abs, 88 89 Sqrt, 89 90 -
trunk/Source/JavaScriptCore/b3/B3ReduceDoubleToFloat.cpp
r193683 r194003 49 49 } 50 50 break; 51 case Abs: 51 52 case Sqrt: 52 53 if (candidate->child(0)->opcode() == FloatToDouble) { -
trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp
r193993 r194003 506 506 break; 507 507 508 case Abs: 509 // Turn this: Abs(constant) 510 // Into this: fabs<value->type()>(constant) 511 if (Value* constant = m_value->child(0)->absConstant(m_proc)) { 512 replaceWithNewValue(constant); 513 break; 514 } 515 516 // Turn this: Abs(Abs(value)) 517 // Into this: Abs(value) 518 if (m_value->child(0)->opcode() == Abs) { 519 m_value->replaceWithIdentity(m_value->child(0)); 520 break; 521 } 522 523 // Turn this: Abs(BitwiseCast(value)) 524 // Into this: BitwiseCast(And(value, mask-top-bit)) 525 if (m_value->child(0)->opcode() == BitwiseCast) { 526 Value* mask; 527 if (m_value->type() == Double) 528 mask = m_insertionSet.insert<Const64Value>(m_index, m_value->origin(), ~(1l << 63)); 529 else 530 mask = m_insertionSet.insert<Const32Value>(m_index, m_value->origin(), ~(1l << 31)); 531 532 Value* bitAnd = m_insertionSet.insert<Value>(m_index, BitAnd, m_value->origin(), 533 m_value->child(0)->child(0), 534 mask); 535 Value* cast = m_insertionSet.insert<Value>(m_index, BitwiseCast, m_value->origin(), bitAnd); 536 m_value->replaceWithIdentity(cast); 537 break; 538 } 539 break; 540 508 541 case Sqrt: 509 542 // Turn this: Sqrt(constant) -
trunk/Source/JavaScriptCore/b3/B3Validate.cpp
r193943 r194003 155 155 case Div: 156 156 case Mod: 157 case BitAnd: 157 158 VALIDATE(value->numChildren() == 2, ("At ", *value)); 158 159 VALIDATE(value->type() == value->child(0)->type(), ("At ", *value)); … … 162 163 case ChillDiv: 163 164 case ChillMod: 164 case BitAnd:165 165 case BitOr: 166 166 case BitXor: … … 210 210 VALIDATE(value->type() == Int32, ("At ", *value)); 211 211 break; 212 case Abs: 212 213 case Sqrt: 213 214 VALIDATE(value->numChildren() == 1, ("At ", *value)); -
trunk/Source/JavaScriptCore/b3/B3Value.cpp
r193987 r194003 218 218 219 219 Value* Value::floatToDoubleConstant(Procedure&) const 220 { 221 return nullptr; 222 } 223 224 Value* Value::absConstant(Procedure&) const 220 225 { 221 226 return nullptr; … … 358 363 case ZShr: 359 364 case Clz: 365 case Abs: 360 366 case Sqrt: 361 367 case BitwiseCast: … … 434 440 return ValueKey(opcode(), type()); 435 441 case Identity: 442 case Abs: 436 443 case Sqrt: 437 444 case SExt8: … … 540 547 case ZShr: 541 548 case Clz: 549 case Abs: 542 550 case Sqrt: 543 551 case CheckAdd: -
trunk/Source/JavaScriptCore/b3/B3Value.h
r193943 r194003 132 132 virtual Value* doubleToFloatConstant(Procedure&) const; 133 133 virtual Value* floatToDoubleConstant(Procedure&) const; 134 virtual Value* absConstant(Procedure&) const; 134 135 virtual Value* sqrtConstant(Procedure&) const; 135 136 -
trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes
r193804 r194003 171 171 Imm, Tmp 172 172 173 AndDouble U:F, UD:F 174 Tmp, Tmp 175 176 AndFloat U:F, UD:F 177 Tmp, Tmp 178 173 179 Lshift32 U:G, UD:G 174 180 Tmp*, Tmp -
trunk/Source/JavaScriptCore/b3/testb3.cpp
r193989 r194003 1943 1943 } 1944 1944 1945 double bitAndDouble(double a, double b) 1946 { 1947 return bitwise_cast<double>(bitwise_cast<uint64_t>(a) & bitwise_cast<uint64_t>(b)); 1948 } 1949 1950 void testBitAndArgDouble(double a) 1951 { 1952 Procedure proc; 1953 BasicBlock* root = proc.addBlock(); 1954 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0); 1955 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argument, argument); 1956 root->appendNew<ControlValue>(proc, Return, Origin(), result); 1957 1958 CHECK(isIdentical(compileAndRun<double>(proc, a), bitAndDouble(a, a))); 1959 } 1960 1961 void testBitAndArgsDouble(double a, double b) 1962 { 1963 Procedure proc; 1964 BasicBlock* root = proc.addBlock(); 1965 Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0); 1966 Value* argumentB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1); 1967 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB); 1968 root->appendNew<ControlValue>(proc, Return, Origin(), result); 1969 1970 CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitAndDouble(a, b))); 1971 } 1972 1973 void testBitAndArgImmDouble(double a, double b) 1974 { 1975 Procedure proc; 1976 BasicBlock* root = proc.addBlock(); 1977 Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0); 1978 Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b); 1979 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB); 1980 root->appendNew<ControlValue>(proc, Return, Origin(), result); 1981 1982 CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitAndDouble(a, b))); 1983 } 1984 1985 void testBitAndImmsDouble(double a, double b) 1986 { 1987 Procedure proc; 1988 BasicBlock* root = proc.addBlock(); 1989 Value* argumentA = root->appendNew<ConstDoubleValue>(proc, Origin(), a); 1990 Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b); 1991 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB); 1992 root->appendNew<ControlValue>(proc, Return, Origin(), result); 1993 1994 CHECK(isIdentical(compileAndRun<double>(proc), bitAndDouble(a, b))); 1995 } 1996 1997 float bitAndFloat(float a, float b) 1998 { 1999 return bitwise_cast<float>(bitwise_cast<uint32_t>(a) & bitwise_cast<uint32_t>(b)); 2000 } 2001 2002 void testBitAndArgFloat(float a) 2003 { 2004 Procedure proc; 2005 BasicBlock* root = proc.addBlock(); 2006 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), 2007 root->appendNew<Value>(proc, Trunc, Origin(), 2008 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))); 2009 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argument, argument); 2010 root->appendNew<ControlValue>(proc, Return, Origin(), result); 2011 2012 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), bitAndFloat(a, a))); 2013 } 2014 2015 void testBitAndArgsFloat(float a, float b) 2016 { 2017 Procedure proc; 2018 BasicBlock* root = proc.addBlock(); 2019 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(), 2020 root->appendNew<Value>(proc, Trunc, Origin(), 2021 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))); 2022 Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(), 2023 root->appendNew<Value>(proc, Trunc, Origin(), 2024 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))); 2025 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB); 2026 root->appendNew<ControlValue>(proc, Return, Origin(), result); 2027 2028 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitAndFloat(a, b))); 2029 } 2030 2031 void testBitAndArgImmFloat(float a, float b) 2032 { 2033 Procedure proc; 2034 BasicBlock* root = proc.addBlock(); 2035 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(), 2036 root->appendNew<Value>(proc, Trunc, Origin(), 2037 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))); 2038 Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b); 2039 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB); 2040 root->appendNew<ControlValue>(proc, Return, Origin(), result); 2041 2042 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitAndFloat(a, b))); 2043 } 2044 2045 void testBitAndImmsFloat(float a, float b) 2046 { 2047 Procedure proc; 2048 BasicBlock* root = proc.addBlock(); 2049 Value* argumentA = root->appendNew<ConstFloatValue>(proc, Origin(), a); 2050 Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b); 2051 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB); 2052 root->appendNew<ControlValue>(proc, Return, Origin(), result); 2053 2054 CHECK(isIdentical(compileAndRun<float>(proc), bitAndFloat(a, b))); 2055 } 2056 2057 void testBitAndArgsFloatWithUselessDoubleConversion(float a, float b) 2058 { 2059 Procedure proc; 2060 BasicBlock* root = proc.addBlock(); 2061 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(), 2062 root->appendNew<Value>(proc, Trunc, Origin(), 2063 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))); 2064 Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(), 2065 root->appendNew<Value>(proc, Trunc, Origin(), 2066 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))); 2067 Value* argumentAasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentA); 2068 Value* argumentBasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentB); 2069 Value* doubleResult = root->appendNew<Value>(proc, BitAnd, Origin(), argumentAasDouble, argumentBasDouble); 2070 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), doubleResult); 2071 root->appendNew<ControlValue>(proc, Return, Origin(), floatResult); 2072 2073 double doubleA = a; 2074 double doubleB = b; 2075 float expected = static_cast<float>(bitAndDouble(doubleA, doubleB)); 2076 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), expected)); 2077 } 2078 1945 2079 void testBitOrArgs(int64_t a, int64_t b) 1946 2080 { … … 2896 3030 root->appendNew<ControlValue>(proc, Return, Origin(), clzValue); 2897 3031 CHECK(compileAndRun<unsigned>(proc, &a) == countLeadingZero(a)); 3032 } 3033 3034 void testAbsArg(double a) 3035 { 3036 Procedure proc; 3037 BasicBlock* root = proc.addBlock(); 3038 root->appendNew<ControlValue>( 3039 proc, Return, Origin(), 3040 root->appendNew<Value>( 3041 proc, Abs, Origin(), 3042 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0))); 3043 3044 CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(a))); 3045 } 3046 3047 void testAbsImm(double a) 3048 { 3049 Procedure proc; 3050 BasicBlock* root = proc.addBlock(); 3051 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a); 3052 root->appendNew<ControlValue>( 3053 proc, Return, Origin(), 3054 root->appendNew<Value>(proc, Abs, Origin(), argument)); 3055 3056 CHECK(isIdentical(compileAndRun<double>(proc), fabs(a))); 3057 } 3058 3059 void testAbsMem(double a) 3060 { 3061 Procedure proc; 3062 BasicBlock* root = proc.addBlock(); 3063 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0); 3064 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address); 3065 root->appendNew<ControlValue>( 3066 proc, Return, Origin(), 3067 root->appendNew<Value>(proc, Abs, Origin(), loadDouble)); 3068 3069 CHECK(isIdentical(compileAndRun<double>(proc, &a), fabs(a))); 3070 } 3071 3072 void testAbsAbsArg(double a) 3073 { 3074 Procedure proc; 3075 BasicBlock* root = proc.addBlock(); 3076 Value* firstAbs = root->appendNew<Value>(proc, Abs, Origin(), 3077 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)); 3078 Value* secondAbs = root->appendNew<Value>(proc, Abs, Origin(), firstAbs); 3079 root->appendNew<ControlValue>(proc, Return, Origin(), secondAbs); 3080 3081 CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(a))); 3082 } 3083 3084 void testAbsBitwiseCastArg(double a) 3085 { 3086 Procedure proc; 3087 BasicBlock* root = proc.addBlock(); 3088 Value* argumentAsInt64 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0); 3089 Value* argumentAsDouble = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt64); 3090 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsDouble); 3091 root->appendNew<ControlValue>(proc, Return, Origin(), absValue); 3092 3093 CHECK(isIdentical(compileAndRun<double>(proc, bitwise_cast<int64_t>(a)), fabs(a))); 3094 } 3095 3096 void testBitwiseCastAbsBitwiseCastArg(double a) 3097 { 3098 Procedure proc; 3099 BasicBlock* root = proc.addBlock(); 3100 Value* argumentAsInt64 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0); 3101 Value* argumentAsDouble = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt64); 3102 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsDouble); 3103 Value* resultAsInt64 = root->appendNew<Value>(proc, BitwiseCast, Origin(), absValue); 3104 3105 root->appendNew<ControlValue>(proc, Return, Origin(), resultAsInt64); 3106 3107 int64_t expectedResult = bitwise_cast<int64_t>(fabs(a)); 3108 CHECK(isIdentical(compileAndRun<int64_t>(proc, bitwise_cast<int64_t>(a)), expectedResult)); 3109 } 3110 3111 void testAbsArg(float a) 3112 { 3113 Procedure proc; 3114 BasicBlock* root = proc.addBlock(); 3115 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(), 3116 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)); 3117 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32); 3118 Value* result = root->appendNew<Value>(proc, Abs, Origin(), argument); 3119 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result); 3120 root->appendNew<ControlValue>(proc, Return, Origin(), result32); 3121 3122 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a))))); 3123 } 3124 3125 void testAbsImm(float a) 3126 { 3127 Procedure proc; 3128 BasicBlock* root = proc.addBlock(); 3129 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a); 3130 Value* result = root->appendNew<Value>(proc, Abs, Origin(), argument); 3131 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result); 3132 root->appendNew<ControlValue>(proc, Return, Origin(), result32); 3133 3134 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a))))); 3135 } 3136 3137 void testAbsMem(float a) 3138 { 3139 Procedure proc; 3140 BasicBlock* root = proc.addBlock(); 3141 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0); 3142 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address); 3143 Value* result = root->appendNew<Value>(proc, Abs, Origin(), loadFloat); 3144 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result); 3145 root->appendNew<ControlValue>(proc, Return, Origin(), result32); 3146 3147 CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(static_cast<float>(fabs(a))))); 3148 } 3149 3150 void testAbsAbsArg(float a) 3151 { 3152 Procedure proc; 3153 BasicBlock* root = proc.addBlock(); 3154 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(), 3155 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)); 3156 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32); 3157 Value* firstAbs = root->appendNew<Value>(proc, Abs, Origin(), argument); 3158 Value* secondAbs = root->appendNew<Value>(proc, Abs, Origin(), firstAbs); 3159 root->appendNew<ControlValue>(proc, Return, Origin(), secondAbs); 3160 3161 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(a)))); 3162 } 3163 3164 void testAbsBitwiseCastArg(float a) 3165 { 3166 Procedure proc; 3167 BasicBlock* root = proc.addBlock(); 3168 Value* argumentAsInt32 = root->appendNew<Value>(proc, Trunc, Origin(), 3169 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)); 3170 Value* argumentAsfloat = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt32); 3171 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsfloat); 3172 root->appendNew<ControlValue>(proc, Return, Origin(), absValue); 3173 3174 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(a)))); 3175 } 3176 3177 void testBitwiseCastAbsBitwiseCastArg(float a) 3178 { 3179 Procedure proc; 3180 BasicBlock* root = proc.addBlock(); 3181 Value* argumentAsInt32 = root->appendNew<Value>(proc, Trunc, Origin(), 3182 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)); 3183 Value* argumentAsfloat = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt32); 3184 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsfloat); 3185 Value* resultAsInt64 = root->appendNew<Value>(proc, BitwiseCast, Origin(), absValue); 3186 3187 root->appendNew<ControlValue>(proc, Return, Origin(), resultAsInt64); 3188 3189 int32_t expectedResult = bitwise_cast<int32_t>(static_cast<float>(fabs(a))); 3190 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), expectedResult)); 3191 } 3192 3193 void testAbsArgWithUselessDoubleConversion(float a) 3194 { 3195 Procedure proc; 3196 BasicBlock* root = proc.addBlock(); 3197 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(), 3198 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)); 3199 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32); 3200 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue); 3201 Value* result = root->appendNew<Value>(proc, Abs, Origin(), asDouble); 3202 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result); 3203 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult); 3204 root->appendNew<ControlValue>(proc, Return, Origin(), result32); 3205 3206 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a))))); 3207 } 3208 3209 void testAbsArgWithEffectfulDoubleConversion(float a) 3210 { 3211 Procedure proc; 3212 BasicBlock* root = proc.addBlock(); 3213 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(), 3214 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)); 3215 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32); 3216 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue); 3217 Value* result = root->appendNew<Value>(proc, Abs, Origin(), asDouble); 3218 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result); 3219 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult); 3220 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1); 3221 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress); 3222 root->appendNew<ControlValue>(proc, Return, Origin(), result32); 3223 3224 double effect = 0; 3225 int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect); 3226 CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(static_cast<float>(fabs(a))))); 3227 CHECK(isIdentical(effect, fabs(a))); 2898 3228 } 2899 3229 … … 7516 7846 RUN(testBitAndImmBitAndArgImm32(24, 0xffff, 7)); 7517 7847 RUN_BINARY(testBitAndWithMaskReturnsBooleans, int64Operands(), int64Operands()); 7848 RUN_UNARY(testBitAndArgDouble, floatingPointOperands<double>()); 7849 RUN_BINARY(testBitAndArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>()); 7850 RUN_BINARY(testBitAndArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>()); 7851 RUN_BINARY(testBitAndImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>()); 7852 RUN_UNARY(testBitAndArgFloat, floatingPointOperands<float>()); 7853 RUN_BINARY(testBitAndArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>()); 7854 RUN_BINARY(testBitAndArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>()); 7855 RUN_BINARY(testBitAndImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>()); 7856 RUN_BINARY(testBitAndArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>()); 7518 7857 7519 7858 RUN(testBitOrArgs(43, 43)); … … 7747 8086 RUN_UNARY(testClzMem32, int64Operands()); 7748 8087 8088 RUN_UNARY(testAbsArg, floatingPointOperands<double>()); 8089 RUN_UNARY(testAbsImm, floatingPointOperands<double>()); 8090 RUN_UNARY(testAbsMem, floatingPointOperands<double>()); 8091 RUN_UNARY(testAbsAbsArg, floatingPointOperands<double>()); 8092 RUN_UNARY(testAbsBitwiseCastArg, floatingPointOperands<double>()); 8093 RUN_UNARY(testBitwiseCastAbsBitwiseCastArg, floatingPointOperands<double>()); 8094 RUN_UNARY(testAbsArg, floatingPointOperands<float>()); 8095 RUN_UNARY(testAbsImm, floatingPointOperands<float>()); 8096 RUN_UNARY(testAbsMem, floatingPointOperands<float>()); 8097 RUN_UNARY(testAbsAbsArg, floatingPointOperands<float>()); 8098 RUN_UNARY(testAbsBitwiseCastArg, floatingPointOperands<float>()); 8099 RUN_UNARY(testBitwiseCastAbsBitwiseCastArg, floatingPointOperands<float>()); 8100 RUN_UNARY(testAbsArgWithUselessDoubleConversion, floatingPointOperands<float>()); 8101 RUN_UNARY(testAbsArgWithEffectfulDoubleConversion, floatingPointOperands<float>()); 8102 7749 8103 RUN_UNARY(testSqrtArg, floatingPointOperands<double>()); 7750 8104 RUN_UNARY(testSqrtImm, floatingPointOperands<double>()); -
trunk/Source/JavaScriptCore/ftl/FTLB3Output.h
r193989 r194003 163 163 LValue subWithOverflow64(LValue left, LValue right) { CRASH(); } 164 164 LValue mulWithOverflow64(LValue left, LValue right) { CRASH(); } 165 LValue doubleAbs(LValue value) { CRASH(); }165 LValue doubleAbs(LValue value) { return m_block->appendNew<B3::Value>(m_proc, B3::Abs, origin(), value); } 166 166 167 167 LValue doubleSin(LValue value) { return callWithoutSideEffects(B3::Double, sin, value); }
Note: See TracChangeset
for help on using the changeset viewer.