summaryrefslogtreecommitdiff
path: root/compiler/utils
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/utils')
-rw-r--r--compiler/utils/assembler_test_base.h2
-rw-r--r--compiler/utils/atomic_dex_ref_map-inl.h6
-rw-r--r--compiler/utils/atomic_dex_ref_map.h3
-rw-r--r--compiler/utils/atomic_dex_ref_map_test.cc2
-rw-r--r--compiler/utils/mips/assembler_mips.cc20
-rw-r--r--compiler/utils/mips/assembler_mips.h5
-rw-r--r--compiler/utils/mips/assembler_mips32r6_test.cc16
-rw-r--r--compiler/utils/mips64/assembler_mips64.cc20
-rw-r--r--compiler/utils/mips64/assembler_mips64.h5
-rw-r--r--compiler/utils/mips64/assembler_mips64_test.cc16
-rw-r--r--compiler/utils/string_reference_test.cc110
-rw-r--r--compiler/utils/swap_space_test.cc2
-rw-r--r--compiler/utils/test_dex_file_builder.h402
-rw-r--r--compiler/utils/test_dex_file_builder_test.cc87
-rw-r--r--compiler/utils/x86/assembler_x86.cc72
-rw-r--r--compiler/utils/x86/assembler_x86.h9
-rw-r--r--compiler/utils/x86/assembler_x86_test.cc32
-rw-r--r--compiler/utils/x86_64/assembler_x86_64.cc80
-rw-r--r--compiler/utils/x86_64/assembler_x86_64.h9
-rw-r--r--compiler/utils/x86_64/assembler_x86_64_test.cc32
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");
}