2 * Copyright (C) 2002-2008, The Perl Foundation.
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.
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)
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); \
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) | \
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); \
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); \
91 # define emitm_3a(pc, op, rd, op3, rs1, asi, rs2) \
92 emitm_fmt3(pc, op, rd, op3, rs1, ((asi) << 5) | (rs2))
95 # define emitm_3b(pc, op, rd, op3, rs1, simm13) \
96 emitm_fmt3(pc, op, rd, op3, rs1, (1L << 13) | emitm_mask(13, (simm13)))
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))
108 # define emitm_nop(pc) emitm_sethi((pc), 0, 0)
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))
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))
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))
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))
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 */
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))
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))
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); }
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));
342 enum {JIT_BRANCH
, JIT_CALL30
};
346 * IMPORTANT SHORTCUTS
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
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) ®_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))
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)), \
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), \
393 /* Generate a jump to a bytecode address in reg_num
394 * - uses the temporary register
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
),
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
)
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
)
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");
441 emitm_2b(jit_info
->native_ptr
, annul
, cond
, branch
, offset
);
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
,
475 op_type
= interp
->op_info_table
[*jit_info
->cur_op
].types
[param
- 1];
476 val
= jit_info
->cur_op
[param
];
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
),
486 emitm_or_i(jit_info
->native_ptr
, emitm_g(0), val
, hwreg
);
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
),
501 val
= (int)®_INT(interp
, val
);
502 emitm_ld_i(jit_info
->native_ptr
, Parrot_jit_regbase
,
503 Parrot_jit_regoff(val
, interp
), hwreg
);
507 val
= (int)®_PMC(interp
, val
);
508 emitm_ld_i(jit_info
->native_ptr
, Parrot_jit_regbase
,
509 Parrot_jit_regoff(val
, interp
), hwreg
);
513 val
= (int)®_STR(interp
, val
);
514 emitm_ld_i(jit_info
->native_ptr
, Parrot_jit_regbase
,
515 Parrot_jit_regoff(val
, interp
), hwreg
);
519 val
= (int)®_NUM(interp
, val
);
520 emitm_ldd_i(jit_info
->native_ptr
, Parrot_jit_regbase
,
521 Parrot_jit_regoff(val
, interp
), hwreg
);
525 internal_exception(JIT_ERROR
,
526 "Unsupported op parameter type %d\n",
531 static void jit_emit_store_i(Parrot_jit_info_t
*jit_info
,
539 op_type
= interp
->op_info_table
[*jit_info
->cur_op
].types
[param
- 1];
540 val
= jit_info
->cur_op
[param
];
544 val
= (int)®_INT(interp
, val
);
545 emitm_st_i(jit_info
->native_ptr
, hwreg
, Parrot_jit_regbase
,
546 Parrot_jit_regoff(val
, interp
));
550 val
= (int)®_PMC(interp
, val
);
551 emitm_st_i(jit_info
->native_ptr
, hwreg
, Parrot_jit_regbase
,
552 Parrot_jit_regoff(val
, interp
));
556 val
= (int)®_STR(interp
, val
);
557 emitm_st_i(jit_info
->native_ptr
, hwreg
, Parrot_jit_regbase
,
558 Parrot_jit_regoff(val
, interp
));
562 val
= (int)®_NUM(interp
, val
);
563 emitm_std_i(jit_info
->native_ptr
, hwreg
, Parrot_jit_regbase
,
564 Parrot_jit_regoff(val
, interp
));
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
,
581 op_type
= interp
->op_info_table
[*jit_info
->cur_op
].types
[param
- 1];
582 val
= jit_info
->cur_op
[param
];
586 /* Load integer into floating point registers - should use
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
);
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
),
604 val
= (int)®_INT(interp
, val
);
605 emitm_ldf_i(jit_info
->native_ptr
, Parrot_jit_regbase
,
606 Parrot_jit_regoff(val
, interp
), hwreg
);
610 val
= (int)®_NUM(interp
, val
);
611 emitm_lddf_i(jit_info
->native_ptr
, Parrot_jit_regbase
,
612 Parrot_jit_regoff(val
, interp
), hwreg
);
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
,
629 op_type
= interp
->op_info_table
[*jit_info
->cur_op
].types
[param
- 1];
630 val
= jit_info
->cur_op
[param
];
634 val
= (int)®_INT(interp
, val
);
635 emitm_stf_i(jit_info
->native_ptr
, hwreg
, Parrot_jit_regbase
,
636 Parrot_jit_regoff(val
, interp
));
640 val
= (int)®_NUM(interp
, val
);
641 emitm_stdf_i(jit_info
->native_ptr
, hwreg
, Parrot_jit_regbase
,
642 Parrot_jit_regoff(val
, interp
));
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
,
655 Parrot_jit_fixup_t
*fixup
;
656 Parrot_jit_fixup_t
*last_fixup
;
660 fixup
= jit_info
->arena
.fixups
;
663 switch (fixup
->type
){
664 /* This fixes-up a branch to a known opcode offset */
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
);
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
));
679 internal_exception(JIT_ERROR
, "Unknown fixup type:%d\n",
688 Parrot_jit_begin(Parrot_jit_info_t
*jit_info
,
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
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
),
713 /* Calculate the address of I0 */
714 emitm_add_i(jit_info
->native_ptr
, Parrot_jit_intrp
, ireg0_offset
,
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
,
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
,
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
,
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) */
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 */
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) */
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 */
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
802 See also the "Hack [perl #37819]" section near the bottom of this
806 Parrot_jit_emit_mov_mr_offs(PARROT_INTERP
, int base
, size_t offs
, int reg
)
811 Parrot_jit_emit_mov_rm_offs(PARROT_INTERP
, int reg
, int base
, size_t offs
)
816 Parrot_jit_emit_mov_mr_n_offs(PARROT_INTERP
, int base
, size_t offs
, int reg
)
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...] )
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 */
862 offset
= offsetof(VTABLE
, absolute
);
863 offset
+= nvtable
* sizeof (void *);
865 for (idx
= 1; idx
<= n
; idx
++) {
867 pi
= *(jit_info
->cur_op
+ i
);
869 switch (op_info
->types
[i
- 1]) {
871 emitm_ld_i(jit_info
->native_ptr
, Parrot_jit_regbase
,
872 REG_OFFS_STR(pi
), emitm_o(rdx
));
876 emitm_ld_i(jit_info
->native_ptr
, Parrot_jit_regbase
,
877 REG_OFFS_PMC(pi
), emitm_o(rdx
));
878 if (! pmc
) { pmc
= rdx
; }
882 emitm_ld_i(jit_info
->native_ptr
, Parrot_jit_regbase
,
883 REG_OFFS_INT(pi
), emitm_o(rdx
));
887 if (emitm_simm13_const(pi
)) {
888 emitm_mov_i(jit_info
->native_ptr
, pi
, emitm_o(rdx
));
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
));
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
));
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
));
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
));
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
));
925 internal_exception(1,
926 "jit_vtable_n_op: unimp type %d, arg %d vtable %d",
927 op_info
->types
[i
- 1], i
, nvtable
);
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));
942 Parrot_jit_store_retval(Parrot_jit_info_t
*jit_info
,
945 opcode_t op_type
= interp
->op_info_table
[*jit_info
->cur_op
].types
[0];
946 long val
= jit_info
->cur_op
[1];
950 emitm_st_i(jit_info
->native_ptr
, emitm_o(0), Parrot_jit_regbase
,
951 Parrot_jit_regoff((int)®_INT(interp
, val
), interp
));
954 emitm_st_i(jit_info
->native_ptr
, emitm_o(0), Parrot_jit_regbase
,
955 Parrot_jit_regoff((int)®_PMC(interp
, val
), interp
));
958 emitm_st_i(jit_info
->native_ptr
, emitm_o(0), Parrot_jit_regbase
,
959 Parrot_jit_regoff((int)®_STR(interp
, val
), interp
));
962 emitm_stdf_i(jit_info
->native_ptr
, emitm_f(0), Parrot_jit_regbase
,
963 Parrot_jit_regoff((int)®_NUM(interp
, val
), interp
));
966 internal_exception(JIT_ERROR
, "jit_vtable1r: ill LHS");
970 /* emit a call to a vtable func
971 * $1->vtable(interp, $1)
974 Parrot_jit_vtable1_op(Parrot_jit_info_t
*jit_info
,
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)
985 Parrot_jit_vtable1r_op(Parrot_jit_info_t
*jit_info
,
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)
997 Parrot_jit_vtable_1r223_op(Parrot_jit_info_t
*jit_info
,
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)
1009 Parrot_jit_vtable_1r332_op(Parrot_jit_info_t
*jit_info
,
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)
1021 Parrot_jit_vtable_112_op(Parrot_jit_info_t
*jit_info
,
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)
1032 Parrot_jit_vtable_111_op(Parrot_jit_info_t
*jit_info
,
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)
1043 Parrot_jit_vtable_221_op(Parrot_jit_info_t
*jit_info
,
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)
1054 Parrot_jit_vtable_2231_op(Parrot_jit_info_t
*jit_info
,
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)
1065 Parrot_jit_vtable_1123_op(Parrot_jit_info_t
*jit_info
,
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)
1076 Parrot_jit_vtable_1121_op(Parrot_jit_info_t
*jit_info
,
1079 int a
[] = { 1, 2, 1 };
1080 Parrot_jit_vtable_n_op(jit_info
, interp
, 3, a
);
1083 /* if_p_ic, unless_p_ic */
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
);
1101 Parrot_jit_vtable_ifp_op(Parrot_jit_info_t
*jit_info
,
1104 Parrot_jit_vtable_if_unless_op(jit_info
, interp
, 0);
1108 Parrot_jit_vtable_unlessp_op(Parrot_jit_info_t
*jit_info
,
1111 Parrot_jit_vtable_if_unless_op(jit_info
, interp
, 1);
1116 Parrot_jit_vtable_newp_ic_op(Parrot_jit_info_t
*jit_info
,
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));
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)®_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
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)
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
1186 # define Parrot_jit_emit_get_base_reg_no(pc) 26 /*Parrot_jit_regbase */
1188 #endif /* PARROT_SUN4_JIT_EMIT_H_GUARD */
1193 * c-file-style: "parrot"
1195 * vim: expandtab shiftwidth=4: