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(); |