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