diff options
| author | 2018-11-21 18:57:54 +0000 | |
|---|---|---|
| committer | 2018-12-03 18:43:48 +0000 | |
| commit | aa6f48362b3258a5df5e527987ffe7e068eb4a79 (patch) | |
| tree | 0fa8cfbebb77d2e7796084721c836b44114bdc97 | |
| parent | 8bda21f1d8bbc1060bf693f5d1666d3396d1cb69 (diff) | |
ART: ARM64: Pass ISA features to VIXL macroassembler.
VIXL macroassembler should be initialized properly
to support Armv8.X features in order to emit corresponding
instructions.
Test: codegen_test.cc, relative_patcher_arm64_test.
Test: test-art-host, test-art-target.
Change-Id: I2f9e155c28b4d2252a3cfb19717f5d25824d5e11
| -rw-r--r-- | compiler/driver/compiler_options.h | 5 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 3 | ||||
| -rw-r--r-- | compiler/optimizing/codegen_test.cc | 27 | ||||
| -rw-r--r-- | compiler/utils/arm64/assembler_arm64.cc | 32 | ||||
| -rw-r--r-- | compiler/utils/arm64/assembler_arm64.h | 6 | ||||
| -rw-r--r-- | dex2oat/linker/arm64/relative_patcher_arm64_test.cc | 7 |
6 files changed, 78 insertions, 2 deletions
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h index 17a779c965..a8f246dcab 100644 --- a/compiler/driver/compiler_options.h +++ b/compiler/driver/compiler_options.h @@ -39,6 +39,10 @@ namespace verifier { class VerifierDepsTest; } // namespace verifier +namespace linker { +class Arm64RelativePatcherTest; +} // namespace linker + class DexFile; enum class InstructionSet; class InstructionSetFeatures; @@ -450,6 +454,7 @@ class CompilerOptions final { friend class CommonCompilerTest; friend class jit::JitCompiler; friend class verifier::VerifierDepsTest; + friend class linker::Arm64RelativePatcherTest; template <class Base> friend bool ReadCompilerOptions(Base& map, CompilerOptions* options, std::string* error_msg); diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index bbf167d615..9e2fd9ef84 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -885,7 +885,8 @@ CodeGeneratorARM64::CodeGeneratorARM64(HGraph* graph, location_builder_(graph, this), instruction_visitor_(graph, this), move_resolver_(graph->GetAllocator(), this), - assembler_(graph->GetAllocator()), + assembler_(graph->GetAllocator(), + compiler_options.GetInstructionSetFeatures()->AsArm64InstructionSetFeatures()), uint32_literals_(std::less<uint32_t>(), graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)), uint64_literals_(std::less<uint64_t>(), diff --git a/compiler/optimizing/codegen_test.cc b/compiler/optimizing/codegen_test.cc index f186191a0f..b5a7c137f6 100644 --- a/compiler/optimizing/codegen_test.cc +++ b/compiler/optimizing/codegen_test.cc @@ -823,6 +823,33 @@ TEST_F(CodegenTest, ARM64ParallelMoveResolverSIMD) { InternalCodeAllocator code_allocator; codegen.Finalize(&code_allocator); } + +// Check that ART ISA Features are propagated to VIXL for arm64 (using cortex-a75 as example). +TEST_F(CodegenTest, ARM64IsaVIXLFeaturesA75) { + OverrideInstructionSetFeatures(InstructionSet::kArm64, "cortex-a75"); + HGraph* graph = CreateGraph(); + arm64::CodeGeneratorARM64 codegen(graph, *compiler_options_); + vixl::CPUFeatures* features = codegen.GetVIXLAssembler()->GetCPUFeatures(); + + EXPECT_TRUE(features->Has(vixl::CPUFeatures::kCRC32)); + EXPECT_TRUE(features->Has(vixl::CPUFeatures::kDotProduct)); + EXPECT_TRUE(features->Has(vixl::CPUFeatures::kFPHalf)); + EXPECT_TRUE(features->Has(vixl::CPUFeatures::kAtomics)); +} + +// Check that ART ISA Features are propagated to VIXL for arm64 (using cortex-a53 as example). +TEST_F(CodegenTest, ARM64IsaVIXLFeaturesA53) { + OverrideInstructionSetFeatures(InstructionSet::kArm64, "cortex-a53"); + HGraph* graph = CreateGraph(); + arm64::CodeGeneratorARM64 codegen(graph, *compiler_options_); + vixl::CPUFeatures* features = codegen.GetVIXLAssembler()->GetCPUFeatures(); + + EXPECT_TRUE(features->Has(vixl::CPUFeatures::kCRC32)); + EXPECT_FALSE(features->Has(vixl::CPUFeatures::kDotProduct)); + EXPECT_FALSE(features->Has(vixl::CPUFeatures::kFPHalf)); + EXPECT_FALSE(features->Has(vixl::CPUFeatures::kAtomics)); +} + #endif #ifdef ART_ENABLE_CODEGEN_mips diff --git a/compiler/utils/arm64/assembler_arm64.cc b/compiler/utils/arm64/assembler_arm64.cc index c83fd4404a..d7ade058a4 100644 --- a/compiler/utils/arm64/assembler_arm64.cc +++ b/compiler/utils/arm64/assembler_arm64.cc @@ -14,6 +14,7 @@ * limitations under the License. */ +#include "arch/arm64/instruction_set_features_arm64.h" #include "assembler_arm64.h" #include "entrypoints/quick/quick_entrypoints.h" #include "heap_poisoning.h" @@ -31,6 +32,37 @@ namespace arm64 { #define ___ vixl_masm_. #endif +// Sets vixl::CPUFeatures according to ART instruction set features. +static void SetVIXLCPUFeaturesFromART(vixl::aarch64::MacroAssembler* vixl_masm_, + const Arm64InstructionSetFeatures* art_features) { + // Retrieve already initialized default features of vixl. + vixl::CPUFeatures* features = vixl_masm_->GetCPUFeatures(); + + DCHECK(features->Has(vixl::CPUFeatures::kFP)); + DCHECK(features->Has(vixl::CPUFeatures::kNEON)); + DCHECK(art_features != nullptr); + if (art_features->HasCRC()) { + features->Combine(vixl::CPUFeatures::kCRC32); + } + if (art_features->HasDotProd()) { + features->Combine(vixl::CPUFeatures::kDotProduct); + } + if (art_features->HasFP16()) { + features->Combine(vixl::CPUFeatures::kFPHalf); + } + if (art_features->HasLSE()) { + features->Combine(vixl::CPUFeatures::kAtomics); + } +} + +Arm64Assembler::Arm64Assembler(ArenaAllocator* allocator, + const Arm64InstructionSetFeatures* art_features) + : Assembler(allocator) { + if (art_features != nullptr) { + SetVIXLCPUFeaturesFromART(&vixl_masm_, art_features); + } +} + void Arm64Assembler::FinalizeCode() { ___ FinalizeCode(); } diff --git a/compiler/utils/arm64/assembler_arm64.h b/compiler/utils/arm64/assembler_arm64.h index 74537dd5a3..fdecab8251 100644 --- a/compiler/utils/arm64/assembler_arm64.h +++ b/compiler/utils/arm64/assembler_arm64.h @@ -37,6 +37,9 @@ #pragma GCC diagnostic pop namespace art { + +class Arm64InstructionSetFeatures; + namespace arm64 { #define MEM_OP(...) vixl::aarch64::MemOperand(__VA_ARGS__) @@ -63,7 +66,8 @@ enum StoreOperandType { class Arm64Assembler final : public Assembler { public: - explicit Arm64Assembler(ArenaAllocator* allocator) : Assembler(allocator) {} + explicit Arm64Assembler( + ArenaAllocator* allocator, const Arm64InstructionSetFeatures* features = nullptr); virtual ~Arm64Assembler() {} diff --git a/dex2oat/linker/arm64/relative_patcher_arm64_test.cc b/dex2oat/linker/arm64/relative_patcher_arm64_test.cc index f242ae286b..9e91c6568a 100644 --- a/dex2oat/linker/arm64/relative_patcher_arm64_test.cc +++ b/dex2oat/linker/arm64/relative_patcher_arm64_test.cc @@ -177,6 +177,13 @@ class Arm64RelativePatcherTest : public RelativePatcherTest { OptimizingUnitTestHelper helper; HGraph* graph = helper.CreateGraph(); CompilerOptions compiler_options; + + // Set isa to arm64. + compiler_options.instruction_set_ = instruction_set_; + compiler_options.instruction_set_features_ = + InstructionSetFeatures::FromBitmap(instruction_set_, instruction_set_features_->AsBitmap()); + CHECK(compiler_options.instruction_set_features_->Equals(instruction_set_features_.get())); + arm64::CodeGeneratorARM64 codegen(graph, compiler_options); ArenaVector<uint8_t> code(helper.GetAllocator()->Adapter()); codegen.EmitThunkCode(patch, &code, debug_name); |