Merge "ART: Extend list of instructions accepted as boolean inputs"
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index f7fa5db..8ab759d 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -36,6 +36,80 @@
namespace art {
+// Return whether a location is consistent with a type.
+static bool CheckType(Primitive::Type type, Location location) {
+ if (location.IsFpuRegister()
+ || (location.IsUnallocated() && (location.GetPolicy() == Location::kRequiresFpuRegister))) {
+ return (type == Primitive::kPrimFloat) || (type == Primitive::kPrimDouble);
+ } else if (location.IsRegister() ||
+ (location.IsUnallocated() && (location.GetPolicy() == Location::kRequiresRegister))) {
+ return Primitive::IsIntegralType(type) || (type == Primitive::kPrimNot);
+ } else if (location.IsRegisterPair()) {
+ return type == Primitive::kPrimLong;
+ } else if (location.IsFpuRegisterPair()) {
+ return type == Primitive::kPrimDouble;
+ } else if (location.IsStackSlot()) {
+ return (Primitive::IsIntegralType(type) && type != Primitive::kPrimLong)
+ || (type == Primitive::kPrimFloat)
+ || (type == Primitive::kPrimNot);
+ } else if (location.IsDoubleStackSlot()) {
+ return (type == Primitive::kPrimLong) || (type == Primitive::kPrimDouble);
+ } else if (location.IsConstant()) {
+ if (location.GetConstant()->IsIntConstant()) {
+ return Primitive::IsIntegralType(type) && (type != Primitive::kPrimLong);
+ } else if (location.GetConstant()->IsNullConstant()) {
+ return type == Primitive::kPrimNot;
+ } else if (location.GetConstant()->IsLongConstant()) {
+ return type == Primitive::kPrimLong;
+ } else if (location.GetConstant()->IsFloatConstant()) {
+ return type == Primitive::kPrimFloat;
+ } else {
+ return location.GetConstant()->IsDoubleConstant()
+ && (type == Primitive::kPrimDouble);
+ }
+ } else {
+ return location.IsInvalid() || (location.GetPolicy() == Location::kAny);
+ }
+}
+
+// Check that a location summary is consistent with an instruction.
+static bool CheckTypeConsistency(HInstruction* instruction) {
+ LocationSummary* locations = instruction->GetLocations();
+ if (locations == nullptr) {
+ return true;
+ }
+
+ if (locations->Out().IsUnallocated()
+ && (locations->Out().GetPolicy() == Location::kSameAsFirstInput)) {
+ DCHECK(CheckType(instruction->GetType(), locations->InAt(0)))
+ << instruction->GetType()
+ << " " << locations->InAt(0);
+ } else {
+ DCHECK(CheckType(instruction->GetType(), locations->Out()))
+ << instruction->GetType()
+ << " " << locations->Out();
+ }
+
+ for (size_t i = 0, e = instruction->InputCount(); i < e; ++i) {
+ DCHECK(CheckType(instruction->InputAt(i)->GetType(), locations->InAt(i)))
+ << instruction->InputAt(i)->GetType()
+ << " " << locations->InAt(i);
+ }
+
+ HEnvironment* environment = instruction->GetEnvironment();
+ for (size_t i = 0; i < instruction->EnvironmentSize(); ++i) {
+ if (environment->GetInstructionAt(i) != nullptr) {
+ Primitive::Type type = environment->GetInstructionAt(i)->GetType();
+ DCHECK(CheckType(type, locations->GetEnvironmentAt(i)))
+ << type << " " << locations->GetEnvironmentAt(i);
+ } else {
+ DCHECK(locations->GetEnvironmentAt(i).IsInvalid())
+ << locations->GetEnvironmentAt(i);
+ }
+ }
+ return true;
+}
+
size_t CodeGenerator::GetCacheOffset(uint32_t index) {
return mirror::ObjectArray<mirror::Object>::OffsetOfElement(index).SizeValue();
}
@@ -95,6 +169,7 @@
if (is_baseline) {
InitLocationsBaseline(current);
}
+ DCHECK(CheckTypeConsistency(current));
current->Accept(instruction_visitor);
}
}
@@ -347,6 +422,7 @@
void CodeGenerator::AllocateLocations(HInstruction* instruction) {
instruction->Accept(GetLocationBuilder());
+ DCHECK(CheckTypeConsistency(instruction));
LocationSummary* locations = instruction->GetLocations();
if (!instruction->IsSuspendCheckEntry()) {
if (locations != nullptr && locations->CanCall()) {
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 2ea9203..7e03865 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -2826,10 +2826,14 @@
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
locations->SetInAt(0, Location::RequiresRegister());
- locations->SetInAt(1, Location::RequiresRegister());
-
Primitive::Type field_type = field_info.GetFieldType();
+ if (Primitive::IsFloatingPointType(field_type)) {
+ locations->SetInAt(1, Location::RequiresFpuRegister());
+ } else {
+ locations->SetInAt(1, Location::RequiresRegister());
+ }
+
bool is_wide = field_type == Primitive::kPrimLong || field_type == Primitive::kPrimDouble;
bool generate_volatile = field_info.IsVolatile()
&& is_wide
@@ -2965,8 +2969,13 @@
&& (field_info.GetFieldType() == Primitive::kPrimDouble)
&& !codegen_->GetInstructionSetFeatures().HasAtomicLdrdAndStrd();
bool overlap = field_info.IsVolatile() && (field_info.GetFieldType() == Primitive::kPrimLong);
- locations->SetOut(Location::RequiresRegister(),
- (overlap ? Location::kOutputOverlap : Location::kNoOutputOverlap));
+
+ if (Primitive::IsFloatingPointType(instruction->GetType())) {
+ locations->SetOut(Location::RequiresFpuRegister());
+ } else {
+ locations->SetOut(Location::RequiresRegister(),
+ (overlap ? Location::kOutputOverlap : Location::kNoOutputOverlap));
+ }
if (volatile_for_double) {
// Arm encoding have some additional constraints for ldrexd/strexd:
// - registers need to be consecutive
@@ -3139,7 +3148,11 @@
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
locations->SetInAt(0, Location::RequiresRegister());
locations->SetInAt(1, Location::RegisterOrConstant(instruction->InputAt(1)));
- locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+ if (Primitive::IsFloatingPointType(instruction->GetType())) {
+ locations->SetOut(Location::RequiresFpuRegister(), Location::kNoOutputOverlap);
+ } else {
+ locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+ }
}
void InstructionCodeGeneratorARM::VisitArrayGet(HArrayGet* instruction) {
@@ -3286,7 +3299,11 @@
} else {
locations->SetInAt(0, Location::RequiresRegister());
locations->SetInAt(1, Location::RegisterOrConstant(instruction->InputAt(1)));
- locations->SetInAt(2, Location::RequiresRegister());
+ if (Primitive::IsFloatingPointType(value_type)) {
+ locations->SetInAt(2, Location::RequiresFpuRegister());
+ } else {
+ locations->SetInAt(2, Location::RequiresRegister());
+ }
if (needs_write_barrier) {
// Temporary registers for the write barrier.
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index efc41e7..4be4612 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -1250,7 +1250,11 @@
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
locations->SetInAt(0, Location::RequiresRegister());
locations->SetInAt(1, Location::RegisterOrConstant(instruction->InputAt(1)));
- locations->SetOut(Location::RequiresRegister());
+ if (Primitive::IsFloatingPointType(instruction->GetType())) {
+ locations->SetOut(Location::RequiresFpuRegister(), Location::kNoOutputOverlap);
+ } else {
+ locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+ }
}
void InstructionCodeGeneratorARM64::VisitArrayGet(HArrayGet* instruction) {
@@ -1301,7 +1305,11 @@
} else {
locations->SetInAt(0, Location::RequiresRegister());
locations->SetInAt(1, Location::RegisterOrConstant(instruction->InputAt(1)));
- locations->SetInAt(2, Location::RequiresRegister());
+ if (Primitive::IsFloatingPointType(instruction->InputAt(2)->GetType())) {
+ locations->SetInAt(2, Location::RequiresFpuRegister());
+ } else {
+ locations->SetInAt(2, Location::RequiresRegister());
+ }
}
}
@@ -1745,7 +1753,11 @@
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
locations->SetInAt(0, Location::RequiresRegister());
- locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+ if (Primitive::IsFloatingPointType(instruction->GetType())) {
+ locations->SetOut(Location::RequiresFpuRegister());
+ } else {
+ locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+ }
}
void InstructionCodeGeneratorARM64::VisitInstanceFieldGet(HInstanceFieldGet* instruction) {
@@ -1772,7 +1784,11 @@
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
locations->SetInAt(0, Location::RequiresRegister());
- locations->SetInAt(1, Location::RequiresRegister());
+ if (Primitive::IsFloatingPointType(instruction->InputAt(1)->GetType())) {
+ locations->SetInAt(1, Location::RequiresFpuRegister());
+ } else {
+ locations->SetInAt(1, Location::RequiresRegister());
+ }
}
void InstructionCodeGeneratorARM64::VisitInstanceFieldSet(HInstanceFieldSet* instruction) {
@@ -2506,7 +2522,11 @@
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
locations->SetInAt(0, Location::RequiresRegister());
- locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+ if (Primitive::IsFloatingPointType(instruction->GetType())) {
+ locations->SetOut(Location::RequiresFpuRegister());
+ } else {
+ locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+ }
}
void InstructionCodeGeneratorARM64::VisitStaticFieldGet(HStaticFieldGet* instruction) {
@@ -2531,7 +2551,11 @@
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
locations->SetInAt(0, Location::RequiresRegister());
- locations->SetInAt(1, Location::RequiresRegister());
+ if (Primitive::IsFloatingPointType(instruction->InputAt(1)->GetType())) {
+ locations->SetInAt(1, Location::RequiresFpuRegister());
+ } else {
+ locations->SetInAt(1, Location::RequiresRegister());
+ }
}
void InstructionCodeGeneratorARM64::VisitStaticFieldSet(HStaticFieldSet* instruction) {
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 879216d..0f11755 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -3119,11 +3119,15 @@
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
locations->SetInAt(0, Location::RequiresRegister());
- // The output overlaps in case of long: we don't want the low move to overwrite
- // the object's location.
- locations->SetOut(Location::RequiresRegister(),
- (instruction->GetType() == Primitive::kPrimLong) ? Location::kOutputOverlap
- : Location::kNoOutputOverlap);
+ if (Primitive::IsFloatingPointType(instruction->GetType())) {
+ locations->SetOut(Location::RequiresFpuRegister());
+ } else {
+ // The output overlaps in case of long: we don't want the low move to overwrite
+ // the object's location.
+ locations->SetOut(Location::RequiresRegister(),
+ (instruction->GetType() == Primitive::kPrimLong) ? Location::kOutputOverlap
+ : Location::kNoOutputOverlap);
+ }
if (field_info.IsVolatile() && (field_info.GetFieldType() == Primitive::kPrimLong)) {
// Long values can be loaded atomically into an XMM using movsd.
@@ -3229,6 +3233,8 @@
if (is_byte_type) {
// Ensure the value is in a byte register.
locations->SetInAt(1, Location::RegisterLocation(EAX));
+ } else if (Primitive::IsFloatingPointType(field_type)) {
+ locations->SetInAt(1, Location::RequiresFpuRegister());
} else {
locations->SetInAt(1, Location::RequiresRegister());
}
@@ -3418,11 +3424,15 @@
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
locations->SetInAt(0, Location::RequiresRegister());
locations->SetInAt(1, Location::RegisterOrConstant(instruction->InputAt(1)));
- // The output overlaps in case of long: we don't want the low move to overwrite
- // the array's location.
- locations->SetOut(Location::RequiresRegister(),
- (instruction->GetType() == Primitive::kPrimLong) ? Location::kOutputOverlap
- : Location::kNoOutputOverlap);
+ if (Primitive::IsFloatingPointType(instruction->GetType())) {
+ locations->SetOut(Location::RequiresFpuRegister(), Location::kNoOutputOverlap);
+ } else {
+ // The output overlaps in case of long: we don't want the low move to overwrite
+ // the array's location.
+ locations->SetOut(Location::RequiresRegister(),
+ (instruction->GetType() == Primitive::kPrimLong) ? Location::kOutputOverlap
+ : Location::kNoOutputOverlap);
+ }
}
void InstructionCodeGeneratorX86::VisitArrayGet(HArrayGet* instruction) {
@@ -3578,14 +3588,10 @@
if (is_byte_type) {
// Ensure the value is in a byte register.
locations->SetInAt(2, Location::ByteRegisterOrConstant(EAX, instruction->InputAt(2)));
+ } else if (Primitive::IsFloatingPointType(value_type)) {
+ locations->SetInAt(2, Location::RequiresFpuRegister());
} else {
- bool is_fp_type = (value_type == Primitive::kPrimFloat)
- || (value_type == Primitive::kPrimDouble);
- if (is_fp_type) {
- locations->SetInAt(2, Location::RequiresFpuRegister());
- } else {
- locations->SetInAt(2, Location::RegisterOrConstant(instruction->InputAt(2)));
- }
+ locations->SetInAt(2, Location::RegisterOrConstant(instruction->InputAt(2)));
}
// Temporary registers for the write barrier.
if (needs_write_barrier) {
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index a3d3490..5b681fa 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -3035,7 +3035,11 @@
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
locations->SetInAt(0, Location::RequiresRegister());
- locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+ if (Primitive::IsFloatingPointType(instruction->GetType())) {
+ locations->SetOut(Location::RequiresFpuRegister());
+ } else {
+ locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+ }
}
void InstructionCodeGeneratorX86_64::HandleFieldGet(HInstruction* instruction,
@@ -3113,7 +3117,11 @@
CodeGenerator::StoreNeedsWriteBarrier(field_info.GetFieldType(), instruction->InputAt(1));
locations->SetInAt(0, Location::RequiresRegister());
- locations->SetInAt(1, Location::RequiresRegister());
+ if (Primitive::IsFloatingPointType(instruction->InputAt(1)->GetType())) {
+ locations->SetInAt(1, Location::RequiresFpuRegister());
+ } else {
+ locations->SetInAt(1, Location::RequiresRegister());
+ }
if (needs_write_barrier) {
// Temporary registers for the write barrier.
locations->AddTemp(Location::RequiresRegister());
@@ -3277,7 +3285,11 @@
locations->SetInAt(0, Location::RequiresRegister());
locations->SetInAt(
1, Location::RegisterOrConstant(instruction->InputAt(1)));
- locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+ if (Primitive::IsFloatingPointType(instruction->GetType())) {
+ locations->SetOut(Location::RequiresFpuRegister(), Location::kNoOutputOverlap);
+ } else {
+ locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+ }
}
void InstructionCodeGeneratorX86_64::VisitArrayGet(HArrayGet* instruction) {
diff --git a/compiler/optimizing/codegen_test.cc b/compiler/optimizing/codegen_test.cc
index afcff1e..94f56e5 100644
--- a/compiler/optimizing/codegen_test.cc
+++ b/compiler/optimizing/codegen_test.cc
@@ -18,8 +18,10 @@
#include "arch/instruction_set.h"
#include "arch/arm/instruction_set_features_arm.h"
+#include "arch/arm/registers_arm.h"
#include "arch/arm64/instruction_set_features_arm64.h"
#include "arch/x86/instruction_set_features_x86.h"
+#include "arch/x86/registers_x86.h"
#include "arch/x86_64/instruction_set_features_x86_64.h"
#include "base/macros.h"
#include "builder.h"
@@ -37,6 +39,8 @@
#include "register_allocator.h"
#include "ssa_liveness_analysis.h"
#include "utils.h"
+#include "utils/arm/managed_register_arm.h"
+#include "utils/x86/managed_register_x86.h"
#include "gtest/gtest.h"
@@ -53,17 +57,42 @@
const ArmInstructionSetFeatures& isa_features,
const CompilerOptions& compiler_options)
: arm::CodeGeneratorARM(graph, isa_features, compiler_options) {
- AddAllocatedRegister(Location::RegisterLocation(6));
- AddAllocatedRegister(Location::RegisterLocation(7));
+ AddAllocatedRegister(Location::RegisterLocation(arm::R6));
+ AddAllocatedRegister(Location::RegisterLocation(arm::R7));
}
void SetupBlockedRegisters(bool is_baseline) const OVERRIDE {
arm::CodeGeneratorARM::SetupBlockedRegisters(is_baseline);
- blocked_core_registers_[4] = true;
- blocked_core_registers_[6] = false;
- blocked_core_registers_[7] = false;
+ blocked_core_registers_[arm::R4] = true;
+ blocked_core_registers_[arm::R6] = false;
+ blocked_core_registers_[arm::R7] = false;
// Makes pair R6-R7 available.
- blocked_register_pairs_[6 >> 1] = false;
+ blocked_register_pairs_[arm::R6_R7] = false;
+ }
+};
+
+class TestCodeGeneratorX86 : public x86::CodeGeneratorX86 {
+ public:
+ TestCodeGeneratorX86(HGraph* graph,
+ const X86InstructionSetFeatures& isa_features,
+ const CompilerOptions& compiler_options)
+ : x86::CodeGeneratorX86(graph, isa_features, compiler_options) {
+ // Save edi, we need it for getting enough registers for long multiplication.
+ AddAllocatedRegister(Location::RegisterLocation(x86::EDI));
+ }
+
+ void SetupBlockedRegisters(bool is_baseline) const OVERRIDE {
+ x86::CodeGeneratorX86::SetupBlockedRegisters(is_baseline);
+ // ebx is a callee-save register in C, but caller-save for ART.
+ blocked_core_registers_[x86::EBX] = true;
+ blocked_register_pairs_[x86::EAX_EBX] = true;
+ blocked_register_pairs_[x86::EDX_EBX] = true;
+ blocked_register_pairs_[x86::ECX_EBX] = true;
+ blocked_register_pairs_[x86::EBX_EDI] = true;
+
+ // Make edi available.
+ blocked_core_registers_[x86::EDI] = false;
+ blocked_register_pairs_[x86::ECX_EDI] = false;
}
};
@@ -101,7 +130,7 @@
}
Expected result = f();
if (has_result) {
- ASSERT_EQ(result, expected);
+ ASSERT_EQ(expected, result);
}
}
@@ -112,7 +141,7 @@
CompilerOptions compiler_options;
std::unique_ptr<const X86InstructionSetFeatures> features_x86(
X86InstructionSetFeatures::FromCppDefines());
- x86::CodeGeneratorX86 codegenX86(graph, *features_x86.get(), compiler_options);
+ TestCodeGeneratorX86 codegenX86(graph, *features_x86.get(), compiler_options);
// We avoid doing a stack overflow check that requires the runtime being setup,
// by making sure the compiler knows the methods we are running are leaf methods.
codegenX86.CompileBaseline(&allocator, true);
@@ -520,29 +549,49 @@
RunCodeOptimized(graph, hook_before_codegen, true, 0);
}
-#define MUL_TEST(TYPE, TEST_NAME) \
- TEST(CodegenTest, Return ## TEST_NAME) { \
- const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( \
- Instruction::CONST_4 | 3 << 12 | 0, \
- Instruction::CONST_4 | 4 << 12 | 1 << 8, \
- Instruction::MUL_ ## TYPE, 1 << 8 | 0, \
- Instruction::RETURN); \
- \
- TestCode(data, true, 12); \
- } \
- \
- TEST(CodegenTest, Return ## TEST_NAME ## 2addr) { \
- const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( \
- Instruction::CONST_4 | 3 << 12 | 0, \
- Instruction::CONST_4 | 4 << 12 | 1 << 8, \
- Instruction::MUL_ ## TYPE ## _2ADDR | 1 << 12, \
- Instruction::RETURN); \
- \
- TestCode(data, true, 12); \
- }
+TEST(CodegenTest, ReturnMulInt) {
+ const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
+ Instruction::CONST_4 | 3 << 12 | 0,
+ Instruction::CONST_4 | 4 << 12 | 1 << 8,
+ Instruction::MUL_INT, 1 << 8 | 0,
+ Instruction::RETURN);
-MUL_TEST(INT, MulInt);
-MUL_TEST(LONG, MulLong);
+ TestCode(data, true, 12);
+}
+
+TEST(CodegenTest, ReturnMulInt2addr) {
+ const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
+ Instruction::CONST_4 | 3 << 12 | 0,
+ Instruction::CONST_4 | 4 << 12 | 1 << 8,
+ Instruction::MUL_INT_2ADDR | 1 << 12,
+ Instruction::RETURN);
+
+ TestCode(data, true, 12);
+}
+
+TEST(CodegenTest, ReturnMulLong) {
+ const uint16_t data[] = FOUR_REGISTERS_CODE_ITEM(
+ Instruction::CONST_4 | 3 << 12 | 0,
+ Instruction::CONST_4 | 0 << 12 | 1 << 8,
+ Instruction::CONST_4 | 4 << 12 | 2 << 8,
+ Instruction::CONST_4 | 0 << 12 | 3 << 8,
+ Instruction::MUL_LONG, 2 << 8 | 0,
+ Instruction::RETURN_WIDE);
+
+ TestCodeLong(data, true, 12);
+}
+
+TEST(CodegenTest, ReturnMulLong2addr) {
+ const uint16_t data[] = FOUR_REGISTERS_CODE_ITEM(
+ Instruction::CONST_4 | 3 << 12 | 0 << 8,
+ Instruction::CONST_4 | 0 << 12 | 1 << 8,
+ Instruction::CONST_4 | 4 << 12 | 2 << 8,
+ Instruction::CONST_4 | 0 << 12 | 3 << 8,
+ Instruction::MUL_LONG_2ADDR | 2 << 12,
+ Instruction::RETURN_WIDE);
+
+ TestCodeLong(data, true, 12);
+}
TEST(CodegenTest, ReturnMulIntLit8) {
const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
diff --git a/tools/run-jdwp-tests.sh b/tools/run-jdwp-tests.sh
index 90c01f5..e87ae08 100755
--- a/tools/run-jdwp-tests.sh
+++ b/tools/run-jdwp-tests.sh
@@ -19,11 +19,6 @@
exit 1
fi
-if [[ $ANDROID_SERIAL == 03a79ae90ae5889b ]] || [[ $ANDROID_SERIAL == HT4CTJT03670 ]] || [[ $ANDROID_SERIAL == HT49CJT00070 ]]; then
- echo "Not run because of localhost failures. Investigating."
- exit 0
-fi
-
# Jar containing all the tests.
test_jar=out/host/linux-x86/framework/apache-harmony-jdwp-tests-hostdex.jar
junit_jar=out/host/linux-x86/framework/junit.jar