Annotation of cf/ppc32_jit.h, revision 1.1.1.4

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 */
1.1.1.3   root       25: #define PPC_JIT_MAX_CHUNKS  64
1.1       root       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.1.3   root       37: #define PPC_JIT_TARGET_BITMAP_INDEX(x) (((x) >> 7) & 0x1F)
                     38: #define PPC_JIT_TARGET_BITMAP_POS(x)   (((x) >> 2) & 0x1F)
                     39: 
1.1       root       40: /* Instruction jump patch */
                     41: struct ppc32_insn_patch {
1.1.1.3   root       42:    struct ppc32_insn_patch *next;
1.1       root       43:    u_char *jit_insn;
1.1.1.3   root       44:    m_uint32_t ppc_ia;
1.1       root       45: };
                     46: 
                     47: /* Instruction patch table */
                     48: #define PPC32_INSN_PATCH_TABLE_SIZE  32
                     49: 
1.1.1.3   root       50: struct ppc32_jit_patch_table {   
                     51:    struct ppc32_jit_patch_table *next;
1.1       root       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;
1.1.1.2   root       69: 
                     70:    m_uint32_t phys_page;
                     71:    m_uint32_t phys_hash;
                     72:    ppc32_jit_tcb_t **phys_pprev,*phys_next;
1.1.1.3   root       73:    
                     74:    /* 1024 instructions per page, one bit per instruction */
                     75:    m_uint32_t target_bitmap[32];
                     76:    m_uint32_t target_undef_cnt;
1.1.1.2   root       77: 
1.1       root       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: 
1.1.1.3   root       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: 
1.1       root      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: 
1.1.1.2   root      119:    offset = (vaddr & PPC32_MIN_PAGE_IMASK) >> 2;
1.1       root      120:    return(b->jit_insn_ptr[offset]);
                    121: }
                    122: 
1.1.1.2   root      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: 
1.1.1.3   root      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) */
1.1.1.4 ! root      306: void ppc32_inc_perf_counter(cpu_ppc_t *cpu);
1.1.1.3   root      307: 
                    308: /* ======================================================================== */
                    309: 
1.1.1.2   root      310: /* Virtual Breakpoint */
1.1.1.3   root      311: void ppc32_emit_breakpoint(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b);
1.1.1.2   root      312: 
1.1       root      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 */
1.1.1.3   root      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);
1.1       root      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: 
1.1.1.3   root      341: /* Recompile a page */
                    342: int ppc32_jit_tcb_recompile(cpu_ppc_t *cpu,ppc32_jit_tcb_t *block);
                    343: 
1.1       root      344: /* Execute compiled PowerPC code */
                    345: void *ppc32_jit_run_cpu(cpu_gen_t *gen);
                    346: 
1.1.1.3   root      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: 
1.1       root      365: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.