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

Unified Diff: src/mips/disasm-mips.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 | « no previous file | src/mips64/disasm-mips64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mips/disasm-mips.cc
diff --git a/src/mips/disasm-mips.cc b/src/mips/disasm-mips.cc
index 73169ca00f732d9489384067ccdf5de87a4ac3b1..48427c54558650e2e3d2a8402af116ac5ba8f227 100644
--- a/src/mips/disasm-mips.cc
+++ b/src/mips/disasm-mips.cc
@@ -87,14 +87,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 PrintSImm21(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.
// Printing of instruction name.
@@ -270,6 +274,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 =
@@ -319,6 +335,21 @@ void Decoder::PrintSImm21(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 = instr->Imm26Value() << kImmFieldShift;
@@ -336,6 +367,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();
+ uint32_t pc_mask = ~0xfffffff;
+ uint32_t pc = ((uint32_t)(instr + 1) & pc_mask) | (imm26 << 2);
+ out_buffer_pos_ +=
+ SNPrintF(out_buffer_ + out_buffer_pos_, "%s",
+ converter_.NameOfAddress((reinterpret_cast<byte*>(pc))));
+}
+
+
// Print 26-bit immediate value.
void Decoder::PrintCode(Instruction* instr) {
if (instr->OpcodeFieldRaw() != SPECIAL)
@@ -469,6 +528,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') {
@@ -509,6 +586,24 @@ int Decoder::FormatOption(Instruction* instr, const char* format) {
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') {
@@ -522,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;
}
@@ -1200,16 +1318,16 @@ void Decoder::DecodeTypeImmediate(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();
@@ -1220,19 +1338,19 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
case REGIMM:
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;
default:
UNREACHABLE();
@@ -1240,75 +1358,67 @@ void Decoder::DecodeTypeImmediate(Instruction* 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();
}
@@ -1317,14 +1427,14 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
if (instr->RsValue() == JIC) {
Format(instr, "jic 'rt, 'imm16s");
} else {
- Format(instr, "beqzc 'rs, 'imm21s");
+ Format(instr, "beqzc 'rs, 'imm21s -> '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.
@@ -1333,10 +1443,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();
}
@@ -1345,10 +1455,10 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
case DADDI:
if (IsMipsArchVariant(kMips32r6)) {
// 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();
}
@@ -1475,10 +1585,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 | « no previous file | src/mips64/disasm-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698