xref: /nrf52832-nimble/rt-thread/components/finsh/finsh_vm.c (revision 104654410c56c573564690304ae786df310c91fc)
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.h>
11 
12 #include "finsh_vm.h"
13 #include "finsh_ops.h"
14 #include "finsh_var.h"
15 
16 /* stack */
17 union finsh_value   finsh_vm_stack[FINSH_STACK_MAX];
18 /* text segment */
19 uint8_t             text_segment[FINSH_TEXT_MAX];
20 
21 union finsh_value*  finsh_sp;       /* stack pointer */
22 uint8_t*            finsh_pc;       /* PC */
23 
24 /* syscall list, for dynamic system call register */
25 struct finsh_syscall_item* global_syscall_list = NULL;
26 
27 // #define FINSH_VM_DISASSEMBLE
finsh_vm_run()28 void finsh_vm_run()
29 {
30     uint8_t op;
31 
32     /* if you want to disassemble the byte code, please define FINSH_VM_DISASSEMBLE */
33 #ifdef FINSH_VM_DISASSEMBLE
34     void finsh_disassemble();
35     finsh_disassemble();
36 #endif
37 
38     /* set sp(stack pointer) to the beginning of stack */
39     finsh_sp = &finsh_vm_stack[0];
40 
41     /* set pc to the beginning of text segment */
42     finsh_pc = &text_segment[0];
43 
44     while ((finsh_pc - &text_segment[0] >= 0) &&
45         (finsh_pc - &text_segment[0] < FINSH_TEXT_MAX))
46     {
47         /* get op */
48         op = *finsh_pc++;
49 
50         /* call op function */
51         op_table[op]();
52     }
53 }
54 
55 #ifdef RT_USING_HEAP
finsh_syscall_append(const char * name,syscall_func func)56 void finsh_syscall_append(const char* name, syscall_func func)
57 {
58     /* create the syscall */
59     struct finsh_syscall_item* item;
60 
61     item = (struct finsh_syscall_item*)rt_malloc(sizeof(struct finsh_syscall_item));
62     if (item != RT_NULL)
63     {
64         item->next = NULL;
65         item->syscall.name = rt_strdup(name);
66         item->syscall.func = func;
67 
68         if (global_syscall_list == NULL)
69         {
70             global_syscall_list = item;
71         }
72         else
73         {
74             item->next = global_syscall_list;
75             global_syscall_list = item;
76         }
77     }
78 }
79 #endif
80 
81 #if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
finsh_syscall_next(struct finsh_syscall * call)82 struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call)
83 {
84     unsigned int *ptr;
85     ptr = (unsigned int*) (call + 1);
86     while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _syscall_table_end))
87         ptr ++;
88 
89     return (struct finsh_syscall*)ptr;
90 }
91 
finsh_sysvar_next(struct finsh_sysvar * call)92 struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call)
93 {
94     unsigned int *ptr;
95     ptr = (unsigned int*) (call + 1);
96     while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _sysvar_table_end))
97         ptr ++;
98 
99     return (struct finsh_sysvar*)ptr;
100 }
101 #endif
102 
finsh_syscall_lookup(const char * name)103 struct finsh_syscall* finsh_syscall_lookup(const char* name)
104 {
105     struct finsh_syscall* index;
106     struct finsh_syscall_item* item;
107 
108     for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
109     {
110         if (strcmp(index->name, name) == 0)
111             return index;
112     }
113 
114     /* find on syscall list */
115     item = global_syscall_list;
116     while (item != NULL)
117     {
118         if (strncmp(item->syscall.name, name, strlen(name)) == 0)
119         {
120             return &(item->syscall);
121         }
122 
123         item = item->next;
124     }
125 
126     return NULL;
127 }
128 
129 #ifdef FINSH_VM_DISASSEMBLE
finsh_disassemble()130 void finsh_disassemble()
131 {
132     uint8_t *pc, op;
133 
134     pc = &text_segment[0];
135     while (*pc != 0)
136     {
137         op = *pc;
138         switch (op)
139         {
140         case FINSH_OP_ADD_BYTE:
141             pc ++;
142             rt_kprintf("addb\n");
143             break;
144 
145         case FINSH_OP_SUB_BYTE:
146             pc ++;
147             rt_kprintf("subb\n");
148             break;
149 
150         case FINSH_OP_DIV_BYTE:
151             pc ++;
152             rt_kprintf("divb\n");
153             break;
154 
155         case FINSH_OP_MOD_BYTE:
156             pc ++;
157             rt_kprintf("modb\n");
158             break;
159 
160         case FINSH_OP_MUL_BYTE:
161             pc ++;
162             rt_kprintf("mulb\n");
163             break;
164 
165         case FINSH_OP_AND_BYTE:
166             pc ++;
167             rt_kprintf("andb\n");
168             break;
169 
170         case FINSH_OP_OR_BYTE:
171             pc ++;
172             rt_kprintf("orb\n");
173             break;
174 
175         case FINSH_OP_XOR_BYTE:
176             pc ++;
177             rt_kprintf("xorb\n");
178             break;
179 
180         case FINSH_OP_BITWISE_BYTE:
181             pc ++;
182             rt_kprintf("bwb\n");
183             break;
184 
185         case FINSH_OP_SHL_BYTE:
186             pc ++;
187             rt_kprintf("shlb\n");
188             break;
189 
190         case FINSH_OP_SHR_BYTE:
191             pc ++;
192             rt_kprintf("shrb\n");
193             break;
194 
195         case FINSH_OP_LD_BYTE:
196             pc ++;
197             rt_kprintf("ldb %d\n", *pc++);
198             break;
199 
200         case FINSH_OP_LD_VALUE_BYTE:
201             pc ++;
202             rt_kprintf("ldb [0x%x]\n", FINSH_GET32(pc));
203             pc += 4;
204             break;
205 
206         case FINSH_OP_ST_BYTE:
207             pc ++;
208             rt_kprintf("stb\n");
209             break;
210 
211         case FINSH_OP_ADD_WORD:
212             pc ++;
213             rt_kprintf("addw\n");
214             break;
215 
216         case FINSH_OP_SUB_WORD:
217             pc ++;
218             rt_kprintf("subw\n");
219             break;
220 
221         case FINSH_OP_DIV_WORD:
222             pc ++;
223             rt_kprintf("divw\n");
224             break;
225 
226         case FINSH_OP_MOD_WORD:
227             pc ++;
228             rt_kprintf("modw\n");
229             break;
230 
231         case FINSH_OP_MUL_WORD:
232             pc ++;
233             rt_kprintf("mulw\n");
234             break;
235 
236         case FINSH_OP_AND_WORD:
237             pc ++;
238             rt_kprintf("andw\n");
239             break;
240 
241         case FINSH_OP_OR_WORD:
242             pc ++;
243             rt_kprintf("orw\n");
244             break;
245 
246         case FINSH_OP_XOR_WORD:
247             pc ++;
248             rt_kprintf("xorw\n");
249             break;
250 
251         case FINSH_OP_BITWISE_WORD:
252             pc ++;
253             rt_kprintf("bww\n");
254             break;
255 
256         case FINSH_OP_SHL_WORD:
257             pc ++;
258             rt_kprintf("shlw\n");
259             break;
260 
261         case FINSH_OP_SHR_WORD:
262             pc ++;
263             rt_kprintf("shrw\n");
264             break;
265 
266         case FINSH_OP_LD_WORD:
267             pc ++;
268             rt_kprintf("ldw %d\n", FINSH_GET16(pc));
269             pc += 2;
270             break;
271 
272         case FINSH_OP_LD_VALUE_WORD:
273             pc ++;
274             rt_kprintf("ldw [0x%x]\n", FINSH_GET32(pc));
275             pc += 4;
276             break;
277 
278         case FINSH_OP_ST_WORD:
279             pc ++;
280             rt_kprintf("stw\n");
281             break;
282 
283         case FINSH_OP_ADD_DWORD:
284             pc ++;
285             rt_kprintf("addd\n");
286             break;
287 
288         case FINSH_OP_SUB_DWORD:
289             pc ++;
290             rt_kprintf("subd\n");
291             break;
292 
293         case FINSH_OP_DIV_DWORD:
294             pc ++;
295             rt_kprintf("divd\n");
296             break;
297 
298         case FINSH_OP_MOD_DWORD:
299             pc ++;
300             rt_kprintf("modd\n");
301             break;
302 
303         case FINSH_OP_MUL_DWORD:
304             pc ++;
305             rt_kprintf("muld\n");
306             break;
307 
308         case FINSH_OP_AND_DWORD:
309             pc ++;
310             rt_kprintf("andd\n");
311             break;
312 
313         case FINSH_OP_OR_DWORD:
314             pc ++;
315             rt_kprintf("ord\n");
316             break;
317 
318         case FINSH_OP_XOR_DWORD:
319             pc ++;
320             rt_kprintf("xord\n");
321             break;
322 
323         case FINSH_OP_BITWISE_DWORD:
324             pc ++;
325             rt_kprintf("bwd\n");
326             break;
327 
328         case FINSH_OP_SHL_DWORD:
329             pc ++;
330             rt_kprintf("shld\n");
331             break;
332 
333         case FINSH_OP_SHR_DWORD:
334             pc ++;
335             rt_kprintf("shrd\n");
336             break;
337 
338         case FINSH_OP_LD_DWORD:
339             pc ++;
340             rt_kprintf("ldd 0x%x\n", FINSH_GET32(pc));
341             pc += 4;
342             break;
343 
344         case FINSH_OP_LD_VALUE_DWORD:
345             pc ++;
346             rt_kprintf("ldd [0x%x]\n", FINSH_GET32(pc));
347             pc += 4;
348             break;
349 
350         case FINSH_OP_ST_DWORD:
351             pc ++;
352             rt_kprintf("std\n");
353             break;
354 
355         case FINSH_OP_POP:
356             rt_kprintf("pop\n");
357             pc ++;
358             break;
359 
360         case FINSH_OP_SYSCALL:
361             pc ++;
362             rt_kprintf("syscall %d\n", *pc++);
363             break;
364 
365         case FINSH_OP_LD_VALUE_BYTE_STACK:
366             pc ++;
367             rt_kprintf("ldb [sp]\n");
368             break;
369 
370         case FINSH_OP_LD_VALUE_WORD_STACK:
371             pc ++;
372             rt_kprintf("ldw [sp]\n");
373             break;
374 
375         case FINSH_OP_LD_VALUE_DWORD_STACK:
376             pc ++;
377             rt_kprintf("ldd [sp]\n");
378             break;
379 
380         default:
381             return;
382         }
383     }
384 }
385 #endif
386