summaryrefslogtreecommitdiffstats
path: root/disassembler
diff options
context:
space:
mode:
authorDave Allison <dallison@google.com>2014-06-16 20:44:29 -0700
committerDave Allison <dallison@google.com>2014-06-24 09:05:27 -0700
commit20dfc797dc631bf8d655dcf123f46f13332d3074 (patch)
treec1d4e4f919d54f39a6d39d9d769ed5a844afb22b /disassembler
parentcbb0e809c0a4e8a4e8b7f5d3768a1864cfb381bb (diff)
downloadart-20dfc797dc631bf8d655dcf123f46f13332d3074.zip
art-20dfc797dc631bf8d655dcf123f46f13332d3074.tar.gz
art-20dfc797dc631bf8d655dcf123f46f13332d3074.tar.bz2
Add some more instruction support to optimizing compiler.
This adds a few more DEX instructions to the optimizing compiler's builder (constants, moves, if_xx, etc). Also: * Changes the codegen for IF_XX instructions to use a condition rather than comparing a value against 0. * Fixes some instructions in the ARM disassembler. * Fixes PushList and PopList in the thumb2 assembler. * Switches the assembler for the optimizing compiler to thumb2 rather than ARM. Change-Id: Iaafcd02243ccc5b03a054ef7a15285b84c06740f
Diffstat (limited to 'disassembler')
-rw-r--r--disassembler/disassembler_arm.cc69
1 files changed, 54 insertions, 15 deletions
diff --git a/disassembler/disassembler_arm.cc b/disassembler/disassembler_arm.cc
index 4e4a512..1f565e5 100644
--- a/disassembler/disassembler_arm.cc
+++ b/disassembler/disassembler_arm.cc
@@ -269,18 +269,34 @@ void DisassemblerArm::DumpArm(std::ostream& os, const uint8_t* instr_ptr) {
uint32_t op = (instruction >> 21) & 0xf;
opcode = kDataProcessingOperations[op];
bool implicit_s = ((op & ~3) == 8); // TST, TEQ, CMP, and CMN.
- if (implicit_s) {
- // Rd is unused (and not shown), and we don't show the 's' suffix either.
- } else {
+ bool is_mov = op == 0b1101 || op == 0b1111;
+ if (is_mov) {
+ // Show only Rd and Rm.
if (s) {
- suffixes += 's';
- }
- args << ArmRegister(instruction, 12) << ", ";
- }
- if (i) {
- args << ArmRegister(instruction, 16) << ", " << ShiftedImmediate(instruction);
+ suffixes += 's';
+ }
+ args << ArmRegister(instruction, 12) << ", ";
+ if (i) {
+ args << ShiftedImmediate(instruction);
+ } else {
+ // TODO: Shifted register.
+ args << ArmRegister(instruction, 16) << ", " << ArmRegister(instruction, 0);
+ }
} else {
- args << Rm(instruction);
+ if (implicit_s) {
+ // Rd is unused (and not shown), and we don't show the 's' suffix either.
+ } else {
+ if (s) {
+ suffixes += 's';
+ }
+ args << ArmRegister(instruction, 12) << ", ";
+ }
+ if (i) {
+ args << ArmRegister(instruction, 16) << ", " << ShiftedImmediate(instruction);
+ } else {
+ // TODO: Shifted register.
+ args << ArmRegister(instruction, 16) << ", " << ArmRegister(instruction, 0);
+ }
}
}
break;
@@ -1291,7 +1307,7 @@ size_t DisassemblerArm::DumpThumb32(std::ostream& os, const uint8_t* instr_ptr)
int32_t imm32 = (imm8 << 24) >> 24; // sign-extend imm8
if (Rn.r == 13 && P == 1 && U == 0 && W == 1 && imm32 == 4) {
opcode << "push";
- args << Rt;
+ args << "{" << Rt << "}";
} else if (Rn.r == 15 || (P == 0 && W == 0)) {
opcode << "UNDEFINED";
} else {
@@ -1443,10 +1459,33 @@ size_t DisassemblerArm::DumpThumb32(std::ostream& os, const uint8_t* instr_ptr)
}
args << "]";
} else {
- // LDRT Rt, [Rn, #imm8] - 111 11 00 00 101 nnnn tttt 1110iiiiiiii
- uint32_t imm8 = instr & 0xFF;
- opcode << "ldrt";
- args << Rt << ", [" << Rn << ", #" << imm8 << "]";
+ bool p = (instr & (1 << 10)) != 0;
+ bool w = (instr & (1 << 8)) != 0;
+ bool u = (instr & (1 << 9)) != 0;
+ if (p && u && !w) {
+ // LDRT Rt, [Rn, #imm8] - 111 11 00 00 101 nnnn tttt 1110iiiiiiii
+ uint32_t imm8 = instr & 0xFF;
+ opcode << "ldrt";
+ args << Rt << ", [" << Rn << ", #" << imm8 << "]";
+ } else if (Rn.r == 13 && !p && u && w && (instr & 0xff) == 4) {
+ // POP
+ opcode << "pop";
+ args << "{" << Rt << "}";
+ } else {
+ bool wback = !p || w;
+ uint32_t offset = (instr & 0xff);
+ opcode << "ldr.w";
+ args << Rt << ",";
+ if (p && !wback) {
+ args << "[" << Rn << ", #" << offset << "]";
+ } else if (p && wback) {
+ args << "[" << Rn << ", #" << offset << "]!";
+ } else if (!p && wback) {
+ args << "[" << Rn << "], #" << offset;
+ } else {
+ LOG(FATAL) << p << " " << w;
+ }
+ }
}
break;
}