diff options
Diffstat (limited to 'compiler/utils')
20 files changed, 324 insertions, 606 deletions
diff --git a/compiler/utils/assembler_test_base.h b/compiler/utils/assembler_test_base.h index 1482210ac4..778a01566c 100644 --- a/compiler/utils/assembler_test_base.h +++ b/compiler/utils/assembler_test_base.h @@ -25,9 +25,9 @@ #include "android-base/strings.h" +#include "base/utils.h" #include "common_runtime_test.h" // For ScratchFile #include "exec_utils.h" -#include "utils.h" namespace art { diff --git a/compiler/utils/atomic_dex_ref_map-inl.h b/compiler/utils/atomic_dex_ref_map-inl.h index 7023b9a0e8..7977e8201f 100644 --- a/compiler/utils/atomic_dex_ref_map-inl.h +++ b/compiler/utils/atomic_dex_ref_map-inl.h @@ -21,10 +21,10 @@ #include <type_traits> -#include "class_reference.h" +#include "dex/class_reference.h" #include "dex/dex_file-inl.h" -#include "method_reference.h" -#include "type_reference.h" +#include "dex/method_reference.h" +#include "dex/type_reference.h" namespace art { diff --git a/compiler/utils/atomic_dex_ref_map.h b/compiler/utils/atomic_dex_ref_map.h index 3474e16b8d..fc2437999e 100644 --- a/compiler/utils/atomic_dex_ref_map.h +++ b/compiler/utils/atomic_dex_ref_map.h @@ -17,9 +17,10 @@ #ifndef ART_COMPILER_UTILS_ATOMIC_DEX_REF_MAP_H_ #define ART_COMPILER_UTILS_ATOMIC_DEX_REF_MAP_H_ +#include "base/atomic.h" #include "base/dchecked_vector.h" +#include "base/safe_map.h" #include "dex/dex_file_reference.h" -#include "safe_map.h" namespace art { diff --git a/compiler/utils/atomic_dex_ref_map_test.cc b/compiler/utils/atomic_dex_ref_map_test.cc index d58d60b4f3..4e1ef1248d 100644 --- a/compiler/utils/atomic_dex_ref_map_test.cc +++ b/compiler/utils/atomic_dex_ref_map_test.cc @@ -20,7 +20,7 @@ #include "common_runtime_test.h" #include "dex/dex_file-inl.h" -#include "method_reference.h" +#include "dex/method_reference.h" #include "scoped_thread_state_change-inl.h" namespace art { diff --git a/compiler/utils/mips/assembler_mips.cc b/compiler/utils/mips/assembler_mips.cc index 2218ef9af2..b2ad490a57 100644 --- a/compiler/utils/mips/assembler_mips.cc +++ b/compiler/utils/mips/assembler_mips.cc @@ -2793,6 +2793,26 @@ void MipsAssembler::Hadd_uD(VectorRegister wd, VectorRegister ws, VectorRegister DsFsmInstr(EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x15)).FprOuts(wd).FprIns(ws, wt); } +void MipsAssembler::PcntB(VectorRegister wd, VectorRegister ws) { + CHECK(HasMsa()); + DsFsmInstr(EmitMsa2R(0xc1, 0x0, ws, wd, 0x1e)).FprOuts(wd).FprIns(ws); +} + +void MipsAssembler::PcntH(VectorRegister wd, VectorRegister ws) { + CHECK(HasMsa()); + DsFsmInstr(EmitMsa2R(0xc1, 0x1, ws, wd, 0x1e)).FprOuts(wd).FprIns(ws); +} + +void MipsAssembler::PcntW(VectorRegister wd, VectorRegister ws) { + CHECK(HasMsa()); + DsFsmInstr(EmitMsa2R(0xc1, 0x2, ws, wd, 0x1e)).FprOuts(wd).FprIns(ws); +} + +void MipsAssembler::PcntD(VectorRegister wd, VectorRegister ws) { + CHECK(HasMsa()); + DsFsmInstr(EmitMsa2R(0xc1, 0x3, ws, wd, 0x1e)).FprOuts(wd).FprIns(ws); +} + void MipsAssembler::ReplicateFPToVectorRegister(VectorRegister dst, FRegister src, bool is_double) { diff --git a/compiler/utils/mips/assembler_mips.h b/compiler/utils/mips/assembler_mips.h index 7de8e2e366..c6ce62b4f4 100644 --- a/compiler/utils/mips/assembler_mips.h +++ b/compiler/utils/mips/assembler_mips.h @@ -756,6 +756,11 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi void Hadd_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt); void Hadd_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void PcntB(VectorRegister wd, VectorRegister ws); + void PcntH(VectorRegister wd, VectorRegister ws); + void PcntW(VectorRegister wd, VectorRegister ws); + void PcntD(VectorRegister wd, VectorRegister ws); + // Helper for replicating floating point value in all destination elements. void ReplicateFPToVectorRegister(VectorRegister dst, FRegister src, bool is_double); diff --git a/compiler/utils/mips/assembler_mips32r6_test.cc b/compiler/utils/mips/assembler_mips32r6_test.cc index 937ee25bcb..691c33f3e7 100644 --- a/compiler/utils/mips/assembler_mips32r6_test.cc +++ b/compiler/utils/mips/assembler_mips32r6_test.cc @@ -2277,6 +2277,22 @@ TEST_F(AssemblerMIPS32r6Test, FillW) { DriverStr(RepeatVR(&mips::MipsAssembler::FillW, "fill.w ${reg1}, ${reg2}"), "fill.w"); } +TEST_F(AssemblerMIPS32r6Test, PcntB) { + DriverStr(RepeatVV(&mips::MipsAssembler::PcntB, "pcnt.b ${reg1}, ${reg2}"), "pcnt.b"); +} + +TEST_F(AssemblerMIPS32r6Test, PcntH) { + DriverStr(RepeatVV(&mips::MipsAssembler::PcntH, "pcnt.h ${reg1}, ${reg2}"), "pcnt.h"); +} + +TEST_F(AssemblerMIPS32r6Test, PcntW) { + DriverStr(RepeatVV(&mips::MipsAssembler::PcntW, "pcnt.w ${reg1}, ${reg2}"), "pcnt.w"); +} + +TEST_F(AssemblerMIPS32r6Test, PcntD) { + DriverStr(RepeatVV(&mips::MipsAssembler::PcntD, "pcnt.d ${reg1}, ${reg2}"), "pcnt.d"); +} + TEST_F(AssemblerMIPS32r6Test, LdiB) { DriverStr(RepeatVIb(&mips::MipsAssembler::LdiB, -8, "ldi.b ${reg}, {imm}"), "ldi.b"); } diff --git a/compiler/utils/mips64/assembler_mips64.cc b/compiler/utils/mips64/assembler_mips64.cc index e1b0e75108..5a817fa960 100644 --- a/compiler/utils/mips64/assembler_mips64.cc +++ b/compiler/utils/mips64/assembler_mips64.cc @@ -2279,6 +2279,26 @@ void Mips64Assembler::Hadd_uD(VectorRegister wd, VectorRegister ws, VectorRegist EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x15); } +void Mips64Assembler::PcntB(VectorRegister wd, VectorRegister ws) { + CHECK(HasMsa()); + EmitMsa2R(0xc1, 0x0, ws, wd, 0x1e); +} + +void Mips64Assembler::PcntH(VectorRegister wd, VectorRegister ws) { + CHECK(HasMsa()); + EmitMsa2R(0xc1, 0x1, ws, wd, 0x1e); +} + +void Mips64Assembler::PcntW(VectorRegister wd, VectorRegister ws) { + CHECK(HasMsa()); + EmitMsa2R(0xc1, 0x2, ws, wd, 0x1e); +} + +void Mips64Assembler::PcntD(VectorRegister wd, VectorRegister ws) { + CHECK(HasMsa()); + EmitMsa2R(0xc1, 0x3, ws, wd, 0x1e); +} + void Mips64Assembler::ReplicateFPToVectorRegister(VectorRegister dst, FpuRegister src, bool is_double) { diff --git a/compiler/utils/mips64/assembler_mips64.h b/compiler/utils/mips64/assembler_mips64.h index 7a61f39e64..542dbafc87 100644 --- a/compiler/utils/mips64/assembler_mips64.h +++ b/compiler/utils/mips64/assembler_mips64.h @@ -863,6 +863,11 @@ class Mips64Assembler FINAL : public Assembler, public JNIMacroAssembler<Pointer void Hadd_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt); void Hadd_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void PcntB(VectorRegister wd, VectorRegister ws); + void PcntH(VectorRegister wd, VectorRegister ws); + void PcntW(VectorRegister wd, VectorRegister ws); + void PcntD(VectorRegister wd, VectorRegister ws); + // Helper for replicating floating point value in all destination elements. void ReplicateFPToVectorRegister(VectorRegister dst, FpuRegister src, bool is_double); diff --git a/compiler/utils/mips64/assembler_mips64_test.cc b/compiler/utils/mips64/assembler_mips64_test.cc index b0e1d91c3f..fb5f12be93 100644 --- a/compiler/utils/mips64/assembler_mips64_test.cc +++ b/compiler/utils/mips64/assembler_mips64_test.cc @@ -3529,6 +3529,22 @@ TEST_F(AssemblerMIPS64Test, FillD) { DriverStr(RepeatVR(&mips64::Mips64Assembler::FillD, "fill.d ${reg1}, ${reg2}"), "fill.d"); } +TEST_F(AssemblerMIPS64Test, PcntB) { + DriverStr(RepeatVV(&mips64::Mips64Assembler::PcntB, "pcnt.b ${reg1}, ${reg2}"), "pcnt.b"); +} + +TEST_F(AssemblerMIPS64Test, PcntH) { + DriverStr(RepeatVV(&mips64::Mips64Assembler::PcntH, "pcnt.h ${reg1}, ${reg2}"), "pcnt.h"); +} + +TEST_F(AssemblerMIPS64Test, PcntW) { + DriverStr(RepeatVV(&mips64::Mips64Assembler::PcntW, "pcnt.w ${reg1}, ${reg2}"), "pcnt.w"); +} + +TEST_F(AssemblerMIPS64Test, PcntD) { + DriverStr(RepeatVV(&mips64::Mips64Assembler::PcntD, "pcnt.d ${reg1}, ${reg2}"), "pcnt.d"); +} + TEST_F(AssemblerMIPS64Test, LdiB) { DriverStr(RepeatVIb(&mips64::Mips64Assembler::LdiB, -8, "ldi.b ${reg}, {imm}"), "ldi.b"); } diff --git a/compiler/utils/string_reference_test.cc b/compiler/utils/string_reference_test.cc deleted file mode 100644 index 4b07e65771..0000000000 --- a/compiler/utils/string_reference_test.cc +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "string_reference.h" - -#include <memory> - -#include "dex/dex_file_types.h" -#include "gtest/gtest.h" -#include "utils/test_dex_file_builder.h" - -namespace art { - -TEST(StringReference, ValueComparator) { - // This is a regression test for the StringReferenceValueComparator using the wrong - // dex file to get the string data from a StringId. We construct two dex files with - // just a single string with the same length but different value. This creates dex - // files that have the same layout, so the byte offset read from the StringId in one - // dex file, when used in the other dex file still points to valid string data, except - // that it's the wrong string. Without the fix the strings would then compare equal. - TestDexFileBuilder builder1; - builder1.AddString("String1"); - std::unique_ptr<const DexFile> dex_file1 = builder1.Build("dummy location 1"); - ASSERT_EQ(1u, dex_file1->NumStringIds()); - ASSERT_STREQ("String1", dex_file1->GetStringData(dex_file1->GetStringId(dex::StringIndex(0)))); - StringReference sr1(dex_file1.get(), dex::StringIndex(0)); - - TestDexFileBuilder builder2; - builder2.AddString("String2"); - std::unique_ptr<const DexFile> dex_file2 = builder2.Build("dummy location 2"); - ASSERT_EQ(1u, dex_file2->NumStringIds()); - ASSERT_STREQ("String2", dex_file2->GetStringData(dex_file2->GetStringId(dex::StringIndex(0)))); - StringReference sr2(dex_file2.get(), dex::StringIndex(0)); - - StringReferenceValueComparator cmp; - EXPECT_TRUE(cmp(sr1, sr2)); // "String1" < "String2" is true. - EXPECT_FALSE(cmp(sr2, sr1)); // "String2" < "String1" is false. -} - -TEST(StringReference, ValueComparator2) { - const char* const kDexFile1Strings[] = { - "", - "abc", - "abcxyz", - }; - const char* const kDexFile2Strings[] = { - "a", - "abc", - "abcdef", - "def", - }; - const bool expectedCmp12[arraysize(kDexFile1Strings)][arraysize(kDexFile2Strings)] = { - { true, true, true, true }, - { false, false, true, true }, - { false, false, false, true }, - }; - const bool expectedCmp21[arraysize(kDexFile2Strings)][arraysize(kDexFile1Strings)] = { - { false, true, true }, - { false, false, true }, - { false, false, true }, - { false, false, false }, - }; - - TestDexFileBuilder builder1; - for (const char* s : kDexFile1Strings) { - builder1.AddString(s); - } - std::unique_ptr<const DexFile> dex_file1 = builder1.Build("dummy location 1"); - ASSERT_EQ(arraysize(kDexFile1Strings), dex_file1->NumStringIds()); - for (size_t index = 0; index != arraysize(kDexFile1Strings); ++index) { - ASSERT_STREQ(kDexFile1Strings[index], - dex_file1->GetStringData(dex_file1->GetStringId(dex::StringIndex(index)))); - } - - TestDexFileBuilder builder2; - for (const char* s : kDexFile2Strings) { - builder2.AddString(s); - } - std::unique_ptr<const DexFile> dex_file2 = builder2.Build("dummy location 1"); - ASSERT_EQ(arraysize(kDexFile2Strings), dex_file2->NumStringIds()); - for (size_t index = 0; index != arraysize(kDexFile2Strings); ++index) { - ASSERT_STREQ(kDexFile2Strings[index], - dex_file2->GetStringData(dex_file2->GetStringId(dex::StringIndex(index)))); - } - - StringReferenceValueComparator cmp; - for (size_t index1 = 0; index1 != arraysize(kDexFile1Strings); ++index1) { - for (size_t index2 = 0; index2 != arraysize(kDexFile2Strings); ++index2) { - StringReference sr1(dex_file1.get(), dex::StringIndex(index1)); - StringReference sr2(dex_file2.get(), dex::StringIndex(index2)); - EXPECT_EQ(expectedCmp12[index1][index2], cmp(sr1, sr2)) << index1 << " " << index2; - EXPECT_EQ(expectedCmp21[index2][index1], cmp(sr2, sr1)) << index1 << " " << index2; - } - } -} - -} // namespace art diff --git a/compiler/utils/swap_space_test.cc b/compiler/utils/swap_space_test.cc index f4bca59cb3..1650080e66 100644 --- a/compiler/utils/swap_space_test.cc +++ b/compiler/utils/swap_space_test.cc @@ -24,9 +24,9 @@ #include "gtest/gtest.h" +#include "base/os.h" #include "base/unix_file/fd_file.h" #include "common_runtime_test.h" -#include "os.h" namespace art { diff --git a/compiler/utils/test_dex_file_builder.h b/compiler/utils/test_dex_file_builder.h deleted file mode 100644 index 58f1ec7b08..0000000000 --- a/compiler/utils/test_dex_file_builder.h +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_COMPILER_UTILS_TEST_DEX_FILE_BUILDER_H_ -#define ART_COMPILER_UTILS_TEST_DEX_FILE_BUILDER_H_ - -#include <zlib.h> - -#include <cstring> -#include <map> -#include <set> -#include <vector> - -#include <android-base/logging.h> - -#include "base/bit_utils.h" -#include "dex/art_dex_file_loader.h" -#include "dex/dex_file_loader.h" -#include "dex/standard_dex_file.h" - -namespace art { - -class TestDexFileBuilder { - public: - TestDexFileBuilder() - : strings_(), types_(), fields_(), protos_(), dex_file_data_() { - } - - void AddString(const std::string& str) { - CHECK(dex_file_data_.empty()); - auto it = strings_.emplace(str, IdxAndDataOffset()).first; - CHECK_LT(it->first.length(), 128u); // Don't allow multi-byte length in uleb128. - } - - void AddType(const std::string& descriptor) { - CHECK(dex_file_data_.empty()); - AddString(descriptor); - types_.emplace(descriptor, 0u); - } - - void AddField(const std::string& class_descriptor, const std::string& type, - const std::string& name) { - CHECK(dex_file_data_.empty()); - AddType(class_descriptor); - AddType(type); - AddString(name); - FieldKey key = { class_descriptor, type, name }; - fields_.emplace(key, 0u); - } - - void AddMethod(const std::string& class_descriptor, const std::string& signature, - const std::string& name) { - CHECK(dex_file_data_.empty()); - AddType(class_descriptor); - AddString(name); - - ProtoKey proto_key = CreateProtoKey(signature); - AddString(proto_key.shorty); - AddType(proto_key.return_type); - for (const auto& arg_type : proto_key.args) { - AddType(arg_type); - } - auto it = protos_.emplace(proto_key, IdxAndDataOffset()).first; - const ProtoKey* proto = &it->first; // Valid as long as the element remains in protos_. - - MethodKey method_key = { - class_descriptor, name, proto - }; - methods_.emplace(method_key, 0u); - } - - // NOTE: The builder holds the actual data, so it must live as long as the dex file. - std::unique_ptr<const DexFile> Build(const std::string& dex_location) { - CHECK(dex_file_data_.empty()); - union { - uint8_t data[sizeof(DexFile::Header)]; - uint64_t force_alignment; - } header_data; - std::memset(header_data.data, 0, sizeof(header_data.data)); - DexFile::Header* header = reinterpret_cast<DexFile::Header*>(&header_data.data); - std::copy_n(StandardDexFile::kDexMagic, 4u, header->magic_); - std::copy_n(StandardDexFile::kDexMagicVersions[0], 4u, header->magic_ + 4u); - header->header_size_ = sizeof(DexFile::Header); - header->endian_tag_ = DexFile::kDexEndianConstant; - header->link_size_ = 0u; // Unused. - header->link_off_ = 0u; // Unused. - header->map_off_ = 0u; // Unused. TODO: This is wrong. Dex files created by this builder - // cannot be verified. b/26808512 - - uint32_t data_section_size = 0u; - - uint32_t string_ids_offset = sizeof(DexFile::Header); - uint32_t string_idx = 0u; - for (auto& entry : strings_) { - entry.second.idx = string_idx; - string_idx += 1u; - entry.second.data_offset = data_section_size; - data_section_size += entry.first.length() + 1u /* length */ + 1u /* null-terminator */; - } - header->string_ids_size_ = strings_.size(); - header->string_ids_off_ = strings_.empty() ? 0u : string_ids_offset; - - uint32_t type_ids_offset = string_ids_offset + strings_.size() * sizeof(DexFile::StringId); - uint32_t type_idx = 0u; - for (auto& entry : types_) { - entry.second = type_idx; - type_idx += 1u; - } - header->type_ids_size_ = types_.size(); - header->type_ids_off_ = types_.empty() ? 0u : type_ids_offset; - - uint32_t proto_ids_offset = type_ids_offset + types_.size() * sizeof(DexFile::TypeId); - uint32_t proto_idx = 0u; - for (auto& entry : protos_) { - entry.second.idx = proto_idx; - proto_idx += 1u; - size_t num_args = entry.first.args.size(); - if (num_args != 0u) { - entry.second.data_offset = RoundUp(data_section_size, 4u); - data_section_size = entry.second.data_offset + 4u + num_args * sizeof(DexFile::TypeItem); - } else { - entry.second.data_offset = 0u; - } - } - header->proto_ids_size_ = protos_.size(); - header->proto_ids_off_ = protos_.empty() ? 0u : proto_ids_offset; - - uint32_t field_ids_offset = proto_ids_offset + protos_.size() * sizeof(DexFile::ProtoId); - uint32_t field_idx = 0u; - for (auto& entry : fields_) { - entry.second = field_idx; - field_idx += 1u; - } - header->field_ids_size_ = fields_.size(); - header->field_ids_off_ = fields_.empty() ? 0u : field_ids_offset; - - uint32_t method_ids_offset = field_ids_offset + fields_.size() * sizeof(DexFile::FieldId); - uint32_t method_idx = 0u; - for (auto& entry : methods_) { - entry.second = method_idx; - method_idx += 1u; - } - header->method_ids_size_ = methods_.size(); - header->method_ids_off_ = methods_.empty() ? 0u : method_ids_offset; - - // No class defs. - header->class_defs_size_ = 0u; - header->class_defs_off_ = 0u; - - uint32_t data_section_offset = method_ids_offset + methods_.size() * sizeof(DexFile::MethodId); - header->data_size_ = data_section_size; - header->data_off_ = (data_section_size != 0u) ? data_section_offset : 0u; - - uint32_t total_size = data_section_offset + data_section_size; - - dex_file_data_.resize(total_size); - - for (const auto& entry : strings_) { - CHECK_LT(entry.first.size(), 128u); - uint32_t raw_offset = data_section_offset + entry.second.data_offset; - dex_file_data_[raw_offset] = static_cast<uint8_t>(entry.first.size()); - std::memcpy(&dex_file_data_[raw_offset + 1], entry.first.c_str(), entry.first.size() + 1); - Write32(string_ids_offset + entry.second.idx * sizeof(DexFile::StringId), raw_offset); - } - - for (const auto& entry : types_) { - Write32(type_ids_offset + entry.second * sizeof(DexFile::TypeId), GetStringIdx(entry.first)); - ++type_idx; - } - - for (const auto& entry : protos_) { - size_t num_args = entry.first.args.size(); - uint32_t type_list_offset = - (num_args != 0u) ? data_section_offset + entry.second.data_offset : 0u; - uint32_t raw_offset = proto_ids_offset + entry.second.idx * sizeof(DexFile::ProtoId); - Write32(raw_offset + 0u, GetStringIdx(entry.first.shorty)); - Write16(raw_offset + 4u, GetTypeIdx(entry.first.return_type)); - Write32(raw_offset + 8u, type_list_offset); - if (num_args != 0u) { - CHECK_NE(entry.second.data_offset, 0u); - Write32(type_list_offset, num_args); - for (size_t i = 0; i != num_args; ++i) { - Write16(type_list_offset + 4u + i * sizeof(DexFile::TypeItem), - GetTypeIdx(entry.first.args[i])); - } - } - } - - for (const auto& entry : fields_) { - uint32_t raw_offset = field_ids_offset + entry.second * sizeof(DexFile::FieldId); - Write16(raw_offset + 0u, GetTypeIdx(entry.first.class_descriptor)); - Write16(raw_offset + 2u, GetTypeIdx(entry.first.type)); - Write32(raw_offset + 4u, GetStringIdx(entry.first.name)); - } - - for (const auto& entry : methods_) { - uint32_t raw_offset = method_ids_offset + entry.second * sizeof(DexFile::MethodId); - Write16(raw_offset + 0u, GetTypeIdx(entry.first.class_descriptor)); - auto it = protos_.find(*entry.first.proto); - CHECK(it != protos_.end()); - Write16(raw_offset + 2u, it->second.idx); - Write32(raw_offset + 4u, GetStringIdx(entry.first.name)); - } - - // Leave signature as zeros. - - header->file_size_ = dex_file_data_.size(); - - // Write the complete header early, as part of it needs to be checksummed. - std::memcpy(&dex_file_data_[0], header_data.data, sizeof(DexFile::Header)); - - // Checksum starts after the checksum field. - size_t skip = sizeof(header->magic_) + sizeof(header->checksum_); - header->checksum_ = adler32(adler32(0L, Z_NULL, 0), - dex_file_data_.data() + skip, - dex_file_data_.size() - skip); - - // Write the complete header again, just simpler that way. - std::memcpy(&dex_file_data_[0], header_data.data, sizeof(DexFile::Header)); - - static constexpr bool kVerify = false; - static constexpr bool kVerifyChecksum = false; - std::string error_msg; - const ArtDexFileLoader dex_file_loader; - std::unique_ptr<const DexFile> dex_file(dex_file_loader.Open( - &dex_file_data_[0], - dex_file_data_.size(), - dex_location, - 0u, - nullptr, - kVerify, - kVerifyChecksum, - &error_msg)); - CHECK(dex_file != nullptr) << error_msg; - return dex_file; - } - - uint32_t GetStringIdx(const std::string& type) { - auto it = strings_.find(type); - CHECK(it != strings_.end()); - return it->second.idx; - } - - uint32_t GetTypeIdx(const std::string& type) { - auto it = types_.find(type); - CHECK(it != types_.end()); - return it->second; - } - - uint32_t GetFieldIdx(const std::string& class_descriptor, const std::string& type, - const std::string& name) { - FieldKey key = { class_descriptor, type, name }; - auto it = fields_.find(key); - CHECK(it != fields_.end()); - return it->second; - } - - uint32_t GetMethodIdx(const std::string& class_descriptor, const std::string& signature, - const std::string& name) { - ProtoKey proto_key = CreateProtoKey(signature); - MethodKey method_key = { class_descriptor, name, &proto_key }; - auto it = methods_.find(method_key); - CHECK(it != methods_.end()); - return it->second; - } - - private: - struct IdxAndDataOffset { - uint32_t idx; - uint32_t data_offset; - }; - - struct FieldKey { - const std::string class_descriptor; - const std::string type; - const std::string name; - }; - struct FieldKeyComparator { - bool operator()(const FieldKey& lhs, const FieldKey& rhs) const { - if (lhs.class_descriptor != rhs.class_descriptor) { - return lhs.class_descriptor < rhs.class_descriptor; - } - if (lhs.name != rhs.name) { - return lhs.name < rhs.name; - } - return lhs.type < rhs.type; - } - }; - - struct ProtoKey { - std::string shorty; - std::string return_type; - std::vector<std::string> args; - }; - struct ProtoKeyComparator { - bool operator()(const ProtoKey& lhs, const ProtoKey& rhs) const { - if (lhs.return_type != rhs.return_type) { - return lhs.return_type < rhs.return_type; - } - size_t min_args = std::min(lhs.args.size(), rhs.args.size()); - for (size_t i = 0; i != min_args; ++i) { - if (lhs.args[i] != rhs.args[i]) { - return lhs.args[i] < rhs.args[i]; - } - } - return lhs.args.size() < rhs.args.size(); - } - }; - - struct MethodKey { - std::string class_descriptor; - std::string name; - const ProtoKey* proto; - }; - struct MethodKeyComparator { - bool operator()(const MethodKey& lhs, const MethodKey& rhs) const { - if (lhs.class_descriptor != rhs.class_descriptor) { - return lhs.class_descriptor < rhs.class_descriptor; - } - if (lhs.name != rhs.name) { - return lhs.name < rhs.name; - } - return ProtoKeyComparator()(*lhs.proto, *rhs.proto); - } - }; - - ProtoKey CreateProtoKey(const std::string& signature) { - CHECK_EQ(signature[0], '('); - const char* args = signature.c_str() + 1; - const char* args_end = std::strchr(args, ')'); - CHECK(args_end != nullptr); - const char* return_type = args_end + 1; - - ProtoKey key = { - std::string() + ((*return_type == '[') ? 'L' : *return_type), - return_type, - std::vector<std::string>() - }; - while (args != args_end) { - key.shorty += (*args == '[') ? 'L' : *args; - const char* arg_start = args; - while (*args == '[') { - ++args; - } - if (*args == 'L') { - do { - ++args; - CHECK_NE(args, args_end); - } while (*args != ';'); - } - ++args; - key.args.emplace_back(arg_start, args); - } - return key; - } - - void Write32(size_t offset, uint32_t value) { - CHECK_LE(offset + 4u, dex_file_data_.size()); - CHECK_EQ(dex_file_data_[offset + 0], 0u); - CHECK_EQ(dex_file_data_[offset + 1], 0u); - CHECK_EQ(dex_file_data_[offset + 2], 0u); - CHECK_EQ(dex_file_data_[offset + 3], 0u); - dex_file_data_[offset + 0] = static_cast<uint8_t>(value >> 0); - dex_file_data_[offset + 1] = static_cast<uint8_t>(value >> 8); - dex_file_data_[offset + 2] = static_cast<uint8_t>(value >> 16); - dex_file_data_[offset + 3] = static_cast<uint8_t>(value >> 24); - } - - void Write16(size_t offset, uint32_t value) { - CHECK_LE(value, 0xffffu); - CHECK_LE(offset + 2u, dex_file_data_.size()); - CHECK_EQ(dex_file_data_[offset + 0], 0u); - CHECK_EQ(dex_file_data_[offset + 1], 0u); - dex_file_data_[offset + 0] = static_cast<uint8_t>(value >> 0); - dex_file_data_[offset + 1] = static_cast<uint8_t>(value >> 8); - } - - std::map<std::string, IdxAndDataOffset> strings_; - std::map<std::string, uint32_t> types_; - std::map<FieldKey, uint32_t, FieldKeyComparator> fields_; - std::map<ProtoKey, IdxAndDataOffset, ProtoKeyComparator> protos_; - std::map<MethodKey, uint32_t, MethodKeyComparator> methods_; - - std::vector<uint8_t> dex_file_data_; -}; - -} // namespace art - -#endif // ART_COMPILER_UTILS_TEST_DEX_FILE_BUILDER_H_ diff --git a/compiler/utils/test_dex_file_builder_test.cc b/compiler/utils/test_dex_file_builder_test.cc deleted file mode 100644 index 736a17edac..0000000000 --- a/compiler/utils/test_dex_file_builder_test.cc +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "test_dex_file_builder.h" - -#include "dex/dex_file-inl.h" -#include "gtest/gtest.h" -#include "utils.h" - -namespace art { - -TEST(TestDexFileBuilderTest, SimpleTest) { - TestDexFileBuilder builder; - builder.AddString("Arbitrary string"); - builder.AddType("Ljava/lang/Class;"); - builder.AddField("LTestClass;", "[I", "intField"); - builder.AddMethod("LTestClass;", "()I", "foo"); - builder.AddMethod("LTestClass;", "(Ljava/lang/Object;[Ljava/lang/Object;)LTestClass;", "bar"); - const char* dex_location = "TestDexFileBuilder/SimpleTest"; - std::unique_ptr<const DexFile> dex_file(builder.Build(dex_location)); - ASSERT_TRUE(dex_file != nullptr); - EXPECT_STREQ(dex_location, dex_file->GetLocation().c_str()); - - static const char* const expected_strings[] = { - "Arbitrary string", - "I", - "LLL", // shorty - "LTestClass;", - "Ljava/lang/Class;", - "Ljava/lang/Object;", - "[I", - "[Ljava/lang/Object;", - "bar", - "foo", - "intField", - }; - ASSERT_EQ(arraysize(expected_strings), dex_file->NumStringIds()); - for (size_t i = 0; i != arraysize(expected_strings); ++i) { - EXPECT_STREQ(expected_strings[i], - dex_file->GetStringData(dex_file->GetStringId(dex::StringIndex(i)))) << i; - } - - static const char* const expected_types[] = { - "I", - "LTestClass;", - "Ljava/lang/Class;", - "Ljava/lang/Object;", - "[I", - "[Ljava/lang/Object;", - }; - ASSERT_EQ(arraysize(expected_types), dex_file->NumTypeIds()); - for (size_t i = 0; i != arraysize(expected_types); ++i) { - EXPECT_STREQ(expected_types[i], - dex_file->GetTypeDescriptor(dex_file->GetTypeId(dex::TypeIndex(i)))) << i; - } - - ASSERT_EQ(1u, dex_file->NumFieldIds()); - EXPECT_STREQ("[I TestClass.intField", dex_file->PrettyField(0u).c_str()); - - ASSERT_EQ(2u, dex_file->NumProtoIds()); - ASSERT_EQ(2u, dex_file->NumMethodIds()); - EXPECT_STREQ("TestClass TestClass.bar(java.lang.Object, java.lang.Object[])", - dex_file->PrettyMethod(0u).c_str()); - EXPECT_STREQ("int TestClass.foo()", - dex_file->PrettyMethod(1u).c_str()); - - EXPECT_EQ(0u, builder.GetStringIdx("Arbitrary string")); - EXPECT_EQ(2u, builder.GetTypeIdx("Ljava/lang/Class;")); - EXPECT_EQ(0u, builder.GetFieldIdx("LTestClass;", "[I", "intField")); - EXPECT_EQ(1u, builder.GetMethodIdx("LTestClass;", "()I", "foo")); - EXPECT_EQ(0u, builder.GetMethodIdx("LTestClass;", "(Ljava/lang/Object;[Ljava/lang/Object;)LTestClass;", "bar")); -} - -} // namespace art diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc index ea160c8993..42c2541421 100644 --- a/compiler/utils/x86/assembler_x86.cc +++ b/compiler/utils/x86/assembler_x86.cc @@ -913,6 +913,78 @@ void X86Assembler::psubq(XmmRegister dst, XmmRegister src) { } +void X86Assembler::paddusb(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0xDC); + EmitXmmRegisterOperand(dst, src); +} + + +void X86Assembler::paddsb(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0xEC); + EmitXmmRegisterOperand(dst, src); +} + + +void X86Assembler::paddusw(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0xDD); + EmitXmmRegisterOperand(dst, src); +} + + +void X86Assembler::paddsw(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0xED); + EmitXmmRegisterOperand(dst, src); +} + + +void X86Assembler::psubusb(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0xD8); + EmitXmmRegisterOperand(dst, src); +} + + +void X86Assembler::psubsb(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0xE8); + EmitXmmRegisterOperand(dst, src); +} + + +void X86Assembler::psubusw(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0xD9); + EmitXmmRegisterOperand(dst, src); +} + + +void X86Assembler::psubsw(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0xE9); + EmitXmmRegisterOperand(dst, src); +} + + void X86Assembler::cvtsi2ss(XmmRegister dst, Register src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0xF3); diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h index a085677083..22eaedce61 100644 --- a/compiler/utils/x86/assembler_x86.h +++ b/compiler/utils/x86/assembler_x86.h @@ -449,6 +449,15 @@ class X86Assembler FINAL : public Assembler { void paddq(XmmRegister dst, XmmRegister src); void psubq(XmmRegister dst, XmmRegister src); + void paddusb(XmmRegister dst, XmmRegister src); + void paddsb(XmmRegister dst, XmmRegister src); + void paddusw(XmmRegister dst, XmmRegister src); + void paddsw(XmmRegister dst, XmmRegister src); + void psubusb(XmmRegister dst, XmmRegister src); + void psubsb(XmmRegister dst, XmmRegister src); + void psubusw(XmmRegister dst, XmmRegister src); + void psubsw(XmmRegister dst, XmmRegister src); + void cvtsi2ss(XmmRegister dst, Register src); void cvtsi2sd(XmmRegister dst, Register src); diff --git a/compiler/utils/x86/assembler_x86_test.cc b/compiler/utils/x86/assembler_x86_test.cc index 2fd1b27182..8f72db748b 100644 --- a/compiler/utils/x86/assembler_x86_test.cc +++ b/compiler/utils/x86/assembler_x86_test.cc @@ -600,6 +600,38 @@ TEST_F(AssemblerX86Test, PSubQ) { DriverStr(RepeatFF(&x86::X86Assembler::psubq, "psubq %{reg2}, %{reg1}"), "psubq"); } +TEST_F(AssemblerX86Test, PAddUSB) { + DriverStr(RepeatFF(&x86::X86Assembler::paddusb, "paddusb %{reg2}, %{reg1}"), "paddusb"); +} + +TEST_F(AssemblerX86Test, PAddSB) { + DriverStr(RepeatFF(&x86::X86Assembler::paddsb, "paddsb %{reg2}, %{reg1}"), "paddsb"); +} + +TEST_F(AssemblerX86Test, PAddUSW) { + DriverStr(RepeatFF(&x86::X86Assembler::paddusw, "paddusw %{reg2}, %{reg1}"), "paddusw"); +} + +TEST_F(AssemblerX86Test, PAddSW) { + DriverStr(RepeatFF(&x86::X86Assembler::psubsw, "psubsw %{reg2}, %{reg1}"), "psubsw"); +} + +TEST_F(AssemblerX86Test, PSubUSB) { + DriverStr(RepeatFF(&x86::X86Assembler::psubusb, "psubusb %{reg2}, %{reg1}"), "psubusb"); +} + +TEST_F(AssemblerX86Test, PSubSB) { + DriverStr(RepeatFF(&x86::X86Assembler::psubsb, "psubsb %{reg2}, %{reg1}"), "psubsb"); +} + +TEST_F(AssemblerX86Test, PSubUSW) { + DriverStr(RepeatFF(&x86::X86Assembler::psubusw, "psubusw %{reg2}, %{reg1}"), "psubusw"); +} + +TEST_F(AssemblerX86Test, PSubSW) { + DriverStr(RepeatFF(&x86::X86Assembler::psubsw, "psubsw %{reg2}, %{reg1}"), "psubsw"); +} + TEST_F(AssemblerX86Test, XorPD) { DriverStr(RepeatFF(&x86::X86Assembler::xorpd, "xorpd %{reg2}, %{reg1}"), "xorpd"); } diff --git a/compiler/utils/x86_64/assembler_x86_64.cc b/compiler/utils/x86_64/assembler_x86_64.cc index ff5a357c5e..c6e16e754c 100644 --- a/compiler/utils/x86_64/assembler_x86_64.cc +++ b/compiler/utils/x86_64/assembler_x86_64.cc @@ -1011,6 +1011,86 @@ void X86_64Assembler::psubq(XmmRegister dst, XmmRegister src) { } +void X86_64Assembler::paddusb(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0xDC); + EmitXmmRegisterOperand(dst.LowBits(), src); +} + + +void X86_64Assembler::paddsb(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0xEC); + EmitXmmRegisterOperand(dst.LowBits(), src); +} + + +void X86_64Assembler::paddusw(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0xDD); + EmitXmmRegisterOperand(dst.LowBits(), src); +} + + +void X86_64Assembler::paddsw(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0xED); + EmitXmmRegisterOperand(dst.LowBits(), src); +} + + +void X86_64Assembler::psubusb(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0xD8); + EmitXmmRegisterOperand(dst.LowBits(), src); +} + + +void X86_64Assembler::psubsb(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0xE8); + EmitXmmRegisterOperand(dst.LowBits(), src); +} + + +void X86_64Assembler::psubusw(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0xD9); + EmitXmmRegisterOperand(dst.LowBits(), src); +} + + +void X86_64Assembler::psubsw(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0xE9); + EmitXmmRegisterOperand(dst.LowBits(), src); +} + + void X86_64Assembler::cvtsi2ss(XmmRegister dst, CpuRegister src) { cvtsi2ss(dst, src, false); } diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h index 7a5fdb502f..ab761fb1fc 100644 --- a/compiler/utils/x86_64/assembler_x86_64.h +++ b/compiler/utils/x86_64/assembler_x86_64.h @@ -485,6 +485,15 @@ class X86_64Assembler FINAL : public Assembler { void paddq(XmmRegister dst, XmmRegister src); void psubq(XmmRegister dst, XmmRegister src); + void paddusb(XmmRegister dst, XmmRegister src); + void paddsb(XmmRegister dst, XmmRegister src); + void paddusw(XmmRegister dst, XmmRegister src); + void paddsw(XmmRegister dst, XmmRegister src); + void psubusb(XmmRegister dst, XmmRegister src); + void psubsb(XmmRegister dst, XmmRegister src); + void psubusw(XmmRegister dst, XmmRegister src); + void psubsw(XmmRegister dst, XmmRegister src); + void cvtsi2ss(XmmRegister dst, CpuRegister src); // Note: this is the r/m32 version. void cvtsi2ss(XmmRegister dst, CpuRegister src, bool is64bit); void cvtsi2ss(XmmRegister dst, const Address& src, bool is64bit); diff --git a/compiler/utils/x86_64/assembler_x86_64_test.cc b/compiler/utils/x86_64/assembler_x86_64_test.cc index 6b1e53c35a..104e215cf5 100644 --- a/compiler/utils/x86_64/assembler_x86_64_test.cc +++ b/compiler/utils/x86_64/assembler_x86_64_test.cc @@ -1282,6 +1282,38 @@ TEST_F(AssemblerX86_64Test, Psubq) { DriverStr(RepeatFF(&x86_64::X86_64Assembler::psubq, "psubq %{reg2}, %{reg1}"), "psubq"); } +TEST_F(AssemblerX86_64Test, Paddusb) { + DriverStr(RepeatFF(&x86_64::X86_64Assembler::paddusb, "paddusb %{reg2}, %{reg1}"), "paddusb"); +} + +TEST_F(AssemblerX86_64Test, Paddsb) { + DriverStr(RepeatFF(&x86_64::X86_64Assembler::paddsb, "paddsb %{reg2}, %{reg1}"), "paddsb"); +} + +TEST_F(AssemblerX86_64Test, Paddusw) { + DriverStr(RepeatFF(&x86_64::X86_64Assembler::paddusw, "paddusw %{reg2}, %{reg1}"), "paddusw"); +} + +TEST_F(AssemblerX86_64Test, Paddsw) { + DriverStr(RepeatFF(&x86_64::X86_64Assembler::paddsw, "paddsw %{reg2}, %{reg1}"), "paddsw"); +} + +TEST_F(AssemblerX86_64Test, Psubusb) { + DriverStr(RepeatFF(&x86_64::X86_64Assembler::psubusb, "psubusb %{reg2}, %{reg1}"), "psubusb"); +} + +TEST_F(AssemblerX86_64Test, Psubsb) { + DriverStr(RepeatFF(&x86_64::X86_64Assembler::psubsb, "psubsb %{reg2}, %{reg1}"), "psubsb"); +} + +TEST_F(AssemblerX86_64Test, Psubusw) { + DriverStr(RepeatFF(&x86_64::X86_64Assembler::psubusw, "psubusw %{reg2}, %{reg1}"), "psubusw"); +} + +TEST_F(AssemblerX86_64Test, Psubsw) { + DriverStr(RepeatFF(&x86_64::X86_64Assembler::psubsw, "psubsw %{reg2}, %{reg1}"), "psubsw"); +} + TEST_F(AssemblerX86_64Test, Cvtsi2ss) { DriverStr(RepeatFr(&x86_64::X86_64Assembler::cvtsi2ss, "cvtsi2ss %{reg2}, %{reg1}"), "cvtsi2ss"); } |