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 --- */ 29 void OP_no_op() 30 { 31 /* none */ 32 return ; 33 } 34 35 /* --- add --- */ 36 void OP_add_byte() 37 { 38 OP_BIN_BYTE(+); 39 40 return ; 41 } 42 43 void OP_add_word() 44 { 45 OP_BIN_WORD(+); 46 47 return ; 48 } 49 50 void OP_add_dword() 51 { 52 OP_BIN_DWORD(+); 53 54 return ; 55 } 56 57 /* --- sub --- */ 58 void OP_sub_byte() 59 { 60 OP_BIN_BYTE(-); 61 62 return ; 63 } 64 65 void OP_sub_word() 66 { 67 OP_BIN_WORD(-); 68 69 return ; 70 } 71 72 void OP_sub_dword() 73 { 74 OP_BIN_DWORD(-); 75 76 return ; 77 } 78 79 /* --- div --- */ 80 void OP_div_byte() 81 { 82 OP_BIN_BYTE(/); 83 84 return ; 85 } 86 87 void OP_div_word() 88 { 89 OP_BIN_WORD(/); 90 91 return ; 92 } 93 94 void OP_div_dword() 95 { 96 OP_BIN_DWORD(/); 97 98 return ; 99 } 100 101 /* --- mod --- */ 102 void OP_mod_byte() 103 { 104 OP_BIN_BYTE(%); 105 106 return ; 107 } 108 109 void OP_mod_word() 110 { 111 OP_BIN_WORD(%); 112 113 return ; 114 } 115 116 void OP_mod_dword() 117 { 118 OP_BIN_DWORD(%); 119 120 return ; 121 } 122 123 /* --- mul --- */ 124 void OP_mul_byte() 125 { 126 OP_BIN_BYTE(*); 127 128 return ; 129 } 130 131 void OP_mul_word() 132 { 133 OP_BIN_WORD(*); 134 135 return ; 136 } 137 138 void OP_mul_dword() 139 { 140 OP_BIN_DWORD(*); 141 142 return ; 143 } 144 145 /* --- and --- */ 146 void OP_and_byte() 147 { 148 OP_BIN_BYTE(&); 149 150 return ; 151 } 152 153 void OP_and_word() 154 { 155 OP_BIN_WORD(&); 156 157 return ; 158 } 159 160 void OP_and_dword() 161 { 162 OP_BIN_DWORD(&); 163 164 return ; 165 } 166 167 /* --- or --- */ 168 void OP_or_byte() 169 { 170 OP_BIN_BYTE(|); 171 172 return ; 173 } 174 175 void OP_or_word() 176 { 177 OP_BIN_WORD(|); 178 179 return ; 180 } 181 182 void OP_or_dword() 183 { 184 OP_BIN_DWORD(|); 185 186 return ; 187 } 188 189 /* --- xor --- */ 190 void OP_xor_byte() 191 { 192 OP_BIN_BYTE(^); 193 194 return ; 195 } 196 197 void OP_xor_word() 198 { 199 OP_BIN_WORD(^); 200 201 return ; 202 } 203 204 void OP_xor_dword() 205 { 206 OP_BIN_DWORD(^); 207 208 return ; 209 } 210 211 /* --- bw --- */ 212 void OP_bw_byte() 213 { 214 (finsh_sp - 1)->char_value = ~ ((finsh_sp - 1)->char_value); 215 216 return ; 217 } 218 219 void OP_bw_word() 220 { 221 (finsh_sp - 1)->short_value = ~ ((finsh_sp - 1)->short_value); 222 223 return ; 224 } 225 226 void OP_bw_dword() 227 { 228 (finsh_sp - 1)->long_value = ~ ((finsh_sp - 1)->long_value); 229 230 return ; 231 } 232 233 /* --- shl --- */ 234 void OP_shl_byte() 235 { 236 OP_BIN_BYTE(<<); 237 238 return ; 239 } 240 241 void OP_shl_word() 242 { 243 OP_BIN_WORD(<<); 244 245 return ; 246 } 247 248 void OP_shl_dword() 249 { 250 OP_BIN_DWORD(<<); 251 252 return ; 253 } 254 255 /* --- shr --- */ 256 void OP_shr_byte() 257 { 258 OP_BIN_BYTE(>>); 259 260 return ; 261 } 262 263 void OP_shr_word() 264 { 265 OP_BIN_WORD(>>); 266 267 return ; 268 } 269 270 void OP_shr_dword() 271 { 272 OP_BIN_DWORD(>>); 273 274 return ; 275 } 276 277 /* --- ld --- */ 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 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 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 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 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 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 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 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 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 */ 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 */ 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 */ 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 --- */ 418 void OP_pop() 419 { 420 finsh_sp --; 421 return ; 422 } 423 424 /* --- 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