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

[wasm] Added I64Ior to the Int64Lowering.

R=titzer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#34219}
parent af903021
......@@ -167,27 +167,6 @@ void Int64Lowering::LowerNode(Node* node) {
}
break;
}
case IrOpcode::kWord64And: {
DCHECK(node->InputCount() == 2);
Node* left = node->InputAt(0);
Node* right = node->InputAt(1);
Node* low_node =
graph()->NewNode(machine()->Word32And(), GetReplacementLow(left),
GetReplacementLow(right));
Node* high_node =
graph()->NewNode(machine()->Word32And(), GetReplacementHigh(left),
GetReplacementHigh(right));
ReplaceNode(node, low_node, high_node);
break;
}
case IrOpcode::kTruncateInt64ToInt32: {
DCHECK(node->InputCount() == 1);
Node* input = node->InputAt(0);
ReplaceNode(node, GetReplacementLow(input), nullptr);
node->NullAllInputs();
break;
}
case IrOpcode::kStart: {
int parameter_count = GetParameterCountAfterLowering(signature());
// Only exchange the node if the parameter count actually changed.
......@@ -248,6 +227,85 @@ void Int64Lowering::LowerNode(Node* node) {
}
break;
}
case IrOpcode::kWord64And: {
DCHECK(node->InputCount() == 2);
Node* left = node->InputAt(0);
Node* right = node->InputAt(1);
Node* low_node =
graph()->NewNode(machine()->Word32And(), GetReplacementLow(left),
GetReplacementLow(right));
Node* high_node =
graph()->NewNode(machine()->Word32And(), GetReplacementHigh(left),
GetReplacementHigh(right));
ReplaceNode(node, low_node, high_node);
break;
}
case IrOpcode::kTruncateInt64ToInt32: {
DCHECK(node->InputCount() == 1);
Node* input = node->InputAt(0);
ReplaceNode(node, GetReplacementLow(input), nullptr);
node->NullAllInputs();
break;
}
// todo(ahaas): I added a list of missing instructions here to make merging
// easier when I do them one by one.
// kExprI64Add:
// kExprI64Sub:
// kExprI64Mul:
// kExprI64DivS:
// kExprI64DivU:
// kExprI64RemS:
// kExprI64RemU:
// kExprI64Ior:
case IrOpcode::kWord64Or: {
DCHECK(node->InputCount() == 2);
Node* left = node->InputAt(0);
Node* right = node->InputAt(1);
Node* low_node =
graph()->NewNode(machine()->Word32Or(), GetReplacementLow(left),
GetReplacementLow(right));
Node* high_node =
graph()->NewNode(machine()->Word32Or(), GetReplacementHigh(left),
GetReplacementHigh(right));
ReplaceNode(node, low_node, high_node);
break;
}
// kExprI64Xor:
// kExprI64Shl:
// kExprI64ShrU:
// kExprI64ShrS:
// kExprI64Eq:
// kExprI64Ne:
// kExprI64LtS:
// kExprI64LeS:
// kExprI64LtU:
// kExprI64LeU:
// kExprI64GtS:
// kExprI64GeS:
// kExprI64GtU:
// kExprI64GeU:
// kExprI64SConvertI32:
// kExprI64UConvertI32:
// kExprF64ReinterpretI64:
// kExprI64ReinterpretF64:
// kExprI64Clz:
// kExprI64Ctz:
// kExprI64Popcnt:
// kExprF32SConvertI64:
// kExprF32UConvertI64:
// kExprF64SConvertI64:
// kExprF64UConvertI64:
// kExprI64SConvertF32:
// kExprI64SConvertF64:
// kExprI64UConvertF32:
// kExprI64UConvertF64:
default: { DefaultLowering(node); }
}
}
......
......@@ -485,6 +485,54 @@ Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left,
case wasm::kExprI64And:
op = m->Word64And();
break;
// todo(ahaas): I added a list of missing instructions here to make merging
// easier when I do them one by one.
// kExprI64Add:
// kExprI64Sub:
// kExprI64Mul:
// kExprI64DivS:
// kExprI64DivU:
// kExprI64RemS:
// kExprI64RemU:
// kExprI64And:
// kExprI64Ior:
case wasm::kExprI64Ior:
op = m->Word64Or();
break;
// kExprI64Xor:
// kExprI64Shl:
// kExprI64ShrU:
// kExprI64ShrS:
// kExprI64Eq:
// kExprI64Ne:
// kExprI64LtS:
// kExprI64LeS:
// kExprI64LtU:
// kExprI64LeU:
// kExprI64GtS:
// kExprI64GeS:
// kExprI64GtU:
// kExprI64GeU:
// kExprI32ConvertI64:
// kExprI64SConvertI32:
// kExprI64UConvertI32:
// kExprF64ReinterpretI64:
// kExprI64ReinterpretF64:
// kExprI64Clz:
// kExprI64Ctz:
// kExprI64Popcnt:
// kExprF32SConvertI64:
// kExprF32UConvertI64:
// kExprF64SConvertI64:
// kExprF64UConvertI64:
// kExprI64SConvertF32:
// kExprI64SConvertF64:
// kExprI64UConvertF32:
// kExprI64UConvertF64:
#if WASM_64
// Opcodes only supported on 64-bit platforms.
// TODO(titzer): query the machine operator builder here instead of #ifdef.
......@@ -535,9 +583,6 @@ Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left,
op = m->Uint64Mod();
return graph()->NewNode(op, left, right,
trap_->ZeroCheck64(kTrapRemByZero, right));
case wasm::kExprI64Ior:
op = m->Word64Or();
break;
case wasm::kExprI64Xor:
op = m->Word64Xor();
break;
......
......@@ -188,6 +188,7 @@
'test-weaksets.cc',
'trace-extension.cc',
'wasm/test-run-wasm.cc',
'wasm/test-run-wasm-64.cc',
'wasm/test-run-wasm-js.cc',
'wasm/test-run-wasm-module.cc',
'wasm/test-signatures.h',
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "src/wasm/wasm-macro-gen.h"
#include "test/cctest/cctest.h"
#include "test/cctest/compiler/value-helper.h"
#include "test/cctest/wasm/wasm-run-utils.h"
// using namespace v8::base;
// using namespace v8::internal;
// using namespace v8::internal::compiler;
// using namespace v8::internal::wasm;
// todo(ahaas): I added a list of missing instructions here to make merging
// easier when I do them one by one.
// kExprI64Add:
// kExprI64Sub:
// kExprI64Mul:
// kExprI64DivS:
// kExprI64DivU:
// kExprI64RemS:
// kExprI64RemU:
// kExprI64And:
TEST(Run_WasmI64And) {
WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
BUILD(r, WASM_I64_AND(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) { CHECK_EQ((*i) & (*j), r.Call(*i, *j)); }
}
}
// kExprI64Ior:
TEST(Run_WasmI64Ior) {
WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
BUILD(r, WASM_I64_IOR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) { CHECK_EQ((*i) | (*j), r.Call(*i, *j)); }
}
}
// kExprI64Xor:
// kExprI64Shl:
// kExprI64ShrU:
// kExprI64ShrS:
// kExprI64Eq:
// kExprI64Ne:
// kExprI64LtS:
// kExprI64LeS:
// kExprI64LtU:
// kExprI64LeU:
// kExprI64GtS:
// kExprI64GeS:
// kExprI64GtU:
// kExprI64GeU:
// kExprI32ConvertI64:
TEST(Run_WasmI32ConvertI64) {
FOR_INT64_INPUTS(i) {
WasmRunner<int32_t> r;
BUILD(r, WASM_I32_CONVERT_I64(WASM_I64(*i)));
CHECK_EQ(static_cast<int32_t>(*i), r.Call());
}
}
// kExprI64SConvertI32:
// kExprI64UConvertI32:
// kExprF64ReinterpretI64:
// kExprI64ReinterpretF64:
// kExprI64Clz:
// kExprI64Ctz:
// kExprI64Popcnt:
// kExprF32SConvertI64:
// kExprF32UConvertI64:
// kExprF64SConvertI64:
// kExprF64UConvertI64:
// kExprI64SConvertF32:
// kExprI64SConvertF64:
// kExprI64UConvertF32:
// kExprI64UConvertF64:
TEST(Run_WasmCallI64Parameter) {
// Build the target function.
LocalType param_types[20];
for (int i = 0; i < 20; i++) param_types[i] = kAstI64;
param_types[3] = kAstI32;
param_types[4] = kAstI32;
FunctionSig sig(1, 19, param_types);
for (int i = 0; i < 19; i++) {
TestingModule module;
WasmFunctionCompiler t(&sig, &module);
if (i == 2 || i == 3) {
continue;
} else {
BUILD(t, WASM_GET_LOCAL(i));
}
uint32_t index = t.CompileAndAdd();
// Build the calling function.
WasmRunner<int32_t> r;
r.env()->module = &module;
BUILD(r,
WASM_I32_CONVERT_I64(WASM_CALL_FUNCTION(
index, WASM_I64(0xbcd12340000000b), WASM_I64(0xbcd12340000000c),
WASM_I32(0xd), WASM_I32_CONVERT_I64(WASM_I64(0xbcd12340000000e)),
WASM_I64(0xbcd12340000000f), WASM_I64(0xbcd1234000000010),
WASM_I64(0xbcd1234000000011), WASM_I64(0xbcd1234000000012),
WASM_I64(0xbcd1234000000013), WASM_I64(0xbcd1234000000014),
WASM_I64(0xbcd1234000000015), WASM_I64(0xbcd1234000000016),
WASM_I64(0xbcd1234000000017), WASM_I64(0xbcd1234000000018),
WASM_I64(0xbcd1234000000019), WASM_I64(0xbcd123400000001a),
WASM_I64(0xbcd123400000001b), WASM_I64(0xbcd123400000001c),
WASM_I64(0xbcd123400000001d))));
CHECK_EQ(i + 0xb, r.Call());
}
}
......@@ -18,13 +18,6 @@ using namespace v8::internal;
using namespace v8::internal::compiler;
using namespace v8::internal::wasm;
#define BUILD(r, ...) \
do { \
byte code[] = {__VA_ARGS__}; \
r.Build(code, code + arraysize(code)); \
} while (false)
TEST(Run_WasmInt8Const) {
WasmRunner<int32_t> r;
const byte kExpectedValue = 121;
......@@ -115,23 +108,6 @@ TEST(Run_WasmInt64Const_many) {
}
#endif
TEST(Run_WasmI32ConvertI64) {
FOR_INT64_INPUTS(i) {
WasmRunner<int32_t> r;
BUILD(r, WASM_I32_CONVERT_I64(WASM_I64(*i)));
CHECK_EQ(static_cast<int32_t>(*i), r.Call());
}
}
TEST(Run_WasmI64AndConstants) {
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) {
WasmRunner<int32_t> r;
BUILD(r, WASM_I32_CONVERT_I64(WASM_I64_AND(WASM_I64(*i), WASM_I64(*j))));
CHECK_EQ(static_cast<int32_t>(*i & *j), r.Call());
}
}
}
TEST(Run_WasmInt32Param0) {
WasmRunner<int32_t> r(MachineType::Int32());
......@@ -2436,51 +2412,6 @@ TEST(Run_WasmCallF64StackParameter) {
CHECK_EQ(256.5, result);
}
TEST(Run_WasmCallI64Parameter) {
// Build the target function.
LocalType param_types[20];
for (int i = 0; i < 20; i++) param_types[i] = kAstI64;
param_types[3] = kAstI32;
param_types[4] = kAstI32;
FunctionSig sig(1, 19, param_types);
for (int i = 0; i < 19; i++) {
TestingModule module;
WasmFunctionCompiler t(&sig, &module);
if (i == 2 || i == 3) {
continue;
} else {
BUILD(t, WASM_GET_LOCAL(i));
}
uint32_t index = t.CompileAndAdd();
// Build the calling function.
WasmRunner<int32_t> r;
r.env()->module = &module;
BUILD(r,
WASM_I32_CONVERT_I64(WASM_CALL_FUNCTION(
index, WASM_I64(0xbcd12340000000b), WASM_I64(0xbcd12340000000c),
WASM_I32(0xd), WASM_I32_CONVERT_I64(WASM_I64(0xbcd12340000000e)),
WASM_I64(0xbcd12340000000f), WASM_I64(0xbcd1234000000010),
WASM_I64(0xbcd1234000000011), WASM_I64(0xbcd1234000000012),
WASM_I64(0xbcd1234000000013), WASM_I64(0xbcd1234000000014),
WASM_I64(0xbcd1234000000015), WASM_I64(0xbcd1234000000016),
WASM_I64(0xbcd1234000000017), WASM_I64(0xbcd1234000000018),
WASM_I64(0xbcd1234000000019), WASM_I64(0xbcd123400000001a),
WASM_I64(0xbcd123400000001b), WASM_I64(0xbcd123400000001c),
WASM_I64(0xbcd123400000001d))));
CHECK_EQ(i + 0xb, r.Call());
}
}
TEST(Run_WasmI64And) {
WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64());
BUILD(r, WASM_I64_AND(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) { CHECK_EQ((*i) & (*j), r.Call(*i, *j)); }
}
}
TEST(Run_WasmCallVoid) {
const byte kMemOffset = 8;
const int32_t kElemNum = kMemOffset / sizeof(int32_t);
......@@ -2527,7 +2458,6 @@ TEST(Run_WasmCall_Int32Add) {
}
}
#if WASM_64
TEST(Run_WasmCall_Int64Sub) {
// Build the target function.
......
......@@ -51,6 +51,12 @@ static const uint32_t kMaxFunctions = 10;
#define WASM_RUNNER_MAX_NUM_PARAMETERS 4
#define WASM_WRAPPER_RETURN_VALUE 8754
#define BUILD(r, ...) \
do { \
byte code[] = {__VA_ARGS__}; \
r.Build(code, code + arraysize(code)); \
} while (false)
namespace {
using namespace v8::base;
using namespace v8::internal;
......
......@@ -294,6 +294,66 @@ TEST_F(Int64LoweringTest, CallI64Parameter) {
wasm::ModuleEnv::GetI32WasmCallDescriptor(zone(), desc));
}
// todo(ahaas): I added a list of missing instructions here to make merging
// easier when I do them one by one.
// kExprI64Add:
// kExprI64Sub:
// kExprI64Mul:
// kExprI64DivS:
// kExprI64DivU:
// kExprI64RemS:
// kExprI64RemU:
// kExprI64And:
// kExprI64Ior:
TEST_F(Int64LoweringTest, Int64Ior) {
if (4 != kPointerSize) return;
LowerGraph(graph()->NewNode(machine()->Word64Or(), Int64Constant(value(0)),
Int64Constant(value(1))),
MachineRepresentation::kWord64);
EXPECT_THAT(graph()->end()->InputAt(1),
IsReturn2(IsWord32Or(IsInt32Constant(low_word_value(0)),
IsInt32Constant(low_word_value(1))),
IsWord32Or(IsInt32Constant(high_word_value(0)),
IsInt32Constant(high_word_value(1))),
start(), start()));
}
// kExprI64Xor:
// kExprI64Shl:
// kExprI64ShrU:
// kExprI64ShrS:
// kExprI64Eq:
// kExprI64Ne:
// kExprI64LtS:
// kExprI64LeS:
// kExprI64LtU:
// kExprI64LeU:
// kExprI64GtS:
// kExprI64GeS:
// kExprI64GtU:
// kExprI64GeU:
// kExprI32ConvertI64:
// kExprI64SConvertI32:
// kExprI64UConvertI32:
// kExprF64ReinterpretI64:
// kExprI64ReinterpretF64:
// kExprI64Clz:
// kExprI64Ctz:
// kExprI64Popcnt:
// kExprF32SConvertI64:
// kExprF32UConvertI64:
// kExprF64SConvertI64:
// kExprF64UConvertI64:
// kExprI64SConvertF32:
// kExprI64SConvertF64:
// kExprI64UConvertF32:
// kExprI64UConvertF64:
} // namespace compiler
} // namespace internal
} // namespace v8
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