1 /*
2 
3  Package: dyncall
4  Library: test
5  File: test/suite_x86win32fast/main.cc
6  Description:
7  License:
8 
9    Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>,
10                            Tassilo Philipp <tphilipp@potion-studios.com>
11 
12    Permission to use, copy, modify, and distribute this software for any
13    purpose with or without fee is hereby granted, provided that the above
14    copyright notice and this permission notice appear in all copies.
15 
16    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
17    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
19    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 
24 */
25 
26 
27 
28 #include "../../dyncall/dyncall.h"
29 #include "config.h"
30 #include "../../dyncall/dyncall_value.h"
31 #include "../../dyncall/dyncall_macros.h"
32 #include <math.h>
33 #include "../common/platformInit.h"
34 #include "../common/platformInit.c" /* Impl. for functions only used in this translation unit */
35 
36 
37 int   getId();
38 DCpointer getFunc(int x);
39 DCValue* getArg(int pos);
40 
41 
42 typedef double precise;
43 
44 
45 DCbool     valueBool[NARGS];
46 DCshort    valueShort[NARGS];
47 DCchar     valueChar[NARGS];
48 DCint      valueInt[NARGS];
49 DClonglong valueLongLong[NARGS];
50 DCdouble   valueDouble[NARGS];
51 DCpointer  valuePointer[NARGS];
52 DCfloat    valueFloat[NARGS];
53 
54 
equals(int select,int pos,void * data)55 bool equals(int select, int pos, void* data)
56 {
57   switch(select)
58   {
59     case 0: return ( getArg(pos)->B == valueBool[pos] ); break;
60     case 1: return ( getArg(pos)->i == valueInt[pos] ); break;
61     case 2: return ( getArg(pos)->l == valueLongLong[pos] ); break;
62     case 3: return ( getArg(pos)->d == valueDouble[pos] ); break;
63     case 4: return ( getArg(pos)->p == valuePointer[pos] ); break;
64     case 5: return ( getArg(pos)->f == valueFloat[pos] ); break;
65   }
66   return false;
67 }
68 
69 
70 void clearValues();
71 
72 
init()73 void init()
74 {
75   for (int i = 0 ; i < NARGS ; ++i ) {
76 
77     valueBool[i] = DCbool( (i % 1) ? DC_TRUE : DC_FALSE );
78     valueInt[i] = DCint(i);
79     valueLongLong[i] = DClonglong(i);
80     valueDouble[i] = DCdouble(i);
81     valuePointer[i] = DCpointer(i);
82     valueFloat[i] = DCfloat(i);
83   }
84 }
85 
86 
push(DCCallVM * pCall,int select,int pos)87 void push(DCCallVM* pCall, int select, int pos)
88 {
89   switch(select)
90   {
91     case 0: dcArgBool( pCall, valueBool[pos] ); break;
92     case 1: dcArgInt( pCall, valueInt[pos] ); break;
93     case 2: dcArgLongLong( pCall, valueLongLong[pos] ); break;
94     case 3: dcArgDouble( pCall, valueDouble[pos] ); break;
95     case 4: dcArgPointer( pCall, valuePointer[pos] ); break;
96     case 5: dcArgFloat( pCall, valueFloat[pos] ); break;
97   }
98 }
99 
100 
101 #define test(x) if (!(x)) return false
102 
103 
test_case(int x)104 bool test_case(int x)
105 {
106   clearValues();
107 
108   DCCallVM* pCall = dcNewCallVM(4096);
109 #ifdef DC__C_GNU
110   dcMode(pCall, DC_CALL_C_X86_WIN32_FAST_GNU);
111 #else
112   dcMode(pCall, DC_CALL_C_X86_WIN32_FAST_MS);
113 #endif
114   dcReset(pCall);
115 
116   int y = x;
117   int selects[NARGS] = { 0, };
118   int pos = 0;
119   for(pos = 0;y>0;++pos)
120   {
121     int select = (y-1) % NTYPES;
122     selects[pos] = select;
123     push(pCall,select,pos);
124     y = (y-1) / NTYPES;
125   }
126   dcCallVoid(pCall,getFunc(x));
127 
128   test( getId() == x );
129 
130   for(int i = 0;i<pos;++i) {
131     test( equals( selects[i], i, getArg(i) ) );
132   }
133 
134   dcFree(pCall);
135   return true;
136 }
137 
138 
powerfact(int x,int n)139 int powerfact(int x, int n)
140 {
141   if (n==0) return 0;
142   return static_cast<int>( pow((double)x,n)+powerfact(x,n-1) );
143 }
144 
145 #include <stdio.h>
146 #include <stdlib.h>
147 
run_range(int from,int to)148 bool run_range(int from, int to)
149 {
150   bool tr = true;
151   for (int i = from ; i < to ; ++i ) {
152     printf("%d:",i);
153     bool r = test_case(i);
154     printf("%d\n", r);
155     tr &= r;
156   }
157   return tr;
158 }
159 
160 extern "C" {
161 
main(int argc,char * argv[])162 int main(int argc, char* argv[])
163 {
164   dcTest_initPlatform();
165 
166   bool success = false;
167   init();
168   if (argc == 2) {
169     int index = atoi(argv[1]);
170     success = run_range( index, index+1 );
171   } else if (argc == 3) {
172     int from = atoi(argv[1]);
173     int to   = atoi(argv[2])+1;
174     success = run_range(from,to);
175   } else {
176     int ncalls = powerfact(NTYPES,NARGS)+1;
177     success = run_range(0,ncalls);
178   }
179 
180   printf("result: suite_x86win32fast: %d\n", success);
181 
182   dcTest_deInitPlatform();
183 
184   return !success;
185 }
186 
187 }  // extern "C"
188 
189