diff options
author | Goran Jakovljevic <Goran.Jakovljevic@imgtec.com> | 2017-02-10 17:48:52 +0100 |
---|---|---|
committer | Goran Jakovljevic <Goran.Jakovljevic@imgtec.com> | 2017-02-13 09:05:26 +0000 |
commit | f94fa81e20d00929ef52707cd577353b95d40284 (patch) | |
tree | cb79d0e0610775a41f0511b4cacfe87136bbba60 /compiler/optimizing/code_generator_mips.cc | |
parent | 806ac631e53f12061cb0ae7640aa9cd0dd79243d (diff) |
String Compression for MIPS32 and MIPS64
Changes on intrinsics and Code Generation on MIPS32 and MIPS64 for
string compression feature.
Testing is done with STRING_COMPRESSION_ENABLED = true (in libcore),
mirror::kUseStringCompression = true and STRING_COMPRESSION_FEATURE set
to 1.
Test: booted MIPS32 and MIPS64 in QEMU
Test: mma test-art-target-run-test on CI20 (MIPS32R2)
Test: mma test-art-target-run-test in QEMU (MIPS64R6)
Change-Id: If50a6b6c0792bfa34d4fdff6bf2c7542211d2689
Diffstat (limited to 'compiler/optimizing/code_generator_mips.cc')
-rw-r--r-- | compiler/optimizing/code_generator_mips.cc | 58 |
1 files changed, 52 insertions, 6 deletions
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 0677dad078..c9dde7cc55 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -1914,6 +1914,8 @@ void InstructionCodeGeneratorMIPS::VisitArrayGet(HArrayGet* instruction) { auto null_checker = GetImplicitNullChecker(instruction); Primitive::Type type = instruction->GetType(); + const bool maybe_compressed_char_at = mirror::kUseStringCompression && + instruction->IsStringCharAt(); switch (type) { case Primitive::kPrimBoolean: { Register out = locations->Out().AsRegister<Register>(); @@ -1957,14 +1959,54 @@ void InstructionCodeGeneratorMIPS::VisitArrayGet(HArrayGet* instruction) { case Primitive::kPrimChar: { Register out = locations->Out().AsRegister<Register>(); + if (maybe_compressed_char_at) { + uint32_t count_offset = mirror::String::CountOffset().Uint32Value(); + __ LoadFromOffset(kLoadWord, TMP, obj, count_offset, null_checker); + __ Sll(TMP, TMP, 31); // Extract compression flag into the most significant bit of TMP. + static_assert(static_cast<uint32_t>(mirror::StringCompressionFlag::kCompressed) == 0u, + "Expecting 0=compressed, 1=uncompressed"); + } if (index.IsConstant()) { - size_t offset = - (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset; - __ LoadFromOffset(kLoadUnsignedHalfword, out, obj, offset, null_checker); + int32_t const_index = index.GetConstant()->AsIntConstant()->GetValue(); + if (maybe_compressed_char_at) { + MipsLabel uncompressed_load, done; + __ Bnez(TMP, &uncompressed_load); + __ LoadFromOffset(kLoadUnsignedByte, + out, + obj, + data_offset + (const_index << TIMES_1)); + __ B(&done); + __ Bind(&uncompressed_load); + __ LoadFromOffset(kLoadUnsignedHalfword, + out, + obj, + data_offset + (const_index << TIMES_2)); + __ Bind(&done); + } else { + __ LoadFromOffset(kLoadUnsignedHalfword, + out, + obj, + data_offset + (const_index << TIMES_2), + null_checker); + } } else { - __ Sll(TMP, index.AsRegister<Register>(), TIMES_2); - __ Addu(TMP, obj, TMP); - __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset, null_checker); + Register index_reg = index.AsRegister<Register>(); + if (maybe_compressed_char_at) { + MipsLabel uncompressed_load, done; + __ Bnez(TMP, &uncompressed_load); + __ Addu(TMP, obj, index_reg); + __ LoadFromOffset(kLoadUnsignedByte, out, TMP, data_offset); + __ B(&done); + __ Bind(&uncompressed_load); + __ Sll(TMP, index_reg, TIMES_2); + __ Addu(TMP, obj, TMP); + __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset); + __ Bind(&done); + } else { + __ Sll(TMP, index_reg, TIMES_2); + __ Addu(TMP, obj, TMP); + __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset, null_checker); + } } break; } @@ -2046,6 +2088,10 @@ void InstructionCodeGeneratorMIPS::VisitArrayLength(HArrayLength* instruction) { Register out = locations->Out().AsRegister<Register>(); __ LoadFromOffset(kLoadWord, out, obj, offset); codegen_->MaybeRecordImplicitNullCheck(instruction); + // Mask out compression flag from String's array length. + if (mirror::kUseStringCompression && instruction->IsStringLength()) { + __ Srl(out, out, 1u); + } } Location LocationsBuilderMIPS::RegisterOrZeroConstant(HInstruction* instruction) { |