diff options
author | Roland Levillain <rpl@google.com> | 2014-10-22 18:06:21 +0100 |
---|---|---|
committer | Roland Levillain <rpl@google.com> | 2014-10-23 10:12:06 +0100 |
commit | 1cc5f251df558b0e22cea5000626365eb644c727 (patch) | |
tree | 5e65a32366261646edce02283a185928adba79b5 /compiler/optimizing/code_generator_arm.cc | |
parent | b08f4dcf90215ed49e0b796ab3e609bd605be8ba (diff) | |
download | android_art-1cc5f251df558b0e22cea5000626365eb644c727.tar.gz android_art-1cc5f251df558b0e22cea5000626365eb644c727.tar.bz2 android_art-1cc5f251df558b0e22cea5000626365eb644c727.zip |
Implement int bit-wise not operation in the optimizing compiler.
- Add support for the not-int (integer one's complement
negate) instruction in the optimizing compiler.
- Extend the HNot control-flow graph node type and make it
inherit from HUnaryOperation.
- Generate ARM, x86 and x86-64 code for integer HNeg nodes.
- Exercise these additions in the codegen_test gtest, as there
is not direct way to assess the support of not-int from a
Java source. Indeed, compiling a Java expression such as
`~a' using javac and then dx generates an xor-int/lit8 Dex
instruction instead of the expected not-int Dex instruction.
This is probably because the Java bytecode has an `ixor'
instruction, but there's not instruction directly
corresponding to a bit-wise not operation.
Change-Id: I223aed75c4dac5785e04d99da0d22e8d699aee2b
Diffstat (limited to 'compiler/optimizing/code_generator_arm.cc')
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 7ed802ec7b..b042beb795 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -1351,17 +1351,33 @@ void InstructionCodeGeneratorARM::VisitParameterValue(HParameterValue* instructi // Nothing to do, the parameter is already at its location. } -void LocationsBuilderARM::VisitNot(HNot* instruction) { +void LocationsBuilderARM::VisitNot(HNot* not_) { LocationSummary* locations = - new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall); + new (GetGraph()->GetArena()) LocationSummary(not_, LocationSummary::kNoCall); locations->SetInAt(0, Location::RequiresRegister()); locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); } -void InstructionCodeGeneratorARM::VisitNot(HNot* instruction) { - LocationSummary* locations = instruction->GetLocations(); - __ eor(locations->Out().As<Register>(), - locations->InAt(0).As<Register>(), ShifterOperand(1)); +void InstructionCodeGeneratorARM::VisitNot(HNot* not_) { + LocationSummary* locations = not_->GetLocations(); + Location out = locations->Out(); + Location in = locations->InAt(0); + switch (not_->InputAt(0)->GetType()) { + case Primitive::kPrimBoolean: + __ eor(out.As<Register>(), in.As<Register>(), ShifterOperand(1)); + break; + + case Primitive::kPrimInt: + __ mvn(out.As<Register>(), ShifterOperand(in.As<Register>())); + break; + + case Primitive::kPrimLong: + LOG(FATAL) << "Not yet implemented type for not operation " << not_->GetResultType(); + break; + + default: + LOG(FATAL) << "Unimplemented type for not operation " << not_->GetResultType(); + } } void LocationsBuilderARM::VisitCompare(HCompare* compare) { |