Annotation of cf/ppc32_x86_trans.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

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