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

Unified Diff: runtime/vm/disassembler_mips.cc

Issue 14206002: Adds some floating point instructions to MIPS simulator, assembler, disassembler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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
Index: runtime/vm/disassembler_mips.cc
===================================================================
--- runtime/vm/disassembler_mips.cc (revision 21293)
+++ runtime/vm/disassembler_mips.cc (working copy)
@@ -31,8 +31,11 @@
// Printing of common values.
void PrintRegister(Register reg);
+ void PrintFRegister(FRegister reg);
+ void PrintFormat(Instr* instr);
int FormatRegister(Instr* instr, const char* format);
+ int FormatFRegister(Instr* instr, const char* format);
int FormatOption(Instr* instr, const char* format);
void Format(Instr* instr, const char* format);
void Unknown(Instr* instr);
@@ -40,6 +43,7 @@
void DecodeSpecial(Instr* instr);
void DecodeSpecial2(Instr* instr);
void DecodeRegImm(Instr* instr);
+ void DecodeCop1(Instr* instr);
// Convenience functions.
char* get_buffer() const { return buffer_; }
@@ -79,6 +83,14 @@
};
+static const char* freg_names[kNumberOfFRegisters] = {
+ "f0" , "f1" , "f2" , "f3" , "f4" , "f5" , "f6" , "f7" ,
+ "f8" , "f9" , "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+};
+
+
void MIPSDecoder::PrintRegister(Register reg) {
ASSERT(0 <= reg);
ASSERT(reg < kNumberOfCpuRegisters);
@@ -86,6 +98,13 @@
}
+void MIPSDecoder::PrintFRegister(FRegister reg) {
+ ASSERT(0 <= reg);
+ ASSERT(reg < kNumberOfFRegisters);
+ Print(freg_names[reg]);
+}
+
+
// Handle all register based formatting in these functions to reduce the
// complexity of FormatOption.
int MIPSDecoder::FormatRegister(Instr* instr, const char* format) {
@@ -109,6 +128,57 @@
}
+int MIPSDecoder::FormatFRegister(Instr* instr, const char* format) {
+ ASSERT(format[0] == 'f');
+ switch (format[1]) {
+ case 's': { // 'fs: Fs register
+ PrintFRegister(instr->FsField());
+ return 2;
+ }
+ case 't': { // 'ft: Ft register
+ PrintFRegister(instr->FtField());
+ return 2;
+ }
+ case 'd': { // 'fd: Fd register
+ PrintFRegister(instr->FdField());
+ return 2;
+ }
+ }
+ UNREACHABLE();
+ return -1;
+}
+
+
+void MIPSDecoder::PrintFormat(Instr *instr) {
+ switch (instr->FormatField()) {
+ case FMT_S: {
+ Print("s");
+ break;
+ }
+ case FMT_D: {
+ Print("d");
+ break;
+ }
+ case FMT_W: {
+ Print("w");
+ break;
+ }
+ case FMT_L: {
+ Print("l");
+ break;
+ }
+ case FMT_PS: {
+ Print("ps");
+ break;
+ }
+ default: {
+ Print("unknown");
+ break;
+ }
+ }
+}
+
+
// 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
@@ -170,6 +240,15 @@
case 'r': {
return FormatRegister(instr, format);
}
+ case 'f': {
+ if (format[1] == 'm') {
+ ASSERT(STRING_STARTS_WITH(format, "fmt"));
+ PrintFormat(instr);
+ return 3;
+ } else {
+ return FormatFRegister(instr, format);
+ }
+ }
case 's': {
ASSERT(STRING_STARTS_WITH(format, "sa"));
buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
@@ -397,6 +476,51 @@
}
}
+void MIPSDecoder::DecodeCop1(Instr* instr) {
+ ASSERT(instr->OpcodeField() == COP1);
+ if (instr->HasFormat()) {
+ // If the rs field is a valid format, then the function field identifies
+ // the instruction.
+ switch (instr->Cop1FunctionField()) {
+ case COP1_ADD: {
+ Format(instr, "add.'fmt 'fd, 'fs, 'ft");
+ break;
+ }
+ case COP1_MOV: {
+ Format(instr, "mov.'fmt 'fd, 'fs");
+ break;
+ }
+ default: {
+ Unknown(instr);
+ break;
+ }
+ }
+ } else {
+ // If the rs field isn't a valid format, then it must be a sub-opcode.
+ switch (instr->Cop1SubField()) {
+ case COP1_MF: {
+ if (instr->Bits(0, 11) != 0) {
+ Unknown(instr);
+ } else {
+ Format(instr, "mfc1 'rt, 'fs");
+ }
+ break;
+ }
+ case COP1_MT: {
+ if (instr->Bits(0, 11) != 0) {
+ Unknown(instr);
+ } else {
+ Format(instr, "mtc1 'rt, 'fs");
+ }
+ break;
+ }
+ default: {
+ Unknown(instr);
+ break;
+ }
+ }
+ }
+}
void MIPSDecoder::InstructionDecode(Instr* instr) {
switch (instr->OpcodeField()) {
@@ -412,6 +536,10 @@
DecodeRegImm(instr);
break;
}
+ case COP1: {
+ DecodeCop1(instr);
+ break;
+ }
case ADDIU: {
Format(instr, "addiu 'rt, 'rs, 'imms");
break;
@@ -460,6 +588,10 @@
Format(instr, "lbu 'rt, 'imms('rs)");
break;
}
+ case LDC1: {
+ Format(instr, "ldc1 'ft, 'imms('rs)");
+ break;
+ }
case LH: {
Format(instr, "lh 'rt, 'imms('rs)");
break;
@@ -472,6 +604,10 @@
Format(instr, "lw 'rt, 'imms('rs)");
break;
}
+ case LWC1: {
+ Format(instr, "lwc1 'ft, 'imms('rs)");
+ break;
+ }
case ORI: {
Format(instr, "ori 'rt, 'rs, 'immu");
break;
@@ -484,10 +620,18 @@
Format(instr, "sh 'rt, 'imms('rs)");
break;
}
+ case SDC1: {
+ Format(instr, "sdc1 'ft, 'imms('rs)");
+ break;
+ }
case SW: {
Format(instr, "sw 'rt, 'imms('rs)");
break;
}
+ case SWC1: {
+ Format(instr, "swc1 'ft, 'imms('rs)");
+ break;
+ }
default: {
Unknown(instr);
break;

Powered by Google App Engine
This is Rietveld 408576698