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 "optimizing/optimizing_unit_test.h" 25 #include "utils/assembler.h" 26 27 #include "optimizing/optimizing_cfi_test_expected.inc" 28 29 namespace art { 30 31 // Run the tests only on host. 32 #ifndef HAVE_ANDROID_OS 33 34 class OptimizingCFITest : public CFITest { 35 public: 36 // Enable this flag to generate the expected outputs. 37 static constexpr bool kGenerateExpected = false; 38 39 void TestImpl(InstructionSet isa, const char* isa_str, 40 const std::vector<uint8_t>& expected_asm, 41 const std::vector<uint8_t>& expected_cfi) { 42 // Setup simple context. 43 ArenaPool pool; 44 ArenaAllocator allocator(&pool); 45 CompilerOptions opts; 46 std::unique_ptr<const InstructionSetFeatures> isa_features; 47 std::string error; 48 isa_features.reset(InstructionSetFeatures::FromVariant(isa, "default", &error)); 49 HGraph* graph = CreateGraph(&allocator); 50 // Generate simple frame with some spills. 51 std::unique_ptr<CodeGenerator> code_gen( 52 CodeGenerator::Create(graph, isa, *isa_features.get(), opts)); 53 const int frame_size = 64; 54 int core_reg = 0; 55 int fp_reg = 0; 56 for (int i = 0; i < 2; i++) { // Two registers of each kind. 57 for (; core_reg < 32; core_reg++) { 58 if (code_gen->IsCoreCalleeSaveRegister(core_reg)) { 59 auto location = Location::RegisterLocation(core_reg); 60 code_gen->AddAllocatedRegister(location); 61 core_reg++; 62 break; 63 } 64 } 65 for (; fp_reg < 32; fp_reg++) { 66 if (code_gen->IsFloatingPointCalleeSaveRegister(fp_reg)) { 67 auto location = Location::FpuRegisterLocation(fp_reg); 68 code_gen->AddAllocatedRegister(location); 69 fp_reg++; 70 break; 71 } 72 } 73 } 74 code_gen->ComputeSpillMask(); 75 code_gen->SetFrameSize(frame_size); 76 code_gen->GenerateFrameEntry(); 77 code_gen->GenerateFrameExit(); 78 // Get the outputs. 79 InternalCodeAllocator code_allocator; 80 code_gen->Finalize(&code_allocator); 81 const std::vector<uint8_t>& actual_asm = code_allocator.GetMemory(); 82 Assembler* opt_asm = code_gen->GetAssembler(); 83 const std::vector<uint8_t>& actual_cfi = *(opt_asm->cfi().data()); 84 85 if (kGenerateExpected) { 86 GenerateExpected(stdout, isa, isa_str, actual_asm, actual_cfi); 87 } else { 88 EXPECT_EQ(expected_asm, actual_asm); 89 EXPECT_EQ(expected_cfi, actual_cfi); 90 } 91 } 92 93 private: 94 class InternalCodeAllocator : public CodeAllocator { 95 public: 96 InternalCodeAllocator() {} 97 98 virtual uint8_t* Allocate(size_t size) { 99 memory_.resize(size); 100 return memory_.data(); 101 } 102 103 const std::vector<uint8_t>& GetMemory() { return memory_; } 104 105 private: 106 std::vector<uint8_t> memory_; 107 108 DISALLOW_COPY_AND_ASSIGN(InternalCodeAllocator); 109 }; 110 }; 111 112 #define TEST_ISA(isa) \ 113 TEST_F(OptimizingCFITest, isa) { \ 114 std::vector<uint8_t> expected_asm(expected_asm_##isa, \ 115 expected_asm_##isa + arraysize(expected_asm_##isa)); \ 116 std::vector<uint8_t> expected_cfi(expected_cfi_##isa, \ 117 expected_cfi_##isa + arraysize(expected_cfi_##isa)); \ 118 TestImpl(isa, #isa, expected_asm, expected_cfi); \ 119 } 120 121 TEST_ISA(kThumb2) 122 TEST_ISA(kArm64) 123 TEST_ISA(kX86) 124 TEST_ISA(kX86_64) 125 126 #endif // HAVE_ANDROID_OS 127 128 } // namespace art 129