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

Unified Diff: runtime/vm/disassembler_arm.cc

Issue 12431016: Copies Simulator Debugger from ARM to MIPS. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/disassembler_arm.cc
===================================================================
--- runtime/vm/disassembler_arm.cc (revision 19885)
+++ runtime/vm/disassembler_arm.cc (working copy)
@@ -22,7 +22,8 @@
~ARMDecoder() {}
// Writes one disassembled instruction into 'buffer' (0-terminated).
- void InstructionDecode(uword pc);
+ // Returns true if the instruction was successfully decoded, false otherwise.
+ bool InstructionDecode(uword pc);
private:
// Bottleneck functions to print into the out_buffer.
@@ -49,13 +50,13 @@
// field in the instruction encoding.
// Types 0 and 1 are combined as they are largely the same except for the way
// they interpret the shifter operand.
- void DecodeType01(Instr* instr);
- void DecodeType2(Instr* instr);
- void DecodeType3(Instr* instr);
- void DecodeType4(Instr* instr);
- void DecodeType5(Instr* instr);
- void DecodeType6(Instr* instr);
- void DecodeType7(Instr* instr);
+ bool DecodeType01(Instr* instr);
+ bool DecodeType2(Instr* instr);
+ bool DecodeType3(Instr* instr);
+ bool DecodeType4(Instr* instr);
+ bool DecodeType5(Instr* instr);
+ bool DecodeType6(Instr* instr);
+ bool DecodeType7(Instr* instr);
// Convenience functions.
char* get_buffer() const { return buffer_; }
@@ -575,7 +576,9 @@
}
-void ARMDecoder::DecodeType01(Instr* instr) {
+bool ARMDecoder::DecodeType01(Instr* instr) {
+ bool decoded = true;
+
if (!instr->IsDataProcessing()) {
// miscellaneous, multiply, sync primitives, extra loads and stores.
if (instr->IsMiscellaneous()) {
@@ -587,6 +590,7 @@
Format(instr, "bx'cond 'rm");
} else {
Unknown(instr);
+ decoded = false;
}
break;
}
@@ -596,6 +600,7 @@
} else {
// Could be inlined constant.
Unknown(instr);
+ decoded = false;
}
break;
}
@@ -605,11 +610,13 @@
} else {
// Format(instr, "smc'cond");
Unknown(instr); // Not used.
+ decoded = false;
}
break;
}
default: {
Unknown(instr); // Not used.
+ decoded = false;
break;
}
}
@@ -639,6 +646,7 @@
}
default: {
Unknown(instr); // Not used.
+ decoded = false;
break;
}
}
@@ -655,6 +663,7 @@
}
default: {
Unknown(instr); // Not used.
+ decoded = false;
break;
}
}
@@ -671,6 +680,7 @@
Format(instr, "nop'cond");
} else {
Unknown(instr); // Not used.
+ decoded = false;
}
break;
}
@@ -680,6 +690,7 @@
}
default: {
Unknown(instr); // Not used.
+ decoded = false;
break;
}
}
@@ -764,6 +775,7 @@
Format(instr, "tst'cond 'rn, 'shift_op");
} else {
Unknown(instr); // Not used.
+ decoded = false;
}
break;
}
@@ -772,6 +784,7 @@
Format(instr, "teq'cond 'rn, 'shift_op");
} else {
Unknown(instr); // Not used.
+ decoded = false;
}
break;
}
@@ -780,6 +793,7 @@
Format(instr, "cmp'cond 'rn, 'shift_op");
} else {
Unknown(instr); // Not used.
+ decoded = false;
}
break;
}
@@ -788,6 +802,7 @@
Format(instr, "cmn'cond 'rn, 'shift_op");
} else {
Unknown(instr); // Not used.
+ decoded = false;
}
break;
}
@@ -814,14 +829,19 @@
}
}
}
+
+ return decoded;
}
-void ARMDecoder::DecodeType2(Instr* instr) {
+bool ARMDecoder::DecodeType2(Instr* instr) {
+ bool decoded = true;
+
switch (instr->PUField()) {
case 0: {
if (instr->HasW()) {
Unknown(instr); // Not used.
+ decoded = false;
} else {
Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");
}
@@ -830,6 +850,7 @@
case 1: {
if (instr->HasW()) {
Unknown(instr); // Not used.
+ decoded = false;
} else {
Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12");
}
@@ -849,22 +870,27 @@
break;
}
}
+
+ return decoded;
}
-void ARMDecoder::DecodeType3(Instr* instr) {
+bool ARMDecoder::DecodeType3(Instr* instr) {
+ bool decoded = true;
+
if (instr->IsDivision()) {
if (instr->Bit(21)) {
Format(instr, "udiv'cond 'rd, 'rn, 'rm");
} else {
Format(instr, "sdiv'cond 'rd, 'rn, 'rm");
}
- return;
+ return decoded;
}
switch (instr->PUField()) {
case 0: {
if (instr->HasW()) {
Unknown(instr);
+ decoded = false;
} else {
Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
}
@@ -873,6 +899,7 @@
case 1: {
if (instr->HasW()) {
Unknown(instr);
+ decoded = false;
} else {
Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm");
}
@@ -892,26 +919,34 @@
break;
}
}
+
+ return decoded;
}
-void ARMDecoder::DecodeType4(Instr* instr) {
+bool ARMDecoder::DecodeType4(Instr* instr) {
+ bool decoded = true;
if (instr->Bit(22) == 1) {
Unknown(instr); // Privileged mode currently not supported.
+ decoded = false;
} else if (instr->HasL()) {
Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
} else {
Format(instr, "stm'cond'pu 'rn'w, 'rlist");
}
+ return decoded;
}
-void ARMDecoder::DecodeType5(Instr* instr) {
+bool ARMDecoder::DecodeType5(Instr* instr) {
Format(instr, "b'l'cond 'target ; 'dest");
+ return true;
}
-void ARMDecoder::DecodeType6(Instr* instr) {
+bool ARMDecoder::DecodeType6(Instr* instr) {
+ bool decoded = true;
+
if (instr->IsVFPDoubleTransfer()) {
if (instr->Bit(8) == 0) {
if (instr->Bit(20) == 1) {
@@ -972,11 +1007,16 @@
}
} else {
Unknown(instr);
+ decoded = false;
}
+
+ return decoded;
}
-void ARMDecoder::DecodeType7(Instr* instr) {
+bool ARMDecoder::DecodeType7(Instr* instr) {
+ bool decoded = true;
+
if (instr->Bit(24) == 1) {
Format(instr, "svc'cond #'svc");
if (instr->SvcField() == kStopMessageSvcCode) {
@@ -1010,6 +1050,7 @@
case 1: // vnmla, vnmls, vnmul
default: {
Unknown(instr);
+ decoded = false;
break;
}
case 2: { // vmul
@@ -1074,6 +1115,7 @@
}
default: {
Unknown(instr);
+ decoded = false;
break;
}
}
@@ -1099,6 +1141,7 @@
}
default: {
Unknown(instr);
+ decoded = false;
break;
}
}
@@ -1108,6 +1151,7 @@
case 5: { // vcmp #0.0, vcmpe #0.0
if (instr->Bit(7) == 1) { // vcmpe
Unknown(instr);
+ decoded = false;
} else {
if (instr->Bit(8) == 0) { // vcmps
if (instr->Bit(16) == 0) {
@@ -1154,6 +1198,7 @@
if (instr->Bit(7) == 0) {
// We only support round-to-zero mode
Unknown(instr);
+ decoded = false;
break;
}
if (instr->Bit(8) == 0) {
@@ -1180,6 +1225,7 @@
case 15: // vcvt between floating-point and fixed-point
default: {
Unknown(instr);
+ decoded = false;
break;
}
}
@@ -1199,53 +1245,60 @@
Format(instr, "vmstat'cond");
} else {
Unknown(instr);
+ decoded = false;
}
}
} else if (instr->IsMrcIdIsar0()) {
Format(instr, "mrc'cond p15, 0, 'rd, c0, c2, 0");
} else {
Unknown(instr);
+ decoded = false;
}
+
+ return decoded;
}
-void ARMDecoder::InstructionDecode(uword pc) {
-Instr* instr = Instr::At(pc);
+bool ARMDecoder::InstructionDecode(uword pc) {
+ bool decoded = true;
+ Instr* instr = Instr::At(pc);
+
if (instr->ConditionField() == kSpecialCondition) {
if (instr->InstructionBits() == static_cast<int32_t>(0xf57ff01f)) {
Format(instr, "clrex");
} else {
Unknown(instr);
+ decoded = false;
}
} else {
switch (instr->TypeField()) {
case 0:
case 1: {
- DecodeType01(instr);
+ decoded = DecodeType01(instr);
break;
}
case 2: {
- DecodeType2(instr);
+ decoded = DecodeType2(instr);
break;
}
case 3: {
- DecodeType3(instr);
+ decoded = DecodeType3(instr);
break;
}
case 4: {
- DecodeType4(instr);
+ decoded = DecodeType4(instr);
break;
}
case 5: {
- DecodeType5(instr);
+ decoded = DecodeType5(instr);
break;
}
case 6: {
- DecodeType6(instr);
+ decoded = DecodeType6(instr);
break;
}
case 7: {
- DecodeType7(instr);
+ decoded = DecodeType7(instr);
break;
}
default: {
@@ -1255,6 +1308,8 @@
}
}
}
+
+ return decoded;
}
@@ -1262,18 +1317,22 @@
char* human_buffer, intptr_t human_size,
uword pc) {
ARMDecoder decoder(human_buffer, human_size);
- decoder.InstructionDecode(pc);
- int32_t instruction_bits = Instr::At(pc)->InstructionBits();
- OS::SNPrint(hex_buffer, hex_size, "%08x", instruction_bits);
- return Instr::kInstrSize;
+ if (decoder.InstructionDecode(pc)) {
+ int32_t instruction_bits = Instr::At(pc)->InstructionBits();
+ OS::SNPrint(hex_buffer, hex_size, "%08x", instruction_bits);
+ return Instr::kInstrSize;
+ } else {
+ return -Instr::kInstrSize;
regis 2013/03/12 20:53:19 Did you mean to return 0? I am worried about retur
+ }
}
-void Disassembler::Disassemble(uword start,
+bool Disassembler::Disassemble(uword start,
uword end,
DisassemblyFormatter* formatter,
const Code::Comments& comments) {
ASSERT(formatter != NULL);
+ bool success = true;
char hex_buffer[kHexadecimalBufferSize]; // Instruction in hexadecimal form.
char human_buffer[kUserReadableBufferSize]; // Human-readable instruction.
uword pc = start;
@@ -1292,13 +1351,21 @@
human_buffer,
sizeof(human_buffer),
pc);
- formatter->ConsumeInstruction(hex_buffer,
- sizeof(hex_buffer),
- human_buffer,
- sizeof(human_buffer),
- pc);
- pc += instruction_length;
+ if (instruction_length > 0) {
+ formatter->ConsumeInstruction(hex_buffer,
+ sizeof(hex_buffer),
+ human_buffer,
+ sizeof(human_buffer),
+ pc);
+ pc += instruction_length;
+ } else {
+ ASSERT(instruction_length < 0);
+ success = false;
+ pc += (-instruction_length);
regis 2013/03/12 20:53:19 I see. You encode success/failure in the returned
+ }
}
+
+ return success;
}
} // namespace dart

Powered by Google App Engine
This is Rietveld 408576698