kulp / tenyr
1
#include "ops.h"
2
#include "common.h"
3

4
#include "jit.h"
5
#include "lightning.h"
6

7
// GNU Lightning's macros expect `_jit` to be a jit_state_t pointer
8
#define _jit (*(jit_state_t**)(&s->jj))
9

10 1
void jit_init(struct jit_state **pstate)
11
{
12 1
    init_jit(NULL);
13 1
    *pstate = calloc(1, sizeof **pstate);
14
}
15

16 1
void jit_fini(struct jit_state *s)
17
{
18 1
    if (s->jj != NULL)
19 1
        jit_destroy_state();
20 1
    finish_jit();
21
}
22

23 1
static void build_op(struct jit_state *s, int op, int result, int a, int b)
24
{
25 1
    switch (op & 0xf) {
26 1
        case OP_ADD:                jit_addr(result, a, b);     break;
27 1
        case OP_SUBTRACT:           jit_subr(result, a, b);     break;
28 1
        case OP_BITWISE_ANDN:       jit_comr(b, b);             /* FALLTHROUGH */
29 1
        case OP_BITWISE_AND:        jit_andr(result, a, b);     break;
30 1
        case OP_BITWISE_ORN:        jit_comr(b, b);             /* FALLTHROUGH */
31 1
        case OP_BITWISE_OR:         jit_orr(result, a, b);      break;
32 1
        case OP_BITWISE_XOR:        jit_xorr(result, a, b);     break;
33 1
        case OP_MULTIPLY:           jit_mulr(result, a, b);     break;
34

35 1
        case OP_SHIFT_RIGHT_LOGIC:  jit_rshr_u(result, a, b);   break;
36 1
        case OP_SHIFT_RIGHT_ARITH:  jit_rshr(result, a, b);     break;
37 1
        case OP_SHIFT_LEFT:         jit_lshr(result, a, b);     break;
38

39 1
        case OP_PACK:
40 1
            jit_lshi(a, a, 12);
41 1
            jit_andi(b, b, 0xfff);
42 1
            jit_orr(result, a, b);
43 1
            break;
44

45 1
        case OP_TEST_BIT:
46 1
            jit_movi(result, 1);
47 1
            jit_lshr(result, result, b);
48 1
            jit_andr(result, result, a);
49 1
            jit_nei(result, result, 0);
50 1
            jit_negr(result, result);
51 1
            break;
52

53 1
        case OP_COMPARE_LT:
54 1
            jit_ltr(result, a, b);
55 1
            jit_negr(result, result);
56 1
            break;
57

58 1
        case OP_COMPARE_EQ:
59 1
            jit_eqr(result, a, b);
60 1
            jit_negr(result, result);
61 1
            break;
62

63 1
        case OP_COMPARE_GE:
64 1
            jit_ger(result, a, b);
65 1
            jit_negr(result, result);
66 1
            break;
67
    }
68
}
69

70 1
static void build_insn(struct jit_state *s, insn in, int offset)
71
{
72 1
    const struct instruction_type012 t = in.type012;
73 1
    const struct instruction_type3   v = in.type3;
74

75 1
    const int x = JIT_R0;
76 1
    const int y = JIT_R1;
77 1
    const int i = JIT_R2;
78

79 1
    const int ss = JIT_V0;
80 1
    const int regs = JIT_V1;
81 1
    const int result = JIT_V2;
82

83 1
    if (t.x) {
84 1
        jit_ldxi_i(x, regs, t.x * 4);
85 1
        if (t.x == 15)
86 1
            jit_addi(x, x, offset + 1);
87
    } else {
88 1
        jit_movi(x, 0);
89
    }
90

91 1
    if (t.p == 3) {
92 1
        jit_addi(result, x, SEXTEND32(MEDIUM_IMMEDIATE_BITWIDTH,v.imm));
93
    } else {
94 1
        if (t.y) {
95 1
            jit_ldxi_i(y, regs, t.y * 4);
96 1
            if (t.y == 15)
97 1
                jit_addi(y, y, offset + 1);
98
        } else {
99 1
            jit_movi(y, 0);
100
        }
101 1
        jit_movi(i, SEXTEND32(SMALL_IMMEDIATE_BITWIDTH,t.imm));
102

103 1
        int a = -1, b = -1, c = -1;
104 1
        switch (t.p) {
105 1
            case 0: a = x; b = y; c = i; break;
106 1
            case 1: a = x; b = i; c = y; break;
107 1
            case 2: a = i; b = x; c = y; break;
108
        }
109

110 1
        build_op(s, t.op, result, a, b);
111 1
        jit_addr(result, result, c);
112
    }
113

114 1
    const int tmp = JIT_R0; // reuse
115

116 1
    switch (t.dd) {
117 1
        case 0:
118 1
            if (t.z)
119 1
                jit_stxi_i(t.z * 4, regs, result);
120 1
            break;
121 1
        case 1:
122 1
            jit_ldxi_i(tmp, regs, t.z * 4);
123 1
            jit_prepare();
124 1
            jit_pushargr(ss);
125 1
            jit_pushargr(result);
126 1
            jit_pushargr(tmp);
127 1
            jit_finishi(s->ops.store);
128 1
            break;
129 1
        case 2:
130 1
            jit_ldxi_i(tmp, regs, t.z * 4);
131 1
            jit_prepare();
132 1
            jit_pushargr(ss);
133 1
            jit_pushargr(tmp);
134 1
            jit_pushargr(result);
135 1
            jit_finishi(s->ops.store);
136 1
            break;
137 1
        case 3:
138 1
            jit_prepare();
139 1
            jit_pushargr(ss);
140 1
            jit_pushargr(result);
141 1
            jit_finishi(s->ops.fetch);
142 1
            jit_retval_i(tmp);
143 1
            if (t.z)
144 1
                jit_stxi_i(t.z * 4, regs, tmp);
145 1
            break;
146
    }
147
}
148

149 1
Block *jit_gen_block(struct jit_state *s, int len, int32_t *instructions)
150
{
151 1
    s->jj = jit_new_state();
152

153 1
    jit_prolog();
154 1
    jit_frame(3 * 8);
155 1
    jit_node_t *ss = jit_arg();
156 1
    jit_getarg(JIT_V0, ss);
157 1
    jit_node_t *rr = jit_arg();
158 1
    jit_getarg(JIT_V1, rr);
159

160 1
    for (int i = 0; i < len; i++)
161 1
        build_insn(s, (insn){ .word = instructions[i] }, i);
162

163 1
    jit_ret();
164 1
    jit_epilog();
165

166 1
    Block *result = jit_emit();
167 1
    jit_clear_state();
168

169 1
    return result;
170
}

Read our documentation on viewing source code .

Loading