finsh_ops.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  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. #define OP_BIN_BYTE(x) do {\
  13. (finsh_sp - 2)->char_value = (finsh_sp - 2)->char_value x (finsh_sp - 1)->char_value; \
  14. finsh_sp--; \
  15. }while (0)
  16. #define OP_BIN_WORD(x) do {\
  17. (finsh_sp - 2)->short_value = (finsh_sp - 2)->short_value x (finsh_sp - 1)->short_value; \
  18. finsh_sp--; \
  19. }while (0)
  20. #define OP_BIN_DWORD(x) do {\
  21. (finsh_sp - 2)->long_value = (finsh_sp - 2)->long_value x (finsh_sp - 1)->long_value; \
  22. finsh_sp--; \
  23. }while (0)
  24. /* --- noop --- */
  25. void OP_no_op()
  26. {
  27. /* none */
  28. return ;
  29. }
  30. /* --- add --- */
  31. void OP_add_byte()
  32. {
  33. OP_BIN_BYTE(+);
  34. return ;
  35. }
  36. void OP_add_word()
  37. {
  38. OP_BIN_WORD(+);
  39. return ;
  40. }
  41. void OP_add_dword()
  42. {
  43. OP_BIN_DWORD(+);
  44. return ;
  45. }
  46. /* --- sub --- */
  47. void OP_sub_byte()
  48. {
  49. OP_BIN_BYTE(-);
  50. return ;
  51. }
  52. void OP_sub_word()
  53. {
  54. OP_BIN_WORD(-);
  55. return ;
  56. }
  57. void OP_sub_dword()
  58. {
  59. OP_BIN_DWORD(-);
  60. return ;
  61. }
  62. /* --- div --- */
  63. void OP_div_byte()
  64. {
  65. OP_BIN_BYTE(/);
  66. return ;
  67. }
  68. void OP_div_word()
  69. {
  70. OP_BIN_WORD(/);
  71. return ;
  72. }
  73. void OP_div_dword()
  74. {
  75. OP_BIN_DWORD(/);
  76. return ;
  77. }
  78. /* --- mod --- */
  79. void OP_mod_byte()
  80. {
  81. OP_BIN_BYTE(%);
  82. return ;
  83. }
  84. void OP_mod_word()
  85. {
  86. OP_BIN_WORD(%);
  87. return ;
  88. }
  89. void OP_mod_dword()
  90. {
  91. OP_BIN_DWORD(%);
  92. return ;
  93. }
  94. /* --- mul --- */
  95. void OP_mul_byte()
  96. {
  97. OP_BIN_BYTE(*);
  98. return ;
  99. }
  100. void OP_mul_word()
  101. {
  102. OP_BIN_WORD(*);
  103. return ;
  104. }
  105. void OP_mul_dword()
  106. {
  107. OP_BIN_DWORD(*);
  108. return ;
  109. }
  110. /* --- and --- */
  111. void OP_and_byte()
  112. {
  113. OP_BIN_BYTE(&);
  114. return ;
  115. }
  116. void OP_and_word()
  117. {
  118. OP_BIN_WORD(&);
  119. return ;
  120. }
  121. void OP_and_dword()
  122. {
  123. OP_BIN_DWORD(&);
  124. return ;
  125. }
  126. /* --- or --- */
  127. void OP_or_byte()
  128. {
  129. OP_BIN_BYTE(|);
  130. return ;
  131. }
  132. void OP_or_word()
  133. {
  134. OP_BIN_WORD(|);
  135. return ;
  136. }
  137. void OP_or_dword()
  138. {
  139. OP_BIN_DWORD(|);
  140. return ;
  141. }
  142. /* --- xor --- */
  143. void OP_xor_byte()
  144. {
  145. OP_BIN_BYTE(^);
  146. return ;
  147. }
  148. void OP_xor_word()
  149. {
  150. OP_BIN_WORD(^);
  151. return ;
  152. }
  153. void OP_xor_dword()
  154. {
  155. OP_BIN_DWORD(^);
  156. return ;
  157. }
  158. /* --- bw --- */
  159. void OP_bw_byte()
  160. {
  161. (finsh_sp - 1)->char_value = ~ ((finsh_sp - 1)->char_value);
  162. return ;
  163. }
  164. void OP_bw_word()
  165. {
  166. (finsh_sp - 1)->short_value = ~ ((finsh_sp - 1)->short_value);
  167. return ;
  168. }
  169. void OP_bw_dword()
  170. {
  171. (finsh_sp - 1)->long_value = ~ ((finsh_sp - 1)->long_value);
  172. return ;
  173. }
  174. /* --- shl --- */
  175. void OP_shl_byte()
  176. {
  177. OP_BIN_BYTE(<<);
  178. return ;
  179. }
  180. void OP_shl_word()
  181. {
  182. OP_BIN_WORD(<<);
  183. return ;
  184. }
  185. void OP_shl_dword()
  186. {
  187. OP_BIN_DWORD(<<);
  188. return ;
  189. }
  190. /* --- shr --- */
  191. void OP_shr_byte()
  192. {
  193. OP_BIN_BYTE(>>);
  194. return ;
  195. }
  196. void OP_shr_word()
  197. {
  198. OP_BIN_WORD(>>);
  199. return ;
  200. }
  201. void OP_shr_dword()
  202. {
  203. OP_BIN_DWORD(>>);
  204. return ;
  205. }
  206. /* --- ld --- */
  207. void OP_ld_byte()
  208. {
  209. finsh_sp->char_value = *finsh_pc;
  210. finsh_sp++;
  211. finsh_pc++;
  212. return ;
  213. }
  214. void OP_ld_word()
  215. {
  216. finsh_sp->short_value = FINSH_GET16(finsh_pc);
  217. finsh_sp ++;
  218. finsh_pc += 2;
  219. return ;
  220. }
  221. void OP_ld_dword()
  222. {
  223. finsh_sp->long_value = FINSH_GET32(finsh_pc);
  224. finsh_sp ++;
  225. finsh_pc += 4;
  226. return ;
  227. }
  228. void OP_ld_value_byte()
  229. {
  230. char* c;
  231. c = (char*) (FINSH_GET32(finsh_pc));
  232. finsh_sp->char_value = *c;
  233. finsh_sp ++;
  234. finsh_pc += 4;
  235. return;
  236. }
  237. void OP_ld_value_byte_stack()
  238. {
  239. char* c;
  240. c = (char *)(finsh_sp - 1)->long_value;
  241. (finsh_sp - 1)->char_value = *c;
  242. return;
  243. }
  244. void OP_ld_value_word()
  245. {
  246. short* s;
  247. s = (short*) (FINSH_GET32(finsh_pc));
  248. finsh_sp->short_value = *s;
  249. finsh_sp ++;
  250. finsh_pc += 4;
  251. return;
  252. }
  253. void OP_ld_value_word_stack()
  254. {
  255. short* s;
  256. s = (short *)(finsh_sp - 1)->long_value;
  257. (finsh_sp - 1)->short_value = *s;
  258. return;
  259. }
  260. void OP_ld_value_dword()
  261. {
  262. long* l;
  263. l = (long*) (FINSH_GET32(finsh_pc));
  264. finsh_sp->long_value = *l;
  265. finsh_sp ++;
  266. finsh_pc += 4;
  267. return;
  268. }
  269. void OP_ld_value_dword_stack()
  270. {
  271. long* l;
  272. l = (long *)(finsh_sp - 1)->long_value;
  273. (finsh_sp - 1)->long_value = *l;
  274. return;
  275. }
  276. /* --- st --- */
  277. /*
  278. * 2006-4-16 bernard
  279. * fixed the sp move bug
  280. */
  281. void OP_st_byte()
  282. {
  283. *(char*)((finsh_sp - 2)->long_value) = (finsh_sp - 1)->char_value;
  284. finsh_sp --;
  285. return ;
  286. }
  287. /*
  288. * 2006-4-16 bernard
  289. * fixed the sp move bug
  290. */
  291. void OP_st_word()
  292. {
  293. *(short*)((finsh_sp - 2)->long_value) = (finsh_sp - 1)->short_value;
  294. finsh_sp --;
  295. return ;
  296. }
  297. /*
  298. * 2006-4-16 bernard
  299. * fixed the sp move bug
  300. */
  301. void OP_st_dword()
  302. {
  303. *(long*)((finsh_sp - 2)->long_value) = (finsh_sp - 1)->long_value;
  304. finsh_sp --;
  305. return ;
  306. }
  307. /* --- pop --- */
  308. void OP_pop()
  309. {
  310. finsh_sp --;
  311. return ;
  312. }
  313. /* --- call --- */
  314. void OP_call()
  315. {
  316. /* the max number of arg*/
  317. unsigned long parameterv[16];
  318. unsigned int parameters, i;
  319. typedef unsigned long var_t;
  320. typedef var_t (*op_func)();
  321. op_func f;
  322. var_t r;
  323. parameters = *finsh_pc ++;
  324. i = 0; finsh_sp --;
  325. while (i < parameters)
  326. {
  327. parameterv[parameters - 1 - i] = finsh_sp->long_value;
  328. finsh_sp --;
  329. i++;
  330. }
  331. f = (op_func)(finsh_sp->long_value);
  332. switch (parameters)
  333. {
  334. case 0:
  335. r = f(0);
  336. break;
  337. case 1:
  338. r = f(parameterv[0]);
  339. break;
  340. case 2:
  341. r = f(parameterv[0], parameterv[1]);
  342. break;
  343. case 3:
  344. r = f(parameterv[0], parameterv[1], parameterv[2]);
  345. break;
  346. case 4:
  347. r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3]);
  348. break;
  349. case 5:
  350. r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
  351. parameterv[4]);
  352. break;
  353. case 6:
  354. r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
  355. parameterv[4], parameterv[5]);
  356. break;
  357. case 7:
  358. r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
  359. parameterv[4], parameterv[5], parameterv[6]);
  360. break;
  361. case 8:
  362. r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
  363. parameterv[4], parameterv[5], parameterv[6], parameterv[7]);
  364. break;
  365. case 9:
  366. r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
  367. parameterv[4], parameterv[5], parameterv[6], parameterv[7],
  368. parameterv[8]);
  369. break;
  370. case 10:
  371. r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
  372. parameterv[4], parameterv[5], parameterv[6], parameterv[7],
  373. parameterv[8], parameterv[9]);
  374. break;
  375. case 11:
  376. r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
  377. parameterv[4], parameterv[5], parameterv[6], parameterv[7],
  378. parameterv[8], parameterv[9], parameterv[10]);
  379. break;
  380. case 12:
  381. r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
  382. parameterv[4], parameterv[5], parameterv[6], parameterv[7],
  383. parameterv[8], parameterv[9], parameterv[10], parameterv[11]);
  384. break;
  385. case 13:
  386. r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
  387. parameterv[4], parameterv[5], parameterv[6], parameterv[7],
  388. parameterv[8], parameterv[9], parameterv[10], parameterv[11],
  389. parameterv[12]);
  390. break;
  391. case 14:
  392. r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
  393. parameterv[4], parameterv[5], parameterv[6], parameterv[7],
  394. parameterv[8], parameterv[9], parameterv[10], parameterv[11],
  395. parameterv[12], parameterv[13]);
  396. break;
  397. case 15:
  398. r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
  399. parameterv[4], parameterv[5], parameterv[6], parameterv[7],
  400. parameterv[8], parameterv[9], parameterv[10], parameterv[11],
  401. parameterv[12], parameterv[13], parameterv[14]);
  402. break;
  403. case 16:
  404. r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
  405. parameterv[4], parameterv[5], parameterv[6], parameterv[7],
  406. parameterv[8], parameterv[9], parameterv[10], parameterv[11],
  407. parameterv[12], parameterv[13], parameterv[14], parameterv[15]);
  408. break;
  409. default:
  410. r = 0;
  411. break;
  412. }
  413. finsh_sp->long_value = r;
  414. finsh_sp ++;
  415. return ;
  416. }
  417. const op_func op_table[] =
  418. {
  419. /* 00 */ OP_no_op,
  420. /* 01 */ OP_add_byte,
  421. /* 02 */ OP_add_word,
  422. /* 03 */ OP_add_dword,
  423. /* 04 */ OP_sub_byte,
  424. /* 05 */ OP_sub_word,
  425. /* 06 */ OP_sub_dword,
  426. /* 07 */ OP_div_byte,
  427. /* 08 */ OP_div_word,
  428. /* 09 */ OP_div_dword,
  429. /* 10 */ OP_mod_byte,
  430. /* 11 */ OP_mod_word,
  431. /* 12 */ OP_mod_dword,
  432. /* 13 */ OP_mul_byte,
  433. /* 14 */ OP_mul_word,
  434. /* 15 */ OP_mul_dword,
  435. /* 16 */ OP_and_byte,
  436. /* 17 */ OP_and_word,
  437. /* 18 */ OP_and_dword,
  438. /* 19 */ OP_or_byte,
  439. /* 20 */ OP_or_word,
  440. /* 21 */ OP_or_dword,
  441. /* 22 */ OP_xor_byte,
  442. /* 23 */ OP_xor_word,
  443. /* 24 */ OP_xor_dword,
  444. /* 25 */ OP_bw_byte,
  445. /* 26 */ OP_bw_word,
  446. /* 27 */ OP_bw_dword,
  447. /* 28 */ OP_shl_byte,
  448. /* 29 */ OP_shl_word,
  449. /* 30 */ OP_shl_dword,
  450. /* 31 */ OP_shr_byte,
  451. /* 32 */ OP_shr_word,
  452. /* 33 */ OP_shr_dword,
  453. /* 34 */ OP_ld_byte,
  454. /* 35 */ OP_ld_word,
  455. /* 36 */ OP_ld_dword,
  456. /* 37 */ OP_ld_value_byte,
  457. /* 38 */ OP_ld_value_word,
  458. /* 39 */ OP_ld_value_dword,
  459. /* 40 */ OP_st_byte,
  460. /* 41 */ OP_st_word,
  461. /* 42 */ OP_st_dword,
  462. /* 43 */ OP_pop,
  463. /* 44 */ OP_call,
  464. /* 45 */ OP_ld_value_byte_stack,
  465. /* 46 */ OP_ld_value_word_stack,
  466. /* 47 */ OP_ld_value_dword_stack,
  467. NULL
  468. };