RPA Toolkit
e272b800d0922b1bed42a35e779cfe8997995288
[rpatk.git] / rvm / rvmoperator.c
1 #include "rmem.h"
2 #include "rvmoperator.h"
3
4
5 rvm_opmap_t *rvm_opmap_create()
6 {
7         rvm_opmap_t *opmap;
8
9         opmap = (rvm_opmap_t*)r_malloc(sizeof(*opmap));
10         if (!opmap)
11                 return NULL;
12         r_memset(opmap, 0, sizeof(*opmap));
13         opmap->operators = r_array_create(sizeof(rvm_opinfo_t));
14         return opmap;
15 }
16
17
18 void rvm_opmap_destroy(rvm_opmap_t *opmap)
19 {
20         int i;
21         rvm_opinfo_t *opinfo;
22
23
24         if (!opmap)
25                 return;
26         for (i = 0; i < opmap->operators->len; i++) {
27                 opinfo = ((rvm_opinfo_t*)r_array_slot(opmap->operators, i));
28                 r_free(opinfo->handlers);
29         }
30         r_array_destroy(opmap->operators);
31         r_free(opmap);
32 }
33
34
35 void rvm_opmap_add_binary_operator(rvm_opmap_t *opmap, rushort opid)
36 {
37         rvm_opinfo_t opinfo;
38
39         r_memset(&opinfo, 0, sizeof(opinfo));
40         opinfo.opid = opid;
41         opinfo.handlers = r_malloc(RVM_DTYPE_MAX * RVM_DTYPE_MAX * sizeof(rvm_ophandler_t));
42         r_array_replace(opmap->operators, opid, &opinfo);
43 }
44
45
46 void rvm_opmap_add_unary_operator(rvm_opmap_t *opmap, rushort opid)
47 {
48         rvm_opinfo_t opinfo;
49
50         r_memset(&opinfo, 0, sizeof(opinfo));
51         opinfo.opid = opid;
52         opinfo.unary = TRUE;
53         opinfo.handlers = r_malloc(RVM_DTYPE_MAX * sizeof(rvm_ophandler_t));
54         r_array_replace(opmap->operators, opid, &opinfo);
55 }
56
57
58 rint rvm_opmap_set_binary_handler(rvm_opmap_t *opmap, rushort opid, rvm_binaryop_handler func, ruchar firstType, ruchar secondType)
59 {
60         rvm_ophandler_t *h;
61         rvm_opinfo_t *opinfo = ((rvm_opinfo_t*)r_array_slot(opmap->operators, opid));
62         if (!opinfo->handlers)
63                 return -1;
64         h = &opinfo->handlers[RVM_OP_HANDLER(firstType, secondType)];
65         h->op = func;
66         return 0;
67 }
68
69
70 rint rvm_opmap_set_unary_handler(rvm_opmap_t *opmap, rushort opid, rvm_unaryop_handler func, ruchar type)
71 {
72         rvm_ophandler_t *h;
73         rvm_opinfo_t *opinfo = ((rvm_opinfo_t*)r_array_slot(opmap->operators, opid));
74         if (!opinfo->handlers)
75                 return -1;
76         h = &opinfo->handlers[RVM_UNARY_HANDLER(type)];
77         h->unary = func;
78         return 0;
79 }
80
81
82 void rvm_opmap_invoke_binary_handler(rvm_opmap_t *opmap, rushort opid, rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
83 {
84         rvm_ophandler_t *h;
85         rvm_opinfo_t *opinfo;
86         ruint index = RVM_OP_HANDLER(RVM_REG_GETTYPE(arg1), RVM_REG_GETTYPE(arg2));
87
88         if (opid >= opmap->operators->len)
89                 goto error;
90         opinfo = ((rvm_opinfo_t*)r_array_slot(opmap->operators, opid));
91         h = &opinfo->handlers[index];
92         if (h->op == NULL)
93                 goto error;
94         h->op(cpu, res, arg1, arg2);
95         return;
96
97 error:
98         cpu->error = RVM_E_ILLEGAL;
99         cpu->abort = 1;
100 }
101
102
103 void rvm_opmap_invoke_unary_handler(rvm_opmap_t *opmap, rushort opid, rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg)
104 {
105         rvm_ophandler_t *h;
106         rvm_opinfo_t *opinfo;
107         ruint index = RVM_UNARY_HANDLER(RVM_REG_GETTYPE(arg));
108
109         if (opid >= opmap->operators->len)
110                 goto error;
111         opinfo = ((rvm_opinfo_t*)r_array_slot(opmap->operators, opid));
112         h = &opinfo->handlers[index];
113         if (h->unary == NULL)
114                 goto error;
115         h->unary(cpu, res, arg);
116         return;
117
118 error:
119         cpu->error = RVM_E_ILLEGAL;
120         cpu->abort = 1;
121 }