/[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

Contents of /trunk/ppc32_jit.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (show 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 /*
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 #include "sbox.h"
13
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 #define PPC_JIT_MAX_CHUNKS 64
26
27 /* 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 #define PPC_JIT_TARGET_BITMAP_INDEX(x) (((x) >> 7) & 0x1F)
38 #define PPC_JIT_TARGET_BITMAP_POS(x) (((x) >> 2) & 0x1F)
39
40 /* Instruction jump patch */
41 struct ppc32_insn_patch {
42 struct ppc32_insn_patch *next;
43 u_char *jit_insn;
44 m_uint32_t ppc_ia;
45 };
46
47 /* Instruction patch table */
48 #define PPC32_INSN_PATCH_TABLE_SIZE 32
49
50 struct ppc32_jit_patch_table {
51 struct ppc32_jit_patch_table *next;
52 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
70 m_uint32_t phys_page;
71 m_uint32_t phys_hash;
72 ppc32_jit_tcb_t **phys_pprev,*phys_next;
73
74 /* 1024 instructions per page, one bit per instruction */
75 m_uint32_t target_bitmap[32];
76 m_uint32_t target_undef_cnt;
77
78 #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 /* 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 /* 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 offset = (vaddr & PPC32_MIN_PAGE_IMASK) >> 2;
120 return(b->jit_insn_ptr[offset]);
121 }
122
123 /* 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 /* ======================================================================== */
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 /* Virtual Breakpoint */
311 void ppc32_emit_breakpoint(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b);
312
313 /* 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 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
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 /* Recompile a page */
342 int ppc32_jit_tcb_recompile(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block);
343
344 /* Execute compiled PowerPC code */
345 void *ppc32_jit_run_cpu(cpu_gen_t *gen);
346
347 /* 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 #endif

  ViewVC Help
Powered by ViewVC 1.1.26