/[dynamips]/trunk/ppc32_jit.h
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/ppc32_jit.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (hide annotations)
Sat Oct 6 16:26:06 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7-RC3/ppc32_jit.h
File MIME type: text/plain
File size: 10560 byte(s)
dynamips-0.2.7-RC3

1 dpavlin 7 /*
2     * Cisco router simulation platform.
3     * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4     *
5     * PPC32 JIT compiler.
6     */
7    
8     #ifndef __PPC32_JIT_H__
9     #define __PPC32_JIT_H__
10    
11     #include "utils.h"
12 dpavlin 8 #include "sbox.h"
13 dpavlin 7
14     /* Size of executable page area (in Mb) */
15     #ifndef __CYGWIN__
16     #define PPC_EXEC_AREA_SIZE 64
17     #else
18     #define PPC_EXEC_AREA_SIZE 16
19     #endif
20    
21     /* Buffer size for JIT code generation */
22     #define PPC_JIT_BUFSIZE 32768
23    
24     /* Maximum number of X86 chunks */
25 dpavlin 9 #define PPC_JIT_MAX_CHUNKS 64
26 dpavlin 7
27 dpavlin 8 /* Size of hash for IA lookup */
28     #define PPC_JIT_IA_HASH_BITS 17
29     #define PPC_JIT_IA_HASH_MASK ((1 << PPC_JIT_IA_HASH_BITS) - 1)
30     #define PPC_JIT_IA_HASH_SIZE (1 << PPC_JIT_IA_HASH_BITS)
31    
32     /* Size of hash for physical lookup */
33     #define PPC_JIT_PHYS_HASH_BITS 16
34     #define PPC_JIT_PHYS_HASH_MASK ((1 << PPC_JIT_PHYS_HASH_BITS) - 1)
35     #define PPC_JIT_PHYS_HASH_SIZE (1 << PPC_JIT_PHYS_HASH_BITS)
36    
37 dpavlin 9 #define PPC_JIT_TARGET_BITMAP_INDEX(x) (((x) >> 7) & 0x1F)
38     #define PPC_JIT_TARGET_BITMAP_POS(x) (((x) >> 2) & 0x1F)
39    
40 dpavlin 7 /* Instruction jump patch */
41     struct ppc32_insn_patch {
42 dpavlin 9 struct ppc32_insn_patch *next;
43 dpavlin 7 u_char *jit_insn;
44 dpavlin 9 m_uint32_t ppc_ia;
45 dpavlin 7 };
46    
47     /* Instruction patch table */
48     #define PPC32_INSN_PATCH_TABLE_SIZE 32
49    
50 dpavlin 9 struct ppc32_jit_patch_table {
51     struct ppc32_jit_patch_table *next;
52 dpavlin 7 struct ppc32_insn_patch patches[PPC32_INSN_PATCH_TABLE_SIZE];
53     u_int cur_patch;
54     };
55    
56     /* PPC32 translated code block */
57     struct ppc32_jit_tcb {
58     m_uint32_t start_ia;
59     u_char **jit_insn_ptr;
60     m_uint64_t acc_count;
61     ppc_insn_t *ppc_code;
62     u_int ppc_trans_pos;
63     u_int jit_chunk_pos;
64     u_char *jit_ptr;
65     insn_exec_page_t *jit_buffer;
66     insn_exec_page_t *jit_chunks[PPC_JIT_MAX_CHUNKS];
67     struct ppc32_jit_patch_table *patch_table;
68     ppc32_jit_tcb_t *prev,*next;
69 dpavlin 8
70     m_uint32_t phys_page;
71     m_uint32_t phys_hash;
72     ppc32_jit_tcb_t **phys_pprev,*phys_next;
73 dpavlin 9
74     /* 1024 instructions per page, one bit per instruction */
75     m_uint32_t target_bitmap[32];
76     m_uint32_t target_undef_cnt;
77 dpavlin 8
78 dpavlin 7 #if DEBUG_BLOCK_TIMESTAMP
79     m_uint64_t tm_first_use,tm_last_use;
80     #endif
81     };
82    
83     /* PPC instruction recognition */
84     struct ppc32_insn_tag {
85     int (*emit)(cpu_ppc_t *cpu,ppc32_jit_tcb_t *,ppc_insn_t);
86     m_uint32_t mask,value;
87     };
88    
89 dpavlin 9 /* Mark the specified IA as a target for further recompiling */
90     static inline void
91     ppc32_jit_tcb_set_target_bit(ppc32_jit_tcb_t *b,m_uint32_t ia)
92     {
93     int index,pos;
94    
95     index = PPC_JIT_TARGET_BITMAP_INDEX(ia);
96     pos = PPC_JIT_TARGET_BITMAP_POS(ia);
97    
98     b->target_bitmap[index] |= 1 << pos;
99     }
100    
101     /* Returns TRUE if the specified IA is in the target bitmap */
102     static inline int
103     ppc32_jit_tcb_get_target_bit(ppc32_jit_tcb_t *b,m_uint32_t ia)
104     {
105     int index,pos;
106    
107     index = PPC_JIT_TARGET_BITMAP_INDEX(ia);
108     pos = PPC_JIT_TARGET_BITMAP_POS(ia);
109    
110     return(b->target_bitmap[index] & (1 << pos));
111     }
112    
113 dpavlin 7 /* Get the JIT instruction pointer in a translated block */
114     static forced_inline
115     u_char *ppc32_jit_tcb_get_host_ptr(ppc32_jit_tcb_t *b,m_uint32_t vaddr)
116     {
117     m_uint32_t offset;
118    
119 dpavlin 8 offset = (vaddr & PPC32_MIN_PAGE_IMASK) >> 2;
120 dpavlin 7 return(b->jit_insn_ptr[offset]);
121     }
122    
123 dpavlin 8 /* Check if the specified address belongs to the specified block */
124     static forced_inline
125     int ppc32_jit_tcb_local_addr(ppc32_jit_tcb_t *block,m_uint32_t vaddr,
126     u_char **jit_addr)
127     {
128     if ((vaddr & PPC32_MIN_PAGE_MASK) == block->start_ia) {
129     *jit_addr = ppc32_jit_tcb_get_host_ptr(block,vaddr);
130     return(1);
131     }
132    
133     return(0);
134     }
135    
136     /* Check if PC register matches the compiled block virtual address */
137     static forced_inline
138     int ppc32_jit_tcb_match(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block)
139     {
140     m_uint32_t vpage;
141    
142     vpage = cpu->ia & ~PPC32_MIN_PAGE_IMASK;
143     return(block->start_ia == vpage);
144     }
145    
146     /* Compute the hash index for the specified IA value */
147     static forced_inline m_uint32_t ppc32_jit_get_ia_hash(m_uint32_t ia)
148     {
149     m_uint32_t page_hash;
150    
151     page_hash = sbox_u32(ia >> PPC32_MIN_PAGE_SHIFT);
152     return((page_hash ^ (page_hash >> 14)) & PPC_JIT_IA_HASH_MASK);
153     }
154    
155     /* Compute the hash index for the specified physical page */
156     static forced_inline m_uint32_t ppc32_jit_get_phys_hash(m_uint32_t phys_page)
157     {
158     m_uint32_t page_hash;
159    
160     page_hash = sbox_u32(phys_page);
161     return((page_hash ^ (page_hash >> 12)) & PPC_JIT_PHYS_HASH_MASK);
162     }
163    
164     /* Find the JIT block matching a physical page */
165     static inline ppc32_jit_tcb_t *
166     ppc32_jit_find_by_phys_page(cpu_ppc_t *cpu,m_uint32_t phys_page)
167     {
168     m_uint32_t page_hash = ppc32_jit_get_phys_hash(phys_page);
169     ppc32_jit_tcb_t *block;
170    
171     for(block=cpu->exec_phys_map[page_hash];block;block=block->phys_next)
172     if (block->phys_page == phys_page)
173     return block;
174    
175     return NULL;
176     }
177    
178 dpavlin 9 /* ======================================================================== */
179     /* JIT emit operations (generic). */
180     /* ======================================================================== */
181    
182     /* Indicate registers modified by ppc32_update_cr() functions */
183     extern void ppc32_update_cr_set_altered_hreg(cpu_ppc_t *cpu);
184    
185     /* Set opcode */
186     static inline void ppc32_op_set(cpu_ppc_t *cpu,jit_op_t *op)
187     {
188     cpu_gen_t *c = cpu->gen;
189     *c->jit_op_current = op;
190     c->jit_op_current = &op->next;
191     }
192    
193     /* EMIT_BASIC_OPCODE */
194     static inline void ppc32_op_emit_basic_opcode(cpu_ppc_t *cpu,u_int opcode)
195     {
196     jit_op_t *op = jit_op_get(cpu->gen,0,opcode);
197     ppc32_op_set(cpu,op);
198     }
199    
200     /* Trash the specified host register */
201     static inline void ppc32_op_emit_alter_host_reg(cpu_ppc_t *cpu,int host_reg)
202     {
203     jit_op_t *op = jit_op_get(cpu->gen,0,JIT_OP_ALTER_HOST_REG);
204     op->param[0] = host_reg;
205     ppc32_op_set(cpu,op);
206     }
207    
208     /* EMIT_INSN_OUTPUT */
209     static inline jit_op_t *
210     ppc32_op_emit_insn_output(cpu_ppc_t *cpu,u_int size_index,char *insn_name)
211     {
212     jit_op_t *op = jit_op_get(cpu->gen,size_index,JIT_OP_INSN_OUTPUT);
213     op->arg_ptr = NULL;
214     op->insn_name = insn_name;
215     ppc32_op_set(cpu,op);
216     return op;
217     }
218    
219     /* EMIT_LOAD_GPR */
220     static inline
221     void ppc32_op_emit_load_gpr(cpu_ppc_t *cpu,int host_reg,int ppc_reg)
222     {
223     jit_op_t *op = jit_op_get(cpu->gen,0,JIT_OP_LOAD_GPR);
224     op->param[0] = host_reg;
225     op->param[1] = ppc_reg;
226     op->param[2] = host_reg;
227     ppc32_op_set(cpu,op);
228     }
229    
230     /* EMIT_STORE_GPR */
231     static inline
232     void ppc32_op_emit_store_gpr(cpu_ppc_t *cpu,int ppc_reg,int host_reg)
233     {
234     jit_op_t *op = jit_op_get(cpu->gen,0,JIT_OP_STORE_GPR);
235     op->param[0] = host_reg;
236     op->param[1] = ppc_reg;
237     op->param[2] = host_reg;
238     ppc32_op_set(cpu,op);
239     }
240    
241     /* EMIT_UPDATE_FLAGS */
242     static inline
243     void ppc32_op_emit_update_flags(cpu_ppc_t *cpu,int field,int is_signed)
244     {
245     jit_op_t *op = jit_op_get(cpu->gen,0,JIT_OP_UPDATE_FLAGS);
246    
247     op->param[0] = field;
248     op->param[1] = is_signed;
249    
250     ppc32_op_set(cpu,op);
251     ppc32_update_cr_set_altered_hreg(cpu);
252     }
253    
254     /* EMIT_REQUIRE_FLAGS */
255     static inline void ppc32_op_emit_require_flags(cpu_ppc_t *cpu,int field)
256     {
257     jit_op_t *op = jit_op_get(cpu->gen,0,JIT_OP_REQUIRE_FLAGS);
258     op->param[0] = field;
259     ppc32_op_set(cpu,op);
260     }
261    
262     /* EMIT_BRANCH_TARGET */
263     static inline void ppc32_op_emit_branch_target(cpu_ppc_t *cpu,
264     ppc32_jit_tcb_t *b,
265     m_uint32_t ia)
266     {
267     cpu_gen_t *c = cpu->gen;
268     jit_op_t *op = jit_op_get(c,0,JIT_OP_BRANCH_TARGET);
269     u_int pos;
270    
271     if ((ia & PPC32_MIN_PAGE_MASK) == b->start_ia) {
272     pos = (ia & PPC32_MIN_PAGE_IMASK) >> 2;
273    
274     /* Insert in head */
275     op->next = c->jit_op_array[pos];
276     c->jit_op_array[pos] = op;
277     }
278     }
279    
280     /* EMIT_SET_HOST_REG_IMM32 */
281     static inline void
282     ppc32_op_emit_set_host_reg_imm32(cpu_ppc_t *cpu,int reg,m_uint32_t val)
283     {
284     jit_op_t *op = jit_op_get(cpu->gen,0,JIT_OP_SET_HOST_REG_IMM32);
285     op->param[0] = reg;
286     op->param[1] = val;
287     ppc32_op_set(cpu,op);
288     }
289    
290     /* ======================================================================== */
291     /* JIT operations with implementations specific to target CPU */
292     void ppc32_op_insn_output(ppc32_jit_tcb_t *b,jit_op_t *op);
293     void ppc32_op_load_gpr(ppc32_jit_tcb_t *b,jit_op_t *op);
294     void ppc32_op_store_gpr(ppc32_jit_tcb_t *b,jit_op_t *op);
295     void ppc32_op_update_flags(ppc32_jit_tcb_t *b,jit_op_t *op);
296     void ppc32_op_move_host_reg(ppc32_jit_tcb_t *b,jit_op_t *op);
297     void ppc32_op_set_host_reg_imm32(ppc32_jit_tcb_t *b,jit_op_t *op);
298    
299     /* Set the Instruction Address (IA) register */
300     void ppc32_set_ia(u_char **ptr,m_uint32_t new_ia);
301    
302     /* Jump to the next page */
303     void ppc32_set_page_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b);
304    
305     /* Increment the number of executed instructions (performance debugging) */
306     void ppc32_inc_perf_counter(ppc32_jit_tcb_t *b);
307    
308     /* ======================================================================== */
309    
310 dpavlin 8 /* Virtual Breakpoint */
311 dpavlin 9 void ppc32_emit_breakpoint(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b);
312 dpavlin 8
313 dpavlin 7 /* Initialize instruction lookup table */
314     void ppc32_jit_create_ilt(void);
315    
316     /* Initialize the JIT structure */
317     int ppc32_jit_init(cpu_ppc_t *cpu);
318    
319     /* Flush the JIT */
320     u_int ppc32_jit_flush(cpu_ppc_t *cpu,u_int threshold);
321    
322     /* Shutdown the JIT */
323     void ppc32_jit_shutdown(cpu_ppc_t *cpu);
324    
325     /* Fetch a PowerPC instruction and emit corresponding translated code */
326     struct ppc32_insn_tag *ppc32_jit_fetch_and_emit(cpu_ppc_t *cpu,
327     ppc32_jit_tcb_t *block);
328    
329     /* Record a patch to apply in a compiled block */
330 dpavlin 9 int ppc32_jit_tcb_record_patch(ppc32_jit_tcb_t *block,jit_op_t *iop,
331     u_char *jit_ptr,m_uint32_t vaddr);
332 dpavlin 7
333     /* Free an instruction block */
334     void ppc32_jit_tcb_free(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block,
335     int list_removal);
336    
337     /* Check if the specified address belongs to the specified block */
338     int ppc32_jit_tcb_local_addr(ppc32_jit_tcb_t *block,m_uint32_t vaddr,
339     u_char **jit_addr);
340    
341 dpavlin 9 /* Recompile a page */
342     int ppc32_jit_tcb_recompile(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block);
343    
344 dpavlin 7 /* Execute compiled PowerPC code */
345     void *ppc32_jit_run_cpu(cpu_gen_t *gen);
346    
347 dpavlin 9 /* Start register allocation sequence */
348     void ppc32_jit_start_hreg_seq(cpu_ppc_t *cpu,char *insn);
349    
350     /* Close register allocation sequence */
351     void ppc32_jit_close_hreg_seq(cpu_ppc_t *cpu);
352    
353     /* Insert a reg map as head of list (as MRU element) */
354     void ppc32_jit_insert_hreg_mru(cpu_ppc_t *cpu,struct hreg_map *map);
355    
356     /* Allocate an host register */
357     int ppc32_jit_alloc_hreg(cpu_ppc_t *cpu,int ppc_reg);
358    
359     /* Force allocation of an host register */
360     int ppc32_jit_alloc_hreg_forced(cpu_ppc_t *cpu,int hreg);
361    
362     /* Initialize register mapping */
363     void ppc32_jit_init_hreg_mapping(cpu_ppc_t *cpu);
364    
365 dpavlin 7 #endif

  ViewVC Help
Powered by ViewVC 1.1.26