1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_CCTEST_COMPILER_CODEGEN_TESTER_H_ 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_CCTEST_COMPILER_CODEGEN_TESTER_H_ 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/instruction-selector.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/pipeline.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/raw-machine-assembler.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/simulator.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "test/cctest/compiler/call-tester.h" 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <typename ReturnType> 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass RawMachineAssemblerTester : public HandleAndZoneScope, 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public CallHelper<ReturnType>, 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public RawMachineAssembler { 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawMachineAssemblerTester(MachineType p0 = MachineType::None(), 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p1 = MachineType::None(), 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p2 = MachineType::None(), 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p3 = MachineType::None(), 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p4 = MachineType::None()) 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : HandleAndZoneScope(), 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallHelper<ReturnType>( 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch main_isolate(), 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1, 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch p2, p3, p4)), 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawMachineAssembler( 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch main_isolate(), new (main_zone()) Graph(main_zone()), 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Linkage::GetSimplifiedCDescriptor( 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch main_zone(), 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, 38342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch p1, p2, p3, p4), 39342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch true), 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::PointerRepresentation(), 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionSelector::SupportedMachineOperatorFlags()) {} 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 43342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch virtual ~RawMachineAssemblerTester() {} 44342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CheckNumber(double expected, Object* number) { 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(this->isolate()->factory()->NewNumber(expected)->SameValue(number)); 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CheckString(const char* expected, Object* string) { 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK( 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this->isolate()->factory()->InternalizeUtf8String(expected)->SameValue( 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch string)); 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GenerateCode() { Generate(); } 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> GetCode() { 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Generate(); 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return code_.ToHandleChecked(); 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected: 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual byte* Generate() { 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (code_.is_null()) { 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Schedule* schedule = this->Export(); 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallDescriptor* call_descriptor = this->call_descriptor(); 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Graph* graph = this->graph(); 68537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CompilationInfo info(ArrayVector("testing"), main_isolate(), main_zone()); 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch code_ = Pipeline::GenerateCodeForTesting(&info, call_descriptor, graph, 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch schedule); 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return this->code_.ToHandleChecked()->entry(); 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MaybeHandle<Code> code_; 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename ReturnType> 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass BufferedRawMachineAssemblerTester 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : public RawMachineAssemblerTester<int32_t> { 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BufferedRawMachineAssemblerTester(MachineType p0 = MachineType::None(), 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p1 = MachineType::None(), 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p2 = MachineType::None(), 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p3 = MachineType::None()) 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : BufferedRawMachineAssemblerTester(ComputeParameterCount(p0, p1, p2, p3), 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch p0, p1, p2, p3) {} 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 91342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch virtual byte* Generate() { return RawMachineAssemblerTester::Generate(); } 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The BufferedRawMachineAssemblerTester does not pass parameters directly 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to the constructed IR graph. Instead it passes a pointer to the parameter 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to the IR graph, and adds Load nodes to the IR graph to load the 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // parameters from memory. Thereby it is possible to pass 64 bit parameters 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to the IR graph. 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* Parameter(size_t index) { 99342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK(index < 4); 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return parameter_nodes_[index]; 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The BufferedRawMachineAssemblerTester adds a Store node to the IR graph 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to store the graph's return value in memory. The memory address for the 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Store node is provided as a parameter. By storing the return value in 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // memory it is possible to return 64 bit values. 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Return(Node* input) { 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Store(MachineTypeForC<ReturnType>().representation(), 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawMachineAssembler::Parameter(return_parameter_index_), input, 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kNoWriteBarrier); 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawMachineAssembler::Return(Int32Constant(1234)); 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnType Call() { 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnType return_value; 116342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CSignature::VerifyParams(test_graph_signature_); 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallHelper<int32_t>::Call(reinterpret_cast<void*>(&return_value)); 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return return_value; 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <typename P0> 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnType Call(P0 p0) { 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnType return_value; 124342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CSignature::VerifyParams<P0>(test_graph_signature_); 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallHelper<int32_t>::Call(reinterpret_cast<void*>(&p0), 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<void*>(&return_value)); 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return return_value; 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <typename P0, typename P1> 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnType Call(P0 p0, P1 p1) { 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnType return_value; 133342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CSignature::VerifyParams<P0, P1>(test_graph_signature_); 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallHelper<int32_t>::Call(reinterpret_cast<void*>(&p0), 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<void*>(&p1), 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<void*>(&return_value)); 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return return_value; 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <typename P0, typename P1, typename P2> 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnType Call(P0 p0, P1 p1, P2 p2) { 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnType return_value; 143342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CSignature::VerifyParams<P0, P1, P2>(test_graph_signature_); 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallHelper<int32_t>::Call( 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1), 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&return_value)); 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return return_value; 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <typename P0, typename P1, typename P2, typename P3> 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) { 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnType return_value; 153342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CSignature::VerifyParams<P0, P1, P2, P3>(test_graph_signature_); 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallHelper<int32_t>::Call( 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1), 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&p3), 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<void*>(&return_value)); 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return return_value; 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BufferedRawMachineAssemblerTester(uint32_t return_parameter_index, 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p0, MachineType p1, 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p2, MachineType p3) 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : RawMachineAssemblerTester<int32_t>( 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Pointer(), 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch p0 == MachineType::None() ? MachineType::None() 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : MachineType::Pointer(), 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch p1 == MachineType::None() ? MachineType::None() 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : MachineType::Pointer(), 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch p2 == MachineType::None() ? MachineType::None() 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : MachineType::Pointer(), 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch p3 == MachineType::None() ? MachineType::None() 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : MachineType::Pointer()), 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch test_graph_signature_( 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CSignature::New(main_zone(), MachineType::Int32(), p0, p1, p2, p3)), 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return_parameter_index_(return_parameter_index) { 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameter_nodes_[0] = p0 == MachineType::None() 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? nullptr 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Load(p0, RawMachineAssembler::Parameter(0)); 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameter_nodes_[1] = p1 == MachineType::None() 182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? nullptr 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Load(p1, RawMachineAssembler::Parameter(1)); 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameter_nodes_[2] = p2 == MachineType::None() 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? nullptr 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Load(p2, RawMachineAssembler::Parameter(2)); 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameter_nodes_[3] = p3 == MachineType::None() 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? nullptr 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Load(p3, RawMachineAssembler::Parameter(3)); 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static uint32_t ComputeParameterCount(MachineType p0, MachineType p1, 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p2, MachineType p3) { 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p0 == MachineType::None()) { 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 0; 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p1 == MachineType::None()) { 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 1; 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p2 == MachineType::None()) { 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 2; 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p3 == MachineType::None()) { 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 3; 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 4; 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CSignature* test_graph_signature_; 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* parameter_nodes_[4]; 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t return_parameter_index_; 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <> 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass BufferedRawMachineAssemblerTester<void> 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : public RawMachineAssemblerTester<void> { 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BufferedRawMachineAssemblerTester(MachineType p0 = MachineType::None(), 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p1 = MachineType::None(), 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p2 = MachineType::None(), 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType p3 = MachineType::None()) 225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : RawMachineAssemblerTester<void>( 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch p0 == MachineType::None() ? MachineType::None() 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : MachineType::Pointer(), 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch p1 == MachineType::None() ? MachineType::None() 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : MachineType::Pointer(), 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch p2 == MachineType::None() ? MachineType::None() 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : MachineType::Pointer(), 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch p3 == MachineType::None() ? MachineType::None() 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : MachineType::Pointer()), 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch test_graph_signature_( 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CSignature::New(RawMachineAssemblerTester<void>::main_zone(), 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::None(), p0, p1, p2, p3)) { 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameter_nodes_[0] = p0 == MachineType::None() 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? nullptr 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Load(p0, RawMachineAssembler::Parameter(0)); 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameter_nodes_[1] = p1 == MachineType::None() 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? nullptr 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Load(p1, RawMachineAssembler::Parameter(1)); 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameter_nodes_[2] = p2 == MachineType::None() 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? nullptr 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Load(p2, RawMachineAssembler::Parameter(2)); 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameter_nodes_[3] = p3 == MachineType::None() 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? nullptr 248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Load(p3, RawMachineAssembler::Parameter(3)); 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 251342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch virtual byte* Generate() { return RawMachineAssemblerTester::Generate(); } 252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The BufferedRawMachineAssemblerTester does not pass parameters directly 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to the constructed IR graph. Instead it passes a pointer to the parameter 255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to the IR graph, and adds Load nodes to the IR graph to load the 256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // parameters from memory. Thereby it is possible to pass 64 bit parameters 257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to the IR graph. 258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* Parameter(size_t index) { 25921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch CHECK(index < 4); 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return parameter_nodes_[index]; 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Call() { 265342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CSignature::VerifyParams(test_graph_signature_); 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallHelper<void>::Call(); 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <typename P0> 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Call(P0 p0) { 271342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CSignature::VerifyParams<P0>(test_graph_signature_); 272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallHelper<void>::Call(reinterpret_cast<void*>(&p0)); 273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <typename P0, typename P1> 276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Call(P0 p0, P1 p1) { 277342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CSignature::VerifyParams<P0, P1>(test_graph_signature_); 278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallHelper<void>::Call(reinterpret_cast<void*>(&p0), 279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<void*>(&p1)); 280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <typename P0, typename P1, typename P2> 283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Call(P0 p0, P1 p1, P2 p2) { 284342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CSignature::VerifyParams<P0, P1, P2>(test_graph_signature_); 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallHelper<void>::Call(reinterpret_cast<void*>(&p0), 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<void*>(&p1), 287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<void*>(&p2)); 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <typename P0, typename P1, typename P2, typename P3> 291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Call(P0 p0, P1 p1, P2 p2, P3 p3) { 292342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CSignature::VerifyParams<P0, P1, P2, P3>(test_graph_signature_); 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallHelper<void>::Call( 294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1), 295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&p3)); 296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CSignature* test_graph_signature_; 300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* parameter_nodes_[4]; 301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const bool USE_RESULT_BUFFER = true; 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const bool USE_RETURN_REGISTER = false; 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int32_t CHECK_VALUE = 0x99BEEDCE; 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(titzer): use the C-style calling convention, or any register-based 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// calling convention for binop tests. 309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <typename CType, bool use_result_buffer> 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass BinopTester { 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit BinopTester(RawMachineAssemblerTester<int32_t>* tester, 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType rep) 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : T(tester), 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch param0(T->LoadFromPointer(&p0, rep)), 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch param1(T->LoadFromPointer(&p1, rep)), 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch rep(rep), 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch p0(static_cast<CType>(0)), 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch p1(static_cast<CType>(0)), 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result(static_cast<CType>(0)) {} 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RawMachineAssemblerTester<int32_t>* T; 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* param0; 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* param1; 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CType call(CType a0, CType a1) { 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch p0 = a0; 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch p1 = a1; 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (use_result_buffer) { 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(CHECK_VALUE, T->Call()); 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return static_cast<CType>(T->Call()); 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddReturn(Node* val) { 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (use_result_buffer) { 339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch T->Store(rep.representation(), T->PointerConstant(&result), 340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch T->Int32Constant(0), val, kNoWriteBarrier); 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T->Return(T->Int32Constant(CHECK_VALUE)); 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T->Return(val); 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template <typename Ci, typename Cj, typename Fn> 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Run(const Ci& ci, const Cj& cj, const Fn& fn) { 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typename Ci::const_iterator i; 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typename Cj::const_iterator j; 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (i = ci.begin(); i != ci.end(); ++i) { 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (j = cj.begin(); j != cj.end(); ++j) { 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(fn(*i, *j), this->call(*i, *j)); 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected: 359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType rep; 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CType p0; 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CType p1; 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CType result; 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A helper class for testing code sequences that take two int parameters and 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// return an int value. 368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Int32BinopTester : public BinopTester<int32_t, USE_RETURN_REGISTER> { 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit Int32BinopTester(RawMachineAssemblerTester<int32_t>* tester) 371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : BinopTester<int32_t, USE_RETURN_REGISTER>(tester, 372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32()) {} 373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// A helper class for testing code sequences that take two int parameters and 377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// return an int value. 378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Int64BinopTester : public BinopTester<int64_t, USE_RETURN_REGISTER> { 379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit Int64BinopTester(RawMachineAssemblerTester<int32_t>* tester) 381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : BinopTester<int64_t, USE_RETURN_REGISTER>(tester, 382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int64()) {} 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A helper class for testing code sequences that take two uint parameters and 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// return an uint value. 388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Uint32BinopTester : public BinopTester<uint32_t, USE_RETURN_REGISTER> { 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit Uint32BinopTester(RawMachineAssemblerTester<int32_t>* tester) 391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : BinopTester<uint32_t, USE_RETURN_REGISTER>(tester, 392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Uint32()) {} 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t call(uint32_t a0, uint32_t a1) { 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch p0 = a0; 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch p1 = a1; 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return static_cast<uint32_t>(T->Call()); 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// A helper class for testing code sequences that take two float parameters and 403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// return a float value. 404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Float32BinopTester : public BinopTester<float, USE_RESULT_BUFFER> { 405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit Float32BinopTester(RawMachineAssemblerTester<int32_t>* tester) 407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : BinopTester<float, USE_RESULT_BUFFER>(tester, MachineType::Float32()) {} 408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A helper class for testing code sequences that take two double parameters and 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// return a double value. 413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Float64BinopTester : public BinopTester<double, USE_RESULT_BUFFER> { 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit Float64BinopTester(RawMachineAssemblerTester<int32_t>* tester) 416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : BinopTester<double, USE_RESULT_BUFFER>(tester, MachineType::Float64()) { 417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A helper class for testing code sequences that take two pointer parameters 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and return a pointer value. 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(titzer): pick word size of pointers based on V8_TARGET. 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename Type> 425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass PointerBinopTester : public BinopTester<Type*, USE_RETURN_REGISTER> { 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit PointerBinopTester(RawMachineAssemblerTester<int32_t>* tester) 428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : BinopTester<Type*, USE_RETURN_REGISTER>(tester, 429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Pointer()) {} 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A helper class for testing code sequences that take two tagged parameters and 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// return a tagged value. 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename Type> 436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass TaggedBinopTester : public BinopTester<Type*, USE_RETURN_REGISTER> { 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit TaggedBinopTester(RawMachineAssemblerTester<int32_t>* tester) 439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : BinopTester<Type*, USE_RETURN_REGISTER>(tester, 440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::AnyTagged()) {} 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A helper class for testing compares. Wraps a machine opcode and provides 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// evaluation routines and the operators. 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CompareWrapper { 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit CompareWrapper(IrOpcode::Value op) : opcode(op) {} 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* MakeNode(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) { 450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return m->AddNode(op(m->machine()), a, b); 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operator* op(MachineOperatorBuilder* machine) { 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (opcode) { 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kWord32Equal: 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return machine->Word32Equal(); 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kInt32LessThan: 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return machine->Int32LessThan(); 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kInt32LessThanOrEqual: 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return machine->Int32LessThanOrEqual(); 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kUint32LessThan: 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return machine->Uint32LessThan(); 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kUint32LessThanOrEqual: 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return machine->Uint32LessThanOrEqual(); 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kFloat64Equal: 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return machine->Float64Equal(); 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kFloat64LessThan: 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return machine->Float64LessThan(); 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kFloat64LessThanOrEqual: 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return machine->Float64LessThanOrEqual(); 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool Int32Compare(int32_t a, int32_t b) { 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (opcode) { 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kWord32Equal: 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return a == b; 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kInt32LessThan: 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return a < b; 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kInt32LessThanOrEqual: 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return a <= b; 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kUint32LessThan: 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return static_cast<uint32_t>(a) < static_cast<uint32_t>(b); 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kUint32LessThanOrEqual: 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return static_cast<uint32_t>(a) <= static_cast<uint32_t>(b); 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool Float64Compare(double a, double b) { 496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (opcode) { 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kFloat64Equal: 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return a == b; 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kFloat64LessThan: 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return a < b; 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kFloat64LessThanOrEqual: 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return a <= b; 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IrOpcode::Value opcode; 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A small closure class to generate code for a function of two inputs that 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// produces a single output so that it can be used in many different contexts. 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The {expected()} method should compute the expected output for a given 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// pair of inputs. 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename T> 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass BinopGen { 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual void gen(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) = 0; 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual T expected(T a, T b) = 0; 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~BinopGen() {} 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A helper class to generate various combination of input shape combinations 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and run the generated code to ensure it produces the correct results. 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Int32BinopInputShapeTester { 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 529342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch explicit Int32BinopInputShapeTester(BinopGen<int32_t>* g) 530342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch : gen(g), input_a(0), input_b(0) {} 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TestAllInputShapes(); 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BinopGen<int32_t>* gen; 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t input_a; 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t input_b; 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Run(RawMachineAssemblerTester<int32_t>* m); 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RunLeft(RawMachineAssemblerTester<int32_t>* m); 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RunRight(RawMachineAssemblerTester<int32_t>* m); 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace compiler 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace internal 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_CCTEST_COMPILER_CODEGEN_TESTER_H_ 548