tagged release 0.6.4
[parrot.git] / src / jit / sun4 / jit_emit.h
blob4e81d98c4fa8c4ac26475ae77b2da4b542577001
1 /*
2 * Copyright (C) 2002-2008, The Perl Foundation.
3 */
5 /*
6 ** jit_emit.h
7 **
8 ** SPARC
9 **
10 ** $Id$
11 **/
13 #ifndef PARROT_SUN4_JIT_EMIT_H_GUARD
14 #define PARROT_SUN4_JIT_EMIT_H_GUARD
16 /* XXX As of rev 11423, sun4 jit no longer compiles due to the missing
17 Parrot_jit_init() function and the corresponding arch_info structure.
18 Prior to that, it compiled, but probably didn't work. See notes labeled
19 XXX Hack [perl #37819] below.
23 * SPARC JIT overview:
25 * The interpreter pointer is kept in i0.
26 * The address of register I0 is stored in i1, with all parrot register access
27 * performed relative to this register.
28 * The address of the opcode - native code mapping array is kept in i3.
30 * See IMPORTANT SHORTCUTS below.
33 /* Sparc register numbers */
34 #define emitm_g(n) (n)
35 #define emitm_o(n) ((n) + 8)
36 #define emitm_l(n) ((n) + 16)
37 #define emitm_i(n) ((n) + 24)
38 #define emitm_f(n) (n)
40 #if JIT_EMIT
42 # define emitm_FP emitm_i(6)
43 # define emitm_SP emitm_o(6)
45 # define emitm_mask(n, val) ((unsigned)(val) & ((1U << (n)) - 1))
47 # define emitm_hi30(val) ((unsigned)(val) >> 2)
48 # define emitm_hi22(val) ((unsigned)(val) >> 10)
49 # define emitm_lo10(val) emitm_mask(10, (val))
50 # define emitm_simm13(val) emitm_mask(13, (val))
52 # define emitm_opval(val) ((unsigned)(val) << 30)
53 # define emitm_op2val(val) ((unsigned)(val) << 22)
54 # define emitm_op3val(val) ((unsigned)(val) << 19)
55 # define emitm_rd(val) ((unsigned)(val) << 25)
56 # define emitm_rs1(val) ((unsigned)(val) << 14)
58 # define emitm_simm13_max 4095
59 # define emitm_simm13_min -4096
61 # define emitm_simm13_const(val) (((val) >= emitm_simm13_min) && ((val) < emitm_simm13_max))
63 # define emitm_branch_max 8388607
64 # define emitm_branch_min -8388608
66 /* format 1 - only instruction */
67 # define emitm_call_30(pc, disp30) { \
68 *(unsigned *)(pc) = emitm_opval(1) | (disp30); \
69 pc += 4; }
71 /* format 2a - sethi primarily */
72 # define emitm_2a(pc, op, rd, op2, imm22) { \
73 *(unsigned *)(pc) = emitm_opval(op) | emitm_rd(rd) | emitm_op2val(op2) | \
74 (imm22); \
75 pc += 4; }
77 /* format 2b - branches */
78 # define emitm_2b(pc, a, cond, op2, disp22) { \
79 *(unsigned *)(pc) = emitm_opval(0) | ((unsigned)(a) << 29) | \
80 ((unsigned)(cond) << 25) | emitm_op2val(op2) | \
81 emitm_mask(22, disp22); \
82 pc += 4; }
84 /* Generic fields of format 3 */
85 # define emitm_fmt3(pc, op, rd, op3, rs1, low14) { \
86 *(unsigned *)pc = emitm_opval(op) |emitm_rd(rd) | emitm_op3val(op3) | \
87 emitm_rs1(rs1) | (low14); \
88 pc +=4 ; }
90 /* format 3a */
91 # define emitm_3a(pc, op, rd, op3, rs1, asi, rs2) \
92 emitm_fmt3(pc, op, rd, op3, rs1, ((asi) << 5) | (rs2))
94 /* format 3b */
95 # define emitm_3b(pc, op, rd, op3, rs1, simm13) \
96 emitm_fmt3(pc, op, rd, op3, rs1, (1L << 13) | emitm_mask(13, (simm13)))
98 /* format 3c */
99 # define emitm_3c(pc, op, rd, op3, rs1, opf, rs2) \
100 emitm_fmt3(pc, op, rd, op3, rs1, (opf << 5) | (rs2))
102 /* Miscellaneous instructions */
104 /* sethi imm22, r[rd] */
105 # define emitm_sethi(pc, imm22, rd) emitm_2a((pc), 0, (rd), 04, (imm22))
107 /* NOP */
108 # define emitm_nop(pc) emitm_sethi((pc), 0, 0)
110 /* SAVE */
112 # define emitm_save_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 074, (rs1), 0, (rs2))
113 # define emitm_save_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 074, (rs1), (i))
115 /* RESTORE */
116 # define emitm_restore_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 075, (rs1), 0, (rd))
117 # define emitm_restore_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 075, (rs1), (i))
119 /* MOV */
120 # define emitm_mov_r(pc, rs, rd) emitm_or_r((pc), emitm_g(0), (rs), (rd))
121 # define emitm_mov_i(pc, i, rd) emitm_or_i((pc), emitm_g(0), (i), (rd))
123 /* Integer Register Loads */
125 /* ldX[rs1 + simm13], rd */
126 # define emitm_ldsb_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 011, (rs1), (i))
127 # define emitm_ldub_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 001, (rs1), (i))
128 # define emitm_ldsh_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 012, (rs1), (i))
129 # define emitm_lduh_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 002, (rs1), (i))
130 # define emitm_ld_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 000, (rs1), (i))
131 # define emitm_ldd_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 003, (rs1), (i))
133 /* ldX[rs1 + rs2], rd */
134 # define emitm_ldsb_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 011, (rs1), 0, (rs2))
135 # define emitm_ldub_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 001, (rs1), 0, (rs2))
136 # define emitm_ldsh_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 012, (rs1), 0, (rs2))
137 # define emitm_lduh_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 002, (rs1), 0, (rs2))
138 # define emitm_ld_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 000, (rs1), 0, (rs2))
139 # define emitm_ldd_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 003, (rs1), 0, (rs2))
141 /* Integer Register Stores */
143 /* stX rd, [rs1 + simm13] */
144 # define emitm_stb_i(pc, rd, rs1, i) emitm_3b((pc), 3, (rd), 005, (rs1), (i))
145 # define emitm_sth_i(pc, rd, rs1, i) emitm_3b((pc), 3, (rd), 006, (rs1), (i))
146 # define emitm_st_i(pc, rd, rs1, i) emitm_3b((pc), 3, (rd), 004, (rs1), (i))
147 # define emitm_std_i(pc, rd, rs1, i) emitm_3b((pc), 3, (rd), 007, (rs1), (i))
149 /* stX rd, [rs1 + rs2] */
150 # define emitm_stb_r(pc, rd, rs1, rs2) emitm_3a((pc), 3, (rd), 005, (rs1), 0, (rs2))
151 # define emitm_sth_r(pc, rd, rs1, rs2) emitm_3a((pc), 3, (rd), 006, (rs1), 0, (rs2))
152 # define emitm_st_r(pc, rd, rs1, rs2) emitm_3a((pc), 3, (rd), 004, (rs1), 0, (rs2))
153 # define emitm_std_r(pc, rd, rs1, rs2) emitm_3a((pc), 3, (rd), 007, (rs1), 0, (rs2))
155 /* Floating Point Register Loads */
157 /* ldX[rs1 + simm13], freg[rd] */
158 # define emitm_ldf_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 040, (rs1), (i))
159 # define emitm_lddf_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 043, (rs1), (i))
161 # define emitm_ldfsr_i(pc, rs1, i, rd) emitm_3b((pc), 3, (rd), 041, (rs1), (i))
163 /* ldX[rs1 + rs2], freg[rd] */
164 # define emitm_ldf_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 040, (rs1), 0, (rs2))
165 # define emitm_lddf_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 043, (rs1), 0, (rs2))
167 # define emitm_ldfsr_r(pc, rs1, rs2, rd) emitm_3a((pc), 3, (rd), 041, (rs1), 0, (rs2))
169 /* Floating Point Register Stores */
171 /* stX freg[rd], [rs1 + simm13] */
172 # define emitm_stf_i(pc, rd, rs1, i) emitm_3b((pc), 3, (rd), 044, (rs1), (i))
173 # define emitm_stdf_i(pc, rd, rs1, i) emitm_3b((pc), 3, (rd), 047, (rs1), (i))
175 # define emitm_stfsr_i(pc, rd, rs1, i) emitm_3b((pc), 3, (rd), 045, (rs1), (i))
177 /* stX freg[rd], [rs1 + rs2] */
178 # define emitm_stf_r_r(pc, rd, rs1, rs2) emitm_3a((pc), 3, (rd), 044, (rs1), 0, (rs2))
179 # define emitm_stdf_r_r(pc, rd, rs1, rs2) emitm_3a((pc), 3, (rd), 047, (rs1), 0, (rs2))
180 # define emitm_stfsr_r_r(pc, rd, rs1, rs2) emitm_3a((pc), 3, (rd), 045, (rs1), 0, (rs2))
182 /* Logical instructions */
184 /* op r[rs1], r[rs2], r[rd] */
185 # define emitm_logic_r(pc, op3, rs1, rs2, rd) \
186 emitm_3a((pc), 2, (rd), (op3), (rs1), 0, (rs2))
188 /* op r[rs1], simm13, r[rd] */
189 # define emitm_logic_i(pc, op3, rs1, simm13, rd) \
190 emitm_3b((pc), 2, (rd), (op3), (rs1), (simm13))
192 # define emitm_and_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 001, (rs1), (rs2), (rd))
193 # define emitm_andcc_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 021, (rs1), (rs2), (rd))
194 # define emitm_andn_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 005, (rs1), (rs2), (rd))
195 # define emitm_andncc_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 025, (rs1), (rs2), (rd))
196 # define emitm_and_i(pc, rs1, i, rd) emitm_logic_i((pc), 001, (rs1), (i), (rd))
197 # define emitm_andcc_i(pc, rs1, i, rd) emitm_logic_i((pc), 021, (rs1), (i), (rd))
198 # define emitm_andn_i(pc, rs1, i, rd) emitm_logic_i((pc), 005, (rs1), (i), (rd))
199 # define emitm_andncc_i(pc, rs1, i, rd) emitm_logic_i((pc), 025, (rs1), (i), (rd))
200 # define emitm_or_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 002, (rs1), (rs2), (rd))
201 # define emitm_orcc_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 022, (rs1), (rs2), (rd))
202 # define emitm_orn_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 006, (rs1), (rs2), (rd))
203 # define emitm_orncc_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 026, (rs1), (rs2), (rd))
204 # define emitm_or_i(pc, rs1, i, rd) emitm_logic_i((pc), 002, (rs1), (i), (rd))
205 # define emitm_orcc_i(pc, rs1, i, rd) emitm_logic_i((pc), 022, (rs1), (i), (rd))
206 # define emitm_orn_i(pc, rs1, i, rd) emitm_logic_i((pc), 006, (rs1), (i), (rd))
207 # define emitm_orncc_i(pc, rs1, i, rd) emitm_logic_i((pc), 026, (rs1), (i), (rd))
208 # define emitm_xor_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 003, (rs1), (rs2), (rd))
209 # define emitm_xorcc_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 023, (rs1), (rs2), (rd))
210 # define emitm_xorn_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 007, (rs1), (rs2), (rd))
211 # define emitm_xorncc_r(pc, rs1, rs2, rd) emitm_logic_r((pc), 027, (rs1), (rs2), (rd))
212 # define emitm_xor_i(pc, rs1, i, rd) emitm_logic_i((pc), 003, (rs1), (i), (rd))
213 # define emitm_xorcc_i(pc, rs1, i, rd) emitm_logic_i((pc), 023, (rs1), (i), (rd))
214 # define emitm_xorn_i(pc, rs1, i, rd) emitm_logic_i((pc), 007, (rs1), (i), (rd))
215 # define emitm_xorncc_i(pc, rs1, i, rd) emitm_logic_i((pc), 027, (rs1), (i), (rd))
217 /* Shift Left Logical */
218 # define emitm_sll_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 045, (rs1), 0, (rs2))
219 # define emitm_sll_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 045, (rs1), (i))
221 /* Shift Right Logical */
222 # define emitm_srl_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 046, (rs1), 0, (rs2))
223 # define emitm_srl_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 046, (rs1), (i))
225 /* Shift Right Arithmetic */
226 # define emitm_sra_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 047, (rs1), 0, (rs2))
227 # define emitm_sra_i(pc, rs1, i, rd) emitm_3a((pc), 2, (rd), 047, (rs1), (i))
229 /* Arithmetic ops */
230 # define emitm_add_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 0, (rs1), 0, (rs2))
231 # define emitm_addcc_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 020, (rs1), 0, (rs2))
232 # define emitm_addX_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 010, (rs1), 0, (rs2))
233 # define emitm_addXcc_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 030, (rs1), 0, (rs2))
234 # define emitm_add_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 0, (rs1), (i))
235 # define emitm_addcc_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 020, (rs1), (i))
236 # define emitm_addX_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 010, (rs1), (i))
237 # define emitm_addXcc_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 030, (rs1), (i))
239 /* Arithmetic ops */
240 # define emitm_sub_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 004, (rs1), 0, (rs2))
241 # define emitm_subcc_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 024, (rs1), 0, (rs2))
242 # define emitm_subX_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 014, (rs1), 0, (rs2))
243 # define emitm_subXcc_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 034, (rs1), 0, (rs2))
244 # define emitm_sub_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 004, (rs1), (i))
245 # define emitm_subcc_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 024, (rs1), (i))
246 # define emitm_subX_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 014, (rs1), (i))
247 # define emitm_subXcc_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 034, (rs1), (i))
249 /* Floating point operations */
251 /* MOV */
252 # define emitm_fmovs(pc, rs, rd) emitm_3c((pc), 2, (rd), 064, 0, 0001, (rs))
254 /* Arithmetic operations */
255 # define emitm_faddd(pc, rs1, rs2, rd) emitm_3c((pc), 2, (rd), 064, (rs1), 0102, (rs2))
256 # define emitm_fsubd(pc, rs1, rs2, rd) emitm_3c((pc), 2, (rd), 064, (rs1), 0106, (rs2))
257 # define emitm_fmuld(pc, rs1, rs2, rd) emitm_3c((pc), 2, (rd), 064, (rs1), 0112, (rs2))
258 # define emitm_fdivd(pc, rs1, rs2, rd) emitm_3c((pc), 2, (rd), 064, (rs1), 0116, (rs2))
259 # define emitm_fabss(pc, rs, rd) emitm_3c((pc), 2, (rd), 064, 0, 0011, (rs))
260 # define emitm_fnegs(pc, rs, rd) emitm_3c((pc), 2, (rd), 064, 0, 0005, (rs))
262 # define emitm_fsqrtd(pc, rs, rd) emitm_3c((pc), 2, (rd), 064, 0, 0052, (rs))
264 /* Floating <-> Integer Conversion */
265 # define emitm_fitod(pc, rs, rd) emitm_3c((pc), 2, (rd), 064, 0, 0310, (rs))
266 # define emitm_fdtoi(pc, rs, rd) emitm_3c((pc), 2, (rd), 064, 0, 0322, (rs))
268 /* Floating point tests */
269 # define emitm_fcmpd(pc, rs1, rs2) emitm_3c((pc), 2, 0, 065, (rs1), 0122, (rs2))
271 /* Jump and Link */
273 # define emitm_jumpl_r(pc, rs1, rs2, rd) emitm_3a((pc), 2, (rd), 070, (rs1), 0, (rs2))
274 # define emitm_jumpl_i(pc, rs1, i, rd) emitm_3b((pc), 2, (rd), 070, (rs1), (i))
276 /* RET */
277 # define emitm_ret(pc) emitm_jumpl_i((pc), emitm_i(7), 8, emitm_g(0))
279 /* integer conditions */
280 # define emitm_ba 010
281 # define emitm_bn 000
282 # define emitm_bne 011
283 # define emitm_be 001
284 # define emitm_bg 012
285 # define emitm_ble 002
286 # define emitm_bge 013
287 # define emitm_bl 003
288 # define emitm_bgu 014
289 # define emitm_bleu 004
290 # define emitm_bcc 015
291 # define emitm_bcs 005
292 # define emitm_bpos 016
293 # define emitm_bneg 006
294 # define emitm_bvc 017
295 # define emitm_bvs 007
297 /* floating-point conditions */
298 # define emitm_fba 010
299 # define emitm_fbn 000
300 # define emitm_fbu 007
301 # define emitm_fbg 006
302 # define emitm_fbug 005
303 # define emitm_fbl 004
304 # define emitm_fbul 003
305 # define emitm_fblg 002
306 # define emitm_fbne 001
307 # define emitm_fbe 011
308 # define emitm_fbue 012
309 # define emitm_fbge 013
310 # define emitm_fbuge 014
311 # define emitm_fble 015
312 # define emitm_fbule 016
313 # define emitm_fbo 017
315 # define emitm_icc 02
316 # define emitm_fcc 06
318 /* Branch on integer condition codes */
319 # define emitm_bicc(pc, a, cond, disp22) emitm_2b((pc), (a), (cond), 02, (disp22))
321 /* Branch on floating-point condition codes */
322 # define emitm_fbfcc(pc, a, cond, disp22) emitm_2b((pc), (a), (cond), 06, (disp22))
324 # define jit_emit_mov_rr_i(pc, dst, src) emitm_mov_r((pc), (src), (dst))
325 # define jit_emit_mov_rr_n(pc, dst, src) { \
326 emitm_fmovs((pc), (src), (dst)); \
327 emitm_fmovs((pc), (src)+1, (dst)+1); }
330 void main(){
331 char ar[1024];
332 char *ar2;
334 ar2 = &ar[0];
335 emitm_ld_r(ar2, emitm_g(0), emitm_i(1), emitm_o(7));
336 emitm_ldub_r(ar2, emitm_g(0), emitm_i(1), emitm_o(7));
337 emitm_ldsh_r(ar2, emitm_g(0), emitm_i(1), emitm_o(7));
341 /* Fixup types */
342 enum {JIT_BRANCH, JIT_CALL30 };
346 * IMPORTANT SHORTCUTS
348 * */
350 /* The register holding the interpreter pointer */
351 # define Parrot_jit_intrp emitm_i(0)
353 /* The register holding the address of I0 */
354 # define Parrot_jit_regbase emitm_i(2)
356 /* The register containing the address of the opmap */
357 # define Parrot_jit_opmap emitm_i(3)
359 /* These registers should be used only in .jit ops and not helper routines
360 * in jit_emit.h
362 # define ISR1 emitm_i(4)
363 # define ISR2 emitm_i(5)
364 # define FSR1 emitm_f(0)
365 # define FSR2 emitm_f(2)
367 /* This register can be used only in jit_emit.h calculations */
368 # define XSR1 emitm_l(0)
369 # define XSR2 emitm_g(1)
371 # define Parrot_jit_regbase_ptr(interp) &REG_INT((interp), 0)
373 /* The offset of a Parrot register from the base register */
374 # define Parrot_jit_regoff(a, i) (unsigned)(a) - (unsigned)(Parrot_jit_regbase_ptr(i))
376 /* interp->code */
377 # define jit_emit_load_coderef(pc, reg) \
378 emitm_ld_i(jit_info->native_ptr, Parrot_jit_intrp, offsetof(Interp, code), (reg)); \
380 /* Load op_map address */
381 # define jit_emit_load_op_map(pc, code) \
382 emitm_ld_i(jit_info->native_ptr, (code), \
383 offsetof(PackFile_ByteCode, jit_info), XSR1); \
384 emitm_ld_i(jit_info->native_ptr, XSR1, \
385 (offsetof(Parrot_jit_arena_t, op_map) + offsetof(Parrot_jit_info_t, arena)), \
386 Parrot_jit_opmap);
388 /* Construct the starting address of the byte code (code start) */
389 # define jit_emit_load_code_start(pc, code) \
390 emitm_ld_i(jit_info->native_ptr, (code), offsetof(PackFile_Segment, data), \
391 XSR1);
393 /* Generate a jump to a bytecode address in reg_num
394 * - uses the temporary register
396 static void
397 Parrot_jit_bytejump(Parrot_jit_info_t *jit_info,
398 PARROT_INTERP, int reg_num)
400 jit_emit_load_coderef(jit_info->native_ptr, XSR2);
402 jit_emit_load_op_map(jit_info->native_ptr, XSR2);
403 jit_emit_load_code_start(jit_info->native_ptr, XSR2);
405 /* Calculates the offset into op_map shadow array
406 * assuming sizeof (opcode_t) == sizeof (opmap array entry) */
407 emitm_sub_r(jit_info->native_ptr, reg_num, XSR1, XSR1);
409 /* Load the address of the native code from op_map */
410 emitm_ld_r(jit_info->native_ptr, Parrot_jit_opmap, XSR1, XSR1);
412 /* This jumps to the address from op_map */
413 emitm_jumpl_i(jit_info->native_ptr, XSR1, 0, XSR1);
415 /* fixup where we have the Parrot registers - context switches */
416 emitm_ld_i(jit_info->native_ptr, Parrot_jit_intrp, offsetof(Interp, ctx.bp),
417 Parrot_jit_regbase);
420 /* Generate conditional branch to offset from current parrot op */
421 static void Parrot_jit_branch(Parrot_jit_info_t *jit_info, int branch, int cond,
422 int annul, opcode_t disp)
424 int offset;
425 opcode_t opcode;
427 opcode = jit_info->op_i + disp;
428 if (opcode <= jit_info->op_i){
429 offset = jit_info->arena.op_map[opcode].offset -
430 (jit_info->native_ptr - jit_info->arena.start);
432 if (jit_info->optimizer->cur_section->branch_target ==
433 jit_info->optimizer->cur_section)
434 offset +=
435 jit_info->optimizer->cur_section->branch_target->load_size;
437 if ((offset > emitm_branch_max) || (offset < emitm_branch_min))
438 internal_exception(JIT_ERROR,
439 "Branches beyond 8 Megabytes not yet supported\n");
440 offset /= 4;
441 emitm_2b(jit_info->native_ptr, annul, cond, branch, offset);
442 return;
445 Parrot_jit_newfixup(jit_info);
446 jit_info->arena.fixups->type = JIT_BRANCH;
447 jit_info->arena.fixups->param.opcode = opcode;
449 /* If the branch is to the current section, skip the load instructions. */
450 if (jit_info->optimizer->cur_section->branch_target ==
451 jit_info->optimizer->cur_section)
452 jit_info->arena.fixups->skip =
453 jit_info->optimizer->cur_section->branch_target->load_size;
455 emitm_2b(jit_info->native_ptr, annul, cond, branch, 0);
458 /* Generate branch on integer condition codes */
459 # define Parrot_jit_bicc(jit_info, cond, annul, disp) \
460 Parrot_jit_branch((jit_info), emitm_icc, (cond), (annul), (disp))
462 /* Generate branch on floating-point condition codes */
463 # define Parrot_jit_fbfcc(jit_info, cond, annul, disp) \
464 Parrot_jit_branch((jit_info), emitm_fcc, (cond), (annul), (disp))
466 /* This function loads a value */
467 static void jit_emit_load_i(Parrot_jit_info_t *jit_info,
468 PARROT_INTERP,
469 int param,
470 int hwreg)
472 opcode_t op_type;
473 int val;
475 op_type = interp->op_info_table[*jit_info->cur_op].types[param - 1];
476 val = jit_info->cur_op[param];
478 switch (op_type){
479 case PARROT_ARG_IC:
480 if ((val < emitm_simm13_min) || (val > emitm_simm13_max)){
481 emitm_sethi(jit_info->native_ptr, emitm_hi22(val), hwreg);
482 emitm_or_i(jit_info->native_ptr, hwreg, emitm_lo10(val),
483 hwreg);
485 else {
486 emitm_or_i(jit_info->native_ptr, emitm_g(0), val, hwreg);
489 break;
490 case PARROT_ARG_NC:
491 val = (int)&interp->code->const_table->
492 constants[val]->u.number;
494 /* Load double into integer registers */
495 emitm_sethi(jit_info->native_ptr, emitm_hi22(val), XSR1);
496 emitm_ldd_i(jit_info->native_ptr, XSR1, emitm_lo10(val),
497 hwreg);
498 break;
500 case PARROT_ARG_I:
501 val = (int)&REG_INT(interp, val);
502 emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
503 Parrot_jit_regoff(val, interp), hwreg);
504 break;
506 case PARROT_ARG_P:
507 val = (int)&REG_PMC(interp, val);
508 emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
509 Parrot_jit_regoff(val, interp), hwreg);
510 break;
512 case PARROT_ARG_S:
513 val = (int)&REG_STR(interp, val);
514 emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
515 Parrot_jit_regoff(val, interp), hwreg);
516 break;
518 case PARROT_ARG_N:
519 val = (int)&REG_NUM(interp, val);
520 emitm_ldd_i(jit_info->native_ptr, Parrot_jit_regbase,
521 Parrot_jit_regoff(val, interp), hwreg);
522 break;
524 default:
525 internal_exception(JIT_ERROR,
526 "Unsupported op parameter type %d\n",
527 op_type);
531 static void jit_emit_store_i(Parrot_jit_info_t *jit_info,
532 PARROT_INTERP,
533 int param,
534 int hwreg)
536 opcode_t op_type;
537 int val;
539 op_type = interp->op_info_table[*jit_info->cur_op].types[param - 1];
540 val = jit_info->cur_op[param];
542 switch (op_type){
543 case PARROT_ARG_I:
544 val = (int)&REG_INT(interp, val);
545 emitm_st_i(jit_info->native_ptr, hwreg, Parrot_jit_regbase,
546 Parrot_jit_regoff(val, interp));
547 break;
549 case PARROT_ARG_P:
550 val = (int)&REG_PMC(interp, val);
551 emitm_st_i(jit_info->native_ptr, hwreg, Parrot_jit_regbase,
552 Parrot_jit_regoff(val, interp));
553 break;
555 case PARROT_ARG_S:
556 val = (int)&REG_STR(interp, val);
557 emitm_st_i(jit_info->native_ptr, hwreg, Parrot_jit_regbase,
558 Parrot_jit_regoff(val, interp));
559 break;
561 case PARROT_ARG_N:
562 val = (int)&REG_NUM(interp, val);
563 emitm_std_i(jit_info->native_ptr, hwreg, Parrot_jit_regbase,
564 Parrot_jit_regoff(val, interp));
565 break;
567 default:
568 internal_exception(JIT_ERROR,
569 "Unsupported op parameter type %d\n", op_type);
573 static void jit_emit_load_n(Parrot_jit_info_t *jit_info,
574 PARROT_INTERP,
575 int param,
576 int hwreg)
578 opcode_t op_type;
579 long val;
581 op_type = interp->op_info_table[*jit_info->cur_op].types[param - 1];
582 val = jit_info->cur_op[param];
584 switch (op_type){
585 case PARROT_ARG_IC:
586 /* Load integer into floating point registers - should use
587 constant pool */
588 val = &jit_info->cur_op[param];
589 emitm_sethi(jit_info->native_ptr, emitm_hi22(val), XSR1);
590 emitm_ldf_i(jit_info->native_ptr, XSR1, emitm_lo10(val), hwreg);
591 break;
593 case PARROT_ARG_NC:
594 val = (int)&interp->code->const_table->
595 constants[val]->u.number;
597 /* Load double into floating point registers */
598 emitm_sethi(jit_info->native_ptr, emitm_hi22(val), XSR1);
599 emitm_lddf_i(jit_info->native_ptr, XSR1, emitm_lo10(val),
600 hwreg);
601 break;
603 case PARROT_ARG_I:
604 val = (int)&REG_INT(interp, val);
605 emitm_ldf_i(jit_info->native_ptr, Parrot_jit_regbase,
606 Parrot_jit_regoff(val, interp), hwreg);
607 break;
609 case PARROT_ARG_N:
610 val = (int)&REG_NUM(interp, val);
611 emitm_lddf_i(jit_info->native_ptr, Parrot_jit_regbase,
612 Parrot_jit_regoff(val, interp), hwreg);
613 break;
615 default:
616 internal_exception(JIT_ERROR,
617 "Unsupported op parameter type %d\n", op_type);
621 static void jit_emit_store_n(Parrot_jit_info_t *jit_info,
622 PARROT_INTERP,
623 int param,
624 int hwreg)
626 opcode_t op_type;
627 int val;
629 op_type = interp->op_info_table[*jit_info->cur_op].types[param - 1];
630 val = jit_info->cur_op[param];
632 switch (op_type){
633 case PARROT_ARG_I:
634 val = (int)&REG_INT(interp, val);
635 emitm_stf_i(jit_info->native_ptr, hwreg, Parrot_jit_regbase,
636 Parrot_jit_regoff(val, interp));
637 break;
639 case PARROT_ARG_N:
640 val = (int)&REG_NUM(interp, val);
641 emitm_stdf_i(jit_info->native_ptr, hwreg, Parrot_jit_regbase,
642 Parrot_jit_regoff(val, interp));
643 break;
645 default:
646 internal_exception(JIT_ERROR,
647 "Unsupported op parameter type %d\n", op_type);
652 void Parrot_jit_dofixup(Parrot_jit_info_t *jit_info,
653 PARROT_INTERP)
655 Parrot_jit_fixup_t *fixup;
656 Parrot_jit_fixup_t *last_fixup;
657 char *fixup_ptr;
658 int fixup_val;
660 fixup = jit_info->arena.fixups;
662 while (fixup){
663 switch (fixup->type){
664 /* This fixes-up a branch to a known opcode offset */
665 case JIT_BRANCH:
666 fixup_ptr = Parrot_jit_fixup_target(jit_info, fixup);
667 fixup_val = (jit_info->arena.op_map[fixup->param.opcode].offset
668 - fixup->native_offset + fixup->skip) / 4;
669 *(int *)(fixup_ptr) |= emitm_mask(22, fixup_val);
670 break;
672 case JIT_CALL30:
673 fixup_ptr = jit_info->arena.start + fixup->native_offset;
674 fixup_val = (int)fixup->param.fptr - (int)fixup_ptr;
675 emitm_call_30(fixup_ptr, emitm_hi30(fixup_val));
676 break;
678 default:
679 internal_exception(JIT_ERROR, "Unknown fixup type:%d\n",
680 fixup->type);
681 break;
683 fixup = fixup->next;
687 void
688 Parrot_jit_begin(Parrot_jit_info_t *jit_info,
689 PARROT_INTERP)
691 /* generated code is called as jit_code(interp, pc)
692 * so interpreter is in i0 and pc in i1.
693 * i1 is reusable once past the jump. interpreter is preserved in i0
695 int ireg0_offset;
696 int ireg0_address;
698 /* Standard Prolog */
699 emitm_save_i(jit_info->native_ptr, emitm_SP, -104, emitm_SP);
701 /* Calculate the offset of I0 in the interpreter struct */
702 ireg0_address = (int)Parrot_jit_regbase_ptr(interp);
703 ireg0_offset = ireg0_address - (int)interp;
705 /* All parrot registers will be addressed relative to I0 */
706 if ((ireg0_offset < emitm_simm13_min) || (ireg0_offset > emitm_simm13_max)){
707 /* Store the address of I0 if its offset doesnt fit in the immediate */
708 emitm_sethi(jit_info->native_ptr, emitm_hi22(ireg0_address), Parrot_jit_regbase);
709 emitm_or_i(jit_info->native_ptr, Parrot_jit_regbase, emitm_lo10(ireg0_address),
710 Parrot_jit_regbase);
712 else {
713 /* Calculate the address of I0 */
714 emitm_add_i(jit_info->native_ptr, Parrot_jit_intrp, ireg0_offset,
715 Parrot_jit_regbase);
718 /* Jump to the current pc */
719 Parrot_jit_bytejump(jit_info, interp, emitm_i(1));
722 void Parrot_jit_normal_op(Parrot_jit_info_t *jit_info,
723 PARROT_INTERP)
725 emitm_sethi(jit_info->native_ptr, emitm_hi22(jit_info->cur_op), emitm_o(0));
726 emitm_or_i(jit_info->native_ptr,
727 emitm_o(0), emitm_lo10(jit_info->cur_op), emitm_o(0));
729 Parrot_jit_newfixup(jit_info);
730 jit_info->arena.fixups->type = JIT_CALL30;
731 jit_info->arena.fixups->param.fptr =
732 (void (*)(void))interp->op_func_table[*(jit_info->cur_op)];
734 emitm_call_30(jit_info->native_ptr, 0);
735 emitm_mov_r(jit_info->native_ptr, Parrot_jit_intrp, emitm_o(1));
738 void Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info,
739 PARROT_INTERP)
741 Parrot_jit_normal_op(jit_info, interp);
742 Parrot_jit_bytejump(jit_info, interp, emitm_o(0));
745 # undef Parrot_jit_restart_op
746 void Parrot_jit_restart_op(Parrot_jit_info_t *jit_info,
747 PARROT_INTERP)
749 Parrot_jit_normal_op(jit_info, interp);
751 /* Test whether the return value is 0 */
752 emitm_subcc_r(jit_info->native_ptr, emitm_o(0), emitm_g(0), emitm_g(0));
754 /* If the return pc is not zero skip the next 3 instructions */
755 emitm_bicc(jit_info->native_ptr, 0, emitm_bne, 4);
756 emitm_nop(jit_info->native_ptr);
758 /* Return if the return pc is 0 */
759 emitm_ret(jit_info->native_ptr);
760 emitm_restore_i(jit_info->native_ptr, emitm_g(0), emitm_g(0), emitm_g(0));
762 Parrot_jit_bytejump(jit_info, interp, emitm_o(0));
765 /* move reg to mem (i.e. intreg) */
766 void
767 Parrot_jit_emit_mov_mr(PARROT_INTERP, char *mem, int reg)
769 emitm_st_i(((Parrot_jit_info_t *)(interp->code->jit_info))->native_ptr,
770 reg, Parrot_jit_regbase, Parrot_jit_regoff(mem, interp));
773 /* move mem (i.e. intreg) to reg */
774 void
775 Parrot_jit_emit_mov_rm(PARROT_INTERP, int reg, char *mem)
777 emitm_ld_i(((Parrot_jit_info_t *)(interp->code->jit_info))->native_ptr,
778 Parrot_jit_regbase, Parrot_jit_regoff(mem, interp), reg);
781 /* move reg to mem (i.e. numreg) */
782 void
783 Parrot_jit_emit_mov_mr_n(PARROT_INTERP, char *mem, int reg)
785 emitm_stdf_i(((Parrot_jit_info_t *)(interp->code->jit_info))->native_ptr,
786 reg, Parrot_jit_regbase, Parrot_jit_regoff(mem, interp));
789 /* move mem (i.e. numreg) to reg */
790 void
791 Parrot_jit_emit_mov_rm_n(PARROT_INTERP, int reg, char *mem)
793 emitm_lddf_i(((Parrot_jit_info_t *)(interp->code->jit_info))->native_ptr,
794 Parrot_jit_regbase, Parrot_jit_regoff(mem, interp), reg);
797 /* XXX Hack to fix the following bug as of 05 Dec 2005:
798 Hack [perl #37819] Sun4 builds fail linking against jit.o
799 These dummy definitions blindly copied from jit/mips/jit_emit.h.
800 Apparently, they need to be inside a JIT_EMIT section of this
801 file.
802 See also the "Hack [perl #37819]" section near the bottom of this
803 file.
805 void
806 Parrot_jit_emit_mov_mr_offs(PARROT_INTERP, int base, size_t offs, int reg)
810 void
811 Parrot_jit_emit_mov_rm_offs(PARROT_INTERP, int reg, int base, size_t offs)
815 void
816 Parrot_jit_emit_mov_mr_n_offs(PARROT_INTERP, int base, size_t offs, int reg)
820 void
821 Parrot_jit_emit_mov_rm_n_offs(PARROT_INTERP, int reg, int base, size_t offs)
824 /* XXX end blind hack for [perl #37819] --but see
825 additional hack section at bottom.
827 # ifndef NO_JIT_VTABLE_OPS
829 # undef Parrot_jit_vtable1_op
830 # undef Parrot_jit_vtable1r_op
832 # undef Parrot_jit_vtable_111_op
833 # undef Parrot_jit_vtable_112_op
834 # undef Parrot_jit_vtable_221_op
835 # undef Parrot_jit_vtable_1121_op
836 # undef Parrot_jit_vtable_1123_op
837 # undef Parrot_jit_vtable_2231_op
839 # undef Parrot_jit_vtable_1r223_op
840 # undef Parrot_jit_vtable_1r332_op
842 # undef Parrot_jit_vtable_ifp_op
843 # undef Parrot_jit_vtable_unlessp_op
844 # undef Parrot_jit_vtable_newp_ic_op
846 /* emit a call to a vtable func
847 * $X->vtable(interp, $X [, $Y...] )
849 static void
850 Parrot_jit_vtable_n_op(Parrot_jit_info_t *jit_info,
851 PARROT_INTERP, int n, int *args)
853 int nvtable = op_jit[*jit_info->cur_op].extcall;
854 op_info_t *op_info = &interp->op_info_table[*jit_info->cur_op];
856 int pmc = 0; /* pmc saves the left most Pi */
857 int rdx = 1; /* native (outgoing) register index */
859 int idx, pi, i;
860 size_t offset;
862 offset = offsetof(VTABLE, absolute);
863 offset += nvtable * sizeof (void *);
865 for (idx = 1; idx <= n; idx++) {
866 i = args[idx - 1];
867 pi = *(jit_info->cur_op + i);
869 switch (op_info->types[i - 1]) {
870 case PARROT_ARG_S:
871 emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
872 REG_OFFS_STR(pi), emitm_o(rdx));
873 break;
874 case PARROT_ARG_K:
875 case PARROT_ARG_P:
876 emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
877 REG_OFFS_PMC(pi), emitm_o(rdx));
878 if (! pmc) { pmc = rdx; }
879 break;
880 case PARROT_ARG_KI:
881 case PARROT_ARG_I:
882 emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
883 REG_OFFS_INT(pi), emitm_o(rdx));
884 break;
885 case PARROT_ARG_KIC:
886 case PARROT_ARG_IC:
887 if (emitm_simm13_const(pi)) {
888 emitm_mov_i(jit_info->native_ptr, pi, emitm_o(rdx));
890 else {
891 emitm_sethi(jit_info->native_ptr, emitm_hi22(pi), emitm_o(rdx));
892 emitm_or_i(jit_info->native_ptr, emitm_o(rdx), emitm_lo10(pi), emitm_o(rdx));
894 break;
895 case PARROT_ARG_N:
896 emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
897 REG_OFFS_NUM(pi), emitm_o(rdx));
898 emitm_ld_i(jit_info->native_ptr, Parrot_jit_regbase,
899 REG_OFFS_NUM(pi) + 4, emitm_o(++rdx));
900 break;
901 case PARROT_ARG_NC:
902 # define NC_addr &interp->code->const_table->constants[pi]->u.number
903 emitm_sethi(jit_info->native_ptr, emitm_hi22(NC_addr), XSR1);
904 emitm_or_i(jit_info->native_ptr, XSR1, emitm_lo10(NC_addr), XSR1);
906 emitm_ld_i(jit_info->native_ptr, XSR1, 0, emitm_o(rdx));
907 emitm_ld_i(jit_info->native_ptr, XSR1, 4, emitm_o(++rdx));
908 break;
909 case PARROT_ARG_SC:
910 # define SC_addr &interp->code->const_table->constants[pi]->u.string
911 emitm_sethi(jit_info->native_ptr, emitm_hi22(SC_addr), XSR1);
912 emitm_or_i(jit_info->native_ptr, XSR1, emitm_lo10(SC_addr), XSR1);
914 emitm_ld_i(jit_info->native_ptr, XSR1, 0, emitm_o(rdx));
915 break;
916 case PARROT_ARG_KC:
917 case PARROT_ARG_PC:
918 # define KC_addr &interp->code->const_table->constants[pi]->u.key
919 emitm_sethi(jit_info->native_ptr, emitm_hi22(KC_addr), XSR1);
920 emitm_or_i(jit_info->native_ptr, XSR1, emitm_lo10(KC_addr), XSR1);
922 emitm_ld_i(jit_info->native_ptr, XSR1, 0, emitm_o(rdx));
923 break;
924 default:
925 internal_exception(1,
926 "jit_vtable_n_op: unimp type %d, arg %d vtable %d",
927 op_info->types[i - 1], i, nvtable);
928 break;
931 rdx++;
934 emitm_ld_i(jit_info->native_ptr, emitm_o(pmc), offsetof(struct PMC, vtable), XSR1);
935 emitm_ld_i(jit_info->native_ptr, XSR1, offset, XSR1);
937 emitm_jumpl_i(jit_info->native_ptr, XSR1, 0, emitm_o(7));
938 emitm_mov_r(jit_info->native_ptr, Parrot_jit_intrp, emitm_o(0));
941 static void
942 Parrot_jit_store_retval(Parrot_jit_info_t *jit_info,
943 PARROT_INTERP)
945 opcode_t op_type = interp->op_info_table[*jit_info->cur_op].types[0];
946 long val = jit_info->cur_op[1];
948 switch (op_type){
949 case PARROT_ARG_I:
950 emitm_st_i(jit_info->native_ptr, emitm_o(0), Parrot_jit_regbase,
951 Parrot_jit_regoff((int)&REG_INT(interp, val), interp));
952 break;
953 case PARROT_ARG_P:
954 emitm_st_i(jit_info->native_ptr, emitm_o(0), Parrot_jit_regbase,
955 Parrot_jit_regoff((int)&REG_PMC(interp, val), interp));
956 break;
957 case PARROT_ARG_S:
958 emitm_st_i(jit_info->native_ptr, emitm_o(0), Parrot_jit_regbase,
959 Parrot_jit_regoff((int)&REG_STR(interp, val), interp));
960 break;
961 case PARROT_ARG_N:
962 emitm_stdf_i(jit_info->native_ptr, emitm_f(0), Parrot_jit_regbase,
963 Parrot_jit_regoff((int)&REG_NUM(interp, val), interp));
964 break;
965 default:
966 internal_exception(JIT_ERROR, "jit_vtable1r: ill LHS");
970 /* emit a call to a vtable func
971 * $1->vtable(interp, $1)
973 static void
974 Parrot_jit_vtable1_op(Parrot_jit_info_t *jit_info,
975 PARROT_INTERP)
977 int a[] = { 1 };
978 Parrot_jit_vtable_n_op(jit_info, interp, 1, a);
981 /* emit a call to a vtable func
982 * $1 = $2->vtable(interp, $2)
984 static void
985 Parrot_jit_vtable1r_op(Parrot_jit_info_t *jit_info,
986 Interp * interp)
988 int a[] = { 2 };
989 Parrot_jit_vtable_n_op(jit_info, interp, 1, a);
990 Parrot_jit_store_retval(jit_info, interp);
993 /* emit a call to a vtable func
994 * $1 = $2->vtable(interp, $2, $3)
996 static void
997 Parrot_jit_vtable_1r223_op(Parrot_jit_info_t *jit_info,
998 PARROT_INTERP)
1000 int a[] = { 2, 3 };
1001 Parrot_jit_vtable_n_op(jit_info, interp, 2, a);
1002 Parrot_jit_store_retval(jit_info, interp);
1005 /* emit a call to a vtable func
1006 * $1 = $3->vtable(interp, $3, $2)
1008 static void
1009 Parrot_jit_vtable_1r332_op(Parrot_jit_info_t *jit_info,
1010 PARROT_INTERP)
1012 int a[] = { 3, 2 };
1013 Parrot_jit_vtable_n_op(jit_info, interp, 2, a);
1014 Parrot_jit_store_retval(jit_info, interp);
1017 /* emit a call to a vtable func
1018 * $1->vtable(interp, $1, $2)
1020 static void
1021 Parrot_jit_vtable_112_op(Parrot_jit_info_t *jit_info,
1022 PARROT_INTERP)
1024 int a[] = { 1, 2 };
1025 Parrot_jit_vtable_n_op(jit_info, interp, 2, a);
1028 /* emit a call to a vtable func
1029 * $1->vtable(interp, $1, $1)
1031 static void
1032 Parrot_jit_vtable_111_op(Parrot_jit_info_t *jit_info,
1033 PARROT_INTERP)
1035 int a[] = { 1, 1 };
1036 Parrot_jit_vtable_n_op(jit_info, interp, 2, a);
1039 /* emit a call to a vtable func
1040 * $2->vtable(interp, $2, $1)
1042 static void
1043 Parrot_jit_vtable_221_op(Parrot_jit_info_t *jit_info,
1044 PARROT_INTERP)
1046 int a[] = { 2, 1 };
1047 Parrot_jit_vtable_n_op(jit_info, interp, 2, a);
1050 /* emit a call to a vtable func
1051 * $2->vtable(interp, $2, $3, $1)
1053 static void
1054 Parrot_jit_vtable_2231_op(Parrot_jit_info_t *jit_info,
1055 PARROT_INTERP)
1057 int a[] = { 2, 3, 1 };
1058 Parrot_jit_vtable_n_op(jit_info, interp, 3, a);
1061 /* emit a call to a vtable func
1062 * $1->vtable(interp, $1, $2, $3)
1064 static void
1065 Parrot_jit_vtable_1123_op(Parrot_jit_info_t *jit_info,
1066 PARROT_INTERP)
1068 int a[] = { 1, 2, 3 };
1069 Parrot_jit_vtable_n_op(jit_info, interp, 3, a);
1072 /* emit a call to a vtable func
1073 * $1->vtable(interp, $1, $2, $1)
1075 static void
1076 Parrot_jit_vtable_1121_op(Parrot_jit_info_t *jit_info,
1077 PARROT_INTERP)
1079 int a[] = { 1, 2, 1 };
1080 Parrot_jit_vtable_n_op(jit_info, interp, 3, a);
1083 /* if_p_ic, unless_p_ic */
1084 static void
1085 Parrot_jit_vtable_if_unless_op(Parrot_jit_info_t *jit_info,
1086 PARROT_INTERP, int unless)
1088 int ic = *(jit_info->cur_op + 2); /* branch offset */
1090 /* emit call to vtable function i.e. get_bool, result in o0 */
1091 Parrot_jit_vtable1_op(jit_info, interp);
1093 /* test the result - and branch (or not) accordingly */
1094 emitm_subcc_r(jit_info->native_ptr, emitm_o(0), emitm_g(0), emitm_g(0));
1095 Parrot_jit_bicc(jit_info, unless ? emitm_be : emitm_bne, 0, ic);
1097 emitm_nop(jit_info->native_ptr);
1100 static void
1101 Parrot_jit_vtable_ifp_op(Parrot_jit_info_t *jit_info,
1102 PARROT_INTERP)
1104 Parrot_jit_vtable_if_unless_op(jit_info, interp, 0);
1107 static void
1108 Parrot_jit_vtable_unlessp_op(Parrot_jit_info_t *jit_info,
1109 PARROT_INTERP)
1111 Parrot_jit_vtable_if_unless_op(jit_info, interp, 1);
1114 /* new_p_ic */
1115 static void
1116 Parrot_jit_vtable_newp_ic_op(Parrot_jit_info_t *jit_info,
1117 PARROT_INTERP)
1119 void *igniter = (void (*)(void))pmc_new_noinit;
1120 size_t offset = offsetof(VTABLE, init);
1122 int p1 = *(jit_info->cur_op + 1);
1123 int i2 = *(jit_info->cur_op + 2);
1125 if (i2 <= 0 || i2 >= interp->n_vtable_max)
1126 internal_exception(1, "Illegal PMC enum (%d) in new", i2);
1128 /* get "a" pmc first - calling function: pmc_new_noinit(...) */
1129 /* PMC* pmc_new_noinit(PARROT_INTERP, INTVAL base_type) */
1130 if (emitm_simm13_const(i2)) {
1131 emitm_mov_i(jit_info->native_ptr, i2, emitm_o(1));
1133 else {
1134 emitm_sethi(jit_info->native_ptr, emitm_hi22(i2), emitm_o(1));
1135 emitm_or_i(jit_info->native_ptr, emitm_o(1), emitm_lo10(i2), emitm_o(1));
1138 Parrot_jit_newfixup(jit_info);
1139 jit_info->arena.fixups->type = JIT_CALL30;
1140 jit_info->arena.fixups->param.fptr = D2FPTR(igniter);
1142 emitm_call_30(jit_info->native_ptr, 0);
1143 emitm_mov_r(jit_info->native_ptr, Parrot_jit_intrp, emitm_o(0));
1145 /* got a new pmc, sync mem and prepare vtable call (regs) */
1146 emitm_mov_r(jit_info->native_ptr, emitm_o(0), emitm_o(1));
1147 emitm_st_i(jit_info->native_ptr, emitm_o(0), Parrot_jit_regbase,
1148 Parrot_jit_regoff((int)&REG_PMC(interp, p1), interp));
1150 emitm_ld_i(jit_info->native_ptr, emitm_o(0), offsetof(struct PMC, vtable), XSR1);
1151 emitm_ld_i(jit_info->native_ptr, XSR1, offset, XSR1);
1153 emitm_jumpl_i(jit_info->native_ptr, XSR1, 0, emitm_o(7));
1154 emitm_mov_r(jit_info->native_ptr, Parrot_jit_intrp, emitm_o(0));
1157 # endif /* NO_JIT_VTABLE_OPS */
1159 #else /* JIT_EMIT */
1161 # define REQUIRES_CONSTANT_POOL 0
1162 # define INT_REGISTERS_TO_MAP 6
1163 # define FLOAT_REGISTERS_TO_MAP 6
1165 # ifndef JIT_IMCC
1166 char intval_map[INT_REGISTERS_TO_MAP] =
1167 { emitm_l(1), emitm_l(2), emitm_l(3), emitm_l(4), emitm_l(5), emitm_l(6)
1170 char floatval_map[] =
1171 { emitm_f(4), emitm_f(6), emitm_f(8), emitm_f(10), emitm_f(12), emitm_f(14)
1173 # endif
1175 # define PRESERVED_INT_REGS 6
1176 # define PRESERVED_FLOAT_REGS 0
1178 #endif /* JIT_EMIT */
1180 /* XXX Hack [perl #37819] Unlike the functions above, this one apparently
1181 sometimes needs to be defined both in and out of the JIT_EMIT section.
1182 However, at this point, the Parrot_jit_regbase symbol is not
1183 defined, so we replace it with the integer 26 (which is what it
1184 expands to anyway.
1186 # define Parrot_jit_emit_get_base_reg_no(pc) 26 /*Parrot_jit_regbase */
1188 #endif /* PARROT_SUN4_JIT_EMIT_H_GUARD */
1192 * Local variables:
1193 * c-file-style: "parrot"
1194 * End:
1195 * vim: expandtab shiftwidth=4: