Commit b484cc12 authored by ahaas's avatar ahaas Committed by Commit bot

[wasm] Int64Lowering of I64ReinterpretF64.

The implementation is done by storing to and loading from memory.

R=titzer@chromium.org

Review URL: https://codereview.chromium.org/1804953002

Cr-Commit-Position: refs/heads/master@{#34784}
parent bb3cfeef
......@@ -444,7 +444,30 @@ void Int64Lowering::LowerNode(Node* node) {
}
// kExprF64ReinterpretI64:
// kExprI64ReinterpretF64:
case IrOpcode::kBitcastFloat64ToInt64: {
DCHECK(node->InputCount() == 1);
Node* input = node->InputAt(0);
Node* stack_slot = graph()->NewNode(
machine()->StackSlot(MachineRepresentation::kWord64));
Node* store = graph()->NewNode(
machine()->Store(
StoreRepresentation(MachineRepresentation::kFloat64,
WriteBarrierKind::kNoWriteBarrier)),
stack_slot, graph()->NewNode(common()->Int32Constant(0)), input,
graph()->start(), graph()->start());
Node* high_node =
graph()->NewNode(machine()->Load(MachineType::Int32()), stack_slot,
graph()->NewNode(common()->Int32Constant(4)), store,
graph()->start());
Node* low_node =
graph()->NewNode(machine()->Load(MachineType::Int32()), stack_slot,
graph()->NewNode(common()->Int32Constant(0)), store,
graph()->start());
ReplaceNode(node, low_node, high_node);
break;
}
// kExprI64Clz:
// kExprI64Ctz:
case IrOpcode::kWord64Popcnt: {
......
......@@ -831,6 +831,9 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) {
break;
// kExprF64ReinterpretI64:
// kExprI64ReinterpretF64:
case wasm::kExprI64ReinterpretF64:
op = m->BitcastFloat64ToInt64();
break;
// kExprI64Clz:
// kExprI64Ctz:
// kExprI64Popcnt:
......@@ -897,9 +900,6 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) {
case wasm::kExprF64ReinterpretI64:
op = m->BitcastInt64ToFloat64();
break;
case wasm::kExprI64ReinterpretF64:
op = m->BitcastFloat64ToInt64();
break;
case wasm::kExprI64Clz:
op = m->Word64Clz();
break;
......
......@@ -83,7 +83,7 @@
V(F64SConvertI64, true) \
V(F64UConvertI64, true) \
V(F64ReinterpretI64, false) \
V(I64ReinterpretF64, false) \
V(I64ReinterpretF64, true) \
V(I64Ror, false) \
V(I64Rol, false)
......@@ -1184,8 +1184,8 @@ TEST(Run_Wasm_I64UConvertF64b) {
}
}
TEST(Run_Wasm_F64ReinterpretI64) {
REQUIRE(F64ReinterpretI64);
TEST(Run_Wasm_I64ReinterpretF64) {
REQUIRE(I64ReinterpretF64);
TestingModule module;
int64_t* memory = module.AddMemoryElems<int64_t>(8);
WasmRunner<int64_t> r(&module);
......@@ -1200,8 +1200,8 @@ TEST(Run_Wasm_F64ReinterpretI64) {
}
}
TEST(Run_Wasm_I64ReinterpretF64) {
REQUIRE(I64ReinterpretF64);
TEST(Run_Wasm_F64ReinterpretI64) {
REQUIRE(F64ReinterpretI64);
TestingModule module;
int64_t* memory = module.AddMemoryElems<int64_t>(8);
WasmRunner<int64_t> r(&module, MachineType::Int64());
......
......@@ -492,7 +492,34 @@ TEST_F(Int64LoweringTest, I64UConvertI32_2) {
}
// kExprF64ReinterpretI64:
// kExprI64ReinterpretF64:
TEST_F(Int64LoweringTest, I64ReinterpretF64) {
LowerGraph(graph()->NewNode(machine()->BitcastFloat64ToInt64(),
Float64Constant(bit_cast<double>(value(0)))),
MachineRepresentation::kWord64);
Capture<Node*> stack_slot;
Matcher<Node*> stack_slot_matcher =
IsStackSlot(MachineRepresentation::kWord64);
Capture<Node*> store;
Matcher<Node*> store_matcher = IsStore(
StoreRepresentation(MachineRepresentation::kFloat64,
WriteBarrierKind::kNoWriteBarrier),
AllOf(CaptureEq(&stack_slot), stack_slot_matcher), IsInt32Constant(0),
IsFloat64Constant(bit_cast<double>(value(0))), start(), start());
EXPECT_THAT(
graph()->end()->InputAt(1),
IsReturn2(IsLoad(MachineType::Int32(),
AllOf(CaptureEq(&stack_slot), stack_slot_matcher),
IsInt32Constant(0),
AllOf(CaptureEq(&store), store_matcher), start()),
IsLoad(MachineType::Int32(),
AllOf(CaptureEq(&stack_slot), stack_slot_matcher),
IsInt32Constant(0x4),
AllOf(CaptureEq(&store), store_matcher), start()),
start(), start()));
}
// kExprI64Clz:
// kExprI64Ctz:
// kExprI64Popcnt:
......
......@@ -1330,6 +1330,27 @@ class IsStoreMatcher final : public NodeMatcher {
const Matcher<Node*> control_matcher_;
};
class IsStackSlotMatcher final : public NodeMatcher {
public:
explicit IsStackSlotMatcher(const Matcher<MachineRepresentation>& rep_matcher)
: NodeMatcher(IrOpcode::kStackSlot), rep_matcher_(rep_matcher) {}
void DescribeTo(std::ostream* os) const final {
NodeMatcher::DescribeTo(os);
*os << " whose rep (";
rep_matcher_.DescribeTo(os);
*os << ")";
}
bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
return (NodeMatcher::MatchAndExplain(node, listener) &&
PrintMatchAndExplain(OpParameter<MachineRepresentation>(node),
"rep", rep_matcher_, listener));
}
private:
const Matcher<MachineRepresentation> rep_matcher_;
};
class IsToNumberMatcher final : public NodeMatcher {
public:
......@@ -2123,6 +2144,9 @@ Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher,
effect_matcher, control_matcher));
}
Matcher<Node*> IsStackSlot(const Matcher<MachineRepresentation>& rep_matcher) {
return MakeMatcher(new IsStackSlotMatcher(rep_matcher));
}
Matcher<Node*> IsToNumber(const Matcher<Node*>& base_matcher,
const Matcher<Node*>& context_matcher,
......
......@@ -261,6 +261,7 @@ Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher,
const Matcher<Node*>& value_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher);
Matcher<Node*> IsStackSlot(const Matcher<MachineRepresentation>& rep_matcher);
Matcher<Node*> IsWord32And(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsWord32Or(const Matcher<Node*>& lhs_matcher,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment