codegen_test.cc revision 39d57e2de8ec7420f2395a28cd7bd51e658d57b8
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 if (has_result) { 61 CHECK_EQ(result, expected); 62 } 63#endif 64 CHECK(CodeGenerator::CompileGraph(graph, kArm, &allocator)); 65#if defined(__arm__) 66 int32_t result = reinterpret_cast<fptr>(allocator.memory())(); 67 if (has_result) { 68 CHECK_EQ(result, expected); 69 } 70#endif 71} 72 73TEST(CodegenTest, ReturnVoid) { 74 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(Instruction::RETURN_VOID); 75 TestCode(data); 76} 77 78TEST(CodegenTest, CFG1) { 79 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM( 80 Instruction::GOTO | 0x100, 81 Instruction::RETURN_VOID); 82 83 TestCode(data); 84} 85 86TEST(CodegenTest, CFG2) { 87 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM( 88 Instruction::GOTO | 0x100, 89 Instruction::GOTO | 0x100, 90 Instruction::RETURN_VOID); 91 92 TestCode(data); 93} 94 95TEST(CodegenTest, CFG3) { 96 const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM( 97 Instruction::GOTO | 0x200, 98 Instruction::RETURN_VOID, 99 Instruction::GOTO | 0xFF00); 100 101 TestCode(data1); 102 103 const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM( 104 Instruction::GOTO_16, 3, 105 Instruction::RETURN_VOID, 106 Instruction::GOTO_16, 0xFFFF); 107 108 TestCode(data2); 109 110 const uint16_t data3[] = ZERO_REGISTER_CODE_ITEM( 111 Instruction::GOTO_32, 4, 0, 112 Instruction::RETURN_VOID, 113 Instruction::GOTO_32, 0xFFFF, 0xFFFF); 114 115 TestCode(data3); 116} 117 118TEST(CodegenTest, CFG4) { 119 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM( 120 Instruction::RETURN_VOID, 121 Instruction::GOTO | 0x100, 122 Instruction::GOTO | 0xFE00); 123 124 TestCode(data); 125} 126 127TEST(CodegenTest, CFG5) { 128 const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 129 Instruction::CONST_4 | 0 | 0, 130 Instruction::IF_EQ, 3, 131 Instruction::GOTO | 0x100, 132 Instruction::RETURN_VOID); 133 134 TestCode(data); 135} 136 137TEST(CodegenTest, IntConstant) { 138 const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 139 Instruction::CONST_4 | 0 | 0, 140 Instruction::RETURN_VOID); 141 142 TestCode(data); 143} 144 145TEST(CodegenTest, Return1) { 146 const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 147 Instruction::CONST_4 | 0 | 0, 148 Instruction::RETURN | 0); 149 150 TestCode(data, true, 0); 151} 152 153TEST(CodegenTest, Return2) { 154 const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 155 Instruction::CONST_4 | 0 | 0, 156 Instruction::CONST_4 | 0 | 1 << 8, 157 Instruction::RETURN | 1 << 8); 158 159 TestCode(data, true, 0); 160} 161 162TEST(CodegenTest, Return3) { 163 const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 164 Instruction::CONST_4 | 0 | 0, 165 Instruction::CONST_4 | 1 << 8 | 1 << 12, 166 Instruction::RETURN | 1 << 8); 167 168 TestCode(data, true, 1); 169} 170 171TEST(CodegenTest, ReturnIf1) { 172 const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 173 Instruction::CONST_4 | 0 | 0, 174 Instruction::CONST_4 | 1 << 8 | 1 << 12, 175 Instruction::IF_EQ, 3, 176 Instruction::RETURN | 0 << 8, 177 Instruction::RETURN | 1 << 8); 178 179 TestCode(data, true, 1); 180} 181 182TEST(CodegenTest, ReturnIf2) { 183 const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 184 Instruction::CONST_4 | 0 | 0, 185 Instruction::CONST_4 | 1 << 8 | 1 << 12, 186 Instruction::IF_EQ | 0 << 4 | 1 << 8, 3, 187 Instruction::RETURN | 0 << 8, 188 Instruction::RETURN | 1 << 8); 189 190 TestCode(data, true, 0); 191} 192 193} // namespace art 194