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