17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved. 27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file. 47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifndef V8_CCTEST_COMPILER_CODEGEN_TESTER_H_ 67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define V8_CCTEST_COMPILER_CODEGEN_TESTER_H_ 77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 87d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/v8.h" 97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/pipeline.h" 117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/raw-machine-assembler.h" 127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/simulator.h" 137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "test/cctest/compiler/call-tester.h" 147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace v8 { 167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace internal { 177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace compiler { 187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtemplate <typename MachineAssembler> 207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass MachineAssemblerTester : public HandleAndZoneScope, 217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public CallHelper, 227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public MachineAssembler { 237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 2431c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org MachineAssemblerTester(MachineType return_type, MachineType p0, 2531c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org MachineType p1, MachineType p2, MachineType p3, 2631c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org MachineType p4) 277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : HandleAndZoneScope(), 289aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org CallHelper( 299aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org main_isolate(), 309aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org MakeMachineSignature(main_zone(), return_type, p0, p1, p2, p3, p4)), 319aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org MachineAssembler( 329aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org new (main_zone()) Graph(main_zone()), 339aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org MakeMachineSignature(main_zone(), return_type, p0, p1, p2, p3, p4), 349aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org kMachPtr) {} 357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3631c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org Node* LoadFromPointer(void* address, MachineType rep, int32_t offset = 0) { 377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return this->Load(rep, this->PointerConstant(address), 387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org this->Int32Constant(offset)); 397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4131c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org void StoreToPointer(void* address, MachineType rep, Node* node) { 427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org this->Store(rep, this->PointerConstant(address), node); 437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* StringConstant(const char* string) { 467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return this->HeapConstant( 477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org this->isolate()->factory()->InternalizeUtf8String(string)); 487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void CheckNumber(double expected, Object* number) { 517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK(this->isolate()->factory()->NewNumber(expected)->SameValue(number)); 527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void CheckString(const char* expected, Object* string) { 557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK( 567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org this->isolate()->factory()->InternalizeUtf8String(expected)->SameValue( 577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org string)); 587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void GenerateCode() { Generate(); } 617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org protected: 637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org virtual byte* Generate() { 647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (code_.is_null()) { 657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Schedule* schedule = this->Export(); 667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CallDescriptor* call_descriptor = this->call_descriptor(); 677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Graph* graph = this->graph(); 687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CompilationInfo info(graph->zone()->isolate(), graph->zone()); 697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Linkage linkage(&info, call_descriptor); 707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Pipeline pipeline(&info); 717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org code_ = pipeline.GenerateCodeForMachineGraph(&linkage, graph, schedule); 727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return this->code_.ToHandleChecked()->entry(); 747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private: 777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org MaybeHandle<Code> code_; 787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtemplate <typename ReturnType> 827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass RawMachineAssemblerTester 837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : public MachineAssemblerTester<RawMachineAssembler>, 847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public CallHelper2<ReturnType, RawMachineAssemblerTester<ReturnType> > { 857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 865e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org RawMachineAssemblerTester(MachineType p0 = kMachNone, 875e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org MachineType p1 = kMachNone, 885e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org MachineType p2 = kMachNone, 895e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org MachineType p3 = kMachNone, 905e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org MachineType p4 = kMachNone) 917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : MachineAssemblerTester<RawMachineAssembler>( 927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ReturnValueTraits<ReturnType>::Representation(), p0, p1, p2, p3, 937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org p4) {} 947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org template <typename Ci, typename Fn> 967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void Run(const Ci& ci, const Fn& fn) { 977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typename Ci::const_iterator i; 987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org for (i = ci.begin(); i != ci.end(); ++i) { 997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK_EQ(fn(*i), this->Call(*i)); 1007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org template <typename Ci, typename Cj, typename Fn> 1047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void Run(const Ci& ci, const Cj& cj, const Fn& fn) { 1057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typename Ci::const_iterator i; 1067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typename Cj::const_iterator j; 1077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org for (i = ci.begin(); i != ci.end(); ++i) { 1087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org for (j = cj.begin(); j != cj.end(); ++j) { 1097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK_EQ(fn(*i, *j), this->Call(*i, *j)); 1107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 1147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic const bool USE_RESULT_BUFFER = true; 1177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic const bool USE_RETURN_REGISTER = false; 1187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic const int32_t CHECK_VALUE = 0x99BEEDCE; 1197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// TODO(titzer): use the C-style calling convention, or any register-based 1227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// calling convention for binop tests. 12331c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.orgtemplate <typename CType, MachineType rep, bool use_result_buffer> 1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass BinopTester { 1257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 1267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit BinopTester(RawMachineAssemblerTester<int32_t>* tester) 1277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : T(tester), 1287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org param0(T->LoadFromPointer(&p0, rep)), 1297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org param1(T->LoadFromPointer(&p1, rep)), 1307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org p0(static_cast<CType>(0)), 1317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org p1(static_cast<CType>(0)), 1327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org result(static_cast<CType>(0)) {} 1337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org RawMachineAssemblerTester<int32_t>* T; 1357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* param0; 1367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* param1; 1377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CType call(CType a0, CType a1) { 1397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org p0 = a0; 1407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org p1 = a1; 1417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (use_result_buffer) { 1427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK_EQ(CHECK_VALUE, T->Call()); 1437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return result; 1447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 1457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return T->Call(); 1467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void AddReturn(Node* val) { 1507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (use_result_buffer) { 1517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org T->Store(rep, T->PointerConstant(&result), T->Int32Constant(0), val); 1527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org T->Return(T->Int32Constant(CHECK_VALUE)); 1537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 1547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org T->Return(val); 1557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org template <typename Ci, typename Cj, typename Fn> 1597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void Run(const Ci& ci, const Cj& cj, const Fn& fn) { 1607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typename Ci::const_iterator i; 1617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typename Cj::const_iterator j; 1627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org for (i = ci.begin(); i != ci.end(); ++i) { 1637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org for (j = cj.begin(); j != cj.end(); ++j) { 1647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CHECK_EQ(fn(*i, *j), this->call(*i, *j)); 1657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org protected: 1707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CType p0; 1717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CType p1; 1727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CType result; 1737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 1747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// A helper class for testing code sequences that take two int parameters and 1777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// return an int value. 1787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass Int32BinopTester 1795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org : public BinopTester<int32_t, kMachInt32, USE_RETURN_REGISTER> { 1807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 1817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit Int32BinopTester(RawMachineAssemblerTester<int32_t>* tester) 1825e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org : BinopTester<int32_t, kMachInt32, USE_RETURN_REGISTER>(tester) {} 1835e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}; 1845e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 1855e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 1865e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org// A helper class for testing code sequences that take two uint parameters and 1875e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org// return an uint value. 1885e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgclass Uint32BinopTester 1895e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org : public BinopTester<uint32_t, kMachUint32, USE_RETURN_REGISTER> { 1905e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org public: 1915e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org explicit Uint32BinopTester(RawMachineAssemblerTester<int32_t>* tester) 1925e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org : BinopTester<uint32_t, kMachUint32, USE_RETURN_REGISTER>(tester) {} 1937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1945e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org uint32_t call(uint32_t a0, uint32_t a1) { 1955e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org p0 = a0; 1965e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org p1 = a1; 1975e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org return static_cast<uint32_t>(T->Call()); 1987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 2007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// A helper class for testing code sequences that take two double parameters and 2037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// return a double value. 2047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// TODO(titzer): figure out how to return doubles correctly on ia32. 2057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass Float64BinopTester 2065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org : public BinopTester<double, kMachFloat64, USE_RESULT_BUFFER> { 2077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 2087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit Float64BinopTester(RawMachineAssemblerTester<int32_t>* tester) 2095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org : BinopTester<double, kMachFloat64, USE_RESULT_BUFFER>(tester) {} 2107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 2117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// A helper class for testing code sequences that take two pointer parameters 2147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// and return a pointer value. 2157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// TODO(titzer): pick word size of pointers based on V8_TARGET. 2167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtemplate <typename Type> 2177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass PointerBinopTester 2185e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org : public BinopTester<Type*, kMachPtr, USE_RETURN_REGISTER> { 2197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 2207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit PointerBinopTester(RawMachineAssemblerTester<int32_t>* tester) 2215e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org : BinopTester<Type*, kMachPtr, USE_RETURN_REGISTER>(tester) {} 2227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 2237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// A helper class for testing code sequences that take two tagged parameters and 2267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// return a tagged value. 2277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtemplate <typename Type> 2287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass TaggedBinopTester 2295e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org : public BinopTester<Type*, kMachAnyTagged, USE_RETURN_REGISTER> { 2307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 2317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit TaggedBinopTester(RawMachineAssemblerTester<int32_t>* tester) 2325e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org : BinopTester<Type*, kMachAnyTagged, USE_RETURN_REGISTER>(tester) {} 2337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 2347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// A helper class for testing compares. Wraps a machine opcode and provides 2367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// evaluation routines and the operators. 2377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass CompareWrapper { 2387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 2397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit CompareWrapper(IrOpcode::Value op) : opcode(op) {} 2407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Node* MakeNode(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) { 2427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return m->NewNode(op(m->machine()), a, b); 2437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2452c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org const Operator* op(MachineOperatorBuilder* machine) { 2467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org switch (opcode) { 2477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kWord32Equal: 2487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return machine->Word32Equal(); 2497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kInt32LessThan: 2507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return machine->Int32LessThan(); 2517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kInt32LessThanOrEqual: 2527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return machine->Int32LessThanOrEqual(); 2537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kUint32LessThan: 2547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return machine->Uint32LessThan(); 2557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kUint32LessThanOrEqual: 2567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return machine->Uint32LessThanOrEqual(); 2577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kFloat64Equal: 2587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return machine->Float64Equal(); 2597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kFloat64LessThan: 2607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return machine->Float64LessThan(); 2617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kFloat64LessThanOrEqual: 2627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return machine->Float64LessThanOrEqual(); 2637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org default: 2647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UNREACHABLE(); 2657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return NULL; 2677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool Int32Compare(int32_t a, int32_t b) { 2707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org switch (opcode) { 2717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kWord32Equal: 2727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return a == b; 2737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kInt32LessThan: 2747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return a < b; 2757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kInt32LessThanOrEqual: 2767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return a <= b; 2777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kUint32LessThan: 2787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return static_cast<uint32_t>(a) < static_cast<uint32_t>(b); 2797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kUint32LessThanOrEqual: 2807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return static_cast<uint32_t>(a) <= static_cast<uint32_t>(b); 2817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org default: 2827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UNREACHABLE(); 2837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return false; 2857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool Float64Compare(double a, double b) { 2887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org switch (opcode) { 2897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kFloat64Equal: 2907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return a == b; 2917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kFloat64LessThan: 2927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return a < b; 2937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case IrOpcode::kFloat64LessThanOrEqual: 2947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return a <= b; 2957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org default: 2967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UNREACHABLE(); 2977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return false; 2997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org IrOpcode::Value opcode; 3027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 3037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// A small closure class to generate code for a function of two inputs that 3067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// produces a single output so that it can be used in many different contexts. 3077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// The {expected()} method should compute the expected output for a given 3087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// pair of inputs. 3097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtemplate <typename T> 3107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass BinopGen { 3117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 3127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org virtual void gen(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) = 0; 3137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org virtual T expected(T a, T b) = 0; 3147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org virtual ~BinopGen() {} 3157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 3167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// A helper class to generate various combination of input shape combinations 3187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// and run the generated code to ensure it produces the correct results. 3197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass Int32BinopInputShapeTester { 3207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 3217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit Int32BinopInputShapeTester(BinopGen<int32_t>* g) : gen(g) {} 3227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void TestAllInputShapes(); 3247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private: 3267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BinopGen<int32_t>* gen; 3277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int32_t input_a; 3287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int32_t input_b; 3297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void Run(RawMachineAssemblerTester<int32_t>* m); 3317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void RunLeft(RawMachineAssemblerTester<int32_t>* m); 3327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void RunRight(RawMachineAssemblerTester<int32_t>* m); 3337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 3347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} // namespace compiler 3357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} // namespace internal 3367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} // namespace v8 3377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif // V8_CCTEST_COMPILER_CODEGEN_TESTER_H_ 339