Commit 9feb5305 authored by mythria's avatar mythria Committed by Commit bot

Adds support for following operators

  -Bitwise Or
  -Bitwise Xor
  -Bitwise And

Adds the above bytecodes, support to BytecodeGenerator and BytecodeArrayBuilder to enable it's use, it's implementation and tests.

BUG=v8:4280
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#31210}
parent f113f3c3
......@@ -374,6 +374,24 @@ void BytecodeGraphBuilder::VisitMod(
}
void BytecodeGraphBuilder::VisitBitwiseOr(
const interpreter::BytecodeArrayIterator& iterator) {
BuildBinaryOp(javascript()->BitwiseOr(language_mode()), iterator);
}
void BytecodeGraphBuilder::VisitBitwiseXor(
const interpreter::BytecodeArrayIterator& iterator) {
BuildBinaryOp(javascript()->BitwiseXor(language_mode()), iterator);
}
void BytecodeGraphBuilder::VisitBitwiseAnd(
const interpreter::BytecodeArrayIterator& iterator) {
BuildBinaryOp(javascript()->BitwiseAnd(language_mode()), iterator);
}
void BytecodeGraphBuilder::VisitShiftLeft(
const interpreter::BytecodeArrayIterator& iterator) {
BuildBinaryOp(javascript()->ShiftLeft(language_mode()), iterator);
......
......@@ -604,6 +604,12 @@ Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) {
return Bytecode::kDiv;
case Token::Value::MOD:
return Bytecode::kMod;
case Token::Value::BIT_OR:
return Bytecode::kBitwiseOr;
case Token::Value::BIT_XOR:
return Bytecode::kBitwiseXor;
case Token::Value::BIT_AND:
return Bytecode::kBitwiseAnd;
case Token::Value::SHL:
return Bytecode::kShiftLeft;
case Token::Value::SAR:
......
......@@ -74,6 +74,9 @@ namespace interpreter {
V(Mul, OperandType::kReg8) \
V(Div, OperandType::kReg8) \
V(Mod, OperandType::kReg8) \
V(BitwiseOr, OperandType::kReg8) \
V(BitwiseXor, OperandType::kReg8) \
V(BitwiseAnd, OperandType::kReg8) \
V(ShiftLeft, OperandType::kReg8) \
V(ShiftRight, OperandType::kReg8) \
V(ShiftRightLogical, OperandType::kReg8) \
......
......@@ -400,6 +400,30 @@ void Interpreter::DoMod(compiler::InterpreterAssembler* assembler) {
}
// BitwiseOr <src>
//
// BitwiseOr register <src> to accumulator.
void Interpreter::DoBitwiseOr(compiler::InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kBitwiseOr, assembler);
}
// BitwiseXor <src>
//
// BitwiseXor register <src> to accumulator.
void Interpreter::DoBitwiseXor(compiler::InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kBitwiseXor, assembler);
}
// BitwiseAnd <src>
//
// BitwiseAnd register <src> to accumulator.
void Interpreter::DoBitwiseAnd(compiler::InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kBitwiseAnd, assembler);
}
// ShiftLeft <src>
//
// Left shifts register <src> by the count specified in the accumulator.
......
......@@ -251,6 +251,104 @@ TEST(PrimitiveExpressions) {
B(Return) //
},
0},
{"var x = 0; return x - 3;",
2 * kPointerSize,
1,
12,
{
B(LdaZero), //
B(Star), R(0), //
B(Ldar), R(0), // Easy to spot r1 not really needed here.
B(Star), R(1), // Dead store.
B(LdaSmi8), U8(3), //
B(Sub), R(1), //
B(Return) //
},
0},
{"var x = 4; return x * 3;",
2 * kPointerSize,
1,
13,
{
B(LdaSmi8), U8(4), //
B(Star), R(0), //
B(Ldar), R(0), // Easy to spot r1 not really needed here.
B(Star), R(1), // Dead store.
B(LdaSmi8), U8(3), //
B(Mul), R(1), //
B(Return) //
},
0},
{"var x = 4; return x / 3;",
2 * kPointerSize,
1,
13,
{
B(LdaSmi8), U8(4), //
B(Star), R(0), //
B(Ldar), R(0), // Easy to spot r1 not really needed here.
B(Star), R(1), // Dead store.
B(LdaSmi8), U8(3), //
B(Div), R(1), //
B(Return) //
},
0},
{"var x = 4; return x % 3;",
2 * kPointerSize,
1,
13,
{
B(LdaSmi8), U8(4), //
B(Star), R(0), //
B(Ldar), R(0), // Easy to spot r1 not really needed here.
B(Star), R(1), // Dead store.
B(LdaSmi8), U8(3), //
B(Mod), R(1), //
B(Return) //
},
0},
{"var x = 1; return x | 2;",
2 * kPointerSize,
1,
13,
{
B(LdaSmi8), U8(1), //
B(Star), R(0), //
B(Ldar), R(0), // Easy to spot r1 not really needed here.
B(Star), R(1), // Dead store.
B(LdaSmi8), U8(2), //
B(BitwiseOr), R(1), //
B(Return) //
},
0},
{"var x = 1; return x ^ 2;",
2 * kPointerSize,
1,
13,
{
B(LdaSmi8), U8(1), //
B(Star), R(0), //
B(Ldar), R(0), // Easy to spot r1 not really needed here.
B(Star), R(1), // Dead store.
B(LdaSmi8), U8(2), //
B(BitwiseXor), R(1), //
B(Return) //
},
0},
{"var x = 1; return x & 2;",
2 * kPointerSize,
1,
13,
{
B(LdaSmi8), U8(1), //
B(Star), R(0), //
B(Ldar), R(0), // Easy to spot r1 not really needed here.
B(Star), R(1), // Dead store.
B(LdaSmi8), U8(2), //
B(BitwiseAnd), R(1), //
B(Return) //
},
0},
{"var x = 10; return x << 3;",
2 * kPointerSize,
1,
......
......@@ -351,15 +351,17 @@ TEST(InterpreterLoadStoreRegisters) {
}
static const Token::Value kArithmeticOperators[] = {
Token::Value::SHL, Token::Value::SAR, Token::Value::SHR, Token::Value::ADD,
Token::Value::SUB, Token::Value::MUL, Token::Value::DIV, Token::Value::MOD};
static const Token::Value kShiftOperators[] = {
Token::Value::SHL, Token::Value::SAR, Token::Value::SHR};
static const Token::Value kArithmeticOperators[] = {
Token::Value::BIT_OR, Token::Value::BIT_XOR, Token::Value::BIT_AND,
Token::Value::SHL, Token::Value::SAR, Token::Value::SHR,
Token::Value::ADD, Token::Value::SUB, Token::Value::MUL,
Token::Value::DIV, Token::Value::MOD};
static double BinaryOpC(Token::Value op, double lhs, double rhs) {
switch (op) {
case Token::Value::ADD:
......@@ -372,6 +374,15 @@ static double BinaryOpC(Token::Value op, double lhs, double rhs) {
return lhs / rhs;
case Token::Value::MOD:
return std::fmod(lhs, rhs);
case Token::Value::BIT_OR:
return (v8::internal::DoubleToInt32(lhs) |
v8::internal::DoubleToInt32(rhs));
case Token::Value::BIT_XOR:
return (v8::internal::DoubleToInt32(lhs) ^
v8::internal::DoubleToInt32(rhs));
case Token::Value::BIT_AND:
return (v8::internal::DoubleToInt32(lhs) &
v8::internal::DoubleToInt32(rhs));
case Token::Value::SHL: {
int32_t val = v8::internal::DoubleToInt32(lhs);
uint32_t count = v8::internal::DoubleToUint32(rhs) & 0x1F;
......@@ -415,7 +426,7 @@ TEST(InterpreterShiftOpsSmi) {
builder.LoadLiteral(Smi::FromInt(lhs))
.StoreAccumulatorInRegister(reg)
.LoadLiteral(Smi::FromInt(rhs))
.BinaryOperation(kArithmeticOperators[o], reg, Strength::WEAK)
.BinaryOperation(kShiftOperators[o], reg, Strength::WEAK)
.Return();
Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
......@@ -445,7 +456,7 @@ TEST(InterpreterBinaryOpsSmi) {
builder.set_parameter_count(1);
Register reg(0);
int lhs = lhs_inputs[l];
int rhs = rhs_inputs[l];
int rhs = rhs_inputs[r];
builder.LoadLiteral(Smi::FromInt(lhs))
.StoreAccumulatorInRegister(reg)
.LoadLiteral(Smi::FromInt(rhs))
......@@ -480,7 +491,7 @@ TEST(InterpreterBinaryOpsHeapNumber) {
builder.set_parameter_count(1);
Register reg(0);
double lhs = lhs_inputs[l];
double rhs = rhs_inputs[l];
double rhs = rhs_inputs[r];
builder.LoadLiteral(factory->NewNumber(lhs))
.StoreAccumulatorInRegister(reg)
.LoadLiteral(factory->NewNumber(rhs))
......
......@@ -68,6 +68,11 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.BinaryOperation(Token::Value::DIV, reg, Strength::WEAK)
.BinaryOperation(Token::Value::MOD, reg, Strength::WEAK);
// Emit bitwise operator invocations
builder.BinaryOperation(Token::Value::BIT_OR, reg, Strength::WEAK)
.BinaryOperation(Token::Value::BIT_XOR, reg, Strength::WEAK)
.BinaryOperation(Token::Value::BIT_AND, reg, Strength::WEAK);
// Emit shift operator invocations
builder.BinaryOperation(Token::Value::SHL, reg, Strength::WEAK)
.BinaryOperation(Token::Value::SAR, reg, Strength::WEAK)
......
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