Annotation of cf/ppc32_x86_trans.c, revision 1.1.1.6

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"
1.1.1.3   root       16: #include "jit_op.h"
1.1       root       17: #include "ppc32_jit.h"
                     18: #include "ppc32_x86_trans.h"
                     19: #include "memory.h"
                     20: 
1.1.1.4   root       21: /* %esp adjustment (for MacOS X) */
                     22: #define STACK_ADJUST  12
                     23: 
1.1.1.2   root       24: /* ======================================================================= */
                     25: 
1.1       root       26: /* Macros for CPU structure access */
                     27: #define REG_OFFSET(reg)   (OFFSET(cpu_ppc_t,gpr[(reg)]))
                     28: #define MEMOP_OFFSET(op)  (OFFSET(cpu_ppc_t,mem_op_fn[(op)]))
                     29: 
                     30: #define DECLARE_INSN(name) \
                     31:    static int ppc32_emit_##name(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, \
                     32:                                 ppc_insn_t insn)
                     33: 
1.1.1.2   root       34: /* EFLAGS to Condition Register (CR) field - signed */
1.1.1.5   root       35: static m_uint32_t eflags_to_cr_signed[64] = {
                     36:    0x04, 0x02, 0x08, 0x02, 0x04, 0x02, 0x08, 0x02, 
                     37:    0x04, 0x02, 0x08, 0x02, 0x04, 0x02, 0x08, 0x02, 
                     38:    0x04, 0x02, 0x08, 0x02, 0x04, 0x02, 0x08, 0x02, 
                     39:    0x04, 0x02, 0x08, 0x02, 0x04, 0x02, 0x08, 0x02, 
                     40:    0x08, 0x02, 0x04, 0x02, 0x08, 0x02, 0x04, 0x02, 
                     41:    0x08, 0x02, 0x04, 0x02, 0x08, 0x02, 0x04, 0x02, 
                     42:    0x08, 0x02, 0x04, 0x02, 0x08, 0x02, 0x04, 0x02, 
                     43:    0x08, 0x02, 0x04, 0x02, 0x08, 0x02, 0x04, 0x02, 
1.1.1.2   root       44: };
                     45: 
                     46: /* EFLAGS to Condition Register (CR) field - unsigned */
                     47: static m_uint32_t eflags_to_cr_unsigned[256] = {
1.1.1.5   root       48:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 
                     49:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 
                     50:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 
                     51:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 
                     52:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 
                     53:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 
                     54:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 
                     55:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 
                     56:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
                     57:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
                     58:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
                     59:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
                     60:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
                     61:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
                     62:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
                     63:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
                     64:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 
                     65:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 
                     66:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 
                     67:    0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 
                     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:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
                     73:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
                     74:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
                     75:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
                     76:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
                     77:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
                     78:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
                     79:    0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 
1.1.1.2   root       80: };
                     81: 
1.1.1.3   root       82: /* Emit unhandled instruction code */
                     83: static int ppc32_emit_unknown(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
                     84:                               ppc_insn_t opcode);
1.1       root       85: 
                     86: /* Load a 32 bit immediate value */
1.1.1.3   root       87: static forced_inline void ppc32_load_imm(u_char **ptr,u_int reg,m_uint32_t val)
1.1       root       88: {
                     89:    if (val)
1.1.1.3   root       90:       x86_mov_reg_imm(*ptr,reg,val);
1.1       root       91:    else
1.1.1.3   root       92:       x86_alu_reg_reg(*ptr,X86_XOR,reg,reg);
1.1       root       93: }
                     94: 
                     95: /* Set the Instruction Address (IA) register */
1.1.1.3   root       96: void ppc32_set_ia(u_char **ptr,m_uint32_t new_ia)
1.1       root       97: {
1.1.1.3   root       98:    x86_mov_membase_imm(*ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),new_ia,4);
1.1       root       99: }
                    100: 
                    101: /* Set the Link Register (LR) */
1.1.1.3   root      102: static void ppc32_set_lr(jit_op_t *iop,m_uint32_t new_lr)
1.1       root      103: {  
1.1.1.3   root      104:    x86_mov_membase_imm(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,lr),new_lr,4);
1.1       root      105: }
                    106: 
1.1.1.2   root      107: /* 
                    108:  * Try to branch directly to the specified JIT block without returning to 
                    109:  * main loop.
                    110:  */
1.1.1.3   root      111: static void ppc32_try_direct_far_jump(cpu_ppc_t *cpu,jit_op_t *iop,
1.1.1.2   root      112:                                       m_uint32_t new_ia)
                    113: {
                    114:    m_uint32_t new_page,ia_hash,ia_offset;
1.1.1.6 ! root      115:    u_char *test1,*test2,*test3,*test4;
1.1.1.2   root      116: 
1.1.1.3   root      117:    /* Indicate that we throw %esi, %edx */
                    118:    ppc32_op_emit_alter_host_reg(cpu,X86_ESI);
                    119:    ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
                    120: 
1.1.1.2   root      121:    new_page = new_ia & PPC32_MIN_PAGE_MASK;
                    122:    ia_offset = (new_ia & PPC32_MIN_PAGE_IMASK) >> 2;
1.1.1.6 ! root      123:    ia_hash = ppc32_jit_get_virt_hash(new_ia);
1.1.1.2   root      124: 
                    125:    /* Get JIT block info in %edx */
1.1.1.3   root      126:    x86_mov_reg_membase(iop->ob_ptr,X86_EBX,
1.1.1.6 ! root      127:                        X86_EDI,OFFSET(cpu_ppc_t,tcb_virt_hash),4);
1.1.1.3   root      128:    x86_mov_reg_membase(iop->ob_ptr,X86_EDX,X86_EBX,ia_hash*sizeof(void *),4);
1.1.1.2   root      129: 
                    130:    /* no JIT block found ? */
1.1.1.3   root      131:    x86_test_reg_reg(iop->ob_ptr,X86_EDX,X86_EDX);
                    132:    test1 = iop->ob_ptr;
                    133:    x86_branch8(iop->ob_ptr, X86_CC_Z, 0, 1);
1.1.1.2   root      134: 
                    135:    /* Check block IA */
1.1.1.3   root      136:    x86_mov_reg_imm(iop->ob_ptr,X86_ESI,new_page);
                    137:    x86_alu_reg_membase(iop->ob_ptr,X86_CMP,X86_ESI,X86_EDX,
1.1.1.2   root      138:                        OFFSET(ppc32_jit_tcb_t,start_ia));
1.1.1.3   root      139:    test2 = iop->ob_ptr;
                    140:    x86_branch8(iop->ob_ptr, X86_CC_NE, 0, 1);
1.1.1.2   root      141: 
                    142:    /* Jump to the code */
1.1.1.3   root      143:    x86_mov_reg_membase(iop->ob_ptr,X86_ESI,
1.1.1.2   root      144:                        X86_EDX,OFFSET(ppc32_jit_tcb_t,jit_insn_ptr),4);
1.1.1.6 ! root      145: 
        !           146:    x86_test_reg_reg(iop->ob_ptr,X86_ESI,X86_ESI);
        !           147:    test3 = iop->ob_ptr;
        !           148:    x86_branch8(iop->ob_ptr, X86_CC_Z, 0, 1);
        !           149: 
1.1.1.3   root      150:    x86_mov_reg_membase(iop->ob_ptr,X86_EBX,
1.1.1.2   root      151:                        X86_ESI,ia_offset * sizeof(void *),4);
                    152:    
1.1.1.3   root      153:    x86_test_reg_reg(iop->ob_ptr,X86_EBX,X86_EBX);
1.1.1.6 ! root      154:    test4 = iop->ob_ptr;
1.1.1.3   root      155:    x86_branch8(iop->ob_ptr, X86_CC_Z, 0, 1);
                    156:    x86_jump_reg(iop->ob_ptr,X86_EBX);
1.1.1.2   root      157: 
                    158:    /* Returns to caller... */
1.1.1.3   root      159:    x86_patch(test1,iop->ob_ptr);
                    160:    x86_patch(test2,iop->ob_ptr);
                    161:    x86_patch(test3,iop->ob_ptr);
1.1.1.6 ! root      162:    x86_patch(test4,iop->ob_ptr);
1.1.1.2   root      163: 
1.1.1.3   root      164:    ppc32_set_ia(&iop->ob_ptr,new_ia);
                    165:    ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
1.1.1.2   root      166: }
                    167: 
1.1       root      168: /* Set Jump */
1.1.1.3   root      169: static void ppc32_set_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,jit_op_t *iop,
1.1       root      170:                            m_uint32_t new_ia,int local_jump)
                    171: {      
                    172:    int return_to_caller = FALSE;
                    173:    u_char *jump_ptr;
                    174: 
                    175: #if 0
                    176:    if (cpu->sym_trace && !local_jump)
                    177:       return_to_caller = TRUE;
                    178: #endif
1.1.1.4   root      179:       
1.1       root      180:    if (!return_to_caller && ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr)) {
1.1.1.3   root      181:       ppc32_jit_tcb_record_patch(b,iop,iop->ob_ptr,new_ia);
                    182:       x86_jump32(iop->ob_ptr,0);
1.1       root      183:    } else {
1.1.1.2   root      184:       if (cpu->exec_blk_direct_jump) {
                    185:          /* Block lookup optimization */
1.1.1.3   root      186:          ppc32_try_direct_far_jump(cpu,iop,new_ia);
1.1.1.2   root      187:       } else {
1.1.1.3   root      188:          ppc32_set_ia(&iop->ob_ptr,new_ia);
                    189:          ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
1.1.1.2   root      190:       }
1.1       root      191:    }
                    192: }
                    193: 
1.1.1.3   root      194: /* Jump to the next page */
                    195: void ppc32_set_page_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b)
                    196: {
                    197:    jit_op_t *iop,*op_list = NULL;
                    198: 
                    199:    cpu->gen->jit_op_current = &op_list;
                    200: 
                    201:    iop = ppc32_op_emit_insn_output(cpu,4,"set_page_jump");
                    202:    ppc32_set_jump(cpu,b,iop,b->start_ia + PPC32_MIN_PAGE_SIZE,FALSE);
                    203:    ppc32_op_insn_output(b,iop);
                    204: 
                    205:    jit_op_free_list(cpu->gen,op_list);
                    206:    cpu->gen->jit_op_current = NULL;
                    207: }
                    208: 
1.1       root      209: /* Load a GPR into the specified host register */
1.1.1.3   root      210: static forced_inline void ppc32_load_gpr(u_char **ptr,u_int host_reg,
1.1       root      211:                                          u_int ppc_reg)
                    212: {
1.1.1.3   root      213:    x86_mov_reg_membase(*ptr,host_reg,X86_EDI,REG_OFFSET(ppc_reg),4);
1.1       root      214: }
                    215: 
                    216: /* Store contents for a host register into a GPR register */
1.1.1.3   root      217: static forced_inline void ppc32_store_gpr(u_char **ptr,u_int ppc_reg,
1.1       root      218:                                           u_int host_reg)
                    219: {
1.1.1.3   root      220:    x86_mov_membase_reg(*ptr,X86_EDI,REG_OFFSET(ppc_reg),host_reg,4);
1.1       root      221: }
                    222: 
                    223: /* Apply an ALU operation on a GPR register and a host register */
1.1.1.3   root      224: static forced_inline void ppc32_alu_gpr(u_char **ptr,u_int op,
1.1       root      225:                                         u_int host_reg,u_int ppc_reg)
                    226: {
1.1.1.3   root      227:    x86_alu_reg_membase(*ptr,op,host_reg,X86_EDI,REG_OFFSET(ppc_reg));
1.1       root      228: }
                    229: 
                    230: /* 
                    231:  * Update CR from %eflags
1.1.1.2   root      232:  * %eax, %edx, %esi are modified.
1.1       root      233:  */
                    234: static void ppc32_update_cr(ppc32_jit_tcb_t *b,int field,int is_signed)
                    235: {
1.1.1.2   root      236:    /* Get status bits from EFLAGS */
1.1.1.5   root      237:    if (!is_signed) {
                    238:       x86_mov_reg_imm(b->jit_ptr,X86_EAX,0);
                    239:       x86_lahf(b->jit_ptr);
                    240:       x86_xchg_ah_al(b->jit_ptr);
1.1       root      241: 
1.1.1.2   root      242:       x86_mov_reg_imm(b->jit_ptr,X86_EDX,eflags_to_cr_unsigned);
1.1.1.5   root      243:    } else {
                    244:       x86_pushfd(b->jit_ptr);
                    245:       x86_pop_reg(b->jit_ptr,X86_EAX);
                    246:       x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_EAX,6);
                    247:       x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x3F);
                    248: 
                    249:       x86_mov_reg_imm(b->jit_ptr,X86_EDX,eflags_to_cr_signed);
                    250:    }
1.1       root      251: 
1.1.1.2   root      252:    x86_mov_reg_memindex(b->jit_ptr,X86_EAX,X86_EDX,0,X86_EAX,2,4);
1.1       root      253: 
                    254:    /* Check XER Summary of Overflow and report it */
1.1.1.5   root      255:    //x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,xer),4);
1.1.1.2   root      256:    //x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,PPC32_XER_SO);
                    257:    //x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_ESI,PPC32_XER_SO_BIT);
                    258:    //x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ESI);
                    259: 
                    260:    /* Store modified CR field */
                    261:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,PPC32_CR_FIELD_OFFSET(field),
                    262:                        X86_EAX,4);
1.1       root      263: }
                    264: 
                    265: /* 
                    266:  * Update CR0 from %eflags
1.1.1.3   root      267:  * %eax, %edx, %esi are modified.
1.1       root      268:  */
                    269: static void ppc32_update_cr0(ppc32_jit_tcb_t *b)
                    270: {
                    271:    ppc32_update_cr(b,0,TRUE);
                    272: }
                    273: 
1.1.1.3   root      274: /* Indicate registers modified by ppc32_update_cr() functions */
                    275: void ppc32_update_cr_set_altered_hreg(cpu_ppc_t *cpu)
                    276: {
                    277:    /* Throw %eax and %edx, which are modifed by ppc32_update_cr() */
                    278:    ppc32_op_emit_alter_host_reg(cpu,X86_EAX);
                    279:    ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
                    280: }
                    281: 
1.1       root      282: /* Basic C call */
1.1.1.3   root      283: static forced_inline 
                    284: void ppc32_emit_basic_c_call(u_char **ptr,void *f)
1.1       root      285: {
1.1.1.3   root      286:    x86_mov_reg_imm(*ptr,X86_EBX,f);
                    287:    x86_call_reg(*ptr,X86_EBX);
1.1       root      288: }
                    289: 
                    290: /* Emit a simple call to a C function without any parameter */
1.1.1.3   root      291: static void ppc32_emit_c_call(ppc32_jit_tcb_t *b,jit_op_t *iop,void *f)
1.1       root      292: {   
1.1.1.3   root      293:    ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));
                    294:    ppc32_emit_basic_c_call(&iop->ob_ptr,f);
                    295: }
                    296: 
                    297: /* ======================================================================== */
                    298: 
                    299: /* Initialize register mapping */
                    300: void ppc32_jit_init_hreg_mapping(cpu_ppc_t *cpu)
                    301: {
                    302:    int avail_hregs[] = { X86_ESI, X86_EAX, X86_ECX, X86_EDX, -1 };
                    303:    struct hreg_map *map;
                    304:    int i,hreg;
                    305: 
                    306:    cpu->hreg_map_list = cpu->hreg_lru = NULL;
                    307: 
                    308:    /* Add the available registers to the map list */
                    309:    for(i=0;avail_hregs[i]!=-1;i++) {
                    310:       hreg = avail_hregs[i];
                    311:       map = &cpu->hreg_map[hreg];
                    312: 
                    313:       /* Initialize mapping. At the beginning, no PPC reg is mapped */
                    314:       map->flags = 0;
                    315:       map->hreg  = hreg;
                    316:       map->vreg  = -1;
                    317:       ppc32_jit_insert_hreg_mru(cpu,map);
                    318:    }
                    319: 
                    320:    /* Clear PPC registers mapping */
                    321:    for(i=0;i<PPC32_GPR_NR;i++)
                    322:       cpu->ppc_reg_map[i] = -1;
                    323: }
                    324: 
                    325: /* Allocate a specific temp register */
                    326: static int ppc32_jit_get_tmp_hreg(cpu_ppc_t *cpu)
                    327: {
                    328:    return(X86_EBX);
                    329: }
                    330: 
                    331: /* ======================================================================== */
                    332: /* JIT operations (specific to target CPU).                                 */
                    333: /* ======================================================================== */
                    334: 
                    335: /* INSN_OUTPUT */
                    336: void ppc32_op_insn_output(ppc32_jit_tcb_t *b,jit_op_t *op)
                    337: {
                    338:    op->ob_final = b->jit_ptr;
                    339:    memcpy(b->jit_ptr,op->ob_data,op->ob_ptr - op->ob_data);
                    340:    b->jit_ptr += op->ob_ptr - op->ob_data;
                    341: 
                    342:    if ((op->ob_ptr - op->ob_data) >= jit_op_blk_sizes[op->ob_size_index]) {
1.1.1.4   root      343:       printf("ppc32_op_insn_output: FAILURE: count=%d, size=%d\n",
1.1.1.3   root      344:              op->ob_ptr - op->ob_data, jit_op_blk_sizes[op->ob_size_index]);
                    345:    }
                    346: }
                    347: 
                    348: /* LOAD_GPR: p[0] = %host_reg, p[1] = %ppc_reg */
                    349: void ppc32_op_load_gpr(ppc32_jit_tcb_t *b,jit_op_t *op)
                    350: {
                    351:    if (op->param[0] != JIT_OP_INV_REG)
                    352:       ppc32_load_gpr(&b->jit_ptr,op->param[0],op->param[1]);
                    353: }
                    354: 
                    355: /* STORE_GPR: p[0] = %host_reg, p[1] = %ppc_reg */
                    356: void ppc32_op_store_gpr(ppc32_jit_tcb_t *b,jit_op_t *op)
                    357: {
                    358:    if (op->param[0] != JIT_OP_INV_REG)
                    359:       ppc32_store_gpr(&b->jit_ptr,op->param[1],op->param[0]);
1.1       root      360: }
                    361: 
1.1.1.3   root      362: /* UPDATE_FLAGS: p[0] = cr_field, p[1] = is_signed */
                    363: void ppc32_op_update_flags(ppc32_jit_tcb_t *b,jit_op_t *op)
                    364: {
                    365:    if (op->param[0] != JIT_OP_INV_REG)
                    366:       ppc32_update_cr(b,op->param[0],op->param[1]);
                    367: }
                    368: 
                    369: /* MOVE_HOST_REG: p[0] = %host_dst_reg, p[1] = %host_src_reg */
                    370: void ppc32_op_move_host_reg(ppc32_jit_tcb_t *b,jit_op_t *op)
                    371: {
                    372:    if ((op->param[0] != JIT_OP_INV_REG) && (op->param[1] != JIT_OP_INV_REG))
                    373:       x86_mov_reg_reg(b->jit_ptr,op->param[0],op->param[1],4);
                    374: }
                    375: 
                    376: /* SET_HOST_REG_IMM32: p[0] = %host_reg, p[1] = imm32 */
                    377: void ppc32_op_set_host_reg_imm32(ppc32_jit_tcb_t *b,jit_op_t *op)
                    378: {
                    379:    if (op->param[0] != JIT_OP_INV_REG)
                    380:       ppc32_load_imm(&b->jit_ptr,op->param[0],op->param[1]);
                    381: }
                    382: 
                    383: /* ======================================================================== */
                    384: 
1.1       root      385: /* Memory operation */
1.1.1.3   root      386: static void ppc32_emit_memop(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
                    387:                              int op,int base,int offset,int target,int update)
1.1       root      388: {
                    389:    m_uint32_t val = sign_extend(offset,16);
1.1.1.3   root      390:    jit_op_t *iop;
                    391: 
                    392:    /* 
                    393:     * Since an exception can be triggered, clear JIT state. This allows
                    394:     * to use branch target tag (we can directly branch on this instruction).
                    395:     */
                    396:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_TARGET);
                    397:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
                    398: 
                    399:    iop = ppc32_op_emit_insn_output(cpu,5,"memop");
1.1       root      400: 
                    401:    /* Save PC for exception handling */
1.1.1.3   root      402:    ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));
1.1       root      403: 
                    404:    /* EDX = sign-extended offset */
1.1.1.3   root      405:    ppc32_load_imm(&iop->ob_ptr,X86_EDX,val);
1.1       root      406: 
                    407:    /* EDX = GPR[base] + sign-extended offset */
                    408:    if (update || (base != 0))
1.1.1.3   root      409:       ppc32_alu_gpr(&iop->ob_ptr,X86_ADD,X86_EDX,base);
1.1       root      410: 
                    411:    if (update)
1.1.1.3   root      412:       x86_mov_reg_reg(iop->ob_ptr,X86_ESI,X86_EDX,4);
1.1       root      413: 
                    414:    /* ECX = target register */
1.1.1.3   root      415:    x86_mov_reg_imm(iop->ob_ptr,X86_ECX,target);
1.1       root      416:    
                    417:    /* EAX = CPU instance pointer */
1.1.1.3   root      418:    x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EDI,4);
1.1       root      419: 
                    420:    /* Call memory function */
1.1.1.4   root      421:    x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST);
1.1.1.3   root      422:    x86_call_membase(iop->ob_ptr,X86_EDI,MEMOP_OFFSET(op));
1.1.1.4   root      423:    x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);
                    424:    
1.1       root      425:    if (update)
1.1.1.3   root      426:       ppc32_store_gpr(&iop->ob_ptr,base,X86_ESI);
1.1       root      427: }
                    428: 
                    429: /* Memory operation (indexed) */
1.1.1.3   root      430: static void ppc32_emit_memop_idx(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
                    431:                                  int op,int ra,int rb,int target,int update)
1.1       root      432: {
1.1.1.3   root      433:    jit_op_t *iop;
                    434: 
                    435:    /* 
                    436:     * Since an exception can be triggered, clear JIT state. This allows
                    437:     * to use branch target tag (we can directly branch on this instruction).
                    438:     */
                    439:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_TARGET);
                    440:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
                    441: 
                    442:    iop = ppc32_op_emit_insn_output(cpu,5,"memop_idx");
1.1       root      443: 
                    444:    /* Save PC for exception handling */
1.1.1.3   root      445:    ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));
1.1       root      446: 
                    447:    /* EDX = $rb */
1.1.1.3   root      448:    ppc32_load_gpr(&iop->ob_ptr,X86_EDX,rb);
1.1       root      449: 
                    450:    /* EDX = $rb + $ra */
                    451:    if (update || (ra != 0)) 
1.1.1.3   root      452:       ppc32_alu_gpr(&iop->ob_ptr,X86_ADD,X86_EDX,ra);
1.1       root      453: 
                    454:    if (update)
1.1.1.3   root      455:       x86_mov_reg_reg(iop->ob_ptr,X86_ESI,X86_EDX,4);
1.1       root      456: 
                    457:    /* ECX = target register */
1.1.1.3   root      458:    x86_mov_reg_imm(iop->ob_ptr,X86_ECX,target);
1.1       root      459:    
                    460:    /* EAX = CPU instance pointer */
1.1.1.3   root      461:    x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EDI,4);
1.1       root      462: 
                    463:    /* Call memory function */
1.1.1.4   root      464:    x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST);
1.1.1.3   root      465:    x86_call_membase(iop->ob_ptr,X86_EDI,MEMOP_OFFSET(op));
1.1.1.4   root      466:    x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);
                    467:    
1.1       root      468:    if (update)
1.1.1.3   root      469:       ppc32_store_gpr(&iop->ob_ptr,ra,X86_ESI);
1.1       root      470: }
                    471: 
1.1.1.3   root      472: typedef void (*memop_fast_access)(jit_op_t *iop,int target);
1.1       root      473: 
                    474: /* Fast LBZ */
1.1.1.3   root      475: static void ppc32_memop_fast_lbz(jit_op_t *iop,int target)
1.1       root      476: {
1.1.1.3   root      477:    x86_clear_reg(iop->ob_ptr,X86_ECX);
                    478:    x86_mov_reg_memindex(iop->ob_ptr,X86_ECX,X86_EAX,0,X86_EBX,0,1);
                    479:    ppc32_store_gpr(&iop->ob_ptr,target,X86_ECX);
1.1       root      480: }
                    481: 
                    482: /* Fast STB */
1.1.1.3   root      483: static void ppc32_memop_fast_stb(jit_op_t *iop,int target)
1.1       root      484: {
1.1.1.3   root      485:    ppc32_load_gpr(&iop->ob_ptr,X86_EDX,target);
                    486:    x86_mov_memindex_reg(iop->ob_ptr,X86_EAX,0,X86_EBX,0,X86_EDX,1);
1.1       root      487: }
                    488: 
                    489: /* Fast LWZ */
1.1.1.3   root      490: static void ppc32_memop_fast_lwz(jit_op_t *iop,int target)
1.1       root      491: {
1.1.1.3   root      492:    x86_mov_reg_memindex(iop->ob_ptr,X86_EAX,X86_EAX,0,X86_EBX,0,4);
                    493:    x86_bswap(iop->ob_ptr,X86_EAX);
                    494:    ppc32_store_gpr(&iop->ob_ptr,target,X86_EAX);
1.1       root      495: }
                    496: 
                    497: /* Fast STW */
1.1.1.3   root      498: static void ppc32_memop_fast_stw(jit_op_t *iop,int target)
1.1       root      499: {
1.1.1.3   root      500:    ppc32_load_gpr(&iop->ob_ptr,X86_EDX,target);
                    501:    x86_bswap(iop->ob_ptr,X86_EDX);
                    502:    x86_mov_memindex_reg(iop->ob_ptr,X86_EAX,0,X86_EBX,0,X86_EDX,4);
1.1       root      503: }
                    504: 
                    505: /* Fast memory operation */
1.1.1.3   root      506: static void ppc32_emit_memop_fast(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
                    507:                                   int write_op,int opcode,
1.1       root      508:                                   int base,int offset,int target,
                    509:                                   memop_fast_access op_handler)
                    510: {
                    511:    m_uint32_t val = sign_extend(offset,16);
1.1.1.4   root      512:    u_char *test1,*test2,*p_exit,*p_fast_exit;
1.1.1.3   root      513:    jit_op_t *iop;
1.1       root      514: 
1.1.1.3   root      515:    /* 
                    516:     * Since an exception can be triggered, clear JIT state. This allows
                    517:     * to use branch target tag (we can directly branch on this instruction).
                    518:     */
                    519:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_TARGET);
                    520:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
1.1       root      521: 
1.1.1.3   root      522:    iop = ppc32_op_emit_insn_output(cpu,5,"memop_fast");
1.1       root      523: 
1.1.1.3   root      524:    test2 = NULL;
                    525: 
                    526:    if (val != 0) {
                    527:       /* EBX = sign-extended offset */
                    528:       ppc32_load_imm(&iop->ob_ptr,X86_EBX,val);
                    529: 
                    530:       /* EBX = GPR[base] + sign-extended offset */
                    531:       if (base != 0)
                    532:          ppc32_alu_gpr(&iop->ob_ptr,X86_ADD,X86_EBX,base);
                    533:    } else {
                    534:       if (base != 0)
                    535:          ppc32_load_gpr(&iop->ob_ptr,X86_EBX,base);
                    536:       else
                    537:          ppc32_load_imm(&iop->ob_ptr,X86_EBX,0);
                    538:    }
1.1       root      539: 
                    540:    /* EAX = mts32_entry index */
1.1.1.3   root      541:    x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EBX,4);
1.1.1.6 ! root      542:    x86_mov_reg_reg(iop->ob_ptr,X86_ESI,X86_EBX,4);
        !           543: 
        !           544:    x86_shift_reg_imm(iop->ob_ptr,X86_SHR,X86_EAX,MTS32_HASH_SHIFT1);
        !           545:    x86_shift_reg_imm(iop->ob_ptr,X86_SHR,X86_ESI,MTS32_HASH_SHIFT2);
        !           546:    x86_alu_reg_reg(iop->ob_ptr,X86_XOR,X86_EAX,X86_ESI);
        !           547: 
1.1.1.3   root      548:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,X86_EAX,MTS32_HASH_MASK);
1.1       root      549: 
                    550:    /* EDX = mts32_entry */
1.1.1.3   root      551:    x86_mov_reg_membase(iop->ob_ptr,X86_EDX,
1.1       root      552:                        X86_EDI,OFFSET(cpu_ppc_t,mts_cache[PPC32_MTS_DCACHE]),
                    553:                        4);
1.1.1.3   root      554:    x86_shift_reg_imm(iop->ob_ptr,X86_SHL,X86_EAX,4);
                    555:    x86_alu_reg_reg(iop->ob_ptr,X86_ADD,X86_EDX,X86_EAX);
1.1       root      556: 
                    557:    /* Compare virtual page address (ESI = vpage) */
1.1.1.3   root      558:    x86_mov_reg_reg(iop->ob_ptr,X86_ESI,X86_EBX,4);
                    559:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,X86_ESI,PPC32_MIN_PAGE_MASK);
1.1       root      560: 
1.1.1.3   root      561:    x86_alu_reg_membase(iop->ob_ptr,X86_CMP,X86_ESI,X86_EDX,
1.1       root      562:                        OFFSET(mts32_entry_t,gvpa));
1.1.1.3   root      563:    test1 = iop->ob_ptr;
                    564:    x86_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1);
1.1       root      565: 
                    566:    /* Test if we are writing to a COW page */
                    567:    if (write_op) {
1.1.1.3   root      568:       x86_test_membase_imm(iop->ob_ptr,X86_EDX,OFFSET(mts32_entry_t,flags),
1.1.1.2   root      569:                            MTS_FLAG_COW|MTS_FLAG_EXEC);
1.1.1.3   root      570:       test2 = iop->ob_ptr;
                    571:       x86_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1);
1.1       root      572:    }
                    573: 
                    574:    /* EBX = offset in page, EAX = Host Page Address */
1.1.1.3   root      575:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,X86_EBX,PPC32_MIN_PAGE_IMASK);
                    576:    x86_mov_reg_membase(iop->ob_ptr,X86_EAX,
                    577:                        X86_EDX,OFFSET(mts32_entry_t,hpa),4);
1.1       root      578: 
                    579:    /* Memory access */
1.1.1.3   root      580:    op_handler(iop,target);
1.1       root      581:  
1.1.1.3   root      582:    p_exit = iop->ob_ptr;
                    583:    x86_jump8(iop->ob_ptr,0);
1.1       root      584: 
                    585:    /* === Slow lookup === */
1.1.1.3   root      586:    x86_patch(test1,iop->ob_ptr);
1.1       root      587:    if (test2)
1.1.1.3   root      588:       x86_patch(test2,iop->ob_ptr);
1.1       root      589: 
                    590:    /* Update IA (EBX = vaddr) */
1.1.1.3   root      591:    ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));
1.1       root      592: 
                    593:    /* EDX = virtual address */
1.1.1.3   root      594:    x86_mov_reg_reg(iop->ob_ptr,X86_EDX,X86_EBX,4);
1.1       root      595: 
                    596:    /* ECX = target register */
1.1.1.3   root      597:    x86_mov_reg_imm(iop->ob_ptr,X86_ECX,target);
1.1       root      598: 
                    599:    /* EAX = CPU instance pointer */
1.1.1.3   root      600:    x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EDI,4);
1.1       root      601: 
                    602:    /* Call memory function */
1.1.1.4   root      603:    x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST);
1.1.1.3   root      604:    x86_call_membase(iop->ob_ptr,X86_EDI,MEMOP_OFFSET(opcode));
1.1.1.4   root      605:    x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);
                    606:    
1.1.1.3   root      607:    x86_patch(p_exit,iop->ob_ptr);
1.1       root      608: }
                    609: 
                    610: /* Emit unhandled instruction code */
                    611: static int ppc32_emit_unknown(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
                    612:                               ppc_insn_t opcode)
                    613: {
                    614:    u_char *test1;
1.1.1.3   root      615:    jit_op_t *iop;
1.1       root      616: 
1.1.1.3   root      617:    iop = ppc32_op_emit_insn_output(cpu,3,"unknown");
1.1       root      618: 
                    619:    /* Update IA */
1.1.1.3   root      620:    ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));
1.1       root      621: 
                    622:    /* Fallback to non-JIT mode */
1.1.1.4   root      623:    x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST);
1.1.1.3   root      624:    x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EDI,4);
                    625:    x86_mov_reg_imm(iop->ob_ptr,X86_EDX,opcode);
1.1       root      626: 
1.1.1.4   root      627:    ppc32_emit_basic_c_call(&iop->ob_ptr,ppc32_exec_single_insn_ext);
                    628:    x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);
                    629:    
1.1.1.3   root      630:    x86_test_reg_reg(iop->ob_ptr,X86_EAX,X86_EAX);
                    631:    test1 = iop->ob_ptr;
                    632:    x86_branch8(iop->ob_ptr, X86_CC_Z, 0, 1);
                    633:    ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
1.1       root      634: 
1.1.1.3   root      635:    x86_patch(test1,iop->ob_ptr);
1.1       root      636: 
1.1.1.3   root      637:    /* Signal this as an EOB to reset JIT state */
                    638:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
                    639:    return(0);
1.1       root      640: }
                    641: 
1.1.1.3   root      642: /* Virtual Breakpoint */
                    643: void ppc32_emit_breakpoint(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b)
1.1       root      644: {
1.1.1.3   root      645:    jit_op_t *iop;
                    646: 
                    647:    iop = ppc32_op_emit_insn_output(cpu,2,"breakpoint");
                    648: 
1.1.1.4   root      649:    x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST);
1.1.1.3   root      650:    x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EDI,4);
                    651:    ppc32_emit_c_call(b,iop,ppc32_run_breakpoint);
1.1.1.4   root      652:    x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);
1.1.1.3   root      653: 
                    654:    /* Signal this as an EOB to to reset JIT state */
                    655:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
1.1       root      656: }
                    657: 
1.1.1.3   root      658: /* Dump regs */
                    659: static void ppc32_emit_dump_regs(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b)
                    660: {   
                    661:    jit_op_t *iop;
1.1.1.4   root      662:    
1.1.1.3   root      663:    iop = ppc32_op_emit_insn_output(cpu,2,"dump_regs");
1.1.1.2   root      664: 
1.1.1.3   root      665:    x86_mov_reg_membase(iop->ob_ptr,X86_EAX,X86_EDI,OFFSET(cpu_ppc_t,gen),4);
1.1.1.4   root      666:    
                    667:    x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST-4);
1.1.1.3   root      668:    x86_push_reg(iop->ob_ptr,X86_EAX);
                    669:    ppc32_emit_c_call(b,iop,ppc32_dump_regs);
1.1.1.4   root      670:    x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);
1.1.1.3   root      671: 
                    672:    /* Signal this as an EOB to to reset JIT state */
                    673:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
1.1.1.2   root      674: }
                    675: 
1.1.1.4   root      676: /* Increment the number of executed instructions (performance debugging) */
                    677: void ppc32_inc_perf_counter(cpu_ppc_t *cpu)
                    678: { 
                    679:    jit_op_t *iop;
                    680:    
                    681:    iop = ppc32_op_emit_insn_output(cpu,1,"perf_cnt");
                    682:    x86_inc_membase(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,perf_counter));
                    683: }
                    684: 
1.1       root      685: /* ======================================================================== */
                    686: 
                    687: /* BLR - Branch to Link Register */
                    688: DECLARE_INSN(BLR)
                    689: {
1.1.1.3   root      690:    jit_op_t *iop;
                    691:    int hreg;
                    692: 
                    693:    ppc32_jit_start_hreg_seq(cpu,"blr");
                    694:    hreg = ppc32_jit_alloc_hreg(cpu,-1);
                    695:    ppc32_op_emit_alter_host_reg(cpu,hreg);
                    696: 
                    697:    iop = ppc32_op_emit_insn_output(cpu,2,"blr");
                    698: 
                    699:    x86_mov_reg_membase(iop->ob_ptr,hreg,X86_EDI,OFFSET(cpu_ppc_t,lr),4);
                    700:    x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),hreg,4);
1.1       root      701: 
                    702:    /* set the return address */
                    703:    if (insn & 1)
1.1.1.3   root      704:       ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
                    705: 
                    706:    ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
                    707:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
                    708:    ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
1.1       root      709: 
1.1.1.3   root      710:    ppc32_jit_close_hreg_seq(cpu);
1.1       root      711:    return(0);
                    712: }
                    713: 
                    714: /* BCTR - Branch to Count Register */
                    715: DECLARE_INSN(BCTR)
                    716: {
1.1.1.3   root      717:    jit_op_t *iop;
                    718:    int hreg;
                    719: 
                    720:    ppc32_jit_start_hreg_seq(cpu,"bctr");
                    721:    hreg = ppc32_jit_alloc_hreg(cpu,-1);
                    722:    ppc32_op_emit_alter_host_reg(cpu,hreg);
                    723: 
                    724:    iop = ppc32_op_emit_insn_output(cpu,2,"bctr");
                    725: 
                    726:    x86_mov_reg_membase(iop->ob_ptr,hreg,X86_EDI,OFFSET(cpu_ppc_t,ctr),4);
                    727:    x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),hreg,4);
1.1       root      728: 
                    729:    /* set the return address */
                    730:    if (insn & 1)
1.1.1.3   root      731:       ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
                    732: 
                    733:    ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
                    734:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
                    735:    ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
1.1       root      736: 
1.1.1.3   root      737:    ppc32_jit_close_hreg_seq(cpu);
1.1       root      738:    return(0);
                    739: }
                    740: 
                    741: /* MFLR - Move From Link Register */
                    742: DECLARE_INSN(MFLR)
                    743: {
                    744:    int rd = bits(insn,21,25);
1.1.1.3   root      745:    int hreg_rd;
                    746:    jit_op_t *iop;
                    747: 
                    748:    ppc32_jit_start_hreg_seq(cpu,"mflr");
                    749:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                    750:    iop = ppc32_op_emit_insn_output(cpu,1,"mflr");
                    751: 
                    752:    x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,lr),4);
                    753:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
                    754: 
                    755:    ppc32_jit_close_hreg_seq(cpu);
1.1       root      756:    return(0);
                    757: }
                    758: 
                    759: /* MTLR - Move To Link Register */
                    760: DECLARE_INSN(MTLR)
                    761: {
                    762:    int rs = bits(insn,21,25);
1.1.1.3   root      763:    int hreg_rs;
                    764:    jit_op_t *iop;
                    765:    
                    766:    ppc32_jit_start_hreg_seq(cpu,"mtlr");
                    767:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                    768:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
1.1       root      769: 
1.1.1.3   root      770:    iop = ppc32_op_emit_insn_output(cpu,1,"mtlr");
                    771:    x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,lr),hreg_rs,4);
                    772: 
                    773:    ppc32_jit_close_hreg_seq(cpu);
1.1       root      774:    return(0);
                    775: }
                    776: 
                    777: /* MFCTR - Move From Counter Register */
                    778: DECLARE_INSN(MFCTR)
                    779: {
                    780:    int rd = bits(insn,21,25);
1.1.1.3   root      781:    int hreg_rd;
                    782:    jit_op_t *iop;
1.1       root      783:    
1.1.1.3   root      784:    ppc32_jit_start_hreg_seq(cpu,"mfctr");
                    785:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                    786: 
                    787:    iop = ppc32_op_emit_insn_output(cpu,1,"mfctr");
                    788: 
                    789:    x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,ctr),4);
                    790:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
                    791: 
                    792:    ppc32_jit_close_hreg_seq(cpu);
1.1       root      793:    return(0);
                    794: }
                    795: 
                    796: /* MTCTR - Move To Counter Register */
                    797: DECLARE_INSN(MTCTR)
                    798: {
                    799:    int rs = bits(insn,21,25);
1.1.1.3   root      800:    int hreg_rs;
                    801:    jit_op_t *iop;
1.1       root      802: 
1.1.1.3   root      803:    ppc32_jit_start_hreg_seq(cpu,"mtctr");
                    804:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                    805:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                    806: 
                    807:    iop = ppc32_op_emit_insn_output(cpu,1,"mtctr");
                    808:    x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr),hreg_rs,4);
                    809: 
                    810:    ppc32_jit_close_hreg_seq(cpu);
1.1       root      811:    return(0);
                    812: }
                    813: 
                    814: /* MFTBU - Move from Time Base (Up) */
                    815: DECLARE_INSN(MFTBU)
                    816: {
                    817:    int rd = bits(insn,21,25);
1.1.1.3   root      818:    int hreg_rd;
                    819:    jit_op_t *iop;
                    820: 
                    821:    ppc32_jit_start_hreg_seq(cpu,"mftbu");
                    822:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                    823: 
                    824:    iop = ppc32_op_emit_insn_output(cpu,1,"mftbu");
                    825: 
                    826:    x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,4);
                    827:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1.1       root      828: 
1.1.1.3   root      829:    ppc32_jit_close_hreg_seq(cpu);
1.1       root      830:    return(0);
                    831: }
                    832: 
                    833: #define PPC32_TB_INCREMENT  50
                    834: 
                    835: /* MFTBL - Move from Time Base (Lo) */
                    836: DECLARE_INSN(MFTBL)
                    837: {
                    838:    int rd = bits(insn,21,25);
1.1.1.3   root      839:    int hreg_rd,hreg_t0;
                    840:    jit_op_t *iop;
                    841: 
                    842:    ppc32_jit_start_hreg_seq(cpu,"mftbl");
                    843:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                    844:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                    845: 
                    846:    iop = ppc32_op_emit_insn_output(cpu,3,"mftbl");
                    847: 
                    848:    x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,tb),4);
1.1       root      849: 
                    850:    /* Increment the time base register */
1.1.1.3   root      851:    x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,tb),4);
                    852:    x86_mov_reg_membase(iop->ob_ptr,hreg_t0,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,4);
                    853:    x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_rd,PPC32_TB_INCREMENT);
                    854:    x86_alu_reg_imm(iop->ob_ptr,X86_ADC,hreg_t0,0);
                    855:    x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,tb),hreg_rd,4);
                    856:    x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,hreg_t0,4);
                    857: 
                    858:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1.1       root      859: 
1.1.1.3   root      860:    ppc32_jit_close_hreg_seq(cpu);
1.1       root      861:    return(0);
                    862: }
                    863: 
                    864: /* ADD */
                    865: DECLARE_INSN(ADD)
                    866: {
                    867:    int rd = bits(insn,21,25);
                    868:    int ra = bits(insn,16,20);
                    869:    int rb = bits(insn,11,15);
1.1.1.3   root      870:    int hreg_rd,hreg_ra,hreg_rb;
                    871:    jit_op_t *iop;
1.1       root      872: 
                    873:    /* $rd = $ra + $rb */
1.1.1.3   root      874:    ppc32_jit_start_hreg_seq(cpu,"add");
                    875:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                    876:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                    877:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                    878: 
                    879:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                    880:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                    881: 
                    882:    iop = ppc32_op_emit_insn_output(cpu,2,"add");
                    883: 
                    884:    if (rd == ra)
                    885:       x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb);
                    886:    else if (rd == rb)
                    887:       x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_rd,hreg_ra);
                    888:    else {
                    889:       x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
                    890:       x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb);
                    891:    }
                    892: 
                    893:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1.1       root      894: 
                    895:    if (insn & 1)
1.1.1.3   root      896:       ppc32_op_emit_update_flags(cpu,0,TRUE);
                    897:    
                    898:    ppc32_jit_close_hreg_seq(cpu);
1.1       root      899:    return(0);
                    900: }
                    901: 
                    902: /* ADDC */
                    903: DECLARE_INSN(ADDC)
                    904: {
                    905:    int rd = bits(insn,21,25);
                    906:    int ra = bits(insn,16,20);
                    907:    int rb = bits(insn,11,15);
1.1.1.3   root      908:    int hreg_rd,hreg_ra,hreg_rb,hreg_t0;
                    909:    jit_op_t *iop;
1.1       root      910: 
                    911:    /* $rd = $ra + $rb */
1.1.1.3   root      912:    ppc32_jit_start_hreg_seq(cpu,"addc");
                    913:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                    914:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                    915:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
1.1       root      916: 
                    917:    /* store the carry flag */
1.1.1.3   root      918:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                    919: 
                    920:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                    921:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                    922: 
                    923:    iop = ppc32_op_emit_insn_output(cpu,2,"addc");
                    924: 
                    925:    if (rd == ra)
                    926:       x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb);
                    927:    else if (rd == rb)
                    928:       x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_rd,hreg_ra);
                    929:    else {
                    930:       x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
                    931:       x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb);
                    932:    }
                    933: 
                    934:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
                    935:    
                    936:    x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t0,FALSE);
                    937:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x1);
                    938:    x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),
                    939:                        hreg_t0,4);
1.1       root      940: 
                    941:    if (insn & 1) {
1.1.1.3   root      942:       x86_test_reg_reg(iop->ob_ptr,hreg_rd,hreg_rd);
                    943:       ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1       root      944:    }
1.1.1.3   root      945: 
                    946:    ppc32_jit_close_hreg_seq(cpu);
1.1       root      947:    return(0);
                    948: }
                    949: 
                    950: /* ADDE - Add Extended */
                    951: DECLARE_INSN(ADDE)
                    952: {   
                    953:    int rd = bits(insn,21,25);
                    954:    int ra = bits(insn,16,20);
                    955:    int rb = bits(insn,11,15);
1.1.1.3   root      956:    int hreg_ra,hreg_rb,hreg_rd,hreg_t0,hreg_t1;
                    957:    jit_op_t *iop;
1.1       root      958: 
1.1.1.3   root      959:    ppc32_jit_start_hreg_seq(cpu,"adde");
                    960:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                    961:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                    962:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1.1       root      963: 
1.1.1.3   root      964:    hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
                    965:    hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
1.1       root      966: 
1.1.1.3   root      967:    ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
                    968:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                    969:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
1.1       root      970: 
1.1.1.3   root      971:    iop = ppc32_op_emit_insn_output(cpu,3,"adde");
1.1       root      972: 
1.1.1.3   root      973:    /* $t0 = $ra + carry */
                    974:    x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t1,hreg_t1);
                    975:    x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_ra,4);
                    976: 
                    977:    x86_alu_reg_membase(iop->ob_ptr,X86_ADD,hreg_t0,
                    978:                        X86_EDI,OFFSET(cpu_ppc_t,xer_ca));
                    979:    x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
                    980:    x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),hreg_t1,4);
                    981: 
                    982:    /* $t0 += $rb */
                    983:    x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_t0,hreg_rb);
                    984:    x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
                    985:    x86_alu_membase_reg(iop->ob_ptr,X86_OR,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),
                    986:                        hreg_t1);
1.1       root      987: 
                    988:    /* update cr0 */
1.1.1.3   root      989:    if (insn & 1)
                    990:       x86_test_reg_reg(iop->ob_ptr,hreg_t0,hreg_t0);
1.1       root      991: 
1.1.1.3   root      992:    x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_t0,4);
                    993:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
                    994: 
                    995:    if (insn & 1)
                    996:       ppc32_op_emit_update_flags(cpu,0,TRUE);
                    997: 
                    998:    ppc32_jit_close_hreg_seq(cpu);
1.1       root      999:    return(0);
                   1000: }
                   1001: 
                   1002: /* ADDI - ADD Immediate */
                   1003: DECLARE_INSN(ADDI)
                   1004: {
                   1005:    int rd = bits(insn,21,25);
                   1006:    int ra = bits(insn,16,20);
                   1007:    int imm = bits(insn,0,15);
                   1008:    m_uint32_t tmp = sign_extend_32(imm,16);
1.1.1.3   root     1009:    int hreg_rd,hreg_ra;
                   1010:    jit_op_t *iop;
                   1011: 
                   1012:    /* $rd = $ra + imm */
                   1013:    ppc32_jit_start_hreg_seq(cpu,"addi");
                   1014:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                   1015: 
                   1016:    if (ra != 0) {
                   1017:       hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   1018:       ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                   1019: 
                   1020:       iop = ppc32_op_emit_insn_output(cpu,2,"addi");
1.1       root     1021: 
1.1.1.3   root     1022:       if (rd != ra)
                   1023:          x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
1.1       root     1024: 
1.1.1.3   root     1025:       x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_rd,tmp);
                   1026:    } else {
                   1027:       iop = ppc32_op_emit_insn_output(cpu,1,"addi");
                   1028:       ppc32_load_imm(&iop->ob_ptr,hreg_rd,tmp);
                   1029:    }
                   1030: 
                   1031:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1.1       root     1032: 
1.1.1.3   root     1033:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1034:    return(0);
                   1035: }
                   1036: 
                   1037: /* ADDIC - ADD Immediate with Carry */
                   1038: DECLARE_INSN(ADDIC)
                   1039: {
                   1040:    int rd = bits(insn,21,25);
                   1041:    int ra = bits(insn,16,20);
                   1042:    int imm = bits(insn,0,15);
                   1043:    m_uint32_t tmp = sign_extend_32(imm,16);
1.1.1.3   root     1044:    int hreg_rd,hreg_ra;
                   1045:    jit_op_t *iop;
                   1046: 
                   1047:    /* $rd = $ra + imm */
                   1048:    ppc32_jit_start_hreg_seq(cpu,"addic");
                   1049:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                   1050:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   1051: 
                   1052:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                   1053: 
                   1054:    iop = ppc32_op_emit_insn_output(cpu,1,"addic");
                   1055: 
                   1056:    if (rd != ra)
                   1057:       x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
                   1058: 
                   1059:    x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_rd,tmp);
                   1060:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
                   1061: 
                   1062:    x86_set_membase(iop->ob_ptr,X86_CC_C,
                   1063:                    X86_EDI,OFFSET(cpu_ppc_t,xer_ca),FALSE);
1.1       root     1064: 
1.1.1.3   root     1065:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1066:    return(0);
                   1067: }
                   1068: 
                   1069: /* ADDIC. */
                   1070: DECLARE_INSN(ADDIC_dot)
                   1071: {
                   1072:    int rd = bits(insn,21,25);
                   1073:    int ra = bits(insn,16,20);
                   1074:    int imm = bits(insn,0,15);
                   1075:    m_uint32_t tmp = sign_extend_32(imm,16);
1.1.1.3   root     1076:    int hreg_rd,hreg_ra;
                   1077:    jit_op_t *iop;
1.1       root     1078: 
1.1.1.3   root     1079:    /* $rd = $ra + imm */
                   1080:    ppc32_jit_start_hreg_seq(cpu,"addic.");
                   1081:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                   1082:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1.1       root     1083: 
1.1.1.3   root     1084:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                   1085: 
                   1086:    iop = ppc32_op_emit_insn_output(cpu,1,"addic.");
                   1087: 
                   1088:    if (rd != ra)
                   1089:       x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
                   1090: 
                   1091:    x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_rd,tmp);
                   1092:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
                   1093: 
                   1094:    x86_set_membase(iop->ob_ptr,X86_CC_C,
                   1095:                    X86_EDI,OFFSET(cpu_ppc_t,xer_ca),FALSE);
                   1096: 
                   1097:    ppc32_op_emit_update_flags(cpu,0,TRUE);
                   1098: 
                   1099:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1100:    return(0);
                   1101: }
                   1102: 
                   1103: /* ADDIS - ADD Immediate Shifted */
                   1104: DECLARE_INSN(ADDIS)
                   1105: {
                   1106:    int rd = bits(insn,21,25);
                   1107:    int ra = bits(insn,16,20);
                   1108:    m_uint32_t imm = bits(insn,0,15);
1.1.1.3   root     1109:    m_uint32_t tmp = imm << 16;
                   1110:    int hreg_rd,hreg_ra;
                   1111:    jit_op_t *iop;
                   1112: 
                   1113:    /* $rd = $ra + (imm << 16) */
                   1114:    ppc32_jit_start_hreg_seq(cpu,"addis");
                   1115:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                   1116: 
                   1117:    if (ra != 0) {
                   1118:       hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   1119:       ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                   1120: 
                   1121:       iop = ppc32_op_emit_insn_output(cpu,1,"addis");
1.1       root     1122: 
1.1.1.3   root     1123:       if (rd != ra)
                   1124:          x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
1.1       root     1125: 
1.1.1.3   root     1126:       x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_rd,tmp);
                   1127:    } else {
                   1128:       //iop = ppc32_op_emit_insn_output(cpu,1,"addis");
                   1129:       //x86_mov_reg_imm(iop->ob_ptr,hreg_rd,tmp);
                   1130:       ppc32_op_emit_set_host_reg_imm32(cpu,hreg_rd,tmp);
                   1131:    }
                   1132: 
                   1133:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
                   1134: 
                   1135:    ppc32_jit_close_hreg_seq(cpu);
                   1136:    return(0);
                   1137: }
                   1138: 
                   1139: /* ADDZE */
                   1140: DECLARE_INSN(ADDZE)
                   1141: {
                   1142:    int rd = bits(insn,21,25);
                   1143:    int ra = bits(insn,16,20);
                   1144:    int hreg_rd,hreg_ra,hreg_t0;
                   1145:    jit_op_t *iop;
                   1146: 
                   1147:    /* $rd = $ra + xer_ca + set_carry */
                   1148:    ppc32_jit_start_hreg_seq(cpu,"addze");
                   1149:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                   1150:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   1151:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   1152: 
                   1153:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                   1154: 
                   1155:    iop = ppc32_op_emit_insn_output(cpu,2,"addze");
                   1156: 
                   1157:    x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t0,hreg_t0);
                   1158: 
                   1159:    if (rd != ra)
                   1160:       x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
                   1161: 
                   1162:    x86_alu_reg_membase(iop->ob_ptr,X86_ADD,hreg_rd,
                   1163:                        X86_EDI,OFFSET(cpu_ppc_t,xer_ca));
                   1164: 
                   1165:    x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t0,FALSE);
                   1166:    x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),hreg_t0,4);
1.1       root     1167: 
1.1.1.3   root     1168:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
                   1169: 
                   1170:    if (insn & 1)
                   1171:       ppc32_op_emit_update_flags(cpu,0,TRUE);
                   1172: 
                   1173:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1174:    return(0);
                   1175: }
                   1176: 
                   1177: /* AND */
                   1178: DECLARE_INSN(AND)
                   1179: {
                   1180:    int rs = bits(insn,21,25);
                   1181:    int ra = bits(insn,16,20);
                   1182:    int rb = bits(insn,11,15);
1.1.1.3   root     1183:    int hreg_rs,hreg_ra,hreg_rb;
                   1184:    jit_op_t *iop;
                   1185: 
                   1186:    /* $ra = $rs & $rb */
                   1187:    ppc32_jit_start_hreg_seq(cpu,"and");
                   1188:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   1189:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   1190:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   1191: 
                   1192:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   1193:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                   1194: 
                   1195:    iop = ppc32_op_emit_insn_output(cpu,1,"and");
                   1196: 
                   1197:    if (ra == rs)
                   1198:       x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_ra,hreg_rb);
                   1199:    else if (ra == rb)
                   1200:       x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_ra,hreg_rs);
                   1201:    else {
                   1202:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
                   1203:       x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_ra,hreg_rb);
                   1204:    }
1.1       root     1205: 
1.1.1.3   root     1206:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1.1       root     1207: 
                   1208:    if (insn & 1)
1.1.1.3   root     1209:       ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1       root     1210: 
1.1.1.3   root     1211:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1212:    return(0);
                   1213: }
                   1214: 
                   1215: /* ANDC */
                   1216: DECLARE_INSN(ANDC)
                   1217: {
                   1218:    int rs = bits(insn,21,25);
                   1219:    int ra = bits(insn,16,20);
                   1220:    int rb = bits(insn,11,15);
1.1.1.3   root     1221:    int hreg_rs,hreg_ra,hreg_rb,hreg_t0;
                   1222:    jit_op_t *iop;
1.1       root     1223: 
                   1224:    /* $ra = $rs & ~$rb */
1.1.1.3   root     1225:    ppc32_jit_start_hreg_seq(cpu,"andc");
                   1226:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   1227:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   1228:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   1229: 
                   1230:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   1231:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                   1232: 
                   1233:    iop = ppc32_op_emit_insn_output(cpu,1,"andc");
                   1234: 
                   1235:    /* $t0 = ~$rb */
                   1236:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   1237:    x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rb,4);
                   1238:    x86_not_reg(iop->ob_ptr,hreg_t0);
                   1239: 
                   1240:    /* $ra = $rs & $t0 */
                   1241:    if (ra == rs) 
                   1242:       x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_ra,hreg_t0);
                   1243:    else {
                   1244:       x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_rs);
                   1245:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_t0,4);
                   1246:    }
                   1247: 
                   1248:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1.1       root     1249: 
                   1250:    if (insn & 1)
1.1.1.3   root     1251:       ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1       root     1252: 
1.1.1.3   root     1253:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1254:    return(0);
                   1255: }
                   1256: 
                   1257: /* AND Immediate */
                   1258: DECLARE_INSN(ANDI)
                   1259: {
                   1260:    int rs = bits(insn,21,25);
                   1261:    int ra = bits(insn,16,20);
                   1262:    m_uint16_t imm = bits(insn,0,15);
1.1.1.3   root     1263:    m_uint32_t tmp = imm;
                   1264:    int hreg_rs,hreg_ra;
                   1265:    jit_op_t *iop;
1.1       root     1266: 
                   1267:    /* $ra = $rs & imm */
1.1.1.3   root     1268:    ppc32_jit_start_hreg_seq(cpu,"andi");
                   1269:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   1270:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1.1       root     1271: 
1.1.1.3   root     1272:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   1273: 
                   1274:    iop = ppc32_op_emit_insn_output(cpu,2,"andi");
                   1275: 
                   1276:    if (ra != rs)
                   1277:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
                   1278: 
                   1279:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_ra,tmp);
                   1280:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   1281: 
                   1282:    ppc32_op_emit_update_flags(cpu,0,TRUE);
                   1283: 
                   1284:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1285:    return(0);
                   1286: }
                   1287: 
                   1288: /* AND Immediate Shifted */
                   1289: DECLARE_INSN(ANDIS)
                   1290: {
                   1291:    int rs = bits(insn,21,25);
                   1292:    int ra = bits(insn,16,20);
                   1293:    m_uint32_t imm = bits(insn,0,15);
1.1.1.3   root     1294:    m_uint32_t tmp = imm << 16;
                   1295:    int hreg_rs,hreg_ra;
                   1296:    jit_op_t *iop;
1.1       root     1297: 
                   1298:    /* $ra = $rs & imm */
1.1.1.3   root     1299:    ppc32_jit_start_hreg_seq(cpu,"andis");
                   1300:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   1301:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   1302: 
                   1303:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   1304: 
                   1305:    iop = ppc32_op_emit_insn_output(cpu,2,"andis");
                   1306: 
                   1307:    if (ra != rs)
                   1308:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
                   1309: 
                   1310:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_ra,tmp);
                   1311:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1.1       root     1312: 
1.1.1.3   root     1313:    ppc32_op_emit_update_flags(cpu,0,TRUE);
                   1314: 
                   1315:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1316:    return(0);
                   1317: }
                   1318: 
                   1319: /* B - Branch */
                   1320: DECLARE_INSN(B)
                   1321: {
                   1322:    m_uint32_t offset = bits(insn,2,25);
1.1.1.3   root     1323:    m_uint32_t new_ia;
                   1324:    jit_op_t *iop;
                   1325: 
                   1326:    iop = ppc32_op_emit_insn_output(cpu,4,"b");
1.1       root     1327: 
                   1328:    /* compute the new ia */
1.1.1.3   root     1329:    new_ia = b->start_ia + (b->ppc_trans_pos << 2);
1.1       root     1330:    new_ia += sign_extend(offset << 2,26);
1.1.1.3   root     1331:    ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
                   1332: 
                   1333:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
                   1334:    ppc32_op_emit_branch_target(cpu,b,new_ia);
                   1335:    ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
1.1       root     1336:    return(0);
                   1337: }
                   1338: 
                   1339: /* BA - Branch Absolute */
                   1340: DECLARE_INSN(BA)
                   1341: {
                   1342:    m_uint32_t offset = bits(insn,2,25);
1.1.1.3   root     1343:    m_uint32_t new_ia;
                   1344:    jit_op_t *iop;
                   1345: 
                   1346:    iop = ppc32_op_emit_insn_output(cpu,4,"ba");
1.1       root     1347: 
                   1348:    /* compute the new ia */
                   1349:    new_ia = sign_extend(offset << 2,26);
1.1.1.3   root     1350:    ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
                   1351: 
                   1352:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
                   1353:    ppc32_op_emit_branch_target(cpu,b,new_ia);
                   1354:    ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
1.1       root     1355:    return(0);
                   1356: }
                   1357: 
                   1358: /* BL - Branch and Link */
                   1359: DECLARE_INSN(BL)
                   1360: {
                   1361:    m_uint32_t offset = bits(insn,2,25);
1.1.1.3   root     1362:    m_uint32_t new_ia;
                   1363:    jit_op_t *iop;
                   1364: 
                   1365:    iop = ppc32_op_emit_insn_output(cpu,4,"bl");
1.1       root     1366: 
                   1367:    /* compute the new ia */
1.1.1.3   root     1368:    new_ia = b->start_ia + (b->ppc_trans_pos << 2);
1.1       root     1369:    new_ia += sign_extend(offset << 2,26);
                   1370: 
                   1371:    /* set the return address */
1.1.1.3   root     1372:    ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
                   1373:    ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
1.1       root     1374: 
1.1.1.3   root     1375:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
                   1376:    ppc32_op_emit_branch_target(cpu,b,new_ia);
                   1377:    ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
1.1       root     1378:    return(0);
                   1379: }
                   1380: 
                   1381: /* BLA - Branch and Link Absolute */
                   1382: DECLARE_INSN(BLA)
                   1383: {
                   1384:    m_uint32_t offset = bits(insn,2,25);
1.1.1.3   root     1385:    m_uint32_t new_ia;
                   1386:    jit_op_t *iop;
                   1387: 
                   1388:    iop = ppc32_op_emit_insn_output(cpu,4,"bla");
1.1       root     1389: 
                   1390:    /* compute the new ia */
                   1391:    new_ia = sign_extend(offset << 2,26);
                   1392: 
                   1393:    /* set the return address */
1.1.1.3   root     1394:    ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
                   1395:    ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
1.1       root     1396: 
1.1.1.3   root     1397:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
                   1398:    ppc32_op_emit_branch_target(cpu,b,new_ia);
                   1399:    ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
1.1       root     1400:    return(0);
                   1401: }
                   1402: 
                   1403: /* BC - Branch Conditional (Condition Check only) */
                   1404: DECLARE_INSN(BCC)
                   1405: {
                   1406:    int bo = bits(insn,21,25);
                   1407:    int bi = bits(insn,16,20);
                   1408:    int bd = bits(insn,2,15);
1.1.1.3   root     1409:    jit_op_t *iop;
1.1.1.2   root     1410:    u_int cr_field,cr_bit;
1.1       root     1411:    m_uint32_t new_ia;
                   1412:    u_char *jump_ptr;
                   1413:    int local_jump;
                   1414:    int cond;
                   1415: 
1.1.1.3   root     1416:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_JUMP);
                   1417: 
                   1418:    iop = ppc32_op_emit_insn_output(cpu,5,"bcc");
                   1419: 
1.1       root     1420:    /* Get the wanted value for the condition bit */
                   1421:    cond = (bo >> 3) & 0x1;
                   1422: 
                   1423:    /* Set the return address */
1.1.1.3   root     1424:    if (insn & 1) {
                   1425:       ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
                   1426:       ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1)<<2));
                   1427:    }
1.1       root     1428: 
                   1429:    /* Compute the new ia */
                   1430:    new_ia = sign_extend_32(bd << 2,16);
                   1431:    if (!(insn & 0x02))
1.1.1.3   root     1432:       new_ia += b->start_ia + (b->ppc_trans_pos << 2);
1.1       root     1433: 
                   1434:    /* Test the condition bit */
1.1.1.2   root     1435:    cr_field = ppc32_get_cr_field(bi);
                   1436:    cr_bit = ppc32_get_cr_bit(bi);
                   1437: 
1.1.1.3   root     1438:    ppc32_op_emit_require_flags(cpu,cr_field);
                   1439: 
                   1440:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     1441:                         X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field),
                   1442:                         (1 << cr_bit));
1.1       root     1443: 
                   1444:    local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr);
                   1445: 
                   1446:    /* 
                   1447:     * Optimize the jump, depending if the destination is in the same 
                   1448:     * page or not.
                   1449:     */
                   1450:    if (local_jump) {
1.1.1.3   root     1451:       ppc32_jit_tcb_record_patch(b,iop,iop->ob_ptr,new_ia);
                   1452:       x86_branch32(iop->ob_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,0,FALSE);
1.1       root     1453:    } else {   
1.1.1.3   root     1454:       jump_ptr = iop->ob_ptr;
                   1455:       x86_branch32(iop->ob_ptr,(cond) ? X86_CC_Z : X86_CC_NZ,0,FALSE);
                   1456:       ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
                   1457:       x86_patch(jump_ptr,iop->ob_ptr);
1.1       root     1458:    }
                   1459: 
1.1.1.3   root     1460:    ppc32_op_emit_branch_target(cpu,b,new_ia);
1.1       root     1461:    return(0);
                   1462: }
                   1463: 
                   1464: /* BC - Branch Conditional */
                   1465: DECLARE_INSN(BC)
                   1466: {   
                   1467:    int bo = bits(insn,21,25);
                   1468:    int bi = bits(insn,16,20);
                   1469:    int bd = bits(insn,2,15);
1.1.1.3   root     1470:    int hreg_t0,hreg_t1;
                   1471:    jit_op_t *iop;
1.1.1.2   root     1472:    u_int cr_field,cr_bit;
1.1       root     1473:    m_uint32_t new_ia;
                   1474:    u_char *jump_ptr;
                   1475:    int local_jump;
                   1476:    int cond,ctr;
                   1477: 
1.1.1.3   root     1478:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_JUMP);
                   1479: 
                   1480:    iop = ppc32_op_emit_insn_output(cpu,5,"bc");
                   1481: 
                   1482:    ppc32_jit_start_hreg_seq(cpu,"bc");
                   1483:    hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
                   1484:    hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
                   1485: 
                   1486:    ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
                   1487: 
1.1       root     1488:    /* Get the wanted value for the condition bit and CTR value */
                   1489:    cond = (bo >> 3) & 0x1;
                   1490:    ctr  = (bo >> 1) & 0x1;
                   1491: 
                   1492:    /* Set the return address */
1.1.1.3   root     1493:    if (insn & 1) {
                   1494:       ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
                   1495:       ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1)<<2));
                   1496:    }
1.1       root     1497: 
                   1498:    /* Compute the new ia */
                   1499:    new_ia = sign_extend_32(bd << 2,16);
                   1500:    if (!(insn & 0x02))
1.1.1.3   root     1501:       new_ia += b->start_ia + (b->ppc_trans_pos << 2);
1.1       root     1502: 
1.1.1.3   root     1503:    x86_mov_reg_imm(iop->ob_ptr,hreg_t0,1);
1.1       root     1504: 
                   1505:    /* Decrement the count register */
                   1506:    if (!(bo & 0x04)) {
1.1.1.3   root     1507:       x86_dec_membase(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr));
                   1508:       x86_set_reg(iop->ob_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,hreg_t1,FALSE);
                   1509:       x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1);
1.1       root     1510:    }
                   1511: 
                   1512:    /* Test the condition bit */
                   1513:    if (!((bo >> 4) & 0x01)) {
1.1.1.2   root     1514:       cr_field = ppc32_get_cr_field(bi);
                   1515:       cr_bit = ppc32_get_cr_bit(bi);
                   1516: 
1.1.1.3   root     1517:       ppc32_op_emit_require_flags(cpu,cr_field);
                   1518: 
                   1519:       x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     1520:                            X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field),
                   1521:                            (1 << cr_bit));
                   1522: 
1.1.1.3   root     1523:       x86_set_reg(iop->ob_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,hreg_t1,FALSE);
                   1524:       x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1);
1.1       root     1525:    }
                   1526: 
1.1.1.3   root     1527:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1       root     1528: 
                   1529:    local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr);
                   1530: 
                   1531:    /* 
                   1532:     * Optimize the jump, depending if the destination is in the same 
                   1533:     * page or not.
                   1534:     */
                   1535:    if (local_jump) {
1.1.1.3   root     1536:       ppc32_jit_tcb_record_patch(b,iop,iop->ob_ptr,new_ia);
                   1537:       x86_branch32(iop->ob_ptr,X86_CC_NZ,0,FALSE);
1.1       root     1538:    } else {   
1.1.1.3   root     1539:       jump_ptr = iop->ob_ptr;
                   1540:       x86_branch32(iop->ob_ptr,X86_CC_Z,0,FALSE);
                   1541:       ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
                   1542:       x86_patch(jump_ptr,iop->ob_ptr);
1.1       root     1543:    }
                   1544: 
1.1.1.3   root     1545:    ppc32_op_emit_branch_target(cpu,b,new_ia);
                   1546: 
                   1547:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1548:    return(0);
                   1549: }
                   1550: 
                   1551: /* BCLR - Branch Conditional to Link register */
                   1552: DECLARE_INSN(BCLR)
                   1553: {   
                   1554:    int bo = bits(insn,21,25);
                   1555:    int bi = bits(insn,16,20);
                   1556:    int bd = bits(insn,2,15);
1.1.1.3   root     1557:    int hreg_t0,hreg_t1;
                   1558:    jit_op_t *iop;
1.1.1.2   root     1559:    u_int cr_field,cr_bit;
1.1       root     1560:    m_uint32_t new_ia;
                   1561:    u_char *jump_ptr;
                   1562:    int cond,ctr;
                   1563: 
1.1.1.3   root     1564:    ppc32_jit_start_hreg_seq(cpu,"bclr");
                   1565:    hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
                   1566:    hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
                   1567: 
                   1568:    ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
                   1569: 
                   1570:    iop = ppc32_op_emit_insn_output(cpu,5,"bclr");
                   1571: 
1.1       root     1572:    /* Get the wanted value for the condition bit and CTR value */
                   1573:    cond = (bo >> 3) & 0x1;
                   1574:    ctr  = (bo >> 1) & 0x1;
                   1575: 
                   1576:    /* Compute the new ia */
                   1577:    new_ia = sign_extend_32(bd << 2,16);
                   1578:    if (!(insn & 0x02))
1.1.1.3   root     1579:       new_ia += b->start_ia + (b->ppc_trans_pos << 2);
1.1       root     1580: 
1.1.1.3   root     1581:    x86_mov_reg_imm(iop->ob_ptr,hreg_t0,1);
1.1       root     1582: 
                   1583:    /* Decrement the count register */
                   1584:    if (!(bo & 0x04)) {
1.1.1.3   root     1585:       x86_dec_membase(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr));
                   1586:       x86_set_reg(iop->ob_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,hreg_t1,FALSE);
                   1587:       x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1);
1.1       root     1588:    }
                   1589: 
                   1590:    /* Test the condition bit */
                   1591:    if (!((bo >> 4) & 0x01)) {
1.1.1.2   root     1592:       cr_field = ppc32_get_cr_field(bi);
                   1593:       cr_bit = ppc32_get_cr_bit(bi);
                   1594: 
1.1.1.3   root     1595:       ppc32_op_emit_require_flags(cpu,cr_field);
                   1596: 
                   1597:       x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     1598:                            X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field),
                   1599:                            (1 << cr_bit));
                   1600: 
1.1.1.3   root     1601:       x86_set_reg(iop->ob_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,hreg_t1,FALSE);
                   1602:       x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1);
1.1       root     1603:    }
                   1604: 
                   1605:    /* Set the return address */
1.1.1.3   root     1606:    x86_mov_reg_membase(iop->ob_ptr,hreg_t1,X86_EDI,OFFSET(cpu_ppc_t,lr),4);
1.1       root     1607: 
1.1.1.3   root     1608:    if (insn & 1) {
                   1609:       ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
                   1610:       ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1)<<2));
                   1611:    }
1.1       root     1612: 
                   1613:    /* Branching */
1.1.1.3   root     1614:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
                   1615: 
                   1616:    jump_ptr = iop->ob_ptr;
                   1617:    x86_branch32(iop->ob_ptr,X86_CC_Z,0,FALSE);
                   1618: 
                   1619:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t1,0xFFFFFFFC);
                   1620:    x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),hreg_t1,4);
                   1621:    ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
1.1       root     1622: 
1.1.1.3   root     1623:    x86_patch(jump_ptr,iop->ob_ptr);
1.1       root     1624: 
1.1.1.3   root     1625:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
1.1       root     1626: 
1.1.1.3   root     1627:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1628:    return(0);
                   1629: }
                   1630: 
                   1631: /* CMP - Compare */
                   1632: DECLARE_INSN(CMP)
                   1633: {
                   1634:    int rd = bits(insn,23,25);
                   1635:    int ra = bits(insn,16,20);
                   1636:    int rb = bits(insn,11,15);
1.1.1.3   root     1637:    int hreg_ra,hreg_rb;
                   1638:    jit_op_t *iop;
                   1639:    
                   1640:    ppc32_jit_start_hreg_seq(cpu,"cmp");
                   1641:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   1642:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   1643: 
                   1644:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                   1645:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
1.1       root     1646: 
1.1.1.3   root     1647:    iop = ppc32_op_emit_insn_output(cpu,1,"cmp");
                   1648: 
                   1649:    x86_alu_reg_reg(iop->ob_ptr,X86_CMP,hreg_ra,hreg_rb);
                   1650:    ppc32_op_emit_update_flags(cpu,rd,TRUE);
                   1651: 
                   1652:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1653:    return(0);
                   1654: }
                   1655: 
                   1656: /* CMPI - Compare Immediate */
                   1657: DECLARE_INSN(CMPI)
                   1658: {
                   1659:    int rd = bits(insn,23,25);
                   1660:    int ra = bits(insn,16,20);
                   1661:    m_uint16_t imm = bits(insn,0,15);
                   1662:    m_uint32_t tmp = sign_extend_32(imm,16);
1.1.1.3   root     1663:    int hreg_ra;
                   1664:    jit_op_t *iop;
                   1665: 
                   1666:    ppc32_jit_start_hreg_seq(cpu,"cmpi");
                   1667:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   1668:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                   1669: 
                   1670:    iop = ppc32_op_emit_insn_output(cpu,1,"cmpi");
1.1       root     1671: 
1.1.1.3   root     1672:    x86_alu_reg_imm(iop->ob_ptr,X86_CMP,hreg_ra,tmp);
                   1673:    ppc32_op_emit_update_flags(cpu,rd,TRUE);
1.1       root     1674: 
1.1.1.3   root     1675:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1676:    return(0);
                   1677: }
                   1678: 
                   1679: /* CMPL - Compare Logical */
                   1680: DECLARE_INSN(CMPL)
                   1681: {
                   1682:    int rd = bits(insn,23,25);
                   1683:    int ra = bits(insn,16,20);
                   1684:    int rb = bits(insn,11,15);
1.1.1.3   root     1685:    int hreg_ra,hreg_rb;
                   1686:    jit_op_t *iop;
                   1687:    
                   1688:    ppc32_jit_start_hreg_seq(cpu,"cmpl");
                   1689:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   1690:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   1691: 
                   1692:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                   1693:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                   1694: 
                   1695:    iop = ppc32_op_emit_insn_output(cpu,1,"cmpl");
1.1       root     1696: 
1.1.1.3   root     1697:    x86_alu_reg_reg(iop->ob_ptr,X86_CMP,hreg_ra,hreg_rb);
                   1698:    ppc32_op_emit_update_flags(cpu,rd,FALSE);
                   1699: 
                   1700:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1701:    return(0);
                   1702: }
                   1703: 
                   1704: /* CMPLI - Compare Immediate */
                   1705: DECLARE_INSN(CMPLI)
                   1706: {
                   1707:    int rd = bits(insn,23,25);
                   1708:    int ra = bits(insn,16,20);
1.1.1.3   root     1709:    m_uint32_t imm = bits(insn,0,15);
                   1710:    int hreg_ra;
                   1711:    jit_op_t *iop;
                   1712: 
                   1713:    ppc32_jit_start_hreg_seq(cpu,"cmpli");
                   1714:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   1715:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1.1       root     1716: 
1.1.1.3   root     1717:    iop = ppc32_op_emit_insn_output(cpu,1,"cmpli");
1.1       root     1718: 
1.1.1.3   root     1719:    x86_alu_reg_imm(iop->ob_ptr,X86_CMP,hreg_ra,imm);
                   1720:    ppc32_op_emit_update_flags(cpu,rd,FALSE);
                   1721: 
                   1722:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1723:    return(0);
                   1724: }
                   1725: 
                   1726: /* CRAND - Condition Register AND */
                   1727: DECLARE_INSN(CRAND)
                   1728: {
                   1729:    int bd = bits(insn,21,25);
                   1730:    int bb = bits(insn,16,20);
                   1731:    int ba = bits(insn,11,15);
1.1.1.3   root     1732:    int hreg_t0;
                   1733:    jit_op_t *iop;
                   1734: 
                   1735:    ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
                   1736: 
                   1737:    ppc32_jit_start_hreg_seq(cpu,"crand");
                   1738:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   1739:    ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
                   1740: 
                   1741:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
                   1742:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
                   1743:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
                   1744: 
                   1745:    iop = ppc32_op_emit_insn_output(cpu,3,"crand");
1.1       root     1746: 
                   1747:    /* test $ba bit */
1.1.1.3   root     1748:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     1749:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
                   1750:                         (1 << ppc32_get_cr_bit(ba)));
1.1.1.3   root     1751:    x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
1.1       root     1752: 
                   1753:    /* test $bb bit */
1.1.1.3   root     1754:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     1755:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
                   1756:                         (1 << ppc32_get_cr_bit(bb)));
1.1.1.3   root     1757:    x86_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
1.1       root     1758:    
                   1759:    /* result of AND between $ba and $bb */
1.1.1.3   root     1760:    x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,X86_EDX);
                   1761:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1       root     1762:    
                   1763:    /* set/clear $bd bit depending on the result */
1.1.1.3   root     1764:    x86_alu_membase_imm(iop->ob_ptr,X86_AND,
1.1.1.2   root     1765:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
                   1766:                        ~(1 << ppc32_get_cr_bit(bd)));
                   1767: 
1.1.1.3   root     1768:    x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
                   1769:    x86_alu_membase_reg(iop->ob_ptr,X86_OR,
1.1.1.2   root     1770:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3   root     1771:                        hreg_t0);
                   1772: 
                   1773:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1774:    return(0);
                   1775: }
                   1776: 
                   1777: /* CRANDC - Condition Register AND with Complement */
                   1778: DECLARE_INSN(CRANDC)
                   1779: {
                   1780:    int bd = bits(insn,21,25);
                   1781:    int bb = bits(insn,16,20);
                   1782:    int ba = bits(insn,11,15);
1.1.1.3   root     1783:    int hreg_t0;
                   1784:    jit_op_t *iop;
                   1785: 
                   1786:    ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
                   1787: 
                   1788:    ppc32_jit_start_hreg_seq(cpu,"crandc");
                   1789:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   1790:    ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
                   1791: 
                   1792:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
                   1793:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
                   1794:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
                   1795: 
                   1796:    iop = ppc32_op_emit_insn_output(cpu,3,"crandc");
1.1       root     1797: 
                   1798:    /* test $ba bit */
1.1.1.3   root     1799:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     1800:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
                   1801:                         (1 << ppc32_get_cr_bit(ba)));
1.1.1.3   root     1802:    x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
1.1       root     1803: 
                   1804:    /* test $bb bit */
1.1.1.3   root     1805:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     1806:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
                   1807:                         (1 << ppc32_get_cr_bit(bb)));
1.1.1.3   root     1808:    x86_set_reg(iop->ob_ptr,X86_CC_Z,hreg_t0,FALSE);
1.1       root     1809:    
                   1810:    /* result of AND between $ba and $bb */
1.1.1.3   root     1811:    x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,X86_EDX);
                   1812:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1       root     1813:    
                   1814:    /* set/clear $bd bit depending on the result */
1.1.1.3   root     1815:    x86_alu_membase_imm(iop->ob_ptr,X86_AND,
1.1.1.2   root     1816:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
                   1817:                        ~(1 << ppc32_get_cr_bit(bd)));
                   1818: 
1.1.1.3   root     1819:    x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
                   1820:    x86_alu_membase_reg(iop->ob_ptr,X86_OR,
1.1.1.2   root     1821:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3   root     1822:                        hreg_t0);
                   1823: 
                   1824:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1825:    return(0);
                   1826: }
                   1827: 
                   1828: /* CREQV - Condition Register EQV */
                   1829: DECLARE_INSN(CREQV)
                   1830: {
                   1831:    int bd = bits(insn,21,25);
                   1832:    int bb = bits(insn,16,20);
                   1833:    int ba = bits(insn,11,15);
1.1.1.3   root     1834:    int hreg_t0;
                   1835:    jit_op_t *iop;
                   1836: 
                   1837:    ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
                   1838: 
                   1839:    ppc32_jit_start_hreg_seq(cpu,"creqv");
                   1840:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   1841:    ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
                   1842: 
                   1843:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
                   1844:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
                   1845:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
                   1846: 
                   1847:    iop = ppc32_op_emit_insn_output(cpu,3,"creqv");
1.1       root     1848: 
                   1849:    /* test $ba bit */
1.1.1.3   root     1850:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     1851:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
                   1852:                         (1 << ppc32_get_cr_bit(ba)));
1.1.1.3   root     1853:    x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
1.1       root     1854: 
                   1855:    /* test $bb bit */
1.1.1.3   root     1856:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     1857:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
                   1858:                         (1 << ppc32_get_cr_bit(bb)));
1.1.1.3   root     1859:    x86_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
1.1       root     1860:    
                   1861:    /* result of XOR between $ba and $bb */
1.1.1.3   root     1862:    x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t0,X86_EDX);
                   1863:    x86_not_reg(iop->ob_ptr,hreg_t0);
                   1864:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1       root     1865:    
                   1866:    /* set/clear $bd bit depending on the result */
1.1.1.3   root     1867:    x86_alu_membase_imm(iop->ob_ptr,X86_AND,
1.1.1.2   root     1868:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
                   1869:                        ~(1 << ppc32_get_cr_bit(bd)));
                   1870: 
1.1.1.3   root     1871:    x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
                   1872:    x86_alu_membase_reg(iop->ob_ptr,X86_OR,
1.1.1.2   root     1873:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3   root     1874:                        hreg_t0);
                   1875: 
                   1876:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1877:    return(0);
                   1878: }
                   1879: 
                   1880: /* CRNAND - Condition Register NAND */
                   1881: DECLARE_INSN(CRNAND)
                   1882: {
                   1883:    int bd = bits(insn,21,25);
                   1884:    int bb = bits(insn,16,20);
                   1885:    int ba = bits(insn,11,15);
1.1.1.3   root     1886:    int hreg_t0;
                   1887:    jit_op_t *iop;
                   1888: 
                   1889:    ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
                   1890: 
                   1891:    ppc32_jit_start_hreg_seq(cpu,"crnand");
                   1892:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   1893:    ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
                   1894: 
                   1895:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
                   1896:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
                   1897:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
                   1898: 
                   1899:    iop = ppc32_op_emit_insn_output(cpu,3,"crnand");
1.1       root     1900: 
                   1901:    /* test $ba bit */
1.1.1.3   root     1902:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     1903:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
                   1904:                         (1 << ppc32_get_cr_bit(ba)));
1.1.1.3   root     1905:    x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
1.1       root     1906: 
                   1907:    /* test $bb bit */
1.1.1.3   root     1908:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     1909:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
                   1910:                         (1 << ppc32_get_cr_bit(bb)));
1.1.1.3   root     1911:    x86_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
1.1       root     1912:    
                   1913:    /* result of NAND between $ba and $bb */
1.1.1.3   root     1914:    x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,X86_EDX);
                   1915:    x86_not_reg(iop->ob_ptr,hreg_t0);
                   1916:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1       root     1917:    
                   1918:    /* set/clear $bd bit depending on the result */
1.1.1.3   root     1919:    x86_alu_membase_imm(iop->ob_ptr,X86_AND,
1.1.1.2   root     1920:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
                   1921:                        ~(1 << ppc32_get_cr_bit(bd)));
                   1922: 
1.1.1.3   root     1923:    x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
                   1924:    x86_alu_membase_reg(iop->ob_ptr,X86_OR,
1.1.1.2   root     1925:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3   root     1926:                        hreg_t0);
                   1927: 
                   1928:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1929:    return(0);
                   1930: }
                   1931: 
                   1932: /* CRNOR - Condition Register NOR */
                   1933: DECLARE_INSN(CRNOR)
                   1934: {
                   1935:    int bd = bits(insn,21,25);
                   1936:    int bb = bits(insn,16,20);
                   1937:    int ba = bits(insn,11,15);
1.1.1.3   root     1938:    int hreg_t0;
                   1939:    jit_op_t *iop;
                   1940: 
                   1941:    ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
                   1942: 
                   1943:    ppc32_jit_start_hreg_seq(cpu,"crnor");
                   1944:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   1945:    ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
                   1946: 
                   1947:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
                   1948:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
                   1949:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
                   1950: 
                   1951:    iop = ppc32_op_emit_insn_output(cpu,3,"crnor");
1.1       root     1952: 
                   1953:    /* test $ba bit */
1.1.1.3   root     1954:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     1955:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
                   1956:                         (1 << ppc32_get_cr_bit(ba)));
1.1.1.3   root     1957:    x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
1.1       root     1958: 
                   1959:    /* test $bb bit */
1.1.1.3   root     1960:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     1961:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
                   1962:                         (1 << ppc32_get_cr_bit(bb)));
1.1.1.3   root     1963:    x86_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
1.1       root     1964:    
                   1965:    /* result of NOR between $ba and $bb */
1.1.1.3   root     1966:    x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_t0,X86_EDX);
                   1967:    x86_not_reg(iop->ob_ptr,hreg_t0);
                   1968:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1       root     1969:    
                   1970:    /* set/clear $bd bit depending on the result */
1.1.1.3   root     1971:    x86_alu_membase_imm(iop->ob_ptr,X86_AND,
1.1.1.2   root     1972:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
                   1973:                        ~(1 << ppc32_get_cr_bit(bd)));
                   1974: 
1.1.1.3   root     1975:    x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
                   1976:    x86_alu_membase_reg(iop->ob_ptr,X86_OR,
1.1.1.2   root     1977:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3   root     1978:                        hreg_t0);
                   1979: 
                   1980:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     1981:    return(0);
                   1982: }
                   1983: 
                   1984: /* CROR - Condition Register OR */
                   1985: DECLARE_INSN(CROR)
                   1986: {
                   1987:    int bd = bits(insn,21,25);
                   1988:    int bb = bits(insn,16,20);
                   1989:    int ba = bits(insn,11,15);
1.1.1.3   root     1990:    int hreg_t0;
                   1991:    jit_op_t *iop;
                   1992: 
                   1993:    ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
                   1994: 
                   1995:    ppc32_jit_start_hreg_seq(cpu,"cror");
                   1996:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   1997:    ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
                   1998: 
                   1999:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
                   2000:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
                   2001:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
                   2002: 
                   2003:    iop = ppc32_op_emit_insn_output(cpu,3,"cror");
1.1       root     2004: 
                   2005:    /* test $ba bit */
1.1.1.3   root     2006:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     2007:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
                   2008:                         (1 << ppc32_get_cr_bit(ba)));
1.1.1.3   root     2009:    x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
1.1       root     2010: 
                   2011:    /* test $bb bit */
1.1.1.3   root     2012:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     2013:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
                   2014:                         (1 << ppc32_get_cr_bit(bb)));
1.1.1.3   root     2015:    x86_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
1.1       root     2016:    
                   2017:    /* result of OR between $ba and $bb */
1.1.1.3   root     2018:    x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_t0,X86_EDX);
                   2019:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1       root     2020:    
                   2021:    /* set/clear $bd bit depending on the result */
1.1.1.3   root     2022:    x86_alu_membase_imm(iop->ob_ptr,X86_AND,
1.1.1.2   root     2023:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
                   2024:                        ~(1 << ppc32_get_cr_bit(bd)));
                   2025: 
1.1.1.3   root     2026:    x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
                   2027:    x86_alu_membase_reg(iop->ob_ptr,X86_OR,
1.1.1.2   root     2028:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3   root     2029:                        hreg_t0);
                   2030: 
                   2031:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2032:    return(0);
                   2033: }
                   2034: 
                   2035: /* CRORC - Condition Register OR with Complement */
                   2036: DECLARE_INSN(CRORC)
                   2037: {
                   2038:    int bd = bits(insn,21,25);
                   2039:    int bb = bits(insn,16,20);
                   2040:    int ba = bits(insn,11,15);
1.1.1.3   root     2041:    int hreg_t0;
                   2042:    jit_op_t *iop;
                   2043: 
                   2044:    ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
                   2045: 
                   2046:    ppc32_jit_start_hreg_seq(cpu,"crorc");
                   2047:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   2048:    ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
                   2049: 
                   2050:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
                   2051:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
                   2052:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
                   2053: 
                   2054:    iop = ppc32_op_emit_insn_output(cpu,3,"crorc");
1.1       root     2055: 
                   2056:    /* test $ba bit */
1.1.1.3   root     2057:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     2058:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
                   2059:                         (1 << ppc32_get_cr_bit(ba)));
1.1.1.3   root     2060:    x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
1.1       root     2061: 
                   2062:    /* test $bb bit */
1.1.1.3   root     2063:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     2064:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
                   2065:                         (1 << ppc32_get_cr_bit(bb)));
1.1.1.3   root     2066:    x86_set_reg(iop->ob_ptr,X86_CC_Z,hreg_t0,FALSE);
1.1       root     2067:    
                   2068:    /* result of ORC between $ba and $bb */
1.1.1.3   root     2069:    x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_t0,X86_EDX);
                   2070:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1       root     2071:    
                   2072:    /* set/clear $bd bit depending on the result */
1.1.1.3   root     2073:    x86_alu_membase_imm(iop->ob_ptr,X86_AND,
1.1.1.2   root     2074:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
                   2075:                        ~(1 << ppc32_get_cr_bit(bd)));
                   2076: 
1.1.1.3   root     2077:    x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
                   2078:    x86_alu_membase_reg(iop->ob_ptr,X86_OR,
1.1.1.2   root     2079:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3   root     2080:                        hreg_t0);
                   2081: 
                   2082:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2083:    return(0);
                   2084: }
                   2085: 
                   2086: /* CRXOR - Condition Register XOR */
                   2087: DECLARE_INSN(CRXOR)
                   2088: {
                   2089:    int bd = bits(insn,21,25);
                   2090:    int bb = bits(insn,16,20);
                   2091:    int ba = bits(insn,11,15);
1.1.1.3   root     2092:    int hreg_t0;
                   2093:    jit_op_t *iop;
                   2094: 
                   2095:    ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
                   2096: 
                   2097:    ppc32_jit_start_hreg_seq(cpu,"crxor");
                   2098:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   2099:    ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
                   2100: 
                   2101:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
                   2102:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
                   2103:    ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
                   2104: 
                   2105:    iop = ppc32_op_emit_insn_output(cpu,3,"crxor");
1.1       root     2106: 
                   2107:    /* test $ba bit */
1.1.1.3   root     2108:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     2109:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
                   2110:                         (1 << ppc32_get_cr_bit(ba)));
1.1.1.3   root     2111:    x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
1.1       root     2112: 
                   2113:    /* test $bb bit */
1.1.1.3   root     2114:    x86_test_membase_imm(iop->ob_ptr,
1.1.1.2   root     2115:                         X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
                   2116:                         (1 << ppc32_get_cr_bit(bb)));
1.1.1.3   root     2117:    x86_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
1.1       root     2118:    
                   2119:    /* result of XOR between $ba and $bb */
1.1.1.3   root     2120:    x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t0,X86_EDX);
                   2121:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1       root     2122:    
                   2123:    /* set/clear $bd bit depending on the result */
1.1.1.3   root     2124:    x86_alu_membase_imm(iop->ob_ptr,X86_AND,
1.1.1.2   root     2125:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
                   2126:                        ~(1 << ppc32_get_cr_bit(bd)));
                   2127: 
1.1.1.3   root     2128:    x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
                   2129:    x86_alu_membase_reg(iop->ob_ptr,X86_OR,
1.1.1.2   root     2130:                        X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3   root     2131:                        hreg_t0);
                   2132: 
                   2133:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2134:    return(0);
                   2135: }
                   2136: 
                   2137: /* DIVWU - Divide Word Unsigned */
                   2138: DECLARE_INSN(DIVWU)
                   2139: {
                   2140:    int rd = bits(insn,21,25);
                   2141:    int ra = bits(insn,16,20);
                   2142:    int rb = bits(insn,11,15);
1.1.1.3   root     2143:    int hreg_rb;
                   2144:    jit_op_t *iop;
1.1       root     2145: 
1.1.1.3   root     2146:    ppc32_jit_start_hreg_seq(cpu,"divwu");
                   2147:    ppc32_jit_alloc_hreg_forced(cpu,X86_EAX);
                   2148:    ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
                   2149:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   2150: 
                   2151:    /* $rd = $ra / $rb */
                   2152:    ppc32_op_emit_load_gpr(cpu,X86_EAX,ra);
                   2153:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
1.1       root     2154: 
1.1.1.3   root     2155:    iop = ppc32_op_emit_insn_output(cpu,2,"divwu");
                   2156:    ppc32_load_imm(&iop->ob_ptr,X86_EDX,0);
1.1       root     2157: 
1.1.1.3   root     2158:    x86_div_reg(iop->ob_ptr,hreg_rb,0);
                   2159: 
                   2160:    if (insn & 1)
                   2161:       x86_test_reg_reg(iop->ob_ptr,X86_EAX,X86_EAX);
                   2162: 
                   2163:    ppc32_op_emit_store_gpr(cpu,rd,X86_EAX);
                   2164: 
                   2165:    if (insn & 1)
                   2166:       ppc32_op_emit_update_flags(cpu,0,TRUE);
                   2167: 
                   2168:    /* edx:eax are directly modified: throw them */
                   2169:    ppc32_op_emit_alter_host_reg(cpu,X86_EAX);
                   2170:    ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
                   2171: 
                   2172:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2173:    return(0);
                   2174: }
                   2175: 
                   2176: /* EQV */
                   2177: DECLARE_INSN(EQV)
                   2178: {
                   2179:    int rs = bits(insn,21,25);
                   2180:    int ra = bits(insn,16,20);
                   2181:    int rb = bits(insn,11,15);
1.1.1.3   root     2182:    int hreg_rs,hreg_ra,hreg_rb;
                   2183:    jit_op_t *iop;
1.1       root     2184: 
                   2185:    /* $ra = ~($rs ^ $rb) */
1.1.1.3   root     2186:    ppc32_jit_start_hreg_seq(cpu,"eqv");
                   2187:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   2188:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   2189:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   2190: 
                   2191:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   2192:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                   2193: 
                   2194:    iop = ppc32_op_emit_insn_output(cpu,1,"eqv");
                   2195: 
                   2196:    if (ra == rs)
                   2197:       x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rb);
                   2198:    else if (ra == rb)
                   2199:       x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rs);
                   2200:    else {
                   2201:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
                   2202:       x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rb);
1.1       root     2203:    }
                   2204: 
1.1.1.3   root     2205:    x86_not_reg(iop->ob_ptr,hreg_ra);
                   2206: 
                   2207:    if (insn & 1)
                   2208:       x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
                   2209: 
                   2210:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   2211: 
                   2212:    if (insn & 1)
                   2213:       ppc32_op_emit_update_flags(cpu,0,TRUE);
                   2214: 
                   2215:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2216:    return(0);
                   2217: }
                   2218: 
                   2219: /* EXTSB - Extend Sign Byte */
                   2220: DECLARE_INSN(EXTSB)
                   2221: {   
                   2222:    int rs = bits(insn,21,25);
                   2223:    int ra = bits(insn,16,20);
1.1.1.3   root     2224:    int hreg_rs,hreg_ra;
                   2225:    jit_op_t *iop;
1.1       root     2226: 
1.1.1.3   root     2227:    /* $ra = extsb($rs) */
                   2228:    ppc32_jit_start_hreg_seq(cpu,"extsb");
                   2229:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   2230:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1.1       root     2231: 
1.1.1.3   root     2232:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   2233: 
                   2234:    iop = ppc32_op_emit_insn_output(cpu,2,"extsb");
                   2235: 
                   2236:    if (rs != ra)
                   2237:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
                   2238: 
                   2239:    x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_ra,24);
                   2240:    x86_shift_reg_imm(iop->ob_ptr,X86_SAR,hreg_ra,24);
1.1       root     2241: 
1.1.1.3   root     2242:    if (insn & 1)
                   2243:       x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
                   2244: 
                   2245:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   2246: 
                   2247:    if (insn & 1)
                   2248:       ppc32_op_emit_update_flags(cpu,0,TRUE);
                   2249: 
                   2250:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2251:    return(0);
                   2252: }
                   2253: 
                   2254: /* EXTSH - Extend Sign Word */
                   2255: DECLARE_INSN(EXTSH)
                   2256: {   
                   2257:    int rs = bits(insn,21,25);
                   2258:    int ra = bits(insn,16,20);
1.1.1.3   root     2259:    int hreg_rs,hreg_ra;
                   2260:    jit_op_t *iop;
1.1       root     2261: 
1.1.1.3   root     2262:    /* $ra = extsh($rs) */
                   2263:    ppc32_jit_start_hreg_seq(cpu,"extsh");
                   2264:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   2265:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1.1       root     2266: 
1.1.1.3   root     2267:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   2268: 
                   2269:    iop = ppc32_op_emit_insn_output(cpu,2,"extsh");
                   2270: 
                   2271:    if (rs != ra)
                   2272:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
                   2273: 
                   2274:    x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_ra,16);
                   2275:    x86_shift_reg_imm(iop->ob_ptr,X86_SAR,hreg_ra,16);
                   2276: 
                   2277:    if (insn & 1)
                   2278:       x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
                   2279: 
                   2280:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   2281: 
                   2282:    if (insn & 1)
                   2283:       ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1       root     2284: 
1.1.1.3   root     2285:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2286:    return(0);
                   2287: }
                   2288: 
                   2289: /* LBZ - Load Byte and Zero */
                   2290: DECLARE_INSN(LBZ)
                   2291: {
                   2292:    int rs = bits(insn,21,25);
                   2293:    int ra = bits(insn,16,20);
                   2294:    m_uint16_t offset = bits(insn,0,15);
                   2295: 
1.1.1.3   root     2296:    //ppc32_emit_memop(cpu,b,PPC_MEMOP_LBZ,ra,offset,rs,0);
                   2297:    ppc32_emit_memop_fast(cpu,b,0,PPC_MEMOP_LBZ,ra,offset,rs,
                   2298:                          ppc32_memop_fast_lbz);
1.1       root     2299:    return(0);
                   2300: }
                   2301: 
                   2302: /* LBZU - Load Byte and Zero with Update */
                   2303: DECLARE_INSN(LBZU)
                   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: 
1.1.1.3   root     2309:    ppc32_emit_memop(cpu,b,PPC_MEMOP_LBZ,ra,offset,rs,1);
1.1       root     2310:    return(0);
                   2311: }
                   2312: 
                   2313: /* LBZUX - Load Byte and Zero with Update Indexed */
                   2314: DECLARE_INSN(LBZUX)
                   2315: {
                   2316:    int rs = bits(insn,21,25);
                   2317:    int ra = bits(insn,16,20);
                   2318:    int rb = bits(insn,11,15);
                   2319: 
1.1.1.3   root     2320:    ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LBZ,ra,rb,rs,1);
1.1       root     2321:    return(0);
                   2322: }
                   2323: 
                   2324: /* LBZX - Load Byte and Zero Indexed */
                   2325: DECLARE_INSN(LBZX)
                   2326: {
                   2327:    int rs = bits(insn,21,25);
                   2328:    int ra = bits(insn,16,20);
                   2329:    int rb = bits(insn,11,15);
                   2330: 
1.1.1.3   root     2331:    ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LBZ,ra,rb,rs,0);
1.1       root     2332:    return(0);
                   2333: }
                   2334: 
                   2335: /* LHA - Load Half-Word Algebraic */
                   2336: DECLARE_INSN(LHA)
                   2337: {
                   2338:    int rs = bits(insn,21,25);
                   2339:    int ra = bits(insn,16,20);
                   2340:    m_uint16_t offset = bits(insn,0,15);
                   2341: 
1.1.1.3   root     2342:    ppc32_emit_memop(cpu,b,PPC_MEMOP_LHA,ra,offset,rs,0);
1.1       root     2343:    return(0);
                   2344: }
                   2345: 
                   2346: /* LHAU - Load Half-Word Algebraic with Update */
                   2347: DECLARE_INSN(LHAU)
                   2348: {
                   2349:    int rs = bits(insn,21,25);
                   2350:    int ra = bits(insn,16,20);
                   2351:    m_uint16_t offset = bits(insn,0,15);
                   2352: 
1.1.1.3   root     2353:    ppc32_emit_memop(cpu,b,PPC_MEMOP_LHA,ra,offset,rs,1);
1.1       root     2354:    return(0);
                   2355: }
                   2356: 
                   2357: /* LHAUX - Load Half-Word Algebraic with Update Indexed */
                   2358: DECLARE_INSN(LHAUX)
                   2359: {
                   2360:    int rs = bits(insn,21,25);
                   2361:    int ra = bits(insn,16,20);
                   2362:    int rb = bits(insn,11,15);
                   2363: 
1.1.1.3   root     2364:    ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LHA,ra,rb,rs,1);
1.1       root     2365:    return(0);
                   2366: }
                   2367: 
                   2368: /* LHAX - Load Half-Word Algebraic Indexed */
                   2369: DECLARE_INSN(LHAX)
                   2370: {
                   2371:    int rs = bits(insn,21,25);
                   2372:    int ra = bits(insn,16,20);
                   2373:    int rb = bits(insn,11,15);
                   2374: 
1.1.1.3   root     2375:    ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LHA,ra,rb,rs,0);
1.1       root     2376:    return(0);
                   2377: }
                   2378: 
                   2379: /* LHZ - Load Half-Word and Zero */
                   2380: DECLARE_INSN(LHZ)
                   2381: {
                   2382:    int rs = bits(insn,21,25);
                   2383:    int ra = bits(insn,16,20);
                   2384:    m_uint16_t offset = bits(insn,0,15);
                   2385: 
1.1.1.3   root     2386:    ppc32_emit_memop(cpu,b,PPC_MEMOP_LHZ,ra,offset,rs,0);
1.1       root     2387:    return(0);
                   2388: }
                   2389: 
                   2390: /* LHZU - Load Half-Word and Zero with Update */
                   2391: DECLARE_INSN(LHZU)
                   2392: {
                   2393:    int rs = bits(insn,21,25);
                   2394:    int ra = bits(insn,16,20);
                   2395:    m_uint16_t offset = bits(insn,0,15);
                   2396: 
1.1.1.3   root     2397:    ppc32_emit_memop(cpu,b,PPC_MEMOP_LHZ,ra,offset,rs,1);
1.1       root     2398:    return(0);
                   2399: }
                   2400: 
                   2401: /* LHZUX - Load Half-Word and Zero with Update Indexed */
                   2402: DECLARE_INSN(LHZUX)
                   2403: {
                   2404:    int rs = bits(insn,21,25);
                   2405:    int ra = bits(insn,16,20);
                   2406:    int rb = bits(insn,11,15);
                   2407: 
1.1.1.3   root     2408:    ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LHZ,ra,rb,rs,1);
1.1       root     2409:    return(0);
                   2410: }
                   2411: 
                   2412: /* LHZX - Load Half-Word and Zero Indexed */
                   2413: DECLARE_INSN(LHZX)
                   2414: {
                   2415:    int rs = bits(insn,21,25);
                   2416:    int ra = bits(insn,16,20);
                   2417:    int rb = bits(insn,11,15);
                   2418: 
1.1.1.3   root     2419:    ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LHZ,ra,rb,rs,0);
1.1       root     2420:    return(0);
                   2421: }
                   2422: 
                   2423: /* LWZ - Load Word and Zero */
                   2424: DECLARE_INSN(LWZ)
                   2425: {
                   2426:    int rs = bits(insn,21,25);
                   2427:    int ra = bits(insn,16,20);
                   2428:    m_uint16_t offset = bits(insn,0,15);
                   2429: 
                   2430:    //ppc32_emit_memop(b,PPC_MEMOP_LWZ,ra,offset,rs,0);
1.1.1.3   root     2431:    ppc32_emit_memop_fast(cpu,b,0,PPC_MEMOP_LWZ,ra,offset,rs,
                   2432:                          ppc32_memop_fast_lwz);
1.1       root     2433:    return(0);
                   2434: }
                   2435: 
                   2436: /* LWZU - Load Word and Zero with Update */
                   2437: DECLARE_INSN(LWZU)
                   2438: {
                   2439:    int rs = bits(insn,21,25);
                   2440:    int ra = bits(insn,16,20);
                   2441:    m_uint16_t offset = bits(insn,0,15);
                   2442: 
1.1.1.3   root     2443:    ppc32_emit_memop(cpu,b,PPC_MEMOP_LWZ,ra,offset,rs,1);
1.1       root     2444:    return(0);
                   2445: }
                   2446: 
                   2447: /* LWZUX - Load Word and Zero with Update Indexed */
                   2448: DECLARE_INSN(LWZUX)
                   2449: {
                   2450:    int rs = bits(insn,21,25);
                   2451:    int ra = bits(insn,16,20);
                   2452:    int rb = bits(insn,11,15);
                   2453: 
1.1.1.3   root     2454:    ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LWZ,ra,rb,rs,1);
1.1       root     2455:    return(0);
                   2456: }
                   2457: 
                   2458: /* LWZX - Load Word and Zero Indexed */
                   2459: DECLARE_INSN(LWZX)
                   2460: {
                   2461:    int rs = bits(insn,21,25);
                   2462:    int ra = bits(insn,16,20);
                   2463:    int rb = bits(insn,11,15);
                   2464: 
1.1.1.3   root     2465:    ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LWZ,ra,rb,rs,0);
1.1       root     2466:    return(0);
                   2467: }
                   2468: 
                   2469: /* MCRF - Move Condition Register Field */
                   2470: DECLARE_INSN(MCRF)
                   2471: {
                   2472:    int rd = bits(insn,23,25);
                   2473:    int rs = bits(insn,18,20);
1.1.1.3   root     2474:    int hreg_t0;
                   2475:    jit_op_t *iop;
                   2476: 
                   2477:    ppc32_jit_start_hreg_seq(cpu,"mcrf");
                   2478:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);   
                   2479:    ppc32_op_emit_require_flags(cpu,rs);
                   2480: 
                   2481:    iop = ppc32_op_emit_insn_output(cpu,1,"mcrf");
1.1       root     2482: 
1.1.1.2   root     2483:    /* Load "rs" field in %edx */
1.1.1.3   root     2484:    x86_mov_reg_membase(iop->ob_ptr,hreg_t0,
                   2485:                        X86_EDI,PPC32_CR_FIELD_OFFSET(rs),4);
1.1.1.2   root     2486: 
                   2487:    /* Store it in "rd" field */
1.1.1.3   root     2488:    x86_mov_membase_reg(iop->ob_ptr,X86_EDI,PPC32_CR_FIELD_OFFSET(rd),
                   2489:                        hreg_t0,4);
                   2490: 
                   2491:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2492:    return(0);
                   2493: }
                   2494: 
                   2495: /* MFCR - Move from Condition Register */
                   2496: DECLARE_INSN(MFCR)
                   2497: {
                   2498:    int rd = bits(insn,21,25);
1.1.1.3   root     2499:    int hreg_rd,hreg_t0;
                   2500:    jit_op_t *iop;
1.1.1.2   root     2501:    int i;
                   2502: 
1.1.1.3   root     2503:    ppc32_jit_start_hreg_seq(cpu,"mfcr");
                   2504:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                   2505:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   2506:    ppc32_op_emit_require_flags(cpu,JIT_OP_PPC_ALL_FLAGS);
                   2507: 
                   2508:    iop = ppc32_op_emit_insn_output(cpu,3,"mfcr");
                   2509: 
                   2510:    x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_rd,hreg_rd);
1.1.1.2   root     2511: 
                   2512:    for(i=0;i<8;i++) {
                   2513:       /* load field in %edx */
1.1.1.3   root     2514:       x86_mov_reg_membase(iop->ob_ptr,hreg_t0,
1.1.1.2   root     2515:                           X86_EDI,PPC32_CR_FIELD_OFFSET(i),4);
1.1.1.3   root     2516:       x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_rd,4);
                   2517:       x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_rd,hreg_t0);
1.1.1.2   root     2518:    }
1.1       root     2519: 
1.1.1.3   root     2520:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
                   2521: 
                   2522:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2523:    return(0);
                   2524: }
                   2525: 
                   2526: /* MFMSR - Move from Machine State Register */
                   2527: DECLARE_INSN(MFMSR)
                   2528: {
                   2529:    int rd = bits(insn,21,25);
1.1.1.3   root     2530:    int hreg_rd;
                   2531:    jit_op_t *iop;
                   2532: 
                   2533:    ppc32_jit_start_hreg_seq(cpu,"mfmsr");
                   2534:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                   2535: 
                   2536:    iop = ppc32_op_emit_insn_output(cpu,1,"mfmsr");
                   2537:    x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,msr),4);
                   2538:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1.1       root     2539: 
1.1.1.3   root     2540:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2541:    return(0);
                   2542: }
                   2543: 
                   2544: /* MFSR - Move From Segment Register */
                   2545: DECLARE_INSN(MFSR)
                   2546: {
                   2547:    int rd = bits(insn,21,25);
                   2548:    int sr = bits(insn,16,19);
1.1.1.3   root     2549:    int hreg_rd;
                   2550:    jit_op_t *iop;
1.1       root     2551: 
1.1.1.3   root     2552:    ppc32_jit_start_hreg_seq(cpu,"mfsr");
                   2553:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                   2554: 
                   2555:    iop = ppc32_op_emit_insn_output(cpu,1,"mfsr");
                   2556: 
                   2557:    x86_mov_reg_membase(iop->ob_ptr,hreg_rd,
1.1       root     2558:                        X86_EDI,(OFFSET(cpu_ppc_t,sr) + (sr << 2)),4);
1.1.1.3   root     2559:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
                   2560: 
                   2561:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2562:    return(0);
                   2563: }
                   2564: 
                   2565: /* MTCRF - Move to Condition Register Fields */
                   2566: DECLARE_INSN(MTCRF)
                   2567: {
                   2568:    int rs = bits(insn,21,25);
                   2569:    int crm = bits(insn,12,19);
1.1.1.3   root     2570:    int hreg_rs,hreg_t0;
                   2571:    jit_op_t *iop;
1.1       root     2572:    int i;
                   2573: 
1.1.1.3   root     2574:    ppc32_jit_start_hreg_seq(cpu,"mtcrf");
                   2575:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   2576:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   2577: 
                   2578:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   2579: 
                   2580:    iop = ppc32_op_emit_insn_output(cpu,3,"mtcrf");
1.1.1.2   root     2581: 
1.1       root     2582:    for(i=0;i<8;i++)
1.1.1.2   root     2583:       if (crm & (1 << (7 - i))) {
1.1.1.3   root     2584:          x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
1.1       root     2585: 
1.1.1.2   root     2586:          if (i != 7)
1.1.1.3   root     2587:             x86_shift_reg_imm(iop->ob_ptr,X86_SHR,hreg_t0,28 - (i << 2));
1.1       root     2588: 
1.1.1.3   root     2589:          x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x0F);
                   2590:          x86_mov_membase_reg(iop->ob_ptr,X86_EDI,PPC32_CR_FIELD_OFFSET(i),
                   2591:                              hreg_t0,4);
1.1.1.2   root     2592:       }
1.1       root     2593: 
1.1.1.3   root     2594:    ppc32_op_emit_basic_opcode(cpu,JIT_OP_TRASH_FLAGS);
                   2595: 
                   2596:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2597:    return(0);
                   2598: }
                   2599: 
                   2600: /* MULHW - Multiply High Word */
                   2601: DECLARE_INSN(MULHW)
                   2602: {
                   2603:    int rd = bits(insn,21,25);
                   2604:    int ra = bits(insn,16,20);
                   2605:    int rb = bits(insn,11,15);
1.1.1.3   root     2606:    int hreg_rb;
                   2607:    jit_op_t *iop;
1.1       root     2608: 
1.1.1.3   root     2609:    ppc32_jit_start_hreg_seq(cpu,"mulhw");
                   2610:    ppc32_jit_alloc_hreg_forced(cpu,X86_EAX);
                   2611:    ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
                   2612:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   2613: 
                   2614:    ppc32_op_emit_load_gpr(cpu,X86_EAX,ra);
                   2615:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                   2616: 
                   2617:    /* rd = hi(ra * rb) */
                   2618:    iop = ppc32_op_emit_insn_output(cpu,2,"mulhw");
                   2619:    x86_mul_reg(iop->ob_ptr,hreg_rb,1);
1.1       root     2620: 
1.1.1.3   root     2621:    if (insn & 1)
                   2622:       x86_test_reg_reg(iop->ob_ptr,X86_EDX,X86_EDX);
                   2623: 
                   2624:    ppc32_op_emit_store_gpr(cpu,rd,X86_EDX);
                   2625: 
                   2626:    if (insn & 1)
                   2627:       ppc32_op_emit_update_flags(cpu,0,TRUE);
                   2628: 
                   2629:    /* edx:eax are directly modified: throw them */
                   2630:    ppc32_op_emit_alter_host_reg(cpu,X86_EAX);
                   2631:    ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
1.1       root     2632: 
1.1.1.3   root     2633:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2634:    return(0);
                   2635: }
                   2636: 
                   2637: /* MULHWU - Multiply High Word Unsigned */
                   2638: DECLARE_INSN(MULHWU)
                   2639: {
                   2640:    int rd = bits(insn,21,25);
                   2641:    int ra = bits(insn,16,20);
                   2642:    int rb = bits(insn,11,15);
1.1.1.3   root     2643:    int hreg_rb;
                   2644:    jit_op_t *iop;
1.1       root     2645: 
1.1.1.3   root     2646:    ppc32_jit_start_hreg_seq(cpu,"mulhwu");
                   2647:    ppc32_jit_alloc_hreg_forced(cpu,X86_EAX);
                   2648:    ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
                   2649:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   2650: 
                   2651:    ppc32_op_emit_load_gpr(cpu,X86_EAX,ra);
                   2652:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                   2653: 
                   2654:    /* rd = hi(ra * rb) */
                   2655:    iop = ppc32_op_emit_insn_output(cpu,2,"mulhwu");
                   2656:    x86_mul_reg(iop->ob_ptr,hreg_rb,0);
1.1       root     2657: 
1.1.1.3   root     2658:    if (insn & 1)
                   2659:       x86_test_reg_reg(iop->ob_ptr,X86_EDX,X86_EDX);
                   2660: 
                   2661:    ppc32_op_emit_store_gpr(cpu,rd,X86_EDX);
                   2662: 
                   2663:    if (insn & 1)
                   2664:       ppc32_op_emit_update_flags(cpu,0,TRUE);
                   2665: 
                   2666:    /* edx:eax are directly modified: throw them */
                   2667:    ppc32_op_emit_alter_host_reg(cpu,X86_EAX);
                   2668:    ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
1.1       root     2669: 
1.1.1.3   root     2670:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2671:    return(0);
                   2672: }
                   2673: 
                   2674: /* MULLI - Multiply Low Immediate */
                   2675: DECLARE_INSN(MULLI)
                   2676: {
                   2677:    int rd = bits(insn,21,25);
                   2678:    int ra = bits(insn,16,20);
                   2679:    m_uint32_t imm = bits(insn,0,15);
1.1.1.3   root     2680:    int hreg_t0;
                   2681:    jit_op_t *iop;
                   2682: 
                   2683:    ppc32_jit_start_hreg_seq(cpu,"mulli");
                   2684:    ppc32_jit_alloc_hreg_forced(cpu,X86_EAX);
                   2685:    ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
                   2686:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   2687: 
                   2688:    ppc32_op_emit_load_gpr(cpu,X86_EAX,ra);
1.1       root     2689: 
1.1.1.3   root     2690:    /* rd = lo(ra * imm) */
                   2691:    iop = ppc32_op_emit_insn_output(cpu,2,"mulli");
1.1       root     2692: 
1.1.1.3   root     2693:    ppc32_load_imm(&iop->ob_ptr,hreg_t0,sign_extend_32(imm,16));
                   2694:    x86_mul_reg(iop->ob_ptr,hreg_t0,1);
                   2695:    ppc32_op_emit_store_gpr(cpu,rd,X86_EAX);
                   2696: 
                   2697:    /* edx:eax are directly modified: throw them */
                   2698:    ppc32_op_emit_alter_host_reg(cpu,X86_EAX);
                   2699:    ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
                   2700: 
                   2701:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2702:    return(0);
                   2703: }
                   2704: 
                   2705: /* MULLW - Multiply Low Word */
                   2706: DECLARE_INSN(MULLW)
                   2707: {
                   2708:    int rd = bits(insn,21,25);
                   2709:    int ra = bits(insn,16,20);
                   2710:    int rb = bits(insn,11,15);
1.1.1.3   root     2711:    int hreg_rb;
                   2712:    jit_op_t *iop;
1.1       root     2713: 
1.1.1.3   root     2714:    ppc32_jit_start_hreg_seq(cpu,"mullw");
                   2715:    ppc32_jit_alloc_hreg_forced(cpu,X86_EAX);
                   2716:    ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
                   2717:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   2718: 
                   2719:    ppc32_op_emit_load_gpr(cpu,X86_EAX,ra);
                   2720:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                   2721: 
                   2722:    /* rd = lo(ra * rb) */
                   2723:    iop = ppc32_op_emit_insn_output(cpu,2,"mullw");
                   2724:    x86_mul_reg(iop->ob_ptr,hreg_rb,1);
1.1       root     2725: 
1.1.1.3   root     2726:    if (insn & 1)
                   2727:       x86_test_reg_reg(iop->ob_ptr,X86_EAX,X86_EAX);
                   2728: 
                   2729:    ppc32_op_emit_store_gpr(cpu,rd,X86_EAX);
                   2730: 
                   2731:    if (insn & 1)
                   2732:       ppc32_op_emit_update_flags(cpu,0,TRUE);
                   2733: 
                   2734:    /* edx:eax are directly modified: throw them */
                   2735:    ppc32_op_emit_alter_host_reg(cpu,X86_EAX);
                   2736:    ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
1.1       root     2737: 
1.1.1.3   root     2738:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2739:    return(0);
                   2740: }
                   2741: 
                   2742: /* NAND */
                   2743: DECLARE_INSN(NAND)
                   2744: {
                   2745:    int rs = bits(insn,21,25);
                   2746:    int ra = bits(insn,16,20);
                   2747:    int rb = bits(insn,11,15);
1.1.1.3   root     2748:    int hreg_rs,hreg_ra,hreg_rb;
                   2749:    jit_op_t *iop;
1.1       root     2750: 
                   2751:    /* $ra = ~($rs & $rb) */
1.1.1.3   root     2752:    ppc32_jit_start_hreg_seq(cpu,"nand");
                   2753:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   2754:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   2755:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   2756: 
                   2757:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   2758:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                   2759: 
                   2760:    iop = ppc32_op_emit_insn_output(cpu,2,"nand");
                   2761: 
                   2762:    if (ra == rs)
                   2763:       x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_ra,hreg_rb);
                   2764:    else if (ra == rb)
                   2765:       x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_ra,hreg_rs);
                   2766:    else {
                   2767:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
                   2768:       x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_ra,hreg_rb);
1.1       root     2769:    }
                   2770: 
1.1.1.3   root     2771:    x86_not_reg(iop->ob_ptr,hreg_ra);
                   2772: 
                   2773:    if (insn & 1)
                   2774:       x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
                   2775: 
                   2776:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   2777: 
                   2778:    if (insn & 1)
                   2779:       ppc32_op_emit_update_flags(cpu,0,TRUE);
                   2780: 
                   2781:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2782:    return(0);
                   2783: }
                   2784: 
                   2785: /* NEG */
                   2786: DECLARE_INSN(NEG)
                   2787: {
                   2788:    int rd = bits(insn,21,25);
                   2789:    int ra = bits(insn,16,20);
1.1.1.3   root     2790:    int hreg_rd,hreg_ra;
                   2791:    jit_op_t *iop;
1.1       root     2792: 
1.1.1.3   root     2793:    /* $rd = neg($ra) */
                   2794:    ppc32_jit_start_hreg_seq(cpu,"neg");
                   2795:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   2796:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1.1       root     2797: 
1.1.1.3   root     2798:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                   2799: 
                   2800:    iop = ppc32_op_emit_insn_output(cpu,1,"neg");
                   2801: 
                   2802:    if (rd != ra)
                   2803:       x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
1.1       root     2804: 
1.1.1.3   root     2805:    x86_neg_reg(iop->ob_ptr,hreg_rd);
                   2806: 
                   2807:    if (insn & 1)
                   2808:       x86_test_reg_reg(iop->ob_ptr,hreg_rd,hreg_rd);
                   2809: 
                   2810:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
                   2811: 
                   2812:    if (insn & 1)
                   2813:       ppc32_op_emit_update_flags(cpu,0,TRUE);
                   2814: 
                   2815:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2816:    return(0);
                   2817: }
                   2818: 
                   2819: /* NOR */
                   2820: DECLARE_INSN(NOR)
                   2821: {
                   2822:    int rs = bits(insn,21,25);
                   2823:    int ra = bits(insn,16,20);
                   2824:    int rb = bits(insn,11,15);
1.1.1.3   root     2825:    int hreg_rs,hreg_ra,hreg_rb;
                   2826:    jit_op_t *iop;
1.1       root     2827: 
                   2828:    /* $ra = ~($rs | $rb) */
1.1.1.3   root     2829:    ppc32_jit_start_hreg_seq(cpu,"nor");
                   2830:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   2831:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   2832:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   2833: 
                   2834:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   2835:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                   2836: 
                   2837:    iop = ppc32_op_emit_insn_output(cpu,2,"nor");
                   2838: 
                   2839:    if (ra == rs)
                   2840:       x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_rb);
                   2841:    else if (ra == rb)
                   2842:       x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_rs);
                   2843:    else {
                   2844:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
                   2845:       x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_rb);
1.1       root     2846:    }
                   2847: 
1.1.1.3   root     2848:    x86_not_reg(iop->ob_ptr,hreg_ra);
                   2849: 
                   2850:    if (insn & 1)
                   2851:       x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
                   2852: 
                   2853:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   2854: 
                   2855:    if (insn & 1)
                   2856:       ppc32_op_emit_update_flags(cpu,0,TRUE);
                   2857: 
                   2858:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2859:    return(0);
                   2860: }
                   2861: 
                   2862: /* OR */
                   2863: DECLARE_INSN(OR)
                   2864: {
                   2865:    int rs = bits(insn,21,25);
                   2866:    int ra = bits(insn,16,20);
                   2867:    int rb = bits(insn,11,15);
1.1.1.3   root     2868:    int hreg_rs,hreg_ra,hreg_rb;
                   2869:    jit_op_t *iop;
1.1       root     2870: 
1.1.1.3   root     2871:    /* $ra = $rs | $rb */
                   2872:    ppc32_jit_start_hreg_seq(cpu,"or");
                   2873:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   2874:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   2875:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
1.1       root     2876: 
1.1.1.3   root     2877:    /* special optimization for move/nop operation */
                   2878:    if (rs == rb) {
                   2879:       ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   2880:       iop = ppc32_op_emit_insn_output(cpu,2,"or");
1.1       root     2881: 
1.1.1.3   root     2882:       if (ra != rs)
                   2883:          x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
1.1       root     2884: 
1.1.1.3   root     2885:       if (insn & 1)
                   2886:          x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
                   2887: 
                   2888:       ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   2889: 
                   2890:       if (insn & 1)
                   2891:          ppc32_op_emit_update_flags(cpu,0,TRUE);
                   2892: 
                   2893:       ppc32_jit_close_hreg_seq(cpu);
                   2894:       return(0);
                   2895:    }
                   2896: 
                   2897:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   2898:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                   2899: 
                   2900:    iop = ppc32_op_emit_insn_output(cpu,2,"or");
                   2901: 
                   2902:    if (ra == rs) {
                   2903:       x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_rb);
                   2904:    } else if (ra == rb)
                   2905:       x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_rs);
                   2906:    else {
                   2907:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
                   2908:       x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_rb);
1.1       root     2909:    }
                   2910: 
1.1.1.3   root     2911:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   2912: 
                   2913:    if (insn & 1)
                   2914:       ppc32_op_emit_update_flags(cpu,0,TRUE);
                   2915: 
                   2916:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2917:    return(0);
                   2918: }
                   2919: 
                   2920: /* OR with Complement */
                   2921: DECLARE_INSN(ORC)
                   2922: {
                   2923:    int rs = bits(insn,21,25);
                   2924:    int ra = bits(insn,16,20);
                   2925:    int rb = bits(insn,11,15);
1.1.1.3   root     2926:    int hreg_rs,hreg_ra,hreg_rb,hreg_t0;
                   2927:    jit_op_t *iop;
                   2928: 
                   2929:    /* $ra = $rs & ~$rb */
                   2930:    ppc32_jit_start_hreg_seq(cpu,"orc");
                   2931:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   2932:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   2933:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   2934: 
                   2935:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   2936:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                   2937: 
                   2938:    iop = ppc32_op_emit_insn_output(cpu,1,"orc");
                   2939: 
                   2940:    /* $t0 = ~$rb */
                   2941:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   2942:    x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rb,4);
                   2943:    x86_not_reg(iop->ob_ptr,hreg_t0);
                   2944: 
                   2945:    /* $ra = $rs | $t0 */
                   2946:    if (ra == rs) 
                   2947:       x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_t0);
                   2948:    else {
                   2949:       x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_t0,hreg_rs);
                   2950:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_t0,4);
                   2951:    }
1.1       root     2952: 
1.1.1.3   root     2953:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1.1       root     2954: 
                   2955:    if (insn & 1)
1.1.1.3   root     2956:       ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1       root     2957: 
1.1.1.3   root     2958:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2959:    return(0);
                   2960: }
                   2961: 
                   2962: /* OR Immediate */
                   2963: DECLARE_INSN(ORI)
                   2964: {
                   2965:    int rs = bits(insn,21,25);
                   2966:    int ra = bits(insn,16,20);
                   2967:    m_uint16_t imm = bits(insn,0,15);
1.1.1.3   root     2968:    m_uint32_t tmp = imm;
                   2969:    int hreg_rs,hreg_ra;
                   2970:    jit_op_t *iop;
1.1       root     2971: 
                   2972:    /* $ra = $rs | imm */
1.1.1.3   root     2973:    ppc32_jit_start_hreg_seq(cpu,"ori");
                   2974:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   2975:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   2976: 
                   2977:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   2978: 
                   2979:    iop = ppc32_op_emit_insn_output(cpu,1,"ori");
                   2980: 
                   2981:    if (ra != rs)
                   2982:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
                   2983: 
                   2984:    x86_alu_reg_imm(iop->ob_ptr,X86_OR,hreg_ra,tmp);
                   2985:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   2986: 
                   2987:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     2988:    return(0);
                   2989: }
                   2990: 
                   2991: /* OR Immediate Shifted */
                   2992: DECLARE_INSN(ORIS)
                   2993: {
                   2994:    int rs = bits(insn,21,25);
                   2995:    int ra = bits(insn,16,20);
1.1.1.3   root     2996:    m_uint16_t imm = bits(insn,0,15);
                   2997:    m_uint32_t tmp = imm << 16;
                   2998:    int hreg_rs,hreg_ra;
                   2999:    jit_op_t *iop;
                   3000: 
                   3001:    /* $ra = $rs | imm */
                   3002:    ppc32_jit_start_hreg_seq(cpu,"oris");
                   3003:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   3004:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1.1       root     3005: 
1.1.1.3   root     3006:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   3007: 
                   3008:    iop = ppc32_op_emit_insn_output(cpu,1,"oris");
                   3009: 
                   3010:    if (ra != rs)
                   3011:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
                   3012: 
                   3013:    x86_alu_reg_imm(iop->ob_ptr,X86_OR,hreg_ra,tmp);
                   3014:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   3015: 
                   3016:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     3017:    return(0);
                   3018: }
                   3019: 
                   3020: /* RLWIMI - Rotate Left Word Immediate then Mask Insert */
                   3021: DECLARE_INSN(RLWIMI)
                   3022: {
                   3023:    int rs = bits(insn,21,25);
                   3024:    int ra = bits(insn,16,20);
                   3025:    int sh = bits(insn,11,15);
                   3026:    int mb = bits(insn,6,10);
                   3027:    int me = bits(insn,1,5);
                   3028:    register m_uint32_t mask;
1.1.1.3   root     3029:    int hreg_rs,hreg_ra,hreg_t0;
                   3030:    jit_op_t *iop;
                   3031: 
                   3032:    ppc32_jit_start_hreg_seq(cpu,"rlwimi");
                   3033:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   3034:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   3035:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   3036: 
                   3037:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   3038:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                   3039: 
1.1       root     3040:    mask = ppc32_rotate_mask(mb,me);
                   3041: 
1.1.1.3   root     3042:    iop = ppc32_op_emit_insn_output(cpu,2,"rlwimi");
                   3043: 
                   3044:    /* Apply inverse mask to $ra */
1.1       root     3045:    if (mask != 0)
1.1.1.3   root     3046:       x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_ra,~mask);
1.1       root     3047: 
1.1.1.3   root     3048:    /* Rotate $rs of "sh" bits and apply the mask */
                   3049:    x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
1.1       root     3050: 
                   3051:    if (sh != 0)
1.1.1.3   root     3052:       x86_shift_reg_imm(iop->ob_ptr,X86_ROL,hreg_t0,sh);
1.1       root     3053: 
                   3054:    if (mask != 0xFFFFFFFF)
1.1.1.3   root     3055:       x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,mask);
1.1       root     3056: 
                   3057:    /* Store the result */
1.1.1.3   root     3058:    x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_t0);
                   3059:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1.1       root     3060: 
                   3061:    if (insn & 1)
1.1.1.3   root     3062:       ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1       root     3063: 
1.1.1.3   root     3064:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     3065:    return(0);
                   3066: }
                   3067: 
                   3068: /* RLWINM - Rotate Left Word Immediate AND with Mask */
                   3069: DECLARE_INSN(RLWINM)
                   3070: {
                   3071:    int rs = bits(insn,21,25);
                   3072:    int ra = bits(insn,16,20);
                   3073:    int sh = bits(insn,11,15);
                   3074:    int mb = bits(insn,6,10);
                   3075:    int me = bits(insn,1,5);
                   3076:    register m_uint32_t mask;
1.1.1.3   root     3077:    int hreg_rs,hreg_ra;
                   3078:    jit_op_t *iop;
                   3079: 
                   3080:    ppc32_jit_start_hreg_seq(cpu,"rlwinm");
                   3081:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   3082:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   3083: 
                   3084:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
1.1       root     3085: 
1.1.1.3   root     3086:    iop = ppc32_op_emit_insn_output(cpu,2,"rlwinm");
                   3087: 
                   3088:    /* Rotate $rs of "sh" bits and apply the mask */
1.1       root     3089:    mask = ppc32_rotate_mask(mb,me);
                   3090: 
1.1.1.3   root     3091:    if (rs != ra)
                   3092:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
1.1       root     3093: 
                   3094:    if (sh != 0)
1.1.1.3   root     3095:       x86_shift_reg_imm(iop->ob_ptr,X86_ROL,hreg_ra,sh);
1.1       root     3096: 
                   3097:    if (mask != 0xFFFFFFFF)
1.1.1.3   root     3098:       x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_ra,mask);
1.1       root     3099: 
1.1.1.3   root     3100:    if (insn & 1)
                   3101:       x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
1.1       root     3102: 
1.1.1.3   root     3103:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   3104: 
                   3105:    if (insn & 1)
                   3106:       ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1       root     3107: 
1.1.1.3   root     3108:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     3109:    return(0);
                   3110: }
                   3111: 
                   3112: /* RLWNM - Rotate Left Word then Mask Insert */
                   3113: DECLARE_INSN(RLWNM)
                   3114: {
                   3115:    int rs = bits(insn,21,25);
                   3116:    int ra = bits(insn,16,20);
                   3117:    int rb = bits(insn,11,15);
                   3118:    int mb = bits(insn,6,10);
                   3119:    int me = bits(insn,1,5);
                   3120:    register m_uint32_t mask;
1.1.1.3   root     3121:    int hreg_rs,hreg_ra,hreg_t0;
                   3122:    jit_op_t *iop;
1.1       root     3123: 
1.1.1.3   root     3124:    /* ecx is directly modified: throw it */
                   3125:    ppc32_op_emit_alter_host_reg(cpu,X86_ECX);
                   3126: 
                   3127:    ppc32_jit_start_hreg_seq(cpu,"rlwnm");
                   3128:    ppc32_jit_alloc_hreg_forced(cpu,X86_ECX);
                   3129: 
                   3130:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   3131:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   3132:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   3133: 
                   3134:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                   3135:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   3136:    ppc32_op_emit_load_gpr(cpu,X86_ECX,rb);
                   3137: 
                   3138:    iop = ppc32_op_emit_insn_output(cpu,2,"rlwnm");
1.1       root     3139: 
                   3140:    /* Load the shift register ("sh") */
1.1.1.3   root     3141:    mask = ppc32_rotate_mask(mb,me);
                   3142: 
                   3143:    /* Rotate $rs and apply the mask */
                   3144:    x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
1.1       root     3145: 
1.1.1.3   root     3146:    x86_shift_reg(iop->ob_ptr,X86_ROL,hreg_t0);
1.1       root     3147: 
                   3148:    if (mask != 0xFFFFFFFF)
1.1.1.3   root     3149:       x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,mask);
1.1       root     3150: 
1.1.1.3   root     3151:    x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_t0,4);
1.1       root     3152: 
1.1.1.3   root     3153:    if (insn & 1)
                   3154:       x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
                   3155: 
                   3156:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   3157: 
                   3158:    if (insn & 1)
                   3159:       ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1       root     3160: 
1.1.1.3   root     3161:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     3162:    return(0);
                   3163: }
                   3164: 
                   3165: /* Shift Left Word */
                   3166: DECLARE_INSN(SLW)
                   3167: {
                   3168:    int rs = bits(insn,21,25);
                   3169:    int ra = bits(insn,16,20);
                   3170:    int rb = bits(insn,11,15);
                   3171:    u_char *test1;
1.1.1.3   root     3172:    int hreg_rs,hreg_ra,hreg_t0;
                   3173:    jit_op_t *iop;
1.1       root     3174: 
1.1.1.3   root     3175:    /* ecx is directly modified: throw it */
                   3176:    ppc32_op_emit_alter_host_reg(cpu,X86_ECX);
1.1       root     3177: 
1.1.1.3   root     3178:    ppc32_jit_start_hreg_seq(cpu,"slw");
                   3179:    ppc32_jit_alloc_hreg_forced(cpu,X86_ECX);
                   3180:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   3181:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   3182:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   3183: 
                   3184:    /* $ra = $rs << $rb. If count >= 32, then null result */
                   3185:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   3186:    ppc32_op_emit_load_gpr(cpu,X86_ECX,rb);
                   3187: 
                   3188:    iop = ppc32_op_emit_insn_output(cpu,3,"slw");
                   3189: 
                   3190:    x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t0,hreg_t0);
                   3191:    x86_test_reg_imm(iop->ob_ptr,X86_ECX,0x20);
                   3192:    test1 = iop->ob_ptr;
                   3193:    x86_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1);
                   3194: 
                   3195:    x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
                   3196:    x86_shift_reg(iop->ob_ptr,X86_SHL,hreg_t0);
                   3197:    
                   3198:    /* store the result */
                   3199:    x86_patch(test1,iop->ob_ptr);
                   3200:    x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_t0,4);
1.1       root     3201: 
1.1.1.3   root     3202:    if (insn & 1)
                   3203:       x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
1.1       root     3204: 
1.1.1.3   root     3205:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   3206:    
                   3207:    if (insn & 1)
                   3208:       ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1       root     3209: 
1.1.1.3   root     3210:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     3211:    return(0);
                   3212: }
                   3213: 
                   3214: /* SRAWI - Shift Right Algebraic Word Immediate */
                   3215: DECLARE_INSN(SRAWI)
                   3216: {   
                   3217:    int rs = bits(insn,21,25);
                   3218:    int ra = bits(insn,16,20);
                   3219:    int sh = bits(insn,11,15);
                   3220:    register m_uint32_t mask;
1.1.1.3   root     3221:    int hreg_rs,hreg_ra,hreg_t0;
                   3222:    jit_op_t *iop;
1.1       root     3223: 
1.1.1.3   root     3224:    ppc32_jit_start_hreg_seq(cpu,"srawi");
                   3225:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   3226:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   3227:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1.1       root     3228: 
                   3229:    /* $ra = (int32)$rs >> sh */
1.1.1.3   root     3230:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
1.1       root     3231: 
1.1.1.3   root     3232:    iop = ppc32_op_emit_insn_output(cpu,3,"srawi");
                   3233:    x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
                   3234:    
                   3235:    if (ra != rs)
                   3236:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
                   3237:    x86_shift_reg_imm(iop->ob_ptr,X86_SAR,hreg_ra,sh);
                   3238: 
                   3239:    /* set XER_CA depending on the result */
                   3240:    mask = ~(0xFFFFFFFFU << sh) | 0x80000000;
                   3241: 
                   3242:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,mask);
                   3243:    x86_alu_reg_imm(iop->ob_ptr,X86_CMP,hreg_t0,0x80000000);
                   3244:    x86_set_reg(iop->ob_ptr,X86_CC_A,hreg_t0,FALSE);
                   3245:    x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x1);
                   3246:    x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),hreg_t0,4);
                   3247: 
                   3248:    if (insn & 1)
                   3249:       x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
                   3250: 
                   3251:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   3252:    
                   3253:    if (insn & 1)
                   3254:       ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1       root     3255: 
1.1.1.3   root     3256:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     3257:    return(0);
                   3258: }
                   3259: 
                   3260: /* Shift Right Word */
                   3261: DECLARE_INSN(SRW)
                   3262: {
                   3263:    int rs = bits(insn,21,25);
                   3264:    int ra = bits(insn,16,20);
                   3265:    int rb = bits(insn,11,15);
                   3266:    u_char *test1;
1.1.1.3   root     3267:    int hreg_rs,hreg_ra,hreg_t0;
                   3268:    jit_op_t *iop;
1.1       root     3269: 
1.1.1.3   root     3270:    /* ecx is directly modified: throw it */
                   3271:    ppc32_op_emit_alter_host_reg(cpu,X86_ECX);
1.1       root     3272: 
1.1.1.3   root     3273:    ppc32_jit_start_hreg_seq(cpu,"srw");
                   3274:    ppc32_jit_alloc_hreg_forced(cpu,X86_ECX);
                   3275:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   3276:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   3277:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   3278: 
                   3279:    /* $ra = $rs >> $rb. If count >= 32, then null result */
                   3280:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   3281:    ppc32_op_emit_load_gpr(cpu,X86_ECX,rb);
                   3282: 
                   3283:    iop = ppc32_op_emit_insn_output(cpu,3,"srw");
                   3284: 
                   3285:    x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t0,hreg_t0);
                   3286:    x86_test_reg_imm(iop->ob_ptr,X86_ECX,0x20);
                   3287:    test1 = iop->ob_ptr;
                   3288:    x86_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1);
                   3289: 
                   3290:    x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
                   3291:    x86_shift_reg(iop->ob_ptr,X86_SHR,hreg_t0);
                   3292:    
                   3293:    /* store the result */
                   3294:    x86_patch(test1,iop->ob_ptr);
                   3295:    x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_t0,4);
1.1       root     3296: 
1.1.1.3   root     3297:    if (insn & 1)
                   3298:       x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
1.1       root     3299: 
1.1.1.3   root     3300:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   3301:    
                   3302:    if (insn & 1)
                   3303:       ppc32_op_emit_update_flags(cpu,0,TRUE);
                   3304: 
                   3305:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     3306:    return(0);
                   3307: }
                   3308: 
                   3309: /* STB - Store Byte */
                   3310: DECLARE_INSN(STB)
                   3311: {
                   3312:    int rs = bits(insn,21,25);
                   3313:    int ra = bits(insn,16,20);
                   3314:    m_uint16_t offset = bits(insn,0,15);
                   3315: 
                   3316:    //ppc32_emit_memop(b,PPC_MEMOP_STB,ra,offset,rs,0);
1.1.1.3   root     3317:    ppc32_emit_memop_fast(cpu,b,1,PPC_MEMOP_STB,ra,offset,rs,
                   3318:                          ppc32_memop_fast_stb);
1.1       root     3319:    return(0);
                   3320: }
                   3321: 
                   3322: /* STBU - Store Byte with Update */
                   3323: DECLARE_INSN(STBU)
                   3324: {
                   3325:    int rs = bits(insn,21,25);
                   3326:    int ra = bits(insn,16,20);
                   3327:    m_uint16_t offset = bits(insn,0,15);
                   3328: 
1.1.1.3   root     3329:    ppc32_emit_memop(cpu,b,PPC_MEMOP_STB,ra,offset,rs,1);
1.1       root     3330:    return(0);
                   3331: }
                   3332: 
                   3333: /* STBUX - Store Byte with Update Indexed */
                   3334: DECLARE_INSN(STBUX)
                   3335: {
                   3336:    int rs = bits(insn,21,25);
                   3337:    int ra = bits(insn,16,20);
                   3338:    int rb = bits(insn,11,15);
                   3339: 
1.1.1.3   root     3340:    ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STB,ra,rb,rs,1);
1.1       root     3341:    return(0);
                   3342: }
                   3343: 
                   3344: /* STBUX - Store Byte Indexed */
                   3345: DECLARE_INSN(STBX)
                   3346: {
                   3347:    int rs = bits(insn,21,25);
                   3348:    int ra = bits(insn,16,20);
                   3349:    int rb = bits(insn,11,15);
                   3350: 
1.1.1.3   root     3351:    ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STB,ra,rb,rs,0);
1.1       root     3352:    return(0);
                   3353: }
                   3354: 
                   3355: /* STH - Store Half-Word */
                   3356: DECLARE_INSN(STH)
                   3357: {
                   3358:    int rs = bits(insn,21,25);
                   3359:    int ra = bits(insn,16,20);
                   3360:    m_uint16_t offset = bits(insn,0,15);
                   3361: 
1.1.1.3   root     3362:    ppc32_emit_memop(cpu,b,PPC_MEMOP_STH,ra,offset,rs,0);
1.1       root     3363:    return(0);
                   3364: }
                   3365: 
                   3366: /* STHU - Store Half-Word with Update */
                   3367: DECLARE_INSN(STHU)
                   3368: {
                   3369:    int rs = bits(insn,21,25);
                   3370:    int ra = bits(insn,16,20);
                   3371:    m_uint16_t offset = bits(insn,0,15);
                   3372: 
1.1.1.3   root     3373:    ppc32_emit_memop(cpu,b,PPC_MEMOP_STH,ra,offset,rs,1);
1.1       root     3374:    return(0);
                   3375: }
                   3376: 
                   3377: /* STHUX - Store Half-Word with Update Indexed */
                   3378: DECLARE_INSN(STHUX)
                   3379: {
                   3380:    int rs = bits(insn,21,25);
                   3381:    int ra = bits(insn,16,20);
                   3382:    int rb = bits(insn,11,15);
                   3383: 
1.1.1.3   root     3384:    ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STH,ra,rb,rs,1);
1.1       root     3385:    return(0);
                   3386: }
                   3387: 
                   3388: /* STHUX - Store Half-Word Indexed */
                   3389: DECLARE_INSN(STHX)
                   3390: {
                   3391:    int rs = bits(insn,21,25);
                   3392:    int ra = bits(insn,16,20);
                   3393:    int rb = bits(insn,11,15);
                   3394: 
1.1.1.3   root     3395:    ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STH,ra,rb,rs,0);
1.1       root     3396:    return(0);
                   3397: }
                   3398: 
                   3399: /* STW - Store Word */
                   3400: DECLARE_INSN(STW)
                   3401: {
                   3402:    int rs = bits(insn,21,25);
                   3403:    int ra = bits(insn,16,20);
                   3404:    m_uint16_t offset = bits(insn,0,15);
                   3405: 
                   3406:    //ppc32_emit_memop(b,PPC_MEMOP_STW,ra,offset,rs,0);
1.1.1.3   root     3407:    ppc32_emit_memop_fast(cpu,b,1,PPC_MEMOP_STW,ra,offset,rs,
                   3408:                          ppc32_memop_fast_stw);
1.1       root     3409:    return(0);
                   3410: }
                   3411: 
                   3412: /* STWU - Store Word with Update */
                   3413: DECLARE_INSN(STWU)
                   3414: {
                   3415:    int rs = bits(insn,21,25);
                   3416:    int ra = bits(insn,16,20);
                   3417:    m_uint16_t offset = bits(insn,0,15);
                   3418: 
1.1.1.3   root     3419:    ppc32_emit_memop(cpu,b,PPC_MEMOP_STW,ra,offset,rs,1);
1.1       root     3420:    return(0);
                   3421: }
                   3422: 
                   3423: /* STWUX - Store Word with Update Indexed */
                   3424: DECLARE_INSN(STWUX)
                   3425: {
                   3426:    int rs = bits(insn,21,25);
                   3427:    int ra = bits(insn,16,20);
                   3428:    int rb = bits(insn,11,15);
                   3429: 
1.1.1.3   root     3430:    ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STW,ra,rb,rs,1);
1.1       root     3431:    return(0);
                   3432: }
                   3433: 
                   3434: /* STWUX - Store Word Indexed */
                   3435: DECLARE_INSN(STWX)
                   3436: {
                   3437:    int rs = bits(insn,21,25);
                   3438:    int ra = bits(insn,16,20);
                   3439:    int rb = bits(insn,11,15);
                   3440: 
1.1.1.3   root     3441:    ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STW,ra,rb,rs,0);
1.1       root     3442:    return(0);
                   3443: }
                   3444: 
                   3445: /* SUBF - Subtract From */
                   3446: DECLARE_INSN(SUBF)
                   3447: {
                   3448:    int rd = bits(insn,21,25);
                   3449:    int ra = bits(insn,16,20);
                   3450:    int rb = bits(insn,11,15);
1.1.1.3   root     3451:    int hreg_rd,hreg_ra,hreg_rb,hreg_t0;
                   3452:    jit_op_t *iop;
                   3453: 
                   3454:    /* $rd = $rb - $ra */
                   3455:    ppc32_jit_start_hreg_seq(cpu,"subf");
                   3456:    hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
                   3457: 
                   3458:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                   3459:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   3460:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   3461: 
                   3462:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                   3463:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                   3464: 
                   3465:    iop = ppc32_op_emit_insn_output(cpu,2,"subf");
                   3466: 
                   3467:    if (rd == rb)
                   3468:       x86_alu_reg_reg(iop->ob_ptr,X86_SUB,hreg_rd,hreg_ra);
                   3469:    else if (rd == ra) {
                   3470:       x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rb,4);
                   3471:       x86_alu_reg_reg(iop->ob_ptr,X86_SUB,hreg_t0,hreg_ra);
                   3472:       x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_t0,4);
                   3473:    } else {
                   3474:       x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_rb,4);
                   3475:       x86_alu_reg_reg(iop->ob_ptr,X86_SUB,hreg_rd,hreg_ra);
                   3476:    }
1.1       root     3477: 
1.1.1.3   root     3478:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1.1       root     3479: 
                   3480:    if (insn & 1)
1.1.1.3   root     3481:       ppc32_op_emit_update_flags(cpu,0,TRUE);
                   3482: 
                   3483:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     3484:    return(0);
                   3485: }
                   3486: 
                   3487: /* SUBFC - Subtract From Carrying */
                   3488: DECLARE_INSN(SUBFC)
                   3489: {
                   3490:    int rd = bits(insn,21,25);
                   3491:    int ra = bits(insn,16,20);
                   3492:    int rb = bits(insn,11,15);
1.1.1.3   root     3493:    int hreg_ra,hreg_rb,hreg_rd,hreg_t0,hreg_t1;
                   3494:    jit_op_t *iop;
1.1       root     3495: 
1.1.1.3   root     3496:    /* $rd = ~$ra + 1 + $rb */
                   3497:    ppc32_jit_start_hreg_seq(cpu,"subfc");
                   3498:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   3499:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   3500:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                   3501: 
                   3502:    hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
                   3503:    hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
                   3504: 
                   3505:    ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
                   3506:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                   3507:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                   3508: 
                   3509:    iop = ppc32_op_emit_insn_output(cpu,3,"subfc");
                   3510: 
                   3511:    x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t1,hreg_t1);
                   3512: 
                   3513:    /* $t0 = ~$ra + 1 */
                   3514:    x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_ra,4);
                   3515:    x86_not_reg(iop->ob_ptr,hreg_t0);
                   3516:    x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_t0,1);
                   3517:    x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
                   3518:    x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),hreg_t1,4);
                   3519: 
                   3520:    /* $t0 += $rb */
                   3521:    x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_t0,hreg_rb);
                   3522:    x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
                   3523:    x86_alu_membase_reg(iop->ob_ptr,X86_OR,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),
                   3524:                        hreg_t1);
1.1       root     3525: 
1.1.1.3   root     3526:    x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_t0,4);
1.1       root     3527: 
1.1.1.3   root     3528:    if (insn & 1)
                   3529:       x86_test_reg_reg(iop->ob_ptr,hreg_rd,hreg_rd);
1.1       root     3530: 
1.1.1.3   root     3531:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1.1       root     3532: 
                   3533:    /* update cr0 */
1.1.1.3   root     3534:    if (insn & 1)
1.1       root     3535:       ppc32_update_cr0(b);
                   3536: 
1.1.1.3   root     3537:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     3538:    return(0);
                   3539: }
                   3540: 
                   3541: /* SUBFE - Subtract From Extended */
                   3542: DECLARE_INSN(SUBFE)
                   3543: {
                   3544:    int rd = bits(insn,21,25);
                   3545:    int ra = bits(insn,16,20);
                   3546:    int rb = bits(insn,11,15);
1.1.1.3   root     3547:    int hreg_ra,hreg_rb,hreg_rd,hreg_t0,hreg_t1;
                   3548:    jit_op_t *iop;
1.1       root     3549: 
1.1.1.3   root     3550:    /* $rd = ~$ra + $carry (xer_ca) + $rb */
                   3551:    ppc32_jit_start_hreg_seq(cpu,"subfe");
                   3552:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   3553:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   3554:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
                   3555: 
                   3556:    hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
                   3557:    hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
                   3558: 
                   3559:    ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
                   3560:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                   3561:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                   3562: 
                   3563:    iop = ppc32_op_emit_insn_output(cpu,3,"subfe");
                   3564: 
                   3565:    x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t1,hreg_t1);
                   3566: 
                   3567:    /* $t0 = ~$ra + $carry */
                   3568:    x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_ra,4);
                   3569:    x86_not_reg(iop->ob_ptr,hreg_t0);
                   3570:    x86_alu_reg_membase(iop->ob_ptr,X86_ADD,hreg_t0,
1.1       root     3571:                        X86_EDI,OFFSET(cpu_ppc_t,xer_ca));
                   3572: 
1.1.1.3   root     3573:    x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
                   3574:    x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),hreg_t1,4);
1.1       root     3575: 
1.1.1.3   root     3576:    /* $t0 += $rb */
                   3577:    x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_t0,hreg_rb);
                   3578:    x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
                   3579:    x86_alu_membase_reg(iop->ob_ptr,X86_OR,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),
                   3580:                        hreg_t1);
1.1       root     3581: 
1.1.1.3   root     3582:    x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_t0,4);
                   3583: 
                   3584:    if (insn & 1)
                   3585:       x86_test_reg_reg(iop->ob_ptr,hreg_rd,hreg_rd);
                   3586: 
                   3587:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1.1       root     3588: 
                   3589:    /* update cr0 */
1.1.1.3   root     3590:    if (insn & 1)
1.1       root     3591:       ppc32_update_cr0(b);
                   3592: 
1.1.1.3   root     3593:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     3594:    return(0);
                   3595: }
                   3596: 
                   3597: /* SUBFIC - Subtract From Immediate Carrying */
                   3598: DECLARE_INSN(SUBFIC)
                   3599: {
                   3600:    int rd = bits(insn,21,25);
                   3601:    int ra = bits(insn,16,20);
                   3602:    m_uint16_t imm = bits(insn,0,15);
                   3603:    m_uint32_t tmp = sign_extend_32(imm,16);
1.1.1.3   root     3604:    int hreg_ra,hreg_rd,hreg_t0,hreg_t1;
                   3605:    jit_op_t *iop;
1.1       root     3606: 
1.1.1.3   root     3607:    /* $rd = ~$ra + 1 + sign_extend(imm,16) */
                   3608:    ppc32_jit_start_hreg_seq(cpu,"subfic");
                   3609:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   3610:    hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1.1       root     3611: 
1.1.1.3   root     3612:    hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
                   3613:    hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
1.1       root     3614: 
1.1.1.3   root     3615:    ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
                   3616:    ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
                   3617: 
                   3618:    iop = ppc32_op_emit_insn_output(cpu,3,"subfic");
                   3619: 
                   3620:    x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t1,hreg_t1);
                   3621: 
                   3622:    /* $t0 = ~$ra + 1 */
                   3623:    x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_ra,4);
                   3624:    x86_not_reg(iop->ob_ptr,hreg_t0);
                   3625:    x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_t0,1);
                   3626: 
                   3627:    x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
                   3628:    x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),hreg_t1,4);
                   3629: 
                   3630:    /* $t0 += sign_extend(imm,16) */
                   3631:    x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_t0,tmp);
                   3632:    x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
                   3633:    x86_alu_membase_reg(iop->ob_ptr,X86_OR,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),
                   3634:                        hreg_t1);
1.1       root     3635: 
1.1.1.3   root     3636:    x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_t0,4);
                   3637:    ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
                   3638:    
                   3639:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     3640:    return(0);
                   3641: }
                   3642: 
                   3643: /* SYNC - Synchronize */
                   3644: DECLARE_INSN(SYNC)
                   3645: {
                   3646:    return(0);
                   3647: }
                   3648: 
                   3649: /* XOR */
                   3650: DECLARE_INSN(XOR)
                   3651: {
                   3652:    int rs = bits(insn,21,25);
                   3653:    int ra = bits(insn,16,20);
                   3654:    int rb = bits(insn,11,15);
1.1.1.3   root     3655:    int hreg_rs,hreg_ra,hreg_rb;
                   3656:    jit_op_t *iop;
                   3657: 
                   3658:    /* $ra = $rs ^ $rb */
                   3659:    ppc32_jit_start_hreg_seq(cpu,"xor");
                   3660:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   3661:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   3662:    hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
                   3663: 
                   3664:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   3665:    ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
                   3666: 
                   3667:    iop = ppc32_op_emit_insn_output(cpu,1,"xor");
                   3668: 
                   3669:    if (ra == rs)
                   3670:       x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rb);
                   3671:    else if (ra == rb)
                   3672:       x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rs);
                   3673:    else {
                   3674:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
                   3675:       x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rb);
                   3676:    }
1.1       root     3677: 
1.1.1.3   root     3678:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1.1       root     3679: 
                   3680:    if (insn & 1)
1.1.1.3   root     3681:       ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1       root     3682: 
1.1.1.3   root     3683:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     3684:    return(0);
                   3685: }
                   3686: 
                   3687: /* XORI - XOR Immediate */
                   3688: DECLARE_INSN(XORI)
                   3689: {
                   3690:    int rs = bits(insn,21,25);
                   3691:    int ra = bits(insn,16,20);
                   3692:    m_uint32_t imm = bits(insn,0,15);
1.1.1.3   root     3693:    int hreg_rs,hreg_ra;
                   3694:    jit_op_t *iop;
                   3695: 
                   3696:    /* $ra = $rs ^ imm */
                   3697:    ppc32_jit_start_hreg_seq(cpu,"xori");
                   3698:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   3699:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   3700: 
                   3701:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   3702: 
                   3703:    iop = ppc32_op_emit_insn_output(cpu,1,"xori");
                   3704: 
                   3705:    if (ra != rs)
                   3706:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
1.1       root     3707: 
1.1.1.3   root     3708:    x86_alu_reg_imm(iop->ob_ptr,X86_XOR,hreg_ra,imm);
                   3709:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
                   3710: 
                   3711:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     3712:    return(0);
                   3713: }
                   3714: 
                   3715: /* XORIS - XOR Immediate Shifted */
                   3716: DECLARE_INSN(XORIS)
                   3717: {
                   3718:    int rs = bits(insn,21,25);
                   3719:    int ra = bits(insn,16,20);
1.1.1.3   root     3720:    m_uint16_t imm = bits(insn,0,15);
                   3721:    m_uint32_t tmp = imm << 16;
                   3722:    int hreg_rs,hreg_ra;
                   3723:    jit_op_t *iop;
                   3724: 
                   3725:    /* $ra = $rs ^ (imm << 16) */
                   3726:    ppc32_jit_start_hreg_seq(cpu,"xoris");
                   3727:    hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
                   3728:    hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
                   3729: 
                   3730:    ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
                   3731: 
                   3732:    iop = ppc32_op_emit_insn_output(cpu,1,"xoris");
                   3733: 
                   3734:    if (ra != rs)
                   3735:       x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
                   3736: 
                   3737:    x86_alu_reg_imm(iop->ob_ptr,X86_XOR,hreg_ra,tmp);
                   3738:    ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1.1       root     3739: 
1.1.1.3   root     3740:    ppc32_jit_close_hreg_seq(cpu);
1.1       root     3741:    return(0);
                   3742: }
                   3743: 
                   3744: /* PPC instruction array */
                   3745: struct ppc32_insn_tag ppc32_insn_tags[] = {
                   3746:    { ppc32_emit_BLR        , 0xfffffffe , 0x4e800020 },
                   3747:    { ppc32_emit_BCTR       , 0xfffffffe , 0x4e800420 },
                   3748:    { ppc32_emit_MFLR       , 0xfc1fffff , 0x7c0802a6 },
                   3749:    { ppc32_emit_MTLR       , 0xfc1fffff , 0x7c0803a6 },
                   3750:    { ppc32_emit_MFCTR      , 0xfc1fffff , 0x7c0902a6 },
                   3751:    { ppc32_emit_MTCTR      , 0xfc1fffff , 0x7c0903a6 },
                   3752:    { ppc32_emit_MFTBL      , 0xfc1ff7ff , 0x7c0c42e6 },
                   3753:    { ppc32_emit_MFTBU      , 0xfc1ff7ff , 0x7c0d42e6 },
                   3754:    { ppc32_emit_ADD        , 0xfc0007fe , 0x7c000214 },
                   3755:    { ppc32_emit_ADDC       , 0xfc0007fe , 0x7c000014 },
                   3756:    { ppc32_emit_ADDE       , 0xfc0007fe , 0x7c000114 },
                   3757:    { ppc32_emit_ADDI       , 0xfc000000 , 0x38000000 },
                   3758:    { ppc32_emit_ADDIC      , 0xfc000000 , 0x30000000 },
                   3759:    { ppc32_emit_ADDIC_dot  , 0xfc000000 , 0x34000000 },
                   3760:    { ppc32_emit_ADDIS      , 0xfc000000 , 0x3c000000 },
1.1.1.3   root     3761:    { ppc32_emit_ADDZE      , 0xfc00fffe , 0x7c000194 },
1.1       root     3762:    { ppc32_emit_AND        , 0xfc0007fe , 0x7c000038 },
                   3763:    { ppc32_emit_ANDC       , 0xfc0007fe , 0x7c000078 },
                   3764:    { ppc32_emit_ANDI       , 0xfc000000 , 0x70000000 },
                   3765:    { ppc32_emit_ANDIS      , 0xfc000000 , 0x74000000 },
                   3766:    { ppc32_emit_B          , 0xfc000003 , 0x48000000 },
                   3767:    { ppc32_emit_BA         , 0xfc000003 , 0x48000002 },
                   3768:    { ppc32_emit_BL         , 0xfc000003 , 0x48000001 },
                   3769:    { ppc32_emit_BLA        , 0xfc000003 , 0x48000003 },
                   3770:    { ppc32_emit_BCC        , 0xfe800000 , 0x40800000 },
                   3771:    { ppc32_emit_BC         , 0xfc000000 , 0x40000000 },
1.1.1.4   root     3772:    { ppc32_emit_BCLR       , 0xfc00fffe , 0x4c000020 },   
1.1       root     3773:    { ppc32_emit_CMP        , 0xfc6007ff , 0x7c000000 },
                   3774:    { ppc32_emit_CMPI       , 0xfc600000 , 0x2c000000 },
                   3775:    { ppc32_emit_CMPL       , 0xfc6007ff , 0x7c000040 },
                   3776:    { ppc32_emit_CMPLI      , 0xfc600000 , 0x28000000 },
                   3777:    { ppc32_emit_CRAND      , 0xfc0007ff , 0x4c000202 },
                   3778:    { ppc32_emit_CRANDC     , 0xfc0007ff , 0x4c000102 },
                   3779:    { ppc32_emit_CREQV      , 0xfc0007ff , 0x4c000242 },
                   3780:    { ppc32_emit_CRNAND     , 0xfc0007ff , 0x4c0001c2 },
                   3781:    { ppc32_emit_CRNOR      , 0xfc0007ff , 0x4c000042 },
                   3782:    { ppc32_emit_CROR       , 0xfc0007ff , 0x4c000382 },
                   3783:    { ppc32_emit_CRORC      , 0xfc0007ff , 0x4c000342 },
                   3784:    { ppc32_emit_CRXOR      , 0xfc0007ff , 0x4c000182 },
                   3785:    { ppc32_emit_DIVWU      , 0xfc0007fe , 0x7c000396 },
                   3786:    { ppc32_emit_EQV        , 0xfc0007fe , 0x7c000238 },
                   3787:    { ppc32_emit_EXTSB      , 0xfc00fffe , 0x7c000774 },
                   3788:    { ppc32_emit_EXTSH      , 0xfc00fffe , 0x7c000734 },
                   3789:    { ppc32_emit_LBZ        , 0xfc000000 , 0x88000000 },
                   3790:    { ppc32_emit_LBZU       , 0xfc000000 , 0x8c000000 },
                   3791:    { ppc32_emit_LBZUX      , 0xfc0007ff , 0x7c0000ee },
                   3792:    { ppc32_emit_LBZX       , 0xfc0007ff , 0x7c0000ae },
                   3793:    { ppc32_emit_LHA        , 0xfc000000 , 0xa8000000 },
                   3794:    { ppc32_emit_LHAU       , 0xfc000000 , 0xac000000 },
                   3795:    { ppc32_emit_LHAUX      , 0xfc0007ff , 0x7c0002ee },
                   3796:    { ppc32_emit_LHAX       , 0xfc0007ff , 0x7c0002ae },
                   3797:    { ppc32_emit_LHZ        , 0xfc000000 , 0xa0000000 },
                   3798:    { ppc32_emit_LHZU       , 0xfc000000 , 0xa4000000 },
                   3799:    { ppc32_emit_LHZUX      , 0xfc0007ff , 0x7c00026e },
                   3800:    { ppc32_emit_LHZX       , 0xfc0007ff , 0x7c00022e },
                   3801:    { ppc32_emit_LWZ        , 0xfc000000 , 0x80000000 },
                   3802:    { ppc32_emit_LWZU       , 0xfc000000 , 0x84000000 },
                   3803:    { ppc32_emit_LWZUX      , 0xfc0007ff , 0x7c00006e },
                   3804:    { ppc32_emit_LWZX       , 0xfc0007ff , 0x7c00002e },
                   3805:    { ppc32_emit_MCRF       , 0xfc63ffff , 0x4c000000 },
                   3806:    { ppc32_emit_MFCR       , 0xfc1fffff , 0x7c000026 },
                   3807:    { ppc32_emit_MFMSR      , 0xfc1fffff , 0x7c0000a6 },
                   3808:    { ppc32_emit_MFSR       , 0xfc10ffff , 0x7c0004a6 },
                   3809:    { ppc32_emit_MTCRF      , 0xfc100fff , 0x7c000120 },
                   3810:    { ppc32_emit_MULHW      , 0xfc0007fe , 0x7c000096 },
                   3811:    { ppc32_emit_MULHWU     , 0xfc0007fe , 0x7c000016 },
                   3812:    { ppc32_emit_MULLI      , 0xfc000000 , 0x1c000000 },
                   3813:    { ppc32_emit_MULLW      , 0xfc0007fe , 0x7c0001d6 },
                   3814:    { ppc32_emit_NAND       , 0xfc0007fe , 0x7c0003b8 },
                   3815:    { ppc32_emit_NEG        , 0xfc00fffe , 0x7c0000d0 },
                   3816:    { ppc32_emit_NOR        , 0xfc0007fe , 0x7c0000f8 },
                   3817:    { ppc32_emit_OR         , 0xfc0007fe , 0x7c000378 },
                   3818:    { ppc32_emit_ORC        , 0xfc0007fe , 0x7c000338 },
                   3819:    { ppc32_emit_ORI        , 0xfc000000 , 0x60000000 },
                   3820:    { ppc32_emit_ORIS       , 0xfc000000 , 0x64000000 },
                   3821:    { ppc32_emit_RLWIMI     , 0xfc000000 , 0x50000000 },
                   3822:    { ppc32_emit_RLWINM     , 0xfc000000 , 0x54000000 },
                   3823:    { ppc32_emit_RLWNM      , 0xfc000000 , 0x5c000000 },
                   3824:    { ppc32_emit_SLW        , 0xfc0007fe , 0x7c000030 },
                   3825:    { ppc32_emit_SRAWI      , 0xfc0007fe , 0x7c000670 },
                   3826:    { ppc32_emit_SRW        , 0xfc0007fe , 0x7c000430 },
                   3827:    { ppc32_emit_STB        , 0xfc000000 , 0x98000000 },
                   3828:    { ppc32_emit_STBU       , 0xfc000000 , 0x9c000000 },
                   3829:    { ppc32_emit_STBUX      , 0xfc0007ff , 0x7c0001ee },
                   3830:    { ppc32_emit_STBX       , 0xfc0007ff , 0x7c0001ae },
                   3831:    { ppc32_emit_STH        , 0xfc000000 , 0xb0000000 },
                   3832:    { ppc32_emit_STHU       , 0xfc000000 , 0xb4000000 },
                   3833:    { ppc32_emit_STHUX      , 0xfc0007ff , 0x7c00036e },
                   3834:    { ppc32_emit_STHX       , 0xfc0007ff , 0x7c00032e },
                   3835:    { ppc32_emit_STW        , 0xfc000000 , 0x90000000 },
                   3836:    { ppc32_emit_STWU       , 0xfc000000 , 0x94000000 },
                   3837:    { ppc32_emit_STWUX      , 0xfc0007ff , 0x7c00016e },
                   3838:    { ppc32_emit_STWX       , 0xfc0007ff , 0x7c00012e },
                   3839:    { ppc32_emit_SUBF       , 0xfc0007fe , 0x7c000050 },
                   3840:    { ppc32_emit_SUBFC      , 0xfc0007fe , 0x7c000010 },
                   3841:    { ppc32_emit_SUBFE      , 0xfc0007fe , 0x7c000110 },
                   3842:    { ppc32_emit_SUBFIC     , 0xfc000000 , 0x20000000 },
                   3843:    { ppc32_emit_SYNC       , 0xffffffff , 0x7c0004ac },
                   3844:    { ppc32_emit_XOR        , 0xfc0007fe , 0x7c000278 },
                   3845:    { ppc32_emit_XORI       , 0xfc000000 , 0x68000000 },
                   3846:    { ppc32_emit_XORIS      , 0xfc000000 , 0x6c000000 },
                   3847:    { ppc32_emit_unknown    , 0x00000000 , 0x00000000 },
1.1.1.2   root     3848:    { NULL                  , 0x00000000 , 0x00000000 },
1.1       root     3849: };

unix.superglobalmegacorp.com

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