1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved. 2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file. 4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/assembler.h" 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/codegen.h" 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/linkage.h" 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/raw-machine-assembler.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/machine-type.h" 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/register-configuration.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "test/cctest/cctest.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "test/cctest/compiler/codegen-tester.h" 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "test/cctest/compiler/graph-builder-tester.h" 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "test/cctest/compiler/value-helper.h" 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 { 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal { 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace compiler { 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochconst auto GetRegConfig = RegisterConfiguration::Turbofan; 2221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace { 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef float float32; 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef double float64; 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Picks a representative pair of integers from the given range. 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// If there are less than {max_pairs} possible pairs, do them all, otherwise try 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// to select a representative set. 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Pairs { 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pairs(int max_pairs, int range, const int* codes) 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : range_(range), 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch codes_(codes), 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch max_pairs_(std::min(max_pairs, range_ * range_)), 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch counter_(0) {} 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool More() { return counter_ < max_pairs_; } 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Next(int* r0, int* r1, bool same_is_ok) { 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Find the next pair. 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (exhaustive()) { 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *r0 = codes_[counter_ % range_]; 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *r1 = codes_[counter_ / range_]; 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Try each integer at least once for both r0 and r1. 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int index = counter_ / 2; 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (counter_ & 1) { 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *r0 = codes_[index % range_]; 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *r1 = codes_[index / range_]; 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *r1 = codes_[index % range_]; 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *r0 = codes_[index / range_]; 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch counter_++; 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ((same_is_ok) || (*r0 != *r1)) break; 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (counter_ == max_pairs_) { 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // For the last hurrah, reg#0 with reg#n-1 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *r0 = codes_[0]; 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *r1 = codes_[range_ - 1]; 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (true); 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int range_; 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int* codes_; 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int max_pairs_; 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int counter_; 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool exhaustive() { return max_pairs_ == (range_ * range_); } 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Pairs of general purpose registers. 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass RegisterPairs : public Pairs { 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterPairs() 8121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch : Pairs(100, GetRegConfig()->num_allocatable_general_registers(), 8221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch GetRegConfig()->allocatable_general_codes()) {} 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Pairs of double registers. 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Float32RegisterPairs : public Pairs { 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Float32RegisterPairs() 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Pairs( 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 100, 9221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#if V8_TARGET_ARCH_ARM 9321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch // TODO(bbudge) Modify wasm linkage to allow use of all float regs. 9421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch GetRegConfig()->num_allocatable_double_registers() / 2 - 2, 9521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#else 9621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch GetRegConfig()->num_allocatable_double_registers(), 9721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#endif 9821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch GetRegConfig()->allocatable_double_codes()) { 9921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Pairs of double registers. 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Float64RegisterPairs : public Pairs { 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Float64RegisterPairs() 10721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch : Pairs(100, GetRegConfig()->num_allocatable_double_registers(), 10821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch GetRegConfig()->allocatable_double_codes()) {} 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Helper for allocating either an GP or FP reg, or the next stack slot. 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct Allocator { 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator(int* gp, int gpc, int* fp, int fpc) 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : gp_count(gpc), 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch gp_offset(0), 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch gp_regs(gp), 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch fp_count(fpc), 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch fp_offset(0), 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch fp_regs(fp), 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stack_offset(0) {} 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int gp_count; 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int gp_offset; 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int* gp_regs; 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int fp_count; 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int fp_offset; 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int* fp_regs; 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int stack_offset; 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LinkageLocation Next(MachineType type) { 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsFloatingPoint(type.representation())) { 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate a floating point register/stack location. 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (fp_offset < fp_count) { 13721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int code = fp_regs[fp_offset++]; 13821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#if V8_TARGET_ARCH_ARM 13921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch // TODO(bbudge) Modify wasm linkage to allow use of all float regs. 14021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (type.representation() == MachineRepresentation::kFloat32) code *= 2; 14121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#endif 14221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return LinkageLocation::ForRegister(code); 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int offset = -1 - stack_offset; 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stack_offset += StackWords(type); 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return LinkageLocation::ForCallerFrameSlot(offset); 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate a general purpose register/stack location. 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (gp_offset < gp_count) { 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return LinkageLocation::ForRegister(gp_regs[gp_offset++]); 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int offset = -1 - stack_offset; 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stack_offset += StackWords(type); 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return LinkageLocation::ForCallerFrameSlot(offset); 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int StackWords(MachineType type) { 16021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int size = 1 << ElementSizeLog2Of(type.representation()); 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return size <= kPointerSize ? 1 : size / kPointerSize; 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Reset() { 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch fp_offset = 0; 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch gp_offset = 0; 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stack_offset = 0; 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass RegisterConfig { 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfig(Allocator& p, Allocator& r) : params(p), rets(r) {} 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* Create(Zone* zone, MachineSignature* msig) { 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch rets.Reset(); 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch params.Reset(); 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LocationSignature::Builder locations(zone, msig->return_count(), 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch msig->parameter_count()); 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Add return location(s). 182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int return_count = static_cast<int>(locations.return_count_); 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < return_count; i++) { 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch locations.AddReturn(rets.Next(msig->GetReturn(i))); 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Add register and/or stack parameter(s). 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int parameter_count = static_cast<int>(msig->parameter_count()); 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < parameter_count; i++) { 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch locations.AddParam(params.Next(msig->GetParam(i))); 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegList kCalleeSaveRegisters = 0; 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegList kCalleeSaveFPRegisters = 0; 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType target_type = MachineType::AnyTagged(); 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int stack_param_count = params.stack_offset; 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return new (zone) CallDescriptor( // -- 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor::kCallCodeObject, // kind 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch target_type, // target MachineType 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch target_loc, // target location 203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch msig, // machine_sig 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch locations.Build(), // location_sig 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stack_param_count, // stack_parameter_count 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch compiler::Operator::kNoProperties, // properties 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kCalleeSaveRegisters, // callee-saved registers 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kCalleeSaveFPRegisters, // callee-saved fp regs 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor::kUseNativeStack, // flags 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "c-call"); 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator& params; 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator& rets; 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst int kMaxParamCount = 64; 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMachineType kIntTypes[kMaxParamCount + 1] = { 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int32()}; 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// For making uniform int32 signatures shorter. 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Int32Signature : public MachineSignature { 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit Int32Signature(int param_count) 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : MachineSignature(1, param_count, kIntTypes) { 250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(param_count <= kMaxParamCount); 251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<Code> CompileGraph(const char* name, CallDescriptor* desc, Graph* graph, 256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Schedule* schedule = nullptr) { 257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = CcTest::InitIsolateOnce(); 258537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CompilationInfo info(ArrayVector("testing"), isolate, graph->zone()); 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> code = 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pipeline::GenerateCodeForTesting(&info, desc, graph, schedule); 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(!code.is_null()); 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef ENABLE_DISASSEMBLER 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_print_opt_code) { 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OFStream os(stdout); 265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch code->Disassemble(name, os); 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return code; 269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<Code> WrapWithCFunction(Handle<Code> inner, CallDescriptor* desc) { 2731b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(inner->GetIsolate()->allocator()); 274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineSignature* msig = 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const_cast<MachineSignature*>(desc->GetMachineSignature()); 276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int param_count = static_cast<int>(msig->parameter_count()); 277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GraphAndBuilders caller(&zone); 278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GraphAndBuilders& b = caller; 280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* start = b.graph()->NewNode(b.common()->Start(param_count + 3)); 281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch b.graph()->SetStart(start); 282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* target = b.graph()->NewNode(b.common()->HeapConstant(inner)); 283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Add arguments to the call. 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node** args = zone.NewArray<Node*>(param_count + 3); 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int index = 0; 287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch args[index++] = target; 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < param_count; i++) { 289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch args[index] = b.graph()->NewNode(b.common()->Parameter(i), start); 290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch index++; 291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch args[index++] = start; // effect. 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch args[index++] = start; // control. 294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Build the call and return nodes. 296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* call = 297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch b.graph()->NewNode(b.common()->Call(desc), param_count + 3, args); 298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* ret = b.graph()->NewNode(b.common()->Return(), call, call, start); 299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch b.graph()->SetEnd(ret); 300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, msig); 303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return CompileGraph("wrapper", cdesc, caller.graph()); 305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <typename CType> 309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ArgsBuffer { 310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMaxParamCount = 64; 312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit ArgsBuffer(int count, int seed = 1) : count_(count), seed_(seed) { 314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // initialize the buffer with "seed 0" 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch seed_ = 0; 316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Mutate(); 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch seed_ = seed; 318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class Sig : public MachineSignature { 321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit Sig(int param_count) 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : MachineSignature(1, param_count, MachTypes()) { 324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(param_count <= kMaxParamCount); 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static MachineType* MachTypes() { 329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType t = MachineTypeForC<CType>(); 330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static MachineType kTypes[kMaxParamCount + 1] = { 331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, 332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t}; 334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return kTypes; 335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* MakeConstant(RawMachineAssembler& raw, int32_t value) { 338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return raw.Int32Constant(value); 339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* MakeConstant(RawMachineAssembler& raw, int64_t value) { 342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return raw.Int64Constant(value); 343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* MakeConstant(RawMachineAssembler& raw, float32 value) { 346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return raw.Float32Constant(value); 347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* MakeConstant(RawMachineAssembler& raw, float64 value) { 350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return raw.Float64Constant(value); 351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* LoadInput(RawMachineAssembler& raw, Node* base, int index) { 354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* offset = raw.Int32Constant(index * sizeof(CType)); 355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return raw.Load(MachineTypeForC<CType>(), base, offset); 356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* StoreOutput(RawMachineAssembler& raw, Node* value) { 359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* base = raw.PointerConstant(&output); 360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* offset = raw.Int32Constant(0); 361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return raw.Store(MachineTypeForC<CType>().representation(), base, offset, 362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value, kNoWriteBarrier); 363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Computes the next set of inputs by updating the {input} array. 366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Mutate(); 367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Reset() { memset(input, 0, sizeof(input)); } 369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int count_; 371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int seed_; 372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CType input[kMaxParamCount]; 373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CType output; 374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <> 378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ArgsBuffer<int32_t>::Mutate() { 379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t base = 1111111111u * seed_; 380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int j = 0; j < count_ && j < kMaxParamCount; j++) { 381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch input[j] = static_cast<int32_t>(256 + base + j + seed_ * 13); 382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch output = -1; 384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch seed_++; 385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <> 389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ArgsBuffer<int64_t>::Mutate() { 390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint64_t base = 11111111111111111ull * seed_; 391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int j = 0; j < count_ && j < kMaxParamCount; j++) { 392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch input[j] = static_cast<int64_t>(256 + base + j + seed_ * 13); 393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch output = -1; 395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch seed_++; 396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <> 400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ArgsBuffer<float32>::Mutate() { 401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch float64 base = -33.25 * seed_; 402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int j = 0; j < count_ && j < kMaxParamCount; j++) { 403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch input[j] = 256 + base + j + seed_ * 13; 404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch output = std::numeric_limits<float32>::quiet_NaN(); 406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch seed_++; 407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <> 411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ArgsBuffer<float64>::Mutate() { 412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch float64 base = -111.25 * seed_; 413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int j = 0; j < count_ && j < kMaxParamCount; j++) { 414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch input[j] = 256 + base + j + seed_ * 13; 415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch output = std::numeric_limits<float64>::quiet_NaN(); 417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch seed_++; 418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint ParamCount(CallDescriptor* desc) { 422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return static_cast<int>(desc->GetMachineSignature()->parameter_count()); 423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <typename CType> 427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Computer { 428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void Run(CallDescriptor* desc, 430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void (*build)(CallDescriptor*, RawMachineAssembler&), 431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CType (*compute)(CallDescriptor*, CType* inputs), 432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int seed = 1) { 433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int num_params = ParamCount(desc); 434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_LE(num_params, kMaxParamCount); 435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = CcTest::InitIsolateOnce(); 436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleScope scope(isolate); 437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> inner = Handle<Code>::null(); 438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Build the graph for the computation. 4401b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(isolate->allocator()); 441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Graph graph(&zone); 442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawMachineAssembler raw(isolate, &graph, desc); 443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch build(desc, raw); 444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inner = CompileGraph("Compute", desc, &graph, raw.Export()); 445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CSignature0<int32_t> csig; 448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArgsBuffer<CType> io(num_params, seed); 449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // constant mode. 452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> wrapper = Handle<Code>::null(); 453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Wrap the above code with a callable function that passes constants. 4551b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(isolate->allocator()); 456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Graph graph(&zone); 457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); 458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawMachineAssembler raw(isolate, &graph, cdesc); 459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* target = raw.HeapConstant(inner); 460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node** args = zone.NewArray<Node*>(num_params); 461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < num_params; i++) { 462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch args[i] = io.MakeConstant(raw, io.input[i]); 463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* call = raw.CallN(desc, target, args); 466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* store = io.StoreOutput(raw, call); 467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(store); 468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raw.Return(raw.Int32Constant(seed)); 469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch wrapper = 470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompileGraph("Compute-wrapper-const", cdesc, &graph, raw.Export()); 471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeRunner<int32_t> runnable(isolate, wrapper, &csig); 474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Run the code, checking it against the reference. 476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CType expected = compute(desc, io.input); 477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t check_seed = runnable.Call(); 478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(seed, check_seed); 479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(expected, io.output); 480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // buffer mode. 484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> wrapper = Handle<Code>::null(); 485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Wrap the above code with a callable function that loads from {input}. 4871b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(isolate->allocator()); 488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Graph graph(&zone); 489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); 490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawMachineAssembler raw(isolate, &graph, cdesc); 491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* base = raw.PointerConstant(io.input); 492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* target = raw.HeapConstant(inner); 493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node** args = zone.NewArray<Node*>(kMaxParamCount); 494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < num_params; i++) { 495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch args[i] = io.LoadInput(raw, base, i); 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* call = raw.CallN(desc, target, args); 499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* store = io.StoreOutput(raw, call); 500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(store); 501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raw.Return(raw.Int32Constant(seed)); 502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch wrapper = CompileGraph("Compute-wrapper", cdesc, &graph, raw.Export()); 503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeRunner<int32_t> runnable(isolate, wrapper, &csig); 506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Run the code, checking it against the reference. 508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < 5; i++) { 509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CType expected = compute(desc, io.input); 510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t check_seed = runnable.Call(); 511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(seed, check_seed); 512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(expected, io.output); 513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch io.Mutate(); 514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace 520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void TestInt32Sub(CallDescriptor* desc) { 523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = CcTest::InitIsolateOnce(); 524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleScope scope(isolate); 5251b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(isolate->allocator()); 526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GraphAndBuilders inner(&zone); 527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Build the add function. 529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GraphAndBuilders& b = inner; 530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* start = b.graph()->NewNode(b.common()->Start(5)); 531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch b.graph()->SetStart(start); 532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* p0 = b.graph()->NewNode(b.common()->Parameter(0), start); 533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* p1 = b.graph()->NewNode(b.common()->Parameter(1), start); 534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* add = b.graph()->NewNode(b.machine()->Int32Sub(), p0, p1); 535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* ret = b.graph()->NewNode(b.common()->Return(), add, start, start); 536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch b.graph()->SetEnd(ret); 537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> inner_code = CompileGraph("Int32Sub", desc, inner.graph()); 540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> wrapper = WrapWithCFunction(inner_code, desc); 541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineSignature* msig = 542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const_cast<MachineSignature*>(desc->GetMachineSignature()); 543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeRunner<int32_t> runnable(isolate, wrapper, 544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CSignature::FromMachine(&zone, msig)); 545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FOR_INT32_INPUTS(i) { 547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FOR_INT32_INPUTS(j) { 548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t expected = static_cast<int32_t>(static_cast<uint32_t>(*i) - 549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<uint32_t>(*j)); 550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t result = runnable.Call(*i, *j); 551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(expected, result); 552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void CopyTwentyInt32(CallDescriptor* desc) { 558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int kNumParams = 20; 559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t input[kNumParams]; 560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t output[kNumParams]; 561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = CcTest::InitIsolateOnce(); 562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleScope scope(isolate); 563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> inner = Handle<Code>::null(); 564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Writes all parameters into the output buffer. 5661b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(isolate->allocator()); 567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Graph graph(&zone); 568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawMachineAssembler raw(isolate, &graph, desc); 569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* base = raw.PointerConstant(output); 570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < kNumParams; i++) { 571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* offset = raw.Int32Constant(i * sizeof(int32_t)); 572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raw.Store(MachineRepresentation::kWord32, base, offset, raw.Parameter(i), 573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kNoWriteBarrier); 574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raw.Return(raw.Int32Constant(42)); 576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inner = CompileGraph("CopyTwentyInt32", desc, &graph, raw.Export()); 577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CSignature0<int32_t> csig; 580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> wrapper = Handle<Code>::null(); 581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Loads parameters from the input buffer and calls the above code. 5831b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(isolate->allocator()); 584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Graph graph(&zone); 585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); 586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawMachineAssembler raw(isolate, &graph, cdesc); 587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* base = raw.PointerConstant(input); 588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* target = raw.HeapConstant(inner); 589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node** args = zone.NewArray<Node*>(kNumParams); 590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < kNumParams; i++) { 591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* offset = raw.Int32Constant(i * sizeof(int32_t)); 592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch args[i] = raw.Load(MachineType::Int32(), base, offset); 593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* call = raw.CallN(desc, target, args); 596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raw.Return(call); 597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch wrapper = 598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompileGraph("CopyTwentyInt32-wrapper", cdesc, &graph, raw.Export()); 599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeRunner<int32_t> runnable(isolate, wrapper, &csig); 602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Run the code, checking it correctly implements the memcpy. 604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < 5; i++) { 605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t base = 1111111111u * i; 606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int j = 0; j < kNumParams; j++) { 607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch input[j] = static_cast<int32_t>(base + 13 * j); 608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch memset(output, 0, sizeof(output)); 611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(42, runnable.Call()); 612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int j = 0; j < kNumParams; j++) { 614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(input[j], output[j]); 615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void Test_RunInt32SubWithRet(int retreg) { 621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Int32Signature sig(2); 6221b268ca467c924004286c97bac133db489cf43d0Ben Murdoch base::AccountingAllocator allocator; 6231b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(&allocator); 624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterPairs pairs; 625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (pairs.More()) { 626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int parray[2]; 627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rarray[] = {retreg}; 628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pairs.Next(&parray[0], &parray[1], false); 629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator params(parray, 2, nullptr, 0); 630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator rets(rarray, 1, nullptr, 0); 631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfig config(params, rets); 632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* desc = config.Create(&zone, &sig); 633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TestInt32Sub(desc); 634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Separate tests for parallelization. 63921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#define TEST_INT32_SUB_WITH_RET(x) \ 64021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch TEST(Run_Int32Sub_all_allocatable_pairs_##x) { \ 64121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (x < Register::kNumRegisters && \ 64221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch GetRegConfig()->IsAllocatableGeneralCode(x)) { \ 64321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Test_RunInt32SubWithRet(x); \ 64421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } \ 645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(0) 648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(1) 649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(2) 650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(3) 651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(4) 652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(5) 653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(6) 654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(7) 655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(8) 656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(9) 657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(10) 658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(11) 659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(12) 660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(13) 661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(14) 662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(15) 663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(16) 664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(17) 665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(18) 666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SUB_WITH_RET(19) 667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(Run_Int32Sub_all_allocatable_single) { 670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Int32Signature sig(2); 671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterPairs pairs; 672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (pairs.More()) { 6731b268ca467c924004286c97bac133db489cf43d0Ben Murdoch base::AccountingAllocator allocator; 6741b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(&allocator); 675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int parray[1]; 676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int rarray[1]; 677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pairs.Next(&rarray[0], &parray[0], true); 678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator params(parray, 1, nullptr, 0); 679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator rets(rarray, 1, nullptr, 0); 680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfig config(params, rets); 681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* desc = config.Create(&zone, &sig); 682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TestInt32Sub(desc); 683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(Run_CopyTwentyInt32_all_allocatable_pairs) { 688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Int32Signature sig(20); 689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterPairs pairs; 690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (pairs.More()) { 6911b268ca467c924004286c97bac133db489cf43d0Ben Murdoch base::AccountingAllocator allocator; 6921b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(&allocator); 693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int parray[2]; 69421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int rarray[] = {GetRegConfig()->GetAllocatableGeneralCode(0)}; 695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pairs.Next(&parray[0], &parray[1], false); 696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator params(parray, 2, nullptr, 0); 697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator rets(rarray, 1, nullptr, 0); 698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfig config(params, rets); 699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* desc = config.Create(&zone, &sig); 700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CopyTwentyInt32(desc); 701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <typename CType> 706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void Run_Computation( 707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* desc, void (*build)(CallDescriptor*, RawMachineAssembler&), 708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CType (*compute)(CallDescriptor*, CType* inputs), int seed = 1) { 709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Computer<CType>::Run(desc, build, compute, seed); 710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic uint32_t coeff[] = {1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 79, 83, 89, 97, 101, 103, 107, 109, 113}; 716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void Build_Int32_WeightedSum(CallDescriptor* desc, 719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawMachineAssembler& raw) { 720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* result = raw.Int32Constant(0); 721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < ParamCount(desc); i++) { 722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* term = raw.Int32Mul(raw.Parameter(i), raw.Int32Constant(coeff[i])); 723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch result = raw.Int32Add(result, term); 724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raw.Return(result); 726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic int32_t Compute_Int32_WeightedSum(CallDescriptor* desc, int32_t* input) { 730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t result = 0; 731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < ParamCount(desc); i++) { 732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch result += static_cast<uint32_t>(input[i]) * coeff[i]; 733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return static_cast<int32_t>(result); 735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void Test_Int32_WeightedSum_of_size(int count) { 739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Int32Signature sig(count); 740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int p0 = 0; p0 < Register::kNumRegisters; p0++) { 74121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (GetRegConfig()->IsAllocatableGeneralCode(p0)) { 7421b268ca467c924004286c97bac133db489cf43d0Ben Murdoch base::AccountingAllocator allocator; 7431b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(&allocator); 744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int parray[] = {p0}; 74621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int rarray[] = {GetRegConfig()->GetAllocatableGeneralCode(0)}; 747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator params(parray, 1, nullptr, 0); 748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator rets(rarray, 1, nullptr, 0); 749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfig config(params, rets); 750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* desc = config.Create(&zone, &sig); 751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Run_Computation<int32_t>(desc, Build_Int32_WeightedSum, 752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Compute_Int32_WeightedSum, 257 + count); 753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Separate tests for parallelization. 759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define TEST_INT32_WEIGHTEDSUM(x) \ 760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TEST(Run_Int32_WeightedSum_##x) { Test_Int32_WeightedSum_of_size(x); } 761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_WEIGHTEDSUM(1) 764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_WEIGHTEDSUM(2) 765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_WEIGHTEDSUM(3) 766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_WEIGHTEDSUM(4) 767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_WEIGHTEDSUM(5) 768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_WEIGHTEDSUM(7) 769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_WEIGHTEDSUM(9) 770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_WEIGHTEDSUM(11) 771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_WEIGHTEDSUM(17) 772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_WEIGHTEDSUM(19) 773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <int which> 776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void Build_Select(CallDescriptor* desc, RawMachineAssembler& raw) { 777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raw.Return(raw.Parameter(which)); 778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <typename CType, int which> 782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic CType Compute_Select(CallDescriptor* desc, CType* inputs) { 783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return inputs[which]; 784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <typename CType, int which> 788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void RunSelect(CallDescriptor* desc) { 789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int count = ParamCount(desc); 790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (count <= which) return; 791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Run_Computation<CType>(desc, Build_Select<which>, 792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Compute_Select<CType, which>, 793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1044 + which + 3 * sizeof(CType)); 794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <int which> 798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Test_Int32_Select() { 79921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int parray[] = {GetRegConfig()->GetAllocatableGeneralCode(0)}; 80021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int rarray[] = {GetRegConfig()->GetAllocatableGeneralCode(0)}; 801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator params(parray, 1, nullptr, 0); 802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator rets(rarray, 1, nullptr, 0); 803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfig config(params, rets); 804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 8051b268ca467c924004286c97bac133db489cf43d0Ben Murdoch base::AccountingAllocator allocator; 8061b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(&allocator); 807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = which + 1; i <= 64; i++) { 809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Int32Signature sig(i); 810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* desc = config.Create(&zone, &sig); 811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<int32_t, which>(desc); 812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Separate tests for parallelization. 817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define TEST_INT32_SELECT(x) \ 818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TEST(Run_Int32_Select_##x) { Test_Int32_Select<x>(); } 819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SELECT(0) 822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SELECT(1) 823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SELECT(2) 824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SELECT(3) 825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SELECT(4) 826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SELECT(5) 827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SELECT(6) 828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SELECT(11) 829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SELECT(15) 830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SELECT(19) 831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SELECT(45) 832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SELECT(62) 833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST_INT32_SELECT(63) 834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(Int64Select_registers) { 83721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (GetRegConfig()->num_allocatable_general_registers() < 2) return; 838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize < 8) return; // TODO(titzer): int64 on 32-bit platforms 839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 84021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int rarray[] = {GetRegConfig()->GetAllocatableGeneralCode(0)}; 841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArgsBuffer<int64_t>::Sig sig(2); 842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterPairs pairs; 8441b268ca467c924004286c97bac133db489cf43d0Ben Murdoch base::AccountingAllocator allocator; 8451b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(&allocator); 846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (pairs.More()) { 847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int parray[2]; 848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pairs.Next(&parray[0], &parray[1], false); 849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator params(parray, 2, nullptr, 0); 850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator rets(rarray, 1, nullptr, 0); 851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfig config(params, rets); 852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* desc = config.Create(&zone, &sig); 854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<int64_t, 0>(desc); 855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<int64_t, 1>(desc); 856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(Float32Select_registers) { 86121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (GetRegConfig()->num_allocatable_double_registers() < 2) { 862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 86521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int rarray[] = {GetRegConfig()->GetAllocatableDoubleCode(0)}; 866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArgsBuffer<float32>::Sig sig(2); 867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Float32RegisterPairs pairs; 8691b268ca467c924004286c97bac133db489cf43d0Ben Murdoch base::AccountingAllocator allocator; 8701b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(&allocator); 871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (pairs.More()) { 872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int parray[2]; 873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pairs.Next(&parray[0], &parray[1], false); 874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator params(nullptr, 0, parray, 2); 875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator rets(nullptr, 0, rarray, 1); 876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfig config(params, rets); 877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* desc = config.Create(&zone, &sig); 879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float32, 0>(desc); 880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float32, 1>(desc); 881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(Float64Select_registers) { 88621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (GetRegConfig()->num_allocatable_double_registers() < 2) return; 88721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (GetRegConfig()->num_allocatable_general_registers() < 2) return; 88821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int rarray[] = {GetRegConfig()->GetAllocatableDoubleCode(0)}; 889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArgsBuffer<float64>::Sig sig(2); 890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Float64RegisterPairs pairs; 8921b268ca467c924004286c97bac133db489cf43d0Ben Murdoch base::AccountingAllocator allocator; 8931b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(&allocator); 894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (pairs.More()) { 895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int parray[2]; 896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pairs.Next(&parray[0], &parray[1], false); 897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator params(nullptr, 0, parray, 2); 898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator rets(nullptr, 0, rarray, 1); 899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfig config(params, rets); 900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* desc = config.Create(&zone, &sig); 902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float64, 0>(desc); 903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float64, 1>(desc); 904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(Float32Select_stack_params_return_reg) { 90921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int rarray[] = {GetRegConfig()->GetAllocatableDoubleCode(0)}; 910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator params(nullptr, 0, nullptr, 0); 911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator rets(nullptr, 0, rarray, 1); 912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfig config(params, rets); 913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 9141b268ca467c924004286c97bac133db489cf43d0Ben Murdoch base::AccountingAllocator allocator; 9151b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(&allocator); 916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int count = 1; count < 6; count++) { 917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArgsBuffer<float32>::Sig sig(count); 918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* desc = config.Create(&zone, &sig); 919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float32, 0>(desc); 920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float32, 1>(desc); 921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float32, 2>(desc); 922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float32, 3>(desc); 923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float32, 4>(desc); 924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float32, 5>(desc); 925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(Float64Select_stack_params_return_reg) { 93021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int rarray[] = {GetRegConfig()->GetAllocatableDoubleCode(0)}; 931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator params(nullptr, 0, nullptr, 0); 932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator rets(nullptr, 0, rarray, 1); 933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfig config(params, rets); 934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 9351b268ca467c924004286c97bac133db489cf43d0Ben Murdoch base::AccountingAllocator allocator; 9361b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(&allocator); 937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int count = 1; count < 6; count++) { 938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArgsBuffer<float64>::Sig sig(count); 939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* desc = config.Create(&zone, &sig); 940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float64, 0>(desc); 941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float64, 1>(desc); 942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float64, 2>(desc); 943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float64, 3>(desc); 944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float64, 4>(desc); 945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RunSelect<float64, 5>(desc); 946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <typename CType, int which> 951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void Build_Select_With_Call(CallDescriptor* desc, 952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawMachineAssembler& raw) { 953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> inner = Handle<Code>::null(); 954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int num_params = ParamCount(desc); 955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_LE(num_params, kMaxParamCount); 956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = CcTest::InitIsolateOnce(); 958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Build the actual select. 9591b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(isolate->allocator()); 960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Graph graph(&zone); 961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawMachineAssembler raw(isolate, &graph, desc); 962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raw.Return(raw.Parameter(which)); 963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inner = CompileGraph("Select-indirection", desc, &graph, raw.Export()); 964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(!inner.is_null()); 965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(inner->IsCode()); 966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Build a call to the function that does the select. 970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* target = raw.HeapConstant(inner); 971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node** args = raw.zone()->NewArray<Node*>(num_params); 972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < num_params; i++) { 973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch args[i] = raw.Parameter(i); 974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* call = raw.CallN(desc, target, args); 977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raw.Return(call); 978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(Float64StackParamsToStackParams) { 98321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int rarray[] = {GetRegConfig()->GetAllocatableDoubleCode(0)}; 984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator params(nullptr, 0, nullptr, 0); 985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator rets(nullptr, 0, rarray, 1); 986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 9871b268ca467c924004286c97bac133db489cf43d0Ben Murdoch base::AccountingAllocator allocator; 9881b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(&allocator); 989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArgsBuffer<float64>::Sig sig(2); 990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfig config(params, rets); 991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* desc = config.Create(&zone, &sig); 992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Run_Computation<float64>(desc, Build_Select_With_Call<float64, 0>, 994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Compute_Select<float64, 0>, 1098); 995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Run_Computation<float64>(desc, Build_Select_With_Call<float64, 1>, 997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Compute_Select<float64, 1>, 1099); 998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MixedParamTest(int start) { 100221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (GetRegConfig()->num_double_registers() < 2) return; 1003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// TODO(titzer): mix in 64-bit types on all platforms when supported. 1005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_32_BIT 1006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static MachineType types[] = { 1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Float32(), MachineType::Float64(), 1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Float64(), MachineType::Float32(), 1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Float32(), MachineType::Float64(), MachineType::Int32(), 1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Float32(), MachineType::Int32(), MachineType::Float64(), 1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Float64(), MachineType::Float32(), MachineType::Int32(), 1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Float64(), MachineType::Int32(), MachineType::Float32()}; 1013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 1014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static MachineType types[] = { 1015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Int64(), MachineType::Float32(), 1016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Float64(), MachineType::Int32(), MachineType::Float64(), 1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Float32(), MachineType::Int64(), MachineType::Int64(), 1018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Float32(), MachineType::Float32(), MachineType::Int32(), 1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Float64(), MachineType::Float64(), MachineType::Int64(), 1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Int32(), MachineType::Float64(), MachineType::Int32(), 1021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType::Float32()}; 1022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = CcTest::InitIsolateOnce(); 1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Build machine signature 1027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType* params = &types[start]; 1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int num_params = static_cast<int>(arraysize(types) - start); 1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Build call descriptor 103121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int parray_gp[] = {GetRegConfig()->GetAllocatableGeneralCode(0), 103221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch GetRegConfig()->GetAllocatableGeneralCode(1)}; 103321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int rarray_gp[] = {GetRegConfig()->GetAllocatableGeneralCode(0)}; 103421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int parray_fp[] = {GetRegConfig()->GetAllocatableDoubleCode(0), 103521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch GetRegConfig()->GetAllocatableDoubleCode(1)}; 103621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int rarray_fp[] = {GetRegConfig()->GetAllocatableDoubleCode(0)}; 1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator palloc(parray_gp, 2, parray_fp, 2); 1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocator ralloc(rarray_gp, 1, rarray_fp, 1); 1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfig config(palloc, ralloc); 1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int which = 0; which < num_params; which++) { 10421b268ca467c924004286c97bac133db489cf43d0Ben Murdoch base::AccountingAllocator allocator; 10431b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(&allocator); 1044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleScope scope(isolate); 1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineSignature::Builder builder(&zone, 1, num_params); 1046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder.AddReturn(params[which]); 1047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int j = 0; j < num_params; j++) builder.AddParam(params[j]); 1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineSignature* sig = builder.Build(); 1049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* desc = config.Create(&zone, sig); 1050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> select; 1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // build the select. 10541b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(&allocator); 1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Graph graph(&zone); 1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawMachineAssembler raw(isolate, &graph, desc); 1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raw.Return(raw.Parameter(which)); 1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch select = CompileGraph("Compute", desc, &graph, raw.Export()); 1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // call the select. 1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> wrapper = Handle<Code>::null(); 1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t expected_ret; 1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch char bytes[kDoubleSize]; 1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V8_ALIGNED(8) char output[kDoubleSize]; 1067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int expected_size = 0; 1068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CSignature0<int32_t> csig; 1069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Wrap the select code with a callable function that passes constants. 10711b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(&allocator); 1072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Graph graph(&zone); 1073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); 1074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RawMachineAssembler raw(isolate, &graph, cdesc); 1075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* target = raw.HeapConstant(select); 1076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node** args = zone.NewArray<Node*>(num_params); 1077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t constant = 0x0102030405060708; 1078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < num_params; i++) { 1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineType param_type = sig->GetParam(i); 1080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* konst = nullptr; 1081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (param_type == MachineType::Int32()) { 1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t value[] = {static_cast<int32_t>(constant)}; 1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch konst = raw.Int32Constant(value[0]); 1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (i == which) memcpy(bytes, value, expected_size = 4); 1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (param_type == MachineType::Int64()) { 1087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t value[] = {static_cast<int64_t>(constant)}; 1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch konst = raw.Int64Constant(value[0]); 1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (i == which) memcpy(bytes, value, expected_size = 8); 1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (param_type == MachineType::Float32()) { 1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch float32 value[] = {static_cast<float32>(constant)}; 1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch konst = raw.Float32Constant(value[0]); 1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (i == which) memcpy(bytes, value, expected_size = 4); 1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (param_type == MachineType::Float64()) { 1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch float64 value[] = {static_cast<float64>(constant)}; 1098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch konst = raw.Float64Constant(value[0]); 1099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (i == which) memcpy(bytes, value, expected_size = 8); 1100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_NOT_NULL(konst); 1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch args[i] = konst; 1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch constant += 0x1010101010101010; 1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* call = raw.CallN(desc, target, args); 1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* store = 1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raw.StoreToPointer(output, sig->GetReturn().representation(), call); 1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(store); 1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch expected_ret = static_cast<int32_t>(constant); 1112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raw.Return(raw.Int32Constant(expected_ret)); 1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch wrapper = CompileGraph("Select-mixed-wrapper-const", cdesc, &graph, 1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raw.Export()); 1115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeRunner<int32_t> runnable(isolate, wrapper, &csig); 1118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(expected_ret, runnable.Call()); 1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < expected_size; i++) { 1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(static_cast<int>(bytes[i]), static_cast<int>(output[i])); 1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(MixedParams_0) { MixedParamTest(0); } 1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(MixedParams_1) { MixedParamTest(1); } 1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(MixedParams_2) { MixedParamTest(2); } 1130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(MixedParams_3) { MixedParamTest(3); } 1131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1132342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochtemplate <typename T> 1133342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochvoid TestStackSlot(MachineType slot_type, T expected) { 1134342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch // Test: Generate with a function f which reserves a stack slot, call an inner 1135342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch // function g from f which writes into the stack slot of f. 1136342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 113721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (GetRegConfig()->num_allocatable_double_registers() < 2) return; 1138342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 1139342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Isolate* isolate = CcTest::InitIsolateOnce(); 1140342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 1141342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch // Lots of code to generate the build descriptor for the inner function. 114221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int parray_gp[] = {GetRegConfig()->GetAllocatableGeneralCode(0), 114321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch GetRegConfig()->GetAllocatableGeneralCode(1)}; 114421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int rarray_gp[] = {GetRegConfig()->GetAllocatableGeneralCode(0)}; 114521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int parray_fp[] = {GetRegConfig()->GetAllocatableDoubleCode(0), 114621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch GetRegConfig()->GetAllocatableDoubleCode(1)}; 114721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch int rarray_fp[] = {GetRegConfig()->GetAllocatableDoubleCode(0)}; 1148342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Allocator palloc(parray_gp, 2, parray_fp, 2); 1149342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Allocator ralloc(rarray_gp, 1, rarray_fp, 1); 1150342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch RegisterConfig config(palloc, ralloc); 1151342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 11521b268ca467c924004286c97bac133db489cf43d0Ben Murdoch Zone zone(isolate->allocator()); 1153342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch HandleScope scope(isolate); 1154342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch MachineSignature::Builder builder(&zone, 1, 12); 1155342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch builder.AddReturn(MachineType::Int32()); 1156342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch for (int i = 0; i < 10; i++) { 1157342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch builder.AddParam(MachineType::Int32()); 1158342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 1159342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch builder.AddParam(slot_type); 1160342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch builder.AddParam(MachineType::Pointer()); 1161342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch MachineSignature* sig = builder.Build(); 1162342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CallDescriptor* desc = config.Create(&zone, sig); 1163342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 1164342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch // Create inner function g. g has lots of parameters so that they are passed 1165342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch // over the stack. 1166342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Handle<Code> inner; 1167342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Graph graph(&zone); 1168342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch RawMachineAssembler g(isolate, &graph, desc); 1169342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 1170342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch g.Store(slot_type.representation(), g.Parameter(11), g.Parameter(10), 1171342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch WriteBarrierKind::kNoWriteBarrier); 1172342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch g.Return(g.Parameter(9)); 1173342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch inner = CompileGraph("Compute", desc, &graph, g.Export()); 1174342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 1175342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch // Create function f with a stack slot which calls the inner function g. 1176342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch BufferedRawMachineAssemblerTester<T> f(slot_type); 1177342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Node* target = f.HeapConstant(inner); 1178342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Node* stack_slot = f.StackSlot(slot_type.representation()); 1179342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Node* args[12]; 1180342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch for (int i = 0; i < 10; i++) { 1181342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch args[i] = f.Int32Constant(i); 1182342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 1183342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch args[10] = f.Parameter(0); 1184342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch args[11] = stack_slot; 1185342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 1186342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch f.CallN(desc, target, args); 1187342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch f.Return(f.Load(slot_type, stack_slot, f.IntPtrConstant(0))); 1188342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 1189342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch CHECK_EQ(expected, f.Call(expected)); 1190342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch} 1191342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 1192342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen MurdochTEST(RunStackSlotInt32) { 1193342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch int32_t magic = 0x12345678; 1194342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch TestStackSlot(MachineType::Int32(), magic); 1195342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch} 1196342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 1197342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#if !V8_TARGET_ARCH_32_BIT 1198342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen MurdochTEST(RunStackSlotInt64) { 1199342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch int64_t magic = 0x123456789abcdef0; 1200342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch TestStackSlot(MachineType::Int64(), magic); 1201342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch} 1202342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#endif 1203342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 1204342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen MurdochTEST(RunStackSlotFloat32) { 1205342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch float magic = 1234.125f; 1206342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch TestStackSlot(MachineType::Float32(), magic); 1207342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch} 1208342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 1209342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen MurdochTEST(RunStackSlotFloat64) { 1210342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch double magic = 3456.375; 1211342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch TestStackSlot(MachineType::Float64(), magic); 1212342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch} 1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace compiler 1214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 1215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 1216