Annotation of cf/ppc32_jit.h, revision 1.1.1.3

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) */
        !           306: void ppc32_inc_perf_counter(ppc32_jit_tcb_t *b);
        !           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.