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

Unified Diff: runtime/vm/disassembler_arm64.cc

Issue 261783005: Begins work on arm64 floating point instructions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/constants_arm64.h ('k') | runtime/vm/parser_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/disassembler_arm64.cc
===================================================================
--- runtime/vm/disassembler_arm64.cc (revision 35658)
+++ runtime/vm/disassembler_arm64.cc (working copy)
@@ -31,6 +31,7 @@
// Printing of common values.
void PrintRegister(int reg, R31Type r31t);
+ void PrintVRegister(int reg);
void PrintShiftExtendRm(Instr* instr);
void PrintMemOperand(Instr* instr);
void PrintS(Instr* instr);
@@ -38,6 +39,7 @@
// Handle formatting of instructions and their options.
int FormatRegister(Instr* instr, const char* option);
+ int FormatVRegister(Instr*instr, const char* option);
int FormatOption(Instr* instr, const char* format);
void Format(Instr* instr, const char* format);
void Unknown(Instr* instr);
@@ -103,6 +105,15 @@
}
+void ARM64Decoder::PrintVRegister(int reg) {
+ ASSERT(0 <= reg);
+ ASSERT(reg < kNumberOfVRegisters);
+ buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
+ remaining_size_in_buffer(),
+ "v%d", reg);
+}
+
+
// These shift names are defined in a way to match the native disassembler
// formatting. See for example the command "objdump -d <binary file>".
static const char* shift_names[kMaxShift] = {
@@ -291,6 +302,22 @@
}
+int ARM64Decoder::FormatVRegister(Instr* instr, const char* format) {
+ ASSERT(format[0] == 'v');
+ if (format[1] == 'd') {
+ int reg = instr->VdField();
+ PrintVRegister(reg);
+ return 2;
+ } else if (format[1] == 'n') {
+ int reg = instr->VnField();
+ PrintVRegister(reg);
+ return 2;
+ }
+ UNREACHABLE();
+ return -1;
+}
+
+
// 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
@@ -363,30 +390,41 @@
}
return 2;
}
- case 'i': { // 'imm12, imm16
- uint64_t imm;
- int ret = 5;
- if (format[4] == '2') {
- ASSERT(STRING_STARTS_WITH(format, "imm12"));
- imm = instr->Imm12Field();
- if (format[5] == 's') {
- // shifted immediate.
- if (instr->Imm12ShiftField() == 1) {
- imm = imm << 12;
- } else if ((instr->Imm12ShiftField() & 0x2) != 0) {
- Print("Unknown Shift");
+ case 'i': { // 'imm12, 'imm16, 'immd
+ if (format[3] == '1') {
+ uint64_t imm;
+ int ret = 5;
+ if (format[4] == '2') {
+ ASSERT(STRING_STARTS_WITH(format, "imm12"));
+ imm = instr->Imm12Field();
+ if (format[5] == 's') {
+ // shifted immediate.
+ if (instr->Imm12ShiftField() == 1) {
+ imm = imm << 12;
+ } else if ((instr->Imm12ShiftField() & 0x2) != 0) {
+ Print("Unknown Shift");
+ }
+ ret = 6;
}
- ret = 6;
+ } else {
+ ASSERT(STRING_STARTS_WITH(format, "imm16"));
+ imm = instr->Imm16Field();
}
+ buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
+ remaining_size_in_buffer(),
+ "0x%"Px64,
+ imm);
+ return ret;
} else {
- ASSERT(STRING_STARTS_WITH(format, "imm16"));
- imm = instr->Imm16Field();
+ ASSERT(STRING_STARTS_WITH(format, "immd"));
+ double dimm = bit_cast<double, int64_t>(
+ Instr::VFPExpandImm(instr->Imm8Field()));
+ buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
+ remaining_size_in_buffer(),
+ "%f",
+ dimm);
+ return 4;
}
- buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
- remaining_size_in_buffer(),
- "0x%"Px64,
- imm);
- return ret;
}
case 'm': {
ASSERT(STRING_STARTS_WITH(format, "memop"));
@@ -420,6 +458,9 @@
case 'r': {
return FormatRegister(instr, format);
}
+ case 'v': {
+ return FormatVRegister(instr, format);
+ }
case 's': { // 's: S flag.
if (format[1] == 'h') {
ASSERT(STRING_STARTS_WITH(format, "shift_op"));
@@ -879,8 +920,55 @@
}
+void ARM64Decoder::DecodeFPImm(Instr* instr) {
+ if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || (instr->Bit(23) != 0) ||
+ (instr->Bits(5, 5) != 0)) {
+ Unknown(instr);
+ return;
+ }
+ if (instr->Bit(22) == 1) {
+ // Double.
+ Format(instr, "fmovd 'vd, 'immd");
+ } else {
+ // Single.
+ Unknown(instr);
+ }
+}
+
+
+void ARM64Decoder::DecodeFPIntCvt(Instr* instr) {
+ if ((instr->SFField() != 1) || (instr->Bit(29) != 0) ||
+ (instr->Bits(22, 2) != 1)) {
+ Unknown(instr);
+ return;
+ }
+ if (instr->Bits(16, 3) == 6) {
+ Format(instr, "fmovrd 'rd, 'vn");
+ } else if (instr->Bits(16, 3) == 7) {
+ Format(instr, "fmovdr 'vd, 'rn");
+ } else {
+ Unknown(instr);
+ }
+}
+
+
+void ARM64Decoder::DecodeFP(Instr* instr) {
+ if (instr->IsFPImmOp()) {
+ DecodeFPImm(instr);
+ } else if (instr->IsFPIntCvtOp()) {
+ DecodeFPIntCvt(instr);
+ } else {
+ Unknown(instr);
+ }
+}
+
+
void ARM64Decoder::DecodeDPSimd2(Instr* instr) {
- Unknown(instr);
+ if (instr->IsFPOp()) {
+ DecodeFP(instr);
+ } else {
+ Unknown(instr);
+ }
}
« no previous file with comments | « runtime/vm/constants_arm64.h ('k') | runtime/vm/parser_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698