Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Unified Diff: src/interpreter/interpreter-assembler.cc

Issue 1783483002: [interpreter] Add support for scalable operands. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Re-generate golden files. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/interpreter/interpreter-assembler.h ('k') | src/interpreter/register-translator.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/interpreter/interpreter-assembler.cc
diff --git a/src/interpreter/interpreter-assembler.cc b/src/interpreter/interpreter-assembler.cc
index 01e62e8a1c432a8737a823f080cf67e5c94e723d..3378e9393802dedd2c7c2d469f7c243aa3208530 100644
--- a/src/interpreter/interpreter-assembler.cc
+++ b/src/interpreter/interpreter-assembler.cc
@@ -22,12 +22,14 @@ namespace interpreter {
using compiler::Node;
InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone,
- Bytecode bytecode)
+ Bytecode bytecode,
+ OperandScale operand_scale)
: compiler::CodeStubAssembler(isolate, zone,
InterpreterDispatchDescriptor(isolate),
Code::ComputeFlags(Code::BYTECODE_HANDLER),
Bytecodes::ToString(bytecode), 0),
bytecode_(bytecode),
+ operand_scale_(operand_scale),
accumulator_(this, MachineRepresentation::kTagged),
context_(this, MachineRepresentation::kTagged),
bytecode_array_(this, MachineRepresentation::kTagged),
@@ -84,7 +86,7 @@ Node* InterpreterAssembler::LoadRegister(int offset) {
}
Node* InterpreterAssembler::LoadRegister(Register reg) {
- return LoadRegister(reg.ToOperand() << kPointerSizeLog2);
+ return LoadRegister(IntPtrConstant(-reg.index()));
}
Node* InterpreterAssembler::RegisterFrameOffset(Node* index) {
@@ -103,7 +105,7 @@ Node* InterpreterAssembler::StoreRegister(Node* value, int offset) {
}
Node* InterpreterAssembler::StoreRegister(Node* value, Register reg) {
- return StoreRegister(value, reg.ToOperand() << kPointerSizeLog2);
+ return StoreRegister(value, IntPtrConstant(-reg.index()));
}
Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) {
@@ -117,24 +119,28 @@ Node* InterpreterAssembler::NextRegister(Node* reg_index) {
return IntPtrAdd(reg_index, IntPtrConstant(-1));
}
-Node* InterpreterAssembler::BytecodeOperand(int operand_index) {
+Node* InterpreterAssembler::OperandOffset(int operand_index) {
+ return IntPtrConstant(
+ Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale()));
+}
+
+Node* InterpreterAssembler::BytecodeOperandUnsignedByte(int operand_index) {
DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
- DCHECK_EQ(OperandSize::kByte,
- Bytecodes::GetOperandSize(bytecode_, operand_index));
- return Load(
- MachineType::Uint8(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), IntPtrConstant(Bytecodes::GetOperandOffset(
- bytecode_, operand_index))));
+ DCHECK_EQ(OperandSize::kByte, Bytecodes::GetOperandSize(
+ bytecode_, operand_index, operand_scale()));
+ Node* operand_offset = OperandOffset(operand_index);
+ return Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(), operand_offset));
}
-Node* InterpreterAssembler::BytecodeOperandSignExtended(int operand_index) {
+Node* InterpreterAssembler::BytecodeOperandSignedByte(int operand_index) {
DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
- DCHECK_EQ(OperandSize::kByte,
- Bytecodes::GetOperandSize(bytecode_, operand_index));
- Node* load = Load(
- MachineType::Int8(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), IntPtrConstant(Bytecodes::GetOperandOffset(
- bytecode_, operand_index))));
+ DCHECK_EQ(OperandSize::kByte, Bytecodes::GetOperandSize(
+ bytecode_, operand_index, operand_scale()));
+ Node* operand_offset = OperandOffset(operand_index);
+ Node* load = Load(MachineType::Int8(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(), operand_offset));
+
// Ensure that we sign extend to full pointer size
if (kPointerSize == 8) {
load = ChangeInt32ToInt64(load);
@@ -142,59 +148,85 @@ Node* InterpreterAssembler::BytecodeOperandSignExtended(int operand_index) {
return load;
}
-Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) {
- DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
- DCHECK_EQ(OperandSize::kShort,
- Bytecodes::GetOperandSize(bytecode_, operand_index));
- if (TargetSupportsUnalignedAccess()) {
- return Load(
- MachineType::Uint16(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), IntPtrConstant(Bytecodes::GetOperandOffset(
- bytecode_, operand_index))));
- } else {
- int offset = Bytecodes::GetOperandOffset(bytecode_, operand_index);
- Node* first_byte =
- Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), IntPtrConstant(offset)));
- Node* second_byte =
- Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), IntPtrConstant(offset + 1)));
+compiler::Node* InterpreterAssembler::BytecodeOperandReadUnaligned(
+ int relative_offset, MachineType result_type) {
+ static const int kMaxCount = 4;
+ DCHECK(!TargetSupportsUnalignedAccess());
+
+ int count;
+ switch (result_type.representation()) {
+ case MachineRepresentation::kWord16:
+ count = 2;
+ break;
+ case MachineRepresentation::kWord32:
+ count = 4;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ MachineType msb_type =
+ result_type.IsSigned() ? MachineType::Int8() : MachineType::Uint8();
+
#if V8_TARGET_LITTLE_ENDIAN
- return WordOr(WordShl(second_byte, kBitsPerByte), first_byte);
+ const int kStep = -1;
+ int msb_offset = count - 1;
#elif V8_TARGET_BIG_ENDIAN
- return WordOr(WordShl(first_byte, kBitsPerByte), second_byte);
+ const int kStep = 1;
+ int msb_offset = 0;
#else
#error "Unknown Architecture"
#endif
+
+ // Read the most signicant bytecode into bytes[0] and then in order
+ // down to least significant in bytes[count - 1].
+ DCHECK(count <= kMaxCount);
+ compiler::Node* bytes[kMaxCount];
+ for (int i = 0; i < count; i++) {
+ MachineType machine_type = (i == 0) ? msb_type : MachineType::Uint8();
+ Node* offset = IntPtrConstant(relative_offset + msb_offset + i * kStep);
+ Node* array_offset = IntPtrAdd(BytecodeOffset(), offset);
+ bytes[i] = Load(machine_type, BytecodeArrayTaggedPointer(), array_offset);
+ }
+
+ // Pack LSB to MSB.
+ Node* result = bytes[--count];
+ for (int i = 1; --count >= 0; i++) {
+ Node* shift = Int32Constant(i * kBitsPerByte);
+ Node* value = Word32Shl(bytes[count], shift);
+ result = Word32Or(value, result);
+ }
+ return result;
+}
+
+Node* InterpreterAssembler::BytecodeOperandUnsignedShort(int operand_index) {
+ DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
+ DCHECK_EQ(
+ OperandSize::kShort,
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()));
+ int operand_offset =
+ Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale());
+ if (TargetSupportsUnalignedAccess()) {
+ return Load(MachineType::Uint16(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset)));
+ } else {
+ return BytecodeOperandReadUnaligned(operand_offset, MachineType::Uint16());
}
}
-Node* InterpreterAssembler::BytecodeOperandShortSignExtended(
- int operand_index) {
+Node* InterpreterAssembler::BytecodeOperandSignedShort(int operand_index) {
DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
- DCHECK_EQ(OperandSize::kShort,
- Bytecodes::GetOperandSize(bytecode_, operand_index));
- int operand_offset = Bytecodes::GetOperandOffset(bytecode_, operand_index);
+ DCHECK_EQ(
+ OperandSize::kShort,
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()));
+ int operand_offset =
+ Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale());
Node* load;
if (TargetSupportsUnalignedAccess()) {
load = Load(MachineType::Int16(), BytecodeArrayTaggedPointer(),
IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset)));
} else {
-#if V8_TARGET_LITTLE_ENDIAN
- Node* hi_byte_offset = IntPtrConstant(operand_offset + 1);
- Node* lo_byte_offset = IntPtrConstant(operand_offset);
-#elif V8_TARGET_BIG_ENDIAN
- Node* hi_byte_offset = IntPtrConstant(operand_offset);
- Node* lo_byte_offset = IntPtrConstant(operand_offset + 1);
-#else
-#error "Unknown Architecture"
-#endif
- Node* hi_byte = Load(MachineType::Int8(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), hi_byte_offset));
- Node* lo_byte = Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), lo_byte_offset));
- hi_byte = Word32Shl(hi_byte, Int32Constant(kBitsPerByte));
- load = Word32Or(hi_byte, lo_byte);
+ load = BytecodeOperandReadUnaligned(operand_offset, MachineType::Int16());
}
// Ensure that we sign extend to full pointer size
@@ -204,57 +236,123 @@ Node* InterpreterAssembler::BytecodeOperandShortSignExtended(
return load;
}
-Node* InterpreterAssembler::BytecodeOperandCount(int operand_index) {
- switch (Bytecodes::GetOperandSize(bytecode_, operand_index)) {
+Node* InterpreterAssembler::BytecodeOperandUnsignedQuad(int operand_index) {
+ DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
+ DCHECK_EQ(OperandSize::kQuad, Bytecodes::GetOperandSize(
+ bytecode_, operand_index, operand_scale()));
+ int operand_offset =
+ Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale());
+ if (TargetSupportsUnalignedAccess()) {
+ return Load(MachineType::Uint32(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset)));
+ } else {
+ return BytecodeOperandReadUnaligned(operand_offset, MachineType::Uint32());
+ }
+}
+
+Node* InterpreterAssembler::BytecodeOperandSignedQuad(int operand_index) {
+ DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
+ DCHECK_EQ(OperandSize::kQuad, Bytecodes::GetOperandSize(
+ bytecode_, operand_index, operand_scale()));
+ int operand_offset =
+ Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale());
+ Node* load;
+ if (TargetSupportsUnalignedAccess()) {
+ load = Load(MachineType::Int32(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset)));
+ } else {
+ load = BytecodeOperandReadUnaligned(operand_offset, MachineType::Int32());
+ }
+
+ // Ensure that we sign extend to full pointer size
+ if (kPointerSize == 8) {
+ load = ChangeInt32ToInt64(load);
+ }
+ return load;
+}
+
+Node* InterpreterAssembler::BytecodeSignedOperand(int operand_index,
+ OperandSize operand_size) {
+ DCHECK(!Bytecodes::IsUnsignedOperandType(
+ Bytecodes::GetOperandType(bytecode_, operand_index)));
+ switch (operand_size) {
case OperandSize::kByte:
- DCHECK_EQ(OperandType::kRegCount8,
- Bytecodes::GetOperandType(bytecode_, operand_index));
- return BytecodeOperand(operand_index);
+ return BytecodeOperandSignedByte(operand_index);
case OperandSize::kShort:
- DCHECK_EQ(OperandType::kRegCount16,
- Bytecodes::GetOperandType(bytecode_, operand_index));
- return BytecodeOperandShort(operand_index);
+ return BytecodeOperandSignedShort(operand_index);
+ case OperandSize::kQuad:
+ return BytecodeOperandSignedQuad(operand_index);
case OperandSize::kNone:
UNREACHABLE();
}
return nullptr;
}
-Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) {
- DCHECK_EQ(OperandType::kImm8,
- Bytecodes::GetOperandType(bytecode_, operand_index));
- return BytecodeOperandSignExtended(operand_index);
-}
-
-Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) {
- switch (Bytecodes::GetOperandSize(bytecode_, operand_index)) {
+Node* InterpreterAssembler::BytecodeUnsignedOperand(int operand_index,
+ OperandSize operand_size) {
+ DCHECK(Bytecodes::IsUnsignedOperandType(
+ Bytecodes::GetOperandType(bytecode_, operand_index)));
+ switch (operand_size) {
case OperandSize::kByte:
- DCHECK_EQ(OperandType::kIdx8,
- Bytecodes::GetOperandType(bytecode_, operand_index));
- return BytecodeOperand(operand_index);
+ return BytecodeOperandUnsignedByte(operand_index);
case OperandSize::kShort:
- DCHECK_EQ(OperandType::kIdx16,
- Bytecodes::GetOperandType(bytecode_, operand_index));
- return BytecodeOperandShort(operand_index);
+ return BytecodeOperandUnsignedShort(operand_index);
+ case OperandSize::kQuad:
+ return BytecodeOperandUnsignedQuad(operand_index);
case OperandSize::kNone:
UNREACHABLE();
}
return nullptr;
}
+Node* InterpreterAssembler::BytecodeOperandCount(int operand_index) {
+ DCHECK_EQ(OperandType::kRegCount,
+ Bytecodes::GetOperandType(bytecode_, operand_index));
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
+ return BytecodeUnsignedOperand(operand_index, operand_size);
+}
+
+Node* InterpreterAssembler::BytecodeOperandFlag(int operand_index) {
+ DCHECK_EQ(OperandType::kFlag8,
+ Bytecodes::GetOperandType(bytecode_, operand_index));
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
+ DCHECK_EQ(operand_size, OperandSize::kByte);
+ return BytecodeUnsignedOperand(operand_index, operand_size);
+}
+
+Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) {
+ DCHECK_EQ(OperandType::kImm,
+ Bytecodes::GetOperandType(bytecode_, operand_index));
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
+ return BytecodeSignedOperand(operand_index, operand_size);
+}
+
+Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) {
+ DCHECK(OperandType::kIdx ==
+ Bytecodes::GetOperandType(bytecode_, operand_index));
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
+ return BytecodeUnsignedOperand(operand_index, operand_size);
+}
+
Node* InterpreterAssembler::BytecodeOperandReg(int operand_index) {
- OperandType operand_type =
- Bytecodes::GetOperandType(bytecode_, operand_index);
- if (Bytecodes::IsRegisterOperandType(operand_type)) {
- OperandSize operand_size = Bytecodes::SizeOfOperand(operand_type);
- if (operand_size == OperandSize::kByte) {
- return BytecodeOperandSignExtended(operand_index);
- } else if (operand_size == OperandSize::kShort) {
- return BytecodeOperandShortSignExtended(operand_index);
- }
- }
- UNREACHABLE();
- return nullptr;
+ DCHECK(Bytecodes::IsRegisterOperandType(
+ Bytecodes::GetOperandType(bytecode_, operand_index)));
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
+ return BytecodeSignedOperand(operand_index, operand_size);
+}
+
+Node* InterpreterAssembler::BytecodeOperandRuntimeId(int operand_index) {
+ DCHECK(OperandType::kRuntimeId ==
+ Bytecodes::GetOperandType(bytecode_, operand_index));
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
+ DCHECK_EQ(operand_size, OperandSize::kShort);
+ return BytecodeUnsignedOperand(operand_index, operand_size);
}
Node* InterpreterAssembler::LoadConstantPoolEntry(Node* index) {
@@ -430,7 +528,7 @@ void InterpreterAssembler::JumpIfWordNotEqual(Node* lhs, Node* rhs,
}
void InterpreterAssembler::Dispatch() {
- DispatchTo(Advance(Bytecodes::Size(bytecode_)));
+ DispatchTo(Advance(Bytecodes::Size(bytecode_, operand_scale_)));
}
void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) {
@@ -462,6 +560,40 @@ void InterpreterAssembler::DispatchToBytecodeHandler(Node* handler,
TailCall(descriptor, handler, args, 0);
}
+void InterpreterAssembler::DispatchWide(OperandScale operand_scale) {
+ // Dispatching a wide bytecode requires treating the prefix
+ // bytecode a base pointer into the dispatch table and dispatching
+ // the bytecode that follows relative to this base.
+ //
+ // Indices 0-255 correspond to bytecodes with operand_scale == 0
+ // Indices 256-511 correspond to bytecodes with operand_scale == 1
+ // Indices 512-767 correspond to bytecodes with operand_scale == 2
+ Node* next_bytecode_offset = Advance(1);
+ Node* next_bytecode = Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
+ next_bytecode_offset);
+ if (kPointerSize == 8) {
+ next_bytecode = ChangeUint32ToUint64(next_bytecode);
+ }
+ Node* base_index;
+ switch (operand_scale) {
+ case OperandScale::kDouble:
+ base_index = IntPtrConstant(1 << kBitsPerByte);
+ break;
+ case OperandScale::kQuadruple:
+ base_index = IntPtrConstant(2 << kBitsPerByte);
+ break;
+ default:
+ UNREACHABLE();
+ base_index = nullptr;
+ }
+ Node* target_index = IntPtrAdd(base_index, next_bytecode);
+ Node* target_code_object =
+ Load(MachineType::Pointer(), DispatchTableRawPointer(),
+ WordShl(target_index, kPointerSizeLog2));
+
+ DispatchToBytecodeHandler(target_code_object, next_bytecode_offset);
+}
+
void InterpreterAssembler::InterpreterReturn() {
// TODO(rmcilroy): Investigate whether it is worth supporting self
// optimization of primitive functions like FullCodegen.
« no previous file with comments | « src/interpreter/interpreter-assembler.h ('k') | src/interpreter/register-translator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698