Commit 0dffd972 authored by Deepti Gandluri's avatar Deepti Gandluri Committed by Commit Bot

[wasm] Use the right access operand for atomic ops

Bug=v8:6842,v8:6532

Change-Id: I6ae1064e1e9a54c189311d6f34fc5fad85f13b7f
Reviewed-on: https://chromium-review.googlesource.com/678594
Commit-Queue: Deepti Gandluri <gdeepti@chromium.org>
Reviewed-by: 's avatarBill Budge <bbudge@chromium.org>
Reviewed-by: 's avatarBen Smith <binji@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48127}
parent 79ac69b8
......@@ -3825,6 +3825,7 @@ Node* WasmGraphBuilder::Simd8x16ShuffleOp(const uint8_t shuffle[16],
V(I32AtomicCompareExchange16U, CompareExchange, Uint16)
Node* WasmGraphBuilder::AtomicOp(wasm::WasmOpcode opcode, Node* const* inputs,
uint32_t alignment, uint32_t offset,
wasm::WasmCodePosition position) {
Node* node;
switch (opcode) {
......
......@@ -328,6 +328,7 @@ class WasmGraphBuilder {
Node* Simd8x16ShuffleOp(const uint8_t shuffle[16], Node* const* inputs);
Node* AtomicOp(wasm::WasmOpcode opcode, Node* const* inputs,
uint32_t alignment, uint32_t offset,
wasm::WasmCodePosition position);
bool has_simd() const { return has_simd_; }
......
......@@ -50,6 +50,29 @@ struct WasmException;
(this->errorf(this->pc_, "%s: %s", WasmOpcodes::OpcodeName(opcode), \
(message)))
#define ATOMIC_OP_LIST(V) \
V(I32AtomicAdd, Uint32) \
V(I32AtomicSub, Uint32) \
V(I32AtomicAnd, Uint32) \
V(I32AtomicOr, Uint32) \
V(I32AtomicXor, Uint32) \
V(I32AtomicExchange, Uint32) \
V(I32AtomicAdd8U, Uint8) \
V(I32AtomicSub8U, Uint8) \
V(I32AtomicAnd8U, Uint8) \
V(I32AtomicOr8U, Uint8) \
V(I32AtomicXor8U, Uint8) \
V(I32AtomicExchange8U, Uint8) \
V(I32AtomicAdd16U, Uint16) \
V(I32AtomicSub16U, Uint16) \
V(I32AtomicAnd16U, Uint16) \
V(I32AtomicOr16U, Uint16) \
V(I32AtomicXor16U, Uint16) \
V(I32AtomicExchange16U, Uint16) \
V(I32AtomicCompareExchange, Uint32) \
V(I32AtomicCompareExchange8U, Uint8) \
V(I32AtomicCompareExchange16U, Uint16)
template <typename T>
Vector<T> vec2vec(std::vector<T>& vec) {
return Vector<T>(vec.data(), vec.size());
......@@ -541,7 +564,8 @@ struct ControlWithNamedConstructors : public ControlBase<Value> {
const Value& input0, const Value& input1, Value* result) \
F(Throw, const ExceptionIndexOperand<validate>&) \
F(Catch, const ExceptionIndexOperand<validate>& operand, Control* block) \
F(AtomicOp, WasmOpcode opcode, Vector<Value> args, Value* result)
F(AtomicOp, WasmOpcode opcode, Vector<Value> args, \
const MemoryAccessOperand<validate>& operand, Value* result)
// Generic Wasm bytecode decoder with utilities for decoding operands,
// lengths, etc.
......@@ -1658,7 +1682,17 @@ class WasmFullDecoder : public WasmDecoder<validate> {
opcode = static_cast<WasmOpcode>(opcode << 8 | atomic_index);
TRACE(" @%-4d #%-20s|", startrel(this->pc_),
WasmOpcodes::OpcodeName(opcode));
len += DecodeAtomicOpcode(opcode);
switch (opcode) {
#define DECODE_ATOMIC_BINOP(Name, Type) \
case kExpr##Name: { \
len += DecodeAtomicOpcode(opcode, MachineType::Type()); \
break; \
}
ATOMIC_OP_LIST(DECODE_ATOMIC_BINOP)
#undef DECODE_ATOMIC_BINOP
default:
this->error("Invalid opcode");
}
break;
}
default: {
......@@ -1947,17 +1981,20 @@ class WasmFullDecoder : public WasmDecoder<validate> {
return len;
}
unsigned DecodeAtomicOpcode(WasmOpcode opcode) {
unsigned DecodeAtomicOpcode(WasmOpcode opcode, MachineType mem_type) {
unsigned len = 0;
FunctionSig* sig = WasmOpcodes::AtomicSignature(opcode);
if (sig != nullptr) {
// TODO(clemensh): Better memory management here.
std::vector<Value> args(sig->parameter_count());
MemoryAccessOperand<validate> operand(
this, this->pc_ + 1, ElementSizeLog2Of(mem_type.representation()));
len += operand.length;
for (int i = static_cast<int>(sig->parameter_count() - 1); i >= 0; --i) {
args[i] = Pop(i, sig->GetParam(i));
}
auto* result = Push(GetReturnType(sig));
interface_.AtomicOp(this, opcode, vec2vec(args), result);
interface_.AtomicOp(this, opcode, vec2vec(args), operand, result);
} else {
this->error("invalid atomic opcode");
}
......
......@@ -407,9 +407,10 @@ class WasmGraphBuildingInterface {
}
void AtomicOp(Decoder* decoder, WasmOpcode opcode, Vector<Value> args,
Value* result) {
const MemoryAccessOperand<true>& operand, Value* result) {
TFNode** inputs = GetNodes(args);
TFNode* node = BUILD(AtomicOp, opcode, inputs, decoder->position());
TFNode* node = BUILD(AtomicOp, opcode, inputs, operand.alignment,
operand.offset, decoder->position());
if (result) result->node = node;
}
......
......@@ -13,8 +13,12 @@ namespace internal {
namespace wasm {
#define WASM_ATOMICS_OP(op) kAtomicPrefix, static_cast<byte>(op)
#define WASM_ATOMICS_BINOP(op, x, y) x, y, WASM_ATOMICS_OP(op)
#define WASM_ATOMICS_TERNARY_OP(op, x, y, z) x, y, z, WASM_ATOMICS_OP(op)
#define WASM_ATOMICS_BINOP(op, x, y, representation) \
x, y, WASM_ATOMICS_OP(op), \
static_cast<byte>(ElementSizeLog2Of(representation)), ZERO_OFFSET
#define WASM_ATOMICS_TERNARY_OP(op, x, y, z, representation) \
x, y, z, WASM_ATOMICS_OP(op), \
static_cast<byte>(ElementSizeLog2Of(representation)), ZERO_OFFSET
typedef uint32_t (*Uint32BinOp)(uint32_t, uint32_t);
typedef uint16_t (*Uint16BinOp)(uint16_t, uint16_t);
......@@ -62,7 +66,8 @@ void RunU32BinOp(WasmOpcode wasm_op, Uint32BinOp expected_op) {
uint32_t* memory = r.builder().AddMemoryElems<uint32_t>(8);
r.builder().SetHasSharedMemory();
BUILD(r, WASM_ATOMICS_BINOP(wasm_op, WASM_I32V_1(0), WASM_GET_LOCAL(0)));
BUILD(r, WASM_ATOMICS_BINOP(wasm_op, WASM_I32V_1(0), WASM_GET_LOCAL(0),
MachineRepresentation::kWord32));
FOR_UINT32_INPUTS(i) {
uint32_t initial = *i;
......@@ -88,7 +93,8 @@ void RunU16BinOp(WasmOpcode wasm_op, Uint16BinOp expected_op) {
r.builder().SetHasSharedMemory();
uint16_t* memory = r.builder().AddMemoryElems<uint16_t>(8);
BUILD(r, WASM_ATOMICS_BINOP(wasm_op, WASM_I32V_1(0), WASM_GET_LOCAL(0)));
BUILD(r, WASM_ATOMICS_BINOP(wasm_op, WASM_I32V_1(0), WASM_GET_LOCAL(0),
MachineRepresentation::kWord16));
FOR_UINT16_INPUTS(i) {
uint16_t initial = *i;
......@@ -114,7 +120,8 @@ void RunU8BinOp(WasmOpcode wasm_op, Uint8BinOp expected_op) {
r.builder().SetHasSharedMemory();
uint8_t* memory = r.builder().AddMemoryElems<uint8_t>(8);
BUILD(r, WASM_ATOMICS_BINOP(wasm_op, WASM_I32V_1(0), WASM_GET_LOCAL(0)));
BUILD(r, WASM_ATOMICS_BINOP(wasm_op, WASM_I32V_1(0), WASM_GET_LOCAL(0),
MachineRepresentation::kWord8));
FOR_UINT8_INPUTS(i) {
uint8_t initial = *i;
......@@ -139,9 +146,9 @@ TEST(I32AtomicCompareExchange) {
WasmRunner<uint32_t, uint32_t, uint32_t> r(kExecuteCompiled);
r.builder().SetHasSharedMemory();
uint32_t* memory = r.builder().AddMemoryElems<uint32_t>(8);
BUILD(r,
WASM_ATOMICS_TERNARY_OP(kExprI32AtomicCompareExchange, WASM_I32V_1(0),
WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
BUILD(r, WASM_ATOMICS_TERNARY_OP(
kExprI32AtomicCompareExchange, WASM_I32V_1(0), WASM_GET_LOCAL(0),
WASM_GET_LOCAL(1), MachineRepresentation::kWord32));
FOR_UINT32_INPUTS(i) {
uint32_t initial = *i;
......@@ -161,7 +168,8 @@ TEST(I32AtomicCompareExchange16U) {
uint16_t* memory = r.builder().AddMemoryElems<uint16_t>(8);
BUILD(r, WASM_ATOMICS_TERNARY_OP(kExprI32AtomicCompareExchange16U,
WASM_I32V_1(0), WASM_GET_LOCAL(0),
WASM_GET_LOCAL(1)));
WASM_GET_LOCAL(1),
MachineRepresentation::kWord16));
FOR_UINT16_INPUTS(i) {
uint16_t initial = *i;
......@@ -181,7 +189,8 @@ TEST(I32AtomicCompareExchange8U) {
uint8_t* memory = r.builder().AddMemoryElems<uint8_t>(8);
BUILD(r,
WASM_ATOMICS_TERNARY_OP(kExprI32AtomicCompareExchange8U, WASM_I32V_1(0),
WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
MachineRepresentation::kWord8));
FOR_UINT8_INPUTS(i) {
uint8_t initial = *i;
......
......@@ -21,7 +21,7 @@ function Exchange(a, b) { return b; }
let maxSize = 10;
let memory = new WebAssembly.Memory({initial: 1, maximum: maxSize, shared: true});
function GetAtomicBinOpFunction(wasmExpression) {
function GetAtomicBinOpFunction(wasmExpression, alignment, offset) {
let builder = new WasmModuleBuilder();
builder.addImportedMemory("m", "imported_mem", 0, maxSize, "shared");
builder.addFunction("main", kSig_i_ii)
......@@ -29,7 +29,7 @@ function GetAtomicBinOpFunction(wasmExpression) {
kExprGetLocal, 0,
kExprGetLocal, 1,
kAtomicPrefix,
wasmExpression])
wasmExpression, alignment, offset])
.exportAs("main");
// Instantiate module, get function exports
......@@ -39,7 +39,7 @@ function GetAtomicBinOpFunction(wasmExpression) {
return instance.exports.main;
}
function GetAtomicCmpExchangeFunction(wasmExpression) {
function GetAtomicCmpExchangeFunction(wasmExpression, alignment, offset) {
let builder = new WasmModuleBuilder();
builder.addImportedMemory("m", "imported_mem", 0, maxSize, "shared");
builder.addFunction("main", kSig_i_iii)
......@@ -48,7 +48,7 @@ function GetAtomicCmpExchangeFunction(wasmExpression) {
kExprGetLocal, 1,
kExprGetLocal, 2,
kAtomicPrefix,
wasmExpression])
wasmExpression, alignment, offset])
.exportAs("main");
// Instantiate module, get function exports
......@@ -108,109 +108,109 @@ function Test8Op(operation, func) {
(function TestAtomicAdd() {
print("TestAtomicAdd");
let wasmAdd = GetAtomicBinOpFunction(kExprI32AtomicAdd);
let wasmAdd = GetAtomicBinOpFunction(kExprI32AtomicAdd, 2, 0);
Test32Op(Add, wasmAdd);
})();
(function TestAtomicAdd16U() {
print("TestAtomicAdd16U");
let wasmAdd = GetAtomicBinOpFunction(kExprI32AtomicAdd16U);
let wasmAdd = GetAtomicBinOpFunction(kExprI32AtomicAdd16U, 1, 0);
Test16Op(Add, wasmAdd);
})();
(function TestAtomicAdd8U() {
print("TestAtomicAdd8U");
let wasmAdd = GetAtomicBinOpFunction(kExprI32AtomicAdd8U);
let wasmAdd = GetAtomicBinOpFunction(kExprI32AtomicAdd8U, 0, 0);
Test8Op(Add, wasmAdd);
})();
(function TestAtomicSub() {
print("TestAtomicSub");
let wasmSub = GetAtomicBinOpFunction(kExprI32AtomicSub);
let wasmSub = GetAtomicBinOpFunction(kExprI32AtomicSub, 2, 0);
Test32Op(Sub, wasmSub);
})();
(function TestAtomicSub16U() {
print("TestAtomicSub16U");
let wasmSub = GetAtomicBinOpFunction(kExprI32AtomicSub16U);
let wasmSub = GetAtomicBinOpFunction(kExprI32AtomicSub16U, 1, 0);
Test16Op(Sub, wasmSub);
})();
(function TestAtomicSub8U() {
print("TestAtomicSub8U");
let wasmSub = GetAtomicBinOpFunction(kExprI32AtomicSub8U);
let wasmSub = GetAtomicBinOpFunction(kExprI32AtomicSub8U, 0, 0);
Test8Op(Sub, wasmSub);
})();
(function TestAtomicAnd() {
print("TestAtomicAnd");
let wasmAnd = GetAtomicBinOpFunction(kExprI32AtomicAnd);
let wasmAnd = GetAtomicBinOpFunction(kExprI32AtomicAnd, 2, 0);
Test32Op(And, wasmAnd);
})();
(function TestAtomicAnd16U() {
print("TestAtomicAnd16U");
let wasmAnd = GetAtomicBinOpFunction(kExprI32AtomicAnd16U);
let wasmAnd = GetAtomicBinOpFunction(kExprI32AtomicAnd16U, 1, 0);
Test16Op(And, wasmAnd);
})();
(function TestAtomicAnd8U() {
print("TestAtomicAnd8U");
let wasmAnd = GetAtomicBinOpFunction(kExprI32AtomicAnd8U);
let wasmAnd = GetAtomicBinOpFunction(kExprI32AtomicAnd8U, 0, 0);
Test8Op(And, wasmAnd);
})();
(function TestAtomicOr() {
print("TestAtomicOr");
let wasmOr = GetAtomicBinOpFunction(kExprI32AtomicOr);
let wasmOr = GetAtomicBinOpFunction(kExprI32AtomicOr, 2, 0);
Test32Op(Or, wasmOr);
})();
(function TestAtomicOr16U() {
print("TestAtomicOr16U");
let wasmOr = GetAtomicBinOpFunction(kExprI32AtomicOr16U);
let wasmOr = GetAtomicBinOpFunction(kExprI32AtomicOr16U, 1, 0);
Test16Op(Or, wasmOr);
})();
(function TestAtomicOr8U() {
print("TestAtomicOr8U");
let wasmOr = GetAtomicBinOpFunction(kExprI32AtomicOr8U);
let wasmOr = GetAtomicBinOpFunction(kExprI32AtomicOr8U, 0, 0);
Test8Op(Or, wasmOr);
})();
(function TestAtomicXor() {
print("TestAtomicXor");
let wasmXor = GetAtomicBinOpFunction(kExprI32AtomicXor);
let wasmXor = GetAtomicBinOpFunction(kExprI32AtomicXor, 2, 0);
Test32Op(Xor, wasmXor);
})();
(function TestAtomicXor16U() {
print("TestAtomicXor16U");
let wasmXor = GetAtomicBinOpFunction(kExprI32AtomicXor16U);
let wasmXor = GetAtomicBinOpFunction(kExprI32AtomicXor16U, 1, 0);
Test16Op(Xor, wasmXor);
})();
(function TestAtomicXor8U() {
print("TestAtomicXor8U");
let wasmXor = GetAtomicBinOpFunction(kExprI32AtomicXor8U);
let wasmXor = GetAtomicBinOpFunction(kExprI32AtomicXor8U, 0, 0);
Test8Op(Xor, wasmXor);
})();
(function TestAtomicExchange() {
print("TestAtomicExchange");
let wasmExchange = GetAtomicBinOpFunction(kExprI32AtomicExchange);
let wasmExchange = GetAtomicBinOpFunction(kExprI32AtomicExchange, 2, 0);
Test32Op(Exchange, wasmExchange);
})();
(function TestAtomicExchange16U() {
print("TestAtomicExchange16U");
let wasmExchange = GetAtomicBinOpFunction(kExprI32AtomicExchange16U);
let wasmExchange = GetAtomicBinOpFunction(kExprI32AtomicExchange16U, 1, 0);
Test16Op(Exchange, wasmExchange);
})();
(function TestAtomicExchange8U() {
print("TestAtomicExchange8U");
let wasmExchange = GetAtomicBinOpFunction(kExprI32AtomicExchange8U);
let wasmExchange = GetAtomicBinOpFunction(kExprI32AtomicExchange8U, 0, 0);
Test8Op(Exchange, wasmExchange);
})();
......@@ -232,7 +232,7 @@ function TestCmpExchange(func, buffer, params, size) {
(function TestAtomicCompareExchange() {
print("TestAtomicCompareExchange");
let wasmCmpExchange =
GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange);
GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange, 2, 0);
let i32 = new Uint32Array(memory.buffer);
let params = [0x00000001, 0x00000555, 0x00099999, 0xffffffff];
TestCmpExchange(wasmCmpExchange, i32, params, kMemtypeSize32);
......@@ -241,7 +241,7 @@ function TestCmpExchange(func, buffer, params, size) {
(function TestAtomicCompareExchange16U() {
print("TestAtomicCompareExchange16U");
let wasmCmpExchange =
GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange16U);
GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange16U, 1, 0);
let i16 = new Uint16Array(memory.buffer);
let params = [0x0001, 0x0555, 0x9999];
TestCmpExchange(wasmCmpExchange, i16, params, kMemtypeSize16);
......@@ -250,7 +250,7 @@ function TestCmpExchange(func, buffer, params, size) {
(function TestAtomicCompareExchange8U() {
print("TestAtomicCompareExchange8U");
let wasmCmpExchange =
GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange8U);
GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange8U, 0, 0);
let i8 = new Uint8Array(memory.buffer);
let params = [0x01, 0x0d, 0xf9];
TestCmpExchange(wasmCmpExchange, i8, params, kMemtypeSize8);
......
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