1c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky/* 2c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky * Copyright (C) 2015 The Android Open Source Project 3c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky * 4c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky * Licensed under the Apache License, Version 2.0 (the "License"); 5c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky * you may not use this file except in compliance with the License. 6c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky * You may obtain a copy of the License at 7c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky * 8c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky * http://www.apache.org/licenses/LICENSE-2.0 9c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky * 10c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky * Unless required by applicable law or agreed to in writing, software 11c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky * distributed under the License is distributed on an "AS IS" BASIS, 12c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky * See the License for the specific language governing permissions and 14c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky * limitations under the License. 15c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky */ 16c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky 17c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky#include <memory> 18c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky#include <vector> 19c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky 20c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky#include "arch/instruction_set.h" 21c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky#include "cfi_test.h" 22c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky#include "gtest/gtest.h" 23c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky#include "optimizing/code_generator.h" 240a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray#include "optimizing/optimizing_unit_test.h" 25c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky#include "utils/assembler.h" 26c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky 27c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky#include "optimizing/optimizing_cfi_test_expected.inc" 28c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky 29c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbeckynamespace art { 30c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky 31c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky// Run the tests only on host. 32c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky#ifndef HAVE_ANDROID_OS 33c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky 343d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartierclass OptimizingCFITest : public CFITest { 35c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky public: 36c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky // Enable this flag to generate the expected outputs. 37c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky static constexpr bool kGenerateExpected = false; 38c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky 39c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky void TestImpl(InstructionSet isa, const char* isa_str, 40c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky const std::vector<uint8_t>& expected_asm, 41c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky const std::vector<uint8_t>& expected_cfi) { 42c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky // Setup simple context. 43c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky ArenaPool pool; 44c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky ArenaAllocator allocator(&pool); 45c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky CompilerOptions opts; 46c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky std::unique_ptr<const InstructionSetFeatures> isa_features; 47c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky std::string error; 48c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky isa_features.reset(InstructionSetFeatures::FromVariant(isa, "default", &error)); 490a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray HGraph* graph = CreateGraph(&allocator); 50c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky // Generate simple frame with some spills. 5146325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky std::unique_ptr<CodeGenerator> code_gen( 520a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray CodeGenerator::Create(graph, isa, *isa_features.get(), opts)); 53c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky const int frame_size = 64; 54c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky int core_reg = 0; 55c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky int fp_reg = 0; 56c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky for (int i = 0; i < 2; i++) { // Two registers of each kind. 57c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky for (; core_reg < 32; core_reg++) { 58c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky if (code_gen->IsCoreCalleeSaveRegister(core_reg)) { 59c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky auto location = Location::RegisterLocation(core_reg); 60c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky code_gen->AddAllocatedRegister(location); 61c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky core_reg++; 62c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky break; 63c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky } 64c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky } 65c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky for (; fp_reg < 32; fp_reg++) { 66c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky if (code_gen->IsFloatingPointCalleeSaveRegister(fp_reg)) { 67c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky auto location = Location::FpuRegisterLocation(fp_reg); 68c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky code_gen->AddAllocatedRegister(location); 69c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky fp_reg++; 70c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky break; 71c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky } 72c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky } 73c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky } 74c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky code_gen->ComputeSpillMask(); 75c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky code_gen->SetFrameSize(frame_size); 76c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky code_gen->GenerateFrameEntry(); 77c34dc9362b9ec624b3bdd97d36b6b2098814cd73David Srbecky code_gen->GenerateFrameExit(); 78c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky // Get the outputs. 7946325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky InternalCodeAllocator code_allocator; 8046325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky code_gen->Finalize(&code_allocator); 8146325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky const std::vector<uint8_t>& actual_asm = code_allocator.GetMemory(); 82c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky Assembler* opt_asm = code_gen->GetAssembler(); 83c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky const std::vector<uint8_t>& actual_cfi = *(opt_asm->cfi().data()); 84c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky 85c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky if (kGenerateExpected) { 86c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky GenerateExpected(stdout, isa, isa_str, actual_asm, actual_cfi); 87c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky } else { 88c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky EXPECT_EQ(expected_asm, actual_asm); 89c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky EXPECT_EQ(expected_cfi, actual_cfi); 90c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky } 91c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky } 9246325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky 9346325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky private: 9446325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky class InternalCodeAllocator : public CodeAllocator { 9546325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky public: 9646325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky InternalCodeAllocator() {} 9746325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky 9846325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky virtual uint8_t* Allocate(size_t size) { 9946325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky memory_.resize(size); 10046325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky return memory_.data(); 10146325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky } 10246325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky 10346325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky const std::vector<uint8_t>& GetMemory() { return memory_; } 10446325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky 10546325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky private: 10646325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky std::vector<uint8_t> memory_; 10746325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky 10846325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky DISALLOW_COPY_AND_ASSIGN(InternalCodeAllocator); 10946325a0fae06ccbf5e0d7a7dd34d6cfe49226a40David Srbecky }; 110c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky}; 111c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky 112c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky#define TEST_ISA(isa) \ 113c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky TEST_F(OptimizingCFITest, isa) { \ 114c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky std::vector<uint8_t> expected_asm(expected_asm_##isa, \ 115c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky expected_asm_##isa + arraysize(expected_asm_##isa)); \ 116c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky std::vector<uint8_t> expected_cfi(expected_cfi_##isa, \ 117c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky expected_cfi_##isa + arraysize(expected_cfi_##isa)); \ 118c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky TestImpl(isa, #isa, expected_asm, expected_cfi); \ 119c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky } 120c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky 121c6b4dd8980350aaf250f0185f73e9c42ec17cd57David SrbeckyTEST_ISA(kThumb2) 122c6b4dd8980350aaf250f0185f73e9c42ec17cd57David SrbeckyTEST_ISA(kArm64) 123c6b4dd8980350aaf250f0185f73e9c42ec17cd57David SrbeckyTEST_ISA(kX86) 124c6b4dd8980350aaf250f0185f73e9c42ec17cd57David SrbeckyTEST_ISA(kX86_64) 125c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky 126c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky#endif // HAVE_ANDROID_OS 127c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky 128c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky} // namespace art 129