RPA Toolkit
work on RVM based parser - RPA2
[rpatk.git] / rvm / rvmcpu.h
1 /*
2  *  Regular Pattern Analyzer (RPA)
3  *  Copyright (c) 2009-2010 Martin Stoilov
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  *  Martin Stoilov <martin@rpasearch.com>
19  */
20
21 #ifndef _RVMCPU_H_
22 #define _RVMCPU_H_
23
24 #include "rtypes.h"
25 #include "rarray.h"
26 #include "rcarray.h"
27 #include "rvmreg.h"
28 #include "rvmgc.h"
29
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35
36 enum {
37         RVM_EXT = 0,
38         RVM_ABORT,              /* Abort: set the error code, op1: error code */
39         RVM_PRN,
40         RVM_ASR,                /* Arithmetic shift right: op1 = op2 >> op3, preserve the signed bit */
41         RVM_SWI,
42         RVM_SWIID,
43         RVM_CALL,               /* if op1 is of type RVM_DTYPE_SWIID, then invoke RVM_SWIID, otherwise invoke RVM_BL */
44         RVM_MOV,
45         RVM_SWP,                /* op1 <--> op2 */
46         RVM_INC,                /* INC: op1 = op1 + 1 */
47         RVM_DEC,                /* DEC: op1 = op1 - 1 */
48         RVM_ADD,                /* Add: op1 = op2 + op3 */
49         RVM_ADDS,               /* Add: op1 = op2 + op3, update the status register */
50         RVM_ADC,                /* Add: op1 = op2 + op3 + C, update the status register */
51         RVM_AND,                /* Bitwise AND: op1 = op2 & op3, update status register */
52         RVM_BIC,                /* Bit Clear: op1 = op2 & ~op3, update status register */
53         RVM_CLZ,                /* Count rvm_reg_settypeLeading Zeros: op1 = leading_zeros(op2) */
54         RVM_CMN,                /* Compare Negative: status register is updated based on the result: op1 + op2 */
55         RVM_XOR,                /* XOR: op1 = op2 ^ op3, update the status register */
56         RVM_SUB,
57         RVM_SUBS,
58         RVM_SBC,
59         RVM_MUL,
60         RVM_MLS,                /* Signed multiplication: op1 = op2 * op3 */
61         RVM_MULS,
62         RVM_NOT,                /* Bitwise NOT: op1 = ~op2, Update the status register */
63         RVM_DIV,                /* Divide: op1 = op2 / op3 */
64         RVM_DVS,                /* Signed division: op1 = op2 / op3 */  
65         RVM_DIVS,               /* Divide: op1 = op2 / op3, Update the status register */
66         RVM_MOD,                /* Modulo: op1 = op2 % op3 */
67         RVM_MODS,               /* Modulo: op1 = op2 % op3, Update the status register */
68         RVM_BX,                 /* Jump to op1 */
69         RVM_BXEQ,               /* Jump to op1, if equal */
70         RVM_BXNEQ,              /* Jump to op1, if not equal */
71
72         RVM_BXLEQ,              /* Branch if less or equal */
73         RVM_BXGEQ,              /* Branch if greater or equal */
74         RVM_BXLES,              /* Branch if less */
75         RVM_BXGRE,              /* Branch if greater */
76
77
78         RVM_BXL,                /* Jump to op1, link */
79         RVM_BL,                 /* Branch Link */
80         RVM_B,                  /* Branch */
81         RVM_STR,                /* Save: val_at_location(op2) = op1 */
82         RVM_STRP,               /* Save pointer: pointer_at_location(op2) = op1 */
83         RVM_STRB,               /* Save: byte_at_location(op2) = op1 */
84         RVM_STRH,               /* Save: u16_at_location(op2) = op1 */
85         RVM_STRW,               /* Save: u32_at_location(op2) = op1 */
86         RVM_STRR,               /* Save: rvmreg_t_at_location(op2) = op1 */
87         RVM_LDR,                /* Load: op1 = val_at_location(op2) */
88         RVM_LDRP,               /* Load pointer: op1 = pointer_at_location(op2) */
89         RVM_LDRB,               /* Load Byte: op1 = byte_at_location(op2) */
90         RVM_LDRH,               /* Load Half Word: op1 = u16_at_location(op2) */
91         RVM_LDRW,               /* Load Word: op1 = u32_at_location(op2) */
92         RVM_LDRR,               /* Load rvmreg_t: op1 = rvmreg_t_at_location(op2) */
93         RVM_CFLAG,              /* Clear flag */
94         RVM_CLR,                /* Clear op1 */
95         RVM_CLRR,               /* Clear: rvmreg_t at memory location op1 */
96         RVM_LSL,                /* Logical Shift Left: op1 = op2 << op3, update the status register */
97         RVM_LSR,                /* Logical Shift Right: op1 = op2 >> op3, update the status register */
98         RVM_LSRS,               /* Signed Logical Shift Right: op1 = op2 >> op3, update the status register */
99         RVM_STM,                /* Store multiple */
100         RVM_LDM,                /* Load multiple */
101         RVM_STS,                /* Store op1 on the stack at position op2 + op3, i.e. stack[op2 + op3] = op1 */
102         RVM_LDS,                /* Load op1 from thes stack at position op2 + op3, i.e. op1 = stack[op2 + op3] */
103         RVM_ORR,                /* ORR: op1 = op2 | op3, update the status register */
104         RVM_PUSH,
105         RVM_POP,
106         RVM_CMP,
107         RVM_NOP,
108         RVM_BEQ,                /* Branch if equal */
109         RVM_BNEQ,               /* Branch if not equal */
110         RVM_BLEQ,               /* Branch if less or equal */
111         RVM_BGEQ,               /* Branch if greater or equal */
112         RVM_BLES,               /* Branch if less */
113         RVM_BGRE,               /* Branch if greater */
114         RVM_RET,
115         RVM_ROR,                /* Rotate right, the last bit rotated out updates the Carry flag */
116         RVM_PUSHM,
117         RVM_POPM,
118         RVM_TST,
119         RVM_TEQ,
120         RVM_ADDRS,              /* Memory location of the stack at offset op2 + op3 */
121
122 /* Extended VM opcodes, */
123         RVM_CAST,               /* Cast: op1 = (op3)op2 */
124         RVM_TYPE,               /* Type: op1 = typeof(op2) */
125         RVM_SETTYPE,    /* Type: op1.type = op2 */
126         RVM_EMOV,
127         RVM_EADD,               /* Add: op1 = op2 + op3, update the status register */
128         RVM_ESUB,               /* Subtract: op1 = op2 - op3, update the status register */
129         RVM_EMUL,               /* Multiply: op1 = op2 * op3, update the status register */
130         RVM_EDIV,               /* Divide: op1 = op2 / op3, update the status register */
131         RVM_EMOD,               /* Modulo: op1 = op2 % op3, update the status register */
132         RVM_ELSL,               /* Logical Shift Left: op1 = op2 << op3, update the status register */
133         RVM_ELSR,               /* Logical Shift Right: op1 = op2 >> op3, update the status register */
134         RVM_ELSRU,              /* Logical Unsigned Shift Right: op1 = op2 >>> op3, update the status register */
135         RVM_EAND,               /* Bitwise AND: op1 = op2 & op3, update status register */
136         RVM_EORR,               /* Bitwise OR: op1 = op2 | op3, update the status register */
137         RVM_EXOR,               /* Bitwise XOR: op1 = op2 ^ op3, update the status register */
138         RVM_ENOT,               /* Bitwise NOT: op1 = ~op2, Update the status register */
139         RVM_ELAND,              /* Logical AND: op1 = op2 && op3, update status register */
140         RVM_ELOR,               /* Logical OR: op1 = op2 || op3, update the status register */
141         RVM_ELNOT,              /* Logical NOT: op1 = !op2, update the status register */
142         RVM_EEQ,                /* op1 = op2 == op3 ? 1 : 0, update the status register */
143         RVM_ENOTEQ,             /* op1 = op2 != op3 ? 1 : 0, update the status register */
144         RVM_EGREAT,             /* op1 = op2 > op3 ? 1 : 0, update the status register */
145         RVM_EGREATEQ,   /* op1 = op2 >= op3 ? 1 : 0, update the status register */
146         RVM_ELESS,              /* op1 = op2 < op3 ? 1 : 0, update the status register */
147         RVM_ELESSEQ,    /* op1 = op2 <= op3 ? 1 : 0, update the status register */
148
149         RVM_ECMP,               /* Compare: status register is updated based on the result: op1 - op2 */
150         RVM_ECMN,               /* Compare Negative: status register is updated based on the result: op1 + op2 */
151         RVM_ALLOCSTR,   /* Allocate string in op1, op2 is pointer (char*) to string, op3 is the size */
152         RVM_ALLOCARR,   /* Allocate array in op1, op2 is the size */
153         RVM_ADDRA,              /* op1 is the destination memory, op2 is the array, op3 is the offset */
154         RVM_LDA,                /* op1 is the destination, op2 is the array, op3 is the offset */
155         RVM_STA,                /* op1 is the source, op2 is the array, op3 is the offset */
156         RVM_ALLOCOBJ,
157         RVM_ADDROBJN,
158         RVM_ADDROBJH,
159         RVM_LDOBJN,
160         RVM_STOBJN,
161         RVM_LDOBJH,
162         RVM_STOBJH,
163         RVM_OBJLKUP,
164         RVM_OBJADD,
165         RVM_OBJLKUPADD,
166 };
167
168
169 #define RVM_REGISTER_BITS (8 * sizeof(rword))
170 #define RVM_SIGN_BIT (1LU << (RVM_REGISTER_BITS - 1))
171 #define RVM_STATUS_Z (1 << 0)
172 #define RVM_STATUS_N (1 << 1)
173 #define RVM_STATUS_C (1 << 2)
174 #define RVM_STATUS_V (1 << 3)
175 #define RVM_STATUS_E (1 << 4)
176 #define RVM_STATUS_ALL (RVM_STATUS_Z | RVM_STATUS_N | RVM_STATUS_C | RVM_STATUS_V | RVM_STATUS_E)
177 #define RVM_STATUS_GETBIT(cpu, bit) ((cpu)->status & (bit))
178 #define RVM_STATUS_SETBIT(cpu, bit) do { (cpu)->status |= (bit); } while (0)
179 #define RVM_STATUS_CLRBIT(cpu, bit) do { (cpu)->status &= ~(bit); } while (0)
180 #define RVM_STATUS_CLRALL(cpu) RVM_STATUS_CLRBIT(cpu, RVM_STATUS_ALL)
181
182 #define RVM_STATUS_UPDATE(cpu, b, c) \
183 do { \
184     if (c) \
185         RVM_STATUS_SETBIT(cpu, b); \
186     else \
187         RVM_STATUS_CLRBIT(cpu, b); \
188 } while (0)
189
190 #define RVM_OPERAND_BITS 4
191 #define RVM_REGS_NUM (1 << RVM_OPERAND_BITS)
192 #define R0 0
193 #define R1 1
194 #define R2 2
195 #define R3 3
196 #define R4 4
197 #define R5 5
198 #define R6 6
199 #define R7 7
200 #define R8 8
201 #define R9 9
202 #define R10 10
203 #define R11 11
204 #define R12 12
205 #define R13 13
206 #define R14 14
207 #define R15 15
208 #define R16 16
209 #define R17 17
210 #define R18 18
211 #define R19 19
212 #define R20 20
213 #define R21 21
214 #define R22 22
215 #define R23 23
216 #define R24 24
217 #define R25 25
218 #define R26 26
219 #define R27 27
220 #define R28 28
221 #define R29 29
222 #define R30 30
223 #define R31 31
224
225 #define RLST (RVM_REGS_NUM - 1)
226 #define IP (RLST - 7)
227 #define TP (RLST - 6)
228 #define FP (RLST - 5)
229 #define SP (RLST - 4)
230 #define LR (RLST - 3)
231 #define PC (RLST - 2)
232 #define DA (RLST - 1)                           /* The DA register should never be modified manually, otherwise the result is undefined */
233 #define XX (RLST)
234
235
236 #define RVM_STACK_CHUNK 256
237 #define RVM_ABORT(__cpu__, __e__) do { __cpu__->error = (__e__); (__cpu__)->abort = 1; ASSERT(0); return; } while (0)
238 #define BIT(__shiftby__) (1 << (__shiftby__))
239 #define BITR(__f__, __l__, __r__) (((__r__) >= (__f__) && (__r__) <= (__l__)) ? BIT(__r__) : 0)
240 #define BITS(__f__, __l__)  (BITR(__f__, __l__, R0)) | (BITR(__f__, __l__, R1)) | (BITR(__f__, __l__, R2)) | (BITR(__f__, __l__, R3)) | \
241                                                         (BITR(__f__, __l__, R4)) | (BITR(__f__, __l__, R5)) | (BITR(__f__, __l__, R6)) | (BITR(__f__, __l__, R7)) | \
242                                                         (BITR(__f__, __l__, R8)) | (BITR(__f__, __l__, R9)) | (BITR(__f__, __l__, R10)) | (BITR(__f__, __l__, R11)) | \
243                                                         (BITR(__f__, __l__, R12)) | (BITR(__f__, __l__, R13)) | (BITR(__f__, __l__, R14)) | (BITR(__f__, __l__, R15)) | \
244                                                         (BITR(__f__, __l__, R16)) | (BITR(__f__, __l__, R17)) | (BITR(__f__, __l__, R18)) | (BITR(__f__, __l__, R19)) | \
245                                                         (BITR(__f__, __l__, R20)) | (BITR(__f__, __l__, R21)) | (BITR(__f__, __l__, R22)) | (BITR(__f__, __l__, R23)) | \
246                                                         (BITR(__f__, __l__, R24)) | (BITR(__f__, __l__, R25)) | (BITR(__f__, __l__, R26)) | (BITR(__f__, __l__, R27)) | \
247                                                         (BITR(__f__, __l__, R28)) | (BITR(__f__, __l__, R29)) | (BITR(__f__, __l__, R30)) | (BITR(__f__, __l__, R31))
248
249 #define RVM_OPCODE_BITS 8
250 #define RVM_SWI_TABLE_BITS 8
251 #define RVM_SWI_NUM_BITS 8
252 #define RVM_SWI_TABLE(__op__) ((__op__) >> RVM_SWI_NUM_BITS)
253 #define RVM_SWI_NUM(__op__) ((__op__) & ((1 << RVM_SWI_NUM_BITS) - 1))
254 #define RVM_SWI_ID(__t__, __o__) ((((__t__) & ((1 << RVM_SWI_TABLE_BITS) - 1))  << RVM_SWI_NUM_BITS) | ((__o__) & ((1 << RVM_SWI_NUM_BITS) - 1)))
255 #define RVM_ASMINS_OPCODE(__opcode__) ((__opcode__) & ((1 << RVM_OPCODE_BITS) - 1))
256 #define RVM_ASMINS_SWI(__opcode__) ((__opcode__) >> RVM_OPCODE_BITS)
257 #define RVM_OPSWI(__id__) (((__id__) << RVM_OPCODE_BITS) | RVM_SWI)
258
259 //#define RVM_STACK_WRITE(__s__, __sp__, __p__) r_carray_replace((__s__), (__sp__), (rconstpointer)(__p__));
260 //#define RVM_STACK_READ(__s__, __sp__) r_carray_index((__s__), (__sp__), rvmreg_t)
261 //#define RVM_STACK_ADDR(__s__, __sp__) r_carray_slot_expand((__s__), (__sp__))
262
263
264 #define RVM_STACK_WRITE(__s__, __sp__, __p__) do { r_memcpy(((rvmreg_t*)(__s__)) + (__sp__), (__p__), sizeof(rvmreg_t)); } while(0)
265 #define RVM_STACK_READ(__s__, __sp__) *RVM_STACK_ADDR(__s__, __sp__)
266 #define RVM_STACK_ADDR(__s__, __sp__) (((rvmreg_t*)(__s__)) + (__sp__))
267 #define RVM_STACK_CHECKSIZE(__cpu__, __s__, __sp__)  ((__sp__) < (__cpu__)->stacksize ? 1 : 0)
268 #define RVM_CODE2BYTE_OFFSET(__codeoff__) ((rword)(((rsword)(__codeoff__)) * ((rsword)sizeof(rvm_asmins_t))))
269 #define RVM_BYTE2CODE_OFFSET(__byteoff__) ((rword)(((rsword)(__byteoff__)) / ((rsword)sizeof(rvm_asmins_t))))
270
271 #define RVM_E_DIVZERO           (1)
272 #define RVM_E_ILLEGAL           (2)
273 #define RVM_E_CAST                      (3)
274 #define RVM_E_SWINUM            (4)
275 #define RVM_E_SWITABLE          (5)
276 #define RVM_E_LVALUE            (6)
277 #define RVM_E_NOMEM                     (7)
278 #define RVM_E_NOTFUNCTION       (8)
279 #define RVM_E_NOTOBJECT         (9)
280
281 typedef struct rvm_asmins_s rvm_asmins_t;
282 typedef struct rvmcpu_s rvmcpu_t;
283 typedef void (*rvmcpu_swi)(rvmcpu_t *cpu, rvm_asmins_t *ins);
284 typedef void (*rvm_cpu_op)(rvmcpu_t *cpu, rvm_asmins_t *ins);
285
286 typedef struct rvm_switable_s {
287         const char *name;
288         rvmcpu_swi op;
289 } rvm_switable_t;
290
291
292 #define RVM_ASMINS_RELOC (1 << 0)
293
294 struct rvm_asmins_s {
295         rvmreg_t data;
296         ruint16 op1:RVM_OPERAND_BITS;
297         ruint16 op2:RVM_OPERAND_BITS;
298         ruint16 op3:RVM_OPERAND_BITS;
299         ruint16 da:1;
300         ruint16 swi;
301         ruint8 flags;
302         ruint8 opcode;
303 };
304
305
306 struct rvm_opmap_s;
307
308 struct rvmcpu_s {
309         rvmreg_t r[RVM_REGS_NUM];
310         rword status;
311         rword error;
312         rword abort;
313         rarray_t *switables;
314         rulong stacksize;
315         void *stack;
316         rcarray_t *data;
317         struct rvm_opmap_s *opmap;
318         rvmreg_t *thisptr;
319         rvm_gc_t *gc;
320         void *userdata1;
321         void *userdata2;
322         void *userdata3;
323         void *userdata4;
324         void *userdata5;
325         void *userdata6;
326         void *userdata7;
327 };
328
329
330 rvmcpu_t *rvm_cpu_create_default();
331 rvmcpu_t *rvm_cpu_create(rulong stacksize);
332 void rvm_cpu_destroy(rvmcpu_t * vm);
333 rint rvm_cpu_addswitable(rvmcpu_t * cpu, rvm_switable_t *switalbe);
334 rint rvm_cpu_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off);
335 rint rvm_cpu_exec_debug(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off);
336 rint rvm_cpu_getswi(rvmcpu_t *cpu, const rchar *swiname, rsize_t size);
337 rint rvm_cpu_getswi_s(rvmcpu_t *cpu, const rchar *swiname);
338 rvmreg_t *rvm_cpu_alloc_global(rvmcpu_t *cpu);
339 int rvm_cpu_setreg(rvmcpu_t *cpu, rword regnum, const rvmreg_t *src);
340 rvmreg_t *rvm_cpu_getreg(rvmcpu_t *cpu, rword regnum);
341 rvm_asmins_t rvm_asm(rword opcode, rword op1, rword op2, rword op3, rword data);
342 rvm_asmins_t rvm_asma(rword opcode, rword op1, rword op2, rword op3, rchar *data, rulong size);
343 rvm_asmins_t rvm_asml(rword opcode, rword op1, rword op2, rword op3, rlong data);
344 rvm_asmins_t rvm_asmb(rword opcode, rword op1, rword op2, rword op3, ruint data);
345 rvm_asmins_t rvm_asmd(rword opcode, rword op1, rword op2, rword op3, rdouble data);
346 rvm_asmins_t rvm_asmp(rword opcode, rword op1, rword op2, rword op3, rpointer data);
347 rvm_asmins_t rvm_asms(rword opcode, rword op1, rword op2, rword op3, rword data);
348 rvm_asmins_t rvm_asmf(rword opcode, rword op1, rword op2, rword op3, rword data);
349 rvm_asmins_t rvm_asm2(rword opcode, rword op1, rword op2, rword op3, ruint32 p1, ruint32 p2);
350 rvm_asmins_t rvm_asmr(rword opcode, rword op1, rword op2, rword op3, rpointer pReloc);
351 rvm_asmins_t rvm_asmx(rword opcode, rword op1, rword op2, rword op3, rpointer pReloc);
352 void rvm_asm_dump(rvm_asmins_t *pi, ruint count);
353
354
355 #ifdef __cplusplus
356 }
357 #endif
358
359
360 #endif