diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-07-11 10:57:49 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-07-21 09:54:20 +0100 |
commit | 96f89a290eb67d7bf4b1636798fa28df14309cc7 (patch) | |
tree | ca2b484a18107f8253aa7774cde304586a31bc60 /compiler/utils | |
parent | 4436e926aa8e64ac7e4c4afb81f2a59b2477045a (diff) | |
download | art-96f89a290eb67d7bf4b1636798fa28df14309cc7.zip art-96f89a290eb67d7bf4b1636798fa28df14309cc7.tar.gz art-96f89a290eb67d7bf4b1636798fa28df14309cc7.tar.bz2 |
Add assembly operations with constants in optimizing compiler.
Change-Id: I5bcc35ab50d4457186effef5592a75d7f4e5b65f
Diffstat (limited to 'compiler/utils')
-rw-r--r-- | compiler/utils/arm/assembler_arm.cc | 5 | ||||
-rw-r--r-- | compiler/utils/arm/assembler_arm.h | 4 | ||||
-rw-r--r-- | compiler/utils/arm/assembler_thumb2.cc | 16 | ||||
-rw-r--r-- | compiler/utils/assembler_thumb_test.cc | 17 | ||||
-rw-r--r-- | compiler/utils/assembler_thumb_test_expected.cc.inc | 4 | ||||
-rw-r--r-- | compiler/utils/x86_64/assembler_x86_64.cc | 32 | ||||
-rw-r--r-- | compiler/utils/x86_64/assembler_x86_64.h | 4 |
7 files changed, 65 insertions, 17 deletions
diff --git a/compiler/utils/arm/assembler_arm.cc b/compiler/utils/arm/assembler_arm.cc index 5fe8246..671ccb6 100644 --- a/compiler/utils/arm/assembler_arm.cc +++ b/compiler/utils/arm/assembler_arm.cc @@ -73,6 +73,11 @@ std::ostream& operator<<(std::ostream& os, const Condition& rhs) { return os; } +ShifterOperand::ShifterOperand(uint32_t immed) + : type_(kImmediate), rm_(kNoRegister), rs_(kNoRegister), + is_rotate_(false), is_shift_(false), shift_(kNoShift), rotate_(0), immed_(immed) { + CHECK(immed < (1u << 12) || ArmAssembler::ModifiedImmediate(immed) != kInvalidModifiedImmediate); +} uint32_t ShifterOperand::encodingArm() const { diff --git a/compiler/utils/arm/assembler_arm.h b/compiler/utils/arm/assembler_arm.h index be19174..54965f6 100644 --- a/compiler/utils/arm/assembler_arm.h +++ b/compiler/utils/arm/assembler_arm.h @@ -35,9 +35,7 @@ class ShifterOperand { is_rotate_(false), is_shift_(false), shift_(kNoShift), rotate_(0), immed_(0) { } - explicit ShifterOperand(uint32_t immed) : type_(kImmediate), rm_(kNoRegister), rs_(kNoRegister), - is_rotate_(false), is_shift_(false), shift_(kNoShift), rotate_(0), immed_(immed) { - } + explicit ShifterOperand(uint32_t immed); // Data-processing operands - Register explicit ShifterOperand(Register rm) : type_(kRegister), rm_(rm), rs_(kNoRegister), diff --git a/compiler/utils/arm/assembler_thumb2.cc b/compiler/utils/arm/assembler_thumb2.cc index 2ce4fd2..c693ec0 100644 --- a/compiler/utils/arm/assembler_thumb2.cc +++ b/compiler/utils/arm/assembler_thumb2.cc @@ -619,7 +619,8 @@ bool Thumb2Assembler::Is32BitDataProcessing(Condition cond, return true; } - bool can_contain_high_register = opcode == MOV || opcode == ADD || opcode == SUB; + bool can_contain_high_register = (opcode == MOV) + || ((opcode == ADD || opcode == SUB) && (rn == rd)); if (IsHighRegister(rd) || IsHighRegister(rn)) { if (can_contain_high_register) { @@ -757,23 +758,21 @@ void Thumb2Assembler::Emit32BitDataProcessing(Condition cond, int32_t encoding = 0; if (so.IsImmediate()) { // Check special cases. - if ((opcode == SUB || opcode == ADD) && rn == SP) { - // There are special ADD/SUB rd, SP, #imm12 instructions. + if ((opcode == SUB || opcode == ADD) && (so.GetImmediate() < (1u << 12))) { if (opcode == SUB) { thumb_opcode = 0b0101; } else { thumb_opcode = 0; } uint32_t imm = so.GetImmediate(); - CHECK_LT(imm, (1u << 12)); uint32_t i = (imm >> 11) & 1; uint32_t imm3 = (imm >> 8) & 0b111; uint32_t imm8 = imm & 0xff; encoding = B31 | B30 | B29 | B28 | B25 | - B19 | B18 | B16 | thumb_opcode << 21 | + rn << 16 | rd << 8 | i << 26 | imm3 << 12 | @@ -882,7 +881,12 @@ void Thumb2Assembler::Emit16BitDataProcessing(Condition cond, } break; - case CMN: thumb_opcode = 0b1011; rn = so.GetRegister(); break; + case CMN: { + thumb_opcode = 0b1011; + rd = rn; + rn = so.GetRegister(); + break; + } case ORR: thumb_opcode = 0b1100; break; case MOV: dp_opcode = 0; diff --git a/compiler/utils/assembler_thumb_test.cc b/compiler/utils/assembler_thumb_test.cc index 68cb656..25928da 100644 --- a/compiler/utils/assembler_thumb_test.cc +++ b/compiler/utils/assembler_thumb_test.cc @@ -14,7 +14,10 @@ * limitations under the License. */ +#include <dirent.h> #include <fstream> +#include <sys/types.h> +#include <map> #include "gtest/gtest.h" #include "utils/arm/assembler_thumb2.h" @@ -40,6 +43,8 @@ namespace arm { static constexpr bool kPrintResults = false; #endif +static const char* TOOL_PREFIX = "arm-linux-androideabi-"; + void SetAndroidData() { const char* data = getenv("ANDROID_DATA"); if (data == nullptr) { @@ -109,9 +114,9 @@ std::string GetAndroidToolsDir() { // Suffix on toolsdir will be something like "arm-eabi-4.8" while ((entry = readdir(dir)) != nullptr) { std::string subdir = toolsdir + std::string("/") + std::string(entry->d_name); - size_t eabi = subdir.find("arm-eabi-"); + size_t eabi = subdir.find(TOOL_PREFIX); if (eabi != std::string::npos) { - std::string suffix = subdir.substr(eabi + sizeof("arm-eabi-")); + std::string suffix = subdir.substr(eabi + sizeof(TOOL_PREFIX)); double version = strtod(suffix.c_str(), nullptr); if (version > maxversion) { maxversion = version; @@ -169,19 +174,19 @@ void dump(std::vector<uint8_t>& code, const char* testname) { char cmd[256]; // Assemble the .S - snprintf(cmd, sizeof(cmd), "%sarm-eabi-as %s -o %s.o", toolsdir.c_str(), filename, filename); + snprintf(cmd, sizeof(cmd), "%s%sas %s -o %s.o", toolsdir.c_str(), TOOL_PREFIX, filename, filename); system(cmd); // Remove the $d symbols to prevent the disassembler dumping the instructions // as .word - snprintf(cmd, sizeof(cmd), "%sarm-eabi-objcopy -N '$d' %s.o %s.oo", toolsdir.c_str(), + snprintf(cmd, sizeof(cmd), "%s%sobjcopy -N '$d' %s.o %s.oo", toolsdir.c_str(), TOOL_PREFIX, filename, filename); system(cmd); // Disassemble. - snprintf(cmd, sizeof(cmd), "%sarm-eabi-objdump -d %s.oo | grep '^ *[0-9a-f][0-9a-f]*:'", - toolsdir.c_str(), filename); + snprintf(cmd, sizeof(cmd), "%s%sobjdump -d %s.oo | grep '^ *[0-9a-f][0-9a-f]*:'", + toolsdir.c_str(), TOOL_PREFIX, filename); if (kPrintResults) { // Print the results only, don't check. This is used to generate new output for inserting // into the .inc file. diff --git a/compiler/utils/assembler_thumb_test_expected.cc.inc b/compiler/utils/assembler_thumb_test_expected.cc.inc index 3943e37..18035f3 100644 --- a/compiler/utils/assembler_thumb_test_expected.cc.inc +++ b/compiler/utils/assembler_thumb_test_expected.cc.inc @@ -48,8 +48,8 @@ const char* DataProcessingRegisterResults[] = { const char* DataProcessingImmediateResults[] = { " 0: 2055 movs r0, #85 ; 0x55\n", " 2: f06f 0055 mvn.w r0, #85 ; 0x55\n", - " 6: f101 0055 add.w r0, r1, #85 ; 0x55\n", - " a: f1a1 0055 sub.w r0, r1, #85 ; 0x55\n", + " 6: f201 0055 addw r0, r1, #85 ; 0x55\n", + " a: f2a1 0055 subw r0, r1, #85 ; 0x55\n", " e: f001 0055 and.w r0, r1, #85 ; 0x55\n", " 12: f041 0055 orr.w r0, r1, #85 ; 0x55\n", " 16: f081 0055 eor.w r0, r1, #85 ; 0x55\n", diff --git a/compiler/utils/x86_64/assembler_x86_64.cc b/compiler/utils/x86_64/assembler_x86_64.cc index 78738d8..fe9349b 100644 --- a/compiler/utils/x86_64/assembler_x86_64.cc +++ b/compiler/utils/x86_64/assembler_x86_64.cc @@ -869,6 +869,22 @@ void X86_64Assembler::cmpq(CpuRegister reg0, CpuRegister reg1) { } +void X86_64Assembler::cmpq(CpuRegister reg, const Immediate& imm) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + CHECK(imm.is_int32()); // cmpq only supports 32b immediate. + EmitRex64(reg); + EmitComplex(7, Operand(reg), imm); +} + + +void X86_64Assembler::cmpq(CpuRegister reg, const Address& address) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitRex64(reg); + EmitUint8(0x3B); + EmitOperand(reg.LowBits(), address); +} + + void X86_64Assembler::addl(CpuRegister dst, CpuRegister src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitOptionalRex32(dst, src); @@ -1063,6 +1079,14 @@ void X86_64Assembler::addq(CpuRegister reg, const Immediate& imm) { } +void X86_64Assembler::addq(CpuRegister dst, const Address& address) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitRex64(dst); + EmitUint8(0x03); + EmitOperand(dst.LowBits(), address); +} + + void X86_64Assembler::addq(CpuRegister dst, CpuRegister src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); // 0x01 is addq r/m64 <- r/m64 + r64, with op1 in r/m and op2 in reg: so reverse EmitRex64 @@ -1118,6 +1142,14 @@ void X86_64Assembler::subq(CpuRegister dst, CpuRegister src) { } +void X86_64Assembler::subq(CpuRegister reg, const Address& address) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitRex64(reg); + EmitUint8(0x2B); + EmitOperand(reg.LowBits() & 7, address); +} + + void X86_64Assembler::subl(CpuRegister reg, const Address& address) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitOptionalRex32(reg, address); diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h index 7514854..330d2d5 100644 --- a/compiler/utils/x86_64/assembler_x86_64.h +++ b/compiler/utils/x86_64/assembler_x86_64.h @@ -385,6 +385,8 @@ class X86_64Assembler FINAL : public Assembler { void cmpl(const Address& address, const Immediate& imm); void cmpq(CpuRegister reg0, CpuRegister reg1); + void cmpq(CpuRegister reg0, const Immediate& imm); + void cmpq(CpuRegister reg0, const Address& address); void testl(CpuRegister reg1, CpuRegister reg2); void testl(CpuRegister reg, const Immediate& imm); @@ -408,6 +410,7 @@ class X86_64Assembler FINAL : public Assembler { void addq(CpuRegister reg, const Immediate& imm); void addq(CpuRegister dst, CpuRegister src); + void addq(CpuRegister dst, const Address& address); void subl(CpuRegister dst, CpuRegister src); void subl(CpuRegister reg, const Immediate& imm); @@ -415,6 +418,7 @@ class X86_64Assembler FINAL : public Assembler { void subq(CpuRegister reg, const Immediate& imm); void subq(CpuRegister dst, CpuRegister src); + void subq(CpuRegister dst, const Address& address); void cdq(); |