| Index: crosstest/test_calling_conv_main.cpp
|
| diff --git a/crosstest/test_calling_conv_main.cpp b/crosstest/test_calling_conv_main.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..2ced68f9af6df0c998182de24ad90718f417f234
|
| --- /dev/null
|
| +++ b/crosstest/test_calling_conv_main.cpp
|
| @@ -0,0 +1,183 @@
|
| +//===- subzero/crosstest/test_calling_conv_main.cpp - Driver for tests ----===//
|
| +//
|
| +// The Subzero Code Generator
|
| +//
|
| +// This file is distributed under the University of Illinois Open Source
|
| +// License. See LICENSE.TXT for details.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +//
|
| +// This file contains the driver for cross testing the compatibility of
|
| +// calling conventions.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +/* crosstest.py --test=test_calling_conv.cpp \
|
| + --driver=test_calling_conv_main.cpp --prefix=Subzero_ \
|
| + --output=test_calling_conv */
|
| +
|
| +#include <cstring>
|
| +#include <iostream>
|
| +#include <sstream>
|
| +
|
| +#include "test_calling_conv.h"
|
| +
|
| +namespace Subzero_ {
|
| +#include "test_calling_conv.h"
|
| +}
|
| +
|
| +// The crosstest code consists of caller / callee function pairs.
|
| +//
|
| +// The caller function initializes a list of arguments and calls the
|
| +// function located at Callee.
|
| +//
|
| +// The callee function writes the argument numbered ArgNum into the
|
| +// location pointed to by Buf.
|
| +//
|
| +// testCaller() tests that caller function compiled by Subzero and llc
|
| +// pass arguments to the callee in the same way. The Caller() and
|
| +// Subzero_Caller() functions both call the same callee (which has been
|
| +// compiled by llc). The result in the global buffer is compared to
|
| +// check it is the same value after the calls by both callers.
|
| +//
|
| +// testCallee() runs the same kind of test, except that the functions
|
| +// Callee() and Subzero_Callee() are being tested to ensure that both
|
| +// functions receive arguments from the caller in the same way. The
|
| +// caller is compiled by llc.
|
| +//
|
| +// Some crosstest functions allocate local arrays as part of the test.
|
| +// The fakeUse function is used to ensure that array allocations are not
|
| +// dead code eliminated.
|
| +
|
| +size_t ArgNum, Subzero_ArgNum;
|
| +CalleePtrTy Callee, Subzero_Callee;
|
| +char *Buf, *Subzero_Buf;
|
| +
|
| +const static size_t BUF_SIZE = 16;
|
| +
|
| +std::string bufAsString(const char Buf[BUF_SIZE]) {
|
| + std::ostringstream OS;
|
| + for (size_t i = 0; i < BUF_SIZE; ++i) {
|
| + if (i > 0)
|
| + OS << " ";
|
| + OS << (unsigned) Buf[i];
|
| + }
|
| + return OS.str();
|
| +}
|
| +
|
| +void testCaller(size_t &TotalTests, size_t &Passes, size_t &Failures) {
|
| + static struct {
|
| + const char *CallerName, *CalleeName;
|
| + size_t Args;
|
| + void (*Caller)(void);
|
| + void (*Subzero_Caller)(void);
|
| + CalleePtrTy Callee;
|
| + } Funcs[] = {
|
| +#define X(caller, callee, argc) \
|
| + { \
|
| + STR(caller), STR(callee), argc, &caller, &Subzero_::caller, \
|
| + reinterpret_cast<CalleePtrTy>(&callee), \
|
| + } \
|
| + ,
|
| + TEST_FUNC_TABLE
|
| +#undef X
|
| + };
|
| +
|
| + const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
|
| +
|
| + for (size_t f = 0; f < NumFuncs; ++f) {
|
| + char BufLlc[BUF_SIZE], BufSz[BUF_SIZE];
|
| + Callee = Subzero_Callee = Funcs[f].Callee;
|
| +
|
| + for (size_t i = 0; i < Funcs[f].Args; ++i) {
|
| + memset(BufLlc, 0xff, sizeof(BufLlc));
|
| + memset(BufSz, 0xff, sizeof(BufSz));
|
| +
|
| + ArgNum = Subzero_ArgNum = i;
|
| +
|
| + Buf = BufLlc;
|
| + Funcs[f].Caller();
|
| +
|
| + Buf = BufSz;
|
| + Funcs[f].Subzero_Caller();
|
| +
|
| + ++TotalTests;
|
| + if (!memcmp(BufLlc, BufSz, sizeof(BufLlc))) {
|
| + ++Passes;
|
| + } else {
|
| + ++Failures;
|
| + std::cout << "testCaller(Caller=" << Funcs[f].CallerName << ", ";
|
| + std::cout << "Callee=" << Funcs[f].CalleeName << ", ";
|
| + std::cout << "ArgNum=" << ArgNum << ")\n";
|
| + std::cout << "sz =" << bufAsString(BufSz) << "\n";
|
| + std::cout << "llc=" << bufAsString(BufLlc) << "\n";
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +void testCallee(size_t &TotalTests, size_t &Passes, size_t &Failures) {
|
| + static struct {
|
| + const char *CallerName, *CalleeName;
|
| + size_t Args;
|
| + void (*Caller)(void);
|
| + CalleePtrTy Callee, Subzero_Callee;
|
| + } Funcs[] = {
|
| +#define X(caller, callee, argc) \
|
| + { \
|
| + STR(caller), STR(callee), argc, &caller, \
|
| + reinterpret_cast<CalleePtrTy>(&callee), \
|
| + reinterpret_cast<CalleePtrTy>(&Subzero_::callee) \
|
| + } \
|
| + ,
|
| + TEST_FUNC_TABLE
|
| +#undef X
|
| + };
|
| +
|
| + const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
|
| +
|
| + for (size_t f = 0; f < NumFuncs; ++f) {
|
| + char BufLlc[BUF_SIZE], BufSz[BUF_SIZE];
|
| + Buf = BufLlc;
|
| + Subzero_Buf = BufSz;
|
| +
|
| + for (size_t i = 0; i < Funcs[f].Args; ++i) {
|
| + memset(BufLlc, 0xff, sizeof(BufLlc));
|
| + memset(BufSz, 0xff, sizeof(BufSz));
|
| +
|
| + ArgNum = Subzero_ArgNum = i;
|
| +
|
| + Callee = Funcs[f].Callee;
|
| + Funcs[f].Caller();
|
| +
|
| + Callee = Funcs[f].Subzero_Callee;
|
| + Funcs[f].Caller();
|
| +
|
| + ++TotalTests;
|
| + if (!memcmp(BufLlc, BufSz, sizeof(BufLlc))) {
|
| + ++Passes;
|
| + } else {
|
| + ++Failures;
|
| + std::cout << "testCallee(Caller=" << Funcs[f].CallerName << ", ";
|
| + std::cout << "Callee=" << Funcs[f].CalleeName << ", ";
|
| + std::cout << "ArgNum=" << ArgNum << ")\n";
|
| + std::cout << "sz =" << bufAsString(BufSz) << "\n";
|
| + std::cout << "llc=" << bufAsString(BufLlc) << "\n";
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +int main(int argc, char *argv[]) {
|
| + size_t TotalTests = 0;
|
| + size_t Passes = 0;
|
| + size_t Failures = 0;
|
| +
|
| + testCaller(TotalTests, Passes, Failures);
|
| + testCallee(TotalTests, Passes, Failures);
|
| +
|
| + std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes
|
| + << " Failures=" << Failures << "\n";
|
| +
|
| + return Failures;
|
| +}
|
|
|