diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-11-06 15:15:31 +0000 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-11-07 13:54:29 +0000 |
commit | 52e832b1278449e62d9eb502d54d5ff18f8606ed (patch) | |
tree | 14db2240db9d0cec5551f8588a5901bd1bc081fe /compiler/optimizing | |
parent | eb71b3fc2a18ac649dc3743f4ec28f781932030a (diff) | |
download | android_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.cc | 22 | ||||
-rw-r--r-- | compiler/optimizing/builder.h | 5 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 64 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 64 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 88 |
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(); |