Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (192618 => 192619)
--- trunk/Source/_javascript_Core/ChangeLog 2015-11-19 08:19:56 UTC (rev 192618)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-11-19 08:38:17 UTC (rev 192619)
@@ -1,3 +1,45 @@
+2015-11-19 Benjamin Poulain <bpoul...@apple.com>
+
+ [JSC] Add bitwise Double-Int conversion to B3
+ https://bugs.webkit.org/show_bug.cgi?id=151432
+
+ Reviewed by Filip Pizlo.
+
+ This is needed for boxing/unboxing doubles.
+
+ * b3/B3Const64Value.cpp:
+ (JSC::B3::Const64Value::bitwiseCastConstant):
+ * b3/B3Const64Value.h:
+ * b3/B3ConstDoubleValue.cpp:
+ (JSC::B3::ConstDoubleValue::bitwiseCastConstant):
+ * b3/B3ConstDoubleValue.h:
+ * b3/B3LowerToAir.cpp:
+ (JSC::B3::Air::LowerToAir::lower):
+ * b3/B3Opcode.cpp:
+ (WTF::printInternal):
+ * b3/B3Opcode.h:
+ * b3/B3ReduceStrength.cpp:
+ * b3/B3Validate.cpp:
+ * b3/B3Value.cpp:
+ (JSC::B3::Value::bitwiseCastConstant):
+ (JSC::B3::Value::effects):
+ (JSC::B3::Value::typeFor):
+ * b3/B3Value.h:
+ * b3/air/AirOpcode.opcodes:
+ * b3/testb3.cpp:
+ (JSC::B3::testDoubleArgToInt64BitwiseCast):
+ (JSC::B3::testDoubleImmToInt64BitwiseCast):
+ (JSC::B3::testTwoBitwiseCastOnDouble):
+ (JSC::B3::testBitwiseCastOnDoubleInMemory):
+ (JSC::B3::testInt64BArgToDoubleBitwiseCast):
+ (JSC::B3::testInt64BImmToDoubleBitwiseCast):
+ (JSC::B3::testTwoBitwiseCastOnInt64):
+ (JSC::B3::testBitwiseCastOnInt64InMemory):
+ (JSC::B3::int64Operands):
+ (JSC::B3::run):
+ * ftl/FTLB3Output.h:
+ (JSC::FTL::Output::bitCast):
+
2015-11-18 Benjamin Poulain <bpoul...@apple.com>
[JSC] Add some missing load/store to FTLB3Output
Modified: trunk/Source/_javascript_Core/b3/B3Const64Value.cpp (192618 => 192619)
--- trunk/Source/_javascript_Core/b3/B3Const64Value.cpp 2015-11-19 08:19:56 UTC (rev 192618)
+++ trunk/Source/_javascript_Core/b3/B3Const64Value.cpp 2015-11-19 08:38:17 UTC (rev 192619)
@@ -154,6 +154,11 @@
return proc.add<Const64Value>(origin(), static_cast<int64_t>(static_cast<uint64_t>(m_value) >> (other->asInt32() & 63)));
}
+Value* Const64Value::bitwiseCastConstant(Procedure& proc) const
+{
+ return proc.add<ConstDoubleValue>(origin(), bitwise_cast<double>(m_value));
+}
+
TriState Const64Value::equalConstant(const Value* other) const
{
if (!other->hasInt64())
Modified: trunk/Source/_javascript_Core/b3/B3Const64Value.h (192618 => 192619)
--- trunk/Source/_javascript_Core/b3/B3Const64Value.h 2015-11-19 08:19:56 UTC (rev 192618)
+++ trunk/Source/_javascript_Core/b3/B3Const64Value.h 2015-11-19 08:38:17 UTC (rev 192619)
@@ -56,6 +56,7 @@
Value* shlConstant(Procedure&, const Value* other) const override;
Value* sShrConstant(Procedure&, const Value* other) const override;
Value* zShrConstant(Procedure&, const Value* other) const override;
+ Value* bitwiseCastConstant(Procedure&) const override;
TriState equalConstant(const Value* other) const override;
TriState notEqualConstant(const Value* other) const override;
Modified: trunk/Source/_javascript_Core/b3/B3ConstDoubleValue.cpp (192618 => 192619)
--- trunk/Source/_javascript_Core/b3/B3ConstDoubleValue.cpp 2015-11-19 08:19:56 UTC (rev 192618)
+++ trunk/Source/_javascript_Core/b3/B3ConstDoubleValue.cpp 2015-11-19 08:38:17 UTC (rev 192619)
@@ -68,6 +68,11 @@
return proc.add<ConstDoubleValue>(origin(), m_value * other->asDouble());
}
+Value* ConstDoubleValue::bitwiseCastConstant(Procedure& proc) const
+{
+ return proc.add<Const64Value>(origin(), bitwise_cast<int64_t>(m_value));
+}
+
Value* ConstDoubleValue::divConstant(Procedure& proc, const Value* other) const
{
if (!other->hasDouble())
Modified: trunk/Source/_javascript_Core/b3/B3ConstDoubleValue.h (192618 => 192619)
--- trunk/Source/_javascript_Core/b3/B3ConstDoubleValue.h 2015-11-19 08:19:56 UTC (rev 192618)
+++ trunk/Source/_javascript_Core/b3/B3ConstDoubleValue.h 2015-11-19 08:38:17 UTC (rev 192619)
@@ -46,6 +46,7 @@
Value* subConstant(Procedure&, const Value* other) const override;
Value* divConstant(Procedure&, const Value* other) const override;
Value* mulConstant(Procedure&, const Value* other) const override;
+ Value* bitwiseCastConstant(Procedure&) const override;
TriState equalConstant(const Value* other) const override;
TriState notEqualConstant(const Value* other) const override;
Modified: trunk/Source/_javascript_Core/b3/B3LowerToAir.cpp (192618 => 192619)
--- trunk/Source/_javascript_Core/b3/B3LowerToAir.cpp 2015-11-19 08:19:56 UTC (rev 192618)
+++ trunk/Source/_javascript_Core/b3/B3LowerToAir.cpp 2015-11-19 08:38:17 UTC (rev 192619)
@@ -1344,6 +1344,11 @@
return;
}
+ case BitwiseCast: {
+ appendUnOp<Air::Oops, Move64ToDouble, MoveDoubleTo64>(m_value->child(0));
+ return;
+ }
+
case Store: {
Value* valueToStore = m_value->child(0);
if (canBeInternal(valueToStore)) {
Modified: trunk/Source/_javascript_Core/b3/B3Opcode.cpp (192618 => 192619)
--- trunk/Source/_javascript_Core/b3/B3Opcode.cpp 2015-11-19 08:19:56 UTC (rev 192618)
+++ trunk/Source/_javascript_Core/b3/B3Opcode.cpp 2015-11-19 08:38:17 UTC (rev 192619)
@@ -137,6 +137,9 @@
case ZShr:
out.print("ZShr");
return;
+ case BitwiseCast:
+ out.print("BitwiseCast");
+ return;
case SExt8:
out.print("SExt8");
return;
Modified: trunk/Source/_javascript_Core/b3/B3Opcode.h (192618 => 192619)
--- trunk/Source/_javascript_Core/b3/B3Opcode.h 2015-11-19 08:19:56 UTC (rev 192618)
+++ trunk/Source/_javascript_Core/b3/B3Opcode.h 2015-11-19 08:38:17 UTC (rev 192619)
@@ -82,6 +82,8 @@
ZShr, // Logical Shift.
// Casts and such.
+ // Bitwise Cast of Double->Int64 or Int64->Double
+ BitwiseCast,
// Takes and returns Int32:
SExt8,
SExt16,
Modified: trunk/Source/_javascript_Core/b3/B3ReduceStrength.cpp (192618 => 192619)
--- trunk/Source/_javascript_Core/b3/B3ReduceStrength.cpp 2015-11-19 08:19:56 UTC (rev 192618)
+++ trunk/Source/_javascript_Core/b3/B3ReduceStrength.cpp 2015-11-19 08:38:17 UTC (rev 192619)
@@ -464,6 +464,24 @@
break;
+ case BitwiseCast:
+ // Turn this: BitwiseCast(constant)
+ // Into this: bitwise_cast<value->type()>(constant)
+ if (Value* constant = m_value->child(0)->bitwiseCastConstant(m_proc)) {
+ replaceWithNewValue(constant);
+ break;
+ }
+
+ // Turn this: BitwiseCast(BitwiseCast(value))
+ // Into this: value
+ if (m_value->child(0)->opcode() == BitwiseCast) {
+ m_value->replaceWithIdentity(m_value->child(0)->child(0));
+ m_changed = true;
+ break;
+ }
+
+ break;
+
case Load8Z:
case Load8S:
case Load16Z:
Modified: trunk/Source/_javascript_Core/b3/B3Validate.cpp (192618 => 192619)
--- trunk/Source/_javascript_Core/b3/B3Validate.cpp 2015-11-19 08:19:56 UTC (rev 192618)
+++ trunk/Source/_javascript_Core/b3/B3Validate.cpp 2015-11-19 08:38:17 UTC (rev 192619)
@@ -172,6 +172,14 @@
VALIDATE(value->child(1)->type() == Int32, ("At ", *value));
VALIDATE(isInt(value->type()), ("At ", *value));
break;
+ case BitwiseCast:
+ VALIDATE(value->numChildren() == 1, ("At ", *value));
+ VALIDATE(value->type() != value->child(0)->type(), ("At ", *value));
+ VALIDATE(
+ (value->type() == Int64 && value->child(0)->type() == Double)
+ || (value->type() == Double && value->child(0)->type() == Int64),
+ ("At ", *value));
+ break;
case SExt8:
case SExt16:
VALIDATE(value->numChildren() == 1, ("At ", *value));
Modified: trunk/Source/_javascript_Core/b3/B3Value.cpp (192618 => 192619)
--- trunk/Source/_javascript_Core/b3/B3Value.cpp 2015-11-19 08:19:56 UTC (rev 192618)
+++ trunk/Source/_javascript_Core/b3/B3Value.cpp 2015-11-19 08:38:17 UTC (rev 192619)
@@ -194,6 +194,11 @@
return nullptr;
}
+Value* Value::bitwiseCastConstant(Procedure&) const
+{
+ return nullptr;
+}
+
TriState Value::equalConstant(const Value*) const
{
return MixedTriState;
@@ -320,6 +325,7 @@
case Shl:
case SShr:
case ZShr:
+ case BitwiseCast:
case SExt8:
case SExt16:
case SExt32:
@@ -514,6 +520,13 @@
case FRound:
case IToD:
return Double;
+ case BitwiseCast:
+ if (firstChild->type() == Int64)
+ return Double;
+ if (firstChild->type() == Double)
+ return Int64;
+ ASSERT_NOT_REACHED();
+ return Void;
case Nop:
return Void;
default:
Modified: trunk/Source/_javascript_Core/b3/B3Value.h (192618 => 192619)
--- trunk/Source/_javascript_Core/b3/B3Value.h 2015-11-19 08:19:56 UTC (rev 192618)
+++ trunk/Source/_javascript_Core/b3/B3Value.h 2015-11-19 08:38:17 UTC (rev 192619)
@@ -127,6 +127,7 @@
virtual Value* shlConstant(Procedure&, const Value* other) const;
virtual Value* sShrConstant(Procedure&, const Value* other) const;
virtual Value* zShrConstant(Procedure&, const Value* other) const;
+ virtual Value* bitwiseCastConstant(Procedure&) const;
virtual TriState equalConstant(const Value* other) const;
virtual TriState notEqualConstant(const Value* other) const;
Modified: trunk/Source/_javascript_Core/b3/air/AirOpcode.opcodes (192618 => 192619)
--- trunk/Source/_javascript_Core/b3/air/AirOpcode.opcodes 2015-11-19 08:19:56 UTC (rev 192618)
+++ trunk/Source/_javascript_Core/b3/air/AirOpcode.opcodes 2015-11-19 08:38:17 UTC (rev 192619)
@@ -237,9 +237,11 @@
Move64ToDouble U:G, D:F
Tmp, Tmp
+ Addr, Tmp as loadDouble
MoveDoubleTo64 U:F, D:G
Tmp, Tmp
+ Addr, Tmp as load64
Load8 U:G, D:G
Addr, Tmp
Modified: trunk/Source/_javascript_Core/b3/testb3.cpp (192618 => 192619)
--- trunk/Source/_javascript_Core/b3/testb3.cpp 2015-11-19 08:19:56 UTC (rev 192618)
+++ trunk/Source/_javascript_Core/b3/testb3.cpp 2015-11-19 08:38:17 UTC (rev 192619)
@@ -1729,6 +1729,110 @@
CHECK(compileAndRun<uint32_t>(proc, a) == (a >> b));
}
+void testDoubleArgToInt64BitwiseCast(double value)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
+
+ root->appendNew<ControlValue>(
+ proc, Return, Origin(),
+ root->appendNew<Value>(
+ proc, BitwiseCast, Origin(), argument));
+
+ CHECK(isIdentical(compileAndRun<int64_t>(proc, value), bitwise_cast<int64_t>(value)));
+}
+
+void testDoubleImmToInt64BitwiseCast(double value)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), value);
+
+ root->appendNew<ControlValue>(
+ proc, Return, Origin(),
+ root->appendNew<Value>(
+ proc, BitwiseCast, Origin(), argument));
+
+ CHECK(isIdentical(compileAndRun<int64_t>(proc), bitwise_cast<int64_t>(value)));
+}
+
+void testTwoBitwiseCastOnDouble(double value)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
+ Value* first = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument);
+ Value* second = root->appendNew<Value>(proc, BitwiseCast, Origin(), first);
+ root->appendNew<ControlValue>(proc, Return, Origin(), second);
+
+ CHECK(isIdentical(compileAndRun<double>(proc, value), value));
+}
+
+void testBitwiseCastOnDoubleInMemory(double value)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+ MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
+ Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
+ root->appendNew<ControlValue>(proc, Return, Origin(), cast);
+
+ CHECK(isIdentical(compileAndRun<int64_t>(proc, &value), bitwise_cast<int64_t>(value)));
+}
+
+void testInt64BArgToDoubleBitwiseCast(int64_t value)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+
+ root->appendNew<ControlValue>(
+ proc, Return, Origin(),
+ root->appendNew<Value>(
+ proc, BitwiseCast, Origin(), argument));
+
+ CHECK(isIdentical(compileAndRun<double>(proc, value), bitwise_cast<double>(value)));
+}
+
+void testInt64BImmToDoubleBitwiseCast(int64_t value)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argument = root->appendNew<Const64Value>(proc, Origin(), value);
+
+ root->appendNew<ControlValue>(
+ proc, Return, Origin(),
+ root->appendNew<Value>(
+ proc, BitwiseCast, Origin(), argument));
+
+ CHECK(isIdentical(compileAndRun<double>(proc), bitwise_cast<double>(value)));
+}
+
+void testTwoBitwiseCastOnInt64(int64_t value)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+ Value* first = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument);
+ Value* second = root->appendNew<Value>(proc, BitwiseCast, Origin(), first);
+ root->appendNew<ControlValue>(proc, Return, Origin(), second);
+
+ CHECK(isIdentical(compileAndRun<int64_t>(proc, value), value));
+}
+
+void testBitwiseCastOnInt64InMemory(int64_t value)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+ MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
+ Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
+ root->appendNew<ControlValue>(proc, Return, Origin(), cast);
+
+ CHECK(isIdentical(compileAndRun<double>(proc, &value), bitwise_cast<double>(value)));
+}
+
void testStore(int value)
{
Procedure proc;
@@ -4547,12 +4651,15 @@
return -std::numeric_limits<double>::infinity();
}
-
-struct DoubleOperand {
+template<typename Type>
+struct Operand {
const char* name;
- double value;
+ Type value;
};
+typedef Operand<double> DoubleOperand;
+typedef Operand<int64_t> Int64Operand;
+
static const std::array<DoubleOperand, 9>& doubleOperands()
{
static const std::array<DoubleOperand, 9> operands = {{
@@ -4569,6 +4676,14 @@
return operands;
};
+static Vector<Int64Operand> int64Operands()
+{
+ Vector<Int64Operand> operands;
+ for (DoubleOperand doubleOperand : doubleOperands())
+ operands.append({ doubleOperand.name, bitwise_cast<int64_t>(doubleOperand.value) });
+ return operands;
+}
+
#define RUN(test) do { \
if (!shouldRun(#test)) \
break; \
@@ -5052,6 +5167,15 @@
RUN(testZShrArgImm32(0xffffffff, 1));
RUN(testZShrArgImm32(0xffffffff, 63));
+ RUN_UNARY(testDoubleArgToInt64BitwiseCast, doubleOperands());
+ RUN_UNARY(testDoubleImmToInt64BitwiseCast, doubleOperands());
+ RUN_UNARY(testTwoBitwiseCastOnDouble, doubleOperands());
+ RUN_UNARY(testBitwiseCastOnDoubleInMemory, doubleOperands());
+ RUN_UNARY(testInt64BArgToDoubleBitwiseCast, int64Operands());
+ RUN_UNARY(testInt64BImmToDoubleBitwiseCast, int64Operands());
+ RUN_UNARY(testTwoBitwiseCastOnInt64, int64Operands());
+ RUN_UNARY(testBitwiseCastOnInt64InMemory, int64Operands());
+
RUN(testStore(44));
RUN(testStoreConstant(49));
RUN(testStoreConstantPtr(49));
Modified: trunk/Source/_javascript_Core/ftl/FTLB3Output.h (192618 => 192619)
--- trunk/Source/_javascript_Core/ftl/FTLB3Output.h 2015-11-19 08:19:56 UTC (rev 192618)
+++ trunk/Source/_javascript_Core/ftl/FTLB3Output.h 2015-11-19 08:38:17 UTC (rev 192619)
@@ -189,7 +189,7 @@
LValue fpCast(LValue value, LType type) { CRASH(); }
LValue intToPtr(LValue value, LType type) { CRASH(); }
LValue ptrToInt(LValue value, LType type) { CRASH(); }
- LValue bitCast(LValue value, LType type) { CRASH(); }
+ LValue bitCast(LValue, LType);
LValue fround(LValue doubleValue) { CRASH(); }
@@ -412,6 +412,11 @@
addIncomingToPhi(phi, theRest...);
}
+inline LValue Output::bitCast(LValue value, LType type)
+{
+ ASSERT_UNUSED(type, type == int64 || type == doubleType);
+ return m_block->appendNew<B3::Value>(m_proc, B3::BitwiseCast, origin(), value);
+}
#if COMPILER(CLANG)
#pragma clang diagnostic pop