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

Unified Diff: src/arm/disasm-arm.cc

Issue 651029: Forking disassembler and simulator for Thumb2 support; (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/constants-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/disasm-arm.cc
===================================================================
--- src/arm/disasm-arm.cc (revision 4001)
+++ src/arm/disasm-arm.cc (working copy)
@@ -89,6 +89,8 @@
// Writes one disassembled instruction into 'buffer' (0-terminated).
// Returns the length of the disassembled machine instruction in bytes.
int InstructionDecode(byte* instruction);
+ int InstructionDecodeArm(byte* instruction);
+ int InstructionDecodeThumb2(const InstrThumb2& instr);
private:
// Bottleneck functions to print into the out_buffer.
@@ -103,15 +105,21 @@
int FormatVFPinstruction(Instr* instr, const char* format);
void PrintCondition(Instr* instr);
void PrintShiftRm(Instr* instr);
+ void PrintShiftRm(const InstrThumb2& instr);
void PrintShiftImm(Instr* instr);
+ void PrintShiftImm(const InstrThumb2& instr);
void PrintPU(Instr* instr);
void PrintSoftwareInterrupt(SoftwareInterruptCodes swi);
// Handle formatting of instructions and their options.
int FormatRegister(Instr* instr, const char* option);
+ int FormatRegister(const InstrThumb2& instr, const char* option);
int FormatOption(Instr* instr, const char* option);
+ int FormatOption(const InstrThumb2& instr, const char* option);
void Format(Instr* instr, const char* format);
+ void Format(const InstrThumb2& instr, const char* format);
void Unknown(Instr* instr);
+ void Unknown(const InstrThumb2& instr);
// Each of these functions decodes one particular instruction type, a 3-bit
// field in the instruction encoding.
@@ -230,7 +238,33 @@
}
}
+void Decoder::PrintShiftRm(const InstrThumb2& instr) {
+ int shift = instr.Type();
+ int shift_amount = instr.Imm();
+ int rm = instr.Rm();
+ PrintRegister(rm);
+
+ if (instr.Variant() != VARIANT_REGISTER_SHIFTED_REGISTER) {
+ if (shift == no_shift) {
+ // Special case for using rm only.
+ return;
+ }
+ if (shift == RRX) {
+ Print(", RRX");
+ return;
+ }
+ out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ ", %s #%d",
+ shift_names[shift], shift_amount);
+ } else {
+ // TODO(haustein)
+ UNIMPLEMENTED();
+ }
+}
+
+
+
// Print the immediate operand for the instruction. Generally used for data
// processing instructions.
void Decoder::PrintShiftImm(Instr* instr) {
@@ -241,7 +275,12 @@
"#%d", imm);
}
+void Decoder::PrintShiftImm(const InstrThumb2& instr) {
+ out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ "#%d", instr.Imm());
+}
+
// Print PU formatting to reduce complexity of FormatOption.
void Decoder::PrintPU(Instr* instr) {
switch (instr->PUField()) {
@@ -336,7 +375,40 @@
return -1;
}
+int Decoder::FormatRegister(const InstrThumb2& instr, const char* format) {
+ ASSERT(format[0] == 'r');
+ if (format[1] == 'n') { // 'rn: Rn register
+ int reg = instr.Rn();
+ PrintRegister(reg);
+ return 2;
+ } else if (format[1] == 'd') { // 'rd: Rd register
+ int reg = instr.Rd();
+ PrintRegister(reg);
+ return 2;
+ } else if (format[1] == 's') { // 'rs: Rs register
+ int reg = instr.Rs();
+ PrintRegister(reg);
+ return 2;
+ } else if (format[1] == 'm') { // 'rm: Rm register
+ int reg = instr.Rm();
+ PrintRegister(reg);
+ return 2;
+ } else if (format[1] == 't') { // 'rt: Rt register
+ int reg = instr.Rt();
+ PrintRegister(reg);
+ return 2;
+ } else if (format[1] == 'l') {
+ // 'rlist: register list for load and store multiple instructions
+ ASSERT(STRING_STARTS_WITH(format, "rlist"));
+ // TODO(haustein)
+ UNIMPLEMENTED();
+ return 5;
+ }
+ UNREACHABLE();
+ return -1;
+}
+
// Handle all VFP register based formatting in this function to reduce the
// complexity of FormatOption.
int Decoder::FormatVFPRegister(Instr* instr, const char* format) {
@@ -546,7 +618,48 @@
return -1;
}
+int Decoder::FormatOption(const InstrThumb2& instr, const char* format) {
+ switch (format[0]) {
+ // TODO(haustein) Add code for a, b, c, h, l, m, o, p, see ARM
+ case 'r': {
+ return FormatRegister(instr, format);
+ }
+ case 's': {
+ if (format[1] == 'h') { // 'shift_op or 'shift_rm
+ if (format[6] == 'o') { // 'shift_op
+ ASSERT(STRING_STARTS_WITH(format, "shift_op"));
+ if (instr.Type() == 0) {
+ PrintShiftRm(instr);
+ } else {
+ ASSERT(instr.Type() == 1);
+ PrintShiftImm(instr);
+ }
+ return 8;
+ } else { // 'shift_rm
+ ASSERT(STRING_STARTS_WITH(format, "shift_rm"));
+ PrintShiftRm(instr);
+ return 8;
+ }
+ // TODO(haustein) Add code for 'w', 'i', 's' here (see arm code)
+ }
+ // 's: S field of data processing instructions
+ if (instr.HasS()) {
+ Print("s");
+ }
+ return 1;
+ }
+ // TODO(haustein) Add code for 't', 'u', 'v', 'S', 'D', 'w' below,
+ // see arm code
+ default: {
+ UNIMPLEMENTED();
+ break;
+ }
+ }
+ UNREACHABLE();
+ return -1;
+}
+
// 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.
@@ -564,6 +677,21 @@
}
+void Decoder::Format(const InstrThumb2& 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(Instr* instr) {
@@ -1062,6 +1190,15 @@
// Disassemble the instruction at *instr_ptr into the output buffer.
int Decoder::InstructionDecode(byte* instr_ptr) {
+ if (reinterpret_cast<int32_t>(instr_ptr) & 1) {
+ InstrThumb2 instr(instr_ptr);
+ return InstructionDecodeThumb2(instr);
+ } else {
+ return InstructionDecodeArm(instr_ptr);
+ }
+}
+
+int Decoder::InstructionDecodeArm(byte* instr_ptr) {
Instr* instr = Instr::At(instr_ptr);
// Print raw instruction bytes.
out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
@@ -1111,6 +1248,25 @@
}
+int Decoder::InstructionDecodeThumb2(const InstrThumb2& instr) {
+ switch (instr.Op()) {
+ case OP_ADD:
+ Format(instr, "and's 'rd, 'rn, 'shift_op");
+ break;
+ case OP_AND:
+ Format(instr, "and's 'rd, 'rn, 'shift_op");
+ break;
+ case OP_SUB:
+ Format(instr, "sub's 'rd, 'rn, 'shift_op");
+ break;
+ default:
+ UNIMPLEMENTED();
+ break;
+ }
+ return instr.Size();
+}
+
+
} } // namespace assembler::arm
« no previous file with comments | « src/arm/constants-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698