LCOV - code coverage report
Current view: top level - test/cctest/compiler - codegen-tester.h (source / functions) Hit Total Coverage
Test: app.info Lines: 146 149 98.0 %
Date: 2017-10-20 Functions: 141 187 75.4 %

          Line data    Source code
       1             : // Copyright 2014 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_CCTEST_COMPILER_CODEGEN_TESTER_H_
       6             : #define V8_CCTEST_COMPILER_CODEGEN_TESTER_H_
       7             : 
       8             : #include "src/compilation-info.h"
       9             : #include "src/compiler/instruction-selector.h"
      10             : #include "src/compiler/pipeline.h"
      11             : #include "src/compiler/raw-machine-assembler.h"
      12             : #include "src/simulator.h"
      13             : #include "test/cctest/cctest.h"
      14             : #include "test/cctest/compiler/call-tester.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : namespace compiler {
      19             : 
      20             : template <typename ReturnType>
      21             : class RawMachineAssemblerTester : public HandleAndZoneScope,
      22             :                                   public CallHelper<ReturnType>,
      23             :                                   public RawMachineAssembler {
      24             :  public:
      25      190099 :   RawMachineAssemblerTester(MachineType p0 = MachineType::None(),
      26             :                             MachineType p1 = MachineType::None(),
      27             :                             MachineType p2 = MachineType::None(),
      28             :                             MachineType p3 = MachineType::None(),
      29             :                             MachineType p4 = MachineType::None())
      30             :       : HandleAndZoneScope(),
      31             :         CallHelper<ReturnType>(
      32             :             main_isolate(),
      33             :             CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1,
      34      190099 :                             p2, p3, p4)),
      35             :         RawMachineAssembler(
      36             :             main_isolate(), new (main_zone()) Graph(main_zone()),
      37             :             Linkage::GetSimplifiedCDescriptor(
      38             :                 main_zone(),
      39             :                 CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0,
      40      190099 :                                 p1, p2, p3, p4),
      41             :                 true),
      42             :             MachineType::PointerRepresentation(),
      43             :             InstructionSelector::SupportedMachineOperatorFlags(),
      44     1140594 :             InstructionSelector::AlignmentRequirements()) {}
      45             : 
      46      378999 :   virtual ~RawMachineAssemblerTester() {}
      47             : 
      48         250 :   void CheckNumber(double expected, Object* number) {
      49         500 :     CHECK(this->isolate()->factory()->NewNumber(expected)->SameValue(number));
      50         250 :   }
      51             : 
      52          22 :   void CheckString(const char* expected, Object* string) {
      53          44 :     CHECK(
      54             :         this->isolate()->factory()->InternalizeUtf8String(expected)->SameValue(
      55             :             string));
      56          22 :   }
      57             : 
      58       12183 :   void GenerateCode() { Generate(); }
      59             : 
      60          11 :   Handle<Code> GetCode() {
      61          11 :     Generate();
      62          11 :     return code_.ToHandleChecked();
      63             :   }
      64             : 
      65             :  protected:
      66    44668040 :   virtual byte* Generate() {
      67    44668040 :     if (code_.is_null()) {
      68      188750 :       Schedule* schedule = this->Export();
      69             :       CallDescriptor* call_descriptor = this->call_descriptor();
      70             :       Graph* graph = this->graph();
      71             :       CompilationInfo info(ArrayVector("testing"), main_isolate(), main_zone(),
      72      188750 :                            Code::STUB);
      73      188750 :       code_ = Pipeline::GenerateCodeForTesting(&info, call_descriptor, graph,
      74      188750 :                                                schedule);
      75             :     }
      76    44668040 :     return this->code_.ToHandleChecked()->entry();
      77             :   }
      78             : 
      79             :  private:
      80             :   MaybeHandle<Code> code_;
      81             : };
      82             : 
      83             : 
      84             : template <typename ReturnType>
      85        6300 : class BufferedRawMachineAssemblerTester
      86             :     : public RawMachineAssemblerTester<int32_t> {
      87             :  public:
      88        6300 :   BufferedRawMachineAssemblerTester(MachineType p0 = MachineType::None(),
      89             :                                     MachineType p1 = MachineType::None(),
      90             :                                     MachineType p2 = MachineType::None(),
      91             :                                     MachineType p3 = MachineType::None())
      92             :       : BufferedRawMachineAssemblerTester(ComputeParameterCount(p0, p1, p2, p3),
      93        6300 :                                           p0, p1, p2, p3) {}
      94             : 
      95     3277404 :   virtual byte* Generate() { return RawMachineAssemblerTester::Generate(); }
      96             : 
      97             :   // The BufferedRawMachineAssemblerTester does not pass parameters directly
      98             :   // to the constructed IR graph. Instead it passes a pointer to the parameter
      99             :   // to the IR graph, and adds Load nodes to the IR graph to load the
     100             :   // parameters from memory. Thereby it is possible to pass 64 bit parameters
     101             :   // to the IR graph.
     102        2734 :   Node* Parameter(size_t index) {
     103        2734 :     CHECK_GT(4, index);
     104        2734 :     return parameter_nodes_[index];
     105             :   }
     106             : 
     107             :   // The BufferedRawMachineAssemblerTester adds a Store node to the IR graph
     108             :   // to store the graph's return value in memory. The memory address for the
     109             :   // Store node is provided as a parameter. By storing the return value in
     110             :   // memory it is possible to return 64 bit values.
     111        6280 :   void Return(Node* input) {
     112        6280 :     Store(MachineTypeForC<ReturnType>().representation(),
     113             :           RawMachineAssembler::Parameter(return_parameter_index_), input,
     114             :           kNoWriteBarrier);
     115        6280 :     RawMachineAssembler::Return(Int32Constant(1234));
     116        6280 :   }
     117             : 
     118        3692 :   ReturnType Call() {
     119             :     ReturnType return_value;
     120        3692 :     CSignature::VerifyParams(test_graph_signature_);
     121        3692 :     CallHelper<int32_t>::Call(reinterpret_cast<void*>(&return_value));
     122        3692 :     return return_value;
     123             :   }
     124             : 
     125             :   template <typename P0>
     126      201488 :   ReturnType Call(P0 p0) {
     127             :     ReturnType return_value;
     128      201488 :     CSignature::VerifyParams<P0>(test_graph_signature_);
     129      201488 :     CallHelper<int32_t>::Call(reinterpret_cast<void*>(&p0),
     130      201488 :                               reinterpret_cast<void*>(&return_value));
     131      201488 :     return return_value;
     132             :   }
     133             : 
     134             :   template <typename P0, typename P1>
     135      443682 :   ReturnType Call(P0 p0, P1 p1) {
     136             :     ReturnType return_value;
     137      443682 :     CSignature::VerifyParams<P0, P1>(test_graph_signature_);
     138      443682 :     CallHelper<int32_t>::Call(reinterpret_cast<void*>(&p0),
     139             :                               reinterpret_cast<void*>(&p1),
     140      443682 :                               reinterpret_cast<void*>(&return_value));
     141      443682 :     return return_value;
     142             :   }
     143             : 
     144             :   template <typename P0, typename P1, typename P2>
     145     2471078 :   ReturnType Call(P0 p0, P1 p1, P2 p2) {
     146             :     ReturnType return_value;
     147     2471078 :     CSignature::VerifyParams<P0, P1, P2>(test_graph_signature_);
     148     2471078 :     CallHelper<int32_t>::Call(
     149             :         reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
     150     2471078 :         reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&return_value));
     151     2471078 :     return return_value;
     152             :   }
     153             : 
     154             :   template <typename P0, typename P1, typename P2, typename P3>
     155      157464 :   ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) {
     156             :     ReturnType return_value;
     157      157464 :     CSignature::VerifyParams<P0, P1, P2, P3>(test_graph_signature_);
     158      157464 :     CallHelper<int32_t>::Call(
     159             :         reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
     160             :         reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&p3),
     161      157464 :         reinterpret_cast<void*>(&return_value));
     162      157464 :     return return_value;
     163             :   }
     164             : 
     165             :  private:
     166        6300 :   BufferedRawMachineAssemblerTester(uint32_t return_parameter_index,
     167             :                                     MachineType p0, MachineType p1,
     168             :                                     MachineType p2, MachineType p3)
     169             :       : RawMachineAssemblerTester<int32_t>(
     170             :             MachineType::Pointer(),
     171             :             p0 == MachineType::None() ? MachineType::None()
     172             :                                       : MachineType::Pointer(),
     173             :             p1 == MachineType::None() ? MachineType::None()
     174             :                                       : MachineType::Pointer(),
     175             :             p2 == MachineType::None() ? MachineType::None()
     176             :                                       : MachineType::Pointer(),
     177             :             p3 == MachineType::None() ? MachineType::None()
     178             :                                       : MachineType::Pointer()),
     179             :         test_graph_signature_(
     180        6300 :             CSignature::New(main_zone(), MachineType::Int32(), p0, p1, p2, p3)),
     181       31500 :         return_parameter_index_(return_parameter_index) {
     182        8908 :     parameter_nodes_[0] = p0 == MachineType::None()
     183        2608 :                               ? nullptr
     184             :                               : Load(p0, RawMachineAssembler::Parameter(0));
     185        6398 :     parameter_nodes_[1] = p1 == MachineType::None()
     186          98 :                               ? nullptr
     187             :                               : Load(p1, RawMachineAssembler::Parameter(1));
     188        6332 :     parameter_nodes_[2] = p2 == MachineType::None()
     189          32 :                               ? nullptr
     190             :                               : Load(p2, RawMachineAssembler::Parameter(2));
     191        6306 :     parameter_nodes_[3] = p3 == MachineType::None()
     192           6 :                               ? nullptr
     193             :                               : Load(p3, RawMachineAssembler::Parameter(3));
     194        6300 :   }
     195             : 
     196             : 
     197        6300 :   static uint32_t ComputeParameterCount(MachineType p0, MachineType p1,
     198             :                                         MachineType p2, MachineType p3) {
     199        6300 :     if (p0 == MachineType::None()) {
     200             :       return 0;
     201             :     }
     202        2608 :     if (p1 == MachineType::None()) {
     203             :       return 1;
     204             :     }
     205          98 :     if (p2 == MachineType::None()) {
     206             :       return 2;
     207             :     }
     208          32 :     if (p3 == MachineType::None()) {
     209             :       return 3;
     210             :     }
     211           6 :     return 4;
     212             :   }
     213             : 
     214             : 
     215             :   CSignature* test_graph_signature_;
     216             :   Node* parameter_nodes_[4];
     217             :   uint32_t return_parameter_index_;
     218             : };
     219             : 
     220             : 
     221             : template <>
     222          30 : class BufferedRawMachineAssemblerTester<void>
     223             :     : public RawMachineAssemblerTester<void> {
     224             :  public:
     225          30 :   BufferedRawMachineAssemblerTester(MachineType p0 = MachineType::None(),
     226             :                                     MachineType p1 = MachineType::None(),
     227             :                                     MachineType p2 = MachineType::None(),
     228             :                                     MachineType p3 = MachineType::None())
     229             :       : RawMachineAssemblerTester<void>(
     230             :             p0 == MachineType::None() ? MachineType::None()
     231             :                                       : MachineType::Pointer(),
     232             :             p1 == MachineType::None() ? MachineType::None()
     233             :                                       : MachineType::Pointer(),
     234             :             p2 == MachineType::None() ? MachineType::None()
     235             :                                       : MachineType::Pointer(),
     236             :             p3 == MachineType::None() ? MachineType::None()
     237             :                                       : MachineType::Pointer()),
     238             :         test_graph_signature_(
     239             :             CSignature::New(RawMachineAssemblerTester<void>::main_zone(),
     240         150 :                             MachineType::None(), p0, p1, p2, p3)) {
     241             :     parameter_nodes_[0] = p0 == MachineType::None()
     242             :                               ? nullptr
     243          30 :                               : Load(p0, RawMachineAssembler::Parameter(0));
     244             :     parameter_nodes_[1] = p1 == MachineType::None()
     245             :                               ? nullptr
     246          30 :                               : Load(p1, RawMachineAssembler::Parameter(1));
     247             :     parameter_nodes_[2] = p2 == MachineType::None()
     248             :                               ? nullptr
     249          30 :                               : Load(p2, RawMachineAssembler::Parameter(2));
     250             :     parameter_nodes_[3] = p3 == MachineType::None()
     251             :                               ? nullptr
     252          30 :                               : Load(p3, RawMachineAssembler::Parameter(3));
     253          30 :   }
     254             : 
     255      354594 :   virtual byte* Generate() { return RawMachineAssemblerTester::Generate(); }
     256             : 
     257             :   // The BufferedRawMachineAssemblerTester does not pass parameters directly
     258             :   // to the constructed IR graph. Instead it passes a pointer to the parameter
     259             :   // to the IR graph, and adds Load nodes to the IR graph to load the
     260             :   // parameters from memory. Thereby it is possible to pass 64 bit parameters
     261             :   // to the IR graph.
     262          60 :   Node* Parameter(size_t index) {
     263          60 :     CHECK_GT(4, index);
     264          60 :     return parameter_nodes_[index];
     265             :   }
     266             : 
     267             : 
     268             :   void Call() {
     269           6 :     CSignature::VerifyParams(test_graph_signature_);
     270           6 :     CallHelper<void>::Call();
     271             :   }
     272             : 
     273             :   template <typename P0>
     274             :   void Call(P0 p0) {
     275         294 :     CSignature::VerifyParams<P0>(test_graph_signature_);
     276         294 :     CallHelper<void>::Call(reinterpret_cast<void*>(&p0));
     277             :   }
     278             : 
     279             :   template <typename P0, typename P1>
     280             :   void Call(P0 p0, P1 p1) {
     281       78732 :     CSignature::VerifyParams<P0, P1>(test_graph_signature_);
     282       78732 :     CallHelper<void>::Call(reinterpret_cast<void*>(&p0),
     283             :                            reinterpret_cast<void*>(&p1));
     284             :   }
     285             : 
     286             :   template <typename P0, typename P1, typename P2>
     287             :   void Call(P0 p0, P1 p1, P2 p2) {
     288      118098 :     CSignature::VerifyParams<P0, P1, P2>(test_graph_signature_);
     289      118098 :     CallHelper<void>::Call(reinterpret_cast<void*>(&p0),
     290             :                            reinterpret_cast<void*>(&p1),
     291             :                            reinterpret_cast<void*>(&p2));
     292             :   }
     293             : 
     294             :   template <typename P0, typename P1, typename P2, typename P3>
     295             :   void Call(P0 p0, P1 p1, P2 p2, P3 p3) {
     296      157464 :     CSignature::VerifyParams<P0, P1, P2, P3>(test_graph_signature_);
     297      157464 :     CallHelper<void>::Call(
     298             :         reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
     299             :         reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&p3));
     300             :   }
     301             : 
     302             :  private:
     303             :   CSignature* test_graph_signature_;
     304             :   Node* parameter_nodes_[4];
     305             : };
     306             : static const bool USE_RESULT_BUFFER = true;
     307             : static const bool USE_RETURN_REGISTER = false;
     308             : static const int32_t CHECK_VALUE = 0x99BEEDCE;
     309             : 
     310             : 
     311             : // TODO(titzer): use the C-style calling convention, or any register-based
     312             : // calling convention for binop tests.
     313             : template <typename CType, bool use_result_buffer>
     314             : class BinopTester {
     315             :  public:
     316        1044 :   explicit BinopTester(RawMachineAssemblerTester<int32_t>* tester,
     317             :                        MachineType rep)
     318             :       : T(tester),
     319             :         param0(T->LoadFromPointer(&p0, rep)),
     320             :         param1(T->LoadFromPointer(&p1, rep)),
     321             :         rep(rep),
     322             :         p0(static_cast<CType>(0)),
     323             :         p1(static_cast<CType>(0)),
     324        1044 :         result(static_cast<CType>(0)) {}
     325             : 
     326             :   RawMachineAssemblerTester<int32_t>* T;
     327             :   Node* param0;
     328             :   Node* param1;
     329             : 
     330      505383 :   CType call(CType a0, CType a1) {
     331     3169634 :     p0 = a0;
     332     3169634 :     p1 = a1;
     333             :     if (use_result_buffer) {
     334      505383 :       CHECK_EQ(CHECK_VALUE, T->Call());
     335      505383 :       return result;
     336             :     } else {
     337     2664251 :       return static_cast<CType>(T->Call());
     338             :     }
     339             :   }
     340             : 
     341          87 :   void AddReturn(Node* val) {
     342             :     if (use_result_buffer) {
     343         174 :       T->Store(rep.representation(), T->PointerConstant(&result),
     344             :                T->Int32Constant(0), val, kNoWriteBarrier);
     345          87 :       T->Return(T->Int32Constant(CHECK_VALUE));
     346             :     } else {
     347        1027 :       T->Return(val);
     348             :     }
     349          87 :   }
     350             : 
     351             :   template <typename Ci, typename Cj, typename Fn>
     352             :   void Run(const Ci& ci, const Cj& cj, const Fn& fn) {
     353             :     typename Ci::const_iterator i;
     354             :     typename Cj::const_iterator j;
     355             :     for (i = ci.begin(); i != ci.end(); ++i) {
     356             :       for (j = cj.begin(); j != cj.end(); ++j) {
     357             :         CHECK_EQ(fn(*i, *j), this->call(*i, *j));
     358             :       }
     359             :     }
     360             :   }
     361             : 
     362             :  protected:
     363             :   MachineType rep;
     364             :   CType p0;
     365             :   CType p1;
     366             :   CType result;
     367             : };
     368             : 
     369             : 
     370             : // A helper class for testing code sequences that take two int parameters and
     371             : // return an int value.
     372             : class Int32BinopTester : public BinopTester<int32_t, USE_RETURN_REGISTER> {
     373             :  public:
     374             :   explicit Int32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
     375             :       : BinopTester<int32_t, USE_RETURN_REGISTER>(tester,
     376         792 :                                                   MachineType::Int32()) {}
     377             : };
     378             : 
     379             : 
     380             : // A helper class for testing code sequences that take two int parameters and
     381             : // return an int value.
     382             : class Int64BinopTester : public BinopTester<int64_t, USE_RETURN_REGISTER> {
     383             :  public:
     384             :   explicit Int64BinopTester(RawMachineAssemblerTester<int32_t>* tester)
     385             :       : BinopTester<int64_t, USE_RETURN_REGISTER>(tester,
     386          20 :                                                   MachineType::Int64()) {}
     387             : };
     388             : 
     389             : 
     390             : // A helper class for testing code sequences that take two uint parameters and
     391             : // return an uint value.
     392             : class Uint32BinopTester : public BinopTester<uint32_t, USE_RETURN_REGISTER> {
     393             :  public:
     394             :   explicit Uint32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
     395             :       : BinopTester<uint32_t, USE_RETURN_REGISTER>(tester,
     396         145 :                                                    MachineType::Uint32()) {}
     397             : 
     398             :   uint32_t call(uint32_t a0, uint32_t a1) {
     399      419345 :     p0 = a0;
     400      419345 :     p1 = a1;
     401      419345 :     return static_cast<uint32_t>(T->Call());
     402             :   }
     403             : };
     404             : 
     405             : 
     406             : // A helper class for testing code sequences that take two float parameters and
     407             : // return a float value.
     408             : class Float32BinopTester : public BinopTester<float, USE_RESULT_BUFFER> {
     409             :  public:
     410             :   explicit Float32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
     411          30 :       : BinopTester<float, USE_RESULT_BUFFER>(tester, MachineType::Float32()) {}
     412             : };
     413             : 
     414             : 
     415             : // A helper class for testing code sequences that take two double parameters and
     416             : // return a double value.
     417             : class Float64BinopTester : public BinopTester<double, USE_RESULT_BUFFER> {
     418             :  public:
     419             :   explicit Float64BinopTester(RawMachineAssemblerTester<int32_t>* tester)
     420          57 :       : BinopTester<double, USE_RESULT_BUFFER>(tester, MachineType::Float64()) {
     421             :   }
     422             : };
     423             : 
     424             : 
     425             : // A helper class for testing code sequences that take two pointer parameters
     426             : // and return a pointer value.
     427             : // TODO(titzer): pick word size of pointers based on V8_TARGET.
     428             : template <typename Type>
     429             : class PointerBinopTester : public BinopTester<Type*, USE_RETURN_REGISTER> {
     430             :  public:
     431             :   explicit PointerBinopTester(RawMachineAssemblerTester<int32_t>* tester)
     432             :       : BinopTester<Type*, USE_RETURN_REGISTER>(tester,
     433             :                                                 MachineType::Pointer()) {}
     434             : };
     435             : 
     436             : 
     437             : // A helper class for testing code sequences that take two tagged parameters and
     438             : // return a tagged value.
     439             : template <typename Type>
     440             : class TaggedBinopTester : public BinopTester<Type*, USE_RETURN_REGISTER> {
     441             :  public:
     442             :   explicit TaggedBinopTester(RawMachineAssemblerTester<int32_t>* tester)
     443             :       : BinopTester<Type*, USE_RETURN_REGISTER>(tester,
     444             :                                                 MachineType::AnyTagged()) {}
     445             : };
     446             : 
     447             : // A helper class for testing compares. Wraps a machine opcode and provides
     448             : // evaluation routines and the operators.
     449             : class CompareWrapper {
     450             :  public:
     451         208 :   explicit CompareWrapper(IrOpcode::Value op) : opcode(op) {}
     452             : 
     453       12276 :   Node* MakeNode(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) {
     454       24552 :     return m->AddNode(op(m->machine()), a, b);
     455             :   }
     456             : 
     457       12276 :   const Operator* op(MachineOperatorBuilder* machine) {
     458       12276 :     switch (opcode) {
     459             :       case IrOpcode::kWord32Equal:
     460        2448 :         return machine->Word32Equal();
     461             :       case IrOpcode::kInt32LessThan:
     462        2448 :         return machine->Int32LessThan();
     463             :       case IrOpcode::kInt32LessThanOrEqual:
     464        2448 :         return machine->Int32LessThanOrEqual();
     465             :       case IrOpcode::kUint32LessThan:
     466        2448 :         return machine->Uint32LessThan();
     467             :       case IrOpcode::kUint32LessThanOrEqual:
     468        2448 :         return machine->Uint32LessThanOrEqual();
     469             :       case IrOpcode::kFloat64Equal:
     470          12 :         return machine->Float64Equal();
     471             :       case IrOpcode::kFloat64LessThan:
     472          12 :         return machine->Float64LessThan();
     473             :       case IrOpcode::kFloat64LessThanOrEqual:
     474          12 :         return machine->Float64LessThanOrEqual();
     475             :       default:
     476           0 :         UNREACHABLE();
     477             :     }
     478             :     return nullptr;
     479             :   }
     480             : 
     481     3211746 :   bool Int32Compare(int32_t a, int32_t b) {
     482     3211746 :     switch (opcode) {
     483             :       case IrOpcode::kWord32Equal:
     484      658464 :         return a == b;
     485             :       case IrOpcode::kInt32LessThan:
     486      638304 :         return a < b;
     487             :       case IrOpcode::kInt32LessThanOrEqual:
     488      638304 :         return a <= b;
     489             :       case IrOpcode::kUint32LessThan:
     490      638340 :         return static_cast<uint32_t>(a) < static_cast<uint32_t>(b);
     491             :       case IrOpcode::kUint32LessThanOrEqual:
     492      638334 :         return static_cast<uint32_t>(a) <= static_cast<uint32_t>(b);
     493             :       default:
     494           0 :         UNREACHABLE();
     495             :     }
     496             :     return false;
     497             :   }
     498             : 
     499       25876 :   bool Float64Compare(double a, double b) {
     500       25876 :     switch (opcode) {
     501             :       case IrOpcode::kFloat64Equal:
     502       12611 :         return a == b;
     503             :       case IrOpcode::kFloat64LessThan:
     504       12635 :         return a < b;
     505             :       case IrOpcode::kFloat64LessThanOrEqual:
     506         630 :         return a <= b;
     507             :       default:
     508           0 :         UNREACHABLE();
     509             :     }
     510             :     return false;
     511             :   }
     512             : 
     513             :   IrOpcode::Value opcode;
     514             : };
     515             : 
     516             : 
     517             : // A small closure class to generate code for a function of two inputs that
     518             : // produces a single output so that it can be used in many different contexts.
     519             : // The {expected()} method should compute the expected output for a given
     520             : // pair of inputs.
     521             : template <typename T>
     522         180 : class BinopGen {
     523             :  public:
     524             :   virtual void gen(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) = 0;
     525             :   virtual T expected(T a, T b) = 0;
     526         180 :   virtual ~BinopGen() {}
     527             : };
     528             : 
     529             : // A helper class to generate various combination of input shape combinations
     530             : // and run the generated code to ensure it produces the correct results.
     531             : class Int32BinopInputShapeTester {
     532             :  public:
     533             :   explicit Int32BinopInputShapeTester(BinopGen<int32_t>* g)
     534         180 :       : gen(g), input_a(0), input_b(0) {}
     535             : 
     536             :   void TestAllInputShapes();
     537             : 
     538             :  private:
     539             :   BinopGen<int32_t>* gen;
     540             :   int32_t input_a;
     541             :   int32_t input_b;
     542             : 
     543             :   void Run(RawMachineAssemblerTester<int32_t>* m);
     544             :   void RunLeft(RawMachineAssemblerTester<int32_t>* m);
     545             :   void RunRight(RawMachineAssemblerTester<int32_t>* m);
     546             : };
     547             : }  // namespace compiler
     548             : }  // namespace internal
     549             : }  // namespace v8
     550             : 
     551             : #endif  // V8_CCTEST_COMPILER_CODEGEN_TESTER_H_

Generated by: LCOV version 1.10