codegen_test.cc revision a0bb2bd5b6a049ad806c223f00672d1f0210db67
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" 21927307433af0a9322e8ba77eda37168512a73683Alexandre Rames#include "base/macros.h" 22d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "builder.h" 238a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray#include "code_generator_arm.h" 245319defdf502fc4569316473846b83180ec08035Alexandre Rames#include "code_generator_arm64.h" 258a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray#include "code_generator_x86.h" 268a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray#include "code_generator_x86_64.h" 27d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "common_compiler_test.h" 283ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray#include "dex_file.h" 29d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "dex_instruction.h" 30cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle#include "driver/compiler_options.h" 31d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "nodes.h" 323ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray#include "optimizing_unit_test.h" 33360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray#include "prepare_for_register_allocation.h" 34360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray#include "register_allocator.h" 35360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray#include "ssa_liveness_analysis.h" 3655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain#include "utils.h" 37d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 38d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "gtest/gtest.h" 39a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray 40d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffraynamespace art { 41d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 42a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray// Provide our own codegen, that ensures the C calling conventions 43a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray// are preserved. Currently, ART and C do not match as R4 is caller-save 44a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray// in ART, and callee-save in C. Alternatively, we could use or write 45a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray// the stub that saves and restores all registers, but it is easier 46a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray// to just overwrite the code generator. 47a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffrayclass TestCodeGeneratorARM : public arm::CodeGeneratorARM { 48a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray public: 49a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray TestCodeGeneratorARM(HGraph* graph, 50a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray const ArmInstructionSetFeatures& isa_features, 51a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray const CompilerOptions& compiler_options) 52a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray : arm::CodeGeneratorARM(graph, isa_features, compiler_options) { 53a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray AddAllocatedRegister(Location::RegisterLocation(6)); 54a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray AddAllocatedRegister(Location::RegisterLocation(7)); 55a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray } 56a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray 57a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray void SetupBlockedRegisters(bool is_baseline) const OVERRIDE { 58a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray arm::CodeGeneratorARM::SetupBlockedRegisters(is_baseline); 59a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray blocked_core_registers_[4] = true; 60a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray blocked_core_registers_[6] = false; 61a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray blocked_core_registers_[7] = false; 62a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray // Makes pari R6-R7 available. 63a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray blocked_register_pairs_[6 >> 1] = false; 64a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray } 65a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray}; 66a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray 67787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffrayclass InternalCodeAllocator : public CodeAllocator { 68d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray public: 69d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers InternalCodeAllocator() : size_(0) { } 70d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 71d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray virtual uint8_t* Allocate(size_t size) { 72787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray size_ = size; 73d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray memory_.reset(new uint8_t[size]); 74d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray return memory_.get(); 75d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray } 76d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 77787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray size_t GetSize() const { return size_; } 78787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray uint8_t* GetMemory() const { return memory_.get(); } 79d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 80d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray private: 81787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray size_t size_; 82700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<uint8_t[]> memory_; 83d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 84787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray DISALLOW_COPY_AND_ASSIGN(InternalCodeAllocator); 85d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray}; 86d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 8755dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillaintemplate <typename Expected> 888d486731559ba0c5e12c27b4a507181333702b7eNicolas Geoffraystatic void Run(const InternalCodeAllocator& allocator, 898d486731559ba0c5e12c27b4a507181333702b7eNicolas Geoffray const CodeGenerator& codegen, 908d486731559ba0c5e12c27b4a507181333702b7eNicolas Geoffray bool has_result, 9155dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain Expected expected) { 9255dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain typedef Expected (*fptr)(); 939cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray CommonCompilerTest::MakeExecutable(allocator.GetMemory(), allocator.GetSize()); 9420dfc797dc631bf8d655dcf123f46f13332d3074Dave Allison fptr f = reinterpret_cast<fptr>(allocator.GetMemory()); 958d486731559ba0c5e12c27b4a507181333702b7eNicolas Geoffray if (codegen.GetInstructionSet() == kThumb2) { 968d486731559ba0c5e12c27b4a507181333702b7eNicolas Geoffray // For thumb we need the bottom bit set. 978d486731559ba0c5e12c27b4a507181333702b7eNicolas Geoffray f = reinterpret_cast<fptr>(reinterpret_cast<uintptr_t>(f) + 1); 988d486731559ba0c5e12c27b4a507181333702b7eNicolas Geoffray } 9955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain Expected result = f(); 1009cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray if (has_result) { 101360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray ASSERT_EQ(result, expected); 1029cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray } 1039cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray} 1049cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray 10555dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillaintemplate <typename Expected> 10655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillainstatic void RunCodeBaseline(HGraph* graph, bool has_result, Expected expected) { 107787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray InternalCodeAllocator allocator; 1089cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray 109cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle CompilerOptions compiler_options; 110cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle x86::CodeGeneratorX86 codegenX86(graph, compiler_options); 11173e80c3ae76fafdb53afe3a85306dcb491fb5b00Nicolas Geoffray // We avoid doing a stack overflow check that requires the runtime being setup, 11273e80c3ae76fafdb53afe3a85306dcb491fb5b00Nicolas Geoffray // by making sure the compiler knows the methods we are running are leaf methods. 1138a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray codegenX86.CompileBaseline(&allocator, true); 1148a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray if (kRuntimeISA == kX86) { 1158a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray Run(allocator, codegenX86, has_result, expected); 1168a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray } 1179cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray 118df64950a466c0f00cd36120d1afd389c577cae87Andreas Gampe std::unique_ptr<const ArmInstructionSetFeatures> features( 119df64950a466c0f00cd36120d1afd389c577cae87Andreas Gampe ArmInstructionSetFeatures::FromCppDefines()); 120a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray TestCodeGeneratorARM codegenARM(graph, *features.get(), compiler_options); 1218a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray codegenARM.CompileBaseline(&allocator, true); 1228a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray if (kRuntimeISA == kArm || kRuntimeISA == kThumb2) { 1238a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray Run(allocator, codegenARM, has_result, expected); 1248a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray } 1259cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray 126cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle x86_64::CodeGeneratorX86_64 codegenX86_64(graph, compiler_options); 1278a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray codegenX86_64.CompileBaseline(&allocator, true); 1288a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray if (kRuntimeISA == kX86_64) { 1298a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray Run(allocator, codegenX86_64, has_result, expected); 1308a16d97fb8f031822b206e65f9109a071da40563Nicolas Geoffray } 1315319defdf502fc4569316473846b83180ec08035Alexandre Rames 132cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle arm64::CodeGeneratorARM64 codegenARM64(graph, compiler_options); 1335319defdf502fc4569316473846b83180ec08035Alexandre Rames codegenARM64.CompileBaseline(&allocator, true); 1345319defdf502fc4569316473846b83180ec08035Alexandre Rames if (kRuntimeISA == kArm64) { 1355319defdf502fc4569316473846b83180ec08035Alexandre Rames Run(allocator, codegenARM64, has_result, expected); 1365319defdf502fc4569316473846b83180ec08035Alexandre Rames } 137d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray} 138d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 13955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillaintemplate <typename Expected> 140360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffraystatic void RunCodeOptimized(CodeGenerator* codegen, 141360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray HGraph* graph, 142360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray std::function<void(HGraph*)> hook_before_codegen, 143360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray bool has_result, 14455dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain Expected expected) { 145360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray SsaLivenessAnalysis liveness(*graph, codegen); 146360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray liveness.Analyze(); 147360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 148360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray RegisterAllocator register_allocator(graph->GetArena(), codegen, liveness); 149360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray register_allocator.AllocateRegisters(); 150360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray hook_before_codegen(graph); 151360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 152360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray InternalCodeAllocator allocator; 153360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray codegen->CompileOptimized(&allocator); 154360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray Run(allocator, *codegen, has_result, expected); 155360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray} 156360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 15755dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillaintemplate <typename Expected> 158360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffraystatic void RunCodeOptimized(HGraph* graph, 159360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray std::function<void(HGraph*)> hook_before_codegen, 160360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray bool has_result, 16155dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain Expected expected) { 162cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle CompilerOptions compiler_options; 1633e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames if (kRuntimeISA == kArm || kRuntimeISA == kThumb2) { 164a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray TestCodeGeneratorARM codegenARM(graph, 165a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray *ArmInstructionSetFeatures::FromCppDefines(), 166a0bb2bd5b6a049ad806c223f00672d1f0210db67Nicolas Geoffray compiler_options); 167360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray RunCodeOptimized(&codegenARM, graph, hook_before_codegen, has_result, expected); 1683e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames } else if (kRuntimeISA == kArm64) { 169cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle arm64::CodeGeneratorARM64 codegenARM64(graph, compiler_options); 1703e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames RunCodeOptimized(&codegenARM64, graph, hook_before_codegen, has_result, expected); 1713e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames } else if (kRuntimeISA == kX86) { 172cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle x86::CodeGeneratorX86 codegenX86(graph, compiler_options); 1733e69f16ae3fddfd24f4f0e29deb106d564ab296cAlexandre Rames RunCodeOptimized(&codegenX86, graph, hook_before_codegen, has_result, expected); 174360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray } else if (kRuntimeISA == kX86_64) { 175cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle x86_64::CodeGeneratorX86_64 codegenX86_64(graph, compiler_options); 176360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray RunCodeOptimized(&codegenX86_64, graph, hook_before_codegen, has_result, expected); 177360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray } 178360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray} 179360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 180360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffraystatic void TestCode(const uint16_t* data, bool has_result = false, int32_t expected = 0) { 181360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray ArenaPool pool; 182360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray ArenaAllocator arena(&pool); 183360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray HGraphBuilder builder(&arena); 184360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data); 185360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray HGraph* graph = builder.BuildGraph(*item); 186360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray ASSERT_NE(graph, nullptr); 187039b6e2fd3bfadbd1ee8583002f673d6ccba5b7eCalin Juravle // Remove suspend checks, they cannot be executed in this context. 18848dee04f4e4214b0fdd8acd0587ef6b08d3d2456Calin Juravle RemoveSuspendChecks(graph); 189360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray RunCodeBaseline(graph, has_result, expected); 190360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray} 191360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 19255dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillainstatic void TestCodeLong(const uint16_t* data, bool has_result, int64_t expected) { 19355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain ArenaPool pool; 19455dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain ArenaAllocator arena(&pool); 19555dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain HGraphBuilder builder(&arena, Primitive::kPrimLong); 19655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data); 19755dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain HGraph* graph = builder.BuildGraph(*item); 19855dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain ASSERT_NE(graph, nullptr); 19955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain // Remove suspend checks, they cannot be executed in this context. 20055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain RemoveSuspendChecks(graph); 20155dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain RunCodeBaseline(graph, has_result, expected); 20255dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain} 20355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain 204d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas GeoffrayTEST(CodegenTest, ReturnVoid) { 2053ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(Instruction::RETURN_VOID); 2063ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray TestCode(data); 207d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray} 208d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 209bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas GeoffrayTEST(CodegenTest, CFG1) { 2103ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray const uint16_t data[] = ZERO_REGISTER_CODE_ITEM( 211d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::GOTO | 0x100, 2123ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray Instruction::RETURN_VOID); 213d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 2143ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray TestCode(data); 215d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray} 216d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 217bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas GeoffrayTEST(CodegenTest, CFG2) { 2183ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray const uint16_t data[] = ZERO_REGISTER_CODE_ITEM( 219d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::GOTO | 0x100, 220d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::GOTO | 0x100, 2213ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray Instruction::RETURN_VOID); 222d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 2233ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray TestCode(data); 224d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray} 225d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 226bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas GeoffrayTEST(CodegenTest, CFG3) { 2273ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM( 228d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::GOTO | 0x200, 229d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::RETURN_VOID, 2303ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray Instruction::GOTO | 0xFF00); 231d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 2323ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray TestCode(data1); 233d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 2343ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM( 235d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::GOTO_16, 3, 236d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::RETURN_VOID, 2373ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray Instruction::GOTO_16, 0xFFFF); 238d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 2393ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray TestCode(data2); 240d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 2413ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray const uint16_t data3[] = ZERO_REGISTER_CODE_ITEM( 242d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::GOTO_32, 4, 0, 243d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::RETURN_VOID, 2443ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray Instruction::GOTO_32, 0xFFFF, 0xFFFF); 245d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 2463ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray TestCode(data3); 247d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray} 248d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 249bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas GeoffrayTEST(CodegenTest, CFG4) { 2503ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray const uint16_t data[] = ZERO_REGISTER_CODE_ITEM( 251d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::RETURN_VOID, 252d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray Instruction::GOTO | 0x100, 2533ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray Instruction::GOTO | 0xFE00); 254d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 2553ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray TestCode(data); 256d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray} 257d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 258bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas GeoffrayTEST(CodegenTest, CFG5) { 259bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 260bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 261bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::IF_EQ, 3, 262bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::GOTO | 0x100, 263bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN_VOID); 264bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 265bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray TestCode(data); 266bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray} 267bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 268bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas GeoffrayTEST(CodegenTest, IntConstant) { 269bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 270bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 271bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN_VOID); 272bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 273bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray TestCode(data); 274bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray} 275bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 276bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas GeoffrayTEST(CodegenTest, Return1) { 277bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 278bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 279bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN | 0); 280bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 281bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray TestCode(data, true, 0); 282bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray} 283bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 284bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas GeoffrayTEST(CodegenTest, Return2) { 285bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 286bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 287bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 1 << 8, 288bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN | 1 << 8); 289bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 290bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray TestCode(data, true, 0); 291bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray} 292bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 293bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas GeoffrayTEST(CodegenTest, Return3) { 294bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 295bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 296bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 1 << 8 | 1 << 12, 297bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN | 1 << 8); 298bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 299bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray TestCode(data, true, 1); 300bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray} 301bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 302bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas GeoffrayTEST(CodegenTest, ReturnIf1) { 303bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 304bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 305bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 1 << 8 | 1 << 12, 306bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::IF_EQ, 3, 307bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN | 0 << 8, 308bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN | 1 << 8); 309bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 310bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray TestCode(data, true, 1); 311bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray} 312bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 313bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas GeoffrayTEST(CodegenTest, ReturnIf2) { 314bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 315bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 0 | 0, 316bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::CONST_4 | 1 << 8 | 1 << 12, 317bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::IF_EQ | 0 << 4 | 1 << 8, 3, 318bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN | 0 << 8, 319bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray Instruction::RETURN | 1 << 8); 320bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 321bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray TestCode(data, true, 0); 322bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray} 323bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 3241cc5f251df558b0e22cea5000626365eb644c727Roland Levillain// Exercise bit-wise (one's complement) not-int instruction. 3251cc5f251df558b0e22cea5000626365eb644c727Roland Levillain#define NOT_INT_TEST(TEST_NAME, INPUT, EXPECTED_OUTPUT) \ 3261cc5f251df558b0e22cea5000626365eb644c727Roland LevillainTEST(CodegenTest, TEST_NAME) { \ 3271cc5f251df558b0e22cea5000626365eb644c727Roland Levillain const int32_t input = INPUT; \ 32855dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const uint16_t input_lo = Low16Bits(input); \ 32955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const uint16_t input_hi = High16Bits(input); \ 3301cc5f251df558b0e22cea5000626365eb644c727Roland Levillain const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( \ 3311cc5f251df558b0e22cea5000626365eb644c727Roland Levillain Instruction::CONST | 0 << 8, input_lo, input_hi, \ 3321cc5f251df558b0e22cea5000626365eb644c727Roland Levillain Instruction::NOT_INT | 1 << 8 | 0 << 12 , \ 3331cc5f251df558b0e22cea5000626365eb644c727Roland Levillain Instruction::RETURN | 1 << 8); \ 3341cc5f251df558b0e22cea5000626365eb644c727Roland Levillain \ 3351cc5f251df558b0e22cea5000626365eb644c727Roland Levillain TestCode(data, true, EXPECTED_OUTPUT); \ 3361cc5f251df558b0e22cea5000626365eb644c727Roland Levillain} 3371cc5f251df558b0e22cea5000626365eb644c727Roland Levillain 3381cc5f251df558b0e22cea5000626365eb644c727Roland LevillainNOT_INT_TEST(ReturnNotIntMinus2, -2, 1) 3391cc5f251df558b0e22cea5000626365eb644c727Roland LevillainNOT_INT_TEST(ReturnNotIntMinus1, -1, 0) 3401cc5f251df558b0e22cea5000626365eb644c727Roland LevillainNOT_INT_TEST(ReturnNotInt0, 0, -1) 3411cc5f251df558b0e22cea5000626365eb644c727Roland LevillainNOT_INT_TEST(ReturnNotInt1, 1, -2) 34255dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_INT_TEST(ReturnNotIntINT32_MIN, -2147483648, 2147483647) // (2^31) - 1 34355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_INT_TEST(ReturnNotIntINT32_MINPlus1, -2147483647, 2147483646) // (2^31) - 2 34455dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_INT_TEST(ReturnNotIntINT32_MAXMinus1, 2147483646, -2147483647) // -(2^31) - 1 34555dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_INT_TEST(ReturnNotIntINT32_MAX, 2147483647, -2147483648) // -(2^31) 3461cc5f251df558b0e22cea5000626365eb644c727Roland Levillain 3471cc5f251df558b0e22cea5000626365eb644c727Roland Levillain#undef NOT_INT_TEST 3481cc5f251df558b0e22cea5000626365eb644c727Roland Levillain 34955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain// Exercise bit-wise (one's complement) not-long instruction. 35055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain#define NOT_LONG_TEST(TEST_NAME, INPUT, EXPECTED_OUTPUT) \ 35155dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainTEST(CodegenTest, TEST_NAME) { \ 35255dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const int64_t input = INPUT; \ 35355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const uint16_t word0 = Low16Bits(Low32Bits(input)); /* LSW. */ \ 35455dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const uint16_t word1 = High16Bits(Low32Bits(input)); \ 35555dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const uint16_t word2 = Low16Bits(High32Bits(input)); \ 35655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const uint16_t word3 = High16Bits(High32Bits(input)); /* MSW. */ \ 35755dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain const uint16_t data[] = FOUR_REGISTERS_CODE_ITEM( \ 35855dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain Instruction::CONST_WIDE | 0 << 8, word0, word1, word2, word3, \ 35955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain Instruction::NOT_LONG | 2 << 8 | 0 << 12, \ 36055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain Instruction::RETURN_WIDE | 2 << 8); \ 36155dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain \ 36255dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain TestCodeLong(data, true, EXPECTED_OUTPUT); \ 36355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain} 36455dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain 36555dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongMinus2, INT64_C(-2), INT64_C(1)) 36655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongMinus1, INT64_C(-1), INT64_C(0)) 36755dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLong0, INT64_C(0), INT64_C(-1)) 36855dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLong1, INT64_C(1), INT64_C(-2)) 36955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain 37055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongINT32_MIN, 37155dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-2147483648), 37255dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(2147483647)) // (2^31) - 1 37355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongINT32_MINPlus1, 37455dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-2147483647), 37555dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(2147483646)) // (2^31) - 2 37655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongINT32_MAXMinus1, 37755dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(2147483646), 37855dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-2147483647)) // -(2^31) - 1 37955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongINT32_MAX, 38055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(2147483647), 38155dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-2147483648)) // -(2^31) 38255dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain 38355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain// Note that the C++ compiler won't accept 38455dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain// INT64_C(-9223372036854775808) (that is, INT64_MIN) as a valid 38555dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain// int64_t literal, so we use INT64_C(-9223372036854775807)-1 instead. 38655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotINT64_MIN, 38755dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-9223372036854775807)-1, 38855dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(9223372036854775807)); // (2^63) - 1 38955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotINT64_MINPlus1, 39055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-9223372036854775807), 39155dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(9223372036854775806)); // (2^63) - 2 39255dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongINT64_MAXMinus1, 39355dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(9223372036854775806), 39455dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-9223372036854775807)); // -(2^63) - 1 39555dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland LevillainNOT_LONG_TEST(ReturnNotLongINT64_MAX, 39655dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(9223372036854775807), 39755dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain INT64_C(-9223372036854775807)-1); // -(2^63) 39855dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain 39955dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain#undef NOT_LONG_TEST 40055dcfb5e0dd626993bb2b7b9f692c1b02b5d955fRoland Levillain 401946e143941d456a4ec666f7f54719c65c5aa3f5dRoland LevillainTEST(CodegenTest, IntToLongOfLongToInt) { 402946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain const int64_t input = INT64_C(4294967296); // 2^32 403946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain const uint16_t word0 = Low16Bits(Low32Bits(input)); // LSW. 404946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain const uint16_t word1 = High16Bits(Low32Bits(input)); 405946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain const uint16_t word2 = Low16Bits(High32Bits(input)); 406946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain const uint16_t word3 = High16Bits(High32Bits(input)); // MSW. 407946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain const uint16_t data[] = FIVE_REGISTERS_CODE_ITEM( 408946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain Instruction::CONST_WIDE | 0 << 8, word0, word1, word2, word3, 409946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain Instruction::CONST_WIDE | 2 << 8, 1, 0, 0, 0, 410946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain Instruction::ADD_LONG | 0, 0 << 8 | 2, // v0 <- 2^32 + 1 411946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain Instruction::LONG_TO_INT | 4 << 8 | 0 << 12, 412946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain Instruction::INT_TO_LONG | 2 << 8 | 4 << 12, 413946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain Instruction::RETURN_WIDE | 2 << 8); 414946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain 415946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain TestCodeLong(data, true, 1); 416946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain} 417946e143941d456a4ec666f7f54719c65c5aa3f5dRoland Levillain 418d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas GeoffrayTEST(CodegenTest, ReturnAdd1) { 419d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 420d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::CONST_4 | 3 << 12 | 0, 421d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 1 << 8, 422d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::ADD_INT, 1 << 8 | 0, 423d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::RETURN); 424d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray 425d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray TestCode(data, true, 7); 426d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray} 427d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray 428d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas GeoffrayTEST(CodegenTest, ReturnAdd2) { 429d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 430d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::CONST_4 | 3 << 12 | 0, 431d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 1 << 8, 432d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::ADD_INT_2ADDR | 1 << 12, 433d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::RETURN); 434d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray 435d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray TestCode(data, true, 7); 436d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray} 437d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray 438d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas GeoffrayTEST(CodegenTest, ReturnAdd3) { 439d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 440d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0 << 8, 441d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::ADD_INT_LIT8, 3 << 8 | 0, 442d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::RETURN); 443d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray 444d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray TestCode(data, true, 7); 445d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray} 446d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray 447d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas GeoffrayTEST(CodegenTest, ReturnAdd4) { 448d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 449d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::CONST_4 | 4 << 12 | 0 << 8, 450d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::ADD_INT_LIT16, 3, 451d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray Instruction::RETURN); 452d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray 453d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray TestCode(data, true, 7); 454d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray} 455d8ee737fdbf380c5bb90c9270c8d1087ac23e76cNicolas Geoffray 456360231a056e796c36ffe62348507e904dc9efb9bNicolas GeoffrayTEST(CodegenTest, NonMaterializedCondition) { 457360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray ArenaPool pool; 458360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray ArenaAllocator allocator(&pool); 459360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 460360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray HGraph* graph = new (&allocator) HGraph(&allocator); 461360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray HBasicBlock* entry = new (&allocator) HBasicBlock(graph); 462360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray graph->AddBlock(entry); 463360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray graph->SetEntryBlock(entry); 464360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray entry->AddInstruction(new (&allocator) HGoto()); 465360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 466360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray HBasicBlock* first_block = new (&allocator) HBasicBlock(graph); 467360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray graph->AddBlock(first_block); 468360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray entry->AddSuccessor(first_block); 469360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray HIntConstant* constant0 = new (&allocator) HIntConstant(0); 470360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray entry->AddInstruction(constant0); 471360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray HIntConstant* constant1 = new (&allocator) HIntConstant(1); 472360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray entry->AddInstruction(constant1); 473360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray HEqual* equal = new (&allocator) HEqual(constant0, constant0); 474360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray first_block->AddInstruction(equal); 475360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray first_block->AddInstruction(new (&allocator) HIf(equal)); 476360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 477360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray HBasicBlock* then = new (&allocator) HBasicBlock(graph); 478360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray HBasicBlock* else_ = new (&allocator) HBasicBlock(graph); 479360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray HBasicBlock* exit = new (&allocator) HBasicBlock(graph); 480360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 481360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray graph->AddBlock(then); 482360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray graph->AddBlock(else_); 483360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray graph->AddBlock(exit); 484360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray first_block->AddSuccessor(then); 485360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray first_block->AddSuccessor(else_); 486360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray then->AddSuccessor(exit); 487360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray else_->AddSuccessor(exit); 488360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 489360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray exit->AddInstruction(new (&allocator) HExit()); 490360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray then->AddInstruction(new (&allocator) HReturn(constant0)); 491360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray else_->AddInstruction(new (&allocator) HReturn(constant1)); 492360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 493360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray ASSERT_TRUE(equal->NeedsMaterialization()); 494360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray graph->BuildDominatorTree(); 495360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray PrepareForRegisterAllocation(graph).Run(); 496360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray ASSERT_FALSE(equal->NeedsMaterialization()); 497360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 498277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe auto hook_before_codegen = [](HGraph* graph_in) { 499277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe HBasicBlock* block = graph_in->GetEntryBlock()->GetSuccessors().Get(0); 500277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe HParallelMove* move = new (graph_in->GetArena()) HParallelMove(graph_in->GetArena()); 501360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray block->InsertInstructionBefore(move, block->GetLastInstruction()); 502360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray }; 503360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 504360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray RunCodeOptimized(graph, hook_before_codegen, true, 0); 505360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray} 506360231a056e796c36ffe62348507e904dc9efb9bNicolas Geoffray 50734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle#define MUL_TEST(TYPE, TEST_NAME) \ 50834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle TEST(CodegenTest, Return ## TEST_NAME) { \ 50934bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( \ 51034bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::CONST_4 | 3 << 12 | 0, \ 51134bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::CONST_4 | 4 << 12 | 1 << 8, \ 51234bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::MUL_ ## TYPE, 1 << 8 | 0, \ 51334bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::RETURN); \ 51434bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle \ 51534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle TestCode(data, true, 12); \ 51634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle } \ 51734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle \ 51834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle TEST(CodegenTest, Return ## TEST_NAME ## 2addr) { \ 51934bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( \ 52034bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::CONST_4 | 3 << 12 | 0, \ 52134bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::CONST_4 | 4 << 12 | 1 << 8, \ 52234bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::MUL_ ## TYPE ## _2ADDR | 1 << 12, \ 52334bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::RETURN); \ 52434bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle \ 52534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle TestCode(data, true, 12); \ 52634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle } 52734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle 52834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin JuravleMUL_TEST(INT, MulInt); 52934bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin JuravleMUL_TEST(LONG, MulLong); 53034bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle 53134bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin JuravleTEST(CodegenTest, ReturnMulIntLit8) { 53234bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 53334bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::CONST_4 | 4 << 12 | 0 << 8, 53434bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::MUL_INT_LIT8, 3 << 8 | 0, 53534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::RETURN); 53634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle 53734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle TestCode(data, true, 12); 53834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle} 53934bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle 54034bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin JuravleTEST(CodegenTest, ReturnMulIntLit16) { 54134bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 54234bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::CONST_4 | 4 << 12 | 0 << 8, 54334bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::MUL_INT_LIT16, 3, 54434bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle Instruction::RETURN); 54534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle 54634bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle TestCode(data, true, 12); 54734bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle} 54834bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle 549927307433af0a9322e8ba77eda37168512a73683Alexandre RamesTEST(CodegenTest, MaterializedCondition1) { 550927307433af0a9322e8ba77eda37168512a73683Alexandre Rames // Check that condition are materialized correctly. A materialized condition 551927307433af0a9322e8ba77eda37168512a73683Alexandre Rames // should yield `1` if it evaluated to true, and `0` otherwise. 552927307433af0a9322e8ba77eda37168512a73683Alexandre Rames // We force the materialization of comparisons for different combinations of 553927307433af0a9322e8ba77eda37168512a73683Alexandre Rames // inputs and check the results. 554927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 555927307433af0a9322e8ba77eda37168512a73683Alexandre Rames int lhs[] = {1, 2, -1, 2, 0xabc}; 556927307433af0a9322e8ba77eda37168512a73683Alexandre Rames int rhs[] = {2, 1, 2, -1, 0xabc}; 557927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 558927307433af0a9322e8ba77eda37168512a73683Alexandre Rames for (size_t i = 0; i < arraysize(lhs); i++) { 559927307433af0a9322e8ba77eda37168512a73683Alexandre Rames ArenaPool pool; 560927307433af0a9322e8ba77eda37168512a73683Alexandre Rames ArenaAllocator allocator(&pool); 561927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HGraph* graph = new (&allocator) HGraph(&allocator); 562927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 563927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HBasicBlock* entry_block = new (&allocator) HBasicBlock(graph); 564927307433af0a9322e8ba77eda37168512a73683Alexandre Rames graph->AddBlock(entry_block); 565927307433af0a9322e8ba77eda37168512a73683Alexandre Rames graph->SetEntryBlock(entry_block); 566927307433af0a9322e8ba77eda37168512a73683Alexandre Rames entry_block->AddInstruction(new (&allocator) HGoto()); 567927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HBasicBlock* code_block = new (&allocator) HBasicBlock(graph); 568927307433af0a9322e8ba77eda37168512a73683Alexandre Rames graph->AddBlock(code_block); 569927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HBasicBlock* exit_block = new (&allocator) HBasicBlock(graph); 570927307433af0a9322e8ba77eda37168512a73683Alexandre Rames graph->AddBlock(exit_block); 571927307433af0a9322e8ba77eda37168512a73683Alexandre Rames exit_block->AddInstruction(new (&allocator) HExit()); 572927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 573927307433af0a9322e8ba77eda37168512a73683Alexandre Rames entry_block->AddSuccessor(code_block); 574927307433af0a9322e8ba77eda37168512a73683Alexandre Rames code_block->AddSuccessor(exit_block); 575927307433af0a9322e8ba77eda37168512a73683Alexandre Rames graph->SetExitBlock(exit_block); 576927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 577927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HIntConstant cst_lhs(lhs[i]); 578927307433af0a9322e8ba77eda37168512a73683Alexandre Rames code_block->AddInstruction(&cst_lhs); 579927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HIntConstant cst_rhs(rhs[i]); 580927307433af0a9322e8ba77eda37168512a73683Alexandre Rames code_block->AddInstruction(&cst_rhs); 581927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HLessThan cmp_lt(&cst_lhs, &cst_rhs); 582927307433af0a9322e8ba77eda37168512a73683Alexandre Rames code_block->AddInstruction(&cmp_lt); 583927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HReturn ret(&cmp_lt); 584927307433af0a9322e8ba77eda37168512a73683Alexandre Rames code_block->AddInstruction(&ret); 585927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 586277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe auto hook_before_codegen = [](HGraph* graph_in) { 587277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe HBasicBlock* block = graph_in->GetEntryBlock()->GetSuccessors().Get(0); 588277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe HParallelMove* move = new (graph_in->GetArena()) HParallelMove(graph_in->GetArena()); 589927307433af0a9322e8ba77eda37168512a73683Alexandre Rames block->InsertInstructionBefore(move, block->GetLastInstruction()); 590927307433af0a9322e8ba77eda37168512a73683Alexandre Rames }; 591927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 592927307433af0a9322e8ba77eda37168512a73683Alexandre Rames RunCodeOptimized(graph, hook_before_codegen, true, lhs[i] < rhs[i]); 593927307433af0a9322e8ba77eda37168512a73683Alexandre Rames } 594927307433af0a9322e8ba77eda37168512a73683Alexandre Rames} 595927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 596927307433af0a9322e8ba77eda37168512a73683Alexandre RamesTEST(CodegenTest, MaterializedCondition2) { 597927307433af0a9322e8ba77eda37168512a73683Alexandre Rames // Check that HIf correctly interprets a materialized condition. 598927307433af0a9322e8ba77eda37168512a73683Alexandre Rames // We force the materialization of comparisons for different combinations of 599927307433af0a9322e8ba77eda37168512a73683Alexandre Rames // inputs. An HIf takes the materialized combination as input and returns a 600927307433af0a9322e8ba77eda37168512a73683Alexandre Rames // value that we verify. 601927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 602927307433af0a9322e8ba77eda37168512a73683Alexandre Rames int lhs[] = {1, 2, -1, 2, 0xabc}; 603927307433af0a9322e8ba77eda37168512a73683Alexandre Rames int rhs[] = {2, 1, 2, -1, 0xabc}; 604927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 605927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 606927307433af0a9322e8ba77eda37168512a73683Alexandre Rames for (size_t i = 0; i < arraysize(lhs); i++) { 607927307433af0a9322e8ba77eda37168512a73683Alexandre Rames ArenaPool pool; 608927307433af0a9322e8ba77eda37168512a73683Alexandre Rames ArenaAllocator allocator(&pool); 609927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HGraph* graph = new (&allocator) HGraph(&allocator); 610927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 611927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HBasicBlock* entry_block = new (&allocator) HBasicBlock(graph); 612927307433af0a9322e8ba77eda37168512a73683Alexandre Rames graph->AddBlock(entry_block); 613927307433af0a9322e8ba77eda37168512a73683Alexandre Rames graph->SetEntryBlock(entry_block); 614927307433af0a9322e8ba77eda37168512a73683Alexandre Rames entry_block->AddInstruction(new (&allocator) HGoto()); 615927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 616927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HBasicBlock* if_block = new (&allocator) HBasicBlock(graph); 617927307433af0a9322e8ba77eda37168512a73683Alexandre Rames graph->AddBlock(if_block); 618927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HBasicBlock* if_true_block = new (&allocator) HBasicBlock(graph); 619927307433af0a9322e8ba77eda37168512a73683Alexandre Rames graph->AddBlock(if_true_block); 620927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HBasicBlock* if_false_block = new (&allocator) HBasicBlock(graph); 621927307433af0a9322e8ba77eda37168512a73683Alexandre Rames graph->AddBlock(if_false_block); 622927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HBasicBlock* exit_block = new (&allocator) HBasicBlock(graph); 623927307433af0a9322e8ba77eda37168512a73683Alexandre Rames graph->AddBlock(exit_block); 624927307433af0a9322e8ba77eda37168512a73683Alexandre Rames exit_block->AddInstruction(new (&allocator) HExit()); 625927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 626927307433af0a9322e8ba77eda37168512a73683Alexandre Rames graph->SetEntryBlock(entry_block); 627927307433af0a9322e8ba77eda37168512a73683Alexandre Rames entry_block->AddSuccessor(if_block); 628927307433af0a9322e8ba77eda37168512a73683Alexandre Rames if_block->AddSuccessor(if_true_block); 629927307433af0a9322e8ba77eda37168512a73683Alexandre Rames if_block->AddSuccessor(if_false_block); 630927307433af0a9322e8ba77eda37168512a73683Alexandre Rames if_true_block->AddSuccessor(exit_block); 631927307433af0a9322e8ba77eda37168512a73683Alexandre Rames if_false_block->AddSuccessor(exit_block); 632927307433af0a9322e8ba77eda37168512a73683Alexandre Rames graph->SetExitBlock(exit_block); 633927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 634927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HIntConstant cst_lhs(lhs[i]); 635927307433af0a9322e8ba77eda37168512a73683Alexandre Rames if_block->AddInstruction(&cst_lhs); 636927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HIntConstant cst_rhs(rhs[i]); 637927307433af0a9322e8ba77eda37168512a73683Alexandre Rames if_block->AddInstruction(&cst_rhs); 638927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HLessThan cmp_lt(&cst_lhs, &cst_rhs); 639927307433af0a9322e8ba77eda37168512a73683Alexandre Rames if_block->AddInstruction(&cmp_lt); 640927307433af0a9322e8ba77eda37168512a73683Alexandre Rames // We insert a temporary to separate the HIf from the HLessThan and force 641927307433af0a9322e8ba77eda37168512a73683Alexandre Rames // the materialization of the condition. 642927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HTemporary force_materialization(0); 643927307433af0a9322e8ba77eda37168512a73683Alexandre Rames if_block->AddInstruction(&force_materialization); 644927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HIf if_lt(&cmp_lt); 645927307433af0a9322e8ba77eda37168512a73683Alexandre Rames if_block->AddInstruction(&if_lt); 646927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 647927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HIntConstant cst_lt(1); 648927307433af0a9322e8ba77eda37168512a73683Alexandre Rames if_true_block->AddInstruction(&cst_lt); 649927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HReturn ret_lt(&cst_lt); 650927307433af0a9322e8ba77eda37168512a73683Alexandre Rames if_true_block->AddInstruction(&ret_lt); 651927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HIntConstant cst_ge(0); 652927307433af0a9322e8ba77eda37168512a73683Alexandre Rames if_false_block->AddInstruction(&cst_ge); 653927307433af0a9322e8ba77eda37168512a73683Alexandre Rames HReturn ret_ge(&cst_ge); 654927307433af0a9322e8ba77eda37168512a73683Alexandre Rames if_false_block->AddInstruction(&ret_ge); 655927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 656277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe auto hook_before_codegen = [](HGraph* graph_in) { 657277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe HBasicBlock* block = graph_in->GetEntryBlock()->GetSuccessors().Get(0); 658277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe HParallelMove* move = new (graph_in->GetArena()) HParallelMove(graph_in->GetArena()); 659927307433af0a9322e8ba77eda37168512a73683Alexandre Rames block->InsertInstructionBefore(move, block->GetLastInstruction()); 660927307433af0a9322e8ba77eda37168512a73683Alexandre Rames }; 661927307433af0a9322e8ba77eda37168512a73683Alexandre Rames 662927307433af0a9322e8ba77eda37168512a73683Alexandre Rames RunCodeOptimized(graph, hook_before_codegen, true, lhs[i] < rhs[i]); 663927307433af0a9322e8ba77eda37168512a73683Alexandre Rames } 664927307433af0a9322e8ba77eda37168512a73683Alexandre Rames} 66534bacdf7eb46c0ffbf24ba7aa14a904bc9176fb2Calin Juravle 666d0d4852847432368b090c184d6639e573538dccfCalin JuravleTEST(CodegenTest, ReturnDivIntLit8) { 667d0d4852847432368b090c184d6639e573538dccfCalin Juravle const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 668d0d4852847432368b090c184d6639e573538dccfCalin Juravle Instruction::CONST_4 | 4 << 12 | 0 << 8, 669d0d4852847432368b090c184d6639e573538dccfCalin Juravle Instruction::DIV_INT_LIT8, 3 << 8 | 0, 670d0d4852847432368b090c184d6639e573538dccfCalin Juravle Instruction::RETURN); 671d0d4852847432368b090c184d6639e573538dccfCalin Juravle 672d0d4852847432368b090c184d6639e573538dccfCalin Juravle TestCode(data, true, 1); 673d0d4852847432368b090c184d6639e573538dccfCalin Juravle} 674d0d4852847432368b090c184d6639e573538dccfCalin Juravle 675865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin JuravleTEST(CodegenTest, ReturnDivInt2Addr) { 676865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 677865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle Instruction::CONST_4 | 4 << 12 | 0, 678865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle Instruction::CONST_4 | 2 << 12 | 1 << 8, 679865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle Instruction::DIV_INT_2ADDR | 1 << 12, 680865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle Instruction::RETURN); 681865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle 682865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle TestCode(data, true, 2); 683865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle} 684865fc88fdfd006ce0362c2c0d55c66a7bffdab61Calin Juravle 685d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray} // namespace art 686