codegen_test.cc revision bab4ed7057799a4fadc6283108ab56f389d117d4
1/* 2 * Copyright (C) 2014 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 "builder.h" 18#include "code_generator.h" 19#include "common_compiler_test.h" 20#include "dex_file.h" 21#include "dex_instruction.h" 22#include "instruction_set.h" 23#include "nodes.h" 24#include "optimizing_unit_test.h" 25 26#include "gtest/gtest.h" 27 28namespace art { 29 30class ExecutableMemoryAllocator : public CodeAllocator { 31 public: 32 ExecutableMemoryAllocator() { } 33 34 virtual uint8_t* Allocate(size_t size) { 35 memory_.reset(new uint8_t[size]); 36 CommonCompilerTest::MakeExecutable(memory_.get(), size); 37 return memory_.get(); 38 } 39 40 uint8_t* memory() const { return memory_.get(); } 41 42 private: 43 UniquePtr<uint8_t[]> memory_; 44 45 DISALLOW_COPY_AND_ASSIGN(ExecutableMemoryAllocator); 46}; 47 48static void TestCode(const uint16_t* data, bool has_result = false, int32_t expected = 0) { 49 ArenaPool pool; 50 ArenaAllocator arena(&pool); 51 HGraphBuilder builder(&arena); 52 const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data); 53 HGraph* graph = builder.BuildGraph(*item); 54 ASSERT_NE(graph, nullptr); 55 ExecutableMemoryAllocator allocator; 56 CHECK(CodeGenerator::CompileGraph(graph, kX86, &allocator)); 57 typedef int32_t (*fptr)(); 58#if defined(__i386__) 59 int32_t result = reinterpret_cast<fptr>(allocator.memory())(); 60#endif 61 CHECK(CodeGenerator::CompileGraph(graph, kArm, &allocator)); 62#if defined(__arm__) 63 int32_t result = reinterpret_cast<fptr>(allocator.memory())(); 64#endif 65 if (has_result) { 66 CHECK_EQ(result, expected); 67 } 68} 69 70TEST(CodegenTest, ReturnVoid) { 71 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(Instruction::RETURN_VOID); 72 TestCode(data); 73} 74 75TEST(CodegenTest, CFG1) { 76 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM( 77 Instruction::GOTO | 0x100, 78 Instruction::RETURN_VOID); 79 80 TestCode(data); 81} 82 83TEST(CodegenTest, CFG2) { 84 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM( 85 Instruction::GOTO | 0x100, 86 Instruction::GOTO | 0x100, 87 Instruction::RETURN_VOID); 88 89 TestCode(data); 90} 91 92TEST(CodegenTest, CFG3) { 93 const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM( 94 Instruction::GOTO | 0x200, 95 Instruction::RETURN_VOID, 96 Instruction::GOTO | 0xFF00); 97 98 TestCode(data1); 99 100 const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM( 101 Instruction::GOTO_16, 3, 102 Instruction::RETURN_VOID, 103 Instruction::GOTO_16, 0xFFFF); 104 105 TestCode(data2); 106 107 const uint16_t data3[] = ZERO_REGISTER_CODE_ITEM( 108 Instruction::GOTO_32, 4, 0, 109 Instruction::RETURN_VOID, 110 Instruction::GOTO_32, 0xFFFF, 0xFFFF); 111 112 TestCode(data3); 113} 114 115TEST(CodegenTest, CFG4) { 116 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM( 117 Instruction::RETURN_VOID, 118 Instruction::GOTO | 0x100, 119 Instruction::GOTO | 0xFE00); 120 121 TestCode(data); 122} 123 124TEST(CodegenTest, CFG5) { 125 const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 126 Instruction::CONST_4 | 0 | 0, 127 Instruction::IF_EQ, 3, 128 Instruction::GOTO | 0x100, 129 Instruction::RETURN_VOID); 130 131 TestCode(data); 132} 133 134TEST(CodegenTest, IntConstant) { 135 const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 136 Instruction::CONST_4 | 0 | 0, 137 Instruction::RETURN_VOID); 138 139 TestCode(data); 140} 141 142TEST(CodegenTest, Return1) { 143 const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 144 Instruction::CONST_4 | 0 | 0, 145 Instruction::RETURN | 0); 146 147 TestCode(data, true, 0); 148} 149 150TEST(CodegenTest, Return2) { 151 const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 152 Instruction::CONST_4 | 0 | 0, 153 Instruction::CONST_4 | 0 | 1 << 8, 154 Instruction::RETURN | 1 << 8); 155 156 TestCode(data, true, 0); 157} 158 159TEST(CodegenTest, Return3) { 160 const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 161 Instruction::CONST_4 | 0 | 0, 162 Instruction::CONST_4 | 1 << 8 | 1 << 12, 163 Instruction::RETURN | 1 << 8); 164 165 TestCode(data, true, 1); 166} 167 168TEST(CodegenTest, ReturnIf1) { 169 const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 170 Instruction::CONST_4 | 0 | 0, 171 Instruction::CONST_4 | 1 << 8 | 1 << 12, 172 Instruction::IF_EQ, 3, 173 Instruction::RETURN | 0 << 8, 174 Instruction::RETURN | 1 << 8); 175 176 TestCode(data, true, 1); 177} 178 179TEST(CodegenTest, ReturnIf2) { 180 const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 181 Instruction::CONST_4 | 0 | 0, 182 Instruction::CONST_4 | 1 << 8 | 1 << 12, 183 Instruction::IF_EQ | 0 << 4 | 1 << 8, 3, 184 Instruction::RETURN | 0 << 8, 185 Instruction::RETURN | 1 << 8); 186 187 TestCode(data, true, 0); 188} 189 190} // namespace art 191