Annotation of cf/ppc32_amd64_trans.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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