diff options
Diffstat (limited to 'compiler/optimizing/intrinsics_x86.cc')
-rw-r--r-- | compiler/optimizing/intrinsics_x86.cc | 93 |
1 files changed, 80 insertions, 13 deletions
diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc index 7275edb695..b3e821cfbe 100644 --- a/compiler/optimizing/intrinsics_x86.cc +++ b/compiler/optimizing/intrinsics_x86.cc @@ -910,23 +910,18 @@ void IntrinsicCodeGeneratorX86::VisitStringCharAt(HInvoke* invoke) { const int32_t value_offset = mirror::String::ValueOffset().Int32Value(); // Location of count const int32_t count_offset = mirror::String::CountOffset().Int32Value(); - // Starting offset within data array - const int32_t offset_offset = mirror::String::OffsetOffset().Int32Value(); - // Start of char data with array_ - const int32_t data_offset = mirror::Array::DataOffset(sizeof(uint16_t)).Int32Value(); Register obj = locations->InAt(0).AsRegister<Register>(); Register idx = locations->InAt(1).AsRegister<Register>(); Register out = locations->Out().AsRegister<Register>(); - Location temp_loc = locations->GetTemp(0); - Register temp = temp_loc.AsRegister<Register>(); // TODO: Maybe we can support range check elimination. Overall, though, I think it's not worth // the cost. // TODO: For simplicity, the index parameter is requested in a register, so different from Quick // we will not optimize the code for constants (which would save a register). - SlowPathCodeX86* slow_path = new (GetAllocator()) IntrinsicSlowPathX86(invoke, temp); + SlowPathCodeX86* slow_path = new (GetAllocator()) IntrinsicSlowPathX86( + invoke, locations->GetTemp(0).AsRegister<Register>()); codegen_->AddSlowPath(slow_path); X86Assembler* assembler = GetAssembler(); @@ -935,12 +930,8 @@ void IntrinsicCodeGeneratorX86::VisitStringCharAt(HInvoke* invoke) { codegen_->MaybeRecordImplicitNullCheck(invoke); __ j(kAboveEqual, slow_path->GetEntryLabel()); - // Get the actual element. - __ movl(temp, idx); // temp := idx. - __ addl(temp, Address(obj, offset_offset)); // temp := offset + idx. - __ movl(out, Address(obj, value_offset)); // obj := obj.array. - // out = out[2*temp]. - __ movzxw(out, Address(out, temp, ScaleFactor::TIMES_2, data_offset)); + // out = out[2*idx]. + __ movzxw(out, Address(out, idx, ScaleFactor::TIMES_2, value_offset)); __ Bind(slow_path->GetExitLabel()); } @@ -976,6 +967,81 @@ void IntrinsicCodeGeneratorX86::VisitStringCompareTo(HInvoke* invoke) { __ Bind(slow_path->GetExitLabel()); } +void IntrinsicLocationsBuilderX86::VisitStringNewStringFromBytes(HInvoke* invoke) { + LocationSummary* locations = new (arena_) LocationSummary(invoke, + LocationSummary::kCall, + kIntrinsified); + InvokeRuntimeCallingConvention calling_convention; + locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0))); + locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(1))); + locations->SetInAt(2, Location::RegisterLocation(calling_convention.GetRegisterAt(2))); + locations->SetInAt(3, Location::RegisterLocation(calling_convention.GetRegisterAt(3))); + locations->SetOut(Location::RegisterLocation(EAX)); + // Needs to be EAX for the invoke. + locations->AddTemp(Location::RegisterLocation(EAX)); +} + +void IntrinsicCodeGeneratorX86::VisitStringNewStringFromBytes(HInvoke* invoke) { + X86Assembler* assembler = GetAssembler(); + LocationSummary* locations = invoke->GetLocations(); + + Register byte_array = locations->InAt(0).AsRegister<Register>(); + __ testl(byte_array, byte_array); + SlowPathCodeX86* slow_path = new (GetAllocator()) IntrinsicSlowPathX86( + invoke, locations->GetTemp(0).AsRegister<Register>()); + codegen_->AddSlowPath(slow_path); + __ j(kEqual, slow_path->GetEntryLabel()); + + __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pAllocStringFromBytes))); + codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); + __ Bind(slow_path->GetExitLabel()); +} + +void IntrinsicLocationsBuilderX86::VisitStringNewStringFromChars(HInvoke* invoke) { + LocationSummary* locations = new (arena_) LocationSummary(invoke, + LocationSummary::kCall, + kIntrinsified); + InvokeRuntimeCallingConvention calling_convention; + locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0))); + locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(1))); + locations->SetInAt(2, Location::RegisterLocation(calling_convention.GetRegisterAt(2))); + locations->SetOut(Location::RegisterLocation(EAX)); +} + +void IntrinsicCodeGeneratorX86::VisitStringNewStringFromChars(HInvoke* invoke) { + X86Assembler* assembler = GetAssembler(); + + __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pAllocStringFromChars))); + codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); +} + +void IntrinsicLocationsBuilderX86::VisitStringNewStringFromString(HInvoke* invoke) { + LocationSummary* locations = new (arena_) LocationSummary(invoke, + LocationSummary::kCall, + kIntrinsified); + InvokeRuntimeCallingConvention calling_convention; + locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0))); + locations->SetOut(Location::RegisterLocation(EAX)); + // Needs to be EAX for the invoke. + locations->AddTemp(Location::RegisterLocation(EAX)); +} + +void IntrinsicCodeGeneratorX86::VisitStringNewStringFromString(HInvoke* invoke) { + X86Assembler* assembler = GetAssembler(); + LocationSummary* locations = invoke->GetLocations(); + + Register string_to_copy = locations->InAt(0).AsRegister<Register>(); + __ testl(string_to_copy, string_to_copy); + SlowPathCodeX86* slow_path = new (GetAllocator()) IntrinsicSlowPathX86( + invoke, locations->GetTemp(0).AsRegister<Register>()); + codegen_->AddSlowPath(slow_path); + __ j(kEqual, slow_path->GetEntryLabel()); + + __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pAllocStringFromString))); + codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); + __ Bind(slow_path->GetExitLabel()); +} + static void GenPeek(LocationSummary* locations, Primitive::Type size, X86Assembler* assembler) { Register address = locations->InAt(0).AsRegisterPairLow<Register>(); Location out_loc = locations->Out(); @@ -1536,6 +1602,7 @@ void IntrinsicCodeGeneratorX86::Visit ## Name(HInvoke* invoke ATTRIBUTE_UNUSED) } UNIMPLEMENTED_INTRINSIC(MathRoundDouble) +UNIMPLEMENTED_INTRINSIC(StringGetCharsNoCheck) UNIMPLEMENTED_INTRINSIC(StringIndexOf) UNIMPLEMENTED_INTRINSIC(StringIndexOfAfter) UNIMPLEMENTED_INTRINSIC(SystemArrayCopyChar) |