|
|
1.1 root 1: /*
2: * Cisco router simulation platform.
3: * Copyright (c) 2005,2006 Christophe Fillot ([email protected])
4: *
5: * PPC32 JIT compiler.
6: */
7:
8: #ifndef __PPC32_JIT_H__
9: #define __PPC32_JIT_H__
10:
11: #include "utils.h"
1.1.1.2 ! root 12: #include "sbox.h"
1.1 root 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 32
26:
1.1.1.2 ! root 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:
1.1 root 37: /* Instruction jump patch */
38: struct ppc32_insn_patch {
39: u_char *jit_insn;
40: m_uint64_t ppc_ia;
41: };
42:
43: /* Instruction patch table */
44: #define PPC32_INSN_PATCH_TABLE_SIZE 32
45:
46: struct ppc32_jit_patch_table {
47: struct ppc32_insn_patch patches[PPC32_INSN_PATCH_TABLE_SIZE];
48: u_int cur_patch;
49: struct ppc32_jit_patch_table *next;
50: };
51:
52: /* PPC32 translated code block */
53: struct ppc32_jit_tcb {
54: m_uint32_t start_ia;
55: u_char **jit_insn_ptr;
56: m_uint64_t acc_count;
57: ppc_insn_t *ppc_code;
58: u_int ppc_trans_pos;
59: u_int jit_chunk_pos;
60: u_char *jit_ptr;
61: insn_exec_page_t *jit_buffer;
62: insn_exec_page_t *jit_chunks[PPC_JIT_MAX_CHUNKS];
63: struct ppc32_jit_patch_table *patch_table;
64: ppc32_jit_tcb_t *prev,*next;
1.1.1.2 ! root 65:
! 66: m_uint32_t phys_page;
! 67: m_uint32_t phys_hash;
! 68: ppc32_jit_tcb_t **phys_pprev,*phys_next;
! 69:
1.1 root 70: #if DEBUG_BLOCK_TIMESTAMP
71: m_uint64_t tm_first_use,tm_last_use;
72: #endif
73: };
74:
75: /* PPC instruction recognition */
76: struct ppc32_insn_tag {
77: int (*emit)(cpu_ppc_t *cpu,ppc32_jit_tcb_t *,ppc_insn_t);
78: m_uint32_t mask,value;
79: };
80:
81: /* Get the JIT instruction pointer in a translated block */
82: static forced_inline
83: u_char *ppc32_jit_tcb_get_host_ptr(ppc32_jit_tcb_t *b,m_uint32_t vaddr)
84: {
85: m_uint32_t offset;
86:
1.1.1.2 ! root 87: offset = (vaddr & PPC32_MIN_PAGE_IMASK) >> 2;
1.1 root 88: return(b->jit_insn_ptr[offset]);
89: }
90:
1.1.1.2 ! root 91: /* Check if the specified address belongs to the specified block */
! 92: static forced_inline
! 93: int ppc32_jit_tcb_local_addr(ppc32_jit_tcb_t *block,m_uint32_t vaddr,
! 94: u_char **jit_addr)
! 95: {
! 96: if ((vaddr & PPC32_MIN_PAGE_MASK) == block->start_ia) {
! 97: *jit_addr = ppc32_jit_tcb_get_host_ptr(block,vaddr);
! 98: return(1);
! 99: }
! 100:
! 101: return(0);
! 102: }
! 103:
! 104: /* Check if PC register matches the compiled block virtual address */
! 105: static forced_inline
! 106: int ppc32_jit_tcb_match(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block)
! 107: {
! 108: m_uint32_t vpage;
! 109:
! 110: vpage = cpu->ia & ~PPC32_MIN_PAGE_IMASK;
! 111: return(block->start_ia == vpage);
! 112: }
! 113:
! 114: /* Compute the hash index for the specified IA value */
! 115: static forced_inline m_uint32_t ppc32_jit_get_ia_hash(m_uint32_t ia)
! 116: {
! 117: m_uint32_t page_hash;
! 118:
! 119: page_hash = sbox_u32(ia >> PPC32_MIN_PAGE_SHIFT);
! 120: return((page_hash ^ (page_hash >> 14)) & PPC_JIT_IA_HASH_MASK);
! 121: }
! 122:
! 123: /* Compute the hash index for the specified physical page */
! 124: static forced_inline m_uint32_t ppc32_jit_get_phys_hash(m_uint32_t phys_page)
! 125: {
! 126: m_uint32_t page_hash;
! 127:
! 128: page_hash = sbox_u32(phys_page);
! 129: return((page_hash ^ (page_hash >> 12)) & PPC_JIT_PHYS_HASH_MASK);
! 130: }
! 131:
! 132: /* Find the JIT block matching a physical page */
! 133: static inline ppc32_jit_tcb_t *
! 134: ppc32_jit_find_by_phys_page(cpu_ppc_t *cpu,m_uint32_t phys_page)
! 135: {
! 136: m_uint32_t page_hash = ppc32_jit_get_phys_hash(phys_page);
! 137: ppc32_jit_tcb_t *block;
! 138:
! 139: for(block=cpu->exec_phys_map[page_hash];block;block=block->phys_next)
! 140: if (block->phys_page == phys_page)
! 141: return block;
! 142:
! 143: return NULL;
! 144: }
! 145:
! 146: /* Virtual Breakpoint */
! 147: void ppc32_emit_breakpoint(ppc32_jit_tcb_t *b);
! 148:
1.1 root 149: /* Initialize instruction lookup table */
150: void ppc32_jit_create_ilt(void);
151:
152: /* Initialize the JIT structure */
153: int ppc32_jit_init(cpu_ppc_t *cpu);
154:
155: /* Flush the JIT */
156: u_int ppc32_jit_flush(cpu_ppc_t *cpu,u_int threshold);
157:
158: /* Shutdown the JIT */
159: void ppc32_jit_shutdown(cpu_ppc_t *cpu);
160:
161: /* Fetch a PowerPC instruction and emit corresponding translated code */
162: struct ppc32_insn_tag *ppc32_jit_fetch_and_emit(cpu_ppc_t *cpu,
163: ppc32_jit_tcb_t *block);
164:
165: /* Record a patch to apply in a compiled block */
166: int ppc32_jit_tcb_record_patch(ppc32_jit_tcb_t *block,u_char *jit_ptr,
167: m_uint32_t vaddr);
168:
169: /* Free an instruction block */
170: void ppc32_jit_tcb_free(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block,
171: int list_removal);
172:
173: /* Check if the specified address belongs to the specified block */
174: int ppc32_jit_tcb_local_addr(ppc32_jit_tcb_t *block,m_uint32_t vaddr,
175: u_char **jit_addr);
176:
177: /* Execute compiled PowerPC code */
178: void *ppc32_jit_run_cpu(cpu_gen_t *gen);
179:
180: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.