Home | History | Annotate | Download | only in optimizing
      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