604 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			604 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /*
 | ||
|  |  * Copyright (c) 2006-2018, RT-Thread Development Team | ||
|  |  * | ||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||
|  |  * | ||
|  |  * Change Logs: | ||
|  |  * Date           Author       Notes | ||
|  |  * 2010-03-22     Bernard      first version | ||
|  |  */ | ||
|  | #include "finsh_ops.h"
 | ||
|  | #include "finsh_vm.h"
 | ||
|  | 
 | ||
|  | #define OP_BIN_BYTE(x)  do {\
 | ||
|  |         (finsh_sp - 2)->char_value = (finsh_sp - 2)->char_value x (finsh_sp - 1)->char_value; \ | ||
|  |         finsh_sp--; \ | ||
|  |     }while (0) | ||
|  | 
 | ||
|  | #define OP_BIN_WORD(x)  do {\
 | ||
|  |         (finsh_sp - 2)->short_value = (finsh_sp - 2)->short_value x (finsh_sp - 1)->short_value; \ | ||
|  |         finsh_sp--; \ | ||
|  |     }while (0) | ||
|  | 
 | ||
|  | #define OP_BIN_DWORD(x)  do {\
 | ||
|  |         (finsh_sp - 2)->long_value = (finsh_sp - 2)->long_value x (finsh_sp - 1)->long_value; \ | ||
|  |         finsh_sp--; \ | ||
|  |     }while (0) | ||
|  | 
 | ||
|  | /* --- noop --- */ | ||
|  | void OP_no_op() | ||
|  | { | ||
|  |     /* none */ | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /* --- add --- */ | ||
|  | void OP_add_byte() | ||
|  | { | ||
|  |     OP_BIN_BYTE(+); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_add_word() | ||
|  | { | ||
|  |     OP_BIN_WORD(+); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_add_dword() | ||
|  | { | ||
|  |     OP_BIN_DWORD(+); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /* --- sub --- */ | ||
|  | void OP_sub_byte() | ||
|  | { | ||
|  |     OP_BIN_BYTE(-); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_sub_word() | ||
|  | { | ||
|  |     OP_BIN_WORD(-); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_sub_dword() | ||
|  | { | ||
|  |     OP_BIN_DWORD(-); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /* --- div --- */ | ||
|  | void OP_div_byte() | ||
|  | { | ||
|  |     OP_BIN_BYTE(/); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_div_word() | ||
|  | { | ||
|  |     OP_BIN_WORD(/); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_div_dword() | ||
|  | { | ||
|  |     OP_BIN_DWORD(/); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /* --- mod --- */ | ||
|  | void OP_mod_byte() | ||
|  | { | ||
|  |     OP_BIN_BYTE(%); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_mod_word() | ||
|  | { | ||
|  |     OP_BIN_WORD(%); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_mod_dword() | ||
|  | { | ||
|  |     OP_BIN_DWORD(%); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /* --- mul --- */ | ||
|  | void OP_mul_byte() | ||
|  | { | ||
|  |     OP_BIN_BYTE(*); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_mul_word() | ||
|  | { | ||
|  |     OP_BIN_WORD(*); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_mul_dword() | ||
|  | { | ||
|  |     OP_BIN_DWORD(*); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /* --- and --- */ | ||
|  | void OP_and_byte() | ||
|  | { | ||
|  |     OP_BIN_BYTE(&); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_and_word() | ||
|  | { | ||
|  |     OP_BIN_WORD(&); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_and_dword() | ||
|  | { | ||
|  |     OP_BIN_DWORD(&); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /* --- or --- */ | ||
|  | void OP_or_byte() | ||
|  | { | ||
|  |     OP_BIN_BYTE(|); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_or_word() | ||
|  | { | ||
|  |     OP_BIN_WORD(|); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_or_dword() | ||
|  | { | ||
|  |     OP_BIN_DWORD(|); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /* --- xor --- */ | ||
|  | void OP_xor_byte() | ||
|  | { | ||
|  |     OP_BIN_BYTE(^); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_xor_word() | ||
|  | { | ||
|  |     OP_BIN_WORD(^); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_xor_dword() | ||
|  | { | ||
|  |     OP_BIN_DWORD(^); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /* --- bw --- */ | ||
|  | void OP_bw_byte() | ||
|  | { | ||
|  |     (finsh_sp - 1)->char_value = ~ ((finsh_sp - 1)->char_value); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_bw_word() | ||
|  | { | ||
|  |     (finsh_sp - 1)->short_value = ~ ((finsh_sp - 1)->short_value); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_bw_dword() | ||
|  | { | ||
|  |     (finsh_sp - 1)->long_value = ~ ((finsh_sp - 1)->long_value); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /* --- shl --- */ | ||
|  | void OP_shl_byte() | ||
|  | { | ||
|  |     OP_BIN_BYTE(<<); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_shl_word() | ||
|  | { | ||
|  |     OP_BIN_WORD(<<); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_shl_dword() | ||
|  | { | ||
|  |     OP_BIN_DWORD(<<); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /* --- shr --- */ | ||
|  | void OP_shr_byte() | ||
|  | { | ||
|  |     OP_BIN_BYTE(>>); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_shr_word() | ||
|  | { | ||
|  |     OP_BIN_WORD(>>); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_shr_dword() | ||
|  | { | ||
|  |     OP_BIN_DWORD(>>); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /* --- ld --- */ | ||
|  | void OP_ld_byte() | ||
|  | { | ||
|  |     finsh_sp->char_value = *finsh_pc; | ||
|  | 
 | ||
|  |     finsh_sp++; | ||
|  |     finsh_pc++; | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_ld_word() | ||
|  | { | ||
|  |     finsh_sp->short_value = FINSH_GET16(finsh_pc); | ||
|  | 
 | ||
|  |     finsh_sp ++; | ||
|  |     finsh_pc += 2; | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_ld_dword() | ||
|  | { | ||
|  |     finsh_sp->long_value = FINSH_GET32(finsh_pc); | ||
|  | 
 | ||
|  |     finsh_sp ++; | ||
|  |     finsh_pc += 4; | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_ld_value_byte() | ||
|  | { | ||
|  |     char* c; | ||
|  | 
 | ||
|  |     c = (char*) (FINSH_GET32(finsh_pc)); | ||
|  | 
 | ||
|  |     finsh_sp->char_value = *c; | ||
|  | 
 | ||
|  |     finsh_sp ++; | ||
|  |     finsh_pc += 4; | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_ld_value_byte_stack() | ||
|  | { | ||
|  |     char* c; | ||
|  | 
 | ||
|  |     c = (char *)(finsh_sp - 1)->long_value; | ||
|  |     (finsh_sp - 1)->char_value = *c; | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_ld_value_word() | ||
|  | { | ||
|  |     short* s; | ||
|  | 
 | ||
|  |     s = (short*) (FINSH_GET32(finsh_pc)); | ||
|  | 
 | ||
|  |     finsh_sp->short_value = *s; | ||
|  | 
 | ||
|  |     finsh_sp ++; | ||
|  |     finsh_pc += 4; | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_ld_value_word_stack() | ||
|  | { | ||
|  |     short* s; | ||
|  | 
 | ||
|  |     s = (short *)(finsh_sp - 1)->long_value; | ||
|  |     (finsh_sp - 1)->short_value = *s; | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_ld_value_dword() | ||
|  | { | ||
|  |     long* l; | ||
|  | 
 | ||
|  |     l = (long*) (FINSH_GET32(finsh_pc)); | ||
|  | 
 | ||
|  |     finsh_sp->long_value = *l; | ||
|  | 
 | ||
|  |     finsh_sp ++; | ||
|  |     finsh_pc += 4; | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void OP_ld_value_dword_stack() | ||
|  | { | ||
|  |     long* l; | ||
|  | 
 | ||
|  |     l = (long *)(finsh_sp - 1)->long_value; | ||
|  |     (finsh_sp - 1)->long_value = *l; | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | /* --- st --- */ | ||
|  | /*
 | ||
|  |  * 2006-4-16 bernard | ||
|  |  * fixed the sp move bug | ||
|  |  */ | ||
|  | void OP_st_byte() | ||
|  | { | ||
|  |     *(char*)((finsh_sp - 2)->long_value) = (finsh_sp - 1)->char_value; | ||
|  |     finsh_sp --; | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /*
 | ||
|  |  * 2006-4-16 bernard | ||
|  |  * fixed the sp move bug | ||
|  |  */ | ||
|  | void OP_st_word() | ||
|  | { | ||
|  |     *(short*)((finsh_sp - 2)->long_value) = (finsh_sp - 1)->short_value; | ||
|  |     finsh_sp --; | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /*
 | ||
|  |  * 2006-4-16 bernard | ||
|  |  * fixed the sp move bug | ||
|  |  */ | ||
|  | void OP_st_dword() | ||
|  | { | ||
|  |     *(long*)((finsh_sp - 2)->long_value) = (finsh_sp - 1)->long_value; | ||
|  |     finsh_sp --; | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /* --- pop --- */ | ||
|  | void OP_pop() | ||
|  | { | ||
|  |     finsh_sp --; | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /* --- call --- */ | ||
|  | void OP_call() | ||
|  | { | ||
|  |     /* the max number of arg*/ | ||
|  |     unsigned long parameterv[16]; | ||
|  |     unsigned int  parameters, i; | ||
|  | 
 | ||
|  |     typedef unsigned long var_t; | ||
|  |     typedef var_t (*op_func)(); | ||
|  |     op_func f; | ||
|  |     var_t   r; | ||
|  | 
 | ||
|  |     parameters = *finsh_pc ++; | ||
|  | 
 | ||
|  |     i = 0; finsh_sp --; | ||
|  |     while (i < parameters) | ||
|  |     { | ||
|  |         parameterv[parameters - 1 - i] = finsh_sp->long_value; | ||
|  |         finsh_sp --; | ||
|  |         i++; | ||
|  |     } | ||
|  | 
 | ||
|  |     f = (op_func)(finsh_sp->long_value); | ||
|  |     switch (parameters) | ||
|  |     { | ||
|  |     case 0: | ||
|  |         r = f(0); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 1: | ||
|  |         r = f(parameterv[0]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 2: | ||
|  |         r = f(parameterv[0], parameterv[1]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 3: | ||
|  |         r = f(parameterv[0], parameterv[1], parameterv[2]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 4: | ||
|  |         r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 5: | ||
|  |         r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3], | ||
|  |                 parameterv[4]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 6: | ||
|  |         r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3], | ||
|  |                 parameterv[4], parameterv[5]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 7: | ||
|  |         r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3], | ||
|  |                 parameterv[4], parameterv[5], parameterv[6]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 8: | ||
|  |         r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3], | ||
|  |                 parameterv[4], parameterv[5], parameterv[6], parameterv[7]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 9: | ||
|  |         r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3], | ||
|  |                 parameterv[4], parameterv[5], parameterv[6], parameterv[7], | ||
|  |                 parameterv[8]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 10: | ||
|  |         r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3], | ||
|  |                 parameterv[4], parameterv[5], parameterv[6], parameterv[7], | ||
|  |                 parameterv[8], parameterv[9]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 11: | ||
|  |         r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3], | ||
|  |                 parameterv[4], parameterv[5], parameterv[6], parameterv[7], | ||
|  |                 parameterv[8], parameterv[9], parameterv[10]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 12: | ||
|  |         r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3], | ||
|  |                 parameterv[4], parameterv[5], parameterv[6], parameterv[7], | ||
|  |                 parameterv[8], parameterv[9], parameterv[10], parameterv[11]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 13: | ||
|  |         r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3], | ||
|  |                 parameterv[4], parameterv[5], parameterv[6], parameterv[7], | ||
|  |                 parameterv[8], parameterv[9], parameterv[10], parameterv[11], | ||
|  |                 parameterv[12]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 14: | ||
|  |         r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3], | ||
|  |                 parameterv[4], parameterv[5], parameterv[6], parameterv[7], | ||
|  |                 parameterv[8], parameterv[9], parameterv[10], parameterv[11], | ||
|  |                 parameterv[12], parameterv[13]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 15: | ||
|  |         r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3], | ||
|  |                 parameterv[4], parameterv[5], parameterv[6], parameterv[7], | ||
|  |                 parameterv[8], parameterv[9], parameterv[10], parameterv[11], | ||
|  |                 parameterv[12], parameterv[13], parameterv[14]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     case 16: | ||
|  |         r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3], | ||
|  |                 parameterv[4], parameterv[5], parameterv[6], parameterv[7], | ||
|  |                 parameterv[8], parameterv[9], parameterv[10], parameterv[11], | ||
|  |                 parameterv[12], parameterv[13], parameterv[14], parameterv[15]); | ||
|  |         break; | ||
|  | 
 | ||
|  |     default: | ||
|  |         r = 0; | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     finsh_sp->long_value = r; | ||
|  |     finsh_sp ++; | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | const op_func op_table[] = | ||
|  | { | ||
|  |     /* 00 */ OP_no_op, | ||
|  |     /* 01 */ OP_add_byte, | ||
|  |     /* 02 */ OP_add_word, | ||
|  |     /* 03 */ OP_add_dword, | ||
|  |     /* 04 */ OP_sub_byte, | ||
|  |     /* 05 */ OP_sub_word, | ||
|  |     /* 06 */ OP_sub_dword, | ||
|  |     /* 07 */ OP_div_byte, | ||
|  |     /* 08 */ OP_div_word, | ||
|  |     /* 09 */ OP_div_dword, | ||
|  |     /* 10 */ OP_mod_byte, | ||
|  |     /* 11 */ OP_mod_word, | ||
|  |     /* 12 */ OP_mod_dword, | ||
|  |     /* 13 */ OP_mul_byte, | ||
|  |     /* 14 */ OP_mul_word, | ||
|  |     /* 15 */ OP_mul_dword, | ||
|  |     /* 16 */ OP_and_byte, | ||
|  |     /* 17 */ OP_and_word, | ||
|  |     /* 18 */ OP_and_dword, | ||
|  |     /* 19 */ OP_or_byte, | ||
|  |     /* 20 */ OP_or_word, | ||
|  |     /* 21 */ OP_or_dword, | ||
|  |     /* 22 */ OP_xor_byte, | ||
|  |     /* 23 */ OP_xor_word, | ||
|  |     /* 24 */ OP_xor_dword, | ||
|  |     /* 25 */ OP_bw_byte, | ||
|  |     /* 26 */ OP_bw_word, | ||
|  |     /* 27 */ OP_bw_dword, | ||
|  |     /* 28 */ OP_shl_byte, | ||
|  |     /* 29 */ OP_shl_word, | ||
|  |     /* 30 */ OP_shl_dword, | ||
|  |     /* 31 */ OP_shr_byte, | ||
|  |     /* 32 */ OP_shr_word, | ||
|  |     /* 33 */ OP_shr_dword, | ||
|  |     /* 34 */ OP_ld_byte, | ||
|  |     /* 35 */ OP_ld_word, | ||
|  |     /* 36 */ OP_ld_dword, | ||
|  |     /* 37 */ OP_ld_value_byte, | ||
|  |     /* 38 */ OP_ld_value_word, | ||
|  |     /* 39 */ OP_ld_value_dword, | ||
|  |     /* 40 */ OP_st_byte, | ||
|  |     /* 41 */ OP_st_word, | ||
|  |     /* 42 */ OP_st_dword, | ||
|  |     /* 43 */ OP_pop, | ||
|  |     /* 44 */ OP_call, | ||
|  |     /* 45 */ OP_ld_value_byte_stack, | ||
|  |     /* 46 */ OP_ld_value_word_stack, | ||
|  |     /* 47 */ OP_ld_value_dword_stack, | ||
|  |     NULL | ||
|  | }; |