summaryrefslogtreecommitdiff
path: root/chromium/v8/src/diagnostics
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src/diagnostics')
-rw-r--r--chromium/v8/src/diagnostics/arm/disasm-arm.cc17
-rw-r--r--chromium/v8/src/diagnostics/arm/eh-frame-arm.cc2
-rw-r--r--chromium/v8/src/diagnostics/arm/unwinder-arm.cc2
-rw-r--r--chromium/v8/src/diagnostics/arm64/disasm-arm64.cc6
-rw-r--r--chromium/v8/src/diagnostics/arm64/eh-frame-arm64.cc2
-rw-r--r--chromium/v8/src/diagnostics/compilation-statistics.cc23
-rw-r--r--chromium/v8/src/diagnostics/compilation-statistics.h2
-rw-r--r--chromium/v8/src/diagnostics/disassembler.cc23
-rw-r--r--chromium/v8/src/diagnostics/eh-frame.cc2
-rw-r--r--chromium/v8/src/diagnostics/gdb-jit.cc206
-rw-r--r--chromium/v8/src/diagnostics/gdb-jit.h12
-rw-r--r--chromium/v8/src/diagnostics/ia32/disasm-ia32.cc159
-rw-r--r--chromium/v8/src/diagnostics/loong64/disasm-loong64.cc1711
-rw-r--r--chromium/v8/src/diagnostics/loong64/unwinder-loong64.cc14
-rw-r--r--chromium/v8/src/diagnostics/mips/disasm-mips.cc8
-rw-r--r--chromium/v8/src/diagnostics/mips64/disasm-mips64.cc9
-rw-r--r--chromium/v8/src/diagnostics/objects-debug.cc68
-rw-r--r--chromium/v8/src/diagnostics/objects-printer.cc210
-rw-r--r--chromium/v8/src/diagnostics/perf-jit.h3
-rw-r--r--chromium/v8/src/diagnostics/ppc/disasm-ppc.cc31
-rw-r--r--chromium/v8/src/diagnostics/ppc/eh-frame-ppc.cc2
-rw-r--r--chromium/v8/src/diagnostics/riscv64/disasm-riscv64.cc1210
-rw-r--r--chromium/v8/src/diagnostics/s390/eh-frame-s390.cc2
-rw-r--r--chromium/v8/src/diagnostics/system-jit-win.cc6
-rw-r--r--chromium/v8/src/diagnostics/unwinder.cc2
-rw-r--r--chromium/v8/src/diagnostics/unwinding-info-win64.h4
-rw-r--r--chromium/v8/src/diagnostics/x64/disasm-x64.cc515
27 files changed, 3335 insertions, 916 deletions
diff --git a/chromium/v8/src/diagnostics/arm/disasm-arm.cc b/chromium/v8/src/diagnostics/arm/disasm-arm.cc
index cf37d12a1f9..01b697b4bb4 100644
--- a/chromium/v8/src/diagnostics/arm/disasm-arm.cc
+++ b/chromium/v8/src/diagnostics/arm/disasm-arm.cc
@@ -676,7 +676,6 @@ int Decoder::FormatOption(Instruction* instr, const char* format) {
}
default: {
UNREACHABLE();
- return -1;
}
}
out_buffer_pos_ +=
@@ -787,7 +786,6 @@ void Decoder::DecodeType01(Instruction* instr) {
break;
default:
UNREACHABLE();
- break;
}
} else {
// strex
@@ -808,7 +806,6 @@ void Decoder::DecodeType01(Instruction* instr) {
break;
default:
UNREACHABLE();
- break;
}
}
} else {
@@ -853,7 +850,6 @@ void Decoder::DecodeType01(Instruction* instr) {
default: {
// The PU field is a 2-bit field.
UNREACHABLE();
- break;
}
}
} else {
@@ -894,7 +890,6 @@ void Decoder::DecodeType01(Instruction* instr) {
default: {
// The PU field is a 2-bit field.
UNREACHABLE();
- break;
}
}
return;
@@ -1030,7 +1025,6 @@ void Decoder::DecodeType01(Instruction* instr) {
default: {
// The Opcode field is a 4-bit field.
UNREACHABLE();
- break;
}
}
}
@@ -1107,10 +1101,8 @@ void Decoder::DecodeType3(Instruction* instr) {
break;
case 1:
UNREACHABLE();
- break;
case 2:
UNREACHABLE();
- break;
case 3:
Format(instr, "usat 'rd, #'imm05@16, 'rm'shift_sat");
break;
@@ -1119,7 +1111,6 @@ void Decoder::DecodeType3(Instruction* instr) {
switch (instr->Bits(22, 21)) {
case 0:
UNREACHABLE();
- break;
case 1:
if (instr->Bits(9, 6) == 1) {
if (instr->Bit(20) == 0) {
@@ -1948,7 +1939,6 @@ void Decoder::DecodeFloatingPointDataProcessing(Instruction* instr) {
break;
default:
UNREACHABLE(); // Case analysis is exhaustive.
- break;
}
} else if (instr->Opc1Value() == 0x4 && op2) {
// Floating-point minNum/maxNum.
@@ -2002,7 +1992,6 @@ void Decoder::DecodeFloatingPointDataProcessing(Instruction* instr) {
break;
default:
UNREACHABLE(); // Case analysis is exhaustive.
- break;
}
} else {
Unknown(instr);
@@ -2037,13 +2026,11 @@ void Decoder::DecodeAdvancedSIMDDataProcessing(Instruction* instr) {
int op1 = instr->Bit(4);
if (op0 == 0) {
// Advanced SIMD three registers of same length.
- int Vd, Vm, Vn;
+ int Vm, Vn;
if (instr->Bit(6) == 0) {
- Vd = instr->VFPDRegValue(kDoublePrecision);
Vm = instr->VFPMRegValue(kDoublePrecision);
Vn = instr->VFPNRegValue(kDoublePrecision);
} else {
- Vd = instr->VFPDRegValue(kSimd128Precision);
Vm = instr->VFPMRegValue(kSimd128Precision);
Vn = instr->VFPNRegValue(kSimd128Precision);
}
@@ -2617,12 +2604,10 @@ const char* NameConverter::NameOfCPURegister(int reg) const {
const char* NameConverter::NameOfByteCPURegister(int reg) const {
UNREACHABLE(); // ARM does not have the concept of a byte register
- return "nobytereg";
}
const char* NameConverter::NameOfXMMRegister(int reg) const {
UNREACHABLE(); // ARM does not have any XMM registers
- return "noxmmreg";
}
const char* NameConverter::NameInCode(byte* addr) const {
diff --git a/chromium/v8/src/diagnostics/arm/eh-frame-arm.cc b/chromium/v8/src/diagnostics/arm/eh-frame-arm.cc
index 7d0dc49155a..ef0a421820b 100644
--- a/chromium/v8/src/diagnostics/arm/eh-frame-arm.cc
+++ b/chromium/v8/src/diagnostics/arm/eh-frame-arm.cc
@@ -37,7 +37,6 @@ int EhFrameWriter::RegisterToDwarfCode(Register name) {
return kR0DwarfCode;
default:
UNIMPLEMENTED();
- return -1;
}
}
@@ -54,7 +53,6 @@ const char* EhFrameDisassembler::DwarfRegisterCodeToString(int code) {
return "lr";
default:
UNIMPLEMENTED();
- return nullptr;
}
}
diff --git a/chromium/v8/src/diagnostics/arm/unwinder-arm.cc b/chromium/v8/src/diagnostics/arm/unwinder-arm.cc
index e0e2f0e91f4..e51804caea1 100644
--- a/chromium/v8/src/diagnostics/arm/unwinder-arm.cc
+++ b/chromium/v8/src/diagnostics/arm/unwinder-arm.cc
@@ -5,7 +5,7 @@
#include <memory>
#include "include/v8-unwinder-state.h"
-#include "include/v8.h"
+#include "include/v8-unwinder.h"
#include "src/diagnostics/unwinder.h"
#include "src/execution/frame-constants.h"
diff --git a/chromium/v8/src/diagnostics/arm64/disasm-arm64.cc b/chromium/v8/src/diagnostics/arm64/disasm-arm64.cc
index 93b9531bd5d..af6e7f5441e 100644
--- a/chromium/v8/src/diagnostics/arm64/disasm-arm64.cc
+++ b/chromium/v8/src/diagnostics/arm64/disasm-arm64.cc
@@ -3954,7 +3954,6 @@ int DisassemblingDecoder::SubstituteImmediateField(Instruction* instr,
}
default: {
UNIMPLEMENTED();
- return 0;
}
}
}
@@ -3997,7 +3996,6 @@ int DisassemblingDecoder::SubstituteImmediateField(Instruction* instr,
return 0;
}
UNIMPLEMENTED();
- return 0;
}
case 'L': { // IVLSLane[0123] - suffix indicates access size shift.
AppendToOutput("%d", instr->NEONLSIndex(format[8] - '0'));
@@ -4042,12 +4040,10 @@ int DisassemblingDecoder::SubstituteImmediateField(Instruction* instr,
return static_cast<int>(strlen("IVMIShiftAmt2"));
} else {
UNIMPLEMENTED();
- return 0;
}
}
default: {
UNIMPLEMENTED();
- return 0;
}
}
}
@@ -4342,12 +4338,10 @@ const char* NameConverter::NameOfCPURegister(int reg) const {
const char* NameConverter::NameOfByteCPURegister(int reg) const {
UNREACHABLE(); // ARM64 does not have the concept of a byte register
- return "nobytereg";
}
const char* NameConverter::NameOfXMMRegister(int reg) const {
UNREACHABLE(); // ARM64 does not have any XMM registers
- return "noxmmreg";
}
const char* NameConverter::NameInCode(byte* addr) const {
diff --git a/chromium/v8/src/diagnostics/arm64/eh-frame-arm64.cc b/chromium/v8/src/diagnostics/arm64/eh-frame-arm64.cc
index 115d0cc300c..d27827cfc12 100644
--- a/chromium/v8/src/diagnostics/arm64/eh-frame-arm64.cc
+++ b/chromium/v8/src/diagnostics/arm64/eh-frame-arm64.cc
@@ -38,7 +38,6 @@ int EhFrameWriter::RegisterToDwarfCode(Register name) {
return kX0DwarfCode;
default:
UNIMPLEMENTED();
- return -1;
}
}
@@ -55,7 +54,6 @@ const char* EhFrameDisassembler::DwarfRegisterCodeToString(int code) {
return "sp"; // This could be zr as well
default:
UNIMPLEMENTED();
- return nullptr;
}
}
diff --git a/chromium/v8/src/diagnostics/compilation-statistics.cc b/chromium/v8/src/diagnostics/compilation-statistics.cc
index 40bb239b125..74fa232a080 100644
--- a/chromium/v8/src/diagnostics/compilation-statistics.cc
+++ b/chromium/v8/src/diagnostics/compilation-statistics.cc
@@ -56,6 +56,29 @@ void CompilationStatistics::BasicStats::Accumulate(const BasicStats& stats) {
}
}
+std::string CompilationStatistics::BasicStats::AsJSON() {
+// clang-format off
+#define DICT(s) "{" << s << "}"
+#define QUOTE(s) "\"" << s << "\""
+#define MEMBER(s) QUOTE(s) << ":"
+
+ DCHECK_EQ(function_name_.find("\""), std::string::npos);
+
+ std::stringstream stream;
+ stream << DICT(
+ MEMBER("function_name") << QUOTE(function_name_) << ","
+ MEMBER("total_allocated_bytes") << total_allocated_bytes_ << ","
+ MEMBER("max_allocated_bytes") << max_allocated_bytes_ << ","
+ MEMBER("absolute_max_allocated_bytes") << absolute_max_allocated_bytes_);
+
+ return stream.str();
+
+#undef DICT
+#undef QUOTE
+#undef MEMBER
+ // clang-format on
+}
+
static void WriteLine(std::ostream& os, bool machine_format, const char* name,
const CompilationStatistics::BasicStats& stats,
const CompilationStatistics::BasicStats& total_stats) {
diff --git a/chromium/v8/src/diagnostics/compilation-statistics.h b/chromium/v8/src/diagnostics/compilation-statistics.h
index d14e108d078..a6abdf5e89b 100644
--- a/chromium/v8/src/diagnostics/compilation-statistics.h
+++ b/chromium/v8/src/diagnostics/compilation-statistics.h
@@ -37,6 +37,8 @@ class CompilationStatistics final : public Malloced {
void Accumulate(const BasicStats& stats);
+ std::string AsJSON();
+
base::TimeDelta delta_;
size_t total_allocated_bytes_;
size_t max_allocated_bytes_;
diff --git a/chromium/v8/src/diagnostics/disassembler.cc b/chromium/v8/src/diagnostics/disassembler.cc
index 596362b351a..928fe1f3576 100644
--- a/chromium/v8/src/diagnostics/disassembler.cc
+++ b/chromium/v8/src/diagnostics/disassembler.cc
@@ -128,8 +128,11 @@ const char* V8NameConverter::RootRelativeName(int offset) const {
const unsigned kRootsTableSize = sizeof(RootsTable);
const int kExtRefsTableStart = IsolateData::external_reference_table_offset();
const unsigned kExtRefsTableSize = ExternalReferenceTable::kSizeInBytes;
- const int kBuiltinsTableStart = IsolateData::builtins_table_offset();
- const unsigned kBuiltinsTableSize =
+ const int kBuiltinTier0TableStart = IsolateData::builtin_tier0_table_offset();
+ const unsigned kBuiltinTier0TableSize =
+ Builtins::kBuiltinTier0Count * kSystemPointerSize;
+ const int kBuiltinTableStart = IsolateData::builtin_table_offset();
+ const unsigned kBuiltinTableSize =
Builtins::kBuiltinCount * kSystemPointerSize;
if (static_cast<unsigned>(offset - kRootsTableStart) < kRootsTableSize) {
@@ -143,7 +146,6 @@ const char* V8NameConverter::RootRelativeName(int offset) const {
SNPrintF(v8_buffer_, "root (%s)", RootsTable::name(root_index));
return v8_buffer_.begin();
-
} else if (static_cast<unsigned>(offset - kExtRefsTableStart) <
kExtRefsTableSize) {
uint32_t offset_in_extref_table = offset - kExtRefsTableStart;
@@ -162,17 +164,24 @@ const char* V8NameConverter::RootRelativeName(int offset) const {
isolate_->external_reference_table()->NameFromOffset(
offset_in_extref_table));
return v8_buffer_.begin();
-
- } else if (static_cast<unsigned>(offset - kBuiltinsTableStart) <
- kBuiltinsTableSize) {
- uint32_t offset_in_builtins_table = (offset - kBuiltinsTableStart);
+ } else if (static_cast<unsigned>(offset - kBuiltinTier0TableStart) <
+ kBuiltinTier0TableSize) {
+ uint32_t offset_in_builtins_table = (offset - kBuiltinTier0TableStart);
Builtin builtin =
Builtins::FromInt(offset_in_builtins_table / kSystemPointerSize);
const char* name = Builtins::name(builtin);
SNPrintF(v8_buffer_, "builtin (%s)", name);
return v8_buffer_.begin();
+ } else if (static_cast<unsigned>(offset - kBuiltinTableStart) <
+ kBuiltinTableSize) {
+ uint32_t offset_in_builtins_table = (offset - kBuiltinTableStart);
+ Builtin builtin =
+ Builtins::FromInt(offset_in_builtins_table / kSystemPointerSize);
+ const char* name = Builtins::name(builtin);
+ SNPrintF(v8_buffer_, "builtin (%s)", name);
+ return v8_buffer_.begin();
} else {
// It must be a direct access to one of the external values.
if (directly_accessed_external_refs_.empty()) {
diff --git a/chromium/v8/src/diagnostics/eh-frame.cc b/chromium/v8/src/diagnostics/eh-frame.cc
index d53ea7698a0..223e288e6e9 100644
--- a/chromium/v8/src/diagnostics/eh-frame.cc
+++ b/chromium/v8/src/diagnostics/eh-frame.cc
@@ -27,14 +27,12 @@ void EhFrameWriter::WriteInitialStateInCie() { UNIMPLEMENTED(); }
int EhFrameWriter::RegisterToDwarfCode(Register) {
UNIMPLEMENTED();
- return -1;
}
#ifdef ENABLE_DISASSEMBLER
const char* EhFrameDisassembler::DwarfRegisterCodeToString(int) {
UNIMPLEMENTED();
- return nullptr;
}
#endif
diff --git a/chromium/v8/src/diagnostics/gdb-jit.cc b/chromium/v8/src/diagnostics/gdb-jit.cc
index 53c29cfb242..bc03a189cd5 100644
--- a/chromium/v8/src/diagnostics/gdb-jit.cc
+++ b/chromium/v8/src/diagnostics/gdb-jit.cc
@@ -4,14 +4,17 @@
#include "src/diagnostics/gdb-jit.h"
+#include <iterator>
#include <map>
#include <memory>
#include <vector>
-#include "include/v8.h"
+#include "include/v8-callbacks.h"
#include "src/api/api-inl.h"
+#include "src/base/address-region.h"
#include "src/base/bits.h"
#include "src/base/hashmap.h"
+#include "src/base/memory.h"
#include "src/base/platform/platform.h"
#include "src/base/platform/wrappers.h"
#include "src/base/strings.h"
@@ -63,7 +66,9 @@ class Writer {
T* operator->() { return w_->RawSlotAt<T>(offset_); }
- void set(const T& value) { *w_->RawSlotAt<T>(offset_) = value; }
+ void set(const T& value) {
+ base::WriteUnalignedValue(w_->AddressAt<T>(offset_), value);
+ }
Slot<T> at(int i) { return Slot<T>(w_, offset_ + sizeof(T) * i); }
@@ -75,7 +80,7 @@ class Writer {
template <typename T>
void Write(const T& val) {
Ensure(position_ + sizeof(T));
- *RawSlotAt<T>(position_) = val;
+ base::WriteUnalignedValue(AddressAt<T>(position_), val);
position_ += sizeof(T);
}
@@ -154,6 +159,12 @@ class Writer {
friend class Slot;
template <typename T>
+ Address AddressAt(uintptr_t offset) {
+ DCHECK(offset < capacity_ && offset + sizeof(T) <= capacity_);
+ return reinterpret_cast<Address>(&buffer_[offset]);
+ }
+
+ template <typename T>
T* RawSlotAt(uintptr_t offset) {
DCHECK(offset < capacity_ && offset + sizeof(T) <= capacity_);
return reinterpret_cast<T*>(&buffer_[offset]);
@@ -896,17 +907,20 @@ class CodeDescription {
};
#endif
- CodeDescription(const char* name, Code code, SharedFunctionInfo shared,
- LineInfo* lineinfo)
- : name_(name), code_(code), shared_info_(shared), lineinfo_(lineinfo) {}
+ CodeDescription(const char* name, base::AddressRegion region,
+ SharedFunctionInfo shared, LineInfo* lineinfo,
+ bool is_function)
+ : name_(name),
+ shared_info_(shared),
+ lineinfo_(lineinfo),
+ is_function_(is_function),
+ code_region_(region) {}
const char* name() const { return name_; }
LineInfo* lineinfo() const { return lineinfo_; }
- bool is_function() const {
- return CodeKindIsOptimizedJSFunction(code_.kind());
- }
+ bool is_function() const { return is_function_; }
bool has_scope_info() const { return !shared_info_.is_null(); }
@@ -915,15 +929,11 @@ class CodeDescription {
return shared_info_.scope_info();
}
- uintptr_t CodeStart() const {
- return static_cast<uintptr_t>(code_.InstructionStart());
- }
+ uintptr_t CodeStart() const { return code_region_.begin(); }
- uintptr_t CodeEnd() const {
- return static_cast<uintptr_t>(code_.InstructionEnd());
- }
+ uintptr_t CodeEnd() const { return code_region_.end(); }
- uintptr_t CodeSize() const { return CodeEnd() - CodeStart(); }
+ uintptr_t CodeSize() const { return code_region_.size(); }
bool has_script() {
return !shared_info_.is_null() && shared_info_.script().IsScript();
@@ -933,6 +943,8 @@ class CodeDescription {
bool IsLineInfoAvailable() { return lineinfo_ != nullptr; }
+ base::AddressRegion region() { return code_region_; }
+
#if V8_TARGET_ARCH_X64
uintptr_t GetStackStateStartAddress(StackState state) const {
DCHECK(state < STACK_STATE_MAX);
@@ -946,7 +958,7 @@ class CodeDescription {
#endif
std::unique_ptr<char[]> GetFilename() {
- if (!shared_info_.is_null()) {
+ if (!shared_info_.is_null() && script().name().IsString()) {
return String::cast(script().name()).ToCString();
} else {
std::unique_ptr<char[]> result(new char[1]);
@@ -965,9 +977,10 @@ class CodeDescription {
private:
const char* name_;
- Code code_;
SharedFunctionInfo shared_info_;
LineInfo* lineinfo_;
+ bool is_function_;
+ base::AddressRegion code_region_;
#if V8_TARGET_ARCH_X64
uintptr_t stack_state_start_addresses_[STACK_STATE_MAX];
#endif
@@ -1080,6 +1093,8 @@ class DebugInfoSection : public DebugSection {
UNIMPLEMENTED();
#elif V8_TARGET_ARCH_MIPS64
UNIMPLEMENTED();
+#elif V8_TARGET_ARCH_LOONG64
+ UNIMPLEMENTED();
#elif V8_TARGET_ARCH_PPC64 && V8_OS_LINUX
w->Write<uint8_t>(DW_OP_reg31); // The frame pointer is here on PPC64.
#elif V8_TARGET_ARCH_S390
@@ -1092,7 +1107,7 @@ class DebugInfoSection : public DebugSection {
int params = scope.ParameterCount();
int context_slots = scope.ContextLocalCount();
// The real slot ID is internal_slots + context_slot_id.
- int internal_slots = Context::MIN_CONTEXT_SLOTS;
+ int internal_slots = scope.ContextHeaderLength();
int current_abbreviation = 4;
for (int param = 0; param < params; ++param) {
@@ -1109,7 +1124,7 @@ class DebugInfoSection : public DebugSection {
}
// See contexts.h for more information.
- DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, 3);
+ DCHECK(internal_slots == 2 || internal_slots == 3);
DCHECK_EQ(Context::SCOPE_INFO_INDEX, 0);
DCHECK_EQ(Context::PREVIOUS_INDEX, 1);
DCHECK_EQ(Context::EXTENSION_INDEX, 2);
@@ -1117,8 +1132,10 @@ class DebugInfoSection : public DebugSection {
w->WriteString(".scope_info");
w->WriteULEB128(current_abbreviation++);
w->WriteString(".previous");
- w->WriteULEB128(current_abbreviation++);
- w->WriteString(".extension");
+ if (internal_slots == 3) {
+ w->WriteULEB128(current_abbreviation++);
+ w->WriteString(".extension");
+ }
for (int context_slot = 0; context_slot < context_slots; ++context_slot) {
w->WriteULEB128(current_abbreviation++);
@@ -1814,26 +1831,17 @@ static JITCodeEntry* CreateELFObject(CodeDescription* desc, Isolate* isolate) {
return CreateCodeEntry(reinterpret_cast<Address>(w.buffer()), w.position());
}
-struct AddressRange {
- Address start;
- Address end;
-};
-
-struct AddressRangeLess {
- bool operator()(const AddressRange& a, const AddressRange& b) const {
- if (a.start == b.start) return a.end < b.end;
- return a.start < b.start;
+// Like base::AddressRegion::StartAddressLess but also compares |end| when
+// |begin| is equal.
+struct AddressRegionLess {
+ bool operator()(const base::AddressRegion& a,
+ const base::AddressRegion& b) const {
+ if (a.begin() == b.begin()) return a.end() < b.end();
+ return a.begin() < b.begin();
}
};
-struct CodeMapConfig {
- using Key = AddressRange;
- using Value = JITCodeEntry*;
- using Less = AddressRangeLess;
-};
-
-using CodeMap =
- std::map<CodeMapConfig::Key, CodeMapConfig::Value, CodeMapConfig::Less>;
+using CodeMap = std::map<base::AddressRegion, JITCodeEntry*, AddressRegionLess>;
static CodeMap* GetCodeMap() {
// TODO(jgruber): Don't leak.
@@ -1907,50 +1915,72 @@ static void AddUnwindInfo(CodeDescription* desc) {
static base::LazyMutex mutex = LAZY_MUTEX_INITIALIZER;
-// Remove entries from the map that intersect the given address range,
-// and deregister them from GDB.
-static void RemoveJITCodeEntries(CodeMap* map, const AddressRange& range) {
- DCHECK(range.start < range.end);
+static base::Optional<std::pair<CodeMap::iterator, CodeMap::iterator>>
+GetOverlappingRegions(CodeMap* map, const base::AddressRegion region) {
+ DCHECK_LT(region.begin(), region.end());
- if (map->empty()) return;
+ if (map->empty()) return {};
// Find the first overlapping entry.
- // If successful, points to the first element not less than `range`. The
+ // If successful, points to the first element not less than `region`. The
// returned iterator has the key in `first` and the value in `second`.
- auto it = map->lower_bound(range);
+ auto it = map->lower_bound(region);
auto start_it = it;
if (it == map->end()) {
start_it = map->begin();
+ // Find the first overlapping entry.
+ for (; start_it != map->end(); ++start_it) {
+ if (start_it->first.end() > region.begin()) {
+ break;
+ }
+ }
} else if (it != map->begin()) {
for (--it; it != map->begin(); --it) {
- if ((*it).first.end <= range.start) break;
+ if ((*it).first.end() <= region.begin()) break;
+ start_it = it;
+ }
+ if (it == map->begin() && it->first.end() > region.begin()) {
start_it = it;
}
}
- DCHECK(start_it != map->end());
+ if (start_it == map->end()) {
+ return {};
+ }
- // Find the first non-overlapping entry after `range`.
+ // Find the first non-overlapping entry after `region`.
- const auto end_it = map->lower_bound({range.end, 0});
+ const auto end_it = map->lower_bound({region.end(), 0});
- // Evict intersecting ranges.
+ // Return a range containing intersecting regions.
- if (std::distance(start_it, end_it) < 1) return; // No overlapping entries.
+ if (std::distance(start_it, end_it) < 1)
+ return {}; // No overlapping entries.
- for (auto it = start_it; it != end_it; it++) {
- JITCodeEntry* old_entry = (*it).second;
- UnregisterCodeEntry(old_entry);
- DestroyCodeEntry(old_entry);
- }
+ return {{start_it, end_it}};
+}
+
+// Remove entries from the map that intersect the given address region,
+// and deregister them from GDB.
+static void RemoveJITCodeEntries(CodeMap* map,
+ const base::AddressRegion region) {
+ if (auto overlap = GetOverlappingRegions(map, region)) {
+ auto start_it = overlap->first;
+ auto end_it = overlap->second;
+ for (auto it = start_it; it != end_it; it++) {
+ JITCodeEntry* old_entry = (*it).second;
+ UnregisterCodeEntry(old_entry);
+ DestroyCodeEntry(old_entry);
+ }
- map->erase(start_it, end_it);
+ map->erase(start_it, end_it);
+ }
}
// Insert the entry into the map and register it with GDB.
-static void AddJITCodeEntry(CodeMap* map, const AddressRange& range,
+static void AddJITCodeEntry(CodeMap* map, const base::AddressRegion region,
JITCodeEntry* entry, bool dump_if_enabled,
const char* name_hint) {
#if defined(DEBUG) && !V8_OS_WIN
@@ -1967,24 +1997,21 @@ static void AddJITCodeEntry(CodeMap* map, const AddressRange& range,
}
#endif
- auto result = map->emplace(range, entry);
+ auto result = map->emplace(region, entry);
DCHECK(result.second); // Insertion happened.
USE(result);
RegisterCodeEntry(entry);
}
-static void AddCode(const char* name, Code code, SharedFunctionInfo shared,
- LineInfo* lineinfo) {
+static void AddCode(const char* name, base::AddressRegion region,
+ SharedFunctionInfo shared, LineInfo* lineinfo,
+ Isolate* isolate, bool is_function) {
DisallowGarbageCollection no_gc;
+ CodeDescription code_desc(name, region, shared, lineinfo, is_function);
CodeMap* code_map = GetCodeMap();
- AddressRange range;
- range.start = code.address();
- range.end = code.address() + code.CodeSize();
- RemoveJITCodeEntries(code_map, range);
-
- CodeDescription code_desc(name, code, shared, lineinfo);
+ RemoveJITCodeEntries(code_map, region);
if (!FLAG_gdbjit_full && !code_desc.IsLineInfoAvailable()) {
delete lineinfo;
@@ -1992,7 +2019,6 @@ static void AddCode(const char* name, Code code, SharedFunctionInfo shared,
}
AddUnwindInfo(&code_desc);
- Isolate* isolate = code.GetIsolate();
JITCodeEntry* entry = CreateELFObject(&code_desc, isolate);
delete lineinfo;
@@ -2008,25 +2034,40 @@ static void AddCode(const char* name, Code code, SharedFunctionInfo shared,
should_dump = (name_hint != nullptr);
}
}
- AddJITCodeEntry(code_map, range, entry, should_dump, name_hint);
+ AddJITCodeEntry(code_map, region, entry, should_dump, name_hint);
}
void EventHandler(const v8::JitCodeEvent* event) {
if (!FLAG_gdbjit) return;
- if (event->code_type != v8::JitCodeEvent::JIT_CODE) return;
+ if ((event->code_type != v8::JitCodeEvent::JIT_CODE) &&
+ (event->code_type != v8::JitCodeEvent::WASM_CODE)) {
+ return;
+ }
base::MutexGuard lock_guard(mutex.Pointer());
switch (event->type) {
case v8::JitCodeEvent::CODE_ADDED: {
Address addr = reinterpret_cast<Address>(event->code_start);
- Isolate* isolate = reinterpret_cast<Isolate*>(event->isolate);
- Code code = isolate->heap()->GcSafeFindCodeForInnerPointer(addr);
LineInfo* lineinfo = GetLineInfo(addr);
std::string event_name(event->name.str, event->name.len);
// It's called UnboundScript in the API but it's a SharedFunctionInfo.
SharedFunctionInfo shared = event->script.IsEmpty()
? SharedFunctionInfo()
: *Utils::OpenHandle(*event->script);
- AddCode(event_name.c_str(), code, shared, lineinfo);
+ Isolate* isolate = reinterpret_cast<Isolate*>(event->isolate);
+ bool is_function = false;
+ // TODO(zhin): See if we can use event->code_type to determine
+ // is_function, the difference currently is that JIT_CODE is SparkPlug,
+ // TurboProp, TurboFan, whereas CodeKindIsOptimizedJSFunction is only
+ // TurboProp and TurboFan. is_function is used for AddUnwindInfo, and the
+ // prologue that SP generates probably matches that of TP/TF, so we can
+ // use event->code_type here instead of finding the Code.
+ // TODO(zhin): Rename is_function to be more accurate.
+ if (event->code_type == v8::JitCodeEvent::JIT_CODE) {
+ Code code = isolate->heap()->GcSafeFindCodeForInnerPointer(addr);
+ is_function = CodeKindIsOptimizedJSFunction(code.kind());
+ }
+ AddCode(event_name.c_str(), {addr, event->code_len}, shared, lineinfo,
+ isolate, is_function);
break;
}
case v8::JitCodeEvent::CODE_MOVED:
@@ -2056,6 +2097,23 @@ void EventHandler(const v8::JitCodeEvent* event) {
}
}
}
+
+void AddRegionForTesting(const base::AddressRegion region) {
+ // For testing purposes we don't care about JITCodeEntry, pass nullptr.
+ auto result = GetCodeMap()->emplace(region, nullptr);
+ DCHECK(result.second); // Insertion happened.
+ USE(result);
+}
+
+void ClearCodeMapForTesting() { GetCodeMap()->clear(); }
+
+size_t NumOverlapEntriesForTesting(const base::AddressRegion region) {
+ if (auto overlaps = GetOverlappingRegions(GetCodeMap(), region)) {
+ return std::distance(overlaps->first, overlaps->second);
+ }
+ return 0;
+}
+
#endif
} // namespace GDBJITInterface
} // namespace internal
diff --git a/chromium/v8/src/diagnostics/gdb-jit.h b/chromium/v8/src/diagnostics/gdb-jit.h
index 82f5ce892c9..eb4d515a810 100644
--- a/chromium/v8/src/diagnostics/gdb-jit.h
+++ b/chromium/v8/src/diagnostics/gdb-jit.h
@@ -5,6 +5,8 @@
#ifndef V8_DIAGNOSTICS_GDB_JIT_H_
#define V8_DIAGNOSTICS_GDB_JIT_H_
+#include "src/base/address-region.h"
+
//
// GDB has two ways of interacting with JIT code. With the "JIT compilation
// interface", V8 can tell GDB when it emits JIT code. Unfortunately to do so,
@@ -29,9 +31,19 @@ struct JitCodeEvent;
namespace internal {
namespace GDBJITInterface {
#ifdef ENABLE_GDB_JIT_INTERFACE
+
// JitCodeEventHandler that creates ELF/Mach-O objects and registers them with
// GDB.
void EventHandler(const v8::JitCodeEvent* event);
+
+// Expose some functions for unittests. These only exercise the logic to add
+// AddressRegion to CodeMap, and checking for overlap. It does not touch the
+// actual JITCodeEntry at all.
+V8_EXPORT_PRIVATE void AddRegionForTesting(const base::AddressRegion region);
+V8_EXPORT_PRIVATE void ClearCodeMapForTesting();
+V8_EXPORT_PRIVATE size_t
+NumOverlapEntriesForTesting(const base::AddressRegion region);
+
#endif
} // namespace GDBJITInterface
} // namespace internal
diff --git a/chromium/v8/src/diagnostics/ia32/disasm-ia32.cc b/chromium/v8/src/diagnostics/ia32/disasm-ia32.cc
index de124de7474..fbcba1a4b2e 100644
--- a/chromium/v8/src/diagnostics/ia32/disasm-ia32.cc
+++ b/chromium/v8/src/diagnostics/ia32/disasm-ia32.cc
@@ -89,6 +89,10 @@ static const char* const conditional_move_mnem[] = {
/*8*/ "cmovs", "cmovns", "cmovpe", "cmovpo",
/*12*/ "cmovl", "cmovnl", "cmovng", "cmovg"};
+static const char* const cmp_pseudo_op[16] = {
+ "eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord",
+ "eq_uq", "nge", "ngt", "false", "neq_oq", "ge", "gt", "true"};
+
enum InstructionType {
NO_INSTR,
ZERO_OPERANDS_INSTR,
@@ -415,13 +419,11 @@ int DisassemblerIA32::PrintRightOperandHelper(
UnimplementedInstruction();
return 1;
}
- } else {
- AppendToBuffer("[%s]", (this->*register_name)(rm));
- return 1;
}
- break;
+ AppendToBuffer("[%s]", (this->*register_name)(rm));
+ return 1;
case 1: // fall through
- case 2:
+ case 2: {
if (rm == esp) {
byte sib = *(modrmp + 1);
int scale, index, base;
@@ -436,14 +438,13 @@ int DisassemblerIA32::PrintRightOperandHelper(
disp < 0 ? "-" : "+", disp < 0 ? -disp : disp);
}
return mod == 2 ? 6 : 3;
- } else {
- // No sib.
- int disp = mod == 2 ? Imm32(modrmp + 1) : Imm8(modrmp + 1);
- AppendToBuffer("[%s%s0x%x]", (this->*register_name)(rm),
- disp < 0 ? "-" : "+", disp < 0 ? -disp : disp);
- return mod == 2 ? 5 : 2;
}
- break;
+ // No sib.
+ int disp = mod == 2 ? Imm32(modrmp + 1) : Imm8(modrmp + 1);
+ AppendToBuffer("[%s%s0x%x]", (this->*register_name)(rm),
+ disp < 0 ? "-" : "+", disp < 0 ? -disp : disp);
+ return mod == 2 ? 5 : 2;
+ }
case 3:
AppendToBuffer("%s", (this->*register_name)(rm));
return 1;
@@ -789,6 +790,15 @@ int DisassemblerIA32::AVXInstruction(byte* data) {
SSSE3_UNOP_INSTRUCTION_LIST(DECLARE_SSE_AVX_RM_DIS_CASE)
SSE4_RM_INSTRUCTION_LIST(DECLARE_SSE_AVX_RM_DIS_CASE)
#undef DECLARE_SSE_AVX_RM_DIS_CASE
+
+#define DISASSEMBLE_AVX2_BROADCAST(instruction, _1, _2, _3, code) \
+ case 0x##code: \
+ AppendToBuffer("" #instruction " %s,", NameOfXMMRegister(regop)); \
+ current += PrintRightXMMOperand(current); \
+ break;
+ AVX2_BROADCAST_LIST(DISASSEMBLE_AVX2_BROADCAST)
+#undef DISASSEMBLE_AVX2_BROADCAST
+
default:
UnimplementedInstruction();
}
@@ -808,6 +818,20 @@ int DisassemblerIA32::AVXInstruction(byte* data) {
AppendToBuffer(",%d", Imm8_U(current));
current++;
break;
+ case 0x0a:
+ AppendToBuffer("vroundss %s,%s,", NameOfXMMRegister(regop),
+ NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ AppendToBuffer(",%d", Imm8_U(current));
+ current++;
+ break;
+ case 0x0b:
+ AppendToBuffer("vroundsd %s,%s,", NameOfXMMRegister(regop),
+ NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ AppendToBuffer(",%d", Imm8_U(current));
+ current++;
+ break;
case 0x0E:
AppendToBuffer("vpblendw %s,%s,", NameOfXMMRegister(regop),
NameOfXMMRegister(vvvv));
@@ -900,39 +924,8 @@ int DisassemblerIA32::AVXInstruction(byte* data) {
AppendToBuffer("vmovddup %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
break;
- case 0x51:
- AppendToBuffer("vsqrtsd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- break;
- case 0x58:
- AppendToBuffer("vaddsd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- break;
- case 0x59:
- AppendToBuffer("vmulsd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- break;
- case 0x5C:
- AppendToBuffer("vsubsd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- break;
- case 0x5D:
- AppendToBuffer("vminsd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- break;
- case 0x5E:
- AppendToBuffer("vdivsd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- break;
- case 0x5F:
- AppendToBuffer("vmaxsd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
+ case 0x2c:
+ AppendToBuffer("vcvttsd2si %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
break;
case 0x70:
@@ -946,6 +939,14 @@ int DisassemblerIA32::AVXInstruction(byte* data) {
NameOfXMMRegister(vvvv));
current += PrintRightXMMOperand(current);
break;
+#define DISASM_SSE2_INSTRUCTION_LIST_SD(instruction, _1, _2, opcode) \
+ case 0x##opcode: \
+ AppendToBuffer("v" #instruction " %s,%s,", NameOfXMMRegister(regop), \
+ NameOfXMMRegister(vvvv)); \
+ current += PrintRightXMMOperand(current); \
+ break;
+ SSE2_INSTRUCTION_LIST_SD(DISASM_SSE2_INSTRUCTION_LIST_SD)
+#undef DISASM_SSE2_INSTRUCTION_LIST_SD
default:
UnimplementedInstruction();
}
@@ -967,6 +968,10 @@ int DisassemblerIA32::AVXInstruction(byte* data) {
AppendToBuffer("vmovshdup %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
break;
+ case 0x2c:
+ AppendToBuffer("vcvttss2si %s,", NameOfXMMRegister(regop));
+ current += PrintRightXMMOperand(current);
+ break;
case 0x51:
AppendToBuffer("vsqrtss %s,%s,", NameOfXMMRegister(regop),
NameOfXMMRegister(vvvv));
@@ -982,6 +987,11 @@ int DisassemblerIA32::AVXInstruction(byte* data) {
NameOfXMMRegister(vvvv));
current += PrintRightXMMOperand(current);
break;
+ case 0x5a:
+ AppendToBuffer("vcvtss2sd %s,%s,", NameOfXMMRegister(regop),
+ NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
case 0x5B:
AppendToBuffer("vcvttps2dq %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
@@ -1167,6 +1177,10 @@ int DisassemblerIA32::AVXInstruction(byte* data) {
AppendToBuffer("vmovaps %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
break;
+ case 0x2e:
+ AppendToBuffer("vucomiss %s,", NameOfXMMRegister(regop));
+ current += PrintRightXMMOperand(current);
+ break;
case 0x50:
AppendToBuffer("vmovmskps %s,%s", NameOfCPURegister(regop),
NameOfXMMRegister(rm));
@@ -1243,12 +1257,10 @@ int DisassemblerIA32::AVXInstruction(byte* data) {
current += PrintRightXMMOperand(current);
break;
case 0xC2: {
- const char* const pseudo_op[] = {"eq", "lt", "le", "unord",
- "neq", "nlt", "nle", "ord"};
AppendToBuffer("vcmpps %s,%s,", NameOfXMMRegister(regop),
NameOfXMMRegister(vvvv));
current += PrintRightXMMOperand(current);
- AppendToBuffer(", (%s)", pseudo_op[*current]);
+ AppendToBuffer(", (%s)", cmp_pseudo_op[*current]);
current++;
break;
}
@@ -1274,6 +1286,10 @@ int DisassemblerIA32::AVXInstruction(byte* data) {
AppendToBuffer("vmovapd %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
break;
+ case 0x2e:
+ AppendToBuffer("vucomisd %s,", NameOfXMMRegister(regop));
+ current += PrintRightXMMOperand(current);
+ break;
case 0x50:
AppendToBuffer("vmovmskpd %s,%s", NameOfCPURegister(regop),
NameOfXMMRegister(rm));
@@ -1371,11 +1387,10 @@ int DisassemblerIA32::AVXInstruction(byte* data) {
AppendToBuffer(",%s", NameOfXMMRegister(regop));
break;
case 0xC2: {
- const char* const pseudo_op[] = {"eq", "lt", "le", "unord", "neq"};
AppendToBuffer("vcmppd %s,%s,", NameOfXMMRegister(regop),
NameOfXMMRegister(vvvv));
current += PrintRightXMMOperand(current);
- AppendToBuffer(", (%s)", pseudo_op[*current]);
+ AppendToBuffer(", (%s)", cmp_pseudo_op[*current]);
current++;
break;
}
@@ -1999,11 +2014,9 @@ int DisassemblerIA32::InstructionDecode(v8::base::Vector<char> out_buffer,
data += PrintOperands("xadd", OPER_REG_OP_ORDER, data);
} else if (f0byte == 0xC2) {
data += 2;
- const char* const pseudo_op[] = {"eq", "lt", "le", "unord",
- "neq", "nlt", "nle", "ord"};
AppendToBuffer("cmpps %s, ", NameOfXMMRegister(regop));
data += PrintRightXMMOperand(data);
- AppendToBuffer(", (%s)", pseudo_op[*data]);
+ AppendToBuffer(", (%s)", cmp_pseudo_op[*data]);
data++;
} else if (f0byte == 0xC6) {
// shufps xmm, xmm/m128, imm8
@@ -2485,10 +2498,9 @@ int DisassemblerIA32::InstructionDecode(v8::base::Vector<char> out_buffer,
data++;
int mod, regop, rm;
get_modrm(*data, &mod, &regop, &rm);
- const char* const pseudo_op[] = {"eq", "lt", "le", "unord", "neq"};
AppendToBuffer("cmppd %s, ", NameOfXMMRegister(regop));
data += PrintRightXMMOperand(data);
- AppendToBuffer(", (%s)", pseudo_op[*data]);
+ AppendToBuffer(", (%s)", cmp_pseudo_op[*data]);
data++;
} else if (*data == 0xC4) {
data++;
@@ -2658,30 +2670,15 @@ int DisassemblerIA32::InstructionDecode(v8::base::Vector<char> out_buffer,
case 0x2D:
mnem = "cvtsd2si";
break;
- case 0x51:
- mnem = "sqrtsd";
- break;
- case 0x58:
- mnem = "addsd";
- break;
- case 0x59:
- mnem = "mulsd";
- break;
- case 0x5C:
- mnem = "subsd";
- break;
- case 0x5D:
- mnem = "minsd";
- break;
- case 0x5E:
- mnem = "divsd";
- break;
- case 0x5F:
- mnem = "maxsd";
- break;
case 0x7C:
mnem = "haddps";
break;
+#define MNEM_FOR_SSE2_INSTRUCTION_LSIT_SD(instruction, _1, _2, opcode) \
+ case 0x##opcode: \
+ mnem = "" #instruction; \
+ break;
+ SSE2_INSTRUCTION_LIST_SD(MNEM_FOR_SSE2_INSTRUCTION_LSIT_SD)
+#undef MNEM_FOR_SSE2_INSTRUCTION_LSIT_SD
}
data += 3;
int mod, regop, rm;
@@ -2694,10 +2691,7 @@ int DisassemblerIA32::InstructionDecode(v8::base::Vector<char> out_buffer,
data += PrintRightXMMOperand(data);
} else if (b2 == 0xC2) {
// Intel manual 2A, Table 3-18.
- const char* const pseudo_op[] = {
- "cmpeqsd", "cmpltsd", "cmplesd", "cmpunordsd",
- "cmpneqsd", "cmpnltsd", "cmpnlesd", "cmpordsd"};
- AppendToBuffer("%s %s,%s", pseudo_op[data[1]],
+ AppendToBuffer("cmp%ssd %s,%s", cmp_pseudo_op[data[1]],
NameOfXMMRegister(regop), NameOfXMMRegister(rm));
data += 2;
} else {
@@ -2835,10 +2829,7 @@ int DisassemblerIA32::InstructionDecode(v8::base::Vector<char> out_buffer,
data += PrintRightXMMOperand(data);
} else if (b2 == 0xC2) {
// Intel manual 2A, Table 3-18.
- const char* const pseudo_op[] = {
- "cmpeqss", "cmpltss", "cmpless", "cmpunordss",
- "cmpneqss", "cmpnltss", "cmpnless", "cmpordss"};
- AppendToBuffer("%s %s,%s", pseudo_op[data[1]],
+ AppendToBuffer("cmp%sss %s,%s", cmp_pseudo_op[data[1]],
NameOfXMMRegister(regop), NameOfXMMRegister(rm));
data += 2;
} else {
diff --git a/chromium/v8/src/diagnostics/loong64/disasm-loong64.cc b/chromium/v8/src/diagnostics/loong64/disasm-loong64.cc
new file mode 100644
index 00000000000..9d8aee96a3a
--- /dev/null
+++ b/chromium/v8/src/diagnostics/loong64/disasm-loong64.cc
@@ -0,0 +1,1711 @@
+// Copyright 2021 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 <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#if V8_TARGET_ARCH_LOONG64
+
+#include "src/base/platform/platform.h"
+#include "src/base/strings.h"
+#include "src/base/vector.h"
+#include "src/codegen/loong64/constants-loong64.h"
+#include "src/codegen/macro-assembler.h"
+#include "src/diagnostics/disasm.h"
+
+namespace v8 {
+namespace internal {
+
+//------------------------------------------------------------------------------
+
+// Decoder decodes and disassembles instructions into an output buffer.
+// It uses the converter to convert register names and call destinations into
+// more informative description.
+class Decoder {
+ public:
+ Decoder(const disasm::NameConverter& converter,
+ v8::base::Vector<char> out_buffer)
+ : converter_(converter), out_buffer_(out_buffer), out_buffer_pos_(0) {
+ out_buffer_[out_buffer_pos_] = '\0';
+ }
+
+ ~Decoder() {}
+
+ Decoder(const Decoder&) = delete;
+ Decoder& operator=(const Decoder&) = delete;
+
+ // Writes one disassembled instruction into 'buffer' (0-terminated).
+ // Returns the length of the disassembled machine instruction in bytes.
+ int InstructionDecode(byte* instruction);
+
+ private:
+ // Bottleneck functions to print into the out_buffer.
+ void PrintChar(const char ch);
+ void Print(const char* str);
+
+ // Printing of common values.
+ void PrintRegister(int reg);
+ void PrintFPURegister(int freg);
+ void PrintFPUStatusRegister(int freg);
+ void PrintRj(Instruction* instr);
+ void PrintRk(Instruction* instr);
+ void PrintRd(Instruction* instr);
+ void PrintFj(Instruction* instr);
+ void PrintFk(Instruction* instr);
+ void PrintFd(Instruction* instr);
+ void PrintFa(Instruction* instr);
+ void PrintSa2(Instruction* instr);
+ void PrintSa3(Instruction* instr);
+ void PrintUi5(Instruction* instr);
+ void PrintUi6(Instruction* instr);
+ void PrintUi12(Instruction* instr);
+ void PrintMsbw(Instruction* instr);
+ void PrintLsbw(Instruction* instr);
+ void PrintMsbd(Instruction* instr);
+ void PrintLsbd(Instruction* instr);
+ // void PrintCond(Instruction* instr);
+ void PrintSi12(Instruction* instr);
+ void PrintSi14(Instruction* instr);
+ void PrintSi16(Instruction* instr);
+ void PrintSi20(Instruction* instr);
+ void PrintXi12(Instruction* instr);
+ void PrintXi20(Instruction* instr);
+ void PrintCj(Instruction* instr);
+ void PrintCd(Instruction* instr);
+ void PrintCa(Instruction* instr);
+ void PrintCode(Instruction* instr);
+ void PrintHint5(Instruction* instr);
+ void PrintHint15(Instruction* instr);
+ void PrintPCOffs16(Instruction* instr);
+ void PrintPCOffs21(Instruction* instr);
+ void PrintPCOffs26(Instruction* instr);
+ void PrintOffs16(Instruction* instr);
+ void PrintOffs21(Instruction* instr);
+ void PrintOffs26(Instruction* instr);
+
+ // Handle formatting of instructions and their options.
+ int FormatRegister(Instruction* instr, const char* option);
+ int FormatFPURegister(Instruction* instr, const char* option);
+ int FormatOption(Instruction* instr, const char* option);
+ void Format(Instruction* instr, const char* format);
+ void Unknown(Instruction* instr);
+ int DecodeBreakInstr(Instruction* instr);
+
+ // Each of these functions decodes one particular instruction type.
+ int InstructionDecode(Instruction* instr);
+ void DecodeTypekOp6(Instruction* instr);
+ void DecodeTypekOp7(Instruction* instr);
+ void DecodeTypekOp8(Instruction* instr);
+ void DecodeTypekOp10(Instruction* instr);
+ void DecodeTypekOp12(Instruction* instr);
+ void DecodeTypekOp14(Instruction* instr);
+ int DecodeTypekOp17(Instruction* instr);
+ void DecodeTypekOp22(Instruction* instr);
+
+ const disasm::NameConverter& converter_;
+ v8::base::Vector<char> out_buffer_;
+ int out_buffer_pos_;
+};
+
+// Support for assertions in the Decoder formatting functions.
+#define STRING_STARTS_WITH(string, compare_string) \
+ (strncmp(string, compare_string, strlen(compare_string)) == 0)
+
+// Append the ch to the output buffer.
+void Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; }
+
+// Append the str to the output buffer.
+void Decoder::Print(const char* str) {
+ char cur = *str++;
+ while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
+ PrintChar(cur);
+ cur = *str++;
+ }
+ out_buffer_[out_buffer_pos_] = 0;
+}
+
+// Print the register name according to the active name converter.
+void Decoder::PrintRegister(int reg) {
+ Print(converter_.NameOfCPURegister(reg));
+}
+
+void Decoder::PrintRj(Instruction* instr) {
+ int reg = instr->RjValue();
+ PrintRegister(reg);
+}
+
+void Decoder::PrintRk(Instruction* instr) {
+ int reg = instr->RkValue();
+ PrintRegister(reg);
+}
+
+void Decoder::PrintRd(Instruction* instr) {
+ int reg = instr->RdValue();
+ PrintRegister(reg);
+}
+
+// Print the FPUregister name according to the active name converter.
+void Decoder::PrintFPURegister(int freg) {
+ Print(converter_.NameOfXMMRegister(freg));
+}
+
+void Decoder::PrintFj(Instruction* instr) {
+ int freg = instr->FjValue();
+ PrintFPURegister(freg);
+}
+
+void Decoder::PrintFk(Instruction* instr) {
+ int freg = instr->FkValue();
+ PrintFPURegister(freg);
+}
+
+void Decoder::PrintFd(Instruction* instr) {
+ int freg = instr->FdValue();
+ PrintFPURegister(freg);
+}
+
+void Decoder::PrintFa(Instruction* instr) {
+ int freg = instr->FaValue();
+ PrintFPURegister(freg);
+}
+
+// Print the integer value of the sa field.
+void Decoder::PrintSa2(Instruction* instr) {
+ int sa = instr->Sa2Value();
+ uint32_t opcode = (instr->InstructionBits() >> 18) << 18;
+ if (opcode == ALSL || opcode == ALSL_D) {
+ sa += 1;
+ }
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa);
+}
+
+void Decoder::PrintSa3(Instruction* instr) {
+ int sa = instr->Sa3Value();
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa);
+}
+
+void Decoder::PrintUi5(Instruction* instr) {
+ int ui = instr->Ui5Value();
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", ui);
+}
+
+void Decoder::PrintUi6(Instruction* instr) {
+ int ui = instr->Ui6Value();
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", ui);
+}
+
+void Decoder::PrintUi12(Instruction* instr) {
+ int ui = instr->Ui12Value();
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", ui);
+}
+
+void Decoder::PrintXi12(Instruction* instr) {
+ int xi = instr->Ui12Value();
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", xi);
+}
+
+void Decoder::PrintXi20(Instruction* instr) {
+ int xi = instr->Si20Value();
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", xi);
+}
+
+void Decoder::PrintMsbd(Instruction* instr) {
+ int msbd = instr->MsbdValue();
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", msbd);
+}
+
+void Decoder::PrintLsbd(Instruction* instr) {
+ int lsbd = instr->LsbdValue();
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", lsbd);
+}
+
+void Decoder::PrintMsbw(Instruction* instr) {
+ int msbw = instr->MsbwValue();
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", msbw);
+}
+
+void Decoder::PrintLsbw(Instruction* instr) {
+ int lsbw = instr->LsbwValue();
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", lsbw);
+}
+
+void Decoder::PrintSi12(Instruction* instr) {
+ int si = ((instr->Si12Value()) << (32 - kSi12Bits)) >> (32 - kSi12Bits);
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d(0x%x)",
+ si, instr->Si12Value());
+}
+
+void Decoder::PrintSi14(Instruction* instr) {
+ int si = ((instr->Si14Value()) << (32 - kSi14Bits)) >> (32 - kSi14Bits);
+ si <<= 2;
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d(0x%x)",
+ si, instr->Si14Value() << 2);
+}
+
+void Decoder::PrintSi16(Instruction* instr) {
+ int si = ((instr->Si16Value()) << (32 - kSi16Bits)) >> (32 - kSi16Bits);
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d(0x%x)",
+ si, instr->Si16Value());
+}
+
+void Decoder::PrintSi20(Instruction* instr) {
+ int si = ((instr->Si20Value()) << (32 - kSi20Bits)) >> (32 - kSi20Bits);
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d(0x%x)",
+ si, instr->Si20Value());
+}
+
+void Decoder::PrintCj(Instruction* instr) {
+ int cj = instr->CjValue();
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", cj);
+}
+
+void Decoder::PrintCd(Instruction* instr) {
+ int cd = instr->CdValue();
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", cd);
+}
+
+void Decoder::PrintCa(Instruction* instr) {
+ int ca = instr->CaValue();
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", ca);
+}
+
+void Decoder::PrintCode(Instruction* instr) {
+ int code = instr->CodeValue();
+ out_buffer_pos_ +=
+ base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x(%u)", code, code);
+}
+
+void Decoder::PrintHint5(Instruction* instr) {
+ int hint = instr->Hint5Value();
+ out_buffer_pos_ +=
+ base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x(%u)", hint, hint);
+}
+
+void Decoder::PrintHint15(Instruction* instr) {
+ int hint = instr->Hint15Value();
+ out_buffer_pos_ +=
+ base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x(%u)", hint, hint);
+}
+
+void Decoder::PrintPCOffs16(Instruction* instr) {
+ int n_bits = 2;
+ int offs = instr->Offs16Value();
+ int target = ((offs << n_bits) << (32 - kOffsLowBits - n_bits)) >>
+ (32 - kOffsLowBits - n_bits);
+ out_buffer_pos_ += base::SNPrintF(
+ out_buffer_ + out_buffer_pos_, "%s",
+ converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + target));
+}
+
+void Decoder::PrintPCOffs21(Instruction* instr) {
+ int n_bits = 2;
+ int offs = instr->Offs21Value();
+ int target =
+ ((offs << n_bits) << (32 - kOffsLowBits - kOffs21HighBits - n_bits)) >>
+ (32 - kOffsLowBits - kOffs21HighBits - n_bits);
+ out_buffer_pos_ += base::SNPrintF(
+ out_buffer_ + out_buffer_pos_, "%s",
+ converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + target));
+}
+
+void Decoder::PrintPCOffs26(Instruction* instr) {
+ int n_bits = 2;
+ int offs = instr->Offs26Value();
+ int target =
+ ((offs << n_bits) << (32 - kOffsLowBits - kOffs26HighBits - n_bits)) >>
+ (32 - kOffsLowBits - kOffs26HighBits - n_bits);
+ out_buffer_pos_ += base::SNPrintF(
+ out_buffer_ + out_buffer_pos_, "%s",
+ converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + target));
+}
+
+void Decoder::PrintOffs16(Instruction* instr) {
+ int offs = instr->Offs16Value();
+ out_buffer_pos_ +=
+ base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", offs << 2);
+}
+
+void Decoder::PrintOffs21(Instruction* instr) {
+ int offs = instr->Offs21Value();
+ out_buffer_pos_ +=
+ base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", offs << 2);
+}
+
+void Decoder::PrintOffs26(Instruction* instr) {
+ int offs = instr->Offs26Value();
+ out_buffer_pos_ +=
+ base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", offs << 2);
+}
+
+// Handle all register based formatting in this function to reduce the
+// complexity of FormatOption.
+int Decoder::FormatRegister(Instruction* instr, const char* format) {
+ DCHECK_EQ(format[0], 'r');
+ if (format[1] == 'j') { // 'rj: Rj register.
+ int reg = instr->RjValue();
+ PrintRegister(reg);
+ return 2;
+ } else if (format[1] == 'k') { // 'rk: rk register.
+ int reg = instr->RkValue();
+ PrintRegister(reg);
+ return 2;
+ } else if (format[1] == 'd') { // 'rd: rd register.
+ int reg = instr->RdValue();
+ PrintRegister(reg);
+ return 2;
+ }
+ UNREACHABLE();
+}
+
+// Handle all FPUregister based formatting in this function to reduce the
+// complexity of FormatOption.
+int Decoder::FormatFPURegister(Instruction* instr, const char* format) {
+ DCHECK_EQ(format[0], 'f');
+ if (format[1] == 'j') { // 'fj: fj register.
+ int reg = instr->FjValue();
+ PrintFPURegister(reg);
+ return 2;
+ } else if (format[1] == 'k') { // 'fk: fk register.
+ int reg = instr->FkValue();
+ PrintFPURegister(reg);
+ return 2;
+ } else if (format[1] == 'd') { // 'fd: fd register.
+ int reg = instr->FdValue();
+ PrintFPURegister(reg);
+ return 2;
+ } else if (format[1] == 'a') { // 'fa: fa register.
+ int reg = instr->FaValue();
+ PrintFPURegister(reg);
+ return 2;
+ }
+ UNREACHABLE();
+}
+
+// FormatOption takes a formatting string and interprets it based on
+// the current instructions. The format string points to the first
+// character of the option string (the option escape has already been
+// consumed by the caller.) FormatOption returns the number of
+// characters that were consumed from the formatting string.
+int Decoder::FormatOption(Instruction* instr, const char* format) {
+ switch (format[0]) {
+ case 'c': {
+ switch (format[1]) {
+ case 'a':
+ DCHECK(STRING_STARTS_WITH(format, "ca"));
+ PrintCa(instr);
+ return 2;
+ case 'd':
+ DCHECK(STRING_STARTS_WITH(format, "cd"));
+ PrintCd(instr);
+ return 2;
+ case 'j':
+ DCHECK(STRING_STARTS_WITH(format, "cj"));
+ PrintCj(instr);
+ return 2;
+ case 'o':
+ DCHECK(STRING_STARTS_WITH(format, "code"));
+ PrintCode(instr);
+ return 4;
+ }
+ }
+ case 'f': {
+ return FormatFPURegister(instr, format);
+ }
+ case 'h': {
+ if (format[4] == '5') {
+ DCHECK(STRING_STARTS_WITH(format, "hint5"));
+ PrintHint5(instr);
+ return 5;
+ } else if (format[4] == '1') {
+ DCHECK(STRING_STARTS_WITH(format, "hint15"));
+ PrintHint15(instr);
+ return 6;
+ }
+ break;
+ }
+ case 'l': {
+ switch (format[3]) {
+ case 'w':
+ DCHECK(STRING_STARTS_WITH(format, "lsbw"));
+ PrintLsbw(instr);
+ return 4;
+ case 'd':
+ DCHECK(STRING_STARTS_WITH(format, "lsbd"));
+ PrintLsbd(instr);
+ return 4;
+ default:
+ return 0;
+ }
+ }
+ case 'm': {
+ if (format[3] == 'w') {
+ DCHECK(STRING_STARTS_WITH(format, "msbw"));
+ PrintMsbw(instr);
+ } else if (format[3] == 'd') {
+ DCHECK(STRING_STARTS_WITH(format, "msbd"));
+ PrintMsbd(instr);
+ }
+ return 4;
+ }
+ case 'o': {
+ if (format[1] == 'f') {
+ if (format[4] == '1') {
+ DCHECK(STRING_STARTS_WITH(format, "offs16"));
+ PrintOffs16(instr);
+ return 6;
+ } else if (format[4] == '2') {
+ if (format[5] == '1') {
+ DCHECK(STRING_STARTS_WITH(format, "offs21"));
+ PrintOffs21(instr);
+ return 6;
+ } else if (format[5] == '6') {
+ DCHECK(STRING_STARTS_WITH(format, "offs26"));
+ PrintOffs26(instr);
+ return 6;
+ }
+ }
+ }
+ break;
+ }
+ case 'p': {
+ if (format[6] == '1') {
+ DCHECK(STRING_STARTS_WITH(format, "pcoffs16"));
+ PrintPCOffs16(instr);
+ return 8;
+ } else if (format[6] == '2') {
+ if (format[7] == '1') {
+ DCHECK(STRING_STARTS_WITH(format, "pcoffs21"));
+ PrintPCOffs21(instr);
+ return 8;
+ } else if (format[7] == '6') {
+ DCHECK(STRING_STARTS_WITH(format, "pcoffs26"));
+ PrintPCOffs26(instr);
+ return 8;
+ }
+ }
+ break;
+ }
+ case 'r': {
+ return FormatRegister(instr, format);
+ }
+ case 's': {
+ switch (format[1]) {
+ case 'a':
+ if (format[2] == '2') {
+ DCHECK(STRING_STARTS_WITH(format, "sa2"));
+ PrintSa2(instr);
+ } else if (format[2] == '3') {
+ DCHECK(STRING_STARTS_WITH(format, "sa3"));
+ PrintSa3(instr);
+ }
+ return 3;
+ case 'i':
+ if (format[2] == '2') {
+ DCHECK(STRING_STARTS_WITH(format, "si20"));
+ PrintSi20(instr);
+ return 4;
+ } else if (format[2] == '1') {
+ switch (format[3]) {
+ case '2':
+ DCHECK(STRING_STARTS_WITH(format, "si12"));
+ PrintSi12(instr);
+ return 4;
+ case '4':
+ DCHECK(STRING_STARTS_WITH(format, "si14"));
+ PrintSi14(instr);
+ return 4;
+ case '6':
+ DCHECK(STRING_STARTS_WITH(format, "si16"));
+ PrintSi16(instr);
+ return 4;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case 'u': {
+ if (format[2] == '5') {
+ DCHECK(STRING_STARTS_WITH(format, "ui5"));
+ PrintUi5(instr);
+ return 3;
+ } else if (format[2] == '6') {
+ DCHECK(STRING_STARTS_WITH(format, "ui6"));
+ PrintUi6(instr);
+ return 3;
+ } else if (format[2] == '1') {
+ DCHECK(STRING_STARTS_WITH(format, "ui12"));
+ PrintUi12(instr);
+ return 4;
+ }
+ break;
+ }
+ case 'x': {
+ if (format[2] == '2') {
+ DCHECK(STRING_STARTS_WITH(format, "xi20"));
+ PrintXi20(instr);
+ return 4;
+ } else if (format[3] == '2') {
+ DCHECK(STRING_STARTS_WITH(format, "xi12"));
+ PrintXi12(instr);
+ return 4;
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ return 0;
+}
+
+// Format takes a formatting string for a whole instruction and prints it into
+// the output buffer. All escaped options are handed to FormatOption to be
+// parsed further.
+void Decoder::Format(Instruction* instr, const char* format) {
+ char cur = *format++;
+ while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
+ if (cur == '\'') { // Single quote is used as the formatting escape.
+ format += FormatOption(instr, format);
+ } else {
+ out_buffer_[out_buffer_pos_++] = cur;
+ }
+ cur = *format++;
+ }
+ out_buffer_[out_buffer_pos_] = '\0';
+}
+
+// For currently unimplemented decodings the disassembler calls Unknown(instr)
+// which will just print "unknown" of the instruction bits.
+void Decoder::Unknown(Instruction* instr) { Format(instr, "unknown"); }
+
+int Decoder::DecodeBreakInstr(Instruction* instr) {
+ // This is already known to be BREAK instr, just extract the code.
+ /*if (instr->Bits(14, 0) == static_cast<int>(kMaxStopCode)) {
+ // This is stop(msg).
+ Format(instr, "break, code: 'code");
+ out_buffer_pos_ += SNPrintF(
+ out_buffer_ + out_buffer_pos_, "\n%p %08" PRIx64,
+ static_cast<void*>(reinterpret_cast<int32_t*>(instr + kInstrSize)),
+ reinterpret_cast<uint64_t>(
+ *reinterpret_cast<char**>(instr + kInstrSize)));
+ // Size 3: the break_ instr, plus embedded 64-bit char pointer.
+ return 3 * kInstrSize;
+ } else {
+ Format(instr, "break, code: 'code");
+ return kInstrSize;
+ }*/
+ Format(instr, "break code: 'code");
+ return kInstrSize;
+} //===================================================
+
+void Decoder::DecodeTypekOp6(Instruction* instr) {
+ switch (instr->Bits(31, 26) << 26) {
+ case ADDU16I_D:
+ Format(instr, "addu16i.d 'rd, 'rj, 'si16");
+ break;
+ case BEQZ:
+ Format(instr, "beqz 'rj, 'offs21 -> 'pcoffs21");
+ break;
+ case BNEZ:
+ Format(instr, "bnez 'rj, 'offs21 -> 'pcoffs21");
+ break;
+ case BCZ:
+ if (instr->Bit(8))
+ Format(instr, "bcnez fcc'cj, 'offs21 -> 'pcoffs21");
+ else
+ Format(instr, "bceqz fcc'cj, 'offs21 -> 'pcoffs21");
+ break;
+ case JIRL:
+ Format(instr, "jirl 'rd, 'rj, 'offs16");
+ break;
+ case B:
+ Format(instr, "b 'offs26 -> 'pcoffs26");
+ break;
+ case BL:
+ Format(instr, "bl 'offs26 -> 'pcoffs26");
+ break;
+ case BEQ:
+ Format(instr, "beq 'rj, 'rd, 'offs16 -> 'pcoffs16");
+ break;
+ case BNE:
+ Format(instr, "bne 'rj, 'rd, 'offs16 -> 'pcoffs16");
+ break;
+ case BLT:
+ Format(instr, "blt 'rj, 'rd, 'offs16 -> 'pcoffs16");
+ break;
+ case BGE:
+ Format(instr, "bge 'rj, 'rd, 'offs16 -> 'pcoffs16");
+ break;
+ case BLTU:
+ Format(instr, "bltu 'rj, 'rd, 'offs16 -> 'pcoffs16");
+ break;
+ case BGEU:
+ Format(instr, "bgeu 'rj, 'rd, 'offs16 -> 'pcoffs16");
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+void Decoder::DecodeTypekOp7(Instruction* instr) {
+ switch (instr->Bits(31, 25) << 25) {
+ case LU12I_W:
+ Format(instr, "lu12i.w 'rd, 'xi20");
+ break;
+ case LU32I_D:
+ Format(instr, "lu32i.d 'rd, 'xi20");
+ break;
+ case PCADDI:
+ Format(instr, "pcaddi 'rd, 'xi20");
+ break;
+ case PCALAU12I:
+ Format(instr, "pcalau12i 'rd, 'xi20");
+ break;
+ case PCADDU12I:
+ Format(instr, "pcaddu12i 'rd, 'xi20");
+ break;
+ case PCADDU18I:
+ Format(instr, "pcaddu18i 'rd, 'xi20");
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+void Decoder::DecodeTypekOp8(Instruction* instr) {
+ switch (instr->Bits(31, 24) << 24) {
+ case LDPTR_W:
+ Format(instr, "ldptr.w 'rd, 'rj, 'si14");
+ break;
+ case STPTR_W:
+ Format(instr, "stptr.w 'rd, 'rj, 'si14");
+ break;
+ case LDPTR_D:
+ Format(instr, "ldptr.d 'rd, 'rj, 'si14");
+ break;
+ case STPTR_D:
+ Format(instr, "stptr.d 'rd, 'rj, 'si14");
+ break;
+ case LL_W:
+ Format(instr, "ll.w 'rd, 'rj, 'si14");
+ break;
+ case SC_W:
+ Format(instr, "sc.w 'rd, 'rj, 'si14");
+ break;
+ case LL_D:
+ Format(instr, "ll.d 'rd, 'rj, 'si14");
+ break;
+ case SC_D:
+ Format(instr, "sc.d 'rd, 'rj, 'si14");
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+void Decoder::DecodeTypekOp10(Instruction* instr) {
+ switch (instr->Bits(31, 22) << 22) {
+ case BSTR_W: {
+ if (instr->Bit(21) != 0) {
+ if (instr->Bit(15) == 0) {
+ Format(instr, "bstrins.w 'rd, 'rj, 'msbw, 'lsbw");
+ } else {
+ Format(instr, "bstrpick.w 'rd, 'rj, 'msbw, 'lsbw");
+ }
+ }
+ break;
+ }
+ case BSTRINS_D:
+ Format(instr, "bstrins.d 'rd, 'rj, 'msbd, 'lsbd");
+ break;
+ case BSTRPICK_D:
+ Format(instr, "bstrpick.d 'rd, 'rj, 'msbd, 'lsbd");
+ break;
+ case SLTI:
+ Format(instr, "slti 'rd, 'rj, 'si12");
+ break;
+ case SLTUI:
+ Format(instr, "sltui 'rd, 'rj, 'si12");
+ break;
+ case ADDI_W:
+ Format(instr, "addi.w 'rd, 'rj, 'si12");
+ break;
+ case ADDI_D:
+ Format(instr, "addi.d 'rd, 'rj, 'si12");
+ break;
+ case LU52I_D:
+ Format(instr, "lu52i.d 'rd, 'rj, 'xi12");
+ break;
+ case ANDI:
+ Format(instr, "andi 'rd, 'rj, 'xi12");
+ break;
+ case ORI:
+ Format(instr, "ori 'rd, 'rj, 'xi12");
+ break;
+ case XORI:
+ Format(instr, "xori 'rd, 'rj, 'xi12");
+ break;
+ case LD_B:
+ Format(instr, "ld.b 'rd, 'rj, 'si12");
+ break;
+ case LD_H:
+ Format(instr, "ld.h 'rd, 'rj, 'si12");
+ break;
+ case LD_W:
+ Format(instr, "ld.w 'rd, 'rj, 'si12");
+ break;
+ case LD_D:
+ Format(instr, "ld.d 'rd, 'rj, 'si12");
+ break;
+ case ST_B:
+ Format(instr, "st.b 'rd, 'rj, 'si12");
+ break;
+ case ST_H:
+ Format(instr, "st.h 'rd, 'rj, 'si12");
+ break;
+ case ST_W:
+ Format(instr, "st.w 'rd, 'rj, 'si12");
+ break;
+ case ST_D:
+ Format(instr, "st.d 'rd, 'rj, 'si12");
+ break;
+ case LD_BU:
+ Format(instr, "ld.bu 'rd, 'rj, 'si12");
+ break;
+ case LD_HU:
+ Format(instr, "ld.hu 'rd, 'rj, 'si12");
+ break;
+ case LD_WU:
+ Format(instr, "ld.wu 'rd, 'rj, 'si12");
+ break;
+ case FLD_S:
+ Format(instr, "fld.s 'fd, 'rj, 'si12");
+ break;
+ case FST_S:
+ Format(instr, "fst.s 'fd, 'rj, 'si12");
+ break;
+ case FLD_D:
+ Format(instr, "fld.d 'fd, 'rj, 'si12");
+ break;
+ case FST_D:
+ Format(instr, "fst.d 'fd, 'rj, 'si12");
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+void Decoder::DecodeTypekOp12(Instruction* instr) {
+ switch (instr->Bits(31, 20) << 20) {
+ case FMADD_S:
+ Format(instr, "fmadd.s 'fd, 'fj, 'fk, 'fa");
+ break;
+ case FMADD_D:
+ Format(instr, "fmadd.d 'fd, 'fj, 'fk, 'fa");
+ break;
+ case FMSUB_S:
+ Format(instr, "fmsub.s 'fd, 'fj, 'fk, 'fa");
+ break;
+ case FMSUB_D:
+ Format(instr, "fmsub.d 'fd, 'fj, 'fk, 'fa");
+ break;
+ case FNMADD_S:
+ Format(instr, "fnmadd.s 'fd, 'fj, 'fk, 'fa");
+ break;
+ case FNMADD_D:
+ Format(instr, "fnmadd.d 'fd, 'fj, 'fk, 'fa");
+ break;
+ case FNMSUB_S:
+ Format(instr, "fnmsub.s 'fd, 'fj, 'fk, 'fa");
+ break;
+ case FNMSUB_D:
+ Format(instr, "fnmsub.d 'fd, 'fj, 'fk, 'fa");
+ break;
+ case FCMP_COND_S:
+ switch (instr->Bits(19, 15)) {
+ case CAF:
+ Format(instr, "fcmp.caf.s fcc'cd, 'fj, 'fk");
+ break;
+ case SAF:
+ Format(instr, "fcmp.saf.s fcc'cd, 'fj, 'fk");
+ break;
+ case CLT:
+ Format(instr, "fcmp.clt.s fcc'cd, 'fj, 'fk");
+ break;
+ case CEQ:
+ Format(instr, "fcmp.ceq.s fcc'cd, 'fj, 'fk");
+ break;
+ case SEQ:
+ Format(instr, "fcmp.seq.s fcc'cd, 'fj, 'fk");
+ break;
+ case CLE:
+ Format(instr, "fcmp.cle.s fcc'cd, 'fj, 'fk");
+ break;
+ case SLE:
+ Format(instr, "fcmp.sle.s fcc'cd, 'fj, 'fk");
+ break;
+ case CUN:
+ Format(instr, "fcmp.cun.s fcc'cd, 'fj, 'fk");
+ break;
+ case SUN:
+ Format(instr, "fcmp.sun.s fcc'cd, 'fj, 'fk");
+ break;
+ case CULT:
+ Format(instr, "fcmp.cult.s fcc'cd, 'fj, 'fk");
+ break;
+ case SULT:
+ Format(instr, "fcmp.sult.s fcc'cd, 'fj, 'fk");
+ break;
+ case CUEQ:
+ Format(instr, "fcmp.cueq.s fcc'cd, 'fj, 'fk");
+ break;
+ case SUEQ:
+ Format(instr, "fcmp.sueq.s fcc'cd, 'fj, 'fk");
+ break;
+ case CULE:
+ Format(instr, "fcmp.cule.s fcc'cd, 'fj, 'fk");
+ break;
+ case SULE:
+ Format(instr, "fcmp.sule.s fcc'cd, 'fj, 'fk");
+ break;
+ case CNE:
+ Format(instr, "fcmp.cne.s fcc'cd, 'fj, 'fk");
+ break;
+ case SNE:
+ Format(instr, "fcmp.sne.s fcc'cd, 'fj, 'fk");
+ break;
+ case COR:
+ Format(instr, "fcmp.cor.s fcc'cd, 'fj, 'fk");
+ break;
+ case SOR:
+ Format(instr, "fcmp.sor.s fcc'cd, 'fj, 'fk");
+ break;
+ case CUNE:
+ Format(instr, "fcmp.cune.s fcc'cd, 'fj, 'fk");
+ break;
+ case SUNE:
+ Format(instr, "fcmp.sune.s fcc'cd, 'fj, 'fk");
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ case FCMP_COND_D:
+ switch (instr->Bits(19, 15)) {
+ case CAF:
+ Format(instr, "fcmp.caf.d fcc'cd, 'fj, 'fk");
+ break;
+ case SAF:
+ Format(instr, "fcmp.saf.d fcc'cd, 'fj, 'fk");
+ break;
+ case CLT:
+ Format(instr, "fcmp.clt.d fcc'cd, 'fj, 'fk");
+ break;
+ case CEQ:
+ Format(instr, "fcmp.ceq.d fcc'cd, 'fj, 'fk");
+ break;
+ case SEQ:
+ Format(instr, "fcmp.seq.d fcc'cd, 'fj, 'fk");
+ break;
+ case CLE:
+ Format(instr, "fcmp.cle.d fcc'cd, 'fj, 'fk");
+ break;
+ case SLE:
+ Format(instr, "fcmp.sle.d fcc'cd, 'fj, 'fk");
+ break;
+ case CUN:
+ Format(instr, "fcmp.cun.d fcc'cd, 'fj, 'fk");
+ break;
+ case SUN:
+ Format(instr, "fcmp.sun.d fcc'cd, 'fj, 'fk");
+ break;
+ case CULT:
+ Format(instr, "fcmp.cult.d fcc'cd, 'fj, 'fk");
+ break;
+ case SULT:
+ Format(instr, "fcmp.sult.d fcc'cd, 'fj, 'fk");
+ break;
+ case CUEQ:
+ Format(instr, "fcmp.cueq.d fcc'cd, 'fj, 'fk");
+ break;
+ case SUEQ:
+ Format(instr, "fcmp.sueq.d fcc'cd, 'fj, 'fk");
+ break;
+ case CULE:
+ Format(instr, "fcmp.cule.d fcc'cd, 'fj, 'fk");
+ break;
+ case SULE:
+ Format(instr, "fcmp.sule.d fcc'cd, 'fj, 'fk");
+ break;
+ case CNE:
+ Format(instr, "fcmp.cne.d fcc'cd, 'fj, 'fk");
+ break;
+ case SNE:
+ Format(instr, "fcmp.sne.d fcc'cd, 'fj, 'fk");
+ break;
+ case COR:
+ Format(instr, "fcmp.cor.d fcc'cd, 'fj, 'fk");
+ break;
+ case SOR:
+ Format(instr, "fcmp.sor.d fcc'cd, 'fj, 'fk");
+ break;
+ case CUNE:
+ Format(instr, "fcmp.cune.d fcc'cd, 'fj, 'fk");
+ break;
+ case SUNE:
+ Format(instr, "fcmp.sune.d fcc'cd, 'fj, 'fk");
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ case FSEL:
+ Format(instr, "fsel 'fd, 'fj, 'fk, fcc'ca");
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+void Decoder::DecodeTypekOp14(Instruction* instr) {
+ switch (instr->Bits(31, 18) << 18) {
+ case ALSL:
+ if (instr->Bit(17))
+ Format(instr, "alsl.wu 'rd, 'rj, 'rk, 'sa2");
+ else
+ Format(instr, "alsl.w 'rd, 'rj, 'rk, 'sa2");
+ break;
+ case BYTEPICK_W:
+ Format(instr, "bytepick.w 'rd, 'rj, 'rk, 'sa2");
+ break;
+ case BYTEPICK_D:
+ Format(instr, "bytepick.d 'rd, 'rj, 'rk, 'sa3");
+ break;
+ case ALSL_D:
+ Format(instr, "alsl.d 'rd, 'rj, 'rk, 'sa2");
+ break;
+ case SLLI:
+ if (instr->Bit(16))
+ Format(instr, "slli.d 'rd, 'rj, 'ui6");
+ else
+ Format(instr, "slli.w 'rd, 'rj, 'ui5");
+ break;
+ case SRLI:
+ if (instr->Bit(16))
+ Format(instr, "srli.d 'rd, 'rj, 'ui6");
+ else
+ Format(instr, "srli.w 'rd, 'rj, 'ui5");
+ break;
+ case SRAI:
+ if (instr->Bit(16))
+ Format(instr, "srai.d 'rd, 'rj, 'ui6");
+ else
+ Format(instr, "srai.w 'rd, 'rj, 'ui5");
+ break;
+ case ROTRI:
+ if (instr->Bit(16))
+ Format(instr, "rotri.d 'rd, 'rj, 'ui6");
+ else
+ Format(instr, "rotri.w 'rd, 'rj, 'ui5");
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+int Decoder::DecodeTypekOp17(Instruction* instr) {
+ switch (instr->Bits(31, 15) << 15) {
+ case ADD_W:
+ Format(instr, "add.w 'rd, 'rj, 'rk");
+ break;
+ case ADD_D:
+ Format(instr, "add.d 'rd, 'rj, 'rk");
+ break;
+ case SUB_W:
+ Format(instr, "sub.w 'rd, 'rj, 'rk");
+ break;
+ case SUB_D:
+ Format(instr, "sub.d 'rd, 'rj, 'rk");
+ break;
+ case SLT:
+ Format(instr, "slt 'rd, 'rj, 'rk");
+ break;
+ case SLTU:
+ Format(instr, "sltu 'rd, 'rj, 'rk");
+ break;
+ case MASKEQZ:
+ Format(instr, "maskeqz 'rd, 'rj, 'rk");
+ break;
+ case MASKNEZ:
+ Format(instr, "masknez 'rd, 'rj, 'rk");
+ break;
+ case NOR:
+ Format(instr, "nor 'rd, 'rj, 'rk");
+ break;
+ case AND:
+ Format(instr, "and 'rd, 'rj, 'rk");
+ break;
+ case OR:
+ Format(instr, "or 'rd, 'rj, 'rk");
+ break;
+ case XOR:
+ Format(instr, "xor 'rd, 'rj, 'rk");
+ break;
+ case ORN:
+ Format(instr, "orn 'rd, 'rj, 'rk");
+ break;
+ case ANDN:
+ Format(instr, "andn 'rd, 'rj, 'rk");
+ break;
+ case SLL_W:
+ Format(instr, "sll.w 'rd, 'rj, 'rk");
+ break;
+ case SRL_W:
+ Format(instr, "srl.w 'rd, 'rj, 'rk");
+ break;
+ case SRA_W:
+ Format(instr, "sra.w 'rd, 'rj, 'rk");
+ break;
+ case SLL_D:
+ Format(instr, "sll.d 'rd, 'rj, 'rk");
+ break;
+ case SRL_D:
+ Format(instr, "srl.d 'rd, 'rj, 'rk");
+ break;
+ case SRA_D:
+ Format(instr, "sra.d 'rd, 'rj, 'rk");
+ break;
+ case ROTR_D:
+ Format(instr, "rotr.d 'rd, 'rj, 'rk");
+ break;
+ case ROTR_W:
+ Format(instr, "rotr.w 'rd, 'rj, 'rk");
+ break;
+ case MUL_W:
+ Format(instr, "mul.w 'rd, 'rj, 'rk");
+ break;
+ case MULH_W:
+ Format(instr, "mulh.w 'rd, 'rj, 'rk");
+ break;
+ case MULH_WU:
+ Format(instr, "mulh.wu 'rd, 'rj, 'rk");
+ break;
+ case MUL_D:
+ Format(instr, "mul.d 'rd, 'rj, 'rk");
+ break;
+ case MULH_D:
+ Format(instr, "mulh.d 'rd, 'rj, 'rk");
+ break;
+ case MULH_DU:
+ Format(instr, "mulh.du 'rd, 'rj, 'rk");
+ break;
+ case MULW_D_W:
+ Format(instr, "mulw.d.w 'rd, 'rj, 'rk");
+ break;
+ case MULW_D_WU:
+ Format(instr, "mulw.d.wu 'rd, 'rj, 'rk");
+ break;
+ case DIV_W:
+ Format(instr, "div.w 'rd, 'rj, 'rk");
+ break;
+ case MOD_W:
+ Format(instr, "mod.w 'rd, 'rj, 'rk");
+ break;
+ case DIV_WU:
+ Format(instr, "div.wu 'rd, 'rj, 'rk");
+ break;
+ case MOD_WU:
+ Format(instr, "mod.wu 'rd, 'rj, 'rk");
+ break;
+ case DIV_D:
+ Format(instr, "div.d 'rd, 'rj, 'rk");
+ break;
+ case MOD_D:
+ Format(instr, "mod.d 'rd, 'rj, 'rk");
+ break;
+ case DIV_DU:
+ Format(instr, "div.du 'rd, 'rj, 'rk");
+ break;
+ case MOD_DU:
+ Format(instr, "mod.du 'rd, 'rj, 'rk");
+ break;
+ case BREAK:
+ return DecodeBreakInstr(instr);
+ case FADD_S:
+ Format(instr, "fadd.s 'fd, 'fj, 'fk");
+ break;
+ case FADD_D:
+ Format(instr, "fadd.d 'fd, 'fj, 'fk");
+ break;
+ case FSUB_S:
+ Format(instr, "fsub.s 'fd, 'fj, 'fk");
+ break;
+ case FSUB_D:
+ Format(instr, "fsub.d 'fd, 'fj, 'fk");
+ break;
+ case FMUL_S:
+ Format(instr, "fmul.s 'fd, 'fj, 'fk");
+ break;
+ case FMUL_D:
+ Format(instr, "fmul.d 'fd, 'fj, 'fk");
+ break;
+ case FDIV_S:
+ Format(instr, "fdiv.s 'fd, 'fj, 'fk");
+ break;
+ case FDIV_D:
+ Format(instr, "fdiv.d 'fd, 'fj, 'fk");
+ break;
+ case FMAX_S:
+ Format(instr, "fmax.s 'fd, 'fj, 'fk");
+ break;
+ case FMAX_D:
+ Format(instr, "fmax.d 'fd, 'fj, 'fk");
+ break;
+ case FMIN_S:
+ Format(instr, "fmin.s 'fd, 'fj, 'fk");
+ break;
+ case FMIN_D:
+ Format(instr, "fmin.d 'fd, 'fj, 'fk");
+ break;
+ case FMAXA_S:
+ Format(instr, "fmaxa.s 'fd, 'fj, 'fk");
+ break;
+ case FMAXA_D:
+ Format(instr, "fmaxa.d 'fd, 'fj, 'fk");
+ break;
+ case FMINA_S:
+ Format(instr, "fmina.s 'fd, 'fj, 'fk");
+ break;
+ case FMINA_D:
+ Format(instr, "fmina.d 'fd, 'fj, 'fk");
+ break;
+ case LDX_B:
+ Format(instr, "ldx.b 'rd, 'rj, 'rk");
+ break;
+ case LDX_H:
+ Format(instr, "ldx.h 'rd, 'rj, 'rk");
+ break;
+ case LDX_W:
+ Format(instr, "ldx.w 'rd, 'rj, 'rk");
+ break;
+ case LDX_D:
+ Format(instr, "ldx.d 'rd, 'rj, 'rk");
+ break;
+ case STX_B:
+ Format(instr, "stx.b 'rd, 'rj, 'rk");
+ break;
+ case STX_H:
+ Format(instr, "stx.h 'rd, 'rj, 'rk");
+ break;
+ case STX_W:
+ Format(instr, "stx.w 'rd, 'rj, 'rk");
+ break;
+ case STX_D:
+ Format(instr, "stx.d 'rd, 'rj, 'rk");
+ break;
+ case LDX_BU:
+ Format(instr, "ldx.bu 'rd, 'rj, 'rk");
+ break;
+ case LDX_HU:
+ Format(instr, "ldx.hu 'rd, 'rj, 'rk");
+ break;
+ case LDX_WU:
+ Format(instr, "ldx.wu 'rd, 'rj, 'rk");
+ break;
+ case FLDX_S:
+ Format(instr, "fldx.s 'fd, 'rj, 'rk");
+ break;
+ case FLDX_D:
+ Format(instr, "fldx.d 'fd, 'rj, 'rk");
+ break;
+ case FSTX_S:
+ Format(instr, "fstx.s 'fd, 'rj, 'rk");
+ break;
+ case FSTX_D:
+ Format(instr, "fstx.d 'fd, 'rj, 'rk");
+ break;
+ case AMSWAP_W:
+ Format(instr, "amswap.w 'rd, 'rk, 'rj");
+ break;
+ case AMSWAP_D:
+ Format(instr, "amswap.d 'rd, 'rk, 'rj");
+ break;
+ case AMADD_W:
+ Format(instr, "amadd.w 'rd, 'rk, 'rj");
+ break;
+ case AMADD_D:
+ Format(instr, "amadd.d 'rd, 'rk, 'rj");
+ break;
+ case AMAND_W:
+ Format(instr, "amand.w 'rd, 'rk, 'rj");
+ break;
+ case AMAND_D:
+ Format(instr, "amand.d 'rd, 'rk, 'rj");
+ break;
+ case AMOR_W:
+ Format(instr, "amor.w 'rd, 'rk, 'rj");
+ break;
+ case AMOR_D:
+ Format(instr, "amor.d 'rd, 'rk, 'rj");
+ break;
+ case AMXOR_W:
+ Format(instr, "amxor.w 'rd, 'rk, 'rj");
+ break;
+ case AMXOR_D:
+ Format(instr, "amxor.d 'rd, 'rk, 'rj");
+ break;
+ case AMMAX_W:
+ Format(instr, "ammax.w 'rd, 'rk, 'rj");
+ break;
+ case AMMAX_D:
+ Format(instr, "ammax.d 'rd, 'rk, 'rj");
+ break;
+ case AMMIN_W:
+ Format(instr, "ammin.w 'rd, 'rk, 'rj");
+ break;
+ case AMMIN_D:
+ Format(instr, "ammin.d 'rd, 'rk, 'rj");
+ break;
+ case AMMAX_WU:
+ Format(instr, "ammax.wu 'rd, 'rk, 'rj");
+ break;
+ case AMMAX_DU:
+ Format(instr, "ammax.du 'rd, 'rk, 'rj");
+ break;
+ case AMMIN_WU:
+ Format(instr, "ammin.wu 'rd, 'rk, 'rj");
+ break;
+ case AMMIN_DU:
+ Format(instr, "ammin.du 'rd, 'rk, 'rj");
+ break;
+ case AMSWAP_DB_W:
+ Format(instr, "amswap_db.w 'rd, 'rk, 'rj");
+ break;
+ case AMSWAP_DB_D:
+ Format(instr, "amswap_db.d 'rd, 'rk, 'rj");
+ break;
+ case AMADD_DB_W:
+ Format(instr, "amadd_db.w 'rd, 'rk, 'rj");
+ break;
+ case AMADD_DB_D:
+ Format(instr, "amadd_db.d 'rd, 'rk, 'rj");
+ break;
+ case AMAND_DB_W:
+ Format(instr, "amand_db.w 'rd, 'rk, 'rj");
+ break;
+ case AMAND_DB_D:
+ Format(instr, "amand_db.d 'rd, 'rk, 'rj");
+ break;
+ case AMOR_DB_W:
+ Format(instr, "amor_db.w 'rd, 'rk, 'rj");
+ break;
+ case AMOR_DB_D:
+ Format(instr, "amor_db.d 'rd, 'rk, 'rj");
+ break;
+ case AMXOR_DB_W:
+ Format(instr, "amxor_db.w 'rd, 'rk, 'rj");
+ break;
+ case AMXOR_DB_D:
+ Format(instr, "amxor_db.d 'rd, 'rk, 'rj");
+ break;
+ case AMMAX_DB_W:
+ Format(instr, "ammax_db.w 'rd, 'rk, 'rj");
+ break;
+ case AMMAX_DB_D:
+ Format(instr, "ammax_db.d 'rd, 'rk, 'rj");
+ break;
+ case AMMIN_DB_W:
+ Format(instr, "ammin_db.w 'rd, 'rk, 'rj");
+ break;
+ case AMMIN_DB_D:
+ Format(instr, "ammin_db.d 'rd, 'rk, 'rj");
+ break;
+ case AMMAX_DB_WU:
+ Format(instr, "ammax_db.wu 'rd, 'rk, 'rj");
+ break;
+ case AMMAX_DB_DU:
+ Format(instr, "ammax_db.du 'rd, 'rk, 'rj");
+ break;
+ case AMMIN_DB_WU:
+ Format(instr, "ammin_db.wu 'rd, 'rk, 'rj");
+ break;
+ case AMMIN_DB_DU:
+ Format(instr, "ammin_db.du 'rd, 'rk, 'rj");
+ break;
+ case DBAR:
+ Format(instr, "dbar 'hint15");
+ break;
+ case IBAR:
+ Format(instr, "ibar 'hint15");
+ break;
+ case FSCALEB_S:
+ Format(instr, "fscaleb.s 'fd, 'fj, 'fk");
+ break;
+ case FSCALEB_D:
+ Format(instr, "fscaleb.d 'fd, 'fj, 'fk");
+ break;
+ case FCOPYSIGN_S:
+ Format(instr, "fcopysign.s 'fd, 'fj, 'fk");
+ break;
+ case FCOPYSIGN_D:
+ Format(instr, "fcopysign.d 'fd, 'fj, 'fk");
+ break;
+ default:
+ UNREACHABLE();
+ }
+ return kInstrSize;
+}
+
+void Decoder::DecodeTypekOp22(Instruction* instr) {
+ switch (instr->Bits(31, 10) << 10) {
+ case CLZ_W:
+ Format(instr, "clz.w 'rd, 'rj");
+ break;
+ case CTZ_W:
+ Format(instr, "ctz.w 'rd, 'rj");
+ break;
+ case CLZ_D:
+ Format(instr, "clz.d 'rd, 'rj");
+ break;
+ case CTZ_D:
+ Format(instr, "ctz.d 'rd, 'rj");
+ break;
+ case REVB_2H:
+ Format(instr, "revb.2h 'rd, 'rj");
+ break;
+ case REVB_4H:
+ Format(instr, "revb.4h 'rd, 'rj");
+ break;
+ case REVB_2W:
+ Format(instr, "revb.2w 'rd, 'rj");
+ break;
+ case REVB_D:
+ Format(instr, "revb.d 'rd, 'rj");
+ break;
+ case REVH_2W:
+ Format(instr, "revh.2w 'rd, 'rj");
+ break;
+ case REVH_D:
+ Format(instr, "revh.d 'rd, 'rj");
+ break;
+ case BITREV_4B:
+ Format(instr, "bitrev.4b 'rd, 'rj");
+ break;
+ case BITREV_8B:
+ Format(instr, "bitrev.8b 'rd, 'rj");
+ break;
+ case BITREV_W:
+ Format(instr, "bitrev.w 'rd, 'rj");
+ break;
+ case BITREV_D:
+ Format(instr, "bitrev.d 'rd, 'rj");
+ break;
+ case EXT_W_B:
+ Format(instr, "ext.w.b 'rd, 'rj");
+ break;
+ case EXT_W_H:
+ Format(instr, "ext.w.h 'rd, 'rj");
+ break;
+ case FABS_S:
+ Format(instr, "fabs.s 'fd, 'fj");
+ break;
+ case FABS_D:
+ Format(instr, "fabs.d 'fd, 'fj");
+ break;
+ case FNEG_S:
+ Format(instr, "fneg.s 'fd, 'fj");
+ break;
+ case FNEG_D:
+ Format(instr, "fneg.d 'fd, 'fj");
+ break;
+ case FSQRT_S:
+ Format(instr, "fsqrt.s 'fd, 'fj");
+ break;
+ case FSQRT_D:
+ Format(instr, "fsqrt.d 'fd, 'fj");
+ break;
+ case FMOV_S:
+ Format(instr, "fmov.s 'fd, 'fj");
+ break;
+ case FMOV_D:
+ Format(instr, "fmov.d 'fd, 'fj");
+ break;
+ case MOVGR2FR_W:
+ Format(instr, "movgr2fr.w 'fd, 'rj");
+ break;
+ case MOVGR2FR_D:
+ Format(instr, "movgr2fr.d 'fd, 'rj");
+ break;
+ case MOVGR2FRH_W:
+ Format(instr, "movgr2frh.w 'fd, 'rj");
+ break;
+ case MOVFR2GR_S:
+ Format(instr, "movfr2gr.s 'rd, 'fj");
+ break;
+ case MOVFR2GR_D:
+ Format(instr, "movfr2gr.d 'rd, 'fj");
+ break;
+ case MOVFRH2GR_S:
+ Format(instr, "movfrh2gr.s 'rd, 'fj");
+ break;
+ case MOVGR2FCSR:
+ Format(instr, "movgr2fcsr fcsr, 'rj");
+ break;
+ case MOVFCSR2GR:
+ Format(instr, "movfcsr2gr 'rd, fcsr");
+ break;
+ case FCVT_S_D:
+ Format(instr, "fcvt.s.d 'fd, 'fj");
+ break;
+ case FCVT_D_S:
+ Format(instr, "fcvt.d.s 'fd, 'fj");
+ break;
+ case FTINTRM_W_S:
+ Format(instr, "ftintrm.w.s 'fd, 'fj");
+ break;
+ case FTINTRM_W_D:
+ Format(instr, "ftintrm.w.d 'fd, 'fj");
+ break;
+ case FTINTRM_L_S:
+ Format(instr, "ftintrm.l.s 'fd, 'fj");
+ break;
+ case FTINTRM_L_D:
+ Format(instr, "ftintrm.l.d 'fd, 'fj");
+ break;
+ case FTINTRP_W_S:
+ Format(instr, "ftintrp.w.s 'fd, 'fj");
+ break;
+ case FTINTRP_W_D:
+ Format(instr, "ftintrp.w.d 'fd, 'fj");
+ break;
+ case FTINTRP_L_S:
+ Format(instr, "ftintrp.l.s 'fd, 'fj");
+ break;
+ case FTINTRP_L_D:
+ Format(instr, "ftintrp.l.d 'fd, 'fj");
+ break;
+ case FTINTRZ_W_S:
+ Format(instr, "ftintrz.w.s 'fd, 'fj");
+ break;
+ case FTINTRZ_W_D:
+ Format(instr, "ftintrz.w.d 'fd, 'fj");
+ break;
+ case FTINTRZ_L_S:
+ Format(instr, "ftintrz.l.s 'fd, 'fj");
+ break;
+ case FTINTRZ_L_D:
+ Format(instr, "ftintrz.l.d 'fd, 'fj");
+ break;
+ case FTINTRNE_W_S:
+ Format(instr, "ftintrne.w.s 'fd, 'fj");
+ break;
+ case FTINTRNE_W_D:
+ Format(instr, "ftintrne.w.d 'fd, 'fj");
+ break;
+ case FTINTRNE_L_S:
+ Format(instr, "ftintrne.l.s 'fd, 'fj");
+ break;
+ case FTINTRNE_L_D:
+ Format(instr, "ftintrne.l.d 'fd, 'fj");
+ break;
+ case FTINT_W_S:
+ Format(instr, "ftint.w.s 'fd, 'fj");
+ break;
+ case FTINT_W_D:
+ Format(instr, "ftint.w.d 'fd, 'fj");
+ break;
+ case FTINT_L_S:
+ Format(instr, "ftint.l.s 'fd, 'fj");
+ break;
+ case FTINT_L_D:
+ Format(instr, "ftint.l.d 'fd, 'fj");
+ break;
+ case FFINT_S_W:
+ Format(instr, "ffint.s.w 'fd, 'fj");
+ break;
+ case FFINT_S_L:
+ Format(instr, "ffint.s.l 'fd, 'fj");
+ break;
+ case FFINT_D_W:
+ Format(instr, "ffint.d.w 'fd, 'fj");
+ break;
+ case FFINT_D_L:
+ Format(instr, "ffint.d.l 'fd, 'fj");
+ break;
+ case FRINT_S:
+ Format(instr, "frint.s 'fd, 'fj");
+ break;
+ case FRINT_D:
+ Format(instr, "frint.d 'fd, 'fj");
+ break;
+ case MOVFR2CF:
+ Format(instr, "movfr2cf fcc'cd, 'fj");
+ break;
+ case MOVCF2FR:
+ Format(instr, "movcf2fr 'fd, fcc'cj");
+ break;
+ case MOVGR2CF:
+ Format(instr, "movgr2cf fcc'cd, 'rj");
+ break;
+ case MOVCF2GR:
+ Format(instr, "movcf2gr 'rd, fcc'cj");
+ break;
+ case FRECIP_S:
+ Format(instr, "frecip.s 'fd, 'fj");
+ break;
+ case FRECIP_D:
+ Format(instr, "frecip.d 'fd, 'fj");
+ break;
+ case FRSQRT_S:
+ Format(instr, "frsqrt.s 'fd, 'fj");
+ break;
+ case FRSQRT_D:
+ Format(instr, "frsqrt.d 'fd, 'fj");
+ break;
+ case FCLASS_S:
+ Format(instr, "fclass.s 'fd, 'fj");
+ break;
+ case FCLASS_D:
+ Format(instr, "fclass.d 'fd, 'fj");
+ break;
+ case FLOGB_S:
+ Format(instr, "flogb.s 'fd, 'fj");
+ break;
+ case FLOGB_D:
+ Format(instr, "flogb.d 'fd, 'fj");
+ break;
+ case CLO_W:
+ Format(instr, "clo.w 'rd, 'rj");
+ break;
+ case CTO_W:
+ Format(instr, "cto.w 'rd, 'rj");
+ break;
+ case CLO_D:
+ Format(instr, "clo.d 'rd, 'rj");
+ break;
+ case CTO_D:
+ Format(instr, "cto.d 'rd, 'rj");
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+int Decoder::InstructionDecode(byte* instr_ptr) {
+ Instruction* instr = Instruction::At(instr_ptr);
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_,
+ "%08x ", instr->InstructionBits());
+ switch (instr->InstructionType()) {
+ case Instruction::kOp6Type: {
+ DecodeTypekOp6(instr);
+ break;
+ }
+ case Instruction::kOp7Type: {
+ DecodeTypekOp7(instr);
+ break;
+ }
+ case Instruction::kOp8Type: {
+ DecodeTypekOp8(instr);
+ break;
+ }
+ case Instruction::kOp10Type: {
+ DecodeTypekOp10(instr);
+ break;
+ }
+ case Instruction::kOp12Type: {
+ DecodeTypekOp12(instr);
+ break;
+ }
+ case Instruction::kOp14Type: {
+ DecodeTypekOp14(instr);
+ break;
+ }
+ case Instruction::kOp17Type: {
+ return DecodeTypekOp17(instr);
+ }
+ case Instruction::kOp22Type: {
+ DecodeTypekOp22(instr);
+ break;
+ }
+ case Instruction::kUnsupported: {
+ Format(instr, "UNSUPPORTED");
+ break;
+ }
+ default: {
+ Format(instr, "UNSUPPORTED");
+ break;
+ }
+ }
+ return kInstrSize;
+}
+
+} // namespace internal
+} // namespace v8
+
+//------------------------------------------------------------------------------
+
+namespace disasm {
+
+const char* NameConverter::NameOfAddress(byte* addr) const {
+ v8::base::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr));
+ return tmp_buffer_.begin();
+}
+
+const char* NameConverter::NameOfConstant(byte* addr) const {
+ return NameOfAddress(addr);
+}
+
+const char* NameConverter::NameOfCPURegister(int reg) const {
+ return v8::internal::Registers::Name(reg);
+}
+
+const char* NameConverter::NameOfXMMRegister(int reg) const {
+ return v8::internal::FPURegisters::Name(reg);
+}
+
+const char* NameConverter::NameOfByteCPURegister(int reg) const {
+ UNREACHABLE();
+}
+
+const char* NameConverter::NameInCode(byte* addr) const {
+ // The default name converter is called for unknown code. So we will not try
+ // to access any memory.
+ return "";
+}
+
+//------------------------------------------------------------------------------
+
+int Disassembler::InstructionDecode(v8::base::Vector<char> buffer,
+ byte* instruction) {
+ v8::internal::Decoder d(converter_, buffer);
+ return d.InstructionDecode(instruction);
+}
+
+int Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; }
+
+void Disassembler::Disassemble(FILE* f, byte* begin, byte* end,
+ UnimplementedOpcodeAction unimplemented_action) {
+ NameConverter converter;
+ Disassembler d(converter, unimplemented_action);
+ for (byte* pc = begin; pc < end;) {
+ v8::base::EmbeddedVector<char, 128> buffer;
+ buffer[0] = '\0';
+ byte* prev_pc = pc;
+ pc += d.InstructionDecode(buffer, pc);
+ v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc),
+ *reinterpret_cast<int32_t*>(prev_pc), buffer.begin());
+ }
+}
+
+#undef STRING_STARTS_WITH
+
+} // namespace disasm
+
+#endif // V8_TARGET_ARCH_LOONG64
diff --git a/chromium/v8/src/diagnostics/loong64/unwinder-loong64.cc b/chromium/v8/src/diagnostics/loong64/unwinder-loong64.cc
new file mode 100644
index 00000000000..84d2e41cfc8
--- /dev/null
+++ b/chromium/v8/src/diagnostics/loong64/unwinder-loong64.cc
@@ -0,0 +1,14 @@
+// Copyright 2021 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 "src/diagnostics/unwinder.h"
+
+namespace v8 {
+
+struct RegisterState;
+
+void GetCalleeSavedRegistersFromEntryFrame(void* fp,
+ RegisterState* register_state) {}
+
+} // namespace v8
diff --git a/chromium/v8/src/diagnostics/mips/disasm-mips.cc b/chromium/v8/src/diagnostics/mips/disasm-mips.cc
index c5aeb274573..32a0bdb0488 100644
--- a/chromium/v8/src/diagnostics/mips/disasm-mips.cc
+++ b/chromium/v8/src/diagnostics/mips/disasm-mips.cc
@@ -555,7 +555,6 @@ void Decoder::PrintMsaDataFormat(Instruction* instr) {
break;
default:
UNREACHABLE();
- break;
}
} else {
char DF[] = {'b', 'h', 'w', 'd'};
@@ -600,7 +599,6 @@ void Decoder::PrintMsaDataFormat(Instruction* instr) {
break;
default:
UNREACHABLE();
- break;
}
}
@@ -904,7 +902,6 @@ int Decoder::FormatOption(Instruction* instr, const char* format) {
PrintSa(instr);
return 2;
}
- break;
case 'd': {
DCHECK(STRING_STARTS_WITH(format, "sd"));
PrintSd(instr);
@@ -1521,7 +1518,6 @@ void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) {
}
default:
UNREACHABLE();
- break;
}
}
}
@@ -1538,7 +1534,6 @@ void Decoder::DecodeTypeRegister(Instruction* instr) {
switch (instr->RsFieldRaw()) {
case BC1: // bc1 handled in DecodeTypeImmediate.
UNREACHABLE();
- break;
case MFC1:
Format(instr, "mfc1 'rt, 'fs");
break;
@@ -1966,7 +1961,6 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
break;
default:
UNREACHABLE();
- break;
}
}
}
@@ -1997,7 +1991,6 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
break;
default:
UNREACHABLE();
- break;
}
break;
default:
@@ -2703,7 +2696,6 @@ const char* NameConverter::NameOfXMMRegister(int reg) const {
const char* NameConverter::NameOfByteCPURegister(int reg) const {
UNREACHABLE(); // MIPS does not have the concept of a byte register.
- return "nobytereg";
}
const char* NameConverter::NameInCode(byte* addr) const {
diff --git a/chromium/v8/src/diagnostics/mips64/disasm-mips64.cc b/chromium/v8/src/diagnostics/mips64/disasm-mips64.cc
index d8ff14730d0..0712431fc3b 100644
--- a/chromium/v8/src/diagnostics/mips64/disasm-mips64.cc
+++ b/chromium/v8/src/diagnostics/mips64/disasm-mips64.cc
@@ -596,7 +596,6 @@ void Decoder::PrintMsaDataFormat(Instruction* instr) {
break;
default:
UNREACHABLE();
- break;
}
} else {
char DF[] = {'b', 'h', 'w', 'd'};
@@ -641,7 +640,6 @@ void Decoder::PrintMsaDataFormat(Instruction* instr) {
break;
default:
UNREACHABLE();
- break;
}
}
@@ -945,7 +943,6 @@ int Decoder::FormatOption(Instruction* instr, const char* format) {
PrintSa(instr);
return 2;
}
- break;
case 'd': {
DCHECK(STRING_STARTS_WITH(format, "sd"));
PrintSd(instr);
@@ -1744,7 +1741,6 @@ void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) {
}
default:
UNREACHABLE();
- break;
}
break;
}
@@ -1761,7 +1757,6 @@ void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) {
break;
default:
UNREACHABLE();
- break;
}
break;
}
@@ -1782,7 +1777,6 @@ void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) {
}
default:
UNREACHABLE();
- break;
}
break;
}
@@ -2250,7 +2244,6 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
break;
default:
UNREACHABLE();
- break;
}
break;
}
@@ -2285,7 +2278,6 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
break;
default:
UNREACHABLE();
- break;
}
break;
default:
@@ -2993,7 +2985,6 @@ const char* NameConverter::NameOfXMMRegister(int reg) const {
const char* NameConverter::NameOfByteCPURegister(int reg) const {
UNREACHABLE(); // MIPS does not have the concept of a byte register.
- return "nobytereg";
}
const char* NameConverter::NameInCode(byte* addr) const {
diff --git a/chromium/v8/src/diagnostics/objects-debug.cc b/chromium/v8/src/diagnostics/objects-debug.cc
index e45d7580c8f..de003a4a549 100644
--- a/chromium/v8/src/diagnostics/objects-debug.cc
+++ b/chromium/v8/src/diagnostics/objects-debug.cc
@@ -166,7 +166,9 @@ void TaggedIndex::TaggedIndexVerify(Isolate* isolate) {
}
void HeapObject::HeapObjectVerify(Isolate* isolate) {
- TorqueGeneratedClassVerifiers::HeapObjectVerify(*this, isolate);
+ CHECK(IsHeapObject());
+ VerifyPointer(isolate, map(isolate));
+ CHECK(map(isolate).IsMap());
switch (map().instance_type()) {
#define STRING_TYPE_CASE(TYPE, size, name, CamelName) case TYPE:
@@ -293,6 +295,7 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
BigIntBase::cast(*this).BigIntBaseVerify(isolate);
break;
+ case JS_CLASS_CONSTRUCTOR_TYPE:
case JS_PROMISE_CONSTRUCTOR_TYPE:
case JS_REG_EXP_CONSTRUCTOR_TYPE:
case JS_ARRAY_CONSTRUCTOR_TYPE:
@@ -343,8 +346,6 @@ void BytecodeArray::BytecodeArrayVerify(Isolate* isolate) {
}
}
-USE_TORQUE_VERIFIER(JSReceiver)
-
bool JSObject::ElementsAreSafeToExamine(PtrComprCageBase cage_base) const {
// If a GC was caused while constructing this object, the elements
// pointer may point to a one pointer filler map.
@@ -419,7 +420,7 @@ void JSObject::JSObjectVerify(Isolate* isolate) {
for (InternalIndex i : map().IterateOwnDescriptors()) {
PropertyDetails details = descriptors.GetDetails(i);
- if (details.location() == kField) {
+ if (details.location() == PropertyLocation::kField) {
DCHECK_EQ(kData, details.kind());
Representation r = details.representation();
FieldIndex index = FieldIndex::ForDescriptor(map(), i);
@@ -654,7 +655,7 @@ void DescriptorArray::DescriptorArrayVerify(Isolate* isolate) {
}
MaybeObject value = GetValue(descriptor);
HeapObject heap_object;
- if (details.location() == kField) {
+ if (details.location() == PropertyLocation::kField) {
CHECK_EQ(details.field_index(), expected_field_index);
CHECK(
value == MaybeObject::FromObject(FieldType::None()) ||
@@ -785,8 +786,6 @@ void JSDate::JSDateVerify(Isolate* isolate) {
}
}
-USE_TORQUE_VERIFIER(JSMessageObject)
-
void String::StringVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::StringVerify(*this, isolate);
CHECK(length() >= 0 && length() <= Smi::kMaxValue);
@@ -830,7 +829,24 @@ void JSBoundFunction::JSBoundFunctionVerify(Isolate* isolate) {
}
void JSFunction::JSFunctionVerify(Isolate* isolate) {
- TorqueGeneratedClassVerifiers::JSFunctionVerify(*this, isolate);
+ // Don't call TorqueGeneratedClassVerifiers::JSFunctionVerify here because the
+ // Torque class definition contains the field `prototype_or_initial_map` which
+ // may not be allocated.
+
+ // This assertion exists to encourage updating this verification function if
+ // new fields are added in the Torque class layout definition.
+ STATIC_ASSERT(JSFunction::TorqueGeneratedClass::kHeaderSize ==
+ 8 * kTaggedSize);
+
+ JSFunctionOrBoundFunctionVerify(isolate);
+ CHECK(IsJSFunction());
+ VerifyPointer(isolate, shared(isolate));
+ CHECK(shared(isolate).IsSharedFunctionInfo());
+ VerifyPointer(isolate, context(isolate, kRelaxedLoad));
+ CHECK(context(isolate, kRelaxedLoad).IsContext());
+ VerifyPointer(isolate, raw_feedback_cell(isolate));
+ CHECK(raw_feedback_cell(isolate).IsFeedbackCell());
+ VerifyPointer(isolate, raw_code(isolate));
CHECK(raw_code(isolate).IsCodeT());
CHECK(map(isolate).is_callable());
Handle<JSFunction> function(*this, isolate);
@@ -1005,8 +1021,11 @@ void Code::CodeVerify(Isolate* isolate) {
CHECK_LE(constant_pool_offset(), code_comments_offset());
CHECK_LE(code_comments_offset(), unwinding_info_offset());
CHECK_LE(unwinding_info_offset(), MetadataSize());
+#if !defined(_MSC_VER) || defined(__clang__)
+ // See also: PlatformEmbeddedFileWriterWin::AlignToCodeAlignment.
CHECK_IMPLIES(!ReadOnlyHeap::Contains(*this),
IsAligned(InstructionStart(), kCodeAlignment));
+#endif // !defined(_MSC_VER) || defined(__clang__)
CHECK_IMPLIES(!ReadOnlyHeap::Contains(*this),
IsAligned(raw_instruction_start(), kCodeAlignment));
if (V8_EXTERNAL_CODE_SPACE_BOOL) {
@@ -1139,19 +1158,13 @@ void JSWeakRef::JSWeakRefVerify(Isolate* isolate) {
}
void JSFinalizationRegistry::JSFinalizationRegistryVerify(Isolate* isolate) {
- CHECK(IsJSFinalizationRegistry());
- JSObjectVerify(isolate);
- VerifyHeapPointer(isolate, cleanup());
- CHECK(active_cells().IsUndefined(isolate) || active_cells().IsWeakCell());
+ TorqueGeneratedClassVerifiers::JSFinalizationRegistryVerify(*this, isolate);
if (active_cells().IsWeakCell()) {
CHECK(WeakCell::cast(active_cells()).prev().IsUndefined(isolate));
}
- CHECK(cleared_cells().IsUndefined(isolate) || cleared_cells().IsWeakCell());
if (cleared_cells().IsWeakCell()) {
CHECK(WeakCell::cast(cleared_cells()).prev().IsUndefined(isolate));
}
- CHECK(next_dirty().IsUndefined(isolate) ||
- next_dirty().IsJSFinalizationRegistry());
}
void JSWeakMap::JSWeakMapVerify(Isolate* isolate) {
@@ -1236,8 +1249,9 @@ void SmallOrderedHashTable<Derived>::SmallOrderedHashTableVerify(
}
}
}
+
void SmallOrderedHashMap::SmallOrderedHashMapVerify(Isolate* isolate) {
- TorqueGeneratedClassVerifiers::SmallOrderedHashMapVerify(*this, isolate);
+ CHECK(IsSmallOrderedHashMap());
SmallOrderedHashTable<SmallOrderedHashMap>::SmallOrderedHashTableVerify(
isolate);
for (int entry = NumberOfElements(); entry < NumberOfDeletedElements();
@@ -1250,7 +1264,7 @@ void SmallOrderedHashMap::SmallOrderedHashMapVerify(Isolate* isolate) {
}
void SmallOrderedHashSet::SmallOrderedHashSetVerify(Isolate* isolate) {
- TorqueGeneratedClassVerifiers::SmallOrderedHashSetVerify(*this, isolate);
+ CHECK(IsSmallOrderedHashSet());
SmallOrderedHashTable<SmallOrderedHashSet>::SmallOrderedHashTableVerify(
isolate);
for (int entry = NumberOfElements(); entry < NumberOfDeletedElements();
@@ -1264,8 +1278,7 @@ void SmallOrderedHashSet::SmallOrderedHashSetVerify(Isolate* isolate) {
void SmallOrderedNameDictionary::SmallOrderedNameDictionaryVerify(
Isolate* isolate) {
- TorqueGeneratedClassVerifiers::SmallOrderedNameDictionaryVerify(*this,
- isolate);
+ CHECK(IsSmallOrderedNameDictionary());
SmallOrderedHashTable<
SmallOrderedNameDictionary>::SmallOrderedHashTableVerify(isolate);
for (int entry = NumberOfElements(); entry < NumberOfDeletedElements();
@@ -1355,7 +1368,7 @@ void SwissNameDictionary::SwissNameDictionaryVerify(Isolate* isolate,
void JSRegExp::JSRegExpVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::JSRegExpVerify(*this, isolate);
- switch (TypeTag()) {
+ switch (type_tag()) {
case JSRegExp::ATOM: {
FixedArray arr = FixedArray::cast(data());
CHECK(arr.get(JSRegExp::kAtomPatternIndex).IsString());
@@ -1433,7 +1446,7 @@ void JSRegExp::JSRegExpVerify(Isolate* isolate) {
break;
}
default:
- CHECK_EQ(JSRegExp::NOT_COMPILED, TypeTag());
+ CHECK_EQ(JSRegExp::NOT_COMPILED, type_tag());
CHECK(data().IsUndefined(isolate));
break;
}
@@ -1661,9 +1674,20 @@ void WasmExportedFunctionData::WasmExportedFunctionDataVerify(
#endif // V8_ENABLE_WEBASSEMBLY
void DataHandler::DataHandlerVerify(Isolate* isolate) {
- TorqueGeneratedClassVerifiers::DataHandlerVerify(*this, isolate);
+ // Don't call TorqueGeneratedClassVerifiers::DataHandlerVerify because the
+ // Torque definition of this class includes all of the optional fields.
+
+ // This assertion exists to encourage updating this verification function if
+ // new fields are added in the Torque class layout definition.
+ STATIC_ASSERT(DataHandler::kHeaderSize == 6 * kTaggedSize);
+
+ StructVerify(isolate);
+ CHECK(IsDataHandler());
+ VerifyPointer(isolate, smi_handler(isolate));
CHECK_IMPLIES(!smi_handler().IsSmi(),
IsStoreHandler() && smi_handler().IsCodeT());
+ VerifyPointer(isolate, validity_cell(isolate));
+ CHECK(validity_cell().IsSmi() || validity_cell().IsCell());
int data_count = data_field_count();
if (data_count >= 1) {
VerifyMaybeObjectField(isolate, kData1Offset);
diff --git a/chromium/v8/src/diagnostics/objects-printer.cc b/chromium/v8/src/diagnostics/objects-printer.cc
index 46fccedde75..8a98a152db0 100644
--- a/chromium/v8/src/diagnostics/objects-printer.cc
+++ b/chromium/v8/src/diagnostics/objects-printer.cc
@@ -234,6 +234,7 @@ void HeapObject::HeapObjectPrint(std::ostream& os) {
case BIG_INT_BASE_TYPE:
BigIntBase::cast(*this).BigIntBasePrint(os);
break;
+ case JS_CLASS_CONSTRUCTOR_TYPE:
case JS_PROMISE_CONSTRUCTOR_TYPE:
case JS_REG_EXP_CONSTRUCTOR_TYPE:
case JS_ARRAY_CONSTRUCTOR_TYPE:
@@ -295,18 +296,18 @@ bool JSObject::PrintProperties(std::ostream& os) {
os << ": ";
PropertyDetails details = descs.GetDetails(i);
switch (details.location()) {
- case kField: {
+ case PropertyLocation::kField: {
FieldIndex field_index = FieldIndex::ForDescriptor(map(), i);
os << Brief(RawFastPropertyAt(field_index));
break;
}
- case kDescriptor:
+ case PropertyLocation::kDescriptor:
os << Brief(descs.GetStrongValue(i));
break;
}
os << " ";
details.PrintAsFastTo(os, PropertyDetails::kForProperties);
- if (details.location() == kField) {
+ if (details.location() == PropertyLocation::kField) {
int field_index = details.field_index();
if (field_index < nof_inobject_properties) {
os << ", location: in-object";
@@ -821,10 +822,15 @@ namespace {
void PrintContextWithHeader(std::ostream& os, Context context,
const char* type) {
context.PrintHeader(os, type);
- os << "\n - length: " << context.length();
+ os << "\n - type: " << context.map().instance_type();
os << "\n - scope_info: " << Brief(context.scope_info());
os << "\n - previous: " << Brief(context.unchecked_previous());
os << "\n - native_context: " << Brief(context.native_context());
+ if (context.scope_info().HasContextExtensionSlot()) {
+ os << "\n - extension: " << context.extension();
+ }
+ os << "\n - length: " << context.length();
+ os << "\n - elements:";
PrintFixedArrayElements(os, context);
os << "\n";
}
@@ -1336,24 +1342,15 @@ void JSDate::JSDatePrint(std::ostream& os) {
JSObjectPrintBody(os, *this);
}
-void JSProxy::JSProxyPrint(std::ostream& os) {
- PrintHeader(os, "JSProxy");
- os << "\n - target: ";
- target().ShortPrint(os);
- os << "\n - handler: ";
- handler().ShortPrint(os);
- os << "\n";
-}
-
void JSSet::JSSetPrint(std::ostream& os) {
JSObjectPrintHeader(os, *this, "JSSet");
- os << " - table: " << Brief(table());
+ os << "\n - table: " << Brief(table());
JSObjectPrintBody(os, *this);
}
void JSMap::JSMapPrint(std::ostream& os) {
JSObjectPrintHeader(os, *this, "JSMap");
- os << " - table: " << Brief(table());
+ os << "\n - table: " << Brief(table());
JSObjectPrintBody(os, *this);
}
@@ -1373,18 +1370,6 @@ void JSMapIterator::JSMapIteratorPrint(std::ostream& os) {
JSCollectionIteratorPrint(os, "JSMapIterator");
}
-void WeakCell::WeakCellPrint(std::ostream& os) {
- PrintHeader(os, "WeakCell");
- os << "\n - finalization_registry: " << Brief(finalization_registry());
- os << "\n - target: " << Brief(target());
- os << "\n - holdings: " << Brief(holdings());
- os << "\n - prev: " << Brief(prev());
- os << "\n - next: " << Brief(next());
- os << "\n - unregister_token: " << Brief(unregister_token());
- os << "\n - key_list_prev: " << Brief(key_list_prev());
- os << "\n - key_list_next: " << Brief(key_list_next());
-}
-
void JSWeakRef::JSWeakRefPrint(std::ostream& os) {
JSObjectPrintHeader(os, *this, "JSWeakRef");
os << "\n - target: " << Brief(target());
@@ -1513,7 +1498,7 @@ void JSFunction::JSFunctionPrint(std::ostream& os) {
}
os << "\n - formal_parameter_count: "
- << shared().internal_formal_parameter_count();
+ << shared().internal_formal_parameter_count_without_receiver();
os << "\n - kind: " << shared().kind();
os << "\n - context: " << Brief(context());
os << "\n - code: " << Brief(raw_code());
@@ -1583,7 +1568,8 @@ void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) {
os << "\n - kind: " << kind();
os << "\n - syntax kind: " << syntax_kind();
os << "\n - function_map_index: " << function_map_index();
- os << "\n - formal_parameter_count: " << internal_formal_parameter_count();
+ os << "\n - formal_parameter_count: "
+ << internal_formal_parameter_count_without_receiver();
os << "\n - expected_nof_properties: " << expected_nof_properties();
os << "\n - language_mode: " << language_mode();
os << "\n - data: " << Brief(function_data(kAcquireLoad));
@@ -1658,7 +1644,7 @@ void Code::CodePrint(std::ostream& os) {
void CodeDataContainer::CodeDataContainerPrint(std::ostream& os) {
PrintHeader(os, "CodeDataContainer");
- os << "\n - kind_specific_flags: " << kind_specific_flags();
+ os << "\n - kind_specific_flags: " << kind_specific_flags(kRelaxedLoad);
if (V8_EXTERNAL_CODE_SPACE_BOOL) {
os << "\n - code: " << Brief(code());
os << "\n - code_entry_point: "
@@ -1673,67 +1659,6 @@ void Foreign::ForeignPrint(std::ostream& os) {
os << "\n";
}
-void CallbackTask::CallbackTaskPrint(std::ostream& os) {
- PrintHeader(os, "CallbackTask");
- os << "\n - callback: " << Brief(callback());
- os << "\n - data: " << Brief(data());
- os << "\n";
-}
-
-void CallableTask::CallableTaskPrint(std::ostream& os) {
- PrintHeader(os, "CallableTask");
- os << "\n - context: " << Brief(context());
- os << "\n - callable: " << Brief(callable());
- os << "\n";
-}
-
-void PromiseFulfillReactionJobTask::PromiseFulfillReactionJobTaskPrint(
- std::ostream& os) {
- PrintHeader(os, "PromiseFulfillReactionJobTask");
- os << "\n - argument: " << Brief(argument());
- os << "\n - context: " << Brief(context());
- os << "\n - handler: " << Brief(handler());
- os << "\n - promise_or_capability: " << Brief(promise_or_capability());
- os << "\n";
-}
-
-void PromiseRejectReactionJobTask::PromiseRejectReactionJobTaskPrint(
- std::ostream& os) {
- PrintHeader(os, "PromiseRejectReactionJobTask");
- os << "\n - argument: " << Brief(argument());
- os << "\n - context: " << Brief(context());
- os << "\n - handler: " << Brief(handler());
- os << "\n - promise_or_capability: " << Brief(promise_or_capability());
- os << "\n";
-}
-
-void PromiseResolveThenableJobTask::PromiseResolveThenableJobTaskPrint(
- std::ostream& os) {
- PrintHeader(os, "PromiseResolveThenableJobTask");
- os << "\n - context: " << Brief(context());
- os << "\n - promise_to_resolve: " << Brief(promise_to_resolve());
- os << "\n - then: " << Brief(then());
- os << "\n - thenable: " << Brief(thenable());
- os << "\n";
-}
-
-void PromiseCapability::PromiseCapabilityPrint(std::ostream& os) {
- PrintHeader(os, "PromiseCapability");
- os << "\n - promise: " << Brief(promise());
- os << "\n - resolve: " << Brief(resolve());
- os << "\n - reject: " << Brief(reject());
- os << "\n";
-}
-
-void PromiseReaction::PromiseReactionPrint(std::ostream& os) {
- PrintHeader(os, "PromiseReaction");
- os << "\n - next: " << Brief(next());
- os << "\n - reject_handler: " << Brief(reject_handler());
- os << "\n - fulfill_handler: " << Brief(fulfill_handler());
- os << "\n - promise_or_capability: " << Brief(promise_or_capability());
- os << "\n";
-}
-
void AsyncGeneratorRequest::AsyncGeneratorRequestPrint(std::ostream& os) {
PrintHeader(os, "AsyncGeneratorRequest");
const char* mode = "Invalid!";
@@ -1754,19 +1679,6 @@ void AsyncGeneratorRequest::AsyncGeneratorRequestPrint(std::ostream& os) {
os << "\n";
}
-void SourceTextModuleInfoEntry::SourceTextModuleInfoEntryPrint(
- std::ostream& os) {
- PrintHeader(os, "SourceTextModuleInfoEntry");
- os << "\n - export_name: " << Brief(export_name());
- os << "\n - local_name: " << Brief(local_name());
- os << "\n - import_name: " << Brief(import_name());
- os << "\n - module_request: " << module_request();
- os << "\n - cell_index: " << cell_index();
- os << "\n - beg_pos: " << beg_pos();
- os << "\n - end_pos: " << end_pos();
- os << "\n";
-}
-
static void PrintModuleFields(Module module, std::ostream& os) {
os << "\n - exports: " << Brief(module.exports());
os << "\n - status: " << module.status();
@@ -1797,14 +1709,6 @@ void SourceTextModule::SourceTextModulePrint(std::ostream& os) {
os << "\n";
}
-void SyntheticModule::SyntheticModulePrint(std::ostream& os) {
- PrintHeader(os, "SyntheticModule");
- PrintModuleFields(*this, os);
- os << "\n - export_names: " << Brief(export_names());
- os << "\n - name: " << Brief(name());
- os << "\n";
-}
-
void JSModuleNamespace::JSModuleNamespacePrint(std::ostream& os) {
JSObjectPrintHeader(os, *this, "JSModuleNamespace");
os << "\n - module: " << Brief(module());
@@ -1821,13 +1725,6 @@ void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) {
os << "\n";
}
-void ClassPositions::ClassPositionsPrint(std::ostream& os) {
- PrintHeader(os, "ClassPositions");
- os << "\n - start position: " << start();
- os << "\n - end position: " << end();
- os << "\n";
-}
-
void ArrayBoilerplateDescription::ArrayBoilerplateDescriptionPrint(
std::ostream& os) {
PrintHeader(os, "ArrayBoilerplateDescription");
@@ -1836,15 +1733,6 @@ void ArrayBoilerplateDescription::ArrayBoilerplateDescriptionPrint(
os << "\n";
}
-void RegExpBoilerplateDescription::RegExpBoilerplateDescriptionPrint(
- std::ostream& os) {
- PrintHeader(os, "RegExpBoilerplateDescription");
- os << "\n - data: " << Brief(data());
- os << "\n - source: " << Brief(source());
- os << "\n - flags: " << flags();
- os << "\n";
-}
-
#if V8_ENABLE_WEBASSEMBLY
void AsmWasmData::AsmWasmDataPrint(std::ostream& os) {
PrintHeader(os, "AsmWasmData");
@@ -1898,10 +1786,11 @@ void WasmStruct::WasmStructPrint(std::ostream& os) {
os << Brief(base::ReadUnalignedValue<Object>(field_address));
break;
case wasm::kS128:
- case wasm::kBottom:
- case wasm::kVoid:
os << "UNIMPLEMENTED"; // TODO(7748): Implement.
break;
+ case wasm::kBottom:
+ case wasm::kVoid:
+ UNREACHABLE();
}
}
os << "\n";
@@ -1947,12 +1836,6 @@ void WasmArray::WasmArrayPrint(std::ostream& os) {
os << "\n";
}
-void WasmExceptionTag::WasmExceptionTagPrint(std::ostream& os) {
- PrintHeader(os, "WasmExceptionTag");
- os << "\n - index: " << index();
- os << "\n";
-}
-
void WasmInstanceObject::WasmInstanceObjectPrint(std::ostream& os) {
JSObjectPrintHeader(os, *this, "WasmInstanceObject");
os << "\n - module_object: " << Brief(module_object());
@@ -1985,7 +1868,6 @@ void WasmInstanceObject::WasmInstanceObjectPrint(std::ostream& os) {
}
os << "\n - memory_start: " << static_cast<void*>(memory_start());
os << "\n - memory_size: " << memory_size();
- os << "\n - memory_mask: " << AsHex(memory_mask());
os << "\n - imported_function_targets: "
<< static_cast<void*>(imported_function_targets());
os << "\n - globals_start: " << static_cast<void*>(globals_start());
@@ -2045,15 +1927,6 @@ void WasmModuleObject::WasmModuleObjectPrint(std::ostream& os) {
os << "\n";
}
-void WasmTableObject::WasmTableObjectPrint(std::ostream& os) {
- PrintHeader(os, "WasmTableObject");
- os << "\n - elements: " << Brief(elements());
- os << "\n - maximum_length: " << Brief(maximum_length());
- os << "\n - dispatch_tables: " << Brief(dispatch_tables());
- os << "\n - raw_type: " << raw_type();
- os << "\n";
-}
-
void WasmGlobalObject::WasmGlobalObjectPrint(std::ostream& os) {
PrintHeader(os, "WasmGlobalObject");
if (type().is_reference()) {
@@ -2069,21 +1942,6 @@ void WasmGlobalObject::WasmGlobalObjectPrint(std::ostream& os) {
os << "\n";
}
-void WasmMemoryObject::WasmMemoryObjectPrint(std::ostream& os) {
- PrintHeader(os, "WasmMemoryObject");
- os << "\n - array_buffer: " << Brief(array_buffer());
- os << "\n - maximum_pages: " << maximum_pages();
- os << "\n - instances: " << Brief(instances());
- os << "\n";
-}
-
-void WasmTagObject::WasmTagObjectPrint(std::ostream& os) {
- PrintHeader(os, "WasmTagObject");
- os << "\n - serialized_signature: " << Brief(serialized_signature());
- os << "\n - tag: " << Brief(tag());
- os << "\n";
-}
-
void WasmIndirectFunctionTable::WasmIndirectFunctionTablePrint(
std::ostream& os) {
PrintHeader(os, "WasmIndirectFunctionTable");
@@ -2141,13 +1999,6 @@ void StoreHandler::StoreHandlerPrint(std::ostream& os) {
os << "\n";
}
-void AccessorPair::AccessorPairPrint(std::ostream& os) {
- PrintHeader(os, "AccessorPair");
- os << "\n - getter: " << Brief(getter());
- os << "\n - setter: " << Brief(setter());
- os << "\n";
-}
-
void CallHandlerInfo::CallHandlerInfoPrint(std::ostream& os) {
PrintHeader(os, "CallHandlerInfo");
os << "\n - callback: " << Brief(callback());
@@ -2431,18 +2282,6 @@ void ScopeInfo::ScopeInfoPrint(std::ostream& os) {
os << "\n";
}
-void StackFrameInfo::StackFrameInfoPrint(std::ostream& os) {
- PrintHeader(os, "StackFrameInfo");
- os << "\n - receiver_or_instance: " << Brief(receiver_or_instance());
- os << "\n - function: " << Brief(function());
- os << "\n - code_object: " << Brief(TorqueGeneratedClass::code_object());
- os << "\n - code_offset_or_source_position: "
- << code_offset_or_source_position();
- os << "\n - flags: " << flags();
- os << "\n - parameters: " << Brief(parameters());
- os << "\n";
-}
-
void PreparseData::PreparseDataPrint(std::ostream& os) {
PrintHeader(os, "PreparseData");
os << "\n - data_length: " << data_length();
@@ -2459,13 +2298,6 @@ void PreparseData::PreparseDataPrint(std::ostream& os) {
os << "\n";
}
-void InterpreterData::InterpreterDataPrint(std::ostream& os) {
- PrintHeader(os, "InterpreterData");
- os << "\n - bytecode_array: " << Brief(bytecode_array());
- os << "\n - interpreter_trampoline: " << Brief(interpreter_trampoline());
- os << "\n";
-}
-
template <HeapObjectReferenceType kRefType, typename StorageType>
void TaggedImpl<kRefType, StorageType>::Print() {
StdoutStream os;
@@ -2659,12 +2491,12 @@ void DescriptorArray::PrintDescriptorDetails(std::ostream& os,
details.PrintAsFastTo(os, mode);
os << " @ ";
switch (details.location()) {
- case kField: {
+ case PropertyLocation::kField: {
FieldType field_type = GetFieldType(descriptor);
field_type.PrintTo(os);
break;
}
- case kDescriptor:
+ case PropertyLocation::kDescriptor:
Object value = GetStrongValue(descriptor);
os << Brief(value);
if (value.IsAccessorPair()) {
diff --git a/chromium/v8/src/diagnostics/perf-jit.h b/chromium/v8/src/diagnostics/perf-jit.h
index 746f9f7c857..47a6002b087 100644
--- a/chromium/v8/src/diagnostics/perf-jit.h
+++ b/chromium/v8/src/diagnostics/perf-jit.h
@@ -87,6 +87,7 @@ class PerfJitLogger : public CodeEventLogger {
static const uint32_t kElfMachARM = 40;
static const uint32_t kElfMachMIPS = 8;
static const uint32_t kElfMachMIPS64 = 8;
+ static const uint32_t kElfMachLOONG64 = 258;
static const uint32_t kElfMachARM64 = 183;
static const uint32_t kElfMachS390x = 22;
static const uint32_t kElfMachPPC64 = 21;
@@ -103,6 +104,8 @@ class PerfJitLogger : public CodeEventLogger {
return kElfMachMIPS;
#elif V8_TARGET_ARCH_MIPS64
return kElfMachMIPS64;
+#elif V8_TARGET_ARCH_LOONG64
+ return kElfMachLOONG64;
#elif V8_TARGET_ARCH_ARM64
return kElfMachARM64;
#elif V8_TARGET_ARCH_S390X
diff --git a/chromium/v8/src/diagnostics/ppc/disasm-ppc.cc b/chromium/v8/src/diagnostics/ppc/disasm-ppc.cc
index affbc0fc8e7..7d366a6ba12 100644
--- a/chromium/v8/src/diagnostics/ppc/disasm-ppc.cc
+++ b/chromium/v8/src/diagnostics/ppc/disasm-ppc.cc
@@ -917,6 +917,18 @@ void Decoder::DecodeExt2(Instruction* instr) {
Format(instr, "cnttzd'. 'ra, 'rs");
return;
}
+ case BRH: {
+ Format(instr, "brh 'ra, 'rs");
+ return;
+ }
+ case BRW: {
+ Format(instr, "brw 'ra, 'rs");
+ return;
+ }
+ case BRD: {
+ Format(instr, "brd 'ra, 'rs");
+ return;
+ }
case ANDX: {
Format(instr, "and'. 'ra, 'rs, 'rb");
return;
@@ -1393,13 +1405,20 @@ void Decoder::DecodeExt6(Instruction* instr) {
#undef DECODE_XX2_B_INSTRUCTIONS
}
switch (EXT6 | (instr->BitField(10, 2))) {
-#define DECODE_XX2_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
- case opcode_name: { \
- Format(instr, #name " 'Xt, 'Xb"); \
- return; \
+#define DECODE_XX2_VECTOR_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
+ case opcode_name: { \
+ Format(instr, #name " 'Xt, 'Xb"); \
+ return; \
+ }
+ PPC_XX2_OPCODE_VECTOR_A_FORM_LIST(DECODE_XX2_VECTOR_A_INSTRUCTIONS)
+#undef DECODE_XX2_VECTOR_A_INSTRUCTIONS
+#define DECODE_XX2_SCALAR_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
+ case opcode_name: { \
+ Format(instr, #name " 'Dt, 'Db"); \
+ return; \
}
- PPC_XX2_OPCODE_A_FORM_LIST(DECODE_XX2_A_INSTRUCTIONS)
-#undef DECODE_XX2_A_INSTRUCTIONS
+ PPC_XX2_OPCODE_SCALAR_A_FORM_LIST(DECODE_XX2_SCALAR_A_INSTRUCTIONS)
+#undef DECODE_XX2_SCALAR_A_INSTRUCTIONS
}
Unknown(instr); // not used by V8
}
diff --git a/chromium/v8/src/diagnostics/ppc/eh-frame-ppc.cc b/chromium/v8/src/diagnostics/ppc/eh-frame-ppc.cc
index 148d01116df..8f7198cd05e 100644
--- a/chromium/v8/src/diagnostics/ppc/eh-frame-ppc.cc
+++ b/chromium/v8/src/diagnostics/ppc/eh-frame-ppc.cc
@@ -32,7 +32,6 @@ int EhFrameWriter::RegisterToDwarfCode(Register name) {
return kR0DwarfCode;
default:
UNIMPLEMENTED();
- return -1;
}
}
@@ -47,7 +46,6 @@ const char* EhFrameDisassembler::DwarfRegisterCodeToString(int code) {
return "sp";
default:
UNIMPLEMENTED();
- return nullptr;
}
}
diff --git a/chromium/v8/src/diagnostics/riscv64/disasm-riscv64.cc b/chromium/v8/src/diagnostics/riscv64/disasm-riscv64.cc
index 2955612166e..ed899d9212f 100644
--- a/chromium/v8/src/diagnostics/riscv64/disasm-riscv64.cc
+++ b/chromium/v8/src/diagnostics/riscv64/disasm-riscv64.cc
@@ -68,11 +68,15 @@ class Decoder {
// Printing of common values.
void PrintRegister(int reg);
void PrintFPURegister(int freg);
+ void PrintVRegister(int reg);
void PrintFPUStatusRegister(int freg);
void PrintRs1(Instruction* instr);
void PrintRs2(Instruction* instr);
void PrintRd(Instruction* instr);
+ void PrintUimm(Instruction* instr);
void PrintVs1(Instruction* instr);
+ void PrintVs2(Instruction* instr);
+ void PrintVd(Instruction* instr);
void PrintFRs1(Instruction* instr);
void PrintFRs2(Instruction* instr);
void PrintFRs3(Instruction* instr);
@@ -96,10 +100,15 @@ class Decoder {
void PrintRvcImm8Addi4spn(Instruction* instr);
void PrintRvcImm11CJ(Instruction* instr);
void PrintRvcImm8B(Instruction* instr);
+ void PrintRvvVm(Instruction* instr);
void PrintAcquireRelease(Instruction* instr);
void PrintBranchOffset(Instruction* instr);
void PrintStoreOffset(Instruction* instr);
void PrintCSRReg(Instruction* instr);
+ void PrintRvvSEW(Instruction* instr);
+ void PrintRvvLMUL(Instruction* instr);
+ void PrintRvvSimm5(Instruction* instr);
+ void PrintRvvUimm5(Instruction* instr);
void PrintRoundingMode(Instruction* instr);
void PrintMemoryOrder(Instruction* instr, bool is_pred);
@@ -123,6 +132,16 @@ class Decoder {
void DecodeCJType(Instruction* instr);
void DecodeCBType(Instruction* instr);
+ void DecodeVType(Instruction* instr);
+ void DecodeRvvIVV(Instruction* instr);
+ void DecodeRvvFVV(Instruction* instr);
+ void DecodeRvvFVF(Instruction* instr);
+ void DecodeRvvIVI(Instruction* instr);
+ void DecodeRvvIVX(Instruction* instr);
+ void DecodeRvvVL(Instruction* instr);
+ void DecodeRvvVS(Instruction* instr);
+ void DecodeRvvMVV(Instruction* instr);
+ void DecodeRvvMVX(Instruction* instr);
// Printing of instruction name.
void PrintInstructionName(Instruction* instr);
@@ -137,6 +156,8 @@ class Decoder {
void Format(Instruction* instr, const char* format);
void Unknown(Instruction* instr);
+ int switch_sew(Instruction* instr);
+ int switch_nf(Instruction* instr);
const disasm::NameConverter& converter_;
v8::base::Vector<char> out_buffer_;
int out_buffer_pos_;
@@ -164,6 +185,10 @@ void Decoder::PrintRegister(int reg) {
Print(converter_.NameOfCPURegister(reg));
}
+void Decoder::PrintVRegister(int reg) {
+ Print(v8::internal::VRegisters::Name(reg));
+}
+
void Decoder::PrintRs1(Instruction* instr) {
int reg = instr->Rs1Value();
PrintRegister(reg);
@@ -179,11 +204,26 @@ void Decoder::PrintRd(Instruction* instr) {
PrintRegister(reg);
}
-void Decoder::PrintVs1(Instruction* instr) {
+void Decoder::PrintUimm(Instruction* instr) {
int val = instr->Rs1Value();
out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", val);
}
+void Decoder::PrintVs1(Instruction* instr) {
+ int reg = instr->Vs1Value();
+ PrintVRegister(reg);
+}
+
+void Decoder::PrintVs2(Instruction* instr) {
+ int reg = instr->Vs2Value();
+ PrintVRegister(reg);
+}
+
+void Decoder::PrintVd(Instruction* instr) {
+ int reg = instr->VdValue();
+ PrintVRegister(reg);
+}
+
// Print the FPUregister name according to the active name converter.
void Decoder::PrintFPURegister(int freg) {
Print(converter_.NameOfXMMRegister(freg));
@@ -247,6 +287,26 @@ void Decoder::PrintStoreOffset(Instruction* instr) {
out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
}
+void Decoder::PrintRvvSEW(Instruction* instr) {
+ const char* sew = instr->RvvSEW();
+ out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%s", sew);
+}
+
+void Decoder::PrintRvvLMUL(Instruction* instr) {
+ const char* lmul = instr->RvvLMUL();
+ out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%s", lmul);
+}
+
+void Decoder::PrintRvvSimm5(Instruction* instr) {
+ const int simm5 = instr->RvvSimm5();
+ out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", simm5);
+}
+
+void Decoder::PrintRvvUimm5(Instruction* instr) {
+ const uint32_t uimm5 = instr->RvvUimm5();
+ out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", uimm5);
+}
+
void Decoder::PrintImm20U(Instruction* instr) {
int32_t imm = instr->Imm20UValue();
out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
@@ -335,6 +395,13 @@ void Decoder::PrintRvcImm8B(Instruction* instr) {
out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
}
+void Decoder::PrintRvvVm(Instruction* instr) {
+ uint8_t imm = instr->RvvVM();
+ if (imm == 0) {
+ out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, " vm");
+ }
+}
+
void Decoder::PrintAcquireRelease(Instruction* instr) {
bool aq = instr->AqValue();
bool rl = instr->RlValue();
@@ -724,13 +791,50 @@ int Decoder::FormatOption(Instruction* instr, const char* format) {
DCHECK(STRING_STARTS_WITH(format, "suc"));
PrintMemoryOrder(instr, false);
return 3;
+ } else if (format[1] == 'e') {
+ DCHECK(STRING_STARTS_WITH(format, "sew"));
+ PrintRvvSEW(instr);
+ return 3;
+ } else if (format[1] == 'i') {
+ DCHECK(STRING_STARTS_WITH(format, "simm5"));
+ PrintRvvSimm5(instr);
+ return 5;
}
UNREACHABLE();
}
- case 'v': { // 'vs1: Raw values from register fields
- DCHECK(STRING_STARTS_WITH(format, "vs1"));
- PrintVs1(instr);
- return 3;
+ case 'v': {
+ if (format[1] == 'd') {
+ DCHECK(STRING_STARTS_WITH(format, "vd"));
+ PrintVd(instr);
+ return 2;
+ } else if (format[2] == '1') {
+ DCHECK(STRING_STARTS_WITH(format, "vs1"));
+ PrintVs1(instr);
+ return 3;
+ } else if (format[2] == '2') {
+ DCHECK(STRING_STARTS_WITH(format, "vs2"));
+ PrintVs2(instr);
+ return 3;
+ } else {
+ DCHECK(STRING_STARTS_WITH(format, "vm"));
+ PrintRvvVm(instr);
+ return 2;
+ }
+ }
+ case 'l': {
+ DCHECK(STRING_STARTS_WITH(format, "lmul"));
+ PrintRvvLMUL(instr);
+ return 4;
+ }
+ case 'u': {
+ if (STRING_STARTS_WITH(format, "uimm5")) {
+ PrintRvvUimm5(instr);
+ return 5;
+ } else {
+ DCHECK(STRING_STARTS_WITH(format, "uimm"));
+ PrintUimm(instr);
+ return 4;
+ }
}
case 't': { // 'target: target of branch instructions'
DCHECK(STRING_STARTS_WITH(format, "target"));
@@ -1308,256 +1412,265 @@ void Decoder::DecodeR4Type(Instruction* instr) {
}
void Decoder::DecodeIType(Instruction* instr) {
- switch (instr->InstructionBits() & kITypeMask) {
- case RO_JALR:
- if (instr->RdValue() == zero_reg.code() &&
- instr->Rs1Value() == ra.code() && instr->Imm12Value() == 0)
- Format(instr, "ret");
- else if (instr->RdValue() == zero_reg.code() && instr->Imm12Value() == 0)
- Format(instr, "jr 'rs1");
- else if (instr->RdValue() == ra.code() && instr->Imm12Value() == 0)
- Format(instr, "jalr 'rs1");
- else
- Format(instr, "jalr 'rd, 'imm12('rs1)'target");
- break;
- case RO_LB:
- Format(instr, "lb 'rd, 'imm12('rs1)");
- break;
- case RO_LH:
- Format(instr, "lh 'rd, 'imm12('rs1)");
- break;
- case RO_LW:
- Format(instr, "lw 'rd, 'imm12('rs1)");
- break;
- case RO_LBU:
- Format(instr, "lbu 'rd, 'imm12('rs1)");
- break;
- case RO_LHU:
- Format(instr, "lhu 'rd, 'imm12('rs1)");
- break;
+ if (instr->vl_vs_width() != -1) {
+ DecodeRvvVL(instr);
+ } else {
+ switch (instr->InstructionBits() & kITypeMask) {
+ case RO_JALR:
+ if (instr->RdValue() == zero_reg.code() &&
+ instr->Rs1Value() == ra.code() && instr->Imm12Value() == 0)
+ Format(instr, "ret");
+ else if (instr->RdValue() == zero_reg.code() &&
+ instr->Imm12Value() == 0)
+ Format(instr, "jr 'rs1");
+ else if (instr->RdValue() == ra.code() && instr->Imm12Value() == 0)
+ Format(instr, "jalr 'rs1");
+ else
+ Format(instr, "jalr 'rd, 'imm12('rs1)");
+ break;
+ case RO_LB:
+ Format(instr, "lb 'rd, 'imm12('rs1)");
+ break;
+ case RO_LH:
+ Format(instr, "lh 'rd, 'imm12('rs1)");
+ break;
+ case RO_LW:
+ Format(instr, "lw 'rd, 'imm12('rs1)");
+ break;
+ case RO_LBU:
+ Format(instr, "lbu 'rd, 'imm12('rs1)");
+ break;
+ case RO_LHU:
+ Format(instr, "lhu 'rd, 'imm12('rs1)");
+ break;
#ifdef V8_TARGET_ARCH_64_BIT
- case RO_LWU:
- Format(instr, "lwu 'rd, 'imm12('rs1)");
- break;
- case RO_LD:
- Format(instr, "ld 'rd, 'imm12('rs1)");
- break;
+ case RO_LWU:
+ Format(instr, "lwu 'rd, 'imm12('rs1)");
+ break;
+ case RO_LD:
+ Format(instr, "ld 'rd, 'imm12('rs1)");
+ break;
#endif /*V8_TARGET_ARCH_64_BIT*/
- case RO_ADDI:
- if (instr->Imm12Value() == 0) {
- if (instr->RdValue() == zero_reg.code() &&
- instr->Rs1Value() == zero_reg.code())
- Format(instr, "nop");
+ case RO_ADDI:
+ if (instr->Imm12Value() == 0) {
+ if (instr->RdValue() == zero_reg.code() &&
+ instr->Rs1Value() == zero_reg.code())
+ Format(instr, "nop");
+ else
+ Format(instr, "mv 'rd, 'rs1");
+ } else if (instr->Rs1Value() == zero_reg.code()) {
+ Format(instr, "li 'rd, 'imm12");
+ } else {
+ Format(instr, "addi 'rd, 'rs1, 'imm12");
+ }
+ break;
+ case RO_SLTI:
+ Format(instr, "slti 'rd, 'rs1, 'imm12");
+ break;
+ case RO_SLTIU:
+ if (instr->Imm12Value() == 1)
+ Format(instr, "seqz 'rd, 'rs1");
else
- Format(instr, "mv 'rd, 'rs1");
- } else if (instr->Rs1Value() == zero_reg.code()) {
- Format(instr, "li 'rd, 'imm12");
- } else {
- Format(instr, "addi 'rd, 'rs1, 'imm12");
- }
- break;
- case RO_SLTI:
- Format(instr, "slti 'rd, 'rs1, 'imm12");
- break;
- case RO_SLTIU:
- if (instr->Imm12Value() == 1)
- Format(instr, "seqz 'rd, 'rs1");
- else
- Format(instr, "sltiu 'rd, 'rs1, 'imm12");
- break;
- case RO_XORI:
- if (instr->Imm12Value() == -1)
- Format(instr, "not 'rd, 'rs1");
- else
- Format(instr, "xori 'rd, 'rs1, 'imm12x");
- break;
- case RO_ORI:
- Format(instr, "ori 'rd, 'rs1, 'imm12x");
- break;
- case RO_ANDI:
- Format(instr, "andi 'rd, 'rs1, 'imm12x");
- break;
- case RO_SLLI:
- Format(instr, "slli 'rd, 'rs1, 's64");
- break;
- case RO_SRLI: { // RO_SRAI
- if (!instr->IsArithShift()) {
- Format(instr, "srli 'rd, 'rs1, 's64");
- } else {
- Format(instr, "srai 'rd, 'rs1, 's64");
+ Format(instr, "sltiu 'rd, 'rs1, 'imm12");
+ break;
+ case RO_XORI:
+ if (instr->Imm12Value() == -1)
+ Format(instr, "not 'rd, 'rs1");
+ else
+ Format(instr, "xori 'rd, 'rs1, 'imm12x");
+ break;
+ case RO_ORI:
+ Format(instr, "ori 'rd, 'rs1, 'imm12x");
+ break;
+ case RO_ANDI:
+ Format(instr, "andi 'rd, 'rs1, 'imm12x");
+ break;
+ case RO_SLLI:
+ Format(instr, "slli 'rd, 'rs1, 's64");
+ break;
+ case RO_SRLI: { // RO_SRAI
+ if (!instr->IsArithShift()) {
+ Format(instr, "srli 'rd, 'rs1, 's64");
+ } else {
+ Format(instr, "srai 'rd, 'rs1, 's64");
+ }
+ break;
}
- break;
- }
#ifdef V8_TARGET_ARCH_64_BIT
- case RO_ADDIW:
- if (instr->Imm12Value() == 0)
- Format(instr, "sext.w 'rd, 'rs1");
- else
- Format(instr, "addiw 'rd, 'rs1, 'imm12");
- break;
- case RO_SLLIW:
- Format(instr, "slliw 'rd, 'rs1, 's32");
- break;
- case RO_SRLIW: { // RO_SRAIW
- if (!instr->IsArithShift()) {
- Format(instr, "srliw 'rd, 'rs1, 's32");
- } else {
- Format(instr, "sraiw 'rd, 'rs1, 's32");
+ case RO_ADDIW:
+ if (instr->Imm12Value() == 0)
+ Format(instr, "sext.w 'rd, 'rs1");
+ else
+ Format(instr, "addiw 'rd, 'rs1, 'imm12");
+ break;
+ case RO_SLLIW:
+ Format(instr, "slliw 'rd, 'rs1, 's32");
+ break;
+ case RO_SRLIW: { // RO_SRAIW
+ if (!instr->IsArithShift()) {
+ Format(instr, "srliw 'rd, 'rs1, 's32");
+ } else {
+ Format(instr, "sraiw 'rd, 'rs1, 's32");
+ }
+ break;
}
- break;
- }
#endif /*V8_TARGET_ARCH_64_BIT*/
- case RO_FENCE:
- if (instr->MemoryOrder(true) == PSIORW &&
- instr->MemoryOrder(false) == PSIORW)
- Format(instr, "fence");
- else
- Format(instr, "fence 'pre, 'suc");
- break;
- case RO_ECALL: { // RO_EBREAK
- if (instr->Imm12Value() == 0) { // ECALL
- Format(instr, "ecall");
- } else if (instr->Imm12Value() == 1) { // EBREAK
- Format(instr, "ebreak");
- } else {
- UNSUPPORTED_RISCV();
+ case RO_FENCE:
+ if (instr->MemoryOrder(true) == PSIORW &&
+ instr->MemoryOrder(false) == PSIORW)
+ Format(instr, "fence");
+ else
+ Format(instr, "fence 'pre, 'suc");
+ break;
+ case RO_ECALL: { // RO_EBREAK
+ if (instr->Imm12Value() == 0) { // ECALL
+ Format(instr, "ecall");
+ } else if (instr->Imm12Value() == 1) { // EBREAK
+ Format(instr, "ebreak");
+ } else {
+ UNSUPPORTED_RISCV();
+ }
+ break;
}
- break;
- }
- // TODO(riscv): use Zifencei Standard Extension macro block
- case RO_FENCE_I:
- Format(instr, "fence.i");
- break;
- // TODO(riscv): use Zicsr Standard Extension macro block
- case RO_CSRRW:
- if (instr->CsrValue() == csr_fcsr) {
+ // TODO(riscv): use Zifencei Standard Extension macro block
+ case RO_FENCE_I:
+ Format(instr, "fence.i");
+ break;
+ // TODO(riscv): use Zicsr Standard Extension macro block
+ // FIXME(RISC-V): Add special formatting for CSR registers
+ case RO_CSRRW:
+ if (instr->CsrValue() == csr_fcsr) {
+ if (instr->RdValue() == zero_reg.code())
+ Format(instr, "fscsr 'rs1");
+ else
+ Format(instr, "fscsr 'rd, 'rs1");
+ } else if (instr->CsrValue() == csr_frm) {
+ if (instr->RdValue() == zero_reg.code())
+ Format(instr, "fsrm 'rs1");
+ else
+ Format(instr, "fsrm 'rd, 'rs1");
+ } else if (instr->CsrValue() == csr_fflags) {
+ if (instr->RdValue() == zero_reg.code())
+ Format(instr, "fsflags 'rs1");
+ else
+ Format(instr, "fsflags 'rd, 'rs1");
+ } else if (instr->RdValue() == zero_reg.code()) {
+ Format(instr, "csrw 'csr, 'rs1");
+ } else {
+ Format(instr, "csrrw 'rd, 'csr, 'rs1");
+ }
+ break;
+ case RO_CSRRS:
+ if (instr->Rs1Value() == zero_reg.code()) {
+ switch (instr->CsrValue()) {
+ case csr_instret:
+ Format(instr, "rdinstret 'rd");
+ break;
+ case csr_instreth:
+ Format(instr, "rdinstreth 'rd");
+ break;
+ case csr_time:
+ Format(instr, "rdtime 'rd");
+ break;
+ case csr_timeh:
+ Format(instr, "rdtimeh 'rd");
+ break;
+ case csr_cycle:
+ Format(instr, "rdcycle 'rd");
+ break;
+ case csr_cycleh:
+ Format(instr, "rdcycleh 'rd");
+ break;
+ case csr_fflags:
+ Format(instr, "frflags 'rd");
+ break;
+ case csr_frm:
+ Format(instr, "frrm 'rd");
+ break;
+ case csr_fcsr:
+ Format(instr, "frcsr 'rd");
+ break;
+ default:
+ UNREACHABLE();
+ }
+ } else if (instr->Rs1Value() == zero_reg.code()) {
+ Format(instr, "csrr 'rd, 'csr");
+ } else if (instr->RdValue() == zero_reg.code()) {
+ Format(instr, "csrs 'csr, 'rs1");
+ } else {
+ Format(instr, "csrrs 'rd, 'csr, 'rs1");
+ }
+ break;
+ case RO_CSRRC:
if (instr->RdValue() == zero_reg.code())
- Format(instr, "fscsr 'rs1");
+ Format(instr, "csrc 'csr, 'rs1");
else
- Format(instr, "fscsr 'rd, 'rs1");
- } else if (instr->CsrValue() == csr_frm) {
+ Format(instr, "csrrc 'rd, 'csr, 'rs1");
+ break;
+ case RO_CSRRWI:
if (instr->RdValue() == zero_reg.code())
- Format(instr, "fsrm 'rs1");
+ Format(instr, "csrwi 'csr, 'uimm");
else
- Format(instr, "fsrm 'rd, 'rs1");
- } else if (instr->CsrValue() == csr_fflags) {
+ Format(instr, "csrrwi 'rd, 'csr, 'uimm");
+ break;
+ case RO_CSRRSI:
if (instr->RdValue() == zero_reg.code())
- Format(instr, "fsflags 'rs1");
+ Format(instr, "csrsi 'csr, 'uimm");
else
- Format(instr, "fsflags 'rd, 'rs1");
- } else if (instr->RdValue() == zero_reg.code()) {
- Format(instr, "csrw 'csr, 'rs1");
- } else {
- Format(instr, "csrrw 'rd, 'csr, 'rs1");
- }
- break;
- case RO_CSRRS:
- if (instr->Rs1Value() == zero_reg.code()) {
- switch (instr->CsrValue()) {
- case csr_instret:
- Format(instr, "rdinstret 'rd");
- break;
- case csr_instreth:
- Format(instr, "rdinstreth 'rd");
- break;
- case csr_time:
- Format(instr, "rdtime 'rd");
- break;
- case csr_timeh:
- Format(instr, "rdtimeh 'rd");
- break;
- case csr_cycle:
- Format(instr, "rdcycle 'rd");
- break;
- case csr_cycleh:
- Format(instr, "rdcycleh 'rd");
- break;
- case csr_fflags:
- Format(instr, "frflags 'rd");
- break;
- case csr_frm:
- Format(instr, "frrm 'rd");
- break;
- case csr_fcsr:
- Format(instr, "frcsr 'rd");
- break;
- default:
- UNREACHABLE();
- }
- } else if (instr->Rs1Value() == zero_reg.code()) {
- Format(instr, "csrr 'rd, 'csr");
- } else if (instr->RdValue() == zero_reg.code()) {
- Format(instr, "csrs 'csr, 'rs1");
- } else {
- Format(instr, "csrrs 'rd, 'csr, 'rs1");
- }
- break;
- case RO_CSRRC:
- if (instr->RdValue() == zero_reg.code())
- Format(instr, "csrc 'csr, 'rs1");
- else
- Format(instr, "csrrc 'rd, 'csr, 'rs1");
- break;
- case RO_CSRRWI:
- if (instr->RdValue() == zero_reg.code())
- Format(instr, "csrwi 'csr, 'vs1");
- else
- Format(instr, "csrrwi 'rd, 'csr, 'vs1");
- break;
- case RO_CSRRSI:
- if (instr->RdValue() == zero_reg.code())
- Format(instr, "csrsi 'csr, 'vs1");
- else
- Format(instr, "csrrsi 'rd, 'csr, 'vs1");
- break;
- case RO_CSRRCI:
- if (instr->RdValue() == zero_reg.code())
- Format(instr, "csrci 'csr, 'vs1");
- else
- Format(instr, "csrrci 'rd, 'csr, 'vs1");
- break;
- // TODO(riscv): use F Extension macro block
- case RO_FLW:
- Format(instr, "flw 'fd, 'imm12('rs1)");
- break;
- // TODO(riscv): use D Extension macro block
- case RO_FLD:
- Format(instr, "fld 'fd, 'imm12('rs1)");
- break;
- default:
- UNSUPPORTED_RISCV();
+ Format(instr, "csrrsi 'rd, 'csr, 'uimm");
+ break;
+ case RO_CSRRCI:
+ if (instr->RdValue() == zero_reg.code())
+ Format(instr, "csrci 'csr, 'uimm");
+ else
+ Format(instr, "csrrci 'rd, 'csr, 'uimm");
+ break;
+ // TODO(riscv): use F Extension macro block
+ case RO_FLW:
+ Format(instr, "flw 'fd, 'imm12('rs1)");
+ break;
+ // TODO(riscv): use D Extension macro block
+ case RO_FLD:
+ Format(instr, "fld 'fd, 'imm12('rs1)");
+ break;
+ default:
+ UNSUPPORTED_RISCV();
+ }
}
}
void Decoder::DecodeSType(Instruction* instr) {
- switch (instr->InstructionBits() & kSTypeMask) {
- case RO_SB:
- Format(instr, "sb 'rs2, 'offS('rs1)");
- break;
- case RO_SH:
- Format(instr, "sh 'rs2, 'offS('rs1)");
- break;
- case RO_SW:
- Format(instr, "sw 'rs2, 'offS('rs1)");
- break;
+ if (instr->vl_vs_width() != -1) {
+ DecodeRvvVS(instr);
+ } else {
+ switch (instr->InstructionBits() & kSTypeMask) {
+ case RO_SB:
+ Format(instr, "sb 'rs2, 'offS('rs1)");
+ break;
+ case RO_SH:
+ Format(instr, "sh 'rs2, 'offS('rs1)");
+ break;
+ case RO_SW:
+ Format(instr, "sw 'rs2, 'offS('rs1)");
+ break;
#ifdef V8_TARGET_ARCH_64_BIT
- case RO_SD:
- Format(instr, "sd 'rs2, 'offS('rs1)");
- break;
+ case RO_SD:
+ Format(instr, "sd 'rs2, 'offS('rs1)");
+ break;
#endif /*V8_TARGET_ARCH_64_BIT*/
- // TODO(riscv): use F Extension macro block
- case RO_FSW:
- Format(instr, "fsw 'fs2, 'offS('rs1)");
- break;
- // TODO(riscv): use D Extension macro block
- case RO_FSD:
- Format(instr, "fsd 'fs2, 'offS('rs1)");
- break;
- default:
- UNSUPPORTED_RISCV();
+ // TODO(riscv): use F Extension macro block
+ case RO_FSW:
+ Format(instr, "fsw 'fs2, 'offS('rs1)");
+ break;
+ // TODO(riscv): use D Extension macro block
+ case RO_FSD:
+ Format(instr, "fsd 'fs2, 'offS('rs1)");
+ break;
+ default:
+ UNSUPPORTED_RISCV();
+ }
}
}
-
void Decoder::DecodeBType(Instruction* instr) {
switch (instr->InstructionBits() & kBTypeMask) {
case RO_BEQ:
@@ -1595,6 +1708,7 @@ void Decoder::DecodeUType(Instruction* instr) {
UNSUPPORTED_RISCV();
}
}
+// namespace internal
void Decoder::DecodeJType(Instruction* instr) {
// J Type doesn't have additional mask
switch (instr->BaseOpcodeValue()) {
@@ -1791,6 +1905,631 @@ void Decoder::DecodeCBType(Instruction* instr) {
}
}
+void Decoder::DecodeRvvIVV(Instruction* instr) {
+ DCHECK_EQ(instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask), OP_IVV);
+ switch (instr->InstructionBits() & kVTypeMask) {
+ case RO_V_VADD_VV:
+ Format(instr, "vadd.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VSADD_VV:
+ Format(instr, "vsadd.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VSADDU_VV:
+ Format(instr, "vsaddu.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VSUB_VV:
+ Format(instr, "vsub.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VSSUB_VV:
+ Format(instr, "vssub.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VMIN_VV:
+ Format(instr, "vmin.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VMINU_VV:
+ Format(instr, "vminu.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VMAX_VV:
+ Format(instr, "vmax.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VMAXU_VV:
+ Format(instr, "vmaxu.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VAND_VV:
+ Format(instr, "vand.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VOR_VV:
+ Format(instr, "vor.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VXOR_VV:
+ Format(instr, "vxor.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VRGATHER_VV:
+ Format(instr, "vrgather.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VMSEQ_VV:
+ Format(instr, "vmseq.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VMSNE_VV:
+ Format(instr, "vmsne.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VMSLT_VV:
+ Format(instr, "vmslt.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VMSLTU_VV:
+ Format(instr, "vmsltu.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VMSLE_VV:
+ Format(instr, "vmsle.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VMSLEU_VV:
+ Format(instr, "vmsleu.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VMV_VV:
+ if (instr->RvvVM()) {
+ Format(instr, "vmv.vv 'vd, 'vs1");
+ } else {
+ Format(instr, "vmerge.vvm 'vd, 'vs2, 'vs1, v0");
+ }
+ break;
+ case RO_V_VADC_VV:
+ if (!instr->RvvVM()) {
+ Format(instr, "vadc.vvm 'vd, 'vs2, 'vs1");
+ } else {
+ UNREACHABLE();
+ }
+ break;
+ case RO_V_VMADC_VV:
+ if (!instr->RvvVM()) {
+ Format(instr, "vmadc.vvm 'vd, 'vs2, 'vs1");
+ } else {
+ UNREACHABLE();
+ }
+ break;
+ default:
+ UNSUPPORTED_RISCV();
+ break;
+ }
+}
+
+void Decoder::DecodeRvvIVI(Instruction* instr) {
+ DCHECK_EQ(instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask), OP_IVI);
+ switch (instr->InstructionBits() & kVTypeMask) {
+ case RO_V_VADD_VI:
+ Format(instr, "vadd.vi 'vd, 'vs2, 'simm5'vm");
+ break;
+ case RO_V_VSADD_VI:
+ Format(instr, "vsadd.vi 'vd, 'vs2, 'simm5'vm");
+ break;
+ case RO_V_VSADDU_VI:
+ Format(instr, "vsaddu.vi 'vd, 'vs2, 'simm5'vm");
+ break;
+ case RO_V_VRSUB_VI:
+ Format(instr, "vrsub.vi 'vd, 'vs2, 'simm5'vm");
+ break;
+ case RO_V_VAND_VI:
+ Format(instr, "vand.vi 'vd, 'vs2, 'simm5'vm");
+ break;
+ case RO_V_VOR_VI:
+ Format(instr, "vor.vi 'vd, 'vs2, 'simm5'vm");
+ break;
+ case RO_V_VXOR_VI:
+ Format(instr, "vxor.vi 'vd, 'vs2, 'simm5'vm");
+ break;
+ case RO_V_VRGATHER_VI:
+ Format(instr, "vrgather.vi 'vd, 'vs2, 'simm5'vm");
+ break;
+ case RO_V_VMV_VI:
+ if (instr->RvvVM()) {
+ Format(instr, "vmv.vi 'vd, 'simm5");
+ } else {
+ Format(instr, "vmerge.vim 'vd, 'vs2, 'simm5, v0");
+ }
+ break;
+ case RO_V_VMSEQ_VI:
+ Format(instr, "vmseq.vi 'vd, 'vs2, 'simm5'vm");
+ break;
+ case RO_V_VMSNE_VI:
+ Format(instr, "vmsne.vi 'vd, 'vs2, 'simm5'vm");
+ break;
+ case RO_V_VMSLEU_VI:
+ Format(instr, "vmsleu.vi 'vd, 'vs2, 'simm5'vm");
+ break;
+ case RO_V_VMSLE_VI:
+ Format(instr, "vmsle.vi 'vd, 'vs2, 'simm5'vm");
+ break;
+ case RO_V_VMSGTU_VI:
+ Format(instr, "vmsgtu.vi 'vd, 'vs2, 'simm5'vm");
+ break;
+ case RO_V_VMSGT_VI:
+ Format(instr, "vmsgt.vi 'vd, 'vs2, 'simm5'vm");
+ break;
+ case RO_V_VSLIDEDOWN_VI:
+ Format(instr, "vslidedown.vi 'vd, 'vs2, 'uimm5'vm");
+ break;
+ case RO_V_VSRL_VI:
+ Format(instr, "vsrl.vi 'vd, 'vs2, 'uimm5'vm");
+ break;
+ case RO_V_VSLL_VI:
+ Format(instr, "vsll.vi 'vd, 'vs2, 'uimm5'vm");
+ break;
+ case RO_V_VADC_VI:
+ if (!instr->RvvVM()) {
+ Format(instr, "vadc.vim 'vd, 'vs2, 'uimm5");
+ } else {
+ UNREACHABLE();
+ }
+ break;
+ case RO_V_VMADC_VI:
+ if (!instr->RvvVM()) {
+ Format(instr, "vmadc.vim 'vd, 'vs2, 'uimm5");
+ } else {
+ UNREACHABLE();
+ }
+ break;
+ default:
+ UNSUPPORTED_RISCV();
+ break;
+ }
+}
+
+void Decoder::DecodeRvvIVX(Instruction* instr) {
+ DCHECK_EQ(instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask), OP_IVX);
+ switch (instr->InstructionBits() & kVTypeMask) {
+ case RO_V_VADD_VX:
+ Format(instr, "vadd.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VSADD_VX:
+ Format(instr, "vsadd.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VSADDU_VX:
+ Format(instr, "vsaddu.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VSUB_VX:
+ Format(instr, "vsub.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VSSUB_VX:
+ Format(instr, "vssub.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VRSUB_VX:
+ Format(instr, "vrsub.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VMIN_VX:
+ Format(instr, "vmin.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VMINU_VX:
+ Format(instr, "vminu.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VMAX_VX:
+ Format(instr, "vmax.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VMAXU_VX:
+ Format(instr, "vmaxu.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VAND_VX:
+ Format(instr, "vand.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VOR_VX:
+ Format(instr, "vor.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VXOR_VX:
+ Format(instr, "vxor.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VRGATHER_VX:
+ Format(instr, "vrgather.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VMV_VX:
+ if (instr->RvvVM()) {
+ Format(instr, "vmv.vx 'vd, 'rs1");
+ } else {
+ Format(instr, "vmerge.vxm 'vd, 'vs2, 'rs1, v0");
+ }
+ break;
+ case RO_V_VMSEQ_VX:
+ Format(instr, "vmseq.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VMSNE_VX:
+ Format(instr, "vmsne.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VMSLT_VX:
+ Format(instr, "vmslt.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VMSLTU_VX:
+ Format(instr, "vmsltu.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VMSLE_VX:
+ Format(instr, "vmsle.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VMSLEU_VX:
+ Format(instr, "vmsleu.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VMSGT_VX:
+ Format(instr, "vmsgt.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VMSGTU_VX:
+ Format(instr, "vmsgtu.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VSLIDEDOWN_VX:
+ Format(instr, "vslidedown.vx 'vd, 'vs2, 'rs1'vm");
+ break;
+ case RO_V_VADC_VX:
+ if (!instr->RvvVM()) {
+ Format(instr, "vadc.vxm 'vd, 'vs2, 'rs1");
+ } else {
+ UNREACHABLE();
+ }
+ break;
+ case RO_V_VMADC_VX:
+ if (!instr->RvvVM()) {
+ Format(instr, "vmadc.vxm 'vd, 'vs2, 'rs1");
+ } else {
+ UNREACHABLE();
+ }
+ break;
+ case RO_V_VSLL_VX:
+ Format(instr, "vsll.vx 'vd, 'vs2, 'rs1");
+ break;
+ case RO_V_VSRL_VX:
+ Format(instr, "vsrl.vx 'vd, 'vs2, 'rs1");
+ break;
+ default:
+ UNSUPPORTED_RISCV();
+ break;
+ }
+}
+
+void Decoder::DecodeRvvMVV(Instruction* instr) {
+ DCHECK_EQ(instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask), OP_MVV);
+ switch (instr->InstructionBits() & kVTypeMask) {
+ case RO_V_VWXUNARY0:
+ if (instr->Vs1Value() == 0x0) {
+ Format(instr, "vmv.x.s 'rd, 'vs2");
+ } else {
+ UNSUPPORTED_RISCV();
+ }
+ break;
+ case RO_V_VREDMAXU:
+ Format(instr, "vredmaxu.vs 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VREDMAX:
+ Format(instr, "vredmax.vs 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VREDMIN:
+ Format(instr, "vredmin.vs 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VREDMINU:
+ Format(instr, "vredminu.vs 'vd, 'vs2, 'vs1'vm");
+ break;
+ default:
+ UNSUPPORTED_RISCV();
+ break;
+ }
+}
+
+void Decoder::DecodeRvvMVX(Instruction* instr) {
+ DCHECK_EQ(instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask), OP_MVX);
+ switch (instr->InstructionBits() & kVTypeMask) {
+ case RO_V_VRXUNARY0:
+ if (instr->Vs2Value() == 0x0) {
+ Format(instr, "vmv.s.x 'vd, 'rs1");
+ } else {
+ UNSUPPORTED_RISCV();
+ }
+ break;
+ default:
+ UNSUPPORTED_RISCV();
+ break;
+ }
+}
+
+void Decoder::DecodeRvvFVV(Instruction* instr) {
+ DCHECK_EQ(instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask), OP_FVV);
+ switch (instr->InstructionBits() & kVTypeMask) {
+ case RO_V_VFUNARY0:
+ switch (instr->Vs1Value()) {
+ case VFCVT_XU_F_V:
+ Format(instr, "vfcvt.xu.f.v 'vd, 'vs2'vm");
+ break;
+ case VFCVT_X_F_V:
+ Format(instr, "vfcvt.x.f.v 'vd, 'vs2'vm");
+ break;
+ case VFNCVT_F_F_W:
+ Format(instr, "vfncvt.f.f.w 'vd, 'vs2'vm");
+ break;
+ case VFCVT_F_X_V:
+ Format(instr, "vfcvt.f.x.v 'vd, 'vs2'vm");
+ break;
+ case VFCVT_F_XU_V:
+ Format(instr, "vfcvt.f.xu.v 'vd, 'vs2'vm");
+ break;
+ default:
+ UNSUPPORTED_RISCV();
+ break;
+ }
+ break;
+ case RO_V_VFUNARY1:
+ switch (instr->Vs1Value()) {
+ case VFCLASS_V:
+ Format(instr, "vfclass.v 'vd, 'vs2'vm");
+ break;
+ default:
+ break;
+ }
+ break;
+ case RO_V_VMFEQ_VV:
+ Format(instr, "vmfeq.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VMFNE_VV:
+ Format(instr, "vmfne.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VMFLT_VV:
+ Format(instr, "vmflt.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VMFLE_VV:
+ Format(instr, "vmfle.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VFMAX_VV:
+ Format(instr, "vfmax.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VFMIN_VV:
+ Format(instr, "vfmin.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VFSGNJ_VV:
+ Format(instr, "vfsgnj.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VFSGNJN_VV:
+ if (instr->Vs1Value() == instr->Vs2Value()) {
+ Format(instr, "vneg.vv 'vd, 'vs1'vm");
+ } else {
+ Format(instr, "vfsgnjn.vv 'vd, 'vs2, 'vs1'vm");
+ }
+ break;
+ case RO_V_VFSGNJX_VV:
+ if (instr->Vs1Value() == instr->Vs2Value()) {
+ Format(instr, "vabs.vv 'vd, 'vs1'vm");
+ } else {
+ Format(instr, "vfsgnjn.vv 'vd, 'vs2, 'vs1'vm");
+ }
+ break;
+ case RO_V_VFADD_VV:
+ Format(instr, "vfadd.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VFSUB_VV:
+ Format(instr, "vfsub.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VFDIV_VV:
+ Format(instr, "vfdiv.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ case RO_V_VFMUL_VV:
+ Format(instr, "vfmul.vv 'vd, 'vs2, 'vs1'vm");
+ break;
+ default:
+ UNSUPPORTED_RISCV();
+ break;
+ }
+}
+
+void Decoder::DecodeRvvFVF(Instruction* instr) {
+ DCHECK_EQ(instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask), OP_FVF);
+ switch (instr->InstructionBits() & kVTypeMask) {
+ case RO_V_VFSGNJ_VF:
+ Format(instr, "vfsgnj.vf 'vd, 'vs2, 'fs1'vm");
+ break;
+ case RO_V_VFSGNJN_VF:
+ Format(instr, "vfsgnjn.vf 'vd, 'vs2, 'fs1'vm");
+ break;
+ case RO_V_VFSGNJX_VF:
+ Format(instr, "vfsgnjn.vf 'vd, 'vs2, 'fs1'vm");
+ break;
+ default:
+ UNSUPPORTED_RISCV();
+ break;
+ }
+}
+
+void Decoder::DecodeVType(Instruction* instr) {
+ switch (instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask)) {
+ case OP_IVV:
+ DecodeRvvIVV(instr);
+ return;
+ case OP_FVV:
+ DecodeRvvFVV(instr);
+ return;
+ case OP_MVV:
+ DecodeRvvMVV(instr);
+ return;
+ case OP_IVI:
+ DecodeRvvIVI(instr);
+ return;
+ case OP_IVX:
+ DecodeRvvIVX(instr);
+ return;
+ case OP_FVF:
+ UNSUPPORTED_RISCV();
+ return;
+ case OP_MVX:
+ DecodeRvvMVX(instr);
+ return;
+ }
+ switch (instr->InstructionBits() &
+ (kBaseOpcodeMask | kFunct3Mask | 0x80000000)) {
+ case RO_V_VSETVLI:
+ Format(instr, "vsetvli 'rd, 'rs1, 'sew, 'lmul");
+ break;
+ case RO_V_VSETVL:
+ if (!(instr->InstructionBits() & 0x40000000)) {
+ Format(instr, "vsetvl 'rd, 'rs1, 'rs2");
+ } else {
+ Format(instr, "vsetivli 'rd, 'uimm, 'sew, 'lmul");
+ }
+ break;
+ default:
+ UNSUPPORTED_RISCV();
+ break;
+ }
+}
+int Decoder::switch_nf(Instruction* instr) {
+ int nf = 0;
+ switch (instr->InstructionBits() & kRvvNfMask) {
+ case 0x20000000:
+ nf = 2;
+ break;
+ case 0x40000000:
+ nf = 3;
+ break;
+ case 0x60000000:
+ nf = 4;
+ break;
+ case 0x80000000:
+ nf = 5;
+ break;
+ case 0xa0000000:
+ nf = 6;
+ break;
+ case 0xc0000000:
+ nf = 7;
+ break;
+ case 0xe0000000:
+ nf = 8;
+ break;
+ }
+ return nf;
+}
+void Decoder::DecodeRvvVL(Instruction* instr) {
+ char str[50];
+ uint32_t instr_temp =
+ instr->InstructionBits() & (kRvvMopMask | kRvvNfMask | kBaseOpcodeMask);
+ // switch (instr->InstructionBits() &
+ // (kRvvMopMask | kRvvNfMask | kBaseOpcodeMask)) {
+ if (RO_V_VL == instr_temp) {
+ if (!(instr->InstructionBits() & (kRvvRs2Mask))) {
+ snprintf(str, sizeof(str), "vle%d.v 'vd, ('rs1)'vm",
+ instr->vl_vs_width());
+ Format(instr, str);
+ } else {
+ snprintf(str, sizeof(str), "vle%dff.v 'vd, ('rs1)'vm",
+ instr->vl_vs_width());
+ Format(instr, str);
+ }
+ } else if (RO_V_VLS == instr_temp) {
+ snprintf(str, sizeof(str), "vlse%d.v 'vd, ('rs1), 'rs2'vm",
+ instr->vl_vs_width());
+ Format(instr, str);
+
+ } else if (RO_V_VLX == instr_temp) {
+ snprintf(str, sizeof(str), "vlxei%d.v 'vd, ('rs1), 'vs2'vm",
+ instr->vl_vs_width());
+ Format(instr, str);
+ } else if (RO_V_VLSEG2 == instr_temp || RO_V_VLSEG3 == instr_temp ||
+ RO_V_VLSEG4 == instr_temp || RO_V_VLSEG5 == instr_temp ||
+ RO_V_VLSEG6 == instr_temp || RO_V_VLSEG7 == instr_temp ||
+ RO_V_VLSEG8 == instr_temp) {
+ if (!(instr->InstructionBits() & (kRvvRs2Mask))) {
+ snprintf(str, sizeof(str), "vlseg%de%d.v 'vd, ('rs1)'vm",
+ switch_nf(instr), instr->vl_vs_width());
+ } else {
+ snprintf(str, sizeof(str), "vlseg%de%dff.v 'vd, ('rs1)'vm",
+ switch_nf(instr), instr->vl_vs_width());
+ }
+ Format(instr, str);
+ } else if (RO_V_VLSSEG2 == instr_temp || RO_V_VLSSEG3 == instr_temp ||
+ RO_V_VLSSEG4 == instr_temp || RO_V_VLSSEG5 == instr_temp ||
+ RO_V_VLSSEG6 == instr_temp || RO_V_VLSSEG7 == instr_temp ||
+ RO_V_VLSSEG8 == instr_temp) {
+ snprintf(str, sizeof(str), "vlsseg%de%d.v 'vd, ('rs1), 'rs2'vm",
+ switch_nf(instr), instr->vl_vs_width());
+ Format(instr, str);
+ } else if (RO_V_VLXSEG2 == instr_temp || RO_V_VLXSEG3 == instr_temp ||
+ RO_V_VLXSEG4 == instr_temp || RO_V_VLXSEG5 == instr_temp ||
+ RO_V_VLXSEG6 == instr_temp || RO_V_VLXSEG7 == instr_temp ||
+ RO_V_VLXSEG8 == instr_temp) {
+ snprintf(str, sizeof(str), "vlxseg%dei%d.v 'vd, ('rs1), 'vs2'vm",
+ switch_nf(instr), instr->vl_vs_width());
+ Format(instr, str);
+ }
+}
+
+int Decoder::switch_sew(Instruction* instr) {
+ int width = 0;
+ if ((instr->InstructionBits() & kBaseOpcodeMask) != LOAD_FP &&
+ (instr->InstructionBits() & kBaseOpcodeMask) != STORE_FP)
+ return -1;
+ switch (instr->InstructionBits() & (kRvvWidthMask | kRvvMewMask)) {
+ case 0x0:
+ width = 8;
+ break;
+ case 0x00005000:
+ width = 16;
+ break;
+ case 0x00006000:
+ width = 32;
+ break;
+ case 0x00007000:
+ width = 64;
+ break;
+ case 0x10000000:
+ width = 128;
+ break;
+ case 0x10005000:
+ width = 256;
+ break;
+ case 0x10006000:
+ width = 512;
+ break;
+ case 0x10007000:
+ width = 1024;
+ break;
+ default:
+ width = -1;
+ break;
+ }
+ return width;
+}
+
+void Decoder::DecodeRvvVS(Instruction* instr) {
+ char str[50];
+ uint32_t instr_temp =
+ instr->InstructionBits() & (kRvvMopMask | kRvvNfMask | kBaseOpcodeMask);
+ if (RO_V_VS == instr_temp) {
+ snprintf(str, sizeof(str), "vse%d.v 'vd, ('rs1)'vm",
+ instr->vl_vs_width());
+ Format(instr, str);
+ } else if (RO_V_VSS == instr_temp) {
+ snprintf(str, sizeof(str), "vsse%d.v 'vd, ('rs1), 'rs2'vm",
+ instr->vl_vs_width());
+ Format(instr, str);
+ } else if (RO_V_VSX == instr_temp) {
+ snprintf(str, sizeof(str), "vsxei%d.v 'vd, ('rs1), 'vs2'vm",
+ instr->vl_vs_width());
+ Format(instr, str);
+ } else if (RO_V_VSU == instr_temp) {
+ snprintf(str, sizeof(str), "vsuxei%d.v 'vd, ('rs1), 'vs2'vm",
+ instr->vl_vs_width());
+ Format(instr, str);
+ } else if (RO_V_VSSEG2 == instr_temp || RO_V_VSSEG3 == instr_temp ||
+ RO_V_VSSEG4 == instr_temp || RO_V_VSSEG5 == instr_temp ||
+ RO_V_VSSEG6 == instr_temp || RO_V_VSSEG7 == instr_temp ||
+ RO_V_VSSEG8 == instr_temp) {
+ snprintf(str, sizeof(str), "vsseg%de%d.v 'vd, ('rs1)'vm",
+ switch_nf(instr), instr->vl_vs_width());
+ Format(instr, str);
+ } else if (RO_V_VSSSEG2 == instr_temp || RO_V_VSSSEG3 == instr_temp ||
+ RO_V_VSSSEG4 == instr_temp || RO_V_VSSSEG5 == instr_temp ||
+ RO_V_VSSSEG6 == instr_temp || RO_V_VSSSEG7 == instr_temp ||
+ RO_V_VSSSEG8 == instr_temp) {
+ snprintf(str, sizeof(str), "vssseg%de%d.v 'vd, ('rs1), 'rs2'vm",
+ switch_nf(instr), instr->vl_vs_width());
+ Format(instr, str);
+ } else if (RO_V_VSXSEG2 == instr_temp || RO_V_VSXSEG3 == instr_temp ||
+ RO_V_VSXSEG4 == instr_temp || RO_V_VSXSEG5 == instr_temp ||
+ RO_V_VSXSEG6 == instr_temp || RO_V_VSXSEG7 == instr_temp ||
+ RO_V_VSXSEG8 == instr_temp) {
+ snprintf(str, sizeof(str), "vsxseg%dei%d.v 'vd, ('rs1), 'vs2'vm",
+ switch_nf(instr), instr->vl_vs_width());
+ Format(instr, str);
+ }
+}
+
// Disassemble the instruction at *instr_ptr into the output buffer.
// All instructions are one word long, except for the simulator
// pseudo-instruction stop(msg). For that one special case, we return
@@ -1849,6 +2588,9 @@ int Decoder::InstructionDecode(byte* instr_ptr) {
case Instruction::kCBType:
DecodeCBType(instr);
break;
+ case Instruction::kVType:
+ DecodeVType(instr);
+ break;
default:
Format(instr, "UNSUPPORTED");
UNSUPPORTED_RISCV();
@@ -1882,7 +2624,7 @@ const char* NameConverter::NameOfXMMRegister(int reg) const {
const char* NameConverter::NameOfByteCPURegister(int reg) const {
UNREACHABLE(); // RISC-V does not have the concept of a byte register.
- return "nobytereg";
+ // return "nobytereg";
}
const char* NameConverter::NameInCode(byte* addr) const {
diff --git a/chromium/v8/src/diagnostics/s390/eh-frame-s390.cc b/chromium/v8/src/diagnostics/s390/eh-frame-s390.cc
index 4f5994c8dab..6da3095e866 100644
--- a/chromium/v8/src/diagnostics/s390/eh-frame-s390.cc
+++ b/chromium/v8/src/diagnostics/s390/eh-frame-s390.cc
@@ -38,7 +38,6 @@ int EhFrameWriter::RegisterToDwarfCode(Register name) {
return kR0DwarfCode;
default:
UNIMPLEMENTED();
- return -1;
}
}
@@ -55,7 +54,6 @@ const char* EhFrameDisassembler::DwarfRegisterCodeToString(int code) {
return "sp";
default:
UNIMPLEMENTED();
- return nullptr;
}
}
diff --git a/chromium/v8/src/diagnostics/system-jit-win.cc b/chromium/v8/src/diagnostics/system-jit-win.cc
index c77c2231836..5ca36e67e6b 100644
--- a/chromium/v8/src/diagnostics/system-jit-win.cc
+++ b/chromium/v8/src/diagnostics/system-jit-win.cc
@@ -4,7 +4,11 @@
#include "src/diagnostics/system-jit-win.h"
-#include "include/v8.h"
+#include "include/v8-callbacks.h"
+#include "include/v8-isolate.h"
+#include "include/v8-local-handle.h"
+#include "include/v8-primitive.h"
+#include "include/v8-script.h"
#include "src/api/api-inl.h"
#include "src/base/lazy-instance.h"
#include "src/base/logging.h"
diff --git a/chromium/v8/src/diagnostics/unwinder.cc b/chromium/v8/src/diagnostics/unwinder.cc
index 68ff6795954..00a5e7dbe68 100644
--- a/chromium/v8/src/diagnostics/unwinder.cc
+++ b/chromium/v8/src/diagnostics/unwinder.cc
@@ -6,7 +6,7 @@
#include <algorithm>
-#include "include/v8.h"
+#include "include/v8-unwinder.h"
#include "src/execution/frame-constants.h"
#include "src/execution/pointer-authentication.h"
diff --git a/chromium/v8/src/diagnostics/unwinding-info-win64.h b/chromium/v8/src/diagnostics/unwinding-info-win64.h
index ca66437e00f..bb32f49e5d8 100644
--- a/chromium/v8/src/diagnostics/unwinding-info-win64.h
+++ b/chromium/v8/src/diagnostics/unwinding-info-win64.h
@@ -5,7 +5,9 @@
#ifndef V8_DIAGNOSTICS_UNWINDING_INFO_WIN64_H_
#define V8_DIAGNOSTICS_UNWINDING_INFO_WIN64_H_
-#include "include/v8.h"
+#include <vector>
+
+#include "include/v8-callbacks.h"
#include "include/v8config.h"
#include "src/common/globals.h"
diff --git a/chromium/v8/src/diagnostics/x64/disasm-x64.cc b/chromium/v8/src/diagnostics/x64/disasm-x64.cc
index 3ddb29e064b..469a6538dc0 100644
--- a/chromium/v8/src/diagnostics/x64/disasm-x64.cc
+++ b/chromium/v8/src/diagnostics/x64/disasm-x64.cc
@@ -244,8 +244,9 @@ static const InstructionDesc cmov_instructions[16] = {
{"cmovle", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
{"cmovg", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}};
-static const char* const cmp_pseudo_op[8] = {"eq", "lt", "le", "unord",
- "neq", "nlt", "nle", "ord"};
+static const char* const cmp_pseudo_op[16] = {
+ "eq", "lt", "le", "unord", "neq", "nlt", "nle", "ord",
+ "eq_uq", "nge", "ngt", "false", "neq_oq", "ge", "gt", "true"};
namespace {
int8_t Imm8(const uint8_t* data) {
@@ -279,6 +280,10 @@ int64_t Imm64(const uint8_t* data) {
//------------------------------------------------------------------------------
// DisassemblerX64 implementation.
+// Forward-declare NameOfYMMRegister to keep its implementation with the
+// NameConverter methods and register name arrays at bottom.
+const char* NameOfYMMRegister(int reg);
+
// A new DisassemblerX64 object is created to disassemble each instruction.
// The object can only disassemble a single instruction.
class DisassemblerX64 {
@@ -356,6 +361,12 @@ class DisassemblerX64 {
return (checked & 4) == 0;
}
+ bool vex_256() const {
+ DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX);
+ byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_;
+ return (checked & 4) != 0;
+ }
+
bool vex_none() {
DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX);
byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_;
@@ -424,6 +435,14 @@ class DisassemblerX64 {
return converter_.NameOfXMMRegister(reg);
}
+ const char* NameOfAVXRegister(int reg) const {
+ if (vex_256()) {
+ return NameOfYMMRegister(reg);
+ } else {
+ return converter_.NameOfXMMRegister(reg);
+ }
+ }
+
const char* NameOfAddress(byte* addr) const {
return converter_.NameOfAddress(addr);
}
@@ -448,6 +467,7 @@ class DisassemblerX64 {
int PrintRightOperand(byte* modrmp);
int PrintRightByteOperand(byte* modrmp);
int PrintRightXMMOperand(byte* modrmp);
+ int PrintRightAVXOperand(byte* modrmp);
int PrintOperands(const char* mnem, OperandType op_order, byte* data);
int PrintImmediate(byte* data, OperandSize size);
int PrintImmediateOp(byte* data);
@@ -606,6 +626,10 @@ int DisassemblerX64::PrintRightXMMOperand(byte* modrmp) {
return PrintRightOperandHelper(modrmp, &DisassemblerX64::NameOfXMMRegister);
}
+int DisassemblerX64::PrintRightAVXOperand(byte* modrmp) {
+ return PrintRightOperandHelper(modrmp, &DisassemblerX64::NameOfAVXRegister);
+}
+
// Returns number of bytes used including the current *data.
// Writes instruction's mnemonic, left and right operands to 'tmp_buffer_'.
int DisassemblerX64::PrintOperands(const char* mnem, OperandType op_order,
@@ -866,78 +890,98 @@ int DisassemblerX64::AVXInstruction(byte* data) {
get_modrm(*current, &mod, &regop, &rm);
switch (opcode) {
case 0x18:
- AppendToBuffer("vbroadcastss %s,", NameOfXMMRegister(regop));
+ AppendToBuffer("vbroadcastss %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
+ break;
+ case 0x98:
+ AppendToBuffer("vfmadd132p%c %s,%s,", float_size_code(),
+ NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
current += PrintRightXMMOperand(current);
break;
case 0x99:
AppendToBuffer("vfmadd132s%c %s,%s,", float_size_code(),
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
+ break;
+ case 0xA8:
+ AppendToBuffer("vfmadd213p%c %s,%s,", float_size_code(),
NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
current += PrintRightXMMOperand(current);
break;
case 0xA9:
AppendToBuffer("vfmadd213s%c %s,%s,", float_size_code(),
- NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0xB8:
AppendToBuffer("vfmadd231p%c %s,%s,", float_size_code(),
- NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0xB9:
AppendToBuffer("vfmadd231s%c %s,%s,", float_size_code(),
- NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0x9B:
AppendToBuffer("vfmsub132s%c %s,%s,", float_size_code(),
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
+ break;
+ case 0x9C:
+ AppendToBuffer("vfnmadd132p%c %s,%s,", float_size_code(),
NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
current += PrintRightXMMOperand(current);
break;
case 0xAB:
AppendToBuffer("vfmsub213s%c %s,%s,", float_size_code(),
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
+ break;
+ case 0xAC:
+ AppendToBuffer("vfnmadd213p%c %s,%s,", float_size_code(),
NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
current += PrintRightXMMOperand(current);
break;
case 0xBB:
AppendToBuffer("vfmsub231s%c %s,%s,", float_size_code(),
- NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0xBC:
AppendToBuffer("vfnmadd231p%c %s,%s,", float_size_code(),
- NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0x9D:
AppendToBuffer("vfnmadd132s%c %s,%s,", float_size_code(),
- NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0xAD:
AppendToBuffer("vfnmadd213s%c %s,%s,", float_size_code(),
- NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0xBD:
AppendToBuffer("vfnmadd231s%c %s,%s,", float_size_code(),
- NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0x9F:
AppendToBuffer("vfnmsub132s%c %s,%s,", float_size_code(),
- NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0xAF:
AppendToBuffer("vfnmsub213s%c %s,%s,", float_size_code(),
- NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0xBF:
AppendToBuffer("vfnmsub231s%c %s,%s,", float_size_code(),
- NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0xF7:
AppendToBuffer("shlx%c %s,", operand_size_code(),
@@ -948,9 +992,9 @@ int DisassemblerX64::AVXInstruction(byte* data) {
#define DECLARE_SSE_AVX_DIS_CASE(instruction, notUsed1, notUsed2, notUsed3, \
opcode) \
case 0x##opcode: { \
- AppendToBuffer("v" #instruction " %s,%s,", NameOfXMMRegister(regop), \
- NameOfXMMRegister(vvvv)); \
- current += PrintRightXMMOperand(current); \
+ AppendToBuffer("v" #instruction " %s,%s,", NameOfAVXRegister(regop), \
+ NameOfAVXRegister(vvvv)); \
+ current += PrintRightAVXOperand(current); \
break; \
}
@@ -962,8 +1006,8 @@ int DisassemblerX64::AVXInstruction(byte* data) {
#define DECLARE_SSE_UNOP_AVX_DIS_CASE(instruction, notUsed1, notUsed2, \
notUsed3, opcode) \
case 0x##opcode: { \
- AppendToBuffer("v" #instruction " %s,", NameOfXMMRegister(regop)); \
- current += PrintRightXMMOperand(current); \
+ AppendToBuffer("v" #instruction " %s,", NameOfAVXRegister(regop)); \
+ current += PrintRightAVXOperand(current); \
break; \
}
SSSE3_UNOP_INSTRUCTION_LIST(DECLARE_SSE_UNOP_AVX_DIS_CASE)
@@ -972,8 +1016,8 @@ int DisassemblerX64::AVXInstruction(byte* data) {
#define DISASSEMBLE_AVX2_BROADCAST(instruction, _1, _2, _3, code) \
case 0x##code: \
- AppendToBuffer("" #instruction " %s,", NameOfXMMRegister(regop)); \
- current += PrintRightXMMOperand(current); \
+ AppendToBuffer("" #instruction " %s,", NameOfAVXRegister(regop)); \
+ current += PrintRightAVXOperand(current); \
break;
AVX2_BROADCAST_LIST(DISASSEMBLE_AVX2_BROADCAST)
#undef DISASSEMBLE_AVX2_BROADCAST
@@ -986,96 +1030,96 @@ int DisassemblerX64::AVXInstruction(byte* data) {
get_modrm(*current, &mod, &regop, &rm);
switch (opcode) {
case 0x08:
- AppendToBuffer("vroundps %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vroundps %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
case 0x09:
- AppendToBuffer("vroundpd %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vroundpd %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
case 0x0A:
- AppendToBuffer("vroundss %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vroundss %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
case 0x0B:
- AppendToBuffer("vroundsd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vroundsd %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
case 0x0E:
- AppendToBuffer("vpblendw %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vpblendw %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
case 0x0F:
- AppendToBuffer("vpalignr %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vpalignr %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
case 0x14:
AppendToBuffer("vpextrb ");
current += PrintRightByteOperand(current);
- AppendToBuffer(",%s,0x%x,", NameOfXMMRegister(regop), *current++);
+ AppendToBuffer(",%s,0x%x,", NameOfAVXRegister(regop), *current++);
break;
case 0x15:
AppendToBuffer("vpextrw ");
current += PrintRightOperand(current);
- AppendToBuffer(",%s,0x%x,", NameOfXMMRegister(regop), *current++);
+ AppendToBuffer(",%s,0x%x,", NameOfAVXRegister(regop), *current++);
break;
case 0x16:
AppendToBuffer("vpextr%c ", rex_w() ? 'q' : 'd');
current += PrintRightOperand(current);
- AppendToBuffer(",%s,0x%x,", NameOfXMMRegister(regop), *current++);
+ AppendToBuffer(",%s,0x%x,", NameOfAVXRegister(regop), *current++);
break;
case 0x17:
AppendToBuffer("vextractps ");
current += PrintRightOperand(current);
- AppendToBuffer(",%s,0x%x,", NameOfXMMRegister(regop), *current++);
+ AppendToBuffer(",%s,0x%x,", NameOfAVXRegister(regop), *current++);
break;
case 0x20:
- AppendToBuffer("vpinsrb %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
+ AppendToBuffer("vpinsrb %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
current += PrintRightByteOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
case 0x21:
- AppendToBuffer("vinsertps %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vinsertps %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
case 0x22:
AppendToBuffer("vpinsr%c %s,%s,", rex_w() ? 'q' : 'd',
- NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
current += PrintRightOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
case 0x4A: {
- AppendToBuffer("vblendvps %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- AppendToBuffer(",%s", NameOfXMMRegister((*current++) >> 4));
+ AppendToBuffer("vblendvps %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
+ AppendToBuffer(",%s", NameOfAVXRegister((*current++) >> 4));
break;
}
case 0x4B: {
- AppendToBuffer("vblendvpd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- AppendToBuffer(",%s", NameOfXMMRegister((*current++) >> 4));
+ AppendToBuffer("vblendvpd %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
+ AppendToBuffer(",%s", NameOfAVXRegister((*current++) >> 4));
break;
}
case 0x4C: {
- AppendToBuffer("vpblendvb %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- AppendToBuffer(",%s", NameOfXMMRegister((*current++) >> 4));
+ AppendToBuffer("vpblendvb %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
+ AppendToBuffer(",%s", NameOfAVXRegister((*current++) >> 4));
break;
}
default:
@@ -1086,95 +1130,95 @@ int DisassemblerX64::AVXInstruction(byte* data) {
get_modrm(*current, &mod, &regop, &rm);
switch (opcode) {
case 0x10:
- AppendToBuffer("vmovss %s,", NameOfXMMRegister(regop));
+ AppendToBuffer("vmovss %s,", NameOfAVXRegister(regop));
if (mod == 3) {
- AppendToBuffer("%s,", NameOfXMMRegister(vvvv));
+ AppendToBuffer("%s,", NameOfAVXRegister(vvvv));
}
- current += PrintRightXMMOperand(current);
+ current += PrintRightAVXOperand(current);
break;
case 0x11:
AppendToBuffer("vmovss ");
- current += PrintRightXMMOperand(current);
+ current += PrintRightAVXOperand(current);
if (mod == 3) {
- AppendToBuffer(",%s", NameOfXMMRegister(vvvv));
+ AppendToBuffer(",%s", NameOfAVXRegister(vvvv));
}
- AppendToBuffer(",%s", NameOfXMMRegister(regop));
+ AppendToBuffer(",%s", NameOfAVXRegister(regop));
break;
case 0x16:
- AppendToBuffer("vmovshdup %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vmovshdup %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
break;
case 0x2A:
AppendToBuffer("%s %s,%s,", vex_w() ? "vcvtqsi2ss" : "vcvtlsi2ss",
- NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
current += PrintRightOperand(current);
break;
case 0x2C:
AppendToBuffer("vcvttss2si%s %s,", vex_w() ? "q" : "",
NameOfCPURegister(regop));
- current += PrintRightXMMOperand(current);
+ current += PrintRightAVXOperand(current);
break;
case 0x51:
- AppendToBuffer("vsqrtss %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vsqrtss %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0x58:
- AppendToBuffer("vaddss %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vaddss %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0x59:
- AppendToBuffer("vmulss %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vmulss %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0x5A:
- AppendToBuffer("vcvtss2sd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vcvtss2sd %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0x5B:
- AppendToBuffer("vcvttps2dq %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vcvttps2dq %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
break;
case 0x5C:
- AppendToBuffer("vsubss %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vsubss %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0x5D:
- AppendToBuffer("vminss %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vminss %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0x5E:
- AppendToBuffer("vdivss %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vdivss %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0x5F:
- AppendToBuffer("vmaxss %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vmaxss %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
break;
case 0x6F:
- AppendToBuffer("vmovdqu %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vmovdqu %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
break;
case 0x70:
- AppendToBuffer("vpshufhw %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vpshufhw %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
case 0x7F:
AppendToBuffer("vmovdqu ");
- current += PrintRightXMMOperand(current);
- AppendToBuffer(",%s", NameOfXMMRegister(regop));
+ current += PrintRightAVXOperand(current);
+ AppendToBuffer(",%s", NameOfAVXRegister(regop));
break;
case 0xE6:
- AppendToBuffer("vcvtdq2pd %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vcvtdq2pd %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
break;
default:
UnimplementedInstruction();
@@ -1184,93 +1228,61 @@ int DisassemblerX64::AVXInstruction(byte* data) {
get_modrm(*current, &mod, &regop, &rm);
switch (opcode) {
case 0x10:
- AppendToBuffer("vmovsd %s,", NameOfXMMRegister(regop));
+ AppendToBuffer("vmovsd %s,", NameOfAVXRegister(regop));
if (mod == 3) {
- AppendToBuffer("%s,", NameOfXMMRegister(vvvv));
+ AppendToBuffer("%s,", NameOfAVXRegister(vvvv));
}
- current += PrintRightXMMOperand(current);
+ current += PrintRightAVXOperand(current);
break;
case 0x11:
AppendToBuffer("vmovsd ");
- current += PrintRightXMMOperand(current);
+ current += PrintRightAVXOperand(current);
if (mod == 3) {
- AppendToBuffer(",%s", NameOfXMMRegister(vvvv));
+ AppendToBuffer(",%s", NameOfAVXRegister(vvvv));
}
- AppendToBuffer(",%s", NameOfXMMRegister(regop));
+ AppendToBuffer(",%s", NameOfAVXRegister(regop));
break;
case 0x12:
- AppendToBuffer("vmovddup %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vmovddup %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
break;
case 0x2A:
AppendToBuffer("%s %s,%s,", vex_w() ? "vcvtqsi2sd" : "vcvtlsi2sd",
- NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+ NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
current += PrintRightOperand(current);
break;
case 0x2C:
AppendToBuffer("vcvttsd2si%s %s,", vex_w() ? "q" : "",
NameOfCPURegister(regop));
- current += PrintRightXMMOperand(current);
+ current += PrintRightAVXOperand(current);
break;
case 0x2D:
AppendToBuffer("vcvtsd2si%s %s,", vex_w() ? "q" : "",
NameOfCPURegister(regop));
- current += PrintRightXMMOperand(current);
- break;
- case 0x51:
- AppendToBuffer("vsqrtsd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- break;
- case 0x58:
- AppendToBuffer("vaddsd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- break;
- case 0x59:
- AppendToBuffer("vmulsd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- break;
- case 0x5A:
- AppendToBuffer("vcvtsd2ss %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- break;
- case 0x5C:
- AppendToBuffer("vsubsd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- break;
- case 0x5D:
- AppendToBuffer("vminsd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- break;
- case 0x5E:
- AppendToBuffer("vdivsd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- break;
- case 0x5F:
- AppendToBuffer("vmaxsd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ current += PrintRightAVXOperand(current);
break;
case 0xF0:
- AppendToBuffer("vlddqu %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vlddqu %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
break;
case 0x70:
- AppendToBuffer("vpshuflw %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vpshuflw %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
case 0x7C:
- AppendToBuffer("vhaddps %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
- break;
+ AppendToBuffer("vhaddps %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
+ break;
+#define DISASM_SSE2_INSTRUCTION_LIST_SD(instruction, _1, _2, opcode) \
+ case 0x##opcode: \
+ AppendToBuffer("v" #instruction " %s,%s,", NameOfAVXRegister(regop), \
+ NameOfAVXRegister(vvvv)); \
+ current += PrintRightAVXOperand(current); \
+ break;
+ SSE2_INSTRUCTION_LIST_SD(DISASM_SSE2_INSTRUCTION_LIST_SD)
+#undef DISASM_SSE2_INSTRUCTION_LIST_SD
default:
UnimplementedInstruction();
}
@@ -1387,90 +1399,90 @@ int DisassemblerX64::AVXInstruction(byte* data) {
get_modrm(*current, &mod, &regop, &rm);
switch (opcode) {
case 0x10:
- AppendToBuffer("vmovups %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vmovups %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
break;
case 0x11:
AppendToBuffer("vmovups ");
- current += PrintRightXMMOperand(current);
- AppendToBuffer(",%s", NameOfXMMRegister(regop));
+ current += PrintRightAVXOperand(current);
+ AppendToBuffer(",%s", NameOfAVXRegister(regop));
break;
case 0x12:
if (mod == 0b11) {
- AppendToBuffer("vmovhlps %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vmovhlps %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
} else {
- AppendToBuffer("vmovlps %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vmovlps %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
}
break;
case 0x13:
AppendToBuffer("vmovlps ");
- current += PrintRightXMMOperand(current);
- AppendToBuffer(",%s", NameOfXMMRegister(regop));
+ current += PrintRightAVXOperand(current);
+ AppendToBuffer(",%s", NameOfAVXRegister(regop));
break;
case 0x16:
if (mod == 0b11) {
- AppendToBuffer("vmovlhps %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vmovlhps %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
} else {
- AppendToBuffer("vmovhps %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vmovhps %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
}
break;
case 0x17:
AppendToBuffer("vmovhps ");
- current += PrintRightXMMOperand(current);
- AppendToBuffer(",%s", NameOfXMMRegister(regop));
+ current += PrintRightAVXOperand(current);
+ AppendToBuffer(",%s", NameOfAVXRegister(regop));
break;
case 0x28:
- AppendToBuffer("vmovaps %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vmovaps %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
break;
case 0x29:
AppendToBuffer("vmovaps ");
- current += PrintRightXMMOperand(current);
- AppendToBuffer(",%s", NameOfXMMRegister(regop));
+ current += PrintRightAVXOperand(current);
+ AppendToBuffer(",%s", NameOfAVXRegister(regop));
break;
case 0x2E:
- AppendToBuffer("vucomiss %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vucomiss %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
break;
case 0x50:
AppendToBuffer("vmovmskps %s,", NameOfCPURegister(regop));
- current += PrintRightXMMOperand(current);
+ current += PrintRightAVXOperand(current);
break;
case 0xC2: {
- AppendToBuffer("vcmpps %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vcmpps %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(", (%s)", cmp_pseudo_op[*current]);
current += 1;
break;
}
case 0xC6: {
- AppendToBuffer("vshufps %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vshufps %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
}
#define SSE_UNOP_CASE(instruction, unused, code) \
case 0x##code: \
- AppendToBuffer("v" #instruction " %s,", NameOfXMMRegister(regop)); \
- current += PrintRightXMMOperand(current); \
+ AppendToBuffer("v" #instruction " %s,", NameOfAVXRegister(regop)); \
+ current += PrintRightAVXOperand(current); \
break;
SSE_UNOP_INSTRUCTION_LIST(SSE_UNOP_CASE)
#undef SSE_UNOP_CASE
#define SSE_BINOP_CASE(instruction, unused, code) \
case 0x##code: \
- AppendToBuffer("v" #instruction " %s,%s,", NameOfXMMRegister(regop), \
- NameOfXMMRegister(vvvv)); \
- current += PrintRightXMMOperand(current); \
+ AppendToBuffer("v" #instruction " %s,%s,", NameOfAVXRegister(regop), \
+ NameOfAVXRegister(vvvv)); \
+ current += PrintRightAVXOperand(current); \
break;
SSE_BINOP_INSTRUCTION_LIST(SSE_BINOP_CASE)
#undef SSE_BINOP_CASE
@@ -1482,92 +1494,92 @@ int DisassemblerX64::AVXInstruction(byte* data) {
get_modrm(*current, &mod, &regop, &rm);
switch (opcode) {
case 0x10:
- AppendToBuffer("vmovupd %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vmovupd %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
break;
case 0x11:
AppendToBuffer("vmovupd ");
- current += PrintRightXMMOperand(current);
- AppendToBuffer(",%s", NameOfXMMRegister(regop));
+ current += PrintRightAVXOperand(current);
+ AppendToBuffer(",%s", NameOfAVXRegister(regop));
break;
case 0x28:
- AppendToBuffer("vmovapd %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vmovapd %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
break;
case 0x29:
AppendToBuffer("vmovapd ");
- current += PrintRightXMMOperand(current);
- AppendToBuffer(",%s", NameOfXMMRegister(regop));
+ current += PrintRightAVXOperand(current);
+ AppendToBuffer(",%s", NameOfAVXRegister(regop));
break;
case 0x50:
AppendToBuffer("vmovmskpd %s,", NameOfCPURegister(regop));
- current += PrintRightXMMOperand(current);
+ current += PrintRightAVXOperand(current);
break;
case 0x6E:
AppendToBuffer("vmov%c %s,", vex_w() ? 'q' : 'd',
- NameOfXMMRegister(regop));
+ NameOfAVXRegister(regop));
current += PrintRightOperand(current);
break;
case 0x6F:
- AppendToBuffer("vmovdqa %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vmovdqa %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
break;
case 0x70:
- AppendToBuffer("vpshufd %s,", NameOfXMMRegister(regop));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vpshufd %s,", NameOfAVXRegister(regop));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
case 0x71:
AppendToBuffer("vps%sw %s,", sf_str[regop / 2],
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(",%u", *current++);
break;
case 0x72:
AppendToBuffer("vps%sd %s,", sf_str[regop / 2],
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(",%u", *current++);
break;
case 0x73:
AppendToBuffer("vps%sq %s,", sf_str[regop / 2],
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(",%u", *current++);
break;
case 0x7E:
AppendToBuffer("vmov%c ", vex_w() ? 'q' : 'd');
current += PrintRightOperand(current);
- AppendToBuffer(",%s", NameOfXMMRegister(regop));
+ AppendToBuffer(",%s", NameOfAVXRegister(regop));
break;
case 0xC2: {
- AppendToBuffer("vcmppd %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
- current += PrintRightXMMOperand(current);
+ AppendToBuffer("vcmppd %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
AppendToBuffer(", (%s)", cmp_pseudo_op[*current]);
current += 1;
break;
}
case 0xC4:
- AppendToBuffer("vpinsrw %s,%s,", NameOfXMMRegister(regop),
- NameOfXMMRegister(vvvv));
+ AppendToBuffer("vpinsrw %s,%s,", NameOfAVXRegister(regop),
+ NameOfAVXRegister(vvvv));
current += PrintRightOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
case 0xC5:
AppendToBuffer("vpextrw %s,", NameOfCPURegister(regop));
- current += PrintRightXMMOperand(current);
+ current += PrintRightAVXOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
case 0xD7:
AppendToBuffer("vpmovmskb %s,", NameOfCPURegister(regop));
- current += PrintRightXMMOperand(current);
+ current += PrintRightAVXOperand(current);
break;
#define DECLARE_SSE_AVX_DIS_CASE(instruction, notUsed1, notUsed2, opcode) \
case 0x##opcode: { \
- AppendToBuffer("v" #instruction " %s,%s,", NameOfXMMRegister(regop), \
- NameOfXMMRegister(vvvv)); \
- current += PrintRightXMMOperand(current); \
+ AppendToBuffer("v" #instruction " %s,%s,", NameOfAVXRegister(regop), \
+ NameOfAVXRegister(vvvv)); \
+ current += PrintRightAVXOperand(current); \
break; \
}
@@ -1575,8 +1587,8 @@ int DisassemblerX64::AVXInstruction(byte* data) {
#undef DECLARE_SSE_AVX_DIS_CASE
#define DECLARE_SSE_UNOP_AVX_DIS_CASE(instruction, notUsed1, notUsed2, opcode) \
case 0x##opcode: { \
- AppendToBuffer("v" #instruction " %s,", NameOfXMMRegister(regop)); \
- current += PrintRightXMMOperand(current); \
+ AppendToBuffer("v" #instruction " %s,", NameOfAVXRegister(regop)); \
+ current += PrintRightAVXOperand(current); \
break; \
}
@@ -2799,9 +2811,9 @@ int DisassemblerX64::InstructionDecode(v8::base::Vector<char> out_buffer,
for (byte* bp = instr; bp < data; bp++) {
outp += v8::base::SNPrintF(out_buffer + outp, "%02x", *bp);
}
- // Indent instruction, leaving space for 9 bytes, i.e. 18 characters in hex.
- // 9-byte nop and rip-relative mov are (probably) the largest we emit.
- while (outp < 18) {
+ // Indent instruction, leaving space for 10 bytes, i.e. 20 characters in hex.
+ // 10-byte mov is (probably) the largest we emit.
+ while (outp < 20) {
outp += v8::base::SNPrintF(out_buffer + outp, " ");
}
@@ -2823,6 +2835,10 @@ static const char* const xmm_regs[16] = {
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"};
+static const char* const ymm_regs[16] = {
+ "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",
+ "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15"};
+
const char* NameConverter::NameOfAddress(byte* addr) const {
v8::base::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr));
return tmp_buffer_.begin();
@@ -2847,6 +2863,11 @@ const char* NameConverter::NameOfXMMRegister(int reg) const {
return "noxmmreg";
}
+const char* NameOfYMMRegister(int reg) {
+ if (0 <= reg && reg < 16) return ymm_regs[reg];
+ return "noymmreg";
+}
+
const char* NameConverter::NameInCode(byte* addr) const {
// X64 does not embed debug strings at the moment.
UNREACHABLE();