• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- subzero/crosstest/test_calling_conv_main.cpp - Driver for tests ----===//
2 //
3 //                        The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the driver for cross testing the compatibility of
11 // calling conventions.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 /* crosstest.py --test=test_calling_conv.cpp               \
16    --driver=test_calling_conv_main.cpp --prefix=Subzero_   \
17    --output=test_calling_conv */
18 
19 #include <cstring>
20 #include <iostream>
21 #include <sstream>
22 
23 #include "test_calling_conv.h"
24 
25 namespace Subzero_ {
26 #include "test_calling_conv.h"
27 }
28 
29 // The crosstest code consists of caller / callee function pairs.
30 //
31 // The caller function initializes a list of arguments and calls the
32 // function located at Callee.
33 //
34 // The callee function writes the argument numbered ArgNum into the
35 // location pointed to by Buf.
36 //
37 // testCaller() tests that caller functions, as compiled by Subzero and
38 // llc, pass arguments to the callee in the same way.  The Caller() and
39 // Subzero_Caller() functions both call the same callee (which has been
40 // compiled by llc).  The result in the global buffer is compared to
41 // check that it is the same value after the calls by both callers.
42 //
43 // testCallee() runs the same kind of test, except that the functions
44 // Callee() and Subzero_Callee() are being tested to ensure that both
45 // functions receive arguments from the caller in the same way.  The
46 // caller is compiled by llc.
47 
48 size_t ArgNum;
49 CalleePtrTy Callee;
50 char *Buf;
51 
52 const static size_t BUF_SIZE = 16;
53 
bufAsString(const char Buf[BUF_SIZE])54 std::string bufAsString(const char Buf[BUF_SIZE]) {
55   std::ostringstream OS;
56   for (size_t i = 0; i < BUF_SIZE; ++i) {
57     if (i > 0)
58       OS << " ";
59     OS << (unsigned)Buf[i];
60   }
61   return OS.str();
62 }
63 
testCaller(size_t & TotalTests,size_t & Passes,size_t & Failures)64 void testCaller(size_t &TotalTests, size_t &Passes, size_t &Failures) {
65   static struct {
66     const char *CallerName, *CalleeName;
67     size_t Args;
68     void (*Caller)(void);
69     void (*Subzero_Caller)(void);
70     CalleePtrTy Callee;
71   } Funcs[] = {
72 #ifdef MIPS32
73 #define X(caller, callee, argc)                                                \
74   {                                                                            \
75       STR(caller),                                                             \
76       STR(callee),                                                             \
77       argc,                                                                    \
78       &caller,                                                                 \
79       &Subzero_::caller,                                                       \
80       reinterpret_cast<CalleePtrTy>(&Subzero_::callee),                        \
81   },
82       TEST_FUNC_TABLE
83 #undef X
84 #else
85 #define X(caller, callee, argc)                                                \
86   {                                                                            \
87       STR(caller), STR(callee),       argc,                                    \
88       &caller,     &Subzero_::caller, reinterpret_cast<CalleePtrTy>(&callee),  \
89   },
90       TEST_FUNC_TABLE
91 #undef X
92 #endif
93   };
94 
95   const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
96 
97   for (size_t f = 0; f < NumFuncs; ++f) {
98     char BufLlc[BUF_SIZE], BufSz[BUF_SIZE];
99     Callee = Funcs[f].Callee;
100 
101     for (size_t i = 0; i < Funcs[f].Args; ++i) {
102       memset(BufLlc, 0xff, sizeof(BufLlc));
103       memset(BufSz, 0xff, sizeof(BufSz));
104 
105       ArgNum = i;
106 
107       Buf = BufLlc;
108       Funcs[f].Caller();
109 
110       Buf = BufSz;
111       Funcs[f].Subzero_Caller();
112 
113       ++TotalTests;
114       if (!memcmp(BufLlc, BufSz, sizeof(BufLlc))) {
115         ++Passes;
116       } else {
117         ++Failures;
118         std::cout << "testCaller(Caller=" << Funcs[f].CallerName
119                   << ", Callee=" << Funcs[f].CalleeName << ", ArgNum=" << ArgNum
120                   << ")\nsz =" << bufAsString(BufSz)
121                   << "\nllc=" << bufAsString(BufLlc) << "\n";
122       }
123     }
124   }
125 }
126 
testCallee(size_t & TotalTests,size_t & Passes,size_t & Failures)127 void testCallee(size_t &TotalTests, size_t &Passes, size_t &Failures) {
128   static struct {
129     const char *CallerName, *CalleeName;
130     size_t Args;
131     void (*Caller)(void);
132     CalleePtrTy Callee, Subzero_Callee;
133   } Funcs[] = {
134 #define X(caller, callee, argc)                                                \
135   {STR(caller),                                                                \
136    STR(callee),                                                                \
137    argc,                                                                       \
138    &caller,                                                                    \
139    reinterpret_cast<CalleePtrTy>(&callee),                                     \
140    reinterpret_cast<CalleePtrTy>(&Subzero_::callee)},
141       TEST_FUNC_TABLE
142 #undef X
143   };
144 
145   const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
146 
147   for (size_t f = 0; f < NumFuncs; ++f) {
148     char BufLlc[BUF_SIZE], BufSz[BUF_SIZE];
149 
150     for (size_t i = 0; i < Funcs[f].Args; ++i) {
151       memset(BufLlc, 0xff, sizeof(BufLlc));
152       memset(BufSz, 0xff, sizeof(BufSz));
153 
154       ArgNum = i;
155 
156       Buf = BufLlc;
157       Callee = Funcs[f].Callee;
158       Funcs[f].Caller();
159 
160       Buf = BufSz;
161       Callee = Funcs[f].Subzero_Callee;
162       Funcs[f].Caller();
163 
164       ++TotalTests;
165       if (!memcmp(BufLlc, BufSz, sizeof(BufLlc))) {
166         ++Passes;
167       } else {
168         ++Failures;
169         std::cout << "testCallee(Caller=" << Funcs[f].CallerName
170                   << ", Callee=" << Funcs[f].CalleeName << ", ArgNum=" << ArgNum
171                   << ")\nsz =" << bufAsString(BufSz)
172                   << "\nllc=" << bufAsString(BufLlc) << "\n";
173       }
174     }
175   }
176 }
177 
main(int argc,char * argv[])178 int main(int argc, char *argv[]) {
179   size_t TotalTests = 0;
180   size_t Passes = 0;
181   size_t Failures = 0;
182 
183   testCaller(TotalTests, Passes, Failures);
184   testCallee(TotalTests, Passes, Failures);
185 
186   std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes
187             << " Failures=" << Failures << "\n";
188 
189   return Failures;
190 }
191