summaryrefslogtreecommitdiff
path: root/disassembler/disassembler_mips.cc
diff options
context:
space:
mode:
authorAlexey Frunze <Alexey.Frunze@imgtec.com>2017-07-25 15:19:36 -0700
committerAlexey Frunze <Alexey.Frunze@imgtec.com>2017-07-30 20:09:26 -0700
commit0cab65610a6a984a94ef4c3f232fe0273e78d95b (patch)
tree669fa607f4cd9ad8eef9223bb124fb72265a06b3 /disassembler/disassembler_mips.cc
parent2e53f8f69f8c4175085e337445ec42aa045a2f7f (diff)
MIPS: Eliminate hard-coded offsets in branches
The bulk of the change is in the assemblers and their tests. The main goal is to introduce "bare" branches to labels (as opposed to the existing bare branches with relative offsets, whose direct use we want to eliminate). These branches' delay/forbidden slots are filled manually and these branches do not promote to long (the branch target must be within reach of the individual branch instruction). The secondary goal is to add more branch tests (mainly for bare vs non-bare branches and a few extra) and refactor and reorganize the branch test code a bit. The third goal is to improve idiom recognition in the disassembler, including branch idioms and a few others. Further details: - introduce bare branches (R2 and R6) to labels, making R2 branches available for use on R6 - make use of the above in the code generators - align beqz/bnez with their GNU assembler encoding to simplify and shorten the test code - update the CFI test because of the above - add trivial tests for bare and non-bare branches (addressing existing debt as well) - add MIPS32R6 tests for long beqc/beqzc/bc (debt) - add MIPS64R6 long beqzc test (debt) - group branch tests together - group constant/literal/address-loading tests together - make the disassembler recognize: - b/beqz/bnez (beq/bne with $zero reg) - nal (bltzal with $zero reg) - bal/bgezal (bal = bgezal with $zero reg) - move (or with $zero reg) - li (ori/addiu with $zero reg) - dli (daddiu with $zero reg) - disassemble 16-bit immediate operands (in andi, ori, xori, li, dli) as signed or unsigned as appropriate - drop unused instructions (bltzl, bltzall, addi) from the disassembler as there are no plans to use them Test: test-art-host-gtest Test: booted MIPS64 (with 2nd arch MIPS32R6) in QEMU Test: test-art-target-gtest Test: testrunner.py --target --optimizing Test: same tests as above on CI20 Test: booted MIPS32R2 in QEMU Change-Id: I62b74a6c00ce0651528114806ba24a59ba564a73
Diffstat (limited to 'disassembler/disassembler_mips.cc')
-rw-r--r--disassembler/disassembler_mips.cc28
1 files changed, 19 insertions, 9 deletions
diff --git a/disassembler/disassembler_mips.cc b/disassembler/disassembler_mips.cc
index 1a395a45d2..938ea5dc2f 100644
--- a/disassembler/disassembler_mips.cc
+++ b/disassembler/disassembler_mips.cc
@@ -112,6 +112,8 @@ static const MipsInstruction gMipsInstructions[] = {
{ kRTypeMask, 34, "sub", "DST", },
{ kRTypeMask, 35, "subu", "DST", },
{ kRTypeMask, 36, "and", "DST", },
+ { kRTypeMask | (0x1f << 16), 37 | (0 << 16), "move", "DS" },
+ { kRTypeMask | (0x1f << 21), 37 | (0 << 21), "move", "DT" },
{ kRTypeMask, 37, "or", "DST", },
{ kRTypeMask, 38, "xor", "DST", },
{ kRTypeMask, 39, "nor", "DST", },
@@ -214,13 +216,19 @@ static const MipsInstruction gMipsInstructions[] = {
{ kJTypeMask, 3 << kOpcodeShift, "jal", "L" },
// I-type instructions.
+ { kITypeMask | (0x3ff << 16), 4 << kOpcodeShift, "b", "B" },
+ { kITypeMask | (0x1f << 16), 4 << kOpcodeShift | (0 << 16), "beqz", "SB" },
+ { kITypeMask | (0x1f << 21), 4 << kOpcodeShift | (0 << 21), "beqz", "TB" },
{ kITypeMask, 4 << kOpcodeShift, "beq", "STB" },
+ { kITypeMask | (0x1f << 16), 5 << kOpcodeShift | (0 << 16), "bnez", "SB" },
+ { kITypeMask | (0x1f << 21), 5 << kOpcodeShift | (0 << 21), "bnez", "TB" },
{ kITypeMask, 5 << kOpcodeShift, "bne", "STB" },
{ kITypeMask | (0x1f << 16), 1 << kOpcodeShift | (1 << 16), "bgez", "SB" },
{ kITypeMask | (0x1f << 16), 1 << kOpcodeShift | (0 << 16), "bltz", "SB" },
- { kITypeMask | (0x1f << 16), 1 << kOpcodeShift | (2 << 16), "bltzl", "SB" },
+ { kITypeMask | (0x3ff << 16), 1 << kOpcodeShift | (16 << 16), "nal", "" },
{ kITypeMask | (0x1f << 16), 1 << kOpcodeShift | (16 << 16), "bltzal", "SB" },
- { kITypeMask | (0x1f << 16), 1 << kOpcodeShift | (18 << 16), "bltzall", "SB" },
+ { kITypeMask | (0x3ff << 16), 1 << kOpcodeShift | (17 << 16), "bal", "B" },
+ { kITypeMask | (0x1f << 16), 1 << kOpcodeShift | (17 << 16), "bgezal", "SB" },
{ kITypeMask | (0x1f << 16), 6 << kOpcodeShift | (0 << 16), "blez", "SB" },
{ kITypeMask, 6 << kOpcodeShift, "bgeuc", "STB" },
{ kITypeMask | (0x1f << 16), 7 << kOpcodeShift | (0 << 16), "bgtz", "SB" },
@@ -228,18 +236,16 @@ static const MipsInstruction gMipsInstructions[] = {
{ kITypeMask | (0x1f << 16), 1 << kOpcodeShift | (6 << 16), "dahi", "Si", },
{ kITypeMask | (0x1f << 16), 1 << kOpcodeShift | (30 << 16), "dati", "Si", },
- { 0xffff0000, (4 << kOpcodeShift), "b", "B" },
- { 0xffff0000, (1 << kOpcodeShift) | (17 << 16), "bal", "B" },
-
{ kITypeMask, 8 << kOpcodeShift, "beqc", "STB" },
- { kITypeMask, 8 << kOpcodeShift, "addi", "TSi", },
+ { kITypeMask | (0x1f << 21), 9 << kOpcodeShift | (0 << 21), "li", "Ti" },
{ kITypeMask, 9 << kOpcodeShift, "addiu", "TSi", },
{ kITypeMask, 10 << kOpcodeShift, "slti", "TSi", },
{ kITypeMask, 11 << kOpcodeShift, "sltiu", "TSi", },
- { kITypeMask, 12 << kOpcodeShift, "andi", "TSi", },
- { kITypeMask, 13 << kOpcodeShift, "ori", "TSi", },
- { kITypeMask, 14 << kOpcodeShift, "xori", "TSi", },
+ { kITypeMask, 12 << kOpcodeShift, "andi", "TSI", },
+ { kITypeMask | (0x1f << 21), 13 << kOpcodeShift | (0 << 21), "li", "TI" },
+ { kITypeMask, 13 << kOpcodeShift, "ori", "TSI", },
+ { kITypeMask, 14 << kOpcodeShift, "xori", "TSI", },
{ kITypeMask | (0x1f << 21), 15 << kOpcodeShift, "lui", "Ti", },
{ kITypeMask, 15 << kOpcodeShift, "aui", "TSi", },
@@ -324,6 +330,7 @@ static const MipsInstruction gMipsInstructions[] = {
{ kITypeMask, 24 << kOpcodeShift, "bnec", "STB" },
+ { kITypeMask | (0x1f << 21), 25 << kOpcodeShift | (0 << 21), "dli", "Ti" },
{ kITypeMask, 25 << kOpcodeShift, "daddiu", "TSi", },
{ kITypeMask, 29 << kOpcodeShift, "daui", "TSi", },
@@ -561,6 +568,9 @@ size_t DisassemblerMips::Dump(std::ostream& os, const uint8_t* instr_ptr) {
}
continue; // No ", ".
}
+ case 'I': // Unsigned lower 16-bit immediate.
+ args << (instruction & 0xffff);
+ break;
case 'i': // Sign-extended lower 16-bit immediate.
args << static_cast<int16_t>(instruction & 0xffff);
break;