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

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

Issue 1213553004: MIPS: Disassembler enhancement. Disassembled branch instruction displays branch target absolute add… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Corrections for calculations of the branch target addresses. Created 5 years, 6 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/mips/disasm-mips.cc ('k') | test/cctest/test-disasm-mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mips64/disasm-mips64.cc
diff --git a/src/mips64/disasm-mips64.cc b/src/mips64/disasm-mips64.cc
index 3ce2b45380ce7dcd6da4c90a67dec96dfdae34d3..ee624db2f8cab4d92fb4df9d02e74baaeb11c558 100644
--- a/src/mips64/disasm-mips64.cc
+++ b/src/mips64/disasm-mips64.cc
@@ -86,13 +86,18 @@ class Decoder {
void PrintUImm16(Instruction* instr);
void PrintSImm16(Instruction* instr);
void PrintXImm16(Instruction* instr);
+ void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits);
void PrintXImm18(Instruction* instr);
void PrintSImm18(Instruction* instr);
void PrintXImm19(Instruction* instr);
void PrintSImm19(Instruction* instr);
void PrintXImm21(Instruction* instr);
+
+ void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits);
void PrintXImm26(Instruction* instr);
void PrintSImm26(Instruction* instr);
+ void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits);
+ void PrintPCImm26(Instruction* instr);
void PrintCode(Instruction* instr); // For break and trap instructions.
void PrintFormat(Instruction* instr); // For floating format postfix.
void PrintBp2(Instruction* instr);
@@ -271,6 +276,18 @@ void Decoder::PrintXImm16(Instruction* instr) {
}
+// Print absoulte address for 16-bit offset or immediate value.
+// The absolute address is calculated according following expression:
+// PC + delta_pc + (offset << n_bits)
+void Decoder::PrintPCImm16(Instruction* instr, int delta_pc, int n_bits) {
+ int16_t offset = instr->Imm16Value();
+ out_buffer_pos_ +=
+ SNPrintF(out_buffer_ + out_buffer_pos_, "%s",
+ converter_.NameOfAddress(reinterpret_cast<byte*>(instr) +
+ delta_pc + (offset << n_bits)));
+}
+
+
// Print 18-bit signed immediate value.
void Decoder::PrintSImm18(Instruction* instr) {
int32_t imm =
@@ -310,6 +327,21 @@ void Decoder::PrintXImm21(Instruction* instr) {
}
+// Print absoulte address for 21-bit offset or immediate value.
+// The absolute address is calculated according following expression:
+// PC + delta_pc + (offset << n_bits)
+void Decoder::PrintPCImm21(Instruction* instr, int delta_pc, int n_bits) {
+ int32_t imm21 = instr->Imm21Value();
+ // set sign
+ imm21 <<= (32 - kImm21Bits);
+ imm21 >>= (32 - kImm21Bits);
+ out_buffer_pos_ +=
+ SNPrintF(out_buffer_ + out_buffer_pos_, "%s",
+ converter_.NameOfAddress(reinterpret_cast<byte*>(instr) +
+ delta_pc + (imm21 << n_bits)));
+}
+
+
// Print 26-bit hex immediate value.
void Decoder::PrintXImm26(Instruction* instr) {
uint32_t imm = static_cast<uint32_t>(instr->Imm26Value()) << kImmFieldShift;
@@ -327,6 +359,34 @@ void Decoder::PrintSImm26(Instruction* instr) {
}
+// Print absoulte address for 26-bit offset or immediate value.
+// The absolute address is calculated according following expression:
+// PC + delta_pc + (offset << n_bits)
+void Decoder::PrintPCImm26(Instruction* instr, int delta_pc, int n_bits) {
+ int32_t imm26 = instr->Imm26Value();
+ // set sign
+ imm26 <<= (32 - kImm26Bits);
+ imm26 >>= (32 - kImm26Bits);
+ out_buffer_pos_ +=
+ SNPrintF(out_buffer_ + out_buffer_pos_, "%s",
+ converter_.NameOfAddress(reinterpret_cast<byte*>(instr) +
+ delta_pc + (imm26 << n_bits)));
+}
+
+
+// Print absoulte address for 26-bit offset or immediate value.
+// The absolute address is calculated according following expression:
+// PC[GPRLEN-1 .. 28] || instr_index26 || 00
+void Decoder::PrintPCImm26(Instruction* instr) {
+ int32_t imm26 = instr->Imm26Value();
+ uint64_t pc_mask = ~0xfffffff;
+ uint64_t pc = ((uint64_t)(instr + 1) & pc_mask) | (imm26 << 2);
+ out_buffer_pos_ +=
+ SNPrintF(out_buffer_ + out_buffer_pos_, "%s",
+ converter_.NameOfAddress((reinterpret_cast<byte*>(pc))));
+}
+
+
void Decoder::PrintBp2(Instruction* instr) {
int bp2 = instr->Bp2Value();
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp2);
@@ -472,6 +532,24 @@ int Decoder::FormatOption(Instruction* instr, const char* format) {
DCHECK(STRING_STARTS_WITH(format, "imm16x"));
PrintXImm16(instr);
break;
+ case 'p': { // The PC relative address.
+ DCHECK(STRING_STARTS_WITH(format, "imm16p"));
+ int delta_pc = 0;
+ int n_bits = 0;
+ switch (format[6]) {
+ case '4': {
+ DCHECK(STRING_STARTS_WITH(format, "imm16p4"));
+ delta_pc = 4;
+ switch (format[8]) {
+ case '2':
+ DCHECK(STRING_STARTS_WITH(format, "imm16p4s2"));
+ n_bits = 2;
+ PrintPCImm16(instr, delta_pc, n_bits);
+ return 9;
+ }
+ }
+ }
+ }
}
return 6;
} else if (format[4] == '8') {
@@ -502,8 +580,31 @@ int Decoder::FormatOption(Instruction* instr, const char* format) {
return 6;
}
} else if (format[3] == '2' && format[4] == '1') {
- DCHECK(STRING_STARTS_WITH(format, "imm21x"));
- PrintXImm21(instr);
+ DCHECK(STRING_STARTS_WITH(format, "imm21"));
+ switch (format[5]) {
+ case 'x':
+ DCHECK(STRING_STARTS_WITH(format, "imm21x"));
+ PrintXImm21(instr);
+ break;
+ case 'p': { // The PC relative address.
+ DCHECK(STRING_STARTS_WITH(format, "imm21p"));
+ int delta_pc = 0;
+ int n_bits = 0;
+ switch (format[6]) {
+ case '4': {
+ DCHECK(STRING_STARTS_WITH(format, "imm21p4"));
+ delta_pc = 4;
+ switch (format[8]) {
+ case '2':
+ DCHECK(STRING_STARTS_WITH(format, "imm21p4s2"));
+ n_bits = 2;
+ PrintPCImm21(instr, delta_pc, n_bits);
+ return 9;
+ }
+ }
+ }
+ }
+ }
return 6;
} else if (format[3] == '2' && format[4] == '6') {
DCHECK(STRING_STARTS_WITH(format, "imm26"));
@@ -516,6 +617,29 @@ int Decoder::FormatOption(Instruction* instr, const char* format) {
DCHECK(STRING_STARTS_WITH(format, "imm26x"));
PrintXImm26(instr);
break;
+ case 'p': { // The PC relative address.
+ DCHECK(STRING_STARTS_WITH(format, "imm26p"));
+ int delta_pc = 0;
+ int n_bits = 0;
+ switch (format[6]) {
+ case '4': {
+ DCHECK(STRING_STARTS_WITH(format, "imm26p4"));
+ delta_pc = 4;
+ switch (format[8]) {
+ case '2':
+ DCHECK(STRING_STARTS_WITH(format, "imm26p4s2"));
+ n_bits = 2;
+ PrintPCImm26(instr, delta_pc, n_bits);
+ return 9;
+ }
+ }
+ }
+ }
+ case 'j': { // Absolute address for jump instructions.
+ DCHECK(STRING_STARTS_WITH(format, "imm26j"));
+ PrintPCImm26(instr);
+ break;
+ }
}
return 6;
}
@@ -1358,16 +1482,16 @@ void Decoder::DecodeTypeImmediateCOP1(Instruction* instr) {
switch (instr->RsFieldRaw()) {
case BC1:
if (instr->FBtrueValue()) {
- Format(instr, "bc1t 'bc, 'imm16u");
+ Format(instr, "bc1t 'bc, 'imm16u -> 'imm16p4s2");
} else {
- Format(instr, "bc1f 'bc, 'imm16u");
+ Format(instr, "bc1f 'bc, 'imm16u -> 'imm16p4s2");
}
break;
case BC1EQZ:
- Format(instr, "bc1eqz 'ft, 'imm16u");
+ Format(instr, "bc1eqz 'ft, 'imm16u -> 'imm16p4s2");
break;
case BC1NEZ:
- Format(instr, "bc1nez 'ft, 'imm16u");
+ Format(instr, "bc1nez 'ft, 'imm16u -> 'imm16p4s2");
break;
default:
UNREACHABLE();
@@ -1378,19 +1502,19 @@ void Decoder::DecodeTypeImmediateCOP1(Instruction* instr) {
void Decoder::DecodeTypeImmediateREGIMM(Instruction* instr) {
switch (instr->RtFieldRaw()) {
case BLTZ:
- Format(instr, "bltz 'rs, 'imm16u");
+ Format(instr, "bltz 'rs, 'imm16u -> 'imm16p4s2");
break;
case BLTZAL:
- Format(instr, "bltzal 'rs, 'imm16u");
+ Format(instr, "bltzal 'rs, 'imm16u -> 'imm16p4s2");
break;
case BGEZ:
- Format(instr, "bgez 'rs, 'imm16u");
+ Format(instr, "bgez 'rs, 'imm16u -> 'imm16p4s2");
break;
case BGEZAL:
- Format(instr, "bgezal 'rs, 'imm16u");
+ Format(instr, "bgezal 'rs, 'imm16u -> 'imm16p4s2");
break;
case BGEZALL:
- Format(instr, "bgezall 'rs, 'imm16u");
+ Format(instr, "bgezall 'rs, 'imm16u -> 'imm16p4s2");
break;
case DAHI:
Format(instr, "dahi 'rs, 'imm16u");
@@ -1411,79 +1535,71 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
break; // Case COP1.
// ------------- REGIMM class.
case REGIMM:
-
- break; // Case REGIMM.
+ DecodeTypeImmediateREGIMM(instr);
+ break; // Case REGIMM.
// ------------- Branch instructions.
case BEQ:
- Format(instr, "beq 'rs, 'rt, 'imm16u");
+ Format(instr, "beq 'rs, 'rt, 'imm16u -> 'imm16p4s2");
break;
case BC:
- Format(instr, "bc 'imm26s");
+ Format(instr, "bc 'imm26s -> 'imm26p4s2");
break;
case BALC:
- Format(instr, "balc 'imm26s");
+ Format(instr, "balc 'imm26s -> 'imm26p4s2");
break;
case BNE:
- Format(instr, "bne 'rs, 'rt, 'imm16u");
+ Format(instr, "bne 'rs, 'rt, 'imm16u -> 'imm16p4s2");
break;
case BLEZ:
- if ((instr->RtFieldRaw() == 0)
- && (instr->RsFieldRaw() != 0)) {
- Format(instr, "blez 'rs, 'imm16u");
- } else if ((instr->RtFieldRaw() != instr->RsFieldRaw())
- && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) {
- Format(instr, "bgeuc 'rs, 'rt, 'imm16u");
- } else if ((instr->RtFieldRaw() == instr->RsFieldRaw())
- && (instr->RtFieldRaw() != 0)) {
- Format(instr, "bgezalc 'rs, 'imm16u");
- } else if ((instr->RsFieldRaw() == 0)
- && (instr->RtFieldRaw() != 0)) {
- Format(instr, "blezalc 'rs, 'imm16u");
+ if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) {
+ Format(instr, "blez 'rs, 'imm16u -> 'imm16p4s2");
+ } else if ((instr->RtValue() != instr->RsValue()) &&
+ (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
+ Format(instr, "bgeuc 'rs, 'rt, 'imm16u -> 'imm16p4s2");
+ } else if ((instr->RtValue() == instr->RsValue()) &&
+ (instr->RtValue() != 0)) {
+ Format(instr, "bgezalc 'rs, 'imm16u -> 'imm16p4s2");
+ } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
+ Format(instr, "blezalc 'rt, 'imm16u -> 'imm16p4s2");
} else {
UNREACHABLE();
}
break;
case BGTZ:
- if ((instr->RtFieldRaw() == 0)
- && (instr->RsFieldRaw() != 0)) {
- Format(instr, "bgtz 'rs, 'imm16u");
- } else if ((instr->RtFieldRaw() != instr->RsFieldRaw())
- && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) {
- Format(instr, "bltuc 'rs, 'rt, 'imm16u");
- } else if ((instr->RtFieldRaw() == instr->RsFieldRaw())
- && (instr->RtFieldRaw() != 0)) {
- Format(instr, "bltzalc 'rt, 'imm16u");
- } else if ((instr->RsFieldRaw() == 0)
- && (instr->RtFieldRaw() != 0)) {
- Format(instr, "bgtzalc 'rt, 'imm16u");
+ if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) {
+ Format(instr, "bgtz 'rs, 'imm16u -> 'imm16p4s2");
+ } else if ((instr->RtValue() != instr->RsValue()) &&
+ (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
+ Format(instr, "bltuc 'rs, 'rt, 'imm16u -> 'imm16p4s2");
+ } else if ((instr->RtValue() == instr->RsValue()) &&
+ (instr->RtValue() != 0)) {
+ Format(instr, "bltzalc 'rt, 'imm16u -> 'imm16p4s2");
+ } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
+ Format(instr, "bgtzalc 'rt, 'imm16u -> 'imm16p4s2");
} else {
UNREACHABLE();
}
break;
case BLEZL:
- if ((instr->RtFieldRaw() == instr->RsFieldRaw())
- && (instr->RtFieldRaw() != 0)) {
- Format(instr, "bgezc 'rt, 'imm16u");
- } else if ((instr->RtFieldRaw() != instr->RsFieldRaw())
- && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) {
- Format(instr, "bgec 'rs, 'rt, 'imm16u");
- } else if ((instr->RsFieldRaw() == 0)
- && (instr->RtFieldRaw() != 0)) {
- Format(instr, "blezc 'rt, 'imm16u");
+ if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) {
+ Format(instr, "bgezc 'rt, 'imm16u -> 'imm16p4s2");
+ } else if ((instr->RtValue() != instr->RsValue()) &&
+ (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
+ Format(instr, "bgec 'rs, 'rt, 'imm16u -> 'imm16p4s2");
+ } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
+ Format(instr, "blezc 'rt, 'imm16u -> 'imm16p4s2");
} else {
UNREACHABLE();
}
break;
case BGTZL:
- if ((instr->RtFieldRaw() == instr->RsFieldRaw())
- && (instr->RtFieldRaw() != 0)) {
- Format(instr, "bltzc 'rt, 'imm16u");
- } else if ((instr->RtFieldRaw() != instr->RsFieldRaw())
- && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) {
- Format(instr, "bltc 'rs, 'rt, 'imm16u");
- } else if ((instr->RsFieldRaw() == 0)
- && (instr->RtFieldRaw() != 0)) {
- Format(instr, "bgtzc 'rt, 'imm16u");
+ if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) {
+ Format(instr, "bltzc 'rt, 'imm16u -> 'imm16p4s2");
+ } else if ((instr->RtValue() != instr->RsValue()) &&
+ (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
+ Format(instr, "bltc 'rs, 'rt, 'imm16u -> 'imm16p4s2");
+ } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
+ Format(instr, "bgtzc 'rt, 'imm16u -> 'imm16p4s2");
} else {
UNREACHABLE();
}
@@ -1492,14 +1608,14 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
if (instr->RsValue() == JIC) {
Format(instr, "jic 'rt, 'imm16s");
} else {
- Format(instr, "beqzc 'rs, 'imm21x");
+ Format(instr, "beqzc 'rs, 'imm21x -> 'imm21p4s2");
}
break;
case POP76:
if (instr->RsValue() == JIALC) {
Format(instr, "jialc 'rt, 'imm16x");
} else {
- Format(instr, "bnezc 'rs, 'imm21x");
+ Format(instr, "bnezc 'rs, 'imm21x -> 'imm21p4s2");
}
break;
// ------------- Arithmetic instructions.
@@ -1508,10 +1624,10 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
Format(instr, "addi 'rt, 'rs, 'imm16s");
} else {
// Check if BOVC or BEQC instruction.
- if (instr->RsFieldRaw() >= instr->RtFieldRaw()) {
- Format(instr, "bovc 'rs, 'rt, 'imm16s");
- } else if (instr->RsFieldRaw() < instr->RtFieldRaw()) {
- Format(instr, "beqc 'rs, 'rt, 'imm16s");
+ if (instr->RsValue() >= instr->RtValue()) {
+ Format(instr, "bovc 'rs, 'rt, 'imm16s -> 'imm16p4s2");
+ } else if (instr->RsValue() < instr->RtValue()) {
+ Format(instr, "beqc 'rs, 'rt, 'imm16s -> 'imm16p4s2");
} else {
UNREACHABLE();
}
@@ -1522,10 +1638,10 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
Format(instr, "daddi 'rt, 'rs, 'imm16s");
} else {
// Check if BNVC or BNEC instruction.
- if (instr->RsFieldRaw() >= instr->RtFieldRaw()) {
- Format(instr, "bnvc 'rs, 'rt, 'imm16s");
- } else if (instr->RsFieldRaw() < instr->RtFieldRaw()) {
- Format(instr, "bnec 'rs, 'rt, 'imm16s");
+ if (instr->RsValue() >= instr->RtValue()) {
+ Format(instr, "bnvc 'rs, 'rt, 'imm16s -> 'imm16p4s2");
+ } else if (instr->RsValue() < instr->RtValue()) {
+ Format(instr, "bnec 'rs, 'rt, 'imm16s -> 'imm16p4s2");
} else {
UNREACHABLE();
}
@@ -1687,10 +1803,10 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
void Decoder::DecodeTypeJump(Instruction* instr) {
switch (instr->OpcodeFieldRaw()) {
case J:
- Format(instr, "j 'imm26x");
+ Format(instr, "j 'imm26x -> 'imm26j");
break;
case JAL:
- Format(instr, "jal 'imm26x");
+ Format(instr, "jal 'imm26x -> 'imm26j");
break;
default:
UNREACHABLE();
« no previous file with comments | « src/mips/disasm-mips.cc ('k') | test/cctest/test-disasm-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698