Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_Parser_Exe_Body.H
Go to the documentation of this file.
1// Body of parser_exe_eval and parser_exe_eval_threaded. Included inside
2// those functions with `p` (bytecode) and `x` (variables) in scope.
3// AMREX_PARSER_THREADED_BODY selects switch (0) or threaded (1) dispatch.
4
5 // The top of the evaluation stack is kept in `top`. A push first
6 // spills `top` into pdata[psize++], so stack entry k lives in
7 // pdata[k+1] (pdata[0] holds an unused value) and psize equals the
8 // logical stack depth. Local variables are stack entries. They are
9 // always spilled before they are read, because every statement
10 // following an assignment starts with a push.
11 double pdata[AMREX_PARSER_STACK_SIZE];
12 int psize = 0;
13 double top = 0.0;
14
15#if AMREX_PARSER_THREADED_BODY
16 // Threaded dispatch: each instruction jumps directly to the next one.
17 static void* const dispatch_table[] = {
18#define AMREX_PARSER_EXE_LABEL(name) &&L_PARSER_EXE_##name,
19 AMREX_PARSER_EXE_TYPES(AMREX_PARSER_EXE_LABEL)
20#undef AMREX_PARSER_EXE_LABEL
21 };
22#define AMREX_PARSER_CASE(X) L_##X:
23#define AMREX_PARSER_NEXT goto *dispatch_table[*((parser_exe_t const*)p)]
25 {
26 AMREX_PARSER_CASE(PARSER_EXE_NULL)
27 {
28 return top;
29 }
30#else
31#define AMREX_PARSER_CASE(X) case X:
32#define AMREX_PARSER_NEXT break
33 while (*((parser_exe_t*)p) != PARSER_EXE_NULL) { // NOLINT
34 switch (*((parser_exe_t*)p))
35 {
36#endif
37 AMREX_PARSER_CASE(PARSER_EXE_NUMBER)
38 {
39 pdata[psize++] = top; // spill before reading locals
40 top = ((ParserExeNumber*)p)->v;
41 p += sizeof(ParserExeNumber);
43 }
44 AMREX_PARSER_CASE(PARSER_EXE_SYMBOL)
45 {
46 pdata[psize++] = top; // spill before reading locals
47 int i = ((ParserExeSymbol*)p)->i;
48 top = AMREX_PARSER_GET_DATA(i);
49 p += sizeof(ParserExeSymbol);
51 }
52 AMREX_PARSER_CASE(PARSER_EXE_ADD)
53 {
54 double a = pdata[--psize]; // NOLINT
55 top = a + top;
56 p += sizeof(ParserExeADD);
58 }
59 AMREX_PARSER_CASE(PARSER_EXE_SUB_F)
60 {
61 double a = pdata[--psize]; // NOLINT
62 top = a - top;
63 p += sizeof(ParserExeSUB_F);
65 }
66 AMREX_PARSER_CASE(PARSER_EXE_SUB_B)
67 {
68 double a = pdata[--psize]; // NOLINT
69 top = top - a;
70 p += sizeof(ParserExeSUB_B);
72 }
73 AMREX_PARSER_CASE(PARSER_EXE_MUL)
74 {
75 double a = pdata[--psize]; // NOLINT
76 top = a * top;
77 p += sizeof(ParserExeMUL);
79 }
80 AMREX_PARSER_CASE(PARSER_EXE_DIV_F)
81 {
82 double a = pdata[--psize]; // NOLINT
83 top = a / top;
84 p += sizeof(ParserExeDIV_F);
86 }
87 AMREX_PARSER_CASE(PARSER_EXE_DIV_B)
88 {
89 double a = pdata[--psize]; // NOLINT
90 top = top / a;
91 p += sizeof(ParserExeDIV_B);
93 }
94 AMREX_PARSER_CASE(PARSER_EXE_F1)
95 {
96 top = parser_call_f1(((ParserExeF1*)p)->ftype, top);
97 p += sizeof(ParserExeF1);
99 }
100 AMREX_PARSER_CASE(PARSER_EXE_F2_F)
101 {
102 double a = pdata[--psize]; // NOLINT
103 top = parser_call_f2(((ParserExeF2_F*)p)->ftype, a, top);
104 p += sizeof(ParserExeF2_F);
106 }
107 AMREX_PARSER_CASE(PARSER_EXE_F2_B)
108 {
109 double a = pdata[--psize]; // NOLINT
110 top = parser_call_f2(((ParserExeF2_B*)p)->ftype, top, a);
111 p += sizeof(ParserExeF2_B);
113 }
114 AMREX_PARSER_CASE(PARSER_EXE_ADD_VP)
115 {
116 pdata[psize++] = top; // spill before reading locals
117 int i = ((ParserExeADD_VP*)p)->i;
118 double d = AMREX_PARSER_GET_DATA(i);
119 top = ((ParserExeADD_VP*)p)->v + d;
120 p += sizeof(ParserExeADD_VP);
122 }
123 AMREX_PARSER_CASE(PARSER_EXE_SUB_VP)
124 {
125 pdata[psize++] = top; // spill before reading locals
126 int i = ((ParserExeSUB_VP*)p)->i;
127 double d = AMREX_PARSER_GET_DATA(i);
128 top = ((ParserExeSUB_VP*)p)->v - d;
129 p += sizeof(ParserExeSUB_VP);
131 }
132 AMREX_PARSER_CASE(PARSER_EXE_MUL_VP)
133 {
134 pdata[psize++] = top; // spill before reading locals
135 int i = ((ParserExeMUL_VP*)p)->i;
136 double d = AMREX_PARSER_GET_DATA(i);
137 top = ((ParserExeMUL_VP*)p)->v * d;
138 p += sizeof(ParserExeMUL_VP);
140 }
141 AMREX_PARSER_CASE(PARSER_EXE_DIV_VP)
142 {
143 pdata[psize++] = top; // spill before reading locals
144 int i = ((ParserExeDIV_VP*)p)->i;
145 double d = AMREX_PARSER_GET_DATA(i);
146 top = ((ParserExeDIV_VP*)p)->v / d;
147 p += sizeof(ParserExeDIV_VP);
149 }
150 AMREX_PARSER_CASE(PARSER_EXE_ADD_PP)
151 {
152 pdata[psize++] = top; // spill before reading locals
153 int i = ((ParserExeADD_PP*)p)->i1;
154 double d1 = AMREX_PARSER_GET_DATA(i);
155 i = ((ParserExeADD_PP*)p)->i2;
156 double d2 = AMREX_PARSER_GET_DATA(i);
157 top = d1+d2;
158 p += sizeof(ParserExeADD_PP);
160 }
161 AMREX_PARSER_CASE(PARSER_EXE_SUB_PP)
162 {
163 pdata[psize++] = top; // spill before reading locals
164 int i = ((ParserExeSUB_PP*)p)->i1;
165 double d1 = AMREX_PARSER_GET_DATA(i);
166 i = ((ParserExeSUB_PP*)p)->i2;
167 double d2 = AMREX_PARSER_GET_DATA(i);
168 top = d1-d2;
169 p += sizeof(ParserExeSUB_PP);
171 }
172 AMREX_PARSER_CASE(PARSER_EXE_MUL_PP)
173 {
174 pdata[psize++] = top; // spill before reading locals
175 int i = ((ParserExeMUL_PP*)p)->i1;
176 double d1 = AMREX_PARSER_GET_DATA(i);
177 i = ((ParserExeMUL_PP*)p)->i2;
178 double d2 = AMREX_PARSER_GET_DATA(i);
179 top = d1*d2;
180 p += sizeof(ParserExeMUL_PP);
182 }
183 AMREX_PARSER_CASE(PARSER_EXE_DIV_PP)
184 {
185 pdata[psize++] = top; // spill before reading locals
186 int i = ((ParserExeDIV_PP*)p)->i1;
187 double d1 = AMREX_PARSER_GET_DATA(i);
188 i = ((ParserExeDIV_PP*)p)->i2;
189 double d2 = AMREX_PARSER_GET_DATA(i);
190 top = d1/d2;
191 p += sizeof(ParserExeDIV_PP);
193 }
194 AMREX_PARSER_CASE(PARSER_EXE_ADD_VN)
195 {
196 top += ((ParserExeADD_VN*)p)->v;
197 p += sizeof(ParserExeADD_VN);
199 }
200 AMREX_PARSER_CASE(PARSER_EXE_SUB_VN)
201 {
202 top = ((ParserExeSUB_VN*)p)->v - top;
203 p += sizeof(ParserExeSUB_VN);
205 }
206 AMREX_PARSER_CASE(PARSER_EXE_MUL_VN)
207 {
208 top *= ((ParserExeMUL_VN*)p)->v;
209 p += sizeof(ParserExeMUL_VN);
211 }
212 AMREX_PARSER_CASE(PARSER_EXE_DIV_VN)
213 {
214 top = ((ParserExeDIV_VN*)p)->v / top;
215 p += sizeof(ParserExeDIV_VN);
217 }
218 AMREX_PARSER_CASE(PARSER_EXE_ADD_PN)
219 {
220 int i = ((ParserExeADD_PN*)p)->i;
221 double d = AMREX_PARSER_GET_DATA(i);
222 top += d;
223 p += sizeof(ParserExeADD_PN);
225 }
226 AMREX_PARSER_CASE(PARSER_EXE_SUB_PN)
227 {
228 int i = ((ParserExeSUB_PN*)p)->i;
229 double d = AMREX_PARSER_GET_DATA(i);
230 if (((ParserExeSUB_PN*)p)->reverse) {
231 top = top - d;
232 } else {
233 top = d - top;
234 }
235 p += sizeof(ParserExeSUB_PN);
237 }
238 AMREX_PARSER_CASE(PARSER_EXE_MUL_PN)
239 {
240 int i = ((ParserExeMUL_PN*)p)->i;
241 double d = AMREX_PARSER_GET_DATA(i);
242 top *= d;
243 p += sizeof(ParserExeMUL_PN);
245 }
246 AMREX_PARSER_CASE(PARSER_EXE_DIV_PN)
247 {
248 int i = ((ParserExeDIV_PN*)p)->i;
249 double d = AMREX_PARSER_GET_DATA(i);
250 if (((ParserExeDIV_PN*)p)->reverse) {
251 top = top / d;
252 } else {
253 top = d / top;
254 }
255 p += sizeof(ParserExeDIV_PN);
257 }
258 AMREX_PARSER_CASE(PARSER_EXE_SQUARE)
259 {
260 top *= top;
261 p += sizeof(ParserExeSquare);
263 }
264 AMREX_PARSER_CASE(PARSER_EXE_POWI)
265 {
266 top = parser_math_powi(top, ((ParserExePOWI*)p)->i);
267 p += sizeof(ParserExePOWI);
269 }
270 AMREX_PARSER_CASE(PARSER_EXE_FMA_VPV)
271 {
272 pdata[psize++] = top; // spill before reading locals
273 int i = ((ParserExeFMA_VPV*)p)->i;
274 double d = AMREX_PARSER_GET_DATA(i);
275 top = ((ParserExeFMA_VPV*)p)->a * d + ((ParserExeFMA_VPV*)p)->b;
276 p += sizeof(ParserExeFMA_VPV);
278 }
279 AMREX_PARSER_CASE(PARSER_EXE_IF)
280 {
281 double cond = top;
282 top = pdata[--psize]; // NOLINT
283 if (cond == 0.0) { // false branch
284 p += ((ParserExeIF*)p)->offset;
285 }
286 p += sizeof(ParserExeIF);
288 }
289 AMREX_PARSER_CASE(PARSER_EXE_JUMP)
290 {
291 int offset = ((ParserExeJUMP*)p)->offset;
292 p += sizeof(ParserExeJUMP) + offset;
294 }
295 AMREX_PARSER_CASE(PARSER_EXE_USER_FN)
296 {
297 psize -= ((ParserExeUserFn*)p)->argc - 1;
298 top = parser_detail::call_user_fn((ParserExeUserFn*)p, pdata+psize, top);
299 p += sizeof(ParserExeUserFn);
301 }
302 AMREX_PARSER_CASE(PARSER_EXE_F1_P)
303 {
304 pdata[psize++] = top; // spill before reading locals
305 int i = ((ParserExeF1_P*)p)->i;
306 double d = AMREX_PARSER_GET_DATA(i);
307 top = parser_call_f1(((ParserExeF1_P*)p)->ftype, d);
308 p += sizeof(ParserExeF1_P);
310 }
311 AMREX_PARSER_CASE(PARSER_EXE_SQUARE_P)
312 {
313 pdata[psize++] = top; // spill before reading locals
314 int i = ((ParserExeSquare_P*)p)->i;
315 double d = AMREX_PARSER_GET_DATA(i);
316 top = d*d;
317 p += sizeof(ParserExeSquare_P);
319 }
320 AMREX_PARSER_CASE(PARSER_EXE_POWI_P)
321 {
322 pdata[psize++] = top; // spill before reading locals
323 int i = ((ParserExePOWI_P*)p)->i;
324 double d = AMREX_PARSER_GET_DATA(i);
325 top = parser_math_powi(d, ((ParserExePOWI_P*)p)->n);
326 p += sizeof(ParserExePOWI_P);
328 }
329 AMREX_PARSER_CASE(PARSER_EXE_F2_PP)
330 {
331 pdata[psize++] = top; // spill before reading locals
332 int i = ((ParserExeF2_PP*)p)->i1;
333 double d1 = AMREX_PARSER_GET_DATA(i);
334 i = ((ParserExeF2_PP*)p)->i2;
335 double d2 = AMREX_PARSER_GET_DATA(i);
336 top = parser_call_f2(((ParserExeF2_PP*)p)->ftype, d1, d2);
337 p += sizeof(ParserExeF2_PP);
339 }
340 AMREX_PARSER_CASE(PARSER_EXE_F2_PV)
341 {
342 pdata[psize++] = top; // spill before reading locals
343 int i = ((ParserExeF2_PV*)p)->i;
344 double d = AMREX_PARSER_GET_DATA(i);
345 top = parser_call_f2(((ParserExeF2_PV*)p)->ftype, d, ((ParserExeF2_PV*)p)->v);
346 p += sizeof(ParserExeF2_PV);
348 }
349 AMREX_PARSER_CASE(PARSER_EXE_F2_VP)
350 {
351 pdata[psize++] = top; // spill before reading locals
352 int i = ((ParserExeF2_VP*)p)->i;
353 double d = AMREX_PARSER_GET_DATA(i);
354 top = parser_call_f2(((ParserExeF2_VP*)p)->ftype, ((ParserExeF2_VP*)p)->v, d);
355 p += sizeof(ParserExeF2_VP);
357 }
358#if AMREX_PARSER_THREADED_BODY
359 }
360#else
361 default:
362 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(false,"parser_exe_eval: unknown node type");
363 }
364 }
365 return top;
366#endif
#define AMREX_ALWAYS_ASSERT_WITH_MESSAGE(EX, MSG)
Definition AMReX_BLassert.H:49
Array4< int const > offset
Definition AMReX_HypreMLABecLap.cpp:1139
int psize
Definition AMReX_Parser_Exe_Body.H:12
double top
Definition AMReX_Parser_Exe_Body.H:13
#define AMREX_PARSER_NEXT
Definition AMReX_Parser_Exe_Body.H:32
while parser_exe_t p
Definition AMReX_Parser_Exe_Body.H:33
#define AMREX_PARSER_CASE(X)
Definition AMReX_Parser_Exe_Body.H:31
double pdata[AMREX_PARSER_STACK_SIZE]
Definition AMReX_Parser_Exe_Body.H:11