Annotation of cf/ppc32_x86_trans.c, revision 1.1.1.5

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

unix.superglobalmegacorp.com

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