diff options
author | Roland Levillain <rpl@google.com> | 2014-10-28 11:21:22 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-10-28 11:21:22 +0000 |
commit | 4816ecfc1b2d544685ec5edcdeaad6870f6bfd7e (patch) | |
tree | 81af9c148bf1ac0806e193ac1958deb3bf4c7a9a | |
parent | d3271e8a48768ed53bfa2515474b57245e7d9a41 (diff) | |
parent | 705664321a5cc1418255172f92d7d7195cf60a7b (diff) | |
download | art-4816ecfc1b2d544685ec5edcdeaad6870f6bfd7e.zip art-4816ecfc1b2d544685ec5edcdeaad6870f6bfd7e.tar.gz art-4816ecfc1b2d544685ec5edcdeaad6870f6bfd7e.tar.bz2 |
Merge "Add long bitwise not instruction in the optimizing compiler."
-rw-r--r-- | compiler/optimizing/builder.cc | 5 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 5 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 7 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 2 | ||||
-rw-r--r-- | compiler/utils/x86_64/assembler_x86_64.cc | 9 | ||||
-rw-r--r-- | compiler/utils/x86_64/assembler_x86_64.h | 2 | ||||
-rw-r--r-- | test/416-optimizing-arith-not/expected.txt | 0 | ||||
-rw-r--r-- | test/416-optimizing-arith-not/info.txt | 1 | ||||
-rw-r--r-- | test/416-optimizing-arith-not/smali/not.smali | 15 | ||||
-rw-r--r-- | test/416-optimizing-arith-not/src/Main.java | 79 |
10 files changed, 120 insertions, 5 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index e4dee46..cc9c6c1 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -758,6 +758,11 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 break; } + case Instruction::NOT_LONG: { + Unop_12x<HNot>(instruction, Primitive::kPrimLong); + break; + } + case Instruction::ADD_INT: { Binop_23x<HAdd>(instruction, Primitive::kPrimInt); break; diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 4733432..7adf2cc 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -1411,7 +1411,10 @@ void InstructionCodeGeneratorARM::VisitNot(HNot* not_) { break; case Primitive::kPrimLong: - LOG(FATAL) << "Not yet implemented type for not operation " << not_->GetResultType(); + __ mvn(out.AsRegisterPairLow<Register>(), + ShifterOperand(in.AsRegisterPairLow<Register>())); + __ mvn(out.AsRegisterPairHigh<Register>(), + ShifterOperand(in.AsRegisterPairHigh<Register>())); break; default: diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index aa0f06b..99fa11d 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -1360,9 +1360,9 @@ void LocationsBuilderX86::VisitNot(HNot* not_) { void InstructionCodeGeneratorX86::VisitNot(HNot* not_) { LocationSummary* locations = not_->GetLocations(); - DCHECK_EQ(locations->InAt(0).As<Register>(), locations->Out().As<Register>()); + Location in = locations->InAt(0); Location out = locations->Out(); - DCHECK_EQ(locations->InAt(0).As<Register>(), out.As<Register>()); + DCHECK(in.Equals(out)); switch (not_->InputAt(0)->GetType()) { case Primitive::kPrimBoolean: __ xorl(out.As<Register>(), Immediate(1)); @@ -1373,7 +1373,8 @@ void InstructionCodeGeneratorX86::VisitNot(HNot* not_) { break; case Primitive::kPrimLong: - LOG(FATAL) << "Not yet implemented type for not operation " << not_->GetResultType(); + __ notl(out.AsRegisterPairLow<Register>()); + __ notl(out.AsRegisterPairHigh<Register>()); break; default: diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 892ca9d..163156a 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -1299,7 +1299,7 @@ void InstructionCodeGeneratorX86_64::VisitNot(HNot* not_) { break; case Primitive::kPrimLong: - LOG(FATAL) << "Not yet implemented type for not operation " << not_->GetResultType(); + __ notq(out.As<CpuRegister>()); break; default: diff --git a/compiler/utils/x86_64/assembler_x86_64.cc b/compiler/utils/x86_64/assembler_x86_64.cc index bf58b16..2e951dd 100644 --- a/compiler/utils/x86_64/assembler_x86_64.cc +++ b/compiler/utils/x86_64/assembler_x86_64.cc @@ -1340,6 +1340,7 @@ void X86_64Assembler::negl(CpuRegister reg) { EmitOperand(3, Operand(reg)); } + void X86_64Assembler::negq(CpuRegister reg) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitRex64(reg); @@ -1356,6 +1357,14 @@ void X86_64Assembler::notl(CpuRegister reg) { } +void X86_64Assembler::notq(CpuRegister reg) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitRex64(reg); + EmitUint8(0xF7); + EmitOperand(2, Operand(reg)); +} + + void X86_64Assembler::enter(const Immediate& imm) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0xC8); diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h index ec29271..2de3ce5 100644 --- a/compiler/utils/x86_64/assembler_x86_64.h +++ b/compiler/utils/x86_64/assembler_x86_64.h @@ -451,7 +451,9 @@ class X86_64Assembler FINAL : public Assembler { void negl(CpuRegister reg); void negq(CpuRegister reg); + void notl(CpuRegister reg); + void notq(CpuRegister reg); void enter(const Immediate& imm); void leave(); diff --git a/test/416-optimizing-arith-not/expected.txt b/test/416-optimizing-arith-not/expected.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/416-optimizing-arith-not/expected.txt diff --git a/test/416-optimizing-arith-not/info.txt b/test/416-optimizing-arith-not/info.txt new file mode 100644 index 0000000..e9418fd --- /dev/null +++ b/test/416-optimizing-arith-not/info.txt @@ -0,0 +1 @@ +Tests for bitwise not operations. diff --git a/test/416-optimizing-arith-not/smali/not.smali b/test/416-optimizing-arith-not/smali/not.smali new file mode 100644 index 0000000..6dea3b6 --- /dev/null +++ b/test/416-optimizing-arith-not/smali/not.smali @@ -0,0 +1,15 @@ +.class public LTestNot; + +.super Ljava/lang/Object; + +.method public static $opt$NotInt(I)I + .registers 2 + not-int v0, v1 + return v0 +.end method + +.method public static $opt$NotLong(J)J + .registers 4 + not-long v0, v2 + return-wide v0 +.end method diff --git a/test/416-optimizing-arith-not/src/Main.java b/test/416-optimizing-arith-not/src/Main.java new file mode 100644 index 0000000..26e206c --- /dev/null +++ b/test/416-optimizing-arith-not/src/Main.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Method; + +public class Main { + + public static void expectEquals(int expected, int result) { + if (expected != result) { + throw new Error("Expected: " + expected + ", found: " + result); + } + } + + public static void expectEquals(long expected, long result) { + if (expected != result) { + throw new Error("Expected: " + expected + ", found: " + result); + } + } + + public static void main(String[] args) throws Exception { + notInt(); + notLong(); + } + + private static void notInt() throws Exception { + expectEquals(1, smaliNotInt(-2)); + expectEquals(0, smaliNotInt(-1)); + expectEquals(-1, smaliNotInt(0)); + expectEquals(-2, smaliNotInt(1)); + expectEquals(2147483647, smaliNotInt(-2147483648)); // (2^31) - 1 + expectEquals(2147483646, smaliNotInt(-2147483647)); // (2^31) - 2 + expectEquals(-2147483647, smaliNotInt(2147483646)); // -(2^31) - 1 + expectEquals(-2147483648, smaliNotInt(2147483647)); // -(2^31) + } + + private static void notLong() throws Exception { + expectEquals(1L, smaliNotLong(-2L)); + expectEquals(0L, smaliNotLong(-1L)); + expectEquals(-1L, smaliNotLong(0L)); + expectEquals(-2L, smaliNotLong(1L)); + expectEquals(2147483647L, smaliNotLong(-2147483648L)); // (2^31) - 1 + expectEquals(2147483646L, smaliNotLong(-2147483647L)); // (2^31) - 2 + expectEquals(-2147483647L, smaliNotLong(2147483646L)); // -(2^31) - 1 + expectEquals(-2147483648L, smaliNotLong(2147483647L)); // -(2^31) + expectEquals(9223372036854775807L, smaliNotLong(-9223372036854775808L)); // (2^63) - 1 + expectEquals(9223372036854775806L, smaliNotLong(-9223372036854775807L)); // (2^63) - 2 + expectEquals(-9223372036854775807L, smaliNotLong(9223372036854775806L)); // -(2^63) - 1 + expectEquals(-9223372036854775808L, smaliNotLong(9223372036854775807L)); // -(2^63) + } + + // Wrappers around methods located in file not.smali. + + private static int smaliNotInt(int a) throws Exception { + Class<?> c = Class.forName("TestNot"); + Method m = c.getMethod("$opt$NotInt", int.class); + int result = (Integer)m.invoke(null, a); + return result; + } + + private static long smaliNotLong(long a) throws Exception { + Class<?> c = Class.forName("TestNot"); + Method m = c.getMethod("$opt$NotLong", long.class); + long result = (Long)m.invoke(null, a); + return result; + } +} |