1d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray/* 2d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * Copyright (C) 2014 The Android Open Source Project 3d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * 4d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License"); 5d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * you may not use this file except in compliance with the License. 6d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * You may obtain a copy of the License at 7d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * 8d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * http://www.apache.org/licenses/LICENSE-2.0 9d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * 10d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * Unless required by applicable law or agreed to in writing, software 11d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS, 12d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * See the License for the specific language governing permissions and 14d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * limitations under the License. 15d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray */ 16d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 17360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray#include <functional> 18360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 19d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "arch/instruction_set.h" 203416601a9e9be81bb7494864287fd3602d18ef13Calin Juravle#include "arch/arm/instruction_set_features_arm.h" 215da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray#include "arch/arm/registers_arm.h" 22579885a26d761f5ba9550f2a1cd7f0f598c2e1e3Serban Constantinescu#include "arch/arm64/instruction_set_features_arm64.h" 23f652cecb984c104d44a0223c3c98400ef8ed8ce2Goran Jakovljevic#include "arch/mips/instruction_set_features_mips.h" 24f652cecb984c104d44a0223c3c98400ef8ed8ce2Goran Jakovljevic#include "arch/mips/registers_mips.h" 254dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#include "arch/mips64/instruction_set_features_mips64.h" 264dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#include "arch/mips64/registers_mips64.h" 27fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell#include "arch/x86/instruction_set_features_x86.h" 285da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray#include "arch/x86/registers_x86.h" 29fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell#include "arch/x86_64/instruction_set_features_x86_64.h" 30927307433af0a9322e8ba77eda37168512a73683Alexandre Rames#include "base/macros.h" 31d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "builder.h" 328a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray#include "code_generator_arm.h" 335319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "code_generator_arm64.h" 34f652cecb984c104d44a0223c3c98400ef8ed8ce2Goran Jakovljevic#include "code_generator_mips.h" 354dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#include "code_generator_mips64.h" 368a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray#include "code_generator_x86.h" 378a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray#include "code_generator_x86_64.h" 38751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang#include "code_simulator_container.h" 39d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "common_compiler_test.h" 403ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray#include "dex_file.h" 41d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "dex_instruction.h" 42cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle#include "driver/compiler_options.h" 4358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil#include "graph_checker.h" 44d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "nodes.h" 453ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray#include "optimizing_unit_test.h" 46360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray#include "prepare_for_register_allocation.h" 47360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray#include "register_allocator.h" 48360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray#include "ssa_liveness_analysis.h" 4955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain#include "utils.h" 505da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray#include "utils/arm/managed_register_arm.h" 51f652cecb984c104d44a0223c3c98400ef8ed8ce2Goran Jakovljevic#include "utils/mips/managed_register_mips.h" 524dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze#include "utils/mips64/managed_register_mips64.h" 535da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray#include "utils/x86/managed_register_x86.h" 54d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 55d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "gtest/gtest.h" 56e6362281bb4586f45fd927e9cd1b3b14c6b037edNicolas Geoffray 57d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffraynamespace art { 58d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 59a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray// Provide our own codegen, that ensures the C calling conventions 60a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray// are preserved. Currently, ART and C do not match as R4 is caller-save 61a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray// in ART, and callee-save in C. Alternatively, we could use or write 62a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray// the stub that saves and restores all registers, but it is easier 63a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray// to just overwrite the code generator. 64a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffrayclass TestCodeGeneratorARM : public arm::CodeGeneratorARM { 65a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray public: 66a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray TestCodeGeneratorARM(HGraph* graph, 67a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray const ArmInstructionSetFeatures& isa_features, 68a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray const CompilerOptions& compiler_options) 69a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray : arm::CodeGeneratorARM(graph, isa_features, compiler_options) { 705da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray AddAllocatedRegister(Location::RegisterLocation(arm::R6)); 715da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray AddAllocatedRegister(Location::RegisterLocation(arm::R7)); 72a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray } 73a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray 7458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil void SetupBlockedRegisters() const OVERRIDE { 7558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil arm::CodeGeneratorARM::SetupBlockedRegisters(); 765da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray blocked_core_registers_[arm::R4] = true; 775da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray blocked_core_registers_[arm::R6] = false; 785da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray blocked_core_registers_[arm::R7] = false; 79e6362281bb4586f45fd927e9cd1b3b14c6b037edNicolas Geoffray // Makes pair R6-R7 available. 805da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray blocked_register_pairs_[arm::R6_R7] = false; 815da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray } 825da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray}; 835da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray 845da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffrayclass TestCodeGeneratorX86 : public x86::CodeGeneratorX86 { 855da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray public: 865da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray TestCodeGeneratorX86(HGraph* graph, 875da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray const X86InstructionSetFeatures& isa_features, 885da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray const CompilerOptions& compiler_options) 895da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray : x86::CodeGeneratorX86(graph, isa_features, compiler_options) { 905da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray // Save edi, we need it for getting enough registers for long multiplication. 915da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray AddAllocatedRegister(Location::RegisterLocation(x86::EDI)); 925da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray } 935da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray 9458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil void SetupBlockedRegisters() const OVERRIDE { 9558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil x86::CodeGeneratorX86::SetupBlockedRegisters(); 965da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray // ebx is a callee-save register in C, but caller-save for ART. 975da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray blocked_core_registers_[x86::EBX] = true; 985da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray blocked_register_pairs_[x86::EAX_EBX] = true; 995da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray blocked_register_pairs_[x86::EDX_EBX] = true; 1005da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray blocked_register_pairs_[x86::ECX_EBX] = true; 1015da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray blocked_register_pairs_[x86::EBX_EDI] = true; 1025da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray 1035da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray // Make edi available. 1045da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray blocked_core_registers_[x86::EDI] = false; 1055da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray blocked_register_pairs_[x86::ECX_EDI] = false; 106a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray } 107a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray}; 108a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray 109787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffrayclass InternalCodeAllocator : public CodeAllocator { 110d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray public: 111d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers InternalCodeAllocator() : size_(0) { } 112d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 113d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray virtual uint8_t* Allocate(size_t size) { 114787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray size_ = size; 115d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray memory_.reset(new uint8_t[size]); 116d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray return memory_.get(); 117d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray } 118d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 119787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray size_t GetSize() const { return size_; } 120787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray uint8_t* GetMemory() const { return memory_.get(); } 121d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 122d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray private: 123787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray size_t size_; 124700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<uint8_t[]> memory_; 125d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 126787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray DISALLOW_COPY_AND_ASSIGN(InternalCodeAllocator); 127d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray}; 128d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 129751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wangstatic bool CanExecuteOnHardware(InstructionSet target_isa) { 130751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang return (target_isa == kRuntimeISA) 131751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang // Handle the special case of ARM, with two instructions sets (ARM32 and Thumb-2). 132751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang || (kRuntimeISA == kArm && target_isa == kThumb2); 133751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang} 134751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang 135751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wangstatic bool CanExecute(InstructionSet target_isa) { 136751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang CodeSimulatorContainer simulator(target_isa); 137751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang return CanExecuteOnHardware(target_isa) || simulator.CanSimulate(); 138751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang} 139751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang 140751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wangtemplate <typename Expected> 141751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wangstatic Expected SimulatorExecute(CodeSimulator* simulator, Expected (*f)()); 142751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang 143751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wangtemplate <> 144751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wangbool SimulatorExecute<bool>(CodeSimulator* simulator, bool (*f)()) { 145751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang simulator->RunFrom(reinterpret_cast<intptr_t>(f)); 146751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang return simulator->GetCReturnBool(); 147751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang} 148751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang 149751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wangtemplate <> 150751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wangint32_t SimulatorExecute<int32_t>(CodeSimulator* simulator, int32_t (*f)()) { 151751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang simulator->RunFrom(reinterpret_cast<intptr_t>(f)); 152751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang return simulator->GetCReturnInt32(); 153751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang} 154751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang 155751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wangtemplate <> 156751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wangint64_t SimulatorExecute<int64_t>(CodeSimulator* simulator, int64_t (*f)()) { 157751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang simulator->RunFrom(reinterpret_cast<intptr_t>(f)); 158751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang return simulator->GetCReturnInt64(); 159751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang} 160751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang 161751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wangtemplate <typename Expected> 162751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wangstatic void VerifyGeneratedCode(InstructionSet target_isa, 163751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang Expected (*f)(), 164751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang bool has_result, 165751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang Expected expected) { 166751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang ASSERT_TRUE(CanExecute(target_isa)) << "Target isa is not executable."; 167751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang 168751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang // Verify on simulator. 169751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang CodeSimulatorContainer simulator(target_isa); 170751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang if (simulator.CanSimulate()) { 171751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang Expected result = SimulatorExecute<Expected>(simulator.Get(), f); 172751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang if (has_result) { 173751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang ASSERT_EQ(expected, result); 174751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang } 175751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang } 176751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang 177751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang // Verify on hardware. 178751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang if (CanExecuteOnHardware(target_isa)) { 179751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang Expected result = f(); 180751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang if (has_result) { 181751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang ASSERT_EQ(expected, result); 182751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang } 183751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang } 184751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang} 185751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang 18655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillaintemplate <typename Expected> 1878d486731559ba0c5e12c27b4a507181333702b7eNicolas Geoffraystatic void Run(const InternalCodeAllocator& allocator, 1888d486731559ba0c5e12c27b4a507181333702b7eNicolas Geoffray const CodeGenerator& codegen, 1898d486731559ba0c5e12c27b4a507181333702b7eNicolas Geoffray bool has_result, 19055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain Expected expected) { 191751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang InstructionSet target_isa = codegen.GetInstructionSet(); 192751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang 19355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain typedef Expected (*fptr)(); 1949cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray CommonCompilerTest::MakeExecutable(allocator.GetMemory(), allocator.GetSize()); 19520dfc797dc631bf8d655dcf123f46f13332d3074Dave Allison fptr f = reinterpret_cast<fptr>(allocator.GetMemory()); 196751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang if (target_isa == kThumb2) { 1978d486731559ba0c5e12c27b4a507181333702b7eNicolas Geoffray // For thumb we need the bottom bit set. 1988d486731559ba0c5e12c27b4a507181333702b7eNicolas Geoffray f = reinterpret_cast<fptr>(reinterpret_cast<uintptr_t>(f) + 1); 1998d486731559ba0c5e12c27b4a507181333702b7eNicolas Geoffray } 200751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang VerifyGeneratedCode(target_isa, f, has_result, expected); 2019cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray} 2029cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray 20355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillaintemplate <typename Expected> 20458282f4510961317b8d5a364a6f740a78926716fDavid Brazdilstatic void RunCode(CodeGenerator* codegen, 20558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HGraph* graph, 20658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil std::function<void(HGraph*)> hook_before_codegen, 20758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil bool has_result, 20858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil Expected expected) { 209badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil GraphChecker graph_checker(graph); 21058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph_checker.Run(); 211badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil if (!graph_checker.IsValid()) { 212badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil for (auto error : graph_checker.GetErrors()) { 213badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil std::cout << error << std::endl; 214badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil } 215badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil } 21658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil ASSERT_TRUE(graph_checker.IsValid()); 217d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 2180d9f17de8f21a10702de1510b73e89d07b3b9bbfNicolas Geoffray SsaLivenessAnalysis liveness(graph, codegen); 219360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 22058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil PrepareForRegisterAllocation(graph).Run(); 22158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil liveness.Analyze(); 22258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil RegisterAllocator(graph->GetArena(), codegen, liveness).AllocateRegisters(); 223360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray hook_before_codegen(graph); 224360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 225360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray InternalCodeAllocator allocator; 22658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil codegen->Compile(&allocator); 227360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray Run(allocator, *codegen, has_result, expected); 228360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray} 229360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 23055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillaintemplate <typename Expected> 23158282f4510961317b8d5a364a6f740a78926716fDavid Brazdilstatic void RunCode(InstructionSet target_isa, 23258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HGraph* graph, 23358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil std::function<void(HGraph*)> hook_before_codegen, 23458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil bool has_result, 23558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil Expected expected) { 236cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle CompilerOptions compiler_options; 237751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang if (target_isa == kArm || target_isa == kThumb2) { 238751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang std::unique_ptr<const ArmInstructionSetFeatures> features_arm( 239751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang ArmInstructionSetFeatures::FromCppDefines()); 240751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang TestCodeGeneratorARM codegenARM(graph, *features_arm.get(), compiler_options); 24158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil RunCode(&codegenARM, graph, hook_before_codegen, has_result, expected); 242751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang } else if (target_isa == kArm64) { 243751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang std::unique_ptr<const Arm64InstructionSetFeatures> features_arm64( 244751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang Arm64InstructionSetFeatures::FromCppDefines()); 245751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang arm64::CodeGeneratorARM64 codegenARM64(graph, *features_arm64.get(), compiler_options); 24658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil RunCode(&codegenARM64, graph, hook_before_codegen, has_result, expected); 247751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang } else if (target_isa == kX86) { 248fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell std::unique_ptr<const X86InstructionSetFeatures> features_x86( 249fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell X86InstructionSetFeatures::FromCppDefines()); 250fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell x86::CodeGeneratorX86 codegenX86(graph, *features_x86.get(), compiler_options); 25158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil RunCode(&codegenX86, graph, hook_before_codegen, has_result, expected); 252751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang } else if (target_isa == kX86_64) { 253fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell std::unique_ptr<const X86_64InstructionSetFeatures> features_x86_64( 254fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell X86_64InstructionSetFeatures::FromCppDefines()); 255fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell x86_64::CodeGeneratorX86_64 codegenX86_64(graph, *features_x86_64.get(), compiler_options); 25658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil RunCode(&codegenX86_64, graph, hook_before_codegen, has_result, expected); 257751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang } else if (target_isa == kMips) { 258f652cecb984c104d44a0223c3c98400ef8ed8ce2Goran Jakovljevic std::unique_ptr<const MipsInstructionSetFeatures> features_mips( 259f652cecb984c104d44a0223c3c98400ef8ed8ce2Goran Jakovljevic MipsInstructionSetFeatures::FromCppDefines()); 260f652cecb984c104d44a0223c3c98400ef8ed8ce2Goran Jakovljevic mips::CodeGeneratorMIPS codegenMIPS(graph, *features_mips.get(), compiler_options); 26158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil RunCode(&codegenMIPS, graph, hook_before_codegen, has_result, expected); 262751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang } else if (target_isa == kMips64) { 2634dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze std::unique_ptr<const Mips64InstructionSetFeatures> features_mips64( 2644dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze Mips64InstructionSetFeatures::FromCppDefines()); 2654dda3376b71209fae07f5c3c8ac3eb4b54207aa8Alexey Frunze mips64::CodeGeneratorMIPS64 codegenMIPS64(graph, *features_mips64.get(), compiler_options); 26658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil RunCode(&codegenMIPS64, graph, hook_before_codegen, has_result, expected); 267360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray } 268360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray} 269360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 27058282f4510961317b8d5a364a6f740a78926716fDavid Brazdilstatic ::std::vector<InstructionSet> GetTargetISAs() { 27158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil ::std::vector<InstructionSet> v; 27258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil // Add all ISAs that are executable on hardware or on simulator. 27358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil const ::std::vector<InstructionSet> executable_isa_candidates = { 27458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil kArm, 27558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil kArm64, 27658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil kThumb2, 27758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil kX86, 27858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil kX86_64, 27958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil kMips, 28058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil kMips64 28158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil }; 28258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 28358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil for (auto target_isa : executable_isa_candidates) { 28458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil if (CanExecute(target_isa)) { 28558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil v.push_back(target_isa); 28658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil } 28758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil } 28858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 28958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil return v; 29058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil} 29158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 29258282f4510961317b8d5a364a6f740a78926716fDavid Brazdilstatic void TestCode(const uint16_t* data, 293751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang bool has_result = false, 294751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang int32_t expected = 0) { 29558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil for (InstructionSet target_isa : GetTargetISAs()) { 29658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil ArenaPool pool; 29758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil ArenaAllocator arena(&pool); 298badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil HGraph* graph = CreateCFG(&arena, data); 29958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil // Remove suspend checks, they cannot be executed in this context. 30058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil RemoveSuspendChecks(graph); 30158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil RunCode(target_isa, graph, [](HGraph*) {}, has_result, expected); 30258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil } 30358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil} 30458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 30558282f4510961317b8d5a364a6f740a78926716fDavid Brazdilstatic void TestCodeLong(const uint16_t* data, 306751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang bool has_result, 307751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang int64_t expected) { 30858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil for (InstructionSet target_isa : GetTargetISAs()) { 30958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil ArenaPool pool; 31058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil ArenaAllocator arena(&pool); 311badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil HGraph* graph = CreateCFG(&arena, data, Primitive::kPrimLong); 31258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil // Remove suspend checks, they cannot be executed in this context. 31358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil RemoveSuspendChecks(graph); 31458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil RunCode(target_isa, graph, [](HGraph*) {}, has_result, expected); 31558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil } 31655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain} 31755dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain 31858282f4510961317b8d5a364a6f740a78926716fDavid Brazdilclass CodegenTest : public CommonCompilerTest {}; 319751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang 32058282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ReturnVoid) { 3213ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(Instruction::RETURN_VOID); 32258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data); 323d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray} 324d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 32558282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, CFG1) { 3263ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray const uint16_t data[] = ZERO_REGISTER_CODE_ITEM( 327d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::GOTO | 0x100, 3283ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray Instruction::RETURN_VOID); 329d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 33058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data); 331d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray} 332d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 33358282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, CFG2) { 3343ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray const uint16_t data[] = ZERO_REGISTER_CODE_ITEM( 335d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::GOTO | 0x100, 336d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::GOTO | 0x100, 3373ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray Instruction::RETURN_VOID); 338d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 33958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data); 340d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray} 341d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 34258282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, CFG3) { 3433ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM( 344d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::GOTO | 0x200, 345d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::RETURN_VOID, 3463ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray Instruction::GOTO | 0xFF00); 347d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 34858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data1); 349d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 3503ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM( 351d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::GOTO_16, 3, 352d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::RETURN_VOID, 3533ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray Instruction::GOTO_16, 0xFFFF); 354d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 35558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data2); 356d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 3573ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray const uint16_t data3[] = ZERO_REGISTER_CODE_ITEM( 358d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::GOTO_32, 4, 0, 359d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::RETURN_VOID, 3603ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray Instruction::GOTO_32, 0xFFFF, 0xFFFF); 361d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 36258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data3); 363d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray} 364d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 36558282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, CFG4) { 3663ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray const uint16_t data[] = ZERO_REGISTER_CODE_ITEM( 367d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::RETURN_VOID, 368d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::GOTO | 0x100, 3693ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray Instruction::GOTO | 0xFE00); 370d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 37158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data); 372d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray} 373d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 37458282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, CFG5) { 375bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 376bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 377bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::IF_EQ, 3, 378bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::GOTO | 0x100, 379bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN_VOID); 380bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 38158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data); 382bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray} 383bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 38458282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, IntConstant) { 385bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 386bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 387bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN_VOID); 388bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 38958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data); 390bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray} 391bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 39258282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, Return1) { 393bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 394bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 395bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN | 0); 396bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 39758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, 0); 398bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray} 399bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 40058282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, Return2) { 401bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 402bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 403bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 1 << 8, 404bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN | 1 << 8); 405bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 40658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, 0); 407bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray} 408bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 40958282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, Return3) { 410bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 411bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 412bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 1 << 8 | 1 << 12, 413bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN | 1 << 8); 414bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 41558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, 1); 416bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray} 417bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 41858282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ReturnIf1) { 419bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 420bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 421bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 1 << 8 | 1 << 12, 422bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::IF_EQ, 3, 423bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN | 0 << 8, 424bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN | 1 << 8); 425bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 42658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, 1); 427bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray} 428bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 42958282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ReturnIf2) { 430bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 431bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 432bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 1 << 8 | 1 << 12, 433bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::IF_EQ | 0 << 4 | 1 << 8, 3, 434bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN | 0 << 8, 435bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN | 1 << 8); 436bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 43758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, 0); 438bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray} 439bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 4401cc5f251df558b0e22cea5000626365eb644c727Roland Levillain// Exercise bit-wise (one's complement) not-int instruction. 4411cc5f251df558b0e22cea5000626365eb644c727Roland Levillain#define NOT_INT_TEST(TEST_NAME, INPUT, EXPECTED_OUTPUT) \ 44258282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, TEST_NAME) { \ 4431cc5f251df558b0e22cea5000626365eb644c727Roland Levillain const int32_t input = INPUT; \ 44455dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const uint16_t input_lo = Low16Bits(input); \ 44555dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const uint16_t input_hi = High16Bits(input); \ 4461cc5f251df558b0e22cea5000626365eb644c727Roland Levillain const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( \ 4471cc5f251df558b0e22cea5000626365eb644c727Roland Levillain Instruction::CONST | 0 << 8, input_lo, input_hi, \ 4481cc5f251df558b0e22cea5000626365eb644c727Roland Levillain Instruction::NOT_INT | 1 << 8 | 0 << 12 , \ 4491cc5f251df558b0e22cea5000626365eb644c727Roland Levillain Instruction::RETURN | 1 << 8); \ 4501cc5f251df558b0e22cea5000626365eb644c727Roland Levillain \ 45158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, EXPECTED_OUTPUT); \ 4521cc5f251df558b0e22cea5000626365eb644c727Roland Levillain} 4531cc5f251df558b0e22cea5000626365eb644c727Roland Levillain 4541cc5f251df558b0e22cea5000626365eb644c727Roland LevillainNOT_INT_TEST(ReturnNotIntMinus2, -2, 1) 4551cc5f251df558b0e22cea5000626365eb644c727Roland LevillainNOT_INT_TEST(ReturnNotIntMinus1, -1, 0) 4561cc5f251df558b0e22cea5000626365eb644c727Roland LevillainNOT_INT_TEST(ReturnNotInt0, 0, -1) 4571cc5f251df558b0e22cea5000626365eb644c727Roland LevillainNOT_INT_TEST(ReturnNotInt1, 1, -2) 45855dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_INT_TEST(ReturnNotIntINT32_MIN, -2147483648, 2147483647) // (2^31) - 1 45955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_INT_TEST(ReturnNotIntINT32_MINPlus1, -2147483647, 2147483646) // (2^31) - 2 46055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_INT_TEST(ReturnNotIntINT32_MAXMinus1, 2147483646, -2147483647) // -(2^31) - 1 46155dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_INT_TEST(ReturnNotIntINT32_MAX, 2147483647, -2147483648) // -(2^31) 4621cc5f251df558b0e22cea5000626365eb644c727Roland Levillain 4631cc5f251df558b0e22cea5000626365eb644c727Roland Levillain#undef NOT_INT_TEST 4641cc5f251df558b0e22cea5000626365eb644c727Roland Levillain 46555dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain// Exercise bit-wise (one's complement) not-long instruction. 46655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain#define NOT_LONG_TEST(TEST_NAME, INPUT, EXPECTED_OUTPUT) \ 46758282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, TEST_NAME) { \ 46855dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const int64_t input = INPUT; \ 46955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const uint16_t word0 = Low16Bits(Low32Bits(input)); /* LSW. */ \ 47055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const uint16_t word1 = High16Bits(Low32Bits(input)); \ 47155dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const uint16_t word2 = Low16Bits(High32Bits(input)); \ 47255dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const uint16_t word3 = High16Bits(High32Bits(input)); /* MSW. */ \ 47355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const uint16_t data[] = FOUR_REGISTERS_CODE_ITEM( \ 47455dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain Instruction::CONST_WIDE | 0 << 8, word0, word1, word2, word3, \ 47555dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain Instruction::NOT_LONG | 2 << 8 | 0 << 12, \ 47655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain Instruction::RETURN_WIDE | 2 << 8); \ 47755dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain \ 47858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCodeLong(data, true, EXPECTED_OUTPUT); \ 47955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain} 48055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain 48155dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongMinus2, INT64_C(-2), INT64_C(1)) 48255dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongMinus1, INT64_C(-1), INT64_C(0)) 48355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLong0, INT64_C(0), INT64_C(-1)) 48455dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLong1, INT64_C(1), INT64_C(-2)) 48555dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain 48655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongINT32_MIN, 48755dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-2147483648), 48855dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(2147483647)) // (2^31) - 1 48955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongINT32_MINPlus1, 49055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-2147483647), 49155dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(2147483646)) // (2^31) - 2 49255dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongINT32_MAXMinus1, 49355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(2147483646), 49455dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-2147483647)) // -(2^31) - 1 49555dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongINT32_MAX, 49655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(2147483647), 49755dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-2147483648)) // -(2^31) 49855dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain 49955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain// Note that the C++ compiler won't accept 50055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain// INT64_C(-9223372036854775808) (that is, INT64_MIN) as a valid 50155dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain// int64_t literal, so we use INT64_C(-9223372036854775807)-1 instead. 50255dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotINT64_MIN, 50355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-9223372036854775807)-1, 50455dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(9223372036854775807)); // (2^63) - 1 50555dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotINT64_MINPlus1, 50655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-9223372036854775807), 50755dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(9223372036854775806)); // (2^63) - 2 50855dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongINT64_MAXMinus1, 50955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(9223372036854775806), 51055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-9223372036854775807)); // -(2^63) - 1 51155dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongINT64_MAX, 51255dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(9223372036854775807), 51355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-9223372036854775807)-1); // -(2^63) 51455dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain 51555dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain#undef NOT_LONG_TEST 51655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain 51758282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, IntToLongOfLongToInt) { 518946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain const int64_t input = INT64_C(4294967296); // 2^32 519946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain const uint16_t word0 = Low16Bits(Low32Bits(input)); // LSW. 520946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain const uint16_t word1 = High16Bits(Low32Bits(input)); 521946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain const uint16_t word2 = Low16Bits(High32Bits(input)); 522946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain const uint16_t word3 = High16Bits(High32Bits(input)); // MSW. 523946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain const uint16_t data[] = FIVE_REGISTERS_CODE_ITEM( 524946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain Instruction::CONST_WIDE | 0 << 8, word0, word1, word2, word3, 525946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain Instruction::CONST_WIDE | 2 << 8, 1, 0, 0, 0, 526946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain Instruction::ADD_LONG | 0, 0 << 8 | 2, // v0 <- 2^32 + 1 527946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain Instruction::LONG_TO_INT | 4 << 8 | 0 << 12, 528946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain Instruction::INT_TO_LONG | 2 << 8 | 4 << 12, 529946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain Instruction::RETURN_WIDE | 2 << 8); 530946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain 53158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCodeLong(data, true, 1); 532946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain} 533946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain 53458282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ReturnAdd1) { 535d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 536d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::CONST_4 | 3 << 12 | 0, 537d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 1 << 8, 538d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::ADD_INT, 1 << 8 | 0, 539d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::RETURN); 540d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray 54158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, 7); 542d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray} 543d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray 54458282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ReturnAdd2) { 545d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 546d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::CONST_4 | 3 << 12 | 0, 547d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 1 << 8, 548d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::ADD_INT_2ADDR | 1 << 12, 549d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::RETURN); 550d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray 55158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, 7); 552d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray} 553d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray 55458282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ReturnAdd3) { 555d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 556d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0 << 8, 557d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::ADD_INT_LIT8, 3 << 8 | 0, 558d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::RETURN); 559d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray 56058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, 7); 561d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray} 562d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray 56358282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ReturnAdd4) { 564d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 565d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0 << 8, 566d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::ADD_INT_LIT16, 3, 567d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::RETURN); 568d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray 56958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, 7); 570360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray} 571360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 57258282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ReturnMulInt) { 5735da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 5745da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray Instruction::CONST_4 | 3 << 12 | 0, 5755da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray Instruction::CONST_4 | 4 << 12 | 1 << 8, 5765da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray Instruction::MUL_INT, 1 << 8 | 0, 5775da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray Instruction::RETURN); 5785da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray 57958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, 12); 5805da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray} 5815da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray 58258282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ReturnMulInt2addr) { 5835da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 5845da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray Instruction::CONST_4 | 3 << 12 | 0, 5855da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray Instruction::CONST_4 | 4 << 12 | 1 << 8, 5865da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray Instruction::MUL_INT_2ADDR | 1 << 12, 5875da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray Instruction::RETURN); 58834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle 58958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, 12); 5905da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray} 5915da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray 59258282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ReturnMulLong) { 5935da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray const uint16_t data[] = FOUR_REGISTERS_CODE_ITEM( 59458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil Instruction::CONST_WIDE | 0 << 8, 3, 0, 0, 0, 59558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil Instruction::CONST_WIDE | 2 << 8, 4, 0, 0, 0, 5965da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray Instruction::MUL_LONG, 2 << 8 | 0, 5975da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray Instruction::RETURN_WIDE); 5985da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray 59958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCodeLong(data, true, 12); 6005da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray} 6015da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray 60258282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ReturnMulLong2addr) { 6035da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray const uint16_t data[] = FOUR_REGISTERS_CODE_ITEM( 60458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil Instruction::CONST_WIDE | 0 << 8, 3, 0, 0, 0, 60558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil Instruction::CONST_WIDE | 2 << 8, 4, 0, 0, 0, 6065da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray Instruction::MUL_LONG_2ADDR | 2 << 12, 6075da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray Instruction::RETURN_WIDE); 6085da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray 60958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCodeLong(data, true, 12); 6105da2180e684ae6afcb55d787f6a69bc97489bb83Nicolas Geoffray} 61134bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle 61258282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ReturnMulIntLit8) { 61334bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 61434bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::CONST_4 | 4 << 12 | 0 << 8, 61534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::MUL_INT_LIT8, 3 << 8 | 0, 61634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::RETURN); 61734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle 61858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, 12); 61934bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle} 62034bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle 62158282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ReturnMulIntLit16) { 62234bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 62334bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::CONST_4 | 4 << 12 | 0 << 8, 62434bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::MUL_INT_LIT16, 3, 62534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::RETURN); 62634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle 62758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, 12); 62834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle} 62934bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle 63058282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, NonMaterializedCondition) { 63158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil for (InstructionSet target_isa : GetTargetISAs()) { 632927307433af0a9322e8ba77eda37168512a73683Alexandre Rames ArenaPool pool; 633927307433af0a9322e8ba77eda37168512a73683Alexandre Rames ArenaAllocator allocator(&pool); 634927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 63558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HGraph* graph = CreateGraph(&allocator); 636badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil 63758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HBasicBlock* entry = new (&allocator) HBasicBlock(graph); 63858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->AddBlock(entry); 63958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->SetEntryBlock(entry); 64058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil entry->AddInstruction(new (&allocator) HGoto()); 64158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 64258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HBasicBlock* first_block = new (&allocator) HBasicBlock(graph); 64358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->AddBlock(first_block); 64458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil entry->AddSuccessor(first_block); 64558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HIntConstant* constant0 = graph->GetIntConstant(0); 64658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HIntConstant* constant1 = graph->GetIntConstant(1); 64758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HEqual* equal = new (&allocator) HEqual(constant0, constant0); 64858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil first_block->AddInstruction(equal); 64958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil first_block->AddInstruction(new (&allocator) HIf(equal)); 65058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 65158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HBasicBlock* then_block = new (&allocator) HBasicBlock(graph); 65258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HBasicBlock* else_block = new (&allocator) HBasicBlock(graph); 653927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HBasicBlock* exit_block = new (&allocator) HBasicBlock(graph); 65458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->SetExitBlock(exit_block); 65558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 65658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->AddBlock(then_block); 65758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->AddBlock(else_block); 658927307433af0a9322e8ba77eda37168512a73683Alexandre Rames graph->AddBlock(exit_block); 65958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil first_block->AddSuccessor(then_block); 66058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil first_block->AddSuccessor(else_block); 66158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil then_block->AddSuccessor(exit_block); 66258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil else_block->AddSuccessor(exit_block); 663927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 66458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil exit_block->AddInstruction(new (&allocator) HExit()); 66558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil then_block->AddInstruction(new (&allocator) HReturn(constant0)); 66658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil else_block->AddInstruction(new (&allocator) HReturn(constant1)); 667927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 668b11b0725d02aafd6e3ea4eb514b215149c893bf0David Brazdil ASSERT_FALSE(equal->IsEmittedAtUseSite()); 669badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil graph->BuildDominatorTree(); 67058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil PrepareForRegisterAllocation(graph).Run(); 671b11b0725d02aafd6e3ea4eb514b215149c893bf0David Brazdil ASSERT_TRUE(equal->IsEmittedAtUseSite()); 672927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 673277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe auto hook_before_codegen = [](HGraph* graph_in) { 674ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HBasicBlock* block = graph_in->GetEntryBlock()->GetSuccessors()[0]; 675277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe HParallelMove* move = new (graph_in->GetArena()) HParallelMove(graph_in->GetArena()); 676927307433af0a9322e8ba77eda37168512a73683Alexandre Rames block->InsertInstructionBefore(move, block->GetLastInstruction()); 677927307433af0a9322e8ba77eda37168512a73683Alexandre Rames }; 678927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 67958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil RunCode(target_isa, graph, hook_before_codegen, true, 0); 680927307433af0a9322e8ba77eda37168512a73683Alexandre Rames } 681927307433af0a9322e8ba77eda37168512a73683Alexandre Rames} 682927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 68358282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, MaterializedCondition1) { 68458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil for (InstructionSet target_isa : GetTargetISAs()) { 68558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil // Check that condition are materialized correctly. A materialized condition 68658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil // should yield `1` if it evaluated to true, and `0` otherwise. 68758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil // We force the materialization of comparisons for different combinations of 68858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 68958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil // inputs and check the results. 69058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 69158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil int lhs[] = {1, 2, -1, 2, 0xabc}; 69258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil int rhs[] = {2, 1, 2, -1, 0xabc}; 69358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 69458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil for (size_t i = 0; i < arraysize(lhs); i++) { 69558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil ArenaPool pool; 69658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil ArenaAllocator allocator(&pool); 69758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HGraph* graph = CreateGraph(&allocator); 69858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 69958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HBasicBlock* entry_block = new (&allocator) HBasicBlock(graph); 70058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->AddBlock(entry_block); 70158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->SetEntryBlock(entry_block); 70258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil entry_block->AddInstruction(new (&allocator) HGoto()); 70358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HBasicBlock* code_block = new (&allocator) HBasicBlock(graph); 70458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->AddBlock(code_block); 70558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HBasicBlock* exit_block = new (&allocator) HBasicBlock(graph); 70658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->AddBlock(exit_block); 70758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil exit_block->AddInstruction(new (&allocator) HExit()); 70858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 70958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil entry_block->AddSuccessor(code_block); 71058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil code_block->AddSuccessor(exit_block); 71158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->SetExitBlock(exit_block); 71258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 71358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HIntConstant* cst_lhs = graph->GetIntConstant(lhs[i]); 71458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HIntConstant* cst_rhs = graph->GetIntConstant(rhs[i]); 71558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HLessThan cmp_lt(cst_lhs, cst_rhs); 71658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil code_block->AddInstruction(&cmp_lt); 71758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HReturn ret(&cmp_lt); 71858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil code_block->AddInstruction(&ret); 71958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 720badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil graph->BuildDominatorTree(); 72158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil auto hook_before_codegen = [](HGraph* graph_in) { 72258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HBasicBlock* block = graph_in->GetEntryBlock()->GetSuccessors()[0]; 72358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HParallelMove* move = new (graph_in->GetArena()) HParallelMove(graph_in->GetArena()); 72458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil block->InsertInstructionBefore(move, block->GetLastInstruction()); 72558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil }; 72658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil RunCode(target_isa, graph, hook_before_codegen, true, lhs[i] < rhs[i]); 72758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil } 72858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil } 72958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil} 730927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 73158282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, MaterializedCondition2) { 73258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil for (InstructionSet target_isa : GetTargetISAs()) { 73358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil // Check that HIf correctly interprets a materialized condition. 73458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil // We force the materialization of comparisons for different combinations of 73558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil // inputs. An HIf takes the materialized combination as input and returns a 73658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil // value that we verify. 73758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 73858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil int lhs[] = {1, 2, -1, 2, 0xabc}; 73958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil int rhs[] = {2, 1, 2, -1, 0xabc}; 74058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 74158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 74258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil for (size_t i = 0; i < arraysize(lhs); i++) { 74358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil ArenaPool pool; 74458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil ArenaAllocator allocator(&pool); 74558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HGraph* graph = CreateGraph(&allocator); 74658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 74758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HBasicBlock* entry_block = new (&allocator) HBasicBlock(graph); 74858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->AddBlock(entry_block); 74958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->SetEntryBlock(entry_block); 75058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil entry_block->AddInstruction(new (&allocator) HGoto()); 75158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 75258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HBasicBlock* if_block = new (&allocator) HBasicBlock(graph); 75358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->AddBlock(if_block); 75458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HBasicBlock* if_true_block = new (&allocator) HBasicBlock(graph); 75558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->AddBlock(if_true_block); 75658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HBasicBlock* if_false_block = new (&allocator) HBasicBlock(graph); 75758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->AddBlock(if_false_block); 75858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HBasicBlock* exit_block = new (&allocator) HBasicBlock(graph); 75958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->AddBlock(exit_block); 76058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil exit_block->AddInstruction(new (&allocator) HExit()); 76158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 76258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->SetEntryBlock(entry_block); 76358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil entry_block->AddSuccessor(if_block); 76458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil if_block->AddSuccessor(if_true_block); 76558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil if_block->AddSuccessor(if_false_block); 76658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil if_true_block->AddSuccessor(exit_block); 76758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil if_false_block->AddSuccessor(exit_block); 76858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil graph->SetExitBlock(exit_block); 76958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 77058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HIntConstant* cst_lhs = graph->GetIntConstant(lhs[i]); 77158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HIntConstant* cst_rhs = graph->GetIntConstant(rhs[i]); 77258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HLessThan cmp_lt(cst_lhs, cst_rhs); 77358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil if_block->AddInstruction(&cmp_lt); 7746e332529c33be4d7dae5dad3609a839f4c0d3bfcDavid Brazdil // We insert a dummy instruction to separate the HIf from the HLessThan 7756e332529c33be4d7dae5dad3609a839f4c0d3bfcDavid Brazdil // and force the materialization of the condition. 7766e332529c33be4d7dae5dad3609a839f4c0d3bfcDavid Brazdil HMemoryBarrier force_materialization(MemBarrierKind::kAnyAny, 0); 77758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil if_block->AddInstruction(&force_materialization); 77858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HIf if_lt(&cmp_lt); 77958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil if_block->AddInstruction(&if_lt); 78058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 78158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HIntConstant* cst_lt = graph->GetIntConstant(1); 78258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HReturn ret_lt(cst_lt); 78358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil if_true_block->AddInstruction(&ret_lt); 78458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HIntConstant* cst_ge = graph->GetIntConstant(0); 78558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HReturn ret_ge(cst_ge); 78658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil if_false_block->AddInstruction(&ret_ge); 78758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 788badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil graph->BuildDominatorTree(); 78958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil auto hook_before_codegen = [](HGraph* graph_in) { 79058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HBasicBlock* block = graph_in->GetEntryBlock()->GetSuccessors()[0]; 79158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil HParallelMove* move = new (graph_in->GetArena()) HParallelMove(graph_in->GetArena()); 79258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil block->InsertInstructionBefore(move, block->GetLastInstruction()); 79358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil }; 79458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil RunCode(target_isa, graph, hook_before_codegen, true, lhs[i] < rhs[i]); 79558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil } 796927307433af0a9322e8ba77eda37168512a73683Alexandre Rames } 797927307433af0a9322e8ba77eda37168512a73683Alexandre Rames} 79834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle 79958282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ReturnDivIntLit8) { 800d0d4852847432368b090c184d6639e573538dccfCalin Juravle const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 801d0d4852847432368b090c184d6639e573538dccfCalin Juravle Instruction::CONST_4 | 4 << 12 | 0 << 8, 802d0d4852847432368b090c184d6639e573538dccfCalin Juravle Instruction::DIV_INT_LIT8, 3 << 8 | 0, 803d0d4852847432368b090c184d6639e573538dccfCalin Juravle Instruction::RETURN); 804d0d4852847432368b090c184d6639e573538dccfCalin Juravle 80558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, 1); 806d0d4852847432368b090c184d6639e573538dccfCalin Juravle} 807d0d4852847432368b090c184d6639e573538dccfCalin Juravle 80858282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ReturnDivInt2Addr) { 809865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 810865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle Instruction::CONST_4 | 4 << 12 | 0, 811865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle Instruction::CONST_4 | 2 << 12 | 1 << 8, 812865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle Instruction::DIV_INT_2ADDR | 1 << 12, 813865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle Instruction::RETURN); 814865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle 81558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestCode(data, true, 2); 816865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle} 817865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle 818e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik// Helper method. 819751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wangstatic void TestComparison(IfCondition condition, 820751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang int64_t i, 821751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang int64_t j, 822751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang Primitive::Type type, 823751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang const InstructionSet target_isa) { 824e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik ArenaPool pool; 825e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik ArenaAllocator allocator(&pool); 826e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik HGraph* graph = CreateGraph(&allocator); 827e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik 828e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik HBasicBlock* entry_block = new (&allocator) HBasicBlock(graph); 829e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik graph->AddBlock(entry_block); 830e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik graph->SetEntryBlock(entry_block); 831e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik entry_block->AddInstruction(new (&allocator) HGoto()); 832e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik 833e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik HBasicBlock* block = new (&allocator) HBasicBlock(graph); 834e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik graph->AddBlock(block); 835e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik 836e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik HBasicBlock* exit_block = new (&allocator) HBasicBlock(graph); 837e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik graph->AddBlock(exit_block); 838e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik graph->SetExitBlock(exit_block); 839e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik exit_block->AddInstruction(new (&allocator) HExit()); 840e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik 841e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik entry_block->AddSuccessor(block); 842e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik block->AddSuccessor(exit_block); 843e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik 844e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik HInstruction* op1; 845e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik HInstruction* op2; 846e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik if (type == Primitive::kPrimInt) { 847e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik op1 = graph->GetIntConstant(i); 848e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik op2 = graph->GetIntConstant(j); 849e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik } else { 850e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik DCHECK_EQ(type, Primitive::kPrimLong); 851e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik op1 = graph->GetLongConstant(i); 852e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik op2 = graph->GetLongConstant(j); 853e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik } 854e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik 855e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik HInstruction* comparison = nullptr; 856e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik bool expected_result = false; 857e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik const uint64_t x = i; 858e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik const uint64_t y = j; 859e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik switch (condition) { 860e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik case kCondEQ: 861e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik comparison = new (&allocator) HEqual(op1, op2); 862e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik expected_result = (i == j); 863e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik break; 864e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik case kCondNE: 865e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik comparison = new (&allocator) HNotEqual(op1, op2); 866e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik expected_result = (i != j); 867e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik break; 868e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik case kCondLT: 869e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik comparison = new (&allocator) HLessThan(op1, op2); 870e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik expected_result = (i < j); 871e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik break; 872e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik case kCondLE: 873e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik comparison = new (&allocator) HLessThanOrEqual(op1, op2); 874e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik expected_result = (i <= j); 875e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik break; 876e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik case kCondGT: 877e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik comparison = new (&allocator) HGreaterThan(op1, op2); 878e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik expected_result = (i > j); 879e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik break; 880e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik case kCondGE: 881e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik comparison = new (&allocator) HGreaterThanOrEqual(op1, op2); 882e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik expected_result = (i >= j); 883e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik break; 884e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik case kCondB: 885e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik comparison = new (&allocator) HBelow(op1, op2); 886e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik expected_result = (x < y); 887e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik break; 888e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik case kCondBE: 889e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik comparison = new (&allocator) HBelowOrEqual(op1, op2); 890e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik expected_result = (x <= y); 891e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik break; 892e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik case kCondA: 893e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik comparison = new (&allocator) HAbove(op1, op2); 894e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik expected_result = (x > y); 895e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik break; 896e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik case kCondAE: 897e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik comparison = new (&allocator) HAboveOrEqual(op1, op2); 898e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik expected_result = (x >= y); 899e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik break; 900e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik } 901e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik block->AddInstruction(comparison); 902e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik block->AddInstruction(new (&allocator) HReturn(comparison)); 903e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik 904badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil graph->BuildDominatorTree(); 90558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil RunCode(target_isa, graph, [](HGraph*) {}, true, expected_result); 90658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil} 90758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil 90858282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ComparisonsInt) { 90958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil for (InstructionSet target_isa : GetTargetISAs()) { 91058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil for (int64_t i = -1; i <= 1; i++) { 91158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil for (int64_t j = -1; j <= 1; j++) { 91258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondEQ, i, j, Primitive::kPrimInt, target_isa); 91358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondNE, i, j, Primitive::kPrimInt, target_isa); 91458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondLT, i, j, Primitive::kPrimInt, target_isa); 91558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondLE, i, j, Primitive::kPrimInt, target_isa); 91658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondGT, i, j, Primitive::kPrimInt, target_isa); 91758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondGE, i, j, Primitive::kPrimInt, target_isa); 91858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondB, i, j, Primitive::kPrimInt, target_isa); 91958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondBE, i, j, Primitive::kPrimInt, target_isa); 92058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondA, i, j, Primitive::kPrimInt, target_isa); 92158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondAE, i, j, Primitive::kPrimInt, target_isa); 92258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil } 923e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik } 924e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik } 925e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik} 926e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik 92758282f4510961317b8d5a364a6f740a78926716fDavid BrazdilTEST_F(CodegenTest, ComparisonsLong) { 928e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik // TODO: make MIPS work for long 929e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik if (kRuntimeISA == kMips || kRuntimeISA == kMips64) { 930e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik return; 931e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik } 932e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik 93358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil for (InstructionSet target_isa : GetTargetISAs()) { 93458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil if (target_isa == kMips || target_isa == kMips64) { 93558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil continue; 936e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik } 937e9f37600e98ba21308ad4f70d9d68cf6c057bdbeAart Bik 93858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil for (int64_t i = -1; i <= 1; i++) { 93958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil for (int64_t j = -1; j <= 1; j++) { 94058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondEQ, i, j, Primitive::kPrimLong, target_isa); 94158282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondNE, i, j, Primitive::kPrimLong, target_isa); 94258282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondLT, i, j, Primitive::kPrimLong, target_isa); 94358282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondLE, i, j, Primitive::kPrimLong, target_isa); 94458282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondGT, i, j, Primitive::kPrimLong, target_isa); 94558282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondGE, i, j, Primitive::kPrimLong, target_isa); 94658282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondB, i, j, Primitive::kPrimLong, target_isa); 94758282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondBE, i, j, Primitive::kPrimLong, target_isa); 94858282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondA, i, j, Primitive::kPrimLong, target_isa); 94958282f4510961317b8d5a364a6f740a78926716fDavid Brazdil TestComparison(kCondAE, i, j, Primitive::kPrimLong, target_isa); 95058282f4510961317b8d5a364a6f740a78926716fDavid Brazdil } 951751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang } 952751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang } 953751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang} 954751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang 955d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray} // namespace art 956