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( ...@@ -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( void BytecodeGraphBuilder::VisitShiftLeft(
const interpreter::BytecodeArrayIterator& iterator) { const interpreter::BytecodeArrayIterator& iterator) {
BuildBinaryOp(javascript()->ShiftLeft(language_mode()), iterator); BuildBinaryOp(javascript()->ShiftLeft(language_mode()), iterator);
......
...@@ -604,6 +604,12 @@ Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { ...@@ -604,6 +604,12 @@ Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) {
return Bytecode::kDiv; return Bytecode::kDiv;
case Token::Value::MOD: case Token::Value::MOD:
return Bytecode::kMod; 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: case Token::Value::SHL:
return Bytecode::kShiftLeft; return Bytecode::kShiftLeft;
case Token::Value::SAR: case Token::Value::SAR:
......
...@@ -74,6 +74,9 @@ namespace interpreter { ...@@ -74,6 +74,9 @@ namespace interpreter {
V(Mul, OperandType::kReg8) \ V(Mul, OperandType::kReg8) \
V(Div, OperandType::kReg8) \ V(Div, OperandType::kReg8) \
V(Mod, OperandType::kReg8) \ V(Mod, OperandType::kReg8) \
V(BitwiseOr, OperandType::kReg8) \
V(BitwiseXor, OperandType::kReg8) \
V(BitwiseAnd, OperandType::kReg8) \
V(ShiftLeft, OperandType::kReg8) \ V(ShiftLeft, OperandType::kReg8) \
V(ShiftRight, OperandType::kReg8) \ V(ShiftRight, OperandType::kReg8) \
V(ShiftRightLogical, OperandType::kReg8) \ V(ShiftRightLogical, OperandType::kReg8) \
......
...@@ -400,6 +400,30 @@ void Interpreter::DoMod(compiler::InterpreterAssembler* assembler) { ...@@ -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> // ShiftLeft <src>
// //
// Left shifts register <src> by the count specified in the accumulator. // Left shifts register <src> by the count specified in the accumulator.
......
...@@ -251,6 +251,104 @@ TEST(PrimitiveExpressions) { ...@@ -251,6 +251,104 @@ TEST(PrimitiveExpressions) {
B(Return) // B(Return) //
}, },
0}, 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;", {"var x = 10; return x << 3;",
2 * kPointerSize, 2 * kPointerSize,
1, 1,
......
...@@ -351,15 +351,17 @@ TEST(InterpreterLoadStoreRegisters) { ...@@ -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[] = { static const Token::Value kShiftOperators[] = {
Token::Value::SHL, Token::Value::SAR, Token::Value::SHR}; 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) { static double BinaryOpC(Token::Value op, double lhs, double rhs) {
switch (op) { switch (op) {
case Token::Value::ADD: case Token::Value::ADD:
...@@ -372,6 +374,15 @@ static double BinaryOpC(Token::Value op, double lhs, double rhs) { ...@@ -372,6 +374,15 @@ static double BinaryOpC(Token::Value op, double lhs, double rhs) {
return lhs / rhs; return lhs / rhs;
case Token::Value::MOD: case Token::Value::MOD:
return std::fmod(lhs, rhs); 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: { case Token::Value::SHL: {
int32_t val = v8::internal::DoubleToInt32(lhs); int32_t val = v8::internal::DoubleToInt32(lhs);
uint32_t count = v8::internal::DoubleToUint32(rhs) & 0x1F; uint32_t count = v8::internal::DoubleToUint32(rhs) & 0x1F;
...@@ -415,7 +426,7 @@ TEST(InterpreterShiftOpsSmi) { ...@@ -415,7 +426,7 @@ TEST(InterpreterShiftOpsSmi) {
builder.LoadLiteral(Smi::FromInt(lhs)) builder.LoadLiteral(Smi::FromInt(lhs))
.StoreAccumulatorInRegister(reg) .StoreAccumulatorInRegister(reg)
.LoadLiteral(Smi::FromInt(rhs)) .LoadLiteral(Smi::FromInt(rhs))
.BinaryOperation(kArithmeticOperators[o], reg, Strength::WEAK) .BinaryOperation(kShiftOperators[o], reg, Strength::WEAK)
.Return(); .Return();
Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
...@@ -445,7 +456,7 @@ TEST(InterpreterBinaryOpsSmi) { ...@@ -445,7 +456,7 @@ TEST(InterpreterBinaryOpsSmi) {
builder.set_parameter_count(1); builder.set_parameter_count(1);
Register reg(0); Register reg(0);
int lhs = lhs_inputs[l]; int lhs = lhs_inputs[l];
int rhs = rhs_inputs[l]; int rhs = rhs_inputs[r];
builder.LoadLiteral(Smi::FromInt(lhs)) builder.LoadLiteral(Smi::FromInt(lhs))
.StoreAccumulatorInRegister(reg) .StoreAccumulatorInRegister(reg)
.LoadLiteral(Smi::FromInt(rhs)) .LoadLiteral(Smi::FromInt(rhs))
...@@ -480,7 +491,7 @@ TEST(InterpreterBinaryOpsHeapNumber) { ...@@ -480,7 +491,7 @@ TEST(InterpreterBinaryOpsHeapNumber) {
builder.set_parameter_count(1); builder.set_parameter_count(1);
Register reg(0); Register reg(0);
double lhs = lhs_inputs[l]; double lhs = lhs_inputs[l];
double rhs = rhs_inputs[l]; double rhs = rhs_inputs[r];
builder.LoadLiteral(factory->NewNumber(lhs)) builder.LoadLiteral(factory->NewNumber(lhs))
.StoreAccumulatorInRegister(reg) .StoreAccumulatorInRegister(reg)
.LoadLiteral(factory->NewNumber(rhs)) .LoadLiteral(factory->NewNumber(rhs))
......
...@@ -68,6 +68,11 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { ...@@ -68,6 +68,11 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.BinaryOperation(Token::Value::DIV, reg, Strength::WEAK) .BinaryOperation(Token::Value::DIV, reg, Strength::WEAK)
.BinaryOperation(Token::Value::MOD, 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 // Emit shift operator invocations
builder.BinaryOperation(Token::Value::SHL, reg, Strength::WEAK) builder.BinaryOperation(Token::Value::SHL, reg, Strength::WEAK)
.BinaryOperation(Token::Value::SAR, 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