| Index: test/cctest/compiler/test-multiple-return.cc
|
| diff --git a/test/cctest/compiler/test-multiple-return.cc b/test/cctest/compiler/test-multiple-return.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7b2cdc4df7dfb184b946a0d7cea63b8b405b5a99
|
| --- /dev/null
|
| +++ b/test/cctest/compiler/test-multiple-return.cc
|
| @@ -0,0 +1,110 @@
|
| +// Copyright 2014 the V8 project authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <cmath>
|
| +#include <functional>
|
| +#include <limits>
|
| +
|
| +#include "src/assembler.h"
|
| +#include "src/base/bits.h"
|
| +#include "src/base/utils/random-number-generator.h"
|
| +#include "src/codegen.h"
|
| +#include "src/compiler.h"
|
| +#include "src/compiler/linkage.h"
|
| +#include "src/macro-assembler.h"
|
| +#include "test/cctest/cctest.h"
|
| +#include "test/cctest/compiler/codegen-tester.h"
|
| +#include "test/cctest/compiler/value-helper.h"
|
| +
|
| +
|
| +using namespace v8::base;
|
| +using namespace v8::internal;
|
| +using namespace v8::internal::compiler;
|
| +
|
| +
|
| +namespace {
|
| +
|
| +CallDescriptor* GetCallDescriptor(Zone* zone, int return_count,
|
| + int param_count) {
|
| + MachineSignature::Builder msig(zone, return_count, param_count);
|
| + LocationSignature::Builder locations(zone, return_count, param_count);
|
| +
|
| + // Add return location(s).
|
| + for (int i = 0; i < return_count; i++) {
|
| + msig.AddReturn(compiler::kMachInt32);
|
| + locations.AddReturn(LinkageLocation::ForRegister(i));
|
| + }
|
| +
|
| + // Add register and/or stack parameter(s).
|
| + for (int i = 0; i < param_count; i++) {
|
| + msig.AddParam(compiler::kMachInt32);
|
| + locations.AddParam(LinkageLocation::ForRegister(i));
|
| + }
|
| +
|
| + const RegList kCalleeSaveRegisters = 0;
|
| + const RegList kCalleeSaveFPRegisters = 0;
|
| +
|
| + // The target for WASM calls is always a code object.
|
| + MachineType target_type = compiler::kMachAnyTagged;
|
| + LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
|
| + return new (zone) CallDescriptor( // --
|
| + CallDescriptor::kCallCodeObject, // kind
|
| + target_type, // target MachineType
|
| + target_loc, // target location
|
| + msig.Build(), // machine_sig
|
| + locations.Build(), // location_sig
|
| + 0, // js_parameter_count
|
| + compiler::Operator::kNoProperties, // properties
|
| + kCalleeSaveRegisters, // callee-saved registers
|
| + kCalleeSaveFPRegisters, // callee-saved fp regs
|
| + CallDescriptor::kNoFlags, // flags
|
| + "c-call");
|
| +}
|
| +}; // namespace
|
| +
|
| +
|
| +TEST(ReturnThreeValues) {
|
| + Zone zone;
|
| + CallDescriptor* desc = GetCallDescriptor(&zone, 3, 2);
|
| + HandleAndZoneScope handles;
|
| + RawMachineAssembler m(handles.main_isolate(),
|
| + new (handles.main_zone()) Graph(handles.main_zone()),
|
| + desc, kMachPtr,
|
| + InstructionSelector::SupportedMachineOperatorFlags());
|
| +
|
| + Node* p0 = m.Parameter(0);
|
| + Node* p1 = m.Parameter(1);
|
| + Node* add = m.Int32Add(p0, p1);
|
| + Node* sub = m.Int32Sub(p0, p1);
|
| + Node* mul = m.Int32Mul(p0, p1);
|
| + m.Return(add, sub, mul);
|
| +
|
| + CompilationInfo info("testing", handles.main_isolate(), handles.main_zone());
|
| + Handle<Code> code =
|
| + Pipeline::GenerateCodeForTesting(&info, desc, m.graph(), m.Export());
|
| +#ifdef DEBUG
|
| + if (FLAG_print_code) {
|
| + OFStream os(stdout);
|
| + code->Disassemble("three_value", os);
|
| + }
|
| +#endif
|
| +
|
| + RawMachineAssemblerTester<int32_t> mt;
|
| + Node* a = mt.Int32Constant(123);
|
| + Node* b = mt.Int32Constant(456);
|
| + Node* ret3 = mt.AddNode(mt.common()->Call(desc), mt.HeapConstant(code), a, b);
|
| + Node* x = mt.AddNode(mt.common()->Projection(0), ret3);
|
| + Node* y = mt.AddNode(mt.common()->Projection(1), ret3);
|
| + Node* z = mt.AddNode(mt.common()->Projection(2), ret3);
|
| + Node* ret = mt.Int32Add(mt.Int32Add(x, y), z);
|
| + mt.Return(ret);
|
| +#ifdef DEBUG
|
| + Handle<Code> code2 = mt.GetCode();
|
| + if (FLAG_print_code) {
|
| + OFStream os(stdout);
|
| + code2->Disassemble("three_value", os);
|
| + }
|
| +#endif
|
| + CHECK_EQ((123 + 456) + (123 - 456) + (123 * 456), mt.Call());
|
| +}
|
|
|