Annotation of cf/ppc32_x86_trans.c, revision 1.1.1.4

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

unix.superglobalmegacorp.com

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