summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2014-11-06 15:15:31 +0000
committerNicolas Geoffray <ngeoffray@google.com>2014-11-07 13:54:29 +0000
commit52e832b1278449e62d9eb502d54d5ff18f8606ed (patch)
tree14db2240db9d0cec5551f8588a5901bd1bc081fe /compiler/optimizing
parenteb71b3fc2a18ac649dc3743f4ec28f781932030a (diff)
downloadandroid_art-52e832b1278449e62d9eb502d54d5ff18f8606ed.tar.gz
android_art-52e832b1278449e62d9eb502d54d5ff18f8606ed.tar.bz2
android_art-52e832b1278449e62d9eb502d54d5ff18f8606ed.zip
Support floats and doubles in fields.
Change-Id: I19832106633405403f0461b3fe13b268abe39db3
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/builder.cc22
-rw-r--r--compiler/optimizing/builder.h5
-rw-r--r--compiler/optimizing/code_generator_arm.cc64
-rw-r--r--compiler/optimizing/code_generator_x86.cc64
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc88
5 files changed, 168 insertions, 75 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 64fb764937..fc7333fa25 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -64,10 +64,6 @@ class Temporaries : public ValueObject {
size_t index_;
};
-static bool IsTypeSupported(Primitive::Type type) {
- return type != Primitive::kPrimFloat && type != Primitive::kPrimDouble;
-}
-
void HGraphBuilder::InitializeLocals(uint16_t count) {
graph_->SetNumberOfVRegs(count);
locals_.SetSize(count);
@@ -78,10 +74,10 @@ void HGraphBuilder::InitializeLocals(uint16_t count) {
}
}
-bool HGraphBuilder::InitializeParameters(uint16_t number_of_parameters) {
+void HGraphBuilder::InitializeParameters(uint16_t number_of_parameters) {
// dex_compilation_unit_ is null only when unit testing.
if (dex_compilation_unit_ == nullptr) {
- return true;
+ return;
}
graph_->SetNumberOfInVRegs(number_of_parameters);
@@ -116,7 +112,6 @@ bool HGraphBuilder::InitializeParameters(uint16_t number_of_parameters) {
parameter_index++;
}
}
- return true;
}
template<typename T>
@@ -195,9 +190,7 @@ HGraph* HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) {
}
}
- if (!InitializeParameters(code_item.ins_size_)) {
- return nullptr;
- }
+ InitializeParameters(code_item.ins_size_);
size_t dex_offset = 0;
while (code_ptr < code_end) {
@@ -456,9 +449,6 @@ bool HGraphBuilder::BuildInstanceFieldAccess(const Instruction& instruction,
}
Primitive::Type field_type = resolved_field->GetTypeAsPrimitiveType();
- if (!IsTypeSupported(field_type)) {
- return false;
- }
HInstruction* object = LoadLocal(obj_reg, Primitive::kPrimNot);
current_block_->AddInstruction(new (arena_) HNullCheck(object, dex_offset));
@@ -516,10 +506,6 @@ bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction,
return false;
}
- if (!IsTypeSupported(field_type)) {
- return false;
- }
-
HLoadClass* constant = new (arena_) HLoadClass(
storage_index, is_referrers_class, dex_offset);
current_block_->AddInstruction(constant);
@@ -574,8 +560,6 @@ void HGraphBuilder::BuildArrayAccess(const Instruction& instruction,
uint8_t array_reg = instruction.VRegB_23x();
uint8_t index_reg = instruction.VRegC_23x();
- DCHECK(IsTypeSupported(anticipated_type));
-
// We need one temporary for the null check, one for the index, and one for the length.
Temporaries temps(graph_, 3);
diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h
index 030f45b609..09c9a51260 100644
--- a/compiler/optimizing/builder.h
+++ b/compiler/optimizing/builder.h
@@ -93,10 +93,7 @@ class HGraphBuilder : public ValueObject {
void UpdateLocal(int register_index, HInstruction* instruction) const;
HInstruction* LoadLocal(int register_index, Primitive::Type type) const;
void PotentiallyAddSuspendCheck(int32_t target_offset, uint32_t dex_offset);
-
- // Temporarily returns whether the compiler supports the parameters
- // of the method.
- bool InitializeParameters(uint16_t number_of_parameters);
+ void InitializeParameters(uint16_t number_of_parameters);
template<typename T>
void Unop_12x(const Instruction& instruction, Primitive::Type type);
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index fef7f0e80f..a031ce3389 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -1826,10 +1826,18 @@ void InstructionCodeGeneratorARM::VisitInstanceFieldSet(HInstanceFieldSet* instr
break;
}
- case Primitive::kPrimFloat:
- case Primitive::kPrimDouble:
- LOG(FATAL) << "Unimplemented register type " << field_type;
- UNREACHABLE();
+ case Primitive::kPrimFloat: {
+ SRegister value = locations->InAt(1).As<SRegister>();
+ __ StoreSToOffset(value, obj, offset);
+ break;
+ }
+
+ case Primitive::kPrimDouble: {
+ DRegister value = FromLowSToD(locations->InAt(1).AsFpuRegisterPairLow<SRegister>());
+ __ StoreDToOffset(value, obj, offset);
+ break;
+ }
+
case Primitive::kPrimVoid:
LOG(FATAL) << "Unreachable type " << field_type;
UNREACHABLE();
@@ -1887,10 +1895,18 @@ void InstructionCodeGeneratorARM::VisitInstanceFieldGet(HInstanceFieldGet* instr
break;
}
- case Primitive::kPrimFloat:
- case Primitive::kPrimDouble:
- LOG(FATAL) << "Unimplemented register type " << instruction->GetType();
- UNREACHABLE();
+ case Primitive::kPrimFloat: {
+ SRegister out = locations->Out().As<SRegister>();
+ __ LoadSFromOffset(out, obj, offset);
+ break;
+ }
+
+ case Primitive::kPrimDouble: {
+ DRegister out = FromLowSToD(locations->Out().AsFpuRegisterPairLow<SRegister>());
+ __ LoadDFromOffset(out, obj, offset);
+ break;
+ }
+
case Primitive::kPrimVoid:
LOG(FATAL) << "Unreachable type " << instruction->GetType();
UNREACHABLE();
@@ -2424,10 +2440,18 @@ void InstructionCodeGeneratorARM::VisitStaticFieldGet(HStaticFieldGet* instructi
break;
}
- case Primitive::kPrimFloat:
- case Primitive::kPrimDouble:
- LOG(FATAL) << "Unimplemented register type " << instruction->GetType();
- UNREACHABLE();
+ case Primitive::kPrimFloat: {
+ SRegister out = locations->Out().As<SRegister>();
+ __ LoadSFromOffset(out, cls, offset);
+ break;
+ }
+
+ case Primitive::kPrimDouble: {
+ DRegister out = FromLowSToD(locations->Out().AsFpuRegisterPairLow<SRegister>());
+ __ LoadDFromOffset(out, cls, offset);
+ break;
+ }
+
case Primitive::kPrimVoid:
LOG(FATAL) << "Unreachable type " << instruction->GetType();
UNREACHABLE();
@@ -2486,10 +2510,18 @@ void InstructionCodeGeneratorARM::VisitStaticFieldSet(HStaticFieldSet* instructi
break;
}
- case Primitive::kPrimFloat:
- case Primitive::kPrimDouble:
- LOG(FATAL) << "Unimplemented register type " << field_type;
- UNREACHABLE();
+ case Primitive::kPrimFloat: {
+ SRegister value = locations->InAt(1).As<SRegister>();
+ __ StoreSToOffset(value, cls, offset);
+ break;
+ }
+
+ case Primitive::kPrimDouble: {
+ DRegister value = FromLowSToD(locations->InAt(1).AsFpuRegisterPairLow<SRegister>());
+ __ StoreDToOffset(value, cls, offset);
+ break;
+ }
+
case Primitive::kPrimVoid:
LOG(FATAL) << "Unreachable type " << field_type;
UNREACHABLE();
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 127ddbeab1..54a12fdee0 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -1844,10 +1844,18 @@ void InstructionCodeGeneratorX86::VisitInstanceFieldSet(HInstanceFieldSet* instr
break;
}
- case Primitive::kPrimFloat:
- case Primitive::kPrimDouble:
- LOG(FATAL) << "Unimplemented register type " << field_type;
- UNREACHABLE();
+ case Primitive::kPrimFloat: {
+ XmmRegister value = locations->InAt(1).As<XmmRegister>();
+ __ movss(Address(obj, offset), value);
+ break;
+ }
+
+ case Primitive::kPrimDouble: {
+ XmmRegister value = locations->InAt(1).As<XmmRegister>();
+ __ movsd(Address(obj, offset), value);
+ break;
+ }
+
case Primitive::kPrimVoid:
LOG(FATAL) << "Unreachable type " << field_type;
UNREACHABLE();
@@ -1917,10 +1925,18 @@ void InstructionCodeGeneratorX86::VisitInstanceFieldGet(HInstanceFieldGet* instr
break;
}
- case Primitive::kPrimFloat:
- case Primitive::kPrimDouble:
- LOG(FATAL) << "Unimplemented register type " << instruction->GetType();
- UNREACHABLE();
+ case Primitive::kPrimFloat: {
+ XmmRegister out = locations->Out().As<XmmRegister>();
+ __ movss(out, Address(obj, offset));
+ break;
+ }
+
+ case Primitive::kPrimDouble: {
+ XmmRegister out = locations->Out().As<XmmRegister>();
+ __ movsd(out, Address(obj, offset));
+ break;
+ }
+
case Primitive::kPrimVoid:
LOG(FATAL) << "Unreachable type " << instruction->GetType();
UNREACHABLE();
@@ -2508,10 +2524,18 @@ void InstructionCodeGeneratorX86::VisitStaticFieldGet(HStaticFieldGet* instructi
break;
}
- case Primitive::kPrimFloat:
- case Primitive::kPrimDouble:
- LOG(FATAL) << "Unimplemented register type " << instruction->GetType();
- UNREACHABLE();
+ case Primitive::kPrimFloat: {
+ XmmRegister out = locations->Out().As<XmmRegister>();
+ __ movss(out, Address(cls, offset));
+ break;
+ }
+
+ case Primitive::kPrimDouble: {
+ XmmRegister out = locations->Out().As<XmmRegister>();
+ __ movsd(out, Address(cls, offset));
+ break;
+ }
+
case Primitive::kPrimVoid:
LOG(FATAL) << "Unreachable type " << instruction->GetType();
UNREACHABLE();
@@ -2583,10 +2607,18 @@ void InstructionCodeGeneratorX86::VisitStaticFieldSet(HStaticFieldSet* instructi
break;
}
- case Primitive::kPrimFloat:
- case Primitive::kPrimDouble:
- LOG(FATAL) << "Unimplemented register type " << field_type;
- UNREACHABLE();
+ case Primitive::kPrimFloat: {
+ XmmRegister value = locations->InAt(1).As<XmmRegister>();
+ __ movss(Address(cls, offset), value);
+ break;
+ }
+
+ case Primitive::kPrimDouble: {
+ XmmRegister value = locations->InAt(1).As<XmmRegister>();
+ __ movsd(Address(cls, offset), value);
+ break;
+ }
+
case Primitive::kPrimVoid:
LOG(FATAL) << "Unreachable type " << field_type;
UNREACHABLE();
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 8c0842cb89..9237cc3a4d 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -1692,25 +1692,27 @@ void LocationsBuilderX86_64::VisitInstanceFieldSet(HInstanceFieldSet* instructio
void InstructionCodeGeneratorX86_64::VisitInstanceFieldSet(HInstanceFieldSet* instruction) {
LocationSummary* locations = instruction->GetLocations();
CpuRegister obj = locations->InAt(0).As<CpuRegister>();
- CpuRegister value = locations->InAt(1).As<CpuRegister>();
size_t offset = instruction->GetFieldOffset().SizeValue();
Primitive::Type field_type = instruction->GetFieldType();
switch (field_type) {
case Primitive::kPrimBoolean:
case Primitive::kPrimByte: {
+ CpuRegister value = locations->InAt(1).As<CpuRegister>();
__ movb(Address(obj, offset), value);
break;
}
case Primitive::kPrimShort:
case Primitive::kPrimChar: {
+ CpuRegister value = locations->InAt(1).As<CpuRegister>();
__ movw(Address(obj, offset), value);
break;
}
case Primitive::kPrimInt:
case Primitive::kPrimNot: {
+ CpuRegister value = locations->InAt(1).As<CpuRegister>();
__ movl(Address(obj, offset), value);
if (field_type == Primitive::kPrimNot) {
CpuRegister temp = locations->GetTemp(0).As<CpuRegister>();
@@ -1721,14 +1723,23 @@ void InstructionCodeGeneratorX86_64::VisitInstanceFieldSet(HInstanceFieldSet* in
}
case Primitive::kPrimLong: {
+ CpuRegister value = locations->InAt(1).As<CpuRegister>();
__ movq(Address(obj, offset), value);
break;
}
- case Primitive::kPrimFloat:
- case Primitive::kPrimDouble:
- LOG(FATAL) << "Unimplemented register type " << field_type;
- UNREACHABLE();
+ case Primitive::kPrimFloat: {
+ XmmRegister value = locations->InAt(1).As<XmmRegister>();
+ __ movss(Address(obj, offset), value);
+ break;
+ }
+
+ case Primitive::kPrimDouble: {
+ XmmRegister value = locations->InAt(1).As<XmmRegister>();
+ __ movsd(Address(obj, offset), value);
+ break;
+ }
+
case Primitive::kPrimVoid:
LOG(FATAL) << "Unreachable type " << field_type;
UNREACHABLE();
@@ -1745,45 +1756,58 @@ void LocationsBuilderX86_64::VisitInstanceFieldGet(HInstanceFieldGet* instructio
void InstructionCodeGeneratorX86_64::VisitInstanceFieldGet(HInstanceFieldGet* instruction) {
LocationSummary* locations = instruction->GetLocations();
CpuRegister obj = locations->InAt(0).As<CpuRegister>();
- CpuRegister out = locations->Out().As<CpuRegister>();
size_t offset = instruction->GetFieldOffset().SizeValue();
switch (instruction->GetType()) {
case Primitive::kPrimBoolean: {
+ CpuRegister out = locations->Out().As<CpuRegister>();
__ movzxb(out, Address(obj, offset));
break;
}
case Primitive::kPrimByte: {
+ CpuRegister out = locations->Out().As<CpuRegister>();
__ movsxb(out, Address(obj, offset));
break;
}
case Primitive::kPrimShort: {
+ CpuRegister out = locations->Out().As<CpuRegister>();
__ movsxw(out, Address(obj, offset));
break;
}
case Primitive::kPrimChar: {
+ CpuRegister out = locations->Out().As<CpuRegister>();
__ movzxw(out, Address(obj, offset));
break;
}
case Primitive::kPrimInt:
case Primitive::kPrimNot: {
+ CpuRegister out = locations->Out().As<CpuRegister>();
__ movl(out, Address(obj, offset));
break;
}
case Primitive::kPrimLong: {
+ CpuRegister out = locations->Out().As<CpuRegister>();
__ movq(out, Address(obj, offset));
break;
}
- case Primitive::kPrimFloat:
- case Primitive::kPrimDouble:
- LOG(FATAL) << "Unimplemented register type " << instruction->GetType();
- UNREACHABLE();
+ case Primitive::kPrimFloat: {
+ XmmRegister out = locations->Out().As<XmmRegister>();
+ __ movss(out, Address(obj, offset));
+ break;
+ }
+
+ case Primitive::kPrimDouble: {
+ XmmRegister out = locations->Out().As<XmmRegister>();
+ __ movsd(out, Address(obj, offset));
+ break;
+ }
+
case Primitive::kPrimVoid:
LOG(FATAL) << "Unreachable type " << instruction->GetType();
UNREACHABLE();
@@ -2460,45 +2484,58 @@ void LocationsBuilderX86_64::VisitStaticFieldGet(HStaticFieldGet* instruction) {
void InstructionCodeGeneratorX86_64::VisitStaticFieldGet(HStaticFieldGet* instruction) {
LocationSummary* locations = instruction->GetLocations();
CpuRegister cls = locations->InAt(0).As<CpuRegister>();
- CpuRegister out = locations->Out().As<CpuRegister>();
size_t offset = instruction->GetFieldOffset().SizeValue();
switch (instruction->GetType()) {
case Primitive::kPrimBoolean: {
+ CpuRegister out = locations->Out().As<CpuRegister>();
__ movzxb(out, Address(cls, offset));
break;
}
case Primitive::kPrimByte: {
+ CpuRegister out = locations->Out().As<CpuRegister>();
__ movsxb(out, Address(cls, offset));
break;
}
case Primitive::kPrimShort: {
+ CpuRegister out = locations->Out().As<CpuRegister>();
__ movsxw(out, Address(cls, offset));
break;
}
case Primitive::kPrimChar: {
+ CpuRegister out = locations->Out().As<CpuRegister>();
__ movzxw(out, Address(cls, offset));
break;
}
case Primitive::kPrimInt:
case Primitive::kPrimNot: {
+ CpuRegister out = locations->Out().As<CpuRegister>();
__ movl(out, Address(cls, offset));
break;
}
case Primitive::kPrimLong: {
+ CpuRegister out = locations->Out().As<CpuRegister>();
__ movq(out, Address(cls, offset));
break;
}
- case Primitive::kPrimFloat:
- case Primitive::kPrimDouble:
- LOG(FATAL) << "Unimplemented register type " << instruction->GetType();
- UNREACHABLE();
+ case Primitive::kPrimFloat: {
+ XmmRegister out = locations->Out().As<XmmRegister>();
+ __ movss(out, Address(cls, offset));
+ break;
+ }
+
+ case Primitive::kPrimDouble: {
+ XmmRegister out = locations->Out().As<XmmRegister>();
+ __ movsd(out, Address(cls, offset));
+ break;
+ }
+
case Primitive::kPrimVoid:
LOG(FATAL) << "Unreachable type " << instruction->GetType();
UNREACHABLE();
@@ -2522,25 +2559,27 @@ void LocationsBuilderX86_64::VisitStaticFieldSet(HStaticFieldSet* instruction) {
void InstructionCodeGeneratorX86_64::VisitStaticFieldSet(HStaticFieldSet* instruction) {
LocationSummary* locations = instruction->GetLocations();
CpuRegister cls = locations->InAt(0).As<CpuRegister>();
- CpuRegister value = locations->InAt(1).As<CpuRegister>();
size_t offset = instruction->GetFieldOffset().SizeValue();
Primitive::Type field_type = instruction->GetFieldType();
switch (field_type) {
case Primitive::kPrimBoolean:
case Primitive::kPrimByte: {
+ CpuRegister value = locations->InAt(1).As<CpuRegister>();
__ movb(Address(cls, offset), value);
break;
}
case Primitive::kPrimShort:
case Primitive::kPrimChar: {
+ CpuRegister value = locations->InAt(1).As<CpuRegister>();
__ movw(Address(cls, offset), value);
break;
}
case Primitive::kPrimInt:
case Primitive::kPrimNot: {
+ CpuRegister value = locations->InAt(1).As<CpuRegister>();
__ movl(Address(cls, offset), value);
if (field_type == Primitive::kPrimNot) {
CpuRegister temp = locations->GetTemp(0).As<CpuRegister>();
@@ -2551,14 +2590,23 @@ void InstructionCodeGeneratorX86_64::VisitStaticFieldSet(HStaticFieldSet* instru
}
case Primitive::kPrimLong: {
+ CpuRegister value = locations->InAt(1).As<CpuRegister>();
__ movq(Address(cls, offset), value);
break;
}
- case Primitive::kPrimFloat:
- case Primitive::kPrimDouble:
- LOG(FATAL) << "Unimplemented register type " << field_type;
- UNREACHABLE();
+ case Primitive::kPrimFloat: {
+ XmmRegister value = locations->InAt(1).As<XmmRegister>();
+ __ movss(Address(cls, offset), value);
+ break;
+ }
+
+ case Primitive::kPrimDouble: {
+ XmmRegister value = locations->InAt(1).As<XmmRegister>();
+ __ movsd(Address(cls, offset), value);
+ break;
+ }
+
case Primitive::kPrimVoid:
LOG(FATAL) << "Unreachable type " << field_type;
UNREACHABLE();