1 /*
2 * Copyright (c) 2006-2018, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2010-03-22 Bernard first version
9 */
10 #include "finsh_ops.h"
11 #include "finsh_vm.h"
12
13 #define OP_BIN_BYTE(x) do {\
14 (finsh_sp - 2)->char_value = (finsh_sp - 2)->char_value x (finsh_sp - 1)->char_value; \
15 finsh_sp--; \
16 }while (0)
17
18 #define OP_BIN_WORD(x) do {\
19 (finsh_sp - 2)->short_value = (finsh_sp - 2)->short_value x (finsh_sp - 1)->short_value; \
20 finsh_sp--; \
21 }while (0)
22
23 #define OP_BIN_DWORD(x) do {\
24 (finsh_sp - 2)->long_value = (finsh_sp - 2)->long_value x (finsh_sp - 1)->long_value; \
25 finsh_sp--; \
26 }while (0)
27
28 /* --- noop --- */
OP_no_op()29 void OP_no_op()
30 {
31 /* none */
32 return ;
33 }
34
35 /* --- add --- */
OP_add_byte()36 void OP_add_byte()
37 {
38 OP_BIN_BYTE(+);
39
40 return ;
41 }
42
OP_add_word()43 void OP_add_word()
44 {
45 OP_BIN_WORD(+);
46
47 return ;
48 }
49
OP_add_dword()50 void OP_add_dword()
51 {
52 OP_BIN_DWORD(+);
53
54 return ;
55 }
56
57 /* --- sub --- */
OP_sub_byte()58 void OP_sub_byte()
59 {
60 OP_BIN_BYTE(-);
61
62 return ;
63 }
64
OP_sub_word()65 void OP_sub_word()
66 {
67 OP_BIN_WORD(-);
68
69 return ;
70 }
71
OP_sub_dword()72 void OP_sub_dword()
73 {
74 OP_BIN_DWORD(-);
75
76 return ;
77 }
78
79 /* --- div --- */
OP_div_byte()80 void OP_div_byte()
81 {
82 OP_BIN_BYTE(/);
83
84 return ;
85 }
86
OP_div_word()87 void OP_div_word()
88 {
89 OP_BIN_WORD(/);
90
91 return ;
92 }
93
OP_div_dword()94 void OP_div_dword()
95 {
96 OP_BIN_DWORD(/);
97
98 return ;
99 }
100
101 /* --- mod --- */
OP_mod_byte()102 void OP_mod_byte()
103 {
104 OP_BIN_BYTE(%);
105
106 return ;
107 }
108
OP_mod_word()109 void OP_mod_word()
110 {
111 OP_BIN_WORD(%);
112
113 return ;
114 }
115
OP_mod_dword()116 void OP_mod_dword()
117 {
118 OP_BIN_DWORD(%);
119
120 return ;
121 }
122
123 /* --- mul --- */
OP_mul_byte()124 void OP_mul_byte()
125 {
126 OP_BIN_BYTE(*);
127
128 return ;
129 }
130
OP_mul_word()131 void OP_mul_word()
132 {
133 OP_BIN_WORD(*);
134
135 return ;
136 }
137
OP_mul_dword()138 void OP_mul_dword()
139 {
140 OP_BIN_DWORD(*);
141
142 return ;
143 }
144
145 /* --- and --- */
OP_and_byte()146 void OP_and_byte()
147 {
148 OP_BIN_BYTE(&);
149
150 return ;
151 }
152
OP_and_word()153 void OP_and_word()
154 {
155 OP_BIN_WORD(&);
156
157 return ;
158 }
159
OP_and_dword()160 void OP_and_dword()
161 {
162 OP_BIN_DWORD(&);
163
164 return ;
165 }
166
167 /* --- or --- */
OP_or_byte()168 void OP_or_byte()
169 {
170 OP_BIN_BYTE(|);
171
172 return ;
173 }
174
OP_or_word()175 void OP_or_word()
176 {
177 OP_BIN_WORD(|);
178
179 return ;
180 }
181
OP_or_dword()182 void OP_or_dword()
183 {
184 OP_BIN_DWORD(|);
185
186 return ;
187 }
188
189 /* --- xor --- */
OP_xor_byte()190 void OP_xor_byte()
191 {
192 OP_BIN_BYTE(^);
193
194 return ;
195 }
196
OP_xor_word()197 void OP_xor_word()
198 {
199 OP_BIN_WORD(^);
200
201 return ;
202 }
203
OP_xor_dword()204 void OP_xor_dword()
205 {
206 OP_BIN_DWORD(^);
207
208 return ;
209 }
210
211 /* --- bw --- */
OP_bw_byte()212 void OP_bw_byte()
213 {
214 (finsh_sp - 1)->char_value = ~ ((finsh_sp - 1)->char_value);
215
216 return ;
217 }
218
OP_bw_word()219 void OP_bw_word()
220 {
221 (finsh_sp - 1)->short_value = ~ ((finsh_sp - 1)->short_value);
222
223 return ;
224 }
225
OP_bw_dword()226 void OP_bw_dword()
227 {
228 (finsh_sp - 1)->long_value = ~ ((finsh_sp - 1)->long_value);
229
230 return ;
231 }
232
233 /* --- shl --- */
OP_shl_byte()234 void OP_shl_byte()
235 {
236 OP_BIN_BYTE(<<);
237
238 return ;
239 }
240
OP_shl_word()241 void OP_shl_word()
242 {
243 OP_BIN_WORD(<<);
244
245 return ;
246 }
247
OP_shl_dword()248 void OP_shl_dword()
249 {
250 OP_BIN_DWORD(<<);
251
252 return ;
253 }
254
255 /* --- shr --- */
OP_shr_byte()256 void OP_shr_byte()
257 {
258 OP_BIN_BYTE(>>);
259
260 return ;
261 }
262
OP_shr_word()263 void OP_shr_word()
264 {
265 OP_BIN_WORD(>>);
266
267 return ;
268 }
269
OP_shr_dword()270 void OP_shr_dword()
271 {
272 OP_BIN_DWORD(>>);
273
274 return ;
275 }
276
277 /* --- ld --- */
OP_ld_byte()278 void OP_ld_byte()
279 {
280 finsh_sp->char_value = *finsh_pc;
281
282 finsh_sp++;
283 finsh_pc++;
284
285 return ;
286 }
287
OP_ld_word()288 void OP_ld_word()
289 {
290 finsh_sp->short_value = FINSH_GET16(finsh_pc);
291
292 finsh_sp ++;
293 finsh_pc += 2;
294
295 return ;
296 }
297
OP_ld_dword()298 void OP_ld_dword()
299 {
300 finsh_sp->long_value = FINSH_GET32(finsh_pc);
301
302 finsh_sp ++;
303 finsh_pc += 4;
304
305 return ;
306 }
307
OP_ld_value_byte()308 void OP_ld_value_byte()
309 {
310 char* c;
311
312 c = (char*) (FINSH_GET32(finsh_pc));
313
314 finsh_sp->char_value = *c;
315
316 finsh_sp ++;
317 finsh_pc += 4;
318
319 return;
320 }
321
OP_ld_value_byte_stack()322 void OP_ld_value_byte_stack()
323 {
324 char* c;
325
326 c = (char *)(finsh_sp - 1)->long_value;
327 (finsh_sp - 1)->char_value = *c;
328
329 return;
330 }
331
OP_ld_value_word()332 void OP_ld_value_word()
333 {
334 short* s;
335
336 s = (short*) (FINSH_GET32(finsh_pc));
337
338 finsh_sp->short_value = *s;
339
340 finsh_sp ++;
341 finsh_pc += 4;
342
343 return;
344 }
345
OP_ld_value_word_stack()346 void OP_ld_value_word_stack()
347 {
348 short* s;
349
350 s = (short *)(finsh_sp - 1)->long_value;
351 (finsh_sp - 1)->short_value = *s;
352
353 return;
354 }
355
OP_ld_value_dword()356 void OP_ld_value_dword()
357 {
358 long* l;
359
360 l = (long*) (FINSH_GET32(finsh_pc));
361
362 finsh_sp->long_value = *l;
363
364 finsh_sp ++;
365 finsh_pc += 4;
366
367 return;
368 }
369
OP_ld_value_dword_stack()370 void OP_ld_value_dword_stack()
371 {
372 long* l;
373
374 l = (long *)(finsh_sp - 1)->long_value;
375 (finsh_sp - 1)->long_value = *l;
376
377 return;
378 }
379
380 /* --- st --- */
381 /*
382 * 2006-4-16 bernard
383 * fixed the sp move bug
384 */
OP_st_byte()385 void OP_st_byte()
386 {
387 *(char*)((finsh_sp - 2)->long_value) = (finsh_sp - 1)->char_value;
388 finsh_sp --;
389
390 return ;
391 }
392
393 /*
394 * 2006-4-16 bernard
395 * fixed the sp move bug
396 */
OP_st_word()397 void OP_st_word()
398 {
399 *(short*)((finsh_sp - 2)->long_value) = (finsh_sp - 1)->short_value;
400 finsh_sp --;
401
402 return ;
403 }
404
405 /*
406 * 2006-4-16 bernard
407 * fixed the sp move bug
408 */
OP_st_dword()409 void OP_st_dword()
410 {
411 *(long*)((finsh_sp - 2)->long_value) = (finsh_sp - 1)->long_value;
412 finsh_sp --;
413
414 return ;
415 }
416
417 /* --- pop --- */
OP_pop()418 void OP_pop()
419 {
420 finsh_sp --;
421 return ;
422 }
423
424 /* --- call --- */
OP_call()425 void OP_call()
426 {
427 /* the max number of arg*/
428 unsigned long parameterv[16];
429 unsigned int parameters, i;
430
431 typedef unsigned long var_t;
432 typedef var_t (*op_func)();
433 op_func f;
434 var_t r;
435
436 parameters = *finsh_pc ++;
437
438 i = 0; finsh_sp --;
439 while (i < parameters)
440 {
441 parameterv[parameters - 1 - i] = finsh_sp->long_value;
442 finsh_sp --;
443 i++;
444 }
445
446 f = (op_func)(finsh_sp->long_value);
447 switch (parameters)
448 {
449 case 0:
450 r = f(0);
451 break;
452
453 case 1:
454 r = f(parameterv[0]);
455 break;
456
457 case 2:
458 r = f(parameterv[0], parameterv[1]);
459 break;
460
461 case 3:
462 r = f(parameterv[0], parameterv[1], parameterv[2]);
463 break;
464
465 case 4:
466 r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3]);
467 break;
468
469 case 5:
470 r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
471 parameterv[4]);
472 break;
473
474 case 6:
475 r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
476 parameterv[4], parameterv[5]);
477 break;
478
479 case 7:
480 r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
481 parameterv[4], parameterv[5], parameterv[6]);
482 break;
483
484 case 8:
485 r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
486 parameterv[4], parameterv[5], parameterv[6], parameterv[7]);
487 break;
488
489 case 9:
490 r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
491 parameterv[4], parameterv[5], parameterv[6], parameterv[7],
492 parameterv[8]);
493 break;
494
495 case 10:
496 r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
497 parameterv[4], parameterv[5], parameterv[6], parameterv[7],
498 parameterv[8], parameterv[9]);
499 break;
500
501 case 11:
502 r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
503 parameterv[4], parameterv[5], parameterv[6], parameterv[7],
504 parameterv[8], parameterv[9], parameterv[10]);
505 break;
506
507 case 12:
508 r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
509 parameterv[4], parameterv[5], parameterv[6], parameterv[7],
510 parameterv[8], parameterv[9], parameterv[10], parameterv[11]);
511 break;
512
513 case 13:
514 r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
515 parameterv[4], parameterv[5], parameterv[6], parameterv[7],
516 parameterv[8], parameterv[9], parameterv[10], parameterv[11],
517 parameterv[12]);
518 break;
519
520 case 14:
521 r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
522 parameterv[4], parameterv[5], parameterv[6], parameterv[7],
523 parameterv[8], parameterv[9], parameterv[10], parameterv[11],
524 parameterv[12], parameterv[13]);
525 break;
526
527 case 15:
528 r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
529 parameterv[4], parameterv[5], parameterv[6], parameterv[7],
530 parameterv[8], parameterv[9], parameterv[10], parameterv[11],
531 parameterv[12], parameterv[13], parameterv[14]);
532 break;
533
534 case 16:
535 r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
536 parameterv[4], parameterv[5], parameterv[6], parameterv[7],
537 parameterv[8], parameterv[9], parameterv[10], parameterv[11],
538 parameterv[12], parameterv[13], parameterv[14], parameterv[15]);
539 break;
540
541 default:
542 r = 0;
543 break;
544 }
545
546 finsh_sp->long_value = r;
547 finsh_sp ++;
548
549 return ;
550 }
551
552 const op_func op_table[] =
553 {
554 /* 00 */ OP_no_op,
555 /* 01 */ OP_add_byte,
556 /* 02 */ OP_add_word,
557 /* 03 */ OP_add_dword,
558 /* 04 */ OP_sub_byte,
559 /* 05 */ OP_sub_word,
560 /* 06 */ OP_sub_dword,
561 /* 07 */ OP_div_byte,
562 /* 08 */ OP_div_word,
563 /* 09 */ OP_div_dword,
564 /* 10 */ OP_mod_byte,
565 /* 11 */ OP_mod_word,
566 /* 12 */ OP_mod_dword,
567 /* 13 */ OP_mul_byte,
568 /* 14 */ OP_mul_word,
569 /* 15 */ OP_mul_dword,
570 /* 16 */ OP_and_byte,
571 /* 17 */ OP_and_word,
572 /* 18 */ OP_and_dword,
573 /* 19 */ OP_or_byte,
574 /* 20 */ OP_or_word,
575 /* 21 */ OP_or_dword,
576 /* 22 */ OP_xor_byte,
577 /* 23 */ OP_xor_word,
578 /* 24 */ OP_xor_dword,
579 /* 25 */ OP_bw_byte,
580 /* 26 */ OP_bw_word,
581 /* 27 */ OP_bw_dword,
582 /* 28 */ OP_shl_byte,
583 /* 29 */ OP_shl_word,
584 /* 30 */ OP_shl_dword,
585 /* 31 */ OP_shr_byte,
586 /* 32 */ OP_shr_word,
587 /* 33 */ OP_shr_dword,
588 /* 34 */ OP_ld_byte,
589 /* 35 */ OP_ld_word,
590 /* 36 */ OP_ld_dword,
591 /* 37 */ OP_ld_value_byte,
592 /* 38 */ OP_ld_value_word,
593 /* 39 */ OP_ld_value_dword,
594 /* 40 */ OP_st_byte,
595 /* 41 */ OP_st_word,
596 /* 42 */ OP_st_dword,
597 /* 43 */ OP_pop,
598 /* 44 */ OP_call,
599 /* 45 */ OP_ld_value_byte_stack,
600 /* 46 */ OP_ld_value_word_stack,
601 /* 47 */ OP_ld_value_dword_stack,
602 NULL
603 };
604