Annotation of cf/ppc32_x86_trans.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  * Cisco router simulation platform.
                      3:  * Copyright (c) 2005,2006 Christophe Fillot ([email protected])
                      4:  */
                      5: 
                      6: #include <stdio.h>
                      7: #include <stdlib.h>
                      8: #include <unistd.h>
                      9: #include <string.h>
                     10: #include <sys/types.h>
                     11: #include <sys/stat.h>
                     12: #include <sys/mman.h>
                     13: #include <fcntl.h>
                     14: 
                     15: #include "cpu.h"
                     16: #include "ppc32_jit.h"
                     17: #include "ppc32_x86_trans.h"
                     18: #include "memory.h"
                     19: 
1.1.1.2 ! root       20: /* ======================================================================= */
        !            21: 
1.1       root       22: /* Macros for CPU structure access */
                     23: #define REG_OFFSET(reg)   (OFFSET(cpu_ppc_t,gpr[(reg)]))
                     24: #define MEMOP_OFFSET(op)  (OFFSET(cpu_ppc_t,mem_op_fn[(op)]))
                     25: 
                     26: #define DECLARE_INSN(name) \
                     27:    static int ppc32_emit_##name(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, \
                     28:                                 ppc_insn_t insn)
                     29: 
1.1.1.2 ! root       30: /* EFLAGS to Condition Register (CR) field - signed */
        !            31: static m_uint32_t eflags_to_cr_signed[256] = {
        !            32:    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
        !            33:    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
        !            34:    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
        !            35:    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
        !            36:    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
        !            37:    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
        !            38:    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
        !            39:    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
        !            40:    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
        !            41:    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
        !            42:    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
        !            43:    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
        !            44:    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
        !            45:    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
        !            46:    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
        !            47:    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
        !            48:    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
        !            49:    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
        !            50:    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
        !            51:    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
        !            52:    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
        !            53:    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
        !            54:    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
        !            55:    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
        !            56:    0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
        !            57:    0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
        !            58:    0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
        !            59:    0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
        !            60:    0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
        !            61:    0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
        !            62:    0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
        !            63:    0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
        !            64: };
        !            65: 
        !            66: /* EFLAGS to Condition Register (CR) field - unsigned */
        !            67: static m_uint32_t eflags_to_cr_unsigned[256] = {
        !            68:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            69:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            70:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            71:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            72:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            73:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            74:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            75:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            76:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !            77:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !            78:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !            79:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !            80:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !            81:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !            82:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !            83:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !            84:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            85:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            86:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            87:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            88:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            89:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            90:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            91:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
        !            92:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !            93:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !            94:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !            95:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !            96:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !            97:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !            98:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !            99:    0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
        !           100: };
        !           101: 
1.1       root      102: /* Dump regs */
                    103: static void ppc32_emit_dump_regs(ppc32_jit_tcb_t *b);
                    104: 
                    105: /* Load a 32 bit immediate value */
                    106: static inline void ppc32_load_imm(ppc32_jit_tcb_t *b,u_int reg,m_uint32_t val)
                    107: {
                    108:    if (val)
                    109:       x86_mov_reg_imm(b->jit_ptr,reg,val);
                    110:    else
                    111:       x86_alu_reg_reg(b->jit_ptr,X86_XOR,reg,reg);
                    112: }
                    113: 
                    114: /* Set the Instruction Address (IA) register */
                    115: void ppc32_set_ia(ppc32_jit_tcb_t *b,m_uint32_t new_ia)
                    116: {
                    117:    x86_mov_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),new_ia,4);
                    118: }
                    119: 
                    120: /* Set the Link Register (LR) */
                    121: void ppc32_set_lr(ppc32_jit_tcb_t *b,m_uint32_t new_lr)
                    122: {  
                    123:    x86_mov_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,lr),new_lr,4);
                    124: }
                    125: 
1.1.1.2 ! root      126: /* 
        !           127:  * Try to branch directly to the specified JIT block without returning to 
        !           128:  * main loop.
        !           129:  */
        !           130: static void ppc32_try_direct_far_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
        !           131:                                       m_uint32_t new_ia)
        !           132: {
        !           133:    m_uint32_t new_page,ia_hash,ia_offset;
        !           134:    u_char *test1,*test2,*test3;
        !           135: 
        !           136:    new_page = new_ia & PPC32_MIN_PAGE_MASK;
        !           137:    ia_offset = (new_ia & PPC32_MIN_PAGE_IMASK) >> 2;
        !           138:    ia_hash = ppc32_jit_get_ia_hash(new_ia);
        !           139: 
        !           140:    /* Get JIT block info in %edx */
        !           141:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,
        !           142:                        X86_EDI,OFFSET(cpu_ppc_t,exec_blk_map),4);
        !           143:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EBX,ia_hash*sizeof(void *),4);
        !           144: 
        !           145:    /* no JIT block found ? */
        !           146:    x86_test_reg_reg(b->jit_ptr,X86_EDX,X86_EDX);
        !           147:    test1 = b->jit_ptr;
        !           148:    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
        !           149: 
        !           150:    /* Check block IA */
        !           151:    x86_mov_reg_imm(b->jit_ptr,X86_EAX,new_page);
        !           152:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EAX,X86_EDX,
        !           153:                        OFFSET(ppc32_jit_tcb_t,start_ia));
        !           154:    test2 = b->jit_ptr;
        !           155:    x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);
        !           156: 
        !           157:    /* Jump to the code */
        !           158:    x86_mov_reg_membase(b->jit_ptr,X86_ESI,
        !           159:                        X86_EDX,OFFSET(ppc32_jit_tcb_t,jit_insn_ptr),4);
        !           160:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,
        !           161:                        X86_ESI,ia_offset * sizeof(void *),4);
        !           162:    
        !           163:    x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
        !           164:    test3 = b->jit_ptr;
        !           165:    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
        !           166:    x86_jump_reg(b->jit_ptr,X86_EBX);
        !           167: 
        !           168:    /* Returns to caller... */
        !           169:    x86_patch(test1,b->jit_ptr);
        !           170:    x86_patch(test2,b->jit_ptr);
        !           171:    x86_patch(test3,b->jit_ptr);
        !           172: 
        !           173:    ppc32_set_ia(b,new_ia);
        !           174:    ppc32_jit_tcb_push_epilog(b);
        !           175: }
        !           176: 
1.1       root      177: /* Set Jump */
                    178: static void ppc32_set_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
                    179:                            m_uint32_t new_ia,int local_jump)
                    180: {      
                    181:    int return_to_caller = FALSE;
                    182:    u_char *jump_ptr;
                    183: 
                    184: #if 0
                    185:    if (cpu->sym_trace && !local_jump)
                    186:       return_to_caller = TRUE;
                    187: #endif
                    188: 
                    189:    if (!return_to_caller && ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr)) {
                    190:       if (jump_ptr) {
                    191:          x86_jump_code(b->jit_ptr,jump_ptr);
                    192:       } else {
                    193:          ppc32_jit_tcb_record_patch(b,b->jit_ptr,new_ia);
                    194:          x86_jump32(b->jit_ptr,0);
                    195:       }
                    196:    } else {
1.1.1.2 ! root      197:       if (cpu->exec_blk_direct_jump) {
        !           198:          /* Block lookup optimization */
        !           199:          ppc32_try_direct_far_jump(cpu,b,new_ia);
        !           200:       } else {
        !           201:          ppc32_set_ia(b,new_ia);
        !           202:          ppc32_jit_tcb_push_epilog(b);
        !           203:       }
1.1       root      204:    }
                    205: }
                    206: 
                    207: /* Load a GPR into the specified host register */
                    208: static forced_inline void ppc32_load_gpr(ppc32_jit_tcb_t *b,u_int host_reg,
                    209:                                          u_int ppc_reg)
                    210: {
                    211:    x86_mov_reg_membase(b->jit_ptr,host_reg,X86_EDI,REG_OFFSET(ppc_reg),4);
                    212: }
                    213: 
                    214: /* Store contents for a host register into a GPR register */
                    215: static forced_inline void ppc32_store_gpr(ppc32_jit_tcb_t *b,u_int ppc_reg,
                    216:                                           u_int host_reg)
                    217: {
                    218:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(ppc_reg),host_reg,4);
                    219: }
                    220: 
                    221: /* Apply an ALU operation on a GPR register and a host register */
                    222: static forced_inline void ppc32_alu_gpr(ppc32_jit_tcb_t *b,u_int op,
                    223:                                         u_int host_reg,u_int ppc_reg)
                    224: {
                    225:    x86_alu_reg_membase(b->jit_ptr,op,host_reg,X86_EDI,REG_OFFSET(ppc_reg));
                    226: }
                    227: 
                    228: /* 
                    229:  * Update CR from %eflags
1.1.1.2 ! root      230:  * %eax, %edx, %esi are modified.
1.1       root      231:  */
                    232: static void ppc32_update_cr(ppc32_jit_tcb_t *b,int field,int is_signed)
                    233: {
1.1.1.2 ! root      234:    /* Get status bits from EFLAGS */
        !           235:    x86_mov_reg_imm(b->jit_ptr,X86_EAX,0);
        !           236:    x86_lahf(b->jit_ptr);
        !           237:    x86_xchg_ah_al(b->jit_ptr);
1.1       root      238: 
1.1.1.2 ! root      239:    if (is_signed)
        !           240:       x86_mov_reg_imm(b->jit_ptr,X86_EDX,eflags_to_cr_signed);
        !           241:    else
        !           242:       x86_mov_reg_imm(b->jit_ptr,X86_EDX,eflags_to_cr_unsigned);
1.1       root      243: 
1.1.1.2 ! root      244:    x86_mov_reg_memindex(b->jit_ptr,X86_EAX,X86_EDX,0,X86_EAX,2,4);
1.1       root      245: 
                    246:    /* Check XER Summary of Overflow and report it */
1.1.1.2 ! root      247:    x86_mov_reg_membase(b->jit_ptr,X86_ESI,X86_EDI,OFFSET(cpu_ppc_t,xer),4);
        !           248:    //x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,PPC32_XER_SO);
        !           249:    //x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_ESI,PPC32_XER_SO_BIT);
        !           250:    //x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ESI);
        !           251: 
        !           252:    /* Store modified CR field */
        !           253:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,PPC32_CR_FIELD_OFFSET(field),
        !           254:                        X86_EAX,4);
1.1       root      255: }
                    256: 
                    257: /* 
                    258:  * Update CR0 from %eflags
                    259:  * %eax, %ecx, %edx, %esi are modified.
                    260:  */
                    261: static void ppc32_update_cr0(ppc32_jit_tcb_t *b)
                    262: {
                    263:    ppc32_update_cr(b,0,TRUE);
                    264: }
                    265: 
                    266: /* Basic C call */
                    267: static forced_inline void ppc32_emit_basic_c_call(ppc32_jit_tcb_t *b,void *f)
                    268: {
                    269:    x86_mov_reg_imm(b->jit_ptr,X86_EBX,f);
                    270:    x86_call_reg(b->jit_ptr,X86_EBX);
                    271: }
                    272: 
                    273: /* Emit a simple call to a C function without any parameter */
                    274: static void ppc32_emit_c_call(ppc32_jit_tcb_t *b,void *f)
                    275: {   
                    276:    ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
                    277:    ppc32_emit_basic_c_call(b,f);
                    278: }
                    279: 
                    280: /* Memory operation */
                    281: static void ppc32_emit_memop(ppc32_jit_tcb_t *b,int op,int base,int offset,
                    282:                              int target,int update)
                    283: {
                    284:    m_uint32_t val = sign_extend(offset,16);
                    285:    u_char *test1;
                    286: 
                    287:    /* Save PC for exception handling */
                    288:    ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
                    289: 
                    290:    /* EDX = sign-extended offset */
                    291:    ppc32_load_imm(b,X86_EDX,val);
                    292: 
                    293:    /* EDX = GPR[base] + sign-extended offset */
                    294:    if (update || (base != 0))
                    295:       ppc32_alu_gpr(b,X86_ADD,X86_EDX,base);
                    296: 
                    297:    if (update)
                    298:       x86_mov_reg_reg(b->jit_ptr,X86_ESI,X86_EDX,4);
                    299: 
                    300:    /* ECX = target register */
                    301:    x86_mov_reg_imm(b->jit_ptr,X86_ECX,target);
                    302:    
                    303:    /* EAX = CPU instance pointer */
                    304:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                    305: 
                    306:    /* Call memory function */
                    307:    x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(op));
                    308: 
                    309:    /* Exception ? */
                    310:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                    311:    test1 = b->jit_ptr;
                    312:    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
                    313:    ppc32_jit_tcb_push_epilog(b);
                    314:    x86_patch(test1,b->jit_ptr);
                    315: 
                    316:    if (update)
                    317:       ppc32_store_gpr(b,base,X86_ESI);
                    318: }
                    319: 
                    320: /* Memory operation (indexed) */
                    321: static void ppc32_emit_memop_idx(ppc32_jit_tcb_t *b,int op,int ra,int rb,
                    322:                                  int target,int update)
                    323: {
                    324:    u_char *test1;
                    325: 
                    326:    /* Save PC for exception handling */
                    327:    ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
                    328: 
                    329:    /* EDX = $rb */
                    330:    ppc32_load_gpr(b,X86_EDX,rb);
                    331: 
                    332:    /* EDX = $rb + $ra */
                    333:    if (update || (ra != 0)) 
                    334:       ppc32_alu_gpr(b,X86_ADD,X86_EDX,ra);
                    335: 
                    336:    if (update)
                    337:       x86_mov_reg_reg(b->jit_ptr,X86_ESI,X86_EDX,4);
                    338: 
                    339:    /* ECX = target register */
                    340:    x86_mov_reg_imm(b->jit_ptr,X86_ECX,target);
                    341:    
                    342:    /* EAX = CPU instance pointer */
                    343:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                    344: 
                    345:    /* Call memory function */
                    346:    x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(op));
                    347: 
                    348:    /* Exception ? */
                    349:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                    350:    test1 = b->jit_ptr;
                    351:    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
                    352:    ppc32_jit_tcb_push_epilog(b);
                    353:    x86_patch(test1,b->jit_ptr);
                    354: 
                    355:    if (update)
                    356:       ppc32_store_gpr(b,ra,X86_ESI);
                    357: }
                    358: 
                    359: typedef void (*memop_fast_access)(ppc32_jit_tcb_t *b,int target);
                    360: 
                    361: /* Fast LBZ */
                    362: static void ppc32_memop_fast_lbz(ppc32_jit_tcb_t *b,int target)
                    363: {
                    364:    x86_clear_reg(b->jit_ptr,X86_ECX);
                    365:    x86_mov_reg_memindex(b->jit_ptr,X86_ECX,X86_EAX,0,X86_EBX,0,1);
                    366:    ppc32_store_gpr(b,target,X86_ECX);
                    367: }
                    368: 
                    369: /* Fast STB */
                    370: static void ppc32_memop_fast_stb(ppc32_jit_tcb_t *b,int target)
                    371: {
                    372:    ppc32_load_gpr(b,X86_EDX,target);
                    373:    x86_mov_memindex_reg(b->jit_ptr,X86_EAX,0,X86_EBX,0,X86_EDX,1);
                    374: }
                    375: 
                    376: /* Fast LWZ */
                    377: static void ppc32_memop_fast_lwz(ppc32_jit_tcb_t *b,int target)
                    378: {
                    379:    x86_mov_reg_memindex(b->jit_ptr,X86_EAX,X86_EAX,0,X86_EBX,0,4);
                    380:    x86_bswap(b->jit_ptr,X86_EAX);
                    381:    ppc32_store_gpr(b,target,X86_EAX);
                    382: }
                    383: 
                    384: /* Fast STW */
                    385: static void ppc32_memop_fast_stw(ppc32_jit_tcb_t *b,int target)
                    386: {
                    387:    ppc32_load_gpr(b,X86_EDX,target);
                    388:    x86_bswap(b->jit_ptr,X86_EDX);
                    389:    x86_mov_memindex_reg(b->jit_ptr,X86_EAX,0,X86_EBX,0,X86_EDX,4);
                    390: }
                    391: 
                    392: /* Fast memory operation */
                    393: static void ppc32_emit_memop_fast(ppc32_jit_tcb_t *b,int write_op,int opcode,
                    394:                                   int base,int offset,int target,
                    395:                                   memop_fast_access op_handler)
                    396: {
                    397:    m_uint32_t val = sign_extend(offset,16);
                    398:    u_char *test1,*test2,*p_exception,*p_exit;
                    399: 
                    400:    test2 = NULL;
                    401: 
                    402:    /* EBX = sign-extended offset */
                    403:    ppc32_load_imm(b,X86_EBX,val);
                    404: 
                    405:    /* EBX = GPR[base] + sign-extended offset */
                    406:    if (base != 0)
                    407:       ppc32_alu_gpr(b,X86_ADD,X86_EBX,base);
                    408: 
                    409:    /* EAX = mts32_entry index */
                    410:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EBX,4);
                    411:    x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_EAX,MTS32_HASH_SHIFT);
                    412:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,MTS32_HASH_MASK);
                    413: 
                    414:    /* EDX = mts32_entry */
                    415:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,
                    416:                        X86_EDI,OFFSET(cpu_ppc_t,mts_cache[PPC32_MTS_DCACHE]),
                    417:                        4);
                    418:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EAX,4);
                    419:    x86_alu_reg_reg(b->jit_ptr,X86_ADD,X86_EDX,X86_EAX);
                    420: 
                    421:    /* Compare virtual page address (ESI = vpage) */
                    422:    x86_mov_reg_reg(b->jit_ptr,X86_ESI,X86_EBX,4);
                    423:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,PPC32_MIN_PAGE_MASK);
                    424: 
                    425:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_ESI,X86_EDX,
                    426:                        OFFSET(mts32_entry_t,gvpa));
                    427:    test1 = b->jit_ptr;
                    428:    x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
                    429: 
                    430:    /* Test if we are writing to a COW page */
                    431:    if (write_op) {
                    432:       x86_test_membase_imm(b->jit_ptr,X86_EDX,OFFSET(mts32_entry_t,flags),
1.1.1.2 ! root      433:                            MTS_FLAG_COW|MTS_FLAG_EXEC);
1.1       root      434:       test2 = b->jit_ptr;
                    435:       x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
                    436:    }
                    437: 
                    438:    /* EBX = offset in page, EAX = Host Page Address */
                    439:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,PPC32_MIN_PAGE_IMASK);
                    440:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDX,OFFSET(mts32_entry_t,hpa),4);
                    441: 
                    442:    /* Memory access */
                    443:    op_handler(b,target);
                    444:  
                    445:    p_exit = b->jit_ptr;
                    446:    x86_jump8(b->jit_ptr,0);
                    447: 
                    448:    /* === Slow lookup === */
                    449:    x86_patch(test1,b->jit_ptr);
                    450:    if (test2)
                    451:       x86_patch(test2,b->jit_ptr);
                    452: 
                    453:    /* Update IA (EBX = vaddr) */
                    454:    ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
                    455: 
                    456:    /* EDX = virtual address */
                    457:    x86_mov_reg_reg(b->jit_ptr,X86_EDX,X86_EBX,4);
                    458: 
                    459:    /* ECX = target register */
                    460:    x86_mov_reg_imm(b->jit_ptr,X86_ECX,target);
                    461: 
                    462:    /* EAX = CPU instance pointer */
                    463:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                    464: 
                    465:    /* Call memory function */
                    466:    x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(opcode));
                    467: 
                    468:    /* Check for exception */
                    469:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                    470:    p_exception = b->jit_ptr;
                    471:    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
                    472:    ppc32_jit_tcb_push_epilog(b);
                    473: 
                    474:    x86_patch(p_exit,b->jit_ptr);
                    475:    x86_patch(p_exception,b->jit_ptr);
                    476: }
                    477: 
                    478: /* Virtual Breakpoint */
                    479: void ppc32_emit_breakpoint(ppc32_jit_tcb_t *b)
                    480: {
                    481:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                    482:    ppc32_emit_c_call(b,ppc32_run_breakpoint);
                    483: }
                    484: 
                    485: /* Unknown opcode handler */
                    486: static asmlinkage void ppc32_unknown_opcode(cpu_ppc_t *cpu,m_uint32_t opcode)
                    487: {
                    488:    printf("PPC32: unhandled opcode 0x%8.8x at 0x%8.8x (lr=0x%8.8x)\n",
                    489:           opcode,cpu->ia,cpu->lr);
                    490: 
                    491:    ppc32_dump_regs(cpu->gen);
                    492:    exit(1);
                    493: }
                    494: 
                    495: /* Emit unhandled instruction code */
                    496: static int ppc32_emit_unknown(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
                    497:                               ppc_insn_t opcode)
                    498: {
                    499:    u_char *test1;
                    500: 
                    501: #if 0      
                    502:    x86_mov_reg_imm(b->jit_ptr,X86_EAX,opcode);
                    503:    x86_alu_reg_imm(b->jit_ptr,X86_SUB,X86_ESP,4);
                    504:    x86_push_reg(b->jit_ptr,X86_EAX);
                    505:    x86_push_reg(b->jit_ptr,X86_EDI);
                    506:    ppc32_emit_c_call(b,ppc32_unknown_opcode);
                    507:    x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);
                    508: #endif
                    509: 
                    510:    /* Update IA */
                    511:    ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
                    512: 
                    513:    /* Fallback to non-JIT mode */
                    514:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                    515:    x86_mov_reg_imm(b->jit_ptr,X86_EDX,opcode);
                    516: 
                    517:    ppc32_emit_c_call(b,ppc32_exec_single_insn_ext);
                    518:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                    519:    test1 = b->jit_ptr;
                    520:    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
                    521:    ppc32_jit_tcb_push_epilog(b);
                    522: 
                    523:    x86_patch(test1,b->jit_ptr);
                    524:    return(0);
                    525: }
                    526: 
                    527: /* Dump regs */
                    528: static void ppc32_emit_dump_regs(ppc32_jit_tcb_t *b)
                    529: {   
                    530:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,OFFSET(cpu_ppc_t,gen),4);
                    531:    x86_push_reg(b->jit_ptr,X86_EAX);
                    532:    ppc32_emit_c_call(b,ppc32_dump_regs);
                    533:    x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,4);
                    534: }
                    535: 
                    536: /* Increment the number of executed instructions (performance debugging) */
                    537: void ppc32_inc_perf_counter(ppc32_jit_tcb_t *b)
                    538: {
                    539:    x86_alu_membase_imm(b->jit_ptr,X86_ADD,
                    540:                        X86_EDI,OFFSET(cpu_ppc_t,perf_counter),1);
                    541:    x86_alu_membase_imm(b->jit_ptr,X86_ADC,
                    542:                        X86_EDI,OFFSET(cpu_ppc_t,perf_counter)+4,0);
                    543: }
                    544: 
1.1.1.2 ! root      545: /* Check if there are pending IRQ */
        !           546: void ppc32_check_pending_irq(ppc32_jit_tcb_t *b)
        !           547: {
        !           548:    u_char *test1;
        !           549: 
        !           550:    /* Check the pending IRQ flag */
        !           551:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,
        !           552:                        X86_EDI,OFFSET(cpu_ppc_t,irq_check),4);
        !           553:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
        !           554:    test1 = b->jit_ptr;
        !           555:    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
        !           556: 
        !           557:    /* Save PC */
        !           558:    ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
        !           559:    ppc32_jit_tcb_push_epilog(b);
        !           560: 
        !           561:    x86_patch(test1,b->jit_ptr);
        !           562: }
        !           563: 
1.1       root      564: /* ======================================================================== */
                    565: 
                    566: /* BLR - Branch to Link Register */
                    567: DECLARE_INSN(BLR)
                    568: {
                    569:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,lr),4);
                    570:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),X86_EDX,4);
                    571: 
                    572:    /* set the return address */
                    573:    if (insn & 1)
                    574:       ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
                    575: 
                    576:    ppc32_jit_tcb_push_epilog(b);
                    577:    return(0);
                    578: }
                    579: 
                    580: /* BCTR - Branch to Count Register */
                    581: DECLARE_INSN(BCTR)
                    582: {
                    583:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,ctr),4);
                    584:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),X86_EDX,4);
                    585: 
                    586:    /* set the return address */
                    587:    if (insn & 1)
                    588:       ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
                    589: 
                    590:    ppc32_jit_tcb_push_epilog(b);
                    591:    return(0);
                    592: }
                    593: 
                    594: /* MFLR - Move From Link Register */
                    595: DECLARE_INSN(MFLR)
                    596: {
                    597:    int rd = bits(insn,21,25);
                    598:    
                    599:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,lr),4);
                    600:    ppc32_store_gpr(b,rd,X86_EDX);
                    601:    return(0);
                    602: }
                    603: 
                    604: /* MTLR - Move To Link Register */
                    605: DECLARE_INSN(MTLR)
                    606: {
                    607:    int rs = bits(insn,21,25);
                    608: 
                    609:    ppc32_load_gpr(b,X86_EDX,rs);
                    610:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,lr),X86_EDX,4);
                    611:    return(0);
                    612: }
                    613: 
                    614: /* MFCTR - Move From Counter Register */
                    615: DECLARE_INSN(MFCTR)
                    616: {
                    617:    int rd = bits(insn,21,25);
                    618:    
                    619:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,ctr),4);
                    620:    ppc32_store_gpr(b,rd,X86_EDX);
                    621:    return(0);
                    622: }
                    623: 
                    624: /* MTCTR - Move To Counter Register */
                    625: DECLARE_INSN(MTCTR)
                    626: {
                    627:    int rs = bits(insn,21,25);
                    628: 
                    629:    ppc32_load_gpr(b,X86_EDX,rs);
                    630:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr),X86_EDX,4);
                    631:    return(0);
                    632: }
                    633: 
                    634: /* MFTBU - Move from Time Base (Up) */
                    635: DECLARE_INSN(MFTBU)
                    636: {
                    637:    int rd = bits(insn,21,25);
                    638: 
                    639:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,4);
                    640:    ppc32_store_gpr(b,rd,X86_EDX);
                    641:    return(0);
                    642: }
                    643: 
                    644: #define PPC32_TB_INCREMENT  50
                    645: 
                    646: /* MFTBL - Move from Time Base (Lo) */
                    647: DECLARE_INSN(MFTBL)
                    648: {
                    649:    int rd = bits(insn,21,25);
                    650: 
                    651:    /* Increment the time base register */
                    652:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,tb),4);
                    653:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,4);
                    654:    x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_EDX,PPC32_TB_INCREMENT);
                    655:    x86_alu_reg_imm(b->jit_ptr,X86_ADC,X86_EBX,0);
                    656:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,tb),X86_EDX,4);
                    657:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,X86_EBX,4);
                    658: 
                    659:    ppc32_store_gpr(b,rd,X86_EDX);
                    660:    return(0);
                    661: }
                    662: 
                    663: /* ADD */
                    664: DECLARE_INSN(ADD)
                    665: {
                    666:    int rd = bits(insn,21,25);
                    667:    int ra = bits(insn,16,20);
                    668:    int rb = bits(insn,11,15);
                    669: 
                    670:    /* $rd = $ra + $rb */
                    671:    ppc32_load_gpr(b,X86_EBX,ra);
                    672:    ppc32_alu_gpr(b,X86_ADD,X86_EBX,rb);
                    673:    ppc32_store_gpr(b,rd,X86_EBX);
                    674: 
                    675:    if (insn & 1)
                    676:       ppc32_update_cr0(b);
                    677:       
                    678:    return(0);
                    679: }
                    680: 
                    681: /* ADDC */
                    682: DECLARE_INSN(ADDC)
                    683: {
                    684:    int rd = bits(insn,21,25);
                    685:    int ra = bits(insn,16,20);
                    686:    int rb = bits(insn,11,15);
                    687: 
                    688:    /* $rd = $ra + $rb */
                    689:    ppc32_load_gpr(b,X86_EBX,ra);
                    690:    ppc32_alu_gpr(b,X86_ADD,X86_EBX,rb);
                    691:    ppc32_store_gpr(b,rd,X86_EBX);
                    692: 
                    693:    /* store the carry flag */
                    694:    x86_set_reg(b->jit_ptr,X86_CC_C,X86_EAX,FALSE);
                    695:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x1);
                    696:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_EAX,4);
                    697: 
                    698:    if (insn & 1) {
                    699:       x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                    700:       ppc32_update_cr0(b);
                    701:    }
                    702:       
                    703:    return(0);
                    704: }
                    705: 
                    706: /* ADDE - Add Extended */
                    707: DECLARE_INSN(ADDE)
                    708: {   
                    709:    int rd = bits(insn,21,25);
                    710:    int ra = bits(insn,16,20);
                    711:    int rb = bits(insn,11,15);
                    712: 
                    713:    /* $ra + carry */
                    714:    ppc32_load_gpr(b,X86_ESI,ra);
                    715:    x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_ESI,
                    716:                        X86_EDI,OFFSET(cpu_ppc_t,xer_ca));
                    717:    x86_set_reg(b->jit_ptr,X86_CC_C,X86_EAX,FALSE);
                    718: 
                    719:    /* add $rb */
                    720:    ppc32_alu_gpr(b,X86_ADD,X86_ESI,rb);
                    721:    x86_set_reg(b->jit_ptr,X86_CC_C,X86_ECX,FALSE);
                    722: 
                    723:    ppc32_store_gpr(b,rd,X86_ESI);
                    724: 
                    725:    /* store the carry flag */
                    726:    x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ECX);
                    727:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x1);
                    728: 
                    729:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_EAX,4);
                    730: 
                    731:    /* update cr0 */
                    732:    if (insn & 1) {
                    733:       x86_test_reg_reg(b->jit_ptr,X86_ESI,X86_ESI);
                    734:       ppc32_update_cr0(b);
                    735:    }
                    736: 
                    737:    return(0);
                    738: }
                    739: 
                    740: /* ADDI - ADD Immediate */
                    741: DECLARE_INSN(ADDI)
                    742: {
                    743:    int rd = bits(insn,21,25);
                    744:    int ra = bits(insn,16,20);
                    745:    int imm = bits(insn,0,15);
                    746:    m_uint32_t tmp = sign_extend_32(imm,16);
                    747: 
                    748:    ppc32_load_imm(b,X86_EBX,tmp);
                    749: 
                    750:    if (ra != 0)
                    751:       x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EBX,X86_EDI,REG_OFFSET(ra));
                    752: 
                    753:    ppc32_store_gpr(b,rd,X86_EBX);
                    754:    return(0);
                    755: }
                    756: 
                    757: /* ADDIC - ADD Immediate with Carry */
                    758: DECLARE_INSN(ADDIC)
                    759: {
                    760:    int rd = bits(insn,21,25);
                    761:    int ra = bits(insn,16,20);
                    762:    int imm = bits(insn,0,15);
                    763:    m_uint32_t tmp = sign_extend_32(imm,16);
                    764: 
                    765:    ppc32_load_imm(b,X86_EAX,tmp);
                    766:    ppc32_alu_gpr(b,X86_ADD,X86_EAX,ra);
                    767:    ppc32_store_gpr(b,rd,X86_EAX);
                    768:    x86_set_membase(b->jit_ptr,X86_CC_C,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),FALSE);
                    769:    return(0);
                    770: }
                    771: 
                    772: /* ADDIC. */
                    773: DECLARE_INSN(ADDIC_dot)
                    774: {
                    775:    int rd = bits(insn,21,25);
                    776:    int ra = bits(insn,16,20);
                    777:    int imm = bits(insn,0,15);
                    778:    m_uint32_t tmp = sign_extend_32(imm,16);
                    779: 
                    780:    ppc32_load_imm(b,X86_EAX,tmp);
                    781:    ppc32_alu_gpr(b,X86_ADD,X86_EAX,ra);
                    782:    ppc32_store_gpr(b,rd,X86_EAX);
                    783:    x86_set_membase(b->jit_ptr,X86_CC_C,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),FALSE);
                    784: 
                    785:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                    786:    ppc32_update_cr0(b);
                    787:    return(0);
                    788: }
                    789: 
                    790: /* ADDIS - ADD Immediate Shifted */
                    791: DECLARE_INSN(ADDIS)
                    792: {
                    793:    int rd = bits(insn,21,25);
                    794:    int ra = bits(insn,16,20);
                    795:    m_uint32_t imm = bits(insn,0,15);
                    796: 
                    797:    ppc32_load_imm(b,X86_EBX,imm << 16);
                    798: 
                    799:    if (ra != 0)
                    800:       x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EBX,X86_EDI,REG_OFFSET(ra));
                    801: 
                    802:    ppc32_store_gpr(b,rd,X86_EBX);
                    803:    return(0);
                    804: }
                    805: 
                    806: /* AND */
                    807: DECLARE_INSN(AND)
                    808: {
                    809:    int rs = bits(insn,21,25);
                    810:    int ra = bits(insn,16,20);
                    811:    int rb = bits(insn,11,15);
                    812: 
                    813:    ppc32_load_gpr(b,X86_EBX,rs);
                    814:    ppc32_alu_gpr(b,X86_AND,X86_EBX,rb);
                    815:    ppc32_store_gpr(b,ra,X86_EBX);
                    816: 
                    817:    if (insn & 1)
                    818:       ppc32_update_cr0(b);
                    819: 
                    820:    return(0);
                    821: }
                    822: 
                    823: /* ANDC */
                    824: DECLARE_INSN(ANDC)
                    825: {
                    826:    int rs = bits(insn,21,25);
                    827:    int ra = bits(insn,16,20);
                    828:    int rb = bits(insn,11,15);
                    829: 
                    830:    /* $ra = $rs & ~$rb */
                    831:    ppc32_load_gpr(b,X86_EBX,rb);
                    832:    x86_not_reg(b->jit_ptr,X86_EBX);
                    833:    ppc32_alu_gpr(b,X86_AND,X86_EBX,rs);
                    834:    ppc32_store_gpr(b,ra,X86_EBX);
                    835: 
                    836:    if (insn & 1)
                    837:       ppc32_update_cr0(b);
                    838: 
                    839:    return(0);
                    840: }
                    841: 
                    842: /* AND Immediate */
                    843: DECLARE_INSN(ANDI)
                    844: {
                    845:    int rs = bits(insn,21,25);
                    846:    int ra = bits(insn,16,20);
                    847:    m_uint16_t imm = bits(insn,0,15);
                    848: 
                    849:    /* $ra = $rs & imm */
                    850:    ppc32_load_imm(b,X86_EBX,imm);
                    851:    ppc32_alu_gpr(b,X86_AND,X86_EBX,rs);
                    852:    ppc32_store_gpr(b,ra,X86_EBX);
                    853: 
                    854:    ppc32_update_cr0(b);
                    855:    return(0);
                    856: }
                    857: 
                    858: /* AND Immediate Shifted */
                    859: DECLARE_INSN(ANDIS)
                    860: {
                    861:    int rs = bits(insn,21,25);
                    862:    int ra = bits(insn,16,20);
                    863:    m_uint32_t imm = bits(insn,0,15);
                    864: 
                    865:    /* $ra = $rs & imm */
                    866:    ppc32_load_imm(b,X86_EBX,imm << 16);
                    867:    ppc32_alu_gpr(b,X86_AND,X86_EBX,rs);
                    868:    ppc32_store_gpr(b,ra,X86_EBX);
                    869: 
                    870:    ppc32_update_cr0(b);
                    871:    return(0);
                    872: }
                    873: 
                    874: /* B - Branch */
                    875: DECLARE_INSN(B)
                    876: {
                    877:    m_uint32_t offset = bits(insn,2,25);
                    878:    m_uint64_t new_ia;
                    879: 
                    880:    /* compute the new ia */
                    881:    new_ia = b->start_ia + ((b->ppc_trans_pos-1) << 2);
                    882:    new_ia += sign_extend(offset << 2,26);
                    883:    ppc32_set_jump(cpu,b,new_ia,1);
                    884:    return(0);
                    885: }
                    886: 
                    887: /* BA - Branch Absolute */
                    888: DECLARE_INSN(BA)
                    889: {
                    890:    m_uint32_t offset = bits(insn,2,25);
                    891:    m_uint64_t new_ia;
                    892: 
                    893:    /* compute the new ia */
                    894:    new_ia = sign_extend(offset << 2,26);
                    895:    ppc32_set_jump(cpu,b,new_ia,1);
                    896:    return(0);
                    897: }
                    898: 
                    899: /* BL - Branch and Link */
                    900: DECLARE_INSN(BL)
                    901: {
                    902:    m_uint32_t offset = bits(insn,2,25);
                    903:    m_uint64_t new_ia;
                    904: 
                    905:    /* compute the new ia */
                    906:    new_ia = b->start_ia + ((b->ppc_trans_pos-1) << 2);
                    907:    new_ia += sign_extend(offset << 2,26);
                    908: 
                    909:    /* set the return address */
                    910:    ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
                    911: 
                    912:    ppc32_set_jump(cpu,b,new_ia,1);
                    913:    return(0);
                    914: }
                    915: 
                    916: /* BLA - Branch and Link Absolute */
                    917: DECLARE_INSN(BLA)
                    918: {
                    919:    m_uint32_t offset = bits(insn,2,25);
                    920:    m_uint64_t new_ia;
                    921: 
                    922:    /* compute the new ia */
                    923:    new_ia = sign_extend(offset << 2,26);
                    924: 
                    925:    /* set the return address */
                    926:    ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
                    927: 
                    928:    ppc32_set_jump(cpu,b,new_ia,1);
                    929:    return(0);
                    930: }
                    931: 
                    932: /* BC - Branch Conditional (Condition Check only) */
                    933: DECLARE_INSN(BCC)
                    934: {
                    935:    int bo = bits(insn,21,25);
                    936:    int bi = bits(insn,16,20);
                    937:    int bd = bits(insn,2,15);
1.1.1.2 ! root      938:    u_int cr_field,cr_bit;
1.1       root      939:    m_uint32_t new_ia;
                    940:    u_char *jump_ptr;
                    941:    int local_jump;
                    942:    int cond;
                    943: 
                    944:    /* Get the wanted value for the condition bit */
                    945:    cond = (bo >> 3) & 0x1;
                    946: 
                    947:    /* Set the return address */
                    948:    if (insn & 1)
                    949:       ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
                    950: 
                    951:    /* Compute the new ia */
                    952:    new_ia = sign_extend_32(bd << 2,16);
                    953:    if (!(insn & 0x02))
                    954:       new_ia += b->start_ia + ((b->ppc_trans_pos-1) << 2);
                    955: 
                    956:    /* Test the condition bit */
1.1.1.2 ! root      957:    cr_field = ppc32_get_cr_field(bi);
        !           958:    cr_bit = ppc32_get_cr_bit(bi);
        !           959: 
        !           960:    x86_test_membase_imm(b->jit_ptr,
        !           961:                         X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field),
        !           962:                         (1 << cr_bit));
1.1       root      963: 
                    964:    local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr);
                    965: 
                    966:    /* 
                    967:     * Optimize the jump, depending if the destination is in the same 
                    968:     * page or not.
                    969:     */
                    970:    if (local_jump) {
                    971:       if (jump_ptr) {
                    972:          x86_branch(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,jump_ptr,FALSE);
                    973:       } else {
                    974:          ppc32_jit_tcb_record_patch(b,b->jit_ptr,new_ia);
                    975:          x86_branch32(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,0,FALSE);
                    976:       }
                    977:    } else {   
                    978:       jump_ptr = b->jit_ptr;
                    979:       x86_branch32(b->jit_ptr,(cond) ? X86_CC_Z : X86_CC_NZ,0,FALSE);
                    980:       ppc32_set_jump(cpu,b,new_ia,TRUE);
                    981:       x86_patch(jump_ptr,b->jit_ptr);
                    982:    }
                    983: 
                    984:    return(0);
                    985: }
                    986: 
                    987: /* BC - Branch Conditional */
                    988: DECLARE_INSN(BC)
                    989: {   
                    990:    int bo = bits(insn,21,25);
                    991:    int bi = bits(insn,16,20);
                    992:    int bd = bits(insn,2,15);
1.1.1.2 ! root      993:    u_int cr_field,cr_bit;
1.1       root      994:    m_uint32_t new_ia;
                    995:    u_char *jump_ptr;
                    996:    int local_jump;
                    997:    int cond,ctr;
                    998: 
                    999:    /* Get the wanted value for the condition bit and CTR value */
                   1000:    cond = (bo >> 3) & 0x1;
                   1001:    ctr  = (bo >> 1) & 0x1;
                   1002: 
                   1003:    /* Set the return address */
                   1004:    if (insn & 1)
                   1005:       ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
                   1006: 
                   1007:    /* Compute the new ia */
                   1008:    new_ia = sign_extend_32(bd << 2,16);
                   1009:    if (!(insn & 0x02))
                   1010:       new_ia += b->start_ia + ((b->ppc_trans_pos-1) << 2);
                   1011: 
                   1012:    x86_mov_reg_imm(b->jit_ptr,X86_EAX,1);
                   1013: 
                   1014:    /* Decrement the count register */
                   1015:    if (!(bo & 0x04)) {
                   1016:       x86_dec_membase(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr));
                   1017:       x86_set_reg(b->jit_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,X86_EBX,FALSE);
                   1018:       x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_EBX);
                   1019:    }
                   1020: 
                   1021:    /* Test the condition bit */
                   1022:    if (!((bo >> 4) & 0x01)) {
1.1.1.2 ! root     1023:       cr_field = ppc32_get_cr_field(bi);
        !          1024:       cr_bit = ppc32_get_cr_bit(bi);
        !          1025: 
        !          1026:       x86_test_membase_imm(b->jit_ptr,
        !          1027:                            X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field),
        !          1028:                            (1 << cr_bit));
        !          1029: 
1.1       root     1030:       x86_set_reg(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,X86_ECX,FALSE);
                   1031:       x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_ECX);
                   1032:    }
                   1033: 
                   1034:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x01);
                   1035: 
                   1036:    local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr);
                   1037: 
                   1038:    /* 
                   1039:     * Optimize the jump, depending if the destination is in the same 
                   1040:     * page or not.
                   1041:     */
                   1042:    if (local_jump) {
                   1043:       if (jump_ptr) {
                   1044:          x86_branch(b->jit_ptr,X86_CC_NZ,jump_ptr,FALSE);
                   1045:       } else {
                   1046:          ppc32_jit_tcb_record_patch(b,b->jit_ptr,new_ia);
                   1047:          x86_branch32(b->jit_ptr,X86_CC_NZ,0,FALSE);
                   1048:       }
                   1049:    } else {   
                   1050:       jump_ptr = b->jit_ptr;
                   1051:       x86_branch32(b->jit_ptr,X86_CC_Z,0,FALSE);
                   1052:       ppc32_set_jump(cpu,b,new_ia,TRUE);
                   1053:       x86_patch(jump_ptr,b->jit_ptr);
                   1054:    }
                   1055: 
                   1056:    return(0);
                   1057: }
                   1058: 
                   1059: /* BCLR - Branch Conditional to Link register */
                   1060: DECLARE_INSN(BCLR)
                   1061: {   
                   1062:    int bo = bits(insn,21,25);
                   1063:    int bi = bits(insn,16,20);
                   1064:    int bd = bits(insn,2,15);
1.1.1.2 ! root     1065:    u_int cr_field,cr_bit;
1.1       root     1066:    m_uint32_t new_ia;
                   1067:    u_char *jump_ptr;
                   1068:    int cond,ctr;
                   1069: 
                   1070:    /* Get the wanted value for the condition bit and CTR value */
                   1071:    cond = (bo >> 3) & 0x1;
                   1072:    ctr  = (bo >> 1) & 0x1;
                   1073: 
                   1074:    /* Compute the new ia */
                   1075:    new_ia = sign_extend_32(bd << 2,16);
                   1076:    if (!(insn & 0x02))
                   1077:       new_ia += b->start_ia + ((b->ppc_trans_pos-1) << 2);
                   1078: 
                   1079:    ppc32_load_imm(b,X86_EAX,1);
                   1080: 
                   1081:    /* Decrement the count register */
                   1082:    if (!(bo & 0x04)) {
                   1083:       x86_dec_membase(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr));
                   1084:       x86_set_reg(b->jit_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,X86_EBX,FALSE);
                   1085:       x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_EBX);
                   1086:    }
                   1087: 
                   1088:    /* Test the condition bit */
                   1089:    if (!((bo >> 4) & 0x01)) {
1.1.1.2 ! root     1090:       cr_field = ppc32_get_cr_field(bi);
        !          1091:       cr_bit = ppc32_get_cr_bit(bi);
        !          1092: 
        !          1093:       x86_test_membase_imm(b->jit_ptr,
        !          1094:                            X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field),
        !          1095:                            (1 << cr_bit));
        !          1096: 
1.1       root     1097:       x86_set_reg(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,X86_ECX,FALSE);
                   1098:       x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_ECX);
                   1099:    }
                   1100: 
                   1101:    /* Set the return address */
                   1102:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,lr),4);
                   1103: 
                   1104:    if (insn & 1)
                   1105:       ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
                   1106: 
                   1107:    /* Branching */
                   1108:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x01);
                   1109: 
                   1110:    jump_ptr = b->jit_ptr;
                   1111:    x86_branch32(b->jit_ptr,X86_CC_Z,0,FALSE);
                   1112: 
                   1113:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EDX,0xFFFFFFFC);
                   1114:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),X86_EDX,4);
                   1115:    ppc32_jit_tcb_push_epilog(b);
                   1116: 
                   1117:    x86_patch(jump_ptr,b->jit_ptr);
                   1118:    return(0);
                   1119: }
                   1120: 
                   1121: /* CMP - Compare */
                   1122: DECLARE_INSN(CMP)
                   1123: {
                   1124:    int rd = bits(insn,23,25);
                   1125:    int ra = bits(insn,16,20);
                   1126:    int rb = bits(insn,11,15);
                   1127: 
                   1128:    ppc32_load_gpr(b,X86_EBX,ra);
                   1129:    ppc32_alu_gpr(b,X86_CMP,X86_EBX,rb);
                   1130:    ppc32_update_cr(b,rd,TRUE);
                   1131:    return(0);
                   1132: }
                   1133: 
                   1134: /* CMPI - Compare Immediate */
                   1135: DECLARE_INSN(CMPI)
                   1136: {
                   1137:    int rd = bits(insn,23,25);
                   1138:    int ra = bits(insn,16,20);
                   1139:    m_uint16_t imm = bits(insn,0,15);
                   1140:    m_uint32_t tmp = sign_extend_32(imm,16);
                   1141: 
                   1142:    ppc32_load_imm(b,X86_EBX,tmp);
                   1143:    ppc32_load_gpr(b,X86_ESI,ra);
                   1144:    x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_ESI,X86_EBX);
                   1145: 
                   1146:    ppc32_update_cr(b,rd,TRUE);
                   1147:    return(0);
                   1148: }
                   1149: 
                   1150: /* CMPL - Compare Logical */
                   1151: DECLARE_INSN(CMPL)
                   1152: {
                   1153:    int rd = bits(insn,23,25);
                   1154:    int ra = bits(insn,16,20);
                   1155:    int rb = bits(insn,11,15);
                   1156: 
                   1157:    ppc32_load_gpr(b,X86_EAX,ra);
                   1158:    ppc32_alu_gpr(b,X86_CMP,X86_EAX,rb);
                   1159:    ppc32_update_cr(b,rd,FALSE);
                   1160:    return(0);
                   1161: }
                   1162: 
                   1163: /* CMPLI - Compare Immediate */
                   1164: DECLARE_INSN(CMPLI)
                   1165: {
                   1166:    int rd = bits(insn,23,25);
                   1167:    int ra = bits(insn,16,20);
                   1168:    m_uint16_t imm = bits(insn,0,15);
                   1169: 
                   1170:    ppc32_load_imm(b,X86_EBX,imm);
                   1171:    ppc32_load_gpr(b,X86_ESI,ra);
                   1172:    x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_ESI,X86_EBX);
                   1173: 
                   1174:    ppc32_update_cr(b,rd,FALSE);
                   1175:    return(0);
                   1176: }
                   1177: 
                   1178: /* CRAND - Condition Register AND */
                   1179: DECLARE_INSN(CRAND)
                   1180: {
                   1181:    int bd = bits(insn,21,25);
                   1182:    int bb = bits(insn,16,20);
                   1183:    int ba = bits(insn,11,15);
                   1184: 
                   1185:    /* test $ba bit */
1.1.1.2 ! root     1186:    x86_test_membase_imm(b->jit_ptr,
        !          1187:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
        !          1188:                         (1 << ppc32_get_cr_bit(ba)));
1.1       root     1189:    x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
                   1190: 
                   1191:    /* test $bb bit */
1.1.1.2 ! root     1192:    x86_test_membase_imm(b->jit_ptr,
        !          1193:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
        !          1194:                         (1 << ppc32_get_cr_bit(bb)));
1.1       root     1195:    x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
                   1196:    
                   1197:    /* result of AND between $ba and $bb */
                   1198:    x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EBX,X86_EAX);
                   1199:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
                   1200:    
                   1201:    /* set/clear $bd bit depending on the result */
1.1.1.2 ! root     1202:    x86_alu_membase_imm(b->jit_ptr,X86_AND,
        !          1203:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1204:                        ~(1 << ppc32_get_cr_bit(bd)));
        !          1205: 
        !          1206:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
        !          1207:    x86_alu_membase_reg(b->jit_ptr,X86_OR,
        !          1208:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1209:                        X86_EBX);
1.1       root     1210:    return(0);
                   1211: }
                   1212: 
                   1213: /* CRANDC - Condition Register AND with Complement */
                   1214: DECLARE_INSN(CRANDC)
                   1215: {
                   1216:    int bd = bits(insn,21,25);
                   1217:    int bb = bits(insn,16,20);
                   1218:    int ba = bits(insn,11,15);
                   1219: 
                   1220:    /* test $ba bit */
1.1.1.2 ! root     1221:    x86_test_membase_imm(b->jit_ptr,
        !          1222:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
        !          1223:                         (1 << ppc32_get_cr_bit(ba)));
1.1       root     1224:    x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
                   1225: 
                   1226:    /* test $bb bit */
1.1.1.2 ! root     1227:    x86_test_membase_imm(b->jit_ptr,
        !          1228:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
        !          1229:                         (1 << ppc32_get_cr_bit(bb)));
1.1       root     1230:    x86_set_reg(b->jit_ptr,X86_CC_Z,X86_EBX,FALSE);
                   1231:    
                   1232:    /* result of AND between $ba and $bb */
                   1233:    x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EBX,X86_EAX);
                   1234:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
                   1235:    
                   1236:    /* set/clear $bd bit depending on the result */
1.1.1.2 ! root     1237:    x86_alu_membase_imm(b->jit_ptr,X86_AND,
        !          1238:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1239:                        ~(1 << ppc32_get_cr_bit(bd)));
        !          1240: 
        !          1241:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
        !          1242:    x86_alu_membase_reg(b->jit_ptr,X86_OR,
        !          1243:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1244:                        X86_EBX);
1.1       root     1245:    return(0);
                   1246: }
                   1247: 
                   1248: /* CREQV - Condition Register EQV */
                   1249: DECLARE_INSN(CREQV)
                   1250: {
                   1251:    int bd = bits(insn,21,25);
                   1252:    int bb = bits(insn,16,20);
                   1253:    int ba = bits(insn,11,15);
                   1254: 
                   1255:    /* test $ba bit */
1.1.1.2 ! root     1256:    x86_test_membase_imm(b->jit_ptr,
        !          1257:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
        !          1258:                         (1 << ppc32_get_cr_bit(ba)));
1.1       root     1259:    x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
                   1260: 
                   1261:    /* test $bb bit */
1.1.1.2 ! root     1262:    x86_test_membase_imm(b->jit_ptr,
        !          1263:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
        !          1264:                         (1 << ppc32_get_cr_bit(bb)));
1.1       root     1265:    x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
                   1266:    
                   1267:    /* result of XOR between $ba and $bb */
                   1268:    x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EBX,X86_EAX);
                   1269:    x86_not_reg(b->jit_ptr,X86_EBX);
                   1270:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
                   1271:    
                   1272:    /* set/clear $bd bit depending on the result */
1.1.1.2 ! root     1273:    x86_alu_membase_imm(b->jit_ptr,X86_AND,
        !          1274:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1275:                        ~(1 << ppc32_get_cr_bit(bd)));
        !          1276: 
        !          1277:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
        !          1278:    x86_alu_membase_reg(b->jit_ptr,X86_OR,
        !          1279:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1280:                        X86_EBX);
1.1       root     1281:    return(0);
                   1282: }
                   1283: 
                   1284: /* CRNAND - Condition Register NAND */
                   1285: DECLARE_INSN(CRNAND)
                   1286: {
                   1287:    int bd = bits(insn,21,25);
                   1288:    int bb = bits(insn,16,20);
                   1289:    int ba = bits(insn,11,15);
                   1290: 
                   1291:    /* test $ba bit */
1.1.1.2 ! root     1292:    x86_test_membase_imm(b->jit_ptr,
        !          1293:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
        !          1294:                         (1 << ppc32_get_cr_bit(ba)));
1.1       root     1295:    x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
                   1296: 
                   1297:    /* test $bb bit */
1.1.1.2 ! root     1298:    x86_test_membase_imm(b->jit_ptr,
        !          1299:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
        !          1300:                         (1 << ppc32_get_cr_bit(bb)));
1.1       root     1301:    x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
                   1302:    
                   1303:    /* result of NAND between $ba and $bb */
                   1304:    x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EBX,X86_EAX);
                   1305:    x86_not_reg(b->jit_ptr,X86_EBX);
                   1306:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
                   1307:    
                   1308:    /* set/clear $bd bit depending on the result */
1.1.1.2 ! root     1309:    x86_alu_membase_imm(b->jit_ptr,X86_AND,
        !          1310:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1311:                        ~(1 << ppc32_get_cr_bit(bd)));
        !          1312: 
        !          1313:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
        !          1314:    x86_alu_membase_reg(b->jit_ptr,X86_OR,
        !          1315:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1316:                        X86_EBX);
1.1       root     1317:    return(0);
                   1318: }
                   1319: 
                   1320: /* CRNOR - Condition Register NOR */
                   1321: DECLARE_INSN(CRNOR)
                   1322: {
                   1323:    int bd = bits(insn,21,25);
                   1324:    int bb = bits(insn,16,20);
                   1325:    int ba = bits(insn,11,15);
                   1326: 
                   1327:    /* test $ba bit */
1.1.1.2 ! root     1328:    x86_test_membase_imm(b->jit_ptr,
        !          1329:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
        !          1330:                         (1 << ppc32_get_cr_bit(ba)));
1.1       root     1331:    x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
                   1332: 
                   1333:    /* test $bb bit */
1.1.1.2 ! root     1334:    x86_test_membase_imm(b->jit_ptr,
        !          1335:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
        !          1336:                         (1 << ppc32_get_cr_bit(bb)));
1.1       root     1337:    x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
                   1338:    
                   1339:    /* result of NOR between $ba and $bb */
                   1340:    x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EBX,X86_EAX);
                   1341:    x86_not_reg(b->jit_ptr,X86_EBX);
                   1342:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
                   1343:    
                   1344:    /* set/clear $bd bit depending on the result */
1.1.1.2 ! root     1345:    x86_alu_membase_imm(b->jit_ptr,X86_AND,
        !          1346:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1347:                        ~(1 << ppc32_get_cr_bit(bd)));
        !          1348: 
        !          1349:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
        !          1350:    x86_alu_membase_reg(b->jit_ptr,X86_OR,
        !          1351:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1352:                        X86_EBX);
1.1       root     1353:    return(0);
                   1354: }
                   1355: 
                   1356: /* CROR - Condition Register OR */
                   1357: DECLARE_INSN(CROR)
                   1358: {
                   1359:    int bd = bits(insn,21,25);
                   1360:    int bb = bits(insn,16,20);
                   1361:    int ba = bits(insn,11,15);
                   1362: 
                   1363:    /* test $ba bit */
1.1.1.2 ! root     1364:    x86_test_membase_imm(b->jit_ptr,
        !          1365:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
        !          1366:                         (1 << ppc32_get_cr_bit(ba)));
1.1       root     1367:    x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
                   1368: 
                   1369:    /* test $bb bit */
1.1.1.2 ! root     1370:    x86_test_membase_imm(b->jit_ptr,
        !          1371:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
        !          1372:                         (1 << ppc32_get_cr_bit(bb)));
1.1       root     1373:    x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
                   1374:    
                   1375:    /* result of OR between $ba and $bb */
                   1376:    x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EBX,X86_EAX);
                   1377:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
                   1378:    
                   1379:    /* set/clear $bd bit depending on the result */
1.1.1.2 ! root     1380:    x86_alu_membase_imm(b->jit_ptr,X86_AND,
        !          1381:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1382:                        ~(1 << ppc32_get_cr_bit(bd)));
        !          1383: 
        !          1384:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
        !          1385:    x86_alu_membase_reg(b->jit_ptr,X86_OR,
        !          1386:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1387:                        X86_EBX);
1.1       root     1388:    return(0);
                   1389: }
                   1390: 
                   1391: /* CRORC - Condition Register OR with Complement */
                   1392: DECLARE_INSN(CRORC)
                   1393: {
                   1394:    int bd = bits(insn,21,25);
                   1395:    int bb = bits(insn,16,20);
                   1396:    int ba = bits(insn,11,15);
                   1397: 
                   1398:    /* test $ba bit */
1.1.1.2 ! root     1399:    x86_test_membase_imm(b->jit_ptr,
        !          1400:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
        !          1401:                         (1 << ppc32_get_cr_bit(ba)));
1.1       root     1402:    x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
                   1403: 
                   1404:    /* test $bb bit */
1.1.1.2 ! root     1405:    x86_test_membase_imm(b->jit_ptr,
        !          1406:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
        !          1407:                         (1 << ppc32_get_cr_bit(bb)));
1.1       root     1408:    x86_set_reg(b->jit_ptr,X86_CC_Z,X86_EBX,FALSE);
                   1409:    
                   1410:    /* result of ORC between $ba and $bb */
                   1411:    x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EBX,X86_EAX);
                   1412:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
                   1413:    
                   1414:    /* set/clear $bd bit depending on the result */
1.1.1.2 ! root     1415:    x86_alu_membase_imm(b->jit_ptr,X86_AND,
        !          1416:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1417:                        ~(1 << ppc32_get_cr_bit(bd)));
        !          1418: 
        !          1419:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
        !          1420:    x86_alu_membase_reg(b->jit_ptr,X86_OR,
        !          1421:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1422:                        X86_EBX);
1.1       root     1423:    return(0);
                   1424: }
                   1425: 
                   1426: /* CRXOR - Condition Register XOR */
                   1427: DECLARE_INSN(CRXOR)
                   1428: {
                   1429:    int bd = bits(insn,21,25);
                   1430:    int bb = bits(insn,16,20);
                   1431:    int ba = bits(insn,11,15);
                   1432: 
                   1433:    /* test $ba bit */
1.1.1.2 ! root     1434:    x86_test_membase_imm(b->jit_ptr,
        !          1435:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
        !          1436:                         (1 << ppc32_get_cr_bit(ba)));
1.1       root     1437:    x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
                   1438: 
                   1439:    /* test $bb bit */
1.1.1.2 ! root     1440:    x86_test_membase_imm(b->jit_ptr,
        !          1441:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
        !          1442:                         (1 << ppc32_get_cr_bit(bb)));
1.1       root     1443:    x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
                   1444:    
                   1445:    /* result of XOR between $ba and $bb */
                   1446:    x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EBX,X86_EAX);
                   1447:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
                   1448:    
                   1449:    /* set/clear $bd bit depending on the result */
1.1.1.2 ! root     1450:    x86_alu_membase_imm(b->jit_ptr,X86_AND,
        !          1451:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1452:                        ~(1 << ppc32_get_cr_bit(bd)));
        !          1453: 
        !          1454:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
        !          1455:    x86_alu_membase_reg(b->jit_ptr,X86_OR,
        !          1456:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
        !          1457:                        X86_EBX);
1.1       root     1458:    return(0);
                   1459: }
                   1460: 
                   1461: /* DIVWU - Divide Word Unsigned */
                   1462: DECLARE_INSN(DIVWU)
                   1463: {
                   1464:    int rd = bits(insn,21,25);
                   1465:    int ra = bits(insn,16,20);
                   1466:    int rb = bits(insn,11,15);
                   1467: 
                   1468:    ppc32_load_gpr(b,X86_EAX,ra);
                   1469:    ppc32_load_gpr(b,X86_EBX,rb);
                   1470:    ppc32_load_imm(b,X86_EDX,0);
                   1471: 
                   1472:    x86_div_reg(b->jit_ptr,X86_EBX,0);
                   1473:    ppc32_store_gpr(b,rd,X86_EAX);
                   1474: 
                   1475:    if (insn & 1) {
                   1476:       x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                   1477:       ppc32_update_cr0(b);
                   1478:    }
                   1479:    
                   1480:    return(0);
                   1481: }
                   1482: 
                   1483: /* EQV */
                   1484: DECLARE_INSN(EQV)
                   1485: {
                   1486:    int rs = bits(insn,21,25);
                   1487:    int ra = bits(insn,16,20);
                   1488:    int rb = bits(insn,11,15);
                   1489: 
                   1490:    /* $ra = ~($rs ^ $rb) */
                   1491:    ppc32_load_gpr(b,X86_EBX,rs);
                   1492:    ppc32_alu_gpr(b,X86_XOR,X86_EBX,rb);
                   1493:    x86_not_reg(b->jit_ptr,X86_EBX);
                   1494:    ppc32_store_gpr(b,ra,X86_EBX);
                   1495: 
                   1496:    if (insn & 1) {
                   1497:       x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                   1498:       ppc32_update_cr0(b);
                   1499:    }
                   1500: 
                   1501:    return(0);
                   1502: }
                   1503: 
                   1504: /* EXTSB - Extend Sign Byte */
                   1505: DECLARE_INSN(EXTSB)
                   1506: {   
                   1507:    int rs = bits(insn,21,25);
                   1508:    int ra = bits(insn,16,20);
                   1509: 
                   1510:    ppc32_load_gpr(b,X86_EBX,rs);
                   1511:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,24);
                   1512:    x86_shift_reg_imm(b->jit_ptr,X86_SAR,X86_EBX,24);
                   1513:    ppc32_store_gpr(b,ra,X86_EBX);
                   1514: 
                   1515:    if (insn & 1) {
                   1516:       x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                   1517:       ppc32_update_cr0(b);
                   1518:    }
                   1519: 
                   1520:    return(0);
                   1521: }
                   1522: 
                   1523: /* EXTSH - Extend Sign Word */
                   1524: DECLARE_INSN(EXTSH)
                   1525: {   
                   1526:    int rs = bits(insn,21,25);
                   1527:    int ra = bits(insn,16,20);
                   1528: 
                   1529:    ppc32_load_gpr(b,X86_EBX,rs);
                   1530:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,16);
                   1531:    x86_shift_reg_imm(b->jit_ptr,X86_SAR,X86_EBX,16);
                   1532:    ppc32_store_gpr(b,ra,X86_EBX);
                   1533: 
                   1534:    if (insn & 1) {
                   1535:       x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                   1536:       ppc32_update_cr0(b);
                   1537:    }
                   1538: 
                   1539:    return(0);
                   1540: }
                   1541: 
                   1542: /* LBZ - Load Byte and Zero */
                   1543: DECLARE_INSN(LBZ)
                   1544: {
                   1545:    int rs = bits(insn,21,25);
                   1546:    int ra = bits(insn,16,20);
                   1547:    m_uint16_t offset = bits(insn,0,15);
                   1548: 
                   1549:    //ppc32_emit_memop(b,PPC_MEMOP_LBZ,ra,offset,rs,0);
                   1550:    ppc32_emit_memop_fast(b,0,PPC_MEMOP_LBZ,ra,offset,rs,ppc32_memop_fast_lbz);
                   1551:    return(0);
                   1552: }
                   1553: 
                   1554: /* LBZU - Load Byte and Zero with Update */
                   1555: DECLARE_INSN(LBZU)
                   1556: {
                   1557:    int rs = bits(insn,21,25);
                   1558:    int ra = bits(insn,16,20);
                   1559:    m_uint16_t offset = bits(insn,0,15);
                   1560: 
                   1561:    ppc32_emit_memop(b,PPC_MEMOP_LBZ,ra,offset,rs,1);
                   1562:    return(0);
                   1563: }
                   1564: 
                   1565: /* LBZUX - Load Byte and Zero with Update Indexed */
                   1566: DECLARE_INSN(LBZUX)
                   1567: {
                   1568:    int rs = bits(insn,21,25);
                   1569:    int ra = bits(insn,16,20);
                   1570:    int rb = bits(insn,11,15);
                   1571: 
                   1572:    ppc32_emit_memop_idx(b,PPC_MEMOP_LBZ,ra,rb,rs,1);
                   1573:    return(0);
                   1574: }
                   1575: 
                   1576: /* LBZX - Load Byte and Zero Indexed */
                   1577: DECLARE_INSN(LBZX)
                   1578: {
                   1579:    int rs = bits(insn,21,25);
                   1580:    int ra = bits(insn,16,20);
                   1581:    int rb = bits(insn,11,15);
                   1582: 
                   1583:    ppc32_emit_memop_idx(b,PPC_MEMOP_LBZ,ra,rb,rs,0);
                   1584:    return(0);
                   1585: }
                   1586: 
                   1587: /* LHA - Load Half-Word Algebraic */
                   1588: DECLARE_INSN(LHA)
                   1589: {
                   1590:    int rs = bits(insn,21,25);
                   1591:    int ra = bits(insn,16,20);
                   1592:    m_uint16_t offset = bits(insn,0,15);
                   1593: 
                   1594:    ppc32_emit_memop(b,PPC_MEMOP_LHA,ra,offset,rs,0);
                   1595:    return(0);
                   1596: }
                   1597: 
                   1598: /* LHAU - Load Half-Word Algebraic with Update */
                   1599: DECLARE_INSN(LHAU)
                   1600: {
                   1601:    int rs = bits(insn,21,25);
                   1602:    int ra = bits(insn,16,20);
                   1603:    m_uint16_t offset = bits(insn,0,15);
                   1604: 
                   1605:    ppc32_emit_memop(b,PPC_MEMOP_LHA,ra,offset,rs,1);
                   1606:    return(0);
                   1607: }
                   1608: 
                   1609: /* LHAUX - Load Half-Word Algebraic with Update Indexed */
                   1610: DECLARE_INSN(LHAUX)
                   1611: {
                   1612:    int rs = bits(insn,21,25);
                   1613:    int ra = bits(insn,16,20);
                   1614:    int rb = bits(insn,11,15);
                   1615: 
                   1616:    ppc32_emit_memop_idx(b,PPC_MEMOP_LHA,ra,rb,rs,1);
                   1617:    return(0);
                   1618: }
                   1619: 
                   1620: /* LHAX - Load Half-Word Algebraic Indexed */
                   1621: DECLARE_INSN(LHAX)
                   1622: {
                   1623:    int rs = bits(insn,21,25);
                   1624:    int ra = bits(insn,16,20);
                   1625:    int rb = bits(insn,11,15);
                   1626: 
                   1627:    ppc32_emit_memop_idx(b,PPC_MEMOP_LHA,ra,rb,rs,0);
                   1628:    return(0);
                   1629: }
                   1630: 
                   1631: /* LHZ - Load Half-Word and Zero */
                   1632: DECLARE_INSN(LHZ)
                   1633: {
                   1634:    int rs = bits(insn,21,25);
                   1635:    int ra = bits(insn,16,20);
                   1636:    m_uint16_t offset = bits(insn,0,15);
                   1637: 
                   1638:    ppc32_emit_memop(b,PPC_MEMOP_LHZ,ra,offset,rs,0);
                   1639:    return(0);
                   1640: }
                   1641: 
                   1642: /* LHZU - Load Half-Word and Zero with Update */
                   1643: DECLARE_INSN(LHZU)
                   1644: {
                   1645:    int rs = bits(insn,21,25);
                   1646:    int ra = bits(insn,16,20);
                   1647:    m_uint16_t offset = bits(insn,0,15);
                   1648: 
                   1649:    ppc32_emit_memop(b,PPC_MEMOP_LHZ,ra,offset,rs,1);
                   1650:    return(0);
                   1651: }
                   1652: 
                   1653: /* LHZUX - Load Half-Word and Zero with Update Indexed */
                   1654: DECLARE_INSN(LHZUX)
                   1655: {
                   1656:    int rs = bits(insn,21,25);
                   1657:    int ra = bits(insn,16,20);
                   1658:    int rb = bits(insn,11,15);
                   1659: 
                   1660:    ppc32_emit_memop_idx(b,PPC_MEMOP_LHZ,ra,rb,rs,1);
                   1661:    return(0);
                   1662: }
                   1663: 
                   1664: /* LHZX - Load Half-Word and Zero Indexed */
                   1665: DECLARE_INSN(LHZX)
                   1666: {
                   1667:    int rs = bits(insn,21,25);
                   1668:    int ra = bits(insn,16,20);
                   1669:    int rb = bits(insn,11,15);
                   1670: 
                   1671:    ppc32_emit_memop_idx(b,PPC_MEMOP_LHZ,ra,rb,rs,0);
                   1672:    return(0);
                   1673: }
                   1674: 
                   1675: /* LWZ - Load Word and Zero */
                   1676: DECLARE_INSN(LWZ)
                   1677: {
                   1678:    int rs = bits(insn,21,25);
                   1679:    int ra = bits(insn,16,20);
                   1680:    m_uint16_t offset = bits(insn,0,15);
                   1681: 
                   1682:    //ppc32_emit_memop(b,PPC_MEMOP_LWZ,ra,offset,rs,0);
                   1683:    ppc32_emit_memop_fast(b,0,PPC_MEMOP_LWZ,ra,offset,rs,ppc32_memop_fast_lwz);
                   1684:    return(0);
                   1685: }
                   1686: 
                   1687: /* LWZU - Load Word and Zero with Update */
                   1688: DECLARE_INSN(LWZU)
                   1689: {
                   1690:    int rs = bits(insn,21,25);
                   1691:    int ra = bits(insn,16,20);
                   1692:    m_uint16_t offset = bits(insn,0,15);
                   1693: 
                   1694:    ppc32_emit_memop(b,PPC_MEMOP_LWZ,ra,offset,rs,1);
                   1695:    return(0);
                   1696: }
                   1697: 
                   1698: /* LWZUX - Load Word and Zero with Update Indexed */
                   1699: DECLARE_INSN(LWZUX)
                   1700: {
                   1701:    int rs = bits(insn,21,25);
                   1702:    int ra = bits(insn,16,20);
                   1703:    int rb = bits(insn,11,15);
                   1704: 
                   1705:    ppc32_emit_memop_idx(b,PPC_MEMOP_LWZ,ra,rb,rs,1);
                   1706:    return(0);
                   1707: }
                   1708: 
                   1709: /* LWZX - Load Word and Zero Indexed */
                   1710: DECLARE_INSN(LWZX)
                   1711: {
                   1712:    int rs = bits(insn,21,25);
                   1713:    int ra = bits(insn,16,20);
                   1714:    int rb = bits(insn,11,15);
                   1715: 
                   1716:    ppc32_emit_memop_idx(b,PPC_MEMOP_LWZ,ra,rb,rs,0);
                   1717:    return(0);
                   1718: }
                   1719: 
                   1720: /* MCRF - Move Condition Register Field */
                   1721: DECLARE_INSN(MCRF)
                   1722: {
                   1723:    int rd = bits(insn,23,25);
                   1724:    int rs = bits(insn,18,20);
                   1725: 
1.1.1.2 ! root     1726:    /* Load "rs" field in %edx */
        !          1727:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,PPC32_CR_FIELD_OFFSET(rs),4);
        !          1728: 
        !          1729:    /* Store it in "rd" field */
        !          1730:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,PPC32_CR_FIELD_OFFSET(rd),X86_EDX,4);
1.1       root     1731:    return(0);
                   1732: }
                   1733: 
                   1734: /* MFCR - Move from Condition Register */
                   1735: DECLARE_INSN(MFCR)
                   1736: {
                   1737:    int rd = bits(insn,21,25);
1.1.1.2 ! root     1738:    int i;
        !          1739: 
        !          1740:    x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EAX,X86_EAX);
        !          1741: 
        !          1742:    for(i=0;i<8;i++) {
        !          1743:       /* load field in %edx */
        !          1744:       x86_mov_reg_membase(b->jit_ptr,X86_EDX,
        !          1745:                           X86_EDI,PPC32_CR_FIELD_OFFSET(i),4);
        !          1746:       x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EAX,4);
        !          1747:       x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_EDX);
        !          1748:    }
1.1       root     1749: 
                   1750:    ppc32_store_gpr(b,rd,X86_EAX);
                   1751:    return(0);
                   1752: }
                   1753: 
                   1754: /* MFMSR - Move from Machine State Register */
                   1755: DECLARE_INSN(MFMSR)
                   1756: {
                   1757:    int rd = bits(insn,21,25);
                   1758: 
                   1759:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,OFFSET(cpu_ppc_t,msr),4);
                   1760:    ppc32_store_gpr(b,rd,X86_EAX);
                   1761:    return(0);
                   1762: }
                   1763: 
                   1764: /* MFSR - Move From Segment Register */
                   1765: DECLARE_INSN(MFSR)
                   1766: {
                   1767:    int rd = bits(insn,21,25);
                   1768:    int sr = bits(insn,16,19);
                   1769: 
                   1770:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,
                   1771:                        X86_EDI,(OFFSET(cpu_ppc_t,sr) + (sr << 2)),4);
                   1772:    ppc32_store_gpr(b,rd,X86_EAX);
                   1773:    return(0);
                   1774: }
                   1775: 
                   1776: /* MTCRF - Move to Condition Register Fields */
                   1777: DECLARE_INSN(MTCRF)
                   1778: {
                   1779:    int rs = bits(insn,21,25);
                   1780:    int crm = bits(insn,12,19);
                   1781:    int i;
                   1782: 
1.1.1.2 ! root     1783:    ppc32_load_gpr(b,X86_EDX,rs);
        !          1784: 
1.1       root     1785:    for(i=0;i<8;i++)
1.1.1.2 ! root     1786:       if (crm & (1 << (7 - i))) {
        !          1787:          x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDX,4);
1.1       root     1788: 
1.1.1.2 ! root     1789:          if (i != 7)
        !          1790:             x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_EAX,28 - (i << 2));
1.1       root     1791: 
1.1.1.2 ! root     1792:          x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x0F);
        !          1793:          x86_mov_membase_reg(b->jit_ptr,X86_EDI,PPC32_CR_FIELD_OFFSET(i),
        !          1794:                              X86_EAX,4);
        !          1795:       }
1.1       root     1796: 
                   1797:    return(0);
                   1798: }
                   1799: 
                   1800: /* MULHW - Multiply High Word */
                   1801: DECLARE_INSN(MULHW)
                   1802: {
                   1803:    int rd = bits(insn,21,25);
                   1804:    int ra = bits(insn,16,20);
                   1805:    int rb = bits(insn,11,15);
                   1806: 
                   1807:    ppc32_load_gpr(b,X86_EAX,ra);
                   1808:    ppc32_load_gpr(b,X86_EBX,rb);
                   1809:    x86_mul_reg(b->jit_ptr,X86_EBX,1);
                   1810:    ppc32_store_gpr(b,rd,X86_EDX);
                   1811: 
                   1812:    if (insn & 1) {
                   1813:       x86_test_reg_reg(b->jit_ptr,X86_EDX,X86_EDX);
                   1814:       ppc32_update_cr0(b);
                   1815:    }
                   1816: 
                   1817:    return(0);
                   1818: }
                   1819: 
                   1820: /* MULHWU - Multiply High Word Unsigned */
                   1821: DECLARE_INSN(MULHWU)
                   1822: {
                   1823:    int rd = bits(insn,21,25);
                   1824:    int ra = bits(insn,16,20);
                   1825:    int rb = bits(insn,11,15);
                   1826: 
                   1827:    ppc32_load_gpr(b,X86_EAX,ra);
                   1828:    ppc32_load_gpr(b,X86_EBX,rb);
                   1829:    x86_mul_reg(b->jit_ptr,X86_EBX,0);
                   1830:    ppc32_store_gpr(b,rd,X86_EDX);
                   1831: 
                   1832:    if (insn & 1) {
                   1833:       x86_test_reg_reg(b->jit_ptr,X86_EDX,X86_EDX);
                   1834:       ppc32_update_cr0(b);
                   1835:    }
                   1836: 
                   1837:    return(0);
                   1838: }
                   1839: 
                   1840: /* MULLI - Multiply Low Immediate */
                   1841: DECLARE_INSN(MULLI)
                   1842: {
                   1843:    int rd = bits(insn,21,25);
                   1844:    int ra = bits(insn,16,20);
                   1845:    m_uint32_t imm = bits(insn,0,15);
                   1846: 
                   1847:    ppc32_load_gpr(b,X86_EAX,ra);
                   1848:    ppc32_load_imm(b,X86_EBX,sign_extend_32(imm,16));
                   1849: 
                   1850:    x86_mul_reg(b->jit_ptr,X86_EBX,1);
                   1851:    ppc32_store_gpr(b,rd,X86_EAX);
                   1852:    return(0);
                   1853: }
                   1854: 
                   1855: /* MULLW - Multiply Low Word */
                   1856: DECLARE_INSN(MULLW)
                   1857: {
                   1858:    int rd = bits(insn,21,25);
                   1859:    int ra = bits(insn,16,20);
                   1860:    int rb = bits(insn,11,15);
                   1861: 
                   1862:    ppc32_load_gpr(b,X86_EAX,ra);
                   1863:    ppc32_load_gpr(b,X86_EBX,rb);
                   1864:    x86_mul_reg(b->jit_ptr,X86_EBX,1);
                   1865:    ppc32_store_gpr(b,rd,X86_EAX);
                   1866: 
                   1867:    if (insn & 1) {
                   1868:       x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                   1869:       ppc32_update_cr0(b);
                   1870:    }
                   1871: 
                   1872:    return(0);
                   1873: }
                   1874: 
                   1875: /* NAND */
                   1876: DECLARE_INSN(NAND)
                   1877: {
                   1878:    int rs = bits(insn,21,25);
                   1879:    int ra = bits(insn,16,20);
                   1880:    int rb = bits(insn,11,15);
                   1881: 
                   1882:    /* $ra = ~($rs & $rb) */
                   1883:    ppc32_load_gpr(b,X86_EBX,rs);
                   1884:    ppc32_alu_gpr(b,X86_AND,X86_EBX,rb);
                   1885:    x86_not_reg(b->jit_ptr,X86_EBX);
                   1886:    ppc32_store_gpr(b,ra,X86_EBX);
                   1887: 
                   1888:    if (insn & 1) {
                   1889:       x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                   1890:       ppc32_update_cr0(b);
                   1891:    }
                   1892: 
                   1893:    return(0);
                   1894: }
                   1895: 
                   1896: /* NEG */
                   1897: DECLARE_INSN(NEG)
                   1898: {
                   1899:    int rd = bits(insn,21,25);
                   1900:    int ra = bits(insn,16,20);
                   1901: 
                   1902:    ppc32_load_gpr(b,X86_EBX,ra);
                   1903:    x86_neg_reg(b->jit_ptr,X86_EBX);
                   1904:    ppc32_store_gpr(b,rd,X86_EBX);
                   1905: 
                   1906:    if (insn & 1) {
                   1907:       x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                   1908:       ppc32_update_cr0(b);
                   1909:    }
                   1910: 
                   1911:    return(0);
                   1912: }
                   1913: 
                   1914: /* NOR */
                   1915: DECLARE_INSN(NOR)
                   1916: {
                   1917:    int rs = bits(insn,21,25);
                   1918:    int ra = bits(insn,16,20);
                   1919:    int rb = bits(insn,11,15);
                   1920: 
                   1921:    /* $ra = ~($rs | $rb) */
                   1922:    ppc32_load_gpr(b,X86_EBX,rs);
                   1923:    ppc32_alu_gpr(b,X86_OR,X86_EBX,rb);
                   1924:    x86_not_reg(b->jit_ptr,X86_EBX);
                   1925:    ppc32_store_gpr(b,ra,X86_EBX);
                   1926: 
                   1927:    if (insn & 1) {
                   1928:       x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                   1929:       ppc32_update_cr0(b);
                   1930:    }
                   1931: 
                   1932:    return(0);
                   1933: }
                   1934: 
                   1935: /* OR */
                   1936: DECLARE_INSN(OR)
                   1937: {
                   1938:    int rs = bits(insn,21,25);
                   1939:    int ra = bits(insn,16,20);
                   1940:    int rb = bits(insn,11,15);
                   1941: 
                   1942:    ppc32_load_gpr(b,X86_ECX,rs);
                   1943: 
                   1944:    if (rs != rb)
                   1945:       ppc32_alu_gpr(b,X86_OR,X86_ECX,rb);
                   1946: 
                   1947:    ppc32_store_gpr(b,ra,X86_ECX);
                   1948: 
                   1949:    if (insn & 1) {
                   1950:       if (rs == rb)
                   1951:          x86_test_reg_reg(b->jit_ptr,X86_ECX,X86_ECX);
                   1952:       ppc32_update_cr0(b);
                   1953:    }
                   1954: 
                   1955:    return(0);
                   1956: }
                   1957: 
                   1958: /* OR with Complement */
                   1959: DECLARE_INSN(ORC)
                   1960: {
                   1961:    int rs = bits(insn,21,25);
                   1962:    int ra = bits(insn,16,20);
                   1963:    int rb = bits(insn,11,15);
                   1964: 
                   1965:    /* $ra = $rs | ~$rb */
                   1966:    ppc32_load_gpr(b,X86_EBX,rb);
                   1967:    x86_not_reg(b->jit_ptr,X86_EBX);
                   1968:    ppc32_alu_gpr(b,X86_OR,X86_EBX,rs);
                   1969:    ppc32_store_gpr(b,ra,X86_EBX);
                   1970: 
                   1971:    if (insn & 1)
                   1972:       ppc32_update_cr0(b);
                   1973: 
                   1974:    return(0);
                   1975: }
                   1976: 
                   1977: /* OR Immediate */
                   1978: DECLARE_INSN(ORI)
                   1979: {
                   1980:    int rs = bits(insn,21,25);
                   1981:    int ra = bits(insn,16,20);
                   1982:    m_uint16_t imm = bits(insn,0,15);
                   1983: 
                   1984:    /* $ra = $rs | imm */
                   1985:    ppc32_load_imm(b,X86_EBX,imm);
                   1986:    ppc32_alu_gpr(b,X86_OR,X86_EBX,rs);
                   1987:    ppc32_store_gpr(b,ra,X86_EBX);
                   1988:    return(0);
                   1989: }
                   1990: 
                   1991: /* OR Immediate Shifted */
                   1992: DECLARE_INSN(ORIS)
                   1993: {
                   1994:    int rs = bits(insn,21,25);
                   1995:    int ra = bits(insn,16,20);
                   1996:    m_uint32_t imm = bits(insn,0,15);
                   1997: 
                   1998:    /* $ra = $rs | (imm << 16) */
                   1999:    ppc32_load_imm(b,X86_EBX,imm << 16);
                   2000:    ppc32_alu_gpr(b,X86_OR,X86_EBX,rs);
                   2001:    ppc32_store_gpr(b,ra,X86_EBX);
                   2002:    return(0);
                   2003: }
                   2004: 
                   2005: /* RLWIMI - Rotate Left Word Immediate then Mask Insert */
                   2006: DECLARE_INSN(RLWIMI)
                   2007: {
                   2008:    int rs = bits(insn,21,25);
                   2009:    int ra = bits(insn,16,20);
                   2010:    int sh = bits(insn,11,15);
                   2011:    int mb = bits(insn,6,10);
                   2012:    int me = bits(insn,1,5);
                   2013:    register m_uint32_t mask;
                   2014:  
                   2015:    mask = ppc32_rotate_mask(mb,me);
                   2016: 
                   2017:    /* Apply inverse mask to %eax "ra" */
                   2018:    ppc32_load_gpr(b,X86_EAX,ra);
                   2019:    if (mask != 0)
                   2020:       x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,~mask);
                   2021: 
                   2022:    /* Rotate %ebx ("rs") of "sh" bits and apply the mask */
                   2023:    ppc32_load_gpr(b,X86_EBX,rs);
                   2024: 
                   2025:    if (sh != 0)
                   2026:    x86_shift_reg_imm(b->jit_ptr,X86_ROL,X86_EBX,sh);
                   2027: 
                   2028:    if (mask != 0xFFFFFFFF)
                   2029:       x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,mask);
                   2030: 
                   2031:    /* Store the result */
                   2032:    x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EBX,X86_EAX);
                   2033:    ppc32_store_gpr(b,ra,X86_EBX);
                   2034: 
                   2035:    if (insn & 1)
                   2036:       ppc32_update_cr0(b);
                   2037: 
                   2038:    return(0);
                   2039: }
                   2040: 
                   2041: /* RLWINM - Rotate Left Word Immediate AND with Mask */
                   2042: DECLARE_INSN(RLWINM)
                   2043: {
                   2044:    int rs = bits(insn,21,25);
                   2045:    int ra = bits(insn,16,20);
                   2046:    int sh = bits(insn,11,15);
                   2047:    int mb = bits(insn,6,10);
                   2048:    int me = bits(insn,1,5);
                   2049:    register m_uint32_t mask;
                   2050: 
                   2051:    mask = ppc32_rotate_mask(mb,me);
                   2052: 
                   2053:    /* Rotate %ebx ("rs") of "sh" bits and apply the mask */
                   2054:    ppc32_load_gpr(b,X86_EBX,rs);
                   2055: 
                   2056:    if (sh != 0)
                   2057:       x86_shift_reg_imm(b->jit_ptr,X86_ROL,X86_EBX,sh);
                   2058: 
                   2059:    if (mask != 0xFFFFFFFF)
                   2060:       x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,mask);
                   2061: 
                   2062:    ppc32_store_gpr(b,ra,X86_EBX);
                   2063: 
                   2064:    if (insn & 1) {
                   2065:       x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                   2066:       ppc32_update_cr0(b);
                   2067:    }
                   2068: 
                   2069:    return(0);
                   2070: }
                   2071: 
                   2072: /* RLWNM - Rotate Left Word then Mask Insert */
                   2073: DECLARE_INSN(RLWNM)
                   2074: {
                   2075:    int rs = bits(insn,21,25);
                   2076:    int ra = bits(insn,16,20);
                   2077:    int rb = bits(insn,11,15);
                   2078:    int mb = bits(insn,6,10);
                   2079:    int me = bits(insn,1,5);
                   2080:    register m_uint32_t mask;
                   2081: 
                   2082:    mask = ppc32_rotate_mask(mb,me);
                   2083: 
                   2084:    /* Load the shift register ("sh") */
                   2085:    ppc32_load_gpr(b,X86_ECX,rb);
                   2086: 
                   2087:    /* Rotate %ebx ("rs") and apply the mask */
                   2088:    ppc32_load_gpr(b,X86_EBX,rs);
                   2089:    x86_shift_reg(b->jit_ptr,X86_ROL,X86_EBX);
                   2090: 
                   2091:    if (mask != 0xFFFFFFFF)
                   2092:       x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,mask);
                   2093: 
                   2094:    ppc32_store_gpr(b,ra,X86_EBX);
                   2095: 
                   2096:    if (insn & 1) {
                   2097:       x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                   2098:       ppc32_update_cr0(b);
                   2099:    }
                   2100: 
                   2101:    return(0);
                   2102: }
                   2103: 
                   2104: /* Shift Left Word */
                   2105: DECLARE_INSN(SLW)
                   2106: {
                   2107:    int rs = bits(insn,21,25);
                   2108:    int ra = bits(insn,16,20);
                   2109:    int rb = bits(insn,11,15);
                   2110:    u_char *test1;
                   2111: 
                   2112:    /* If count >= 32, then null result */
                   2113:    ppc32_load_gpr(b,X86_ECX,rb);
                   2114:    x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EBX,X86_EBX);
                   2115: 
                   2116:    x86_test_reg_imm(b->jit_ptr,X86_ECX,0x20);
                   2117:    test1 = b->jit_ptr;
                   2118:    x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
                   2119: 
                   2120:    ppc32_load_gpr(b,X86_EBX,rs);
                   2121:    x86_shift_reg(b->jit_ptr,X86_SHL,X86_EBX);
                   2122: 
                   2123:    /* Store the result */
                   2124:    x86_patch(test1,b->jit_ptr);
                   2125:    ppc32_store_gpr(b,ra,X86_EBX);
                   2126: 
                   2127:    if (insn & 1) {
                   2128:       x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                   2129:       ppc32_update_cr0(b);
                   2130:    }
                   2131: 
                   2132:    return(0);
                   2133: }
                   2134: 
                   2135: /* SRAWI - Shift Right Algebraic Word Immediate */
                   2136: DECLARE_INSN(SRAWI)
                   2137: {   
                   2138:    int rs = bits(insn,21,25);
                   2139:    int ra = bits(insn,16,20);
                   2140:    int sh = bits(insn,11,15);
                   2141:    register m_uint32_t mask;
                   2142: 
                   2143:    mask = ~(0xFFFFFFFFU << sh);
                   2144: 
                   2145:    /* $ra = (int32)$rs >> sh */
                   2146:    ppc32_load_gpr(b,X86_EBX,rs);
                   2147:    x86_mov_reg_reg(b->jit_ptr,X86_ESI,X86_EBX,4);
                   2148:    x86_shift_reg_imm(b->jit_ptr,X86_SAR,X86_EBX,sh);
                   2149:    ppc32_store_gpr(b,ra,X86_EBX);
                   2150: 
                   2151:    /* test the sign-bit of gpr[rs] */
                   2152:    x86_test_reg_reg(b->jit_ptr,X86_ESI,X86_ESI);
                   2153:    x86_set_reg(b->jit_ptr,X86_CC_LT,X86_EAX,TRUE);
                   2154: 
                   2155:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,mask);
                   2156:    x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_ECX,TRUE);
                   2157:    
                   2158:    x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_ECX,X86_EAX);
                   2159:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ECX,0x1);
                   2160:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_ECX,4);
                   2161: 
                   2162:    if (insn & 1) {
                   2163:       x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                   2164:       ppc32_update_cr0(b);
                   2165:    }
                   2166: 
                   2167:    return(0);
                   2168: }
                   2169: 
                   2170: /* Shift Right Word */
                   2171: DECLARE_INSN(SRW)
                   2172: {
                   2173:    int rs = bits(insn,21,25);
                   2174:    int ra = bits(insn,16,20);
                   2175:    int rb = bits(insn,11,15);
                   2176:    u_char *test1;
                   2177: 
                   2178:    /* If count >= 32, then null result */
                   2179:    ppc32_load_gpr(b,X86_ECX,rb);
                   2180:    x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EBX,X86_EBX);
                   2181: 
                   2182:    x86_test_reg_imm(b->jit_ptr,X86_ECX,0x20);
                   2183:    test1 = b->jit_ptr;
                   2184:    x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
                   2185: 
                   2186:    ppc32_load_gpr(b,X86_EBX,rs);
                   2187:    x86_shift_reg(b->jit_ptr,X86_SHR,X86_EBX);
                   2188: 
                   2189:    /* Store the result */
                   2190:    x86_patch(test1,b->jit_ptr);
                   2191:    ppc32_store_gpr(b,ra,X86_EBX);
                   2192: 
                   2193:    if (insn & 1) {
                   2194:       x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                   2195:       ppc32_update_cr0(b);
                   2196:    }
                   2197:          
                   2198:    return(0);
                   2199: }
                   2200: 
                   2201: /* STB - Store Byte */
                   2202: DECLARE_INSN(STB)
                   2203: {
                   2204:    int rs = bits(insn,21,25);
                   2205:    int ra = bits(insn,16,20);
                   2206:    m_uint16_t offset = bits(insn,0,15);
                   2207: 
                   2208:    //ppc32_emit_memop(b,PPC_MEMOP_STB,ra,offset,rs,0);
                   2209:    ppc32_emit_memop_fast(b,1,PPC_MEMOP_STB,ra,offset,rs,ppc32_memop_fast_stb);
                   2210:    return(0);
                   2211: }
                   2212: 
                   2213: /* STBU - Store Byte with Update */
                   2214: DECLARE_INSN(STBU)
                   2215: {
                   2216:    int rs = bits(insn,21,25);
                   2217:    int ra = bits(insn,16,20);
                   2218:    m_uint16_t offset = bits(insn,0,15);
                   2219: 
                   2220:    ppc32_emit_memop(b,PPC_MEMOP_STB,ra,offset,rs,1);
                   2221:    return(0);
                   2222: }
                   2223: 
                   2224: /* STBUX - Store Byte with Update Indexed */
                   2225: DECLARE_INSN(STBUX)
                   2226: {
                   2227:    int rs = bits(insn,21,25);
                   2228:    int ra = bits(insn,16,20);
                   2229:    int rb = bits(insn,11,15);
                   2230: 
                   2231:    ppc32_emit_memop_idx(b,PPC_MEMOP_STB,ra,rb,rs,1);
                   2232:    return(0);
                   2233: }
                   2234: 
                   2235: /* STBUX - Store Byte Indexed */
                   2236: DECLARE_INSN(STBX)
                   2237: {
                   2238:    int rs = bits(insn,21,25);
                   2239:    int ra = bits(insn,16,20);
                   2240:    int rb = bits(insn,11,15);
                   2241: 
                   2242:    ppc32_emit_memop_idx(b,PPC_MEMOP_STB,ra,rb,rs,0);
                   2243:    return(0);
                   2244: }
                   2245: 
                   2246: /* STH - Store Half-Word */
                   2247: DECLARE_INSN(STH)
                   2248: {
                   2249:    int rs = bits(insn,21,25);
                   2250:    int ra = bits(insn,16,20);
                   2251:    m_uint16_t offset = bits(insn,0,15);
                   2252: 
                   2253:    ppc32_emit_memop(b,PPC_MEMOP_STH,ra,offset,rs,0);
                   2254:    return(0);
                   2255: }
                   2256: 
                   2257: /* STHU - Store Half-Word with Update */
                   2258: DECLARE_INSN(STHU)
                   2259: {
                   2260:    int rs = bits(insn,21,25);
                   2261:    int ra = bits(insn,16,20);
                   2262:    m_uint16_t offset = bits(insn,0,15);
                   2263: 
                   2264:    ppc32_emit_memop(b,PPC_MEMOP_STH,ra,offset,rs,1);
                   2265:    return(0);
                   2266: }
                   2267: 
                   2268: /* STHUX - Store Half-Word with Update Indexed */
                   2269: DECLARE_INSN(STHUX)
                   2270: {
                   2271:    int rs = bits(insn,21,25);
                   2272:    int ra = bits(insn,16,20);
                   2273:    int rb = bits(insn,11,15);
                   2274: 
                   2275:    ppc32_emit_memop_idx(b,PPC_MEMOP_STH,ra,rb,rs,1);
                   2276:    return(0);
                   2277: }
                   2278: 
                   2279: /* STHUX - Store Half-Word Indexed */
                   2280: DECLARE_INSN(STHX)
                   2281: {
                   2282:    int rs = bits(insn,21,25);
                   2283:    int ra = bits(insn,16,20);
                   2284:    int rb = bits(insn,11,15);
                   2285: 
                   2286:    ppc32_emit_memop_idx(b,PPC_MEMOP_STH,ra,rb,rs,0);
                   2287:    return(0);
                   2288: }
                   2289: 
                   2290: /* STW - Store Word */
                   2291: DECLARE_INSN(STW)
                   2292: {
                   2293:    int rs = bits(insn,21,25);
                   2294:    int ra = bits(insn,16,20);
                   2295:    m_uint16_t offset = bits(insn,0,15);
                   2296: 
                   2297:    //ppc32_emit_memop(b,PPC_MEMOP_STW,ra,offset,rs,0);
                   2298:    ppc32_emit_memop_fast(b,1,PPC_MEMOP_STW,ra,offset,rs,ppc32_memop_fast_stw);
                   2299:    return(0);
                   2300: }
                   2301: 
                   2302: /* STWU - Store Word with Update */
                   2303: DECLARE_INSN(STWU)
                   2304: {
                   2305:    int rs = bits(insn,21,25);
                   2306:    int ra = bits(insn,16,20);
                   2307:    m_uint16_t offset = bits(insn,0,15);
                   2308: 
                   2309:    ppc32_emit_memop(b,PPC_MEMOP_STW,ra,offset,rs,1);
                   2310:    return(0);
                   2311: }
                   2312: 
                   2313: /* STWUX - Store Word with Update Indexed */
                   2314: DECLARE_INSN(STWUX)
                   2315: {
                   2316:    int rs = bits(insn,21,25);
                   2317:    int ra = bits(insn,16,20);
                   2318:    int rb = bits(insn,11,15);
                   2319: 
                   2320:    ppc32_emit_memop_idx(b,PPC_MEMOP_STW,ra,rb,rs,1);
                   2321:    return(0);
                   2322: }
                   2323: 
                   2324: /* STWUX - Store Word Indexed */
                   2325: DECLARE_INSN(STWX)
                   2326: {
                   2327:    int rs = bits(insn,21,25);
                   2328:    int ra = bits(insn,16,20);
                   2329:    int rb = bits(insn,11,15);
                   2330: 
                   2331:    ppc32_emit_memop_idx(b,PPC_MEMOP_STW,ra,rb,rs,0);
                   2332:    return(0);
                   2333: }
                   2334: 
                   2335: /* SUBF - Subtract From */
                   2336: DECLARE_INSN(SUBF)
                   2337: {
                   2338:    int rd = bits(insn,21,25);
                   2339:    int ra = bits(insn,16,20);
                   2340:    int rb = bits(insn,11,15);
                   2341: 
                   2342:    /* $rd = $rb - $rb */
                   2343:    ppc32_load_gpr(b,X86_EBX,rb);
                   2344:    ppc32_alu_gpr(b,X86_SUB,X86_EBX,ra);
                   2345:    ppc32_store_gpr(b,rd,X86_EBX);
                   2346: 
                   2347:    if (insn & 1)
                   2348:       ppc32_update_cr0(b);
                   2349:       
                   2350:    return(0);
                   2351: }
                   2352: 
                   2353: /* SUBFC - Subtract From Carrying */
                   2354: DECLARE_INSN(SUBFC)
                   2355: {
                   2356:    int rd = bits(insn,21,25);
                   2357:    int ra = bits(insn,16,20);
                   2358:    int rb = bits(insn,11,15);
                   2359: 
                   2360:    /* ~$ra + 1 */
                   2361:    ppc32_load_gpr(b,X86_ESI,ra);
                   2362:    x86_not_reg(b->jit_ptr,X86_ESI);
                   2363:    x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESI,1);
                   2364:    x86_set_reg(b->jit_ptr,X86_CC_C,X86_EAX,FALSE);
                   2365: 
                   2366:    /* add $rb */
                   2367:    ppc32_alu_gpr(b,X86_ADD,X86_ESI,rb);
                   2368:    x86_set_reg(b->jit_ptr,X86_CC_C,X86_ECX,FALSE);
                   2369: 
                   2370:    ppc32_store_gpr(b,rd,X86_ESI);
                   2371: 
                   2372:    /* store the carry flag */
                   2373:    x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ECX);
                   2374:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x1);
                   2375: 
                   2376:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_EAX,4);
                   2377: 
                   2378:    /* update cr0 */
                   2379:    if (insn & 1) {
                   2380:       x86_test_reg_reg(b->jit_ptr,X86_ESI,X86_ESI);
                   2381:       ppc32_update_cr0(b);
                   2382:    }
                   2383: 
                   2384:    return(0);
                   2385: }
                   2386: 
                   2387: /* SUBFE - Subtract From Extended */
                   2388: DECLARE_INSN(SUBFE)
                   2389: {
                   2390:    int rd = bits(insn,21,25);
                   2391:    int ra = bits(insn,16,20);
                   2392:    int rb = bits(insn,11,15);
                   2393: 
                   2394:    /* ~$ra + carry */
                   2395:    ppc32_load_gpr(b,X86_ESI,ra);
                   2396:    x86_not_reg(b->jit_ptr,X86_ESI);
                   2397:    x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_ESI,
                   2398:                        X86_EDI,OFFSET(cpu_ppc_t,xer_ca));
                   2399:    x86_set_reg(b->jit_ptr,X86_CC_C,X86_EAX,FALSE);
                   2400: 
                   2401:    /* add $rb */
                   2402:    ppc32_alu_gpr(b,X86_ADD,X86_ESI,rb);
                   2403:    x86_set_reg(b->jit_ptr,X86_CC_C,X86_ECX,FALSE);
                   2404: 
                   2405:    ppc32_store_gpr(b,rd,X86_ESI);
                   2406: 
                   2407:    /* store the carry flag */
                   2408:    x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ECX);
                   2409:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x1);
                   2410:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_EAX,4);
                   2411: 
                   2412:    /* update cr0 */
                   2413:    if (insn & 1) {
                   2414:       x86_test_reg_reg(b->jit_ptr,X86_ESI,X86_ESI);
                   2415:       ppc32_update_cr0(b);
                   2416:    }
                   2417: 
                   2418:    return(0);
                   2419: }
                   2420: 
                   2421: /* SUBFIC - Subtract From Immediate Carrying */
                   2422: DECLARE_INSN(SUBFIC)
                   2423: {
                   2424:    int rd = bits(insn,21,25);
                   2425:    int ra = bits(insn,16,20);
                   2426:    m_uint16_t imm = bits(insn,0,15);
                   2427:    m_uint32_t tmp = sign_extend_32(imm,16);
                   2428: 
                   2429:    /* ~$ra + 1 */
                   2430:    ppc32_load_gpr(b,X86_ESI,ra);
                   2431:    x86_not_reg(b->jit_ptr,X86_ESI);
                   2432:    x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESI,1);
                   2433:    x86_set_reg(b->jit_ptr,X86_CC_C,X86_EAX,FALSE);
                   2434: 
                   2435:    /* add sign-extended $immediate */
                   2436:    x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESI,tmp);
                   2437:    x86_set_reg(b->jit_ptr,X86_CC_C,X86_ECX,FALSE);
                   2438: 
                   2439:    ppc32_store_gpr(b,rd,X86_ESI);
                   2440: 
                   2441:    /* store the carry flag */
                   2442:    x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ECX);
                   2443:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x1);
                   2444: 
                   2445:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_EAX,4);
                   2446:    return(0);
                   2447: }
                   2448: 
                   2449: /* SYNC - Synchronize */
                   2450: DECLARE_INSN(SYNC)
                   2451: {
                   2452:    return(0);
                   2453: }
                   2454: 
                   2455: /* XOR */
                   2456: DECLARE_INSN(XOR)
                   2457: {
                   2458:    int rs = bits(insn,21,25);
                   2459:    int ra = bits(insn,16,20);
                   2460:    int rb = bits(insn,11,15);
                   2461: 
                   2462:    ppc32_load_gpr(b,X86_EBX,rs);
                   2463:    ppc32_alu_gpr(b,X86_XOR,X86_EBX,rb);
                   2464:    ppc32_store_gpr(b,ra,X86_EBX);
                   2465: 
                   2466:    if (insn & 1)
                   2467:       ppc32_update_cr0(b);
                   2468: 
                   2469:    return(0);
                   2470: }
                   2471: 
                   2472: /* XORI - XOR Immediate */
                   2473: DECLARE_INSN(XORI)
                   2474: {
                   2475:    int rs = bits(insn,21,25);
                   2476:    int ra = bits(insn,16,20);
                   2477:    m_uint32_t imm = bits(insn,0,15);
                   2478: 
                   2479:    ppc32_load_imm(b,X86_EBX,imm);
                   2480:    ppc32_alu_gpr(b,X86_XOR,X86_EBX,rs);
                   2481:    ppc32_store_gpr(b,ra,X86_EBX);
                   2482:    return(0);
                   2483: }
                   2484: 
                   2485: /* XORIS - XOR Immediate Shifted */
                   2486: DECLARE_INSN(XORIS)
                   2487: {
                   2488:    int rs = bits(insn,21,25);
                   2489:    int ra = bits(insn,16,20);
                   2490:    m_uint32_t imm = bits(insn,0,15);
                   2491: 
                   2492:    ppc32_load_imm(b,X86_EBX,imm << 16);
                   2493:    ppc32_alu_gpr(b,X86_XOR,X86_EBX,rs);
                   2494:    ppc32_store_gpr(b,ra,X86_EBX);
                   2495:    return(0);
                   2496: }
                   2497: 
                   2498: /* PPC instruction array */
                   2499: struct ppc32_insn_tag ppc32_insn_tags[] = {
                   2500:    { ppc32_emit_BLR        , 0xfffffffe , 0x4e800020 },
                   2501:    { ppc32_emit_BCTR       , 0xfffffffe , 0x4e800420 },
                   2502:    { ppc32_emit_MFLR       , 0xfc1fffff , 0x7c0802a6 },
                   2503:    { ppc32_emit_MTLR       , 0xfc1fffff , 0x7c0803a6 },
                   2504:    { ppc32_emit_MFCTR      , 0xfc1fffff , 0x7c0902a6 },
                   2505:    { ppc32_emit_MTCTR      , 0xfc1fffff , 0x7c0903a6 },
                   2506:    { ppc32_emit_MFTBL      , 0xfc1ff7ff , 0x7c0c42e6 },
                   2507:    { ppc32_emit_MFTBU      , 0xfc1ff7ff , 0x7c0d42e6 },
                   2508:    { ppc32_emit_ADD        , 0xfc0007fe , 0x7c000214 },
                   2509:    { ppc32_emit_ADDC       , 0xfc0007fe , 0x7c000014 },
                   2510:    { ppc32_emit_ADDE       , 0xfc0007fe , 0x7c000114 },
                   2511:    { ppc32_emit_ADDI       , 0xfc000000 , 0x38000000 },
                   2512:    { ppc32_emit_ADDIC      , 0xfc000000 , 0x30000000 },
                   2513:    { ppc32_emit_ADDIC_dot  , 0xfc000000 , 0x34000000 },
                   2514:    { ppc32_emit_ADDIS      , 0xfc000000 , 0x3c000000 },
                   2515:    { ppc32_emit_AND        , 0xfc0007fe , 0x7c000038 },
                   2516:    { ppc32_emit_ANDC       , 0xfc0007fe , 0x7c000078 },
                   2517:    { ppc32_emit_ANDI       , 0xfc000000 , 0x70000000 },
                   2518:    { ppc32_emit_ANDIS      , 0xfc000000 , 0x74000000 },
                   2519:    { ppc32_emit_B          , 0xfc000003 , 0x48000000 },
                   2520:    { ppc32_emit_BA         , 0xfc000003 , 0x48000002 },
                   2521:    { ppc32_emit_BL         , 0xfc000003 , 0x48000001 },
                   2522:    { ppc32_emit_BLA        , 0xfc000003 , 0x48000003 },
                   2523:    { ppc32_emit_BCC        , 0xfe800000 , 0x40800000 },
                   2524:    { ppc32_emit_BC         , 0xfc000000 , 0x40000000 },
                   2525:    { ppc32_emit_BCLR       , 0xfc00fffe , 0x4c000020 },
                   2526:    { ppc32_emit_CMP        , 0xfc6007ff , 0x7c000000 },
                   2527:    { ppc32_emit_CMPI       , 0xfc600000 , 0x2c000000 },
                   2528:    { ppc32_emit_CMPL       , 0xfc6007ff , 0x7c000040 },
                   2529:    { ppc32_emit_CMPLI      , 0xfc600000 , 0x28000000 },
                   2530:    { ppc32_emit_CRAND      , 0xfc0007ff , 0x4c000202 },
                   2531:    { ppc32_emit_CRANDC     , 0xfc0007ff , 0x4c000102 },
                   2532:    { ppc32_emit_CREQV      , 0xfc0007ff , 0x4c000242 },
                   2533:    { ppc32_emit_CRNAND     , 0xfc0007ff , 0x4c0001c2 },
                   2534:    { ppc32_emit_CRNOR      , 0xfc0007ff , 0x4c000042 },
                   2535:    { ppc32_emit_CROR       , 0xfc0007ff , 0x4c000382 },
                   2536:    { ppc32_emit_CRORC      , 0xfc0007ff , 0x4c000342 },
                   2537:    { ppc32_emit_CRXOR      , 0xfc0007ff , 0x4c000182 },
                   2538:    { ppc32_emit_DIVWU      , 0xfc0007fe , 0x7c000396 },
                   2539:    { ppc32_emit_EQV        , 0xfc0007fe , 0x7c000238 },
                   2540:    { ppc32_emit_EXTSB      , 0xfc00fffe , 0x7c000774 },
                   2541:    { ppc32_emit_EXTSH      , 0xfc00fffe , 0x7c000734 },
                   2542:    { ppc32_emit_LBZ        , 0xfc000000 , 0x88000000 },
                   2543:    { ppc32_emit_LBZU       , 0xfc000000 , 0x8c000000 },
                   2544:    { ppc32_emit_LBZUX      , 0xfc0007ff , 0x7c0000ee },
                   2545:    { ppc32_emit_LBZX       , 0xfc0007ff , 0x7c0000ae },
                   2546:    { ppc32_emit_LHA        , 0xfc000000 , 0xa8000000 },
                   2547:    { ppc32_emit_LHAU       , 0xfc000000 , 0xac000000 },
                   2548:    { ppc32_emit_LHAUX      , 0xfc0007ff , 0x7c0002ee },
                   2549:    { ppc32_emit_LHAX       , 0xfc0007ff , 0x7c0002ae },
                   2550:    { ppc32_emit_LHZ        , 0xfc000000 , 0xa0000000 },
                   2551:    { ppc32_emit_LHZU       , 0xfc000000 , 0xa4000000 },
                   2552:    { ppc32_emit_LHZUX      , 0xfc0007ff , 0x7c00026e },
                   2553:    { ppc32_emit_LHZX       , 0xfc0007ff , 0x7c00022e },
                   2554:    { ppc32_emit_LWZ        , 0xfc000000 , 0x80000000 },
                   2555:    { ppc32_emit_LWZU       , 0xfc000000 , 0x84000000 },
                   2556:    { ppc32_emit_LWZUX      , 0xfc0007ff , 0x7c00006e },
                   2557:    { ppc32_emit_LWZX       , 0xfc0007ff , 0x7c00002e },
                   2558:    { ppc32_emit_MCRF       , 0xfc63ffff , 0x4c000000 },
                   2559:    { ppc32_emit_MFCR       , 0xfc1fffff , 0x7c000026 },
                   2560:    { ppc32_emit_MFMSR      , 0xfc1fffff , 0x7c0000a6 },
                   2561:    { ppc32_emit_MFSR       , 0xfc10ffff , 0x7c0004a6 },
                   2562:    { ppc32_emit_MTCRF      , 0xfc100fff , 0x7c000120 },
                   2563:    { ppc32_emit_MULHW      , 0xfc0007fe , 0x7c000096 },
                   2564:    { ppc32_emit_MULHWU     , 0xfc0007fe , 0x7c000016 },
                   2565:    { ppc32_emit_MULLI      , 0xfc000000 , 0x1c000000 },
                   2566:    { ppc32_emit_MULLW      , 0xfc0007fe , 0x7c0001d6 },
                   2567:    { ppc32_emit_NAND       , 0xfc0007fe , 0x7c0003b8 },
                   2568:    { ppc32_emit_NEG        , 0xfc00fffe , 0x7c0000d0 },
                   2569:    { ppc32_emit_NOR        , 0xfc0007fe , 0x7c0000f8 },
                   2570:    { ppc32_emit_OR         , 0xfc0007fe , 0x7c000378 },
                   2571:    { ppc32_emit_ORC        , 0xfc0007fe , 0x7c000338 },
                   2572:    { ppc32_emit_ORI        , 0xfc000000 , 0x60000000 },
                   2573:    { ppc32_emit_ORIS       , 0xfc000000 , 0x64000000 },
                   2574:    { ppc32_emit_RLWIMI     , 0xfc000000 , 0x50000000 },
                   2575:    { ppc32_emit_RLWINM     , 0xfc000000 , 0x54000000 },
                   2576:    { ppc32_emit_RLWNM      , 0xfc000000 , 0x5c000000 },
                   2577:    { ppc32_emit_SLW        , 0xfc0007fe , 0x7c000030 },
                   2578:    { ppc32_emit_SRAWI      , 0xfc0007fe , 0x7c000670 },
                   2579:    { ppc32_emit_SRW        , 0xfc0007fe , 0x7c000430 },
                   2580:    { ppc32_emit_STB        , 0xfc000000 , 0x98000000 },
                   2581:    { ppc32_emit_STBU       , 0xfc000000 , 0x9c000000 },
                   2582:    { ppc32_emit_STBUX      , 0xfc0007ff , 0x7c0001ee },
                   2583:    { ppc32_emit_STBX       , 0xfc0007ff , 0x7c0001ae },
                   2584:    { ppc32_emit_STH        , 0xfc000000 , 0xb0000000 },
                   2585:    { ppc32_emit_STHU       , 0xfc000000 , 0xb4000000 },
                   2586:    { ppc32_emit_STHUX      , 0xfc0007ff , 0x7c00036e },
                   2587:    { ppc32_emit_STHX       , 0xfc0007ff , 0x7c00032e },
                   2588:    { ppc32_emit_STW        , 0xfc000000 , 0x90000000 },
                   2589:    { ppc32_emit_STWU       , 0xfc000000 , 0x94000000 },
                   2590:    { ppc32_emit_STWUX      , 0xfc0007ff , 0x7c00016e },
                   2591:    { ppc32_emit_STWX       , 0xfc0007ff , 0x7c00012e },
                   2592:    { ppc32_emit_SUBF       , 0xfc0007fe , 0x7c000050 },
                   2593:    { ppc32_emit_SUBFC      , 0xfc0007fe , 0x7c000010 },
                   2594:    { ppc32_emit_SUBFE      , 0xfc0007fe , 0x7c000110 },
                   2595:    { ppc32_emit_SUBFIC     , 0xfc000000 , 0x20000000 },
                   2596:    { ppc32_emit_SYNC       , 0xffffffff , 0x7c0004ac },
                   2597:    { ppc32_emit_XOR        , 0xfc0007fe , 0x7c000278 },
                   2598:    { ppc32_emit_XORI       , 0xfc000000 , 0x68000000 },
                   2599:    { ppc32_emit_XORIS      , 0xfc000000 , 0x6c000000 },
                   2600:    { ppc32_emit_unknown    , 0x00000000 , 0x00000000 },
1.1.1.2 ! root     2601:    { NULL                  , 0x00000000 , 0x00000000 },
1.1       root     2602: };

unix.superglobalmegacorp.com

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