[TT #871] Add rand as a dynop, with tests
[parrot.git] / src / jit.h
blob27fe7ac66ad2a39e76b8d88425917c3ec2363200
1 /*
2 * Copyright (C) 2001-2007, Parrot Foundation.
3 */
5 /*
6 * jit.h
8 * $Id$
9 */
11 #ifndef PARROT_JIT_H_GUARD
12 #define PARROT_JIT_H_GUARD
14 #if EXEC_CAPABLE
15 # include "parrot/exec.h"
16 #endif
18 typedef void (*jit_f)(PARROT_INTERP, opcode_t *pc);
21 void Parrot_destroy_jit(void *);
23 /* Parrot_jit_fixup_t
24 * Platform generic fixup information
26 * type: The type of fixup.
27 * native_offset: Where to apply the fixup.
28 * skip: Skip instructions after the target.
29 * param: Fixup specific data.
32 typedef struct Parrot_jit_fixup *Parrot_jit_fixup_ptr;
34 typedef struct Parrot_jit_fixup {
35 int type;
36 ptrdiff_t native_offset;
37 char skip;
38 char dummy[3]; /* For alignment ??? XXX */
39 union { /* What has to align with what? */
40 opcode_t opcode;
41 void (*fptr)(void);
42 } param;
44 Parrot_jit_fixup_ptr next;
45 } Parrot_jit_fixup_t;
47 /* Parrot_jit_opmap_t
48 * Hold native code offsets/addresses
50 * ptr: Pointer to native code
51 * offset: Offset of native code from arena.start
54 typedef union {
55 void *ptr;
56 ptrdiff_t offset;
57 } Parrot_jit_opmap_t;
59 enum {
60 JIT_BRANCH_NO, /* The opcode doesn't branch */
61 JIT_BRANCH_TARGET, /* The opcode is a branch target */
62 JIT_BRANCH_SOURCE /* The opcode is a branch source */
66 /* Parrot_jit_arena_t
67 * Holds pointers to the native code of one or more sections.
69 * start: Start of current native code segment.
70 * size: The size of the arena in bytes
71 * op_map: Maps opcode offsets to native code.
72 * map_size: The size of the map in bytes.
73 * fixups: List of fixups.
76 typedef struct Parrot_jit_arena_t {
77 char *start;
78 ptrdiff_t size;
79 Parrot_jit_opmap_t *op_map;
80 unsigned long map_size;
81 Parrot_jit_fixup_t *fixups;
82 } Parrot_jit_arena_t;
84 /* Parrot_jit_optimizer_section_t
85 * The bytecode will be divided in sections depending on the
86 * program structure.
88 * begin: Points where sections begins in the bytecode.
89 * end: Points where sections ends in the bytecode.
90 * arena: The first arena for this section, or NULL if the
91 * section is in the arena inlined in jit_info.
92 * ru[4]: register_usage_t per [IPSN]
93 * maps: Total maps done.
94 * jit_op_count: How many opcodes are jitted.
95 * op_count: Opcodes in this section.
96 * load_size: The size of the register load instructions to be
97 * skipped in an in-section branch.
98 * isjit: If this section is a jitted one or not.
99 * block: block number of section
100 * branch_target: The section where execution continues if this section
101 * ends at a branch source the targeted section is used.
104 typedef struct Parrot_jit_optimizer_section *Parrot_jit_optimizer_section_ptr;
106 /* reg_count: An array with one position for each register
107 * holding the number of times each register is used in the
108 * section.
109 * reg_usage: An array with the registers sorted by the usage.
110 * reg_dir: If the register needs to be loaded or saved.
111 * registers_used: count of used registers
113 typedef struct Parrot_jit_register_usage_t {
114 int reg_count[NUM_REGISTERS];
115 unsigned int reg_usage[NUM_REGISTERS];
116 char reg_dir[NUM_REGISTERS];
117 int registers_used;
118 } Parrot_jit_register_usage_t;
120 typedef struct Parrot_jit_optimizer_section {
121 opcode_t *begin;
122 opcode_t *end;
123 Parrot_jit_register_usage_t ru[4];
124 Parrot_jit_arena_t *arena;
125 unsigned int maps;
126 unsigned int jit_op_count;
127 unsigned int op_count;
128 ptrdiff_t load_size;
129 char isjit;
130 char done;
131 char ins_count;
132 char dummy; /* For alignment ??? XXX */
133 int block; /* What has to align with what? */
134 Parrot_jit_optimizer_section_ptr branch_target;
135 Parrot_jit_optimizer_section_ptr prev;
136 Parrot_jit_optimizer_section_ptr next;
137 } Parrot_jit_optimizer_section_t;
139 /* Parrot_jit_optimizer_section_t
140 * All the information related to optimizing the bytecode.
142 * sections: A pointer to the first section.
143 * cur_section: Pointer to the current section.
144 * map_branch: A pointer to an array with the size of the bytecode
145 * where the positions of the opcodes will have a value
146 * indicating if the opcode is a branch target, source
147 * or isn't related with a control flow opcode at all,
148 * and which register was allocated for each opcode
149 * argument if any.
150 * has_unpredictable_jump: XXX need to define how to handle this.
153 typedef struct Parrot_jit_optimizer_t {
154 Parrot_jit_optimizer_section_t *sections;
155 Parrot_jit_optimizer_section_t *cur_section;
156 char *map_branch;
157 opcode_t **branch_list;
158 unsigned char has_unpredictable_jump;
159 unsigned char dummy[3]; /* For alignment ??? XXX */
160 } Parrot_jit_optimizer_t; /* What has to align with what? */
162 /* Parrot_jit_constant_pool_t
163 * Constants pool information.
166 typedef struct Parrot_jit_constant_pool_t {
167 long frames_used;
168 long cur_used;
169 char *cur_const;
170 INTVAL *slot_ptr;
171 } Parrot_jit_constant_pool_t;
173 typedef enum {
174 JIT_CODE_FILE,
175 JIT_CODE_SUB,
176 JIT_CODE_SUB_REGS_ONLY,
178 /* size */
179 JIT_CODE_TYPES,
180 /* special cases */
181 JIT_CODE_RECURSIVE = 0x10,
182 JIT_CODE_SUB_REGS_ONLY_REC = JIT_CODE_SUB_REGS_ONLY|JIT_CODE_RECURSIVE
183 } enum_jit_code_type;
185 /* Parrot_jit_info_t
186 * All the information needed to jit the bytecode will be here.
188 * prev_op: The previous opcode in this section.
189 * cur_op: The current opcode during the build process.
190 * op_i: Opcode index.
191 * native_ptr: Current pointer to native code.
192 * arena: The arena inlined, this will be the only one used in cases
193 * where there is a way to load an immediate.
194 * optimizer: Optimizer information.
195 * constant_pool: The constant pool information.
198 typedef struct Parrot_jit_info_t {
199 opcode_t *prev_op;
200 opcode_t *cur_op;
201 opcode_t op_i;
202 char *native_ptr;
203 Parrot_jit_arena_t arena;
204 Parrot_jit_optimizer_t *optimizer;
205 Parrot_jit_constant_pool_t *constant_pool;
206 INTVAL code_type;
207 int flags;
208 const struct jit_arch_info_t *arch_info;
209 int n_args;
210 #if EXEC_CAPABLE
211 Parrot_exec_objfile_t *objfile;
212 #else
213 void *objfile;
214 #endif /* EXEC_CAPABLE */
215 } Parrot_jit_info_t;
217 #define Parrot_jit_fixup_target(jit_info, fixup) \
218 ((jit_info)->arena.start + (fixup)->native_offset)
220 typedef void (*jit_fn_t)(Parrot_jit_info_t *jit_info,
221 PARROT_INTERP);
223 /* Parrot_jit_fn_info_t
224 * The table of opcodes.
226 * jit_fn_t: A pointer to the function that emits code for the opcode
227 * or to the C funtion if the opcode is not jitted.
228 * extcall: If the opcode makes an external call to a C funtion.
229 * also used for vtable functions, extcall is #of vtable func
232 typedef struct Parrot_jit_fn_info_t {
233 jit_fn_t fn;
234 int extcall;
235 } Parrot_jit_fn_info_t;
237 PARROT_DATA Parrot_jit_fn_info_t *op_jit;
238 extern Parrot_jit_fn_info_t op_exec[];
240 PARROT_EXPORT void Parrot_jit_newfixup(Parrot_jit_info_t *jit_info);
242 void Parrot_jit_cpcf_op(Parrot_jit_info_t *jit_info,
243 PARROT_INTERP);
245 void Parrot_jit_normal_op(Parrot_jit_info_t *jit_info,
246 PARROT_INTERP);
248 void Parrot_jit_restart_op(Parrot_jit_info_t *jit_info,
249 PARROT_INTERP);
251 void Parrot_exec_cpcf_op(Parrot_jit_info_t *jit_info,
252 PARROT_INTERP);
254 void Parrot_exec_normal_op(Parrot_jit_info_t *jit_info,
255 PARROT_INTERP);
257 void Parrot_exec_restart_op(Parrot_jit_info_t *jit_info,
258 PARROT_INTERP);
261 * interface functions for the register save/restore code
262 * with offsets relative to the base register (obtained by
263 * Parrot_jit_emit_get_base_reg_no)
265 void Parrot_jit_emit_mov_mr_n_offs(
266 Interp *, int base_reg, size_t offs, int src_reg);
267 void Parrot_jit_emit_mov_mr_offs(
268 Interp *, int base_reg, size_t offs, int src_reg);
269 void Parrot_jit_emit_mov_rm_n_offs(
270 Interp *, int dst_reg, int base_reg, size_t offs);
271 void Parrot_jit_emit_mov_rm_offs(
272 Interp *, int dst_reg, int base_reg, size_t offs);
275 * interface to architecture specific details
277 typedef void (*jit_arch_f)(Parrot_jit_info_t *, Interp *);
279 typedef struct jit_arch_regs {
281 * begin function - emit ABI call prologue
283 jit_arch_f jit_begin;
285 int n_mapped_I;
286 int n_preserved_I;
287 const char *map_I;
288 int n_mapped_F;
289 int n_preserved_F;
290 const char *map_F;
291 } jit_arch_regs;
293 typedef void (*mov_RM_f)(PARROT_INTERP, Parrot_jit_info_t *,
294 int cpu_reg, int base_reg, INTVAL offs);
295 typedef void (*mov_MR_f)(PARROT_INTERP, Parrot_jit_info_t *,
296 int base_reg, INTVAL offs, int cpu_reg);
298 typedef struct jit_arch_info_t {
299 /* CPU <- Parrot reg move functions */
300 mov_RM_f mov_RM_i;
301 mov_RM_f mov_RM_n;
302 /* Parrot <- CPU reg move functions */
303 mov_MR_f mov_MR_i;
304 mov_MR_f mov_MR_n;
306 /* fixup branches and calls after codegen */
307 jit_arch_f jit_dofixup;
308 /* flush caches */
309 jit_arch_f jit_flush_cache;
310 /* register mapping info */
311 const jit_arch_regs regs[JIT_CODE_TYPES];
312 } jit_arch_info;
315 * interface to create JIT code
317 Parrot_jit_info_t *
318 parrot_build_asm(PARROT_INTERP,
319 opcode_t *code_start, opcode_t *code_end,
320 void *objfile, INTVAL);
322 * NCI interface
324 void *Parrot_jit_build_call_func(Interp *, PMC *, STRING *, int *);
325 /* custom pmc callback functions */
326 void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv);
327 PMC* Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv);
328 struct jit_buffer_private_data {
329 int size;
332 #endif /* PARROT_JIT_H_GUARD */
336 * Local variables:
337 * c-file-style: "parrot"
338 * End:
339 * vim: expandtab shiftwidth=4: