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

Unified Diff: runtime/vm/disassembler_arm.cc

Issue 18684008: Begins implementation of ARM neon instructions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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
Index: runtime/vm/disassembler_arm.cc
===================================================================
--- runtime/vm/disassembler_arm.cc (revision 24980)
+++ runtime/vm/disassembler_arm.cc (working copy)
@@ -33,6 +33,7 @@
void PrintRegister(int reg);
void PrintSRegister(int reg);
void PrintDRegister(int reg);
+ void PrintQRegister(int reg);
void PrintCondition(Instr* instr);
void PrintShiftRm(Instr* instr);
void PrintShiftImm(Instr* instr);
@@ -42,6 +43,7 @@
int FormatRegister(Instr* instr, const char* option);
int FormatSRegister(Instr* instr, const char* option);
int FormatDRegister(Instr* instr, const char* option);
+ int FormatQRegister(Instr* instr, const char* option);
int FormatOption(Instr* instr, const char* option);
void Format(Instr* instr, const char* format);
void Unknown(Instr* instr);
@@ -57,6 +59,7 @@
void DecodeType5(Instr* instr);
void DecodeType6(Instr* instr);
void DecodeType7(Instr* instr);
+ void DecodeSIMDDataProcessing(Instr* instr);
// Convenience functions.
char* get_buffer() const { return buffer_; }
@@ -137,6 +140,15 @@
}
+void ARMDecoder::PrintQRegister(int reg) {
+ ASSERT(0 <= reg);
+ ASSERT(reg < kNumberOfQRegisters);
+ buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
+ remaining_size_in_buffer(),
+ "q%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] = {
@@ -351,6 +363,26 @@
}
+int ARMDecoder::FormatQRegister(Instr* instr, const char* format) {
+ ASSERT(format[0] == 'q');
+ if (format[1] == 'n') { // 'qn: Qn register
+ int reg = instr->QnField();
+ PrintQRegister(reg);
+ return 2;
+ } else if (format[1] == 'd') { // 'qd: Qd register
+ int reg = instr->QdField();
+ PrintQRegister(reg);
+ return 2;
+ } else if (format[1] == 'm') { // 'qm: Qm register
+ int reg = instr->QmField();
+ PrintQRegister(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
@@ -391,6 +423,9 @@
return FormatDRegister(instr, format);
}
}
+ case 'q': {
+ return FormatQRegister(instr, format);
+ }
case 'i': { // 'imm12_4, imm4_12, immf, or immd
uint16_t immed16;
if (format[3] == 'f') {
@@ -446,7 +481,7 @@
"%d",
instr->Bits(0, 8) << 2);
} else {
- // 'off12: 12-bit offset for load and store instructions
+ // 'off12: 12-bit offset for load and store instructions.
ASSERT(STRING_STARTS_WITH(format, "off12"));
buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
remaining_size_in_buffer(),
@@ -455,7 +490,7 @@
}
return 5;
}
- // 'off8: 8-bit offset for extra load and store instructions
+ // 'off8: 8-bit offset for extra load and store instructions.
ASSERT(STRING_STARTS_WITH(format, "off8"));
int offs8 = (instr->ImmedHField() << 4) | instr->ImmedLField();
buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
@@ -464,7 +499,7 @@
offs8);
return 4;
}
- case 'p': { // 'pu: P and U bits for load and store instructions
+ case 'p': { // 'pu: P and U bits for load and store instructions.
ASSERT(STRING_STARTS_WITH(format, "pu"));
PrintPU(instr);
return 2;
@@ -495,8 +530,16 @@
"0x%x",
instr->SvcField());
return 3;
+ } else if (format[1] == 'z') {
+ // 'sz: Size field of SIMD instruction.
+ int sz = 8 << (instr->Bits(20, 2));
+ buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
+ remaining_size_in_buffer(),
+ "I%d",
+ sz);
+ return 2;
} else if (format[1] == ' ') {
- // 's: S field of data processing instructions
+ // 's: S field of data processing instructions.
if (instr->HasS()) {
Print("s");
}
@@ -505,7 +548,7 @@
return FormatSRegister(instr, format);
}
}
- case 't': { // 'target: target of branch instructions
+ case 't': { // 'target: target of branch instructions.
ASSERT(STRING_STARTS_WITH(format, "target"));
int off = (instr->SImmed24Field() << 2) + 8;
buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
@@ -514,7 +557,7 @@
off);
return 6;
}
- case 'u': { // 'u: signed or unsigned multiplies
+ case 'u': { // 'u: signed or unsigned multiplies.
if (instr->Bit(22) == 0) {
Print("u");
} else {
@@ -522,13 +565,13 @@
}
return 1;
}
- case 'w': { // 'w: W field of load and store instructions
+ case 'w': { // 'w: W field of load and store instructions.
if (instr->HasW()) {
Print("!");
}
return 1;
}
- case 'x': { // 'x: type of extra load/store instructions
+ case 'x': { // 'x: type of extra load/store instructions.
if (!instr->HasSign()) {
Print("h");
} else if (instr->HasL()) {
@@ -1223,6 +1266,24 @@
}
+void ARMDecoder::DecodeSIMDDataProcessing(Instr* instr) {
+ ASSERT(instr->ConditionField() == kSpecialCondition);
+ if (instr->Bit(6) == 1) {
+ if ((instr->Bits(8, 4) == 8) && (instr->Bit(4) == 0) &&
+ (instr->Bit(24) == 0)) {
+ Format(instr, "vadd.'sz 'qd, 'qn, 'qm");
+ } else if ((instr->Bits(8, 4) == 13) && (instr->Bit(4) == 0) &&
+ (instr->Bit(24) == 0)) {
+ Format(instr, "vadd.F32 'qd, 'qn, 'qm");
+ } else {
+ Unknown(instr);
+ }
+ } else {
+ Unknown(instr);
+ }
+}
+
+
void ARMDecoder::InstructionDecode(uword pc) {
Instr* instr = Instr::At(pc);
@@ -1230,7 +1291,11 @@
if (instr->InstructionBits() == static_cast<int32_t>(0xf57ff01f)) {
Format(instr, "clrex");
} else {
- Unknown(instr);
+ if (instr->IsSIMDDataProcessing()) {
+ DecodeSIMDDataProcessing(instr);
+ } else {
+ Unknown(instr);
+ }
}
} else {
switch (instr->TypeField()) {

Powered by Google App Engine
This is Rietveld 408576698