Annotation of cf/mips64_x86_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 "mips64_jit.h"
                     17: #include "mips64_x86_trans.h"
                     18: #include "mips64_cp0.h"
                     19: #include "memory.h"
                     20: 
                     21: /* Macros for CPU structure access */
                     22: #define REG_OFFSET(reg)       (OFFSET(cpu_mips_t,gpr[(reg)]))
                     23: #define CP0_REG_OFFSET(c0reg) (OFFSET(cpu_mips_t,cp0.reg[(c0reg)]))
                     24: #define MEMOP_OFFSET(op)      (OFFSET(cpu_mips_t,mem_op_fn[(op)]))
                     25: 
                     26: #define DECLARE_INSN(name) \
                     27:    static int mips64_emit_##name(cpu_mips_t *cpu,mips64_jit_tcb_t *b, \
                     28:                                  mips_insn_t insn)
                     29: 
                     30: /* Set an IRQ */
                     31: void mips64_set_irq(cpu_mips_t *cpu,m_uint8_t irq)
                     32: {
                     33:    m_uint32_t m;
                     34:    m = (1 << (irq + MIPS_CP0_CAUSE_ISHIFT)) & MIPS_CP0_CAUSE_IMASK;
                     35:    atomic_or(&cpu->irq_cause,m);
                     36: }
                     37: 
                     38: /* Clear an IRQ */
                     39: void mips64_clear_irq(cpu_mips_t *cpu,m_uint8_t irq)
                     40: {
                     41:    m_uint32_t m;
                     42:    m = (1 << (irq + MIPS_CP0_CAUSE_ISHIFT)) & MIPS_CP0_CAUSE_IMASK;
                     43:    atomic_and(&cpu->irq_cause,~m);
                     44: 
                     45:    if (!cpu->irq_cause)
                     46:       cpu->irq_pending = 0;
                     47: }
                     48: 
                     49: /* Load a 64 bit immediate value */
                     50: static inline void mips64_load_imm(mips64_jit_tcb_t *b,
                     51:                                    u_int hi_reg,u_int lo_reg,
                     52:                                    m_uint64_t value)
                     53: {
                     54:    m_uint32_t hi_val = value >> 32;
                     55:    m_uint32_t lo_val = value & 0xffffffff;
                     56: 
                     57:    if (lo_val)
                     58:       x86_mov_reg_imm(b->jit_ptr,lo_reg,lo_val);
                     59:    else
                     60:       x86_alu_reg_reg(b->jit_ptr,X86_XOR,lo_reg,lo_reg);
                     61:    
                     62:    if (hi_val)
                     63:       x86_mov_reg_imm(b->jit_ptr,hi_reg,hi_val);
                     64:    else
                     65:       x86_alu_reg_reg(b->jit_ptr,X86_XOR,hi_reg,hi_reg);
                     66: }
                     67: 
                     68: /* Set the Pointer Counter (PC) register */
                     69: void mips64_set_pc(mips64_jit_tcb_t *b,m_uint64_t new_pc)
                     70: {
                     71:    x86_mov_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,pc),
                     72:                        new_pc & 0xFFFFFFFF,4);
                     73:    x86_mov_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,pc)+4,
                     74:                        new_pc >> 32,4);
                     75: }
                     76: 
                     77: /* Set the Return Address (RA) register */
                     78: void mips64_set_ra(mips64_jit_tcb_t *b,m_uint64_t ret_pc)
                     79: {
                     80:    mips64_load_imm(b,X86_EDX,X86_EAX,ret_pc);
                     81:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(MIPS_GPR_RA),X86_EAX,4);
                     82:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(MIPS_GPR_RA)+4,X86_EDX,4);
                     83: }
                     84: 
1.1.1.2 ! root       85: /* 
        !            86:  * Try to branch directly to the specified JIT block without returning to 
        !            87:  * main loop.
        !            88:  */
        !            89: static void mips64_try_direct_far_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b,
        !            90:                                        m_uint64_t new_pc)
        !            91: {
        !            92:    m_uint64_t new_page;
        !            93:    m_uint32_t pc_hash,pc_offset;
        !            94:    u_char *test1,*test2,*test3,*test4;
        !            95: 
        !            96:    new_page = new_pc & MIPS_MIN_PAGE_MASK;
        !            97:    pc_offset = (new_pc & MIPS_MIN_PAGE_IMASK) >> 2;
        !            98:    pc_hash = mips64_jit_get_pc_hash(new_pc);
        !            99: 
        !           100:    /* Get JIT block info in %edx */
        !           101:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,
        !           102:                        X86_EDI,OFFSET(cpu_mips_t,exec_blk_map),4);
        !           103:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EBX,pc_hash*sizeof(void *),4);
        !           104: 
        !           105:    /* no JIT block found ? */
        !           106:    x86_test_reg_reg(b->jit_ptr,X86_EDX,X86_EDX);
        !           107:    test1 = b->jit_ptr;
        !           108:    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
        !           109: 
        !           110:    /* Check block PC (lower 32-bits first) */
        !           111:    x86_mov_reg_imm(b->jit_ptr,X86_EAX,(m_uint32_t)new_page);
        !           112:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EAX,X86_EDX,
        !           113:                        OFFSET(mips64_jit_tcb_t,start_pc));
        !           114:    test2 = b->jit_ptr;
        !           115:    x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);
        !           116: 
        !           117:    /* Check higher bits... */
        !           118:    x86_mov_reg_imm(b->jit_ptr,X86_ECX,new_page >> 32);
        !           119:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_ECX,X86_EDX,
        !           120:                        OFFSET(mips64_jit_tcb_t,start_pc)+4);
        !           121:    test3 = b->jit_ptr;
        !           122:    x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);
        !           123: 
        !           124:    /* Jump to the code */
        !           125:    x86_mov_reg_membase(b->jit_ptr,X86_ESI,
        !           126:                        X86_EDX,OFFSET(mips64_jit_tcb_t,jit_insn_ptr),4);
        !           127:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,
        !           128:                        X86_ESI,pc_offset * sizeof(void *),4);
        !           129:    
        !           130:    x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
        !           131:    test4 = b->jit_ptr;
        !           132:    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
        !           133:    x86_jump_reg(b->jit_ptr,X86_EBX);
        !           134: 
        !           135:    /* Returns to caller... */
        !           136:    x86_patch(test1,b->jit_ptr);
        !           137:    x86_patch(test2,b->jit_ptr);
        !           138:    x86_patch(test3,b->jit_ptr);
        !           139:    x86_patch(test4,b->jit_ptr);
        !           140: 
        !           141:    mips64_set_pc(b,new_pc);
        !           142:    mips64_jit_tcb_push_epilog(b);
        !           143: }
        !           144: 
1.1       root      145: /* Set Jump */
                    146: static void mips64_set_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b,
                    147:                             m_uint64_t new_pc,int local_jump)
                    148: {      
                    149:    int return_to_caller = FALSE;
                    150:    u_char *jump_ptr;
                    151: 
                    152:    if (cpu->sym_trace && !local_jump)
                    153:       return_to_caller = TRUE;
                    154: 
                    155:    if (!return_to_caller && mips64_jit_tcb_local_addr(b,new_pc,&jump_ptr)) {
                    156:       if (jump_ptr) {
                    157:          x86_jump_code(b->jit_ptr,jump_ptr);
                    158:       } else {
1.1.1.2 ! root      159:          /* Never jump directly to code in a delay slot */
        !           160:          if (mips64_jit_is_delay_slot(b,new_pc)) {
        !           161:             mips64_set_pc(b,new_pc);
        !           162:             mips64_jit_tcb_push_epilog(b);
        !           163:             return;
        !           164:          }
        !           165: 
1.1       root      166:          mips64_jit_tcb_record_patch(b,b->jit_ptr,new_pc);
                    167:          x86_jump32(b->jit_ptr,0);
                    168:       }
                    169:    } else {
1.1.1.2 ! root      170:       if (cpu->exec_blk_direct_jump) {
        !           171:          /* Block lookup optimization */
        !           172:          mips64_try_direct_far_jump(cpu,b,new_pc);
        !           173:       } else {
        !           174:          mips64_set_pc(b,new_pc);
        !           175:          mips64_jit_tcb_push_epilog(b);
        !           176:       }
1.1       root      177:    }
                    178: }
                    179: 
                    180: /* Basic C call */
                    181: static forced_inline void mips64_emit_basic_c_call(mips64_jit_tcb_t *b,void *f)
                    182: {
                    183:    x86_mov_reg_imm(b->jit_ptr,X86_EBX,f);
                    184:    x86_call_reg(b->jit_ptr,X86_EBX);
                    185: }
                    186: 
                    187: /* Emit a simple call to a C function without any parameter */
                    188: static void mips64_emit_c_call(mips64_jit_tcb_t *b,void *f)
                    189: {   
                    190:    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
                    191:    mips64_emit_basic_c_call(b,f);
                    192: }
                    193: 
                    194: /* Single-step operation */
                    195: void mips64_emit_single_step(mips64_jit_tcb_t *b,mips_insn_t insn)
                    196: {
                    197:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                    198:    x86_mov_reg_imm(b->jit_ptr,X86_EDX,insn);
                    199:    mips64_emit_basic_c_call(b,mips64_exec_single_step);
                    200: }
                    201: 
                    202: /* Fast memory operation prototype */
                    203: typedef void (*memop_fast_access)(mips64_jit_tcb_t *b,int target);
                    204: 
                    205: /* Fast LW */
                    206: static void mips64_memop_fast_lw(mips64_jit_tcb_t *b,int target)
                    207: {
                    208:    x86_mov_reg_memindex(b->jit_ptr,X86_EAX,X86_EAX,0,X86_EBX,0,4);
                    209:    x86_bswap(b->jit_ptr,X86_EAX);
                    210:    x86_cdq(b->jit_ptr);
                    211:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(target),X86_EAX,4);
                    212:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(target)+4,X86_EDX,4);
                    213: }
                    214: 
                    215: /* Fast SW */
                    216: static void mips64_memop_fast_sw(mips64_jit_tcb_t *b,int target)
                    217: {
                    218:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,REG_OFFSET(target),4);
                    219:    x86_bswap(b->jit_ptr,X86_EDX);
                    220:    x86_mov_memindex_reg(b->jit_ptr,X86_EAX,0,X86_EBX,0,X86_EDX,4);
                    221: }
                    222: 
                    223: /* Fast memory operation (64-bit) */
                    224: static void mips64_emit_memop_fast64(mips64_jit_tcb_t *b,int write_op,
                    225:                                      int opcode,int base,int offset,
                    226:                                      int target,int keep_ll_bit,
                    227:                                      memop_fast_access op_handler)
                    228: {
                    229:    m_uint64_t val = sign_extend(offset,16);
                    230:    u_char *test1,*test2,*test3,*p_exception,*p_exit;
                    231: 
                    232:    test3 = NULL;
                    233: 
                    234:    /* ECX:EBX = sign-extended offset */
                    235:    mips64_load_imm(b,X86_ECX,X86_EBX,val);
                    236: 
                    237:    /* ECX:EBX = GPR[base] + sign-extended offset */
                    238:    x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EBX,X86_EDI,REG_OFFSET(base));
                    239:    x86_alu_reg_membase(b->jit_ptr,X86_ADC,X86_ECX,X86_EDI,REG_OFFSET(base)+4);
                    240: 
                    241:    /* EAX = mts32_entry index */
                    242:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EBX,4);
                    243:    x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_EAX,MTS32_HASH_SHIFT);
                    244:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,MTS32_HASH_MASK);
                    245: 
                    246:    /* EDX = mts32_entry */
                    247:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,
                    248:                        X86_EDI,OFFSET(cpu_mips_t,mts_u.mts64_cache),
                    249:                        4);
                    250:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EAX,5);
                    251:    x86_alu_reg_reg(b->jit_ptr,X86_ADD,X86_EDX,X86_EAX);
                    252: 
                    253:    /* Compare virtual page address (ESI = vpage) */
                    254:    x86_mov_reg_reg(b->jit_ptr,X86_ESI,X86_EBX,4);
                    255:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,MIPS_MIN_PAGE_MASK);
                    256: 
                    257:    /* Compare the high part of the vaddr */
                    258:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_ECX,X86_EDX,
                    259:                        OFFSET(mts64_entry_t,gvpa)+4);
                    260:    test1 = b->jit_ptr;
                    261:    x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
                    262: 
                    263:    /* Compare the low part of the vaddr */
                    264:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_ESI,X86_EDX,
                    265:                        OFFSET(mts64_entry_t,gvpa));
                    266:    test2 = b->jit_ptr;
                    267:    x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
                    268: 
                    269:    /* Test if we are writing to a COW page */
                    270:    if (write_op) {
                    271:       x86_test_membase_imm(b->jit_ptr,X86_EDX,OFFSET(mts64_entry_t,flags),
                    272:                            MTS_FLAG_COW);
                    273:       test3 = b->jit_ptr;
                    274:       x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
                    275:    }
                    276: 
                    277:    /* EBX = offset in page, EAX = Host Page Address */
                    278:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,MIPS_MIN_PAGE_IMASK);
                    279:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDX,OFFSET(mts64_entry_t,hpa),4);
                    280: 
                    281:    /* Memory access */
                    282:    op_handler(b,target);
                    283:  
                    284:    p_exit = b->jit_ptr;
                    285:    x86_jump8(b->jit_ptr,0);
                    286: 
                    287:    /* === Slow lookup === */
                    288:    x86_patch(test1,b->jit_ptr);
                    289:    x86_patch(test2,b->jit_ptr);
                    290:    if (test3)
                    291:       x86_patch(test3,b->jit_ptr);
                    292: 
                    293:    /* Update PC (ECX:EBX = vaddr) */
                    294:    x86_mov_reg_reg(b->jit_ptr,X86_ESI,X86_EBX,4);
                    295:    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
                    296:    x86_mov_reg_reg(b->jit_ptr,X86_EDX,X86_ESI,4);
                    297: 
                    298:    /* EBX = target register */
                    299:    x86_mov_reg_imm(b->jit_ptr,X86_EBX,target);
                    300: 
                    301:    /* EAX = CPU instance pointer */
                    302:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                    303: 
                    304:    /* 
                    305:     * Push parameters on stack and call memory function.
                    306:     * Keep the stack aligned on a 16-byte boundary for Darwin/x86.
                    307:     */
                    308:    x86_alu_reg_imm(b->jit_ptr,X86_SUB,X86_ESP,8);
                    309:    x86_push_reg(b->jit_ptr,X86_EBX);
                    310:    x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(opcode));
                    311:    x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);
                    312: 
                    313:    /* Check for exception */
                    314:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                    315:    p_exception = b->jit_ptr;
                    316:    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
                    317:    mips64_jit_tcb_push_epilog(b);
                    318: 
                    319:    x86_patch(p_exit,b->jit_ptr);
                    320:    x86_patch(p_exception,b->jit_ptr);
                    321: }
                    322: 
                    323: /* Fast memory operation (32-bit) */
                    324: static void mips64_emit_memop_fast32(mips64_jit_tcb_t *b,int write_op,
                    325:                                      int opcode,int base,int offset,
                    326:                                      int target,int keep_ll_bit,
                    327:                                      memop_fast_access op_handler)
                    328: {
                    329:    m_uint32_t val = sign_extend(offset,16);
                    330:    u_char *test1,*test2,*p_exception,*p_exit;
                    331: 
                    332:    test2 = NULL;
                    333: 
                    334:    /* EBX = sign-extended offset */
                    335:    x86_mov_reg_imm(b->jit_ptr,X86_EBX,val);
                    336: 
                    337:    /* EBX = GPR[base] + sign-extended offset */
                    338:    x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EBX,X86_EDI,REG_OFFSET(base));
                    339: 
                    340:    /* EAX = mts32_entry index */
                    341:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EBX,4);
                    342:    x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_EAX,MTS32_HASH_SHIFT);
                    343:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,MTS32_HASH_MASK);
                    344: 
                    345:    /* EDX = mts32_entry */
                    346:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,
                    347:                        X86_EDI,OFFSET(cpu_mips_t,mts_u.mts32_cache),
                    348:                        4);
                    349:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EAX,4);
                    350:    x86_alu_reg_reg(b->jit_ptr,X86_ADD,X86_EDX,X86_EAX);
                    351: 
                    352:    /* Compare virtual page address (ESI = vpage) */
                    353:    x86_mov_reg_reg(b->jit_ptr,X86_ESI,X86_EBX,4);
                    354:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,PPC32_MIN_PAGE_MASK);
                    355: 
                    356:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_ESI,X86_EDX,
                    357:                        OFFSET(mts32_entry_t,gvpa));
                    358:    test1 = b->jit_ptr;
                    359:    x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
                    360: 
                    361:    /* Test if we are writing to a COW page */
                    362:    if (write_op) {
                    363:       x86_test_membase_imm(b->jit_ptr,X86_EDX,OFFSET(mts32_entry_t,flags),
                    364:                            MTS_FLAG_COW);
                    365:       test2 = b->jit_ptr;
                    366:       x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
                    367:    }
                    368: 
                    369:    /* EBX = offset in page, EAX = Host Page Address */
                    370:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,PPC32_MIN_PAGE_IMASK);
                    371:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDX,OFFSET(mts32_entry_t,hpa),4);
                    372: 
                    373:    /* Memory access */
                    374:    op_handler(b,target);
                    375:  
                    376:    p_exit = b->jit_ptr;
                    377:    x86_jump8(b->jit_ptr,0);
                    378: 
                    379:    /* === Slow lookup === */
                    380:    x86_patch(test1,b->jit_ptr);
                    381:    if (test2)
                    382:       x86_patch(test2,b->jit_ptr);
                    383: 
                    384:    /* Update PC (EBX = vaddr) */
                    385:    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
                    386: 
                    387:    /* Sign-extend virtual address and put vaddr in ECX:EDX */
                    388:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EBX,4);
                    389:    x86_cdq(b->jit_ptr);
                    390:    x86_mov_reg_reg(b->jit_ptr,X86_ECX,X86_EDX,4);
                    391:    x86_mov_reg_reg(b->jit_ptr,X86_EDX,X86_EAX,4);
                    392: 
                    393:    /* EBX = target register */
                    394:    x86_mov_reg_imm(b->jit_ptr,X86_EBX,target);
                    395: 
                    396:    /* EAX = CPU instance pointer */
                    397:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                    398: 
                    399:    /* 
                    400:     * Push parameters on stack and call memory function.
                    401:     * Keep the stack aligned on a 16-byte boundary for Darwin/x86.
                    402:     */
                    403:    x86_alu_reg_imm(b->jit_ptr,X86_SUB,X86_ESP,8);
                    404:    x86_push_reg(b->jit_ptr,X86_EBX);
                    405:    x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(opcode));
                    406:    x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);
                    407: 
                    408:    /* Check for exception */
                    409:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                    410:    p_exception = b->jit_ptr;
                    411:    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
                    412:    mips64_jit_tcb_push_epilog(b);
                    413: 
                    414:    x86_patch(p_exit,b->jit_ptr);
                    415:    x86_patch(p_exception,b->jit_ptr);
                    416: }
                    417: 
                    418: /* Fast memory operation */
                    419: static void mips64_emit_memop_fast(cpu_mips_t *cpu,mips64_jit_tcb_t *b,
                    420:                                    int write_op,int opcode,
                    421:                                    int base,int offset,
                    422:                                    int target,int keep_ll_bit,
                    423:                                    memop_fast_access op_handler)
                    424: {
                    425:    switch(cpu->addr_mode) {
                    426:       case 32:
                    427:          mips64_emit_memop_fast32(b,write_op,opcode,base,offset,target,
                    428:                                   keep_ll_bit,op_handler);
                    429:          break;
                    430:       case 64:
                    431:          mips64_emit_memop_fast64(b,write_op,opcode,base,offset,target,
                    432:                                   keep_ll_bit,op_handler);
                    433:          break;
                    434:    }
                    435: }
                    436: 
                    437: /* Memory operation */
                    438: static void mips64_emit_memop(mips64_jit_tcb_t *b,int op,int base,int offset,
                    439:                               int target,int keep_ll_bit)
                    440: {
                    441:    m_uint64_t val = sign_extend(offset,16);
                    442:    u_char *test1;
                    443: 
                    444:    /* Save PC for exception handling */
                    445:    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
                    446: 
                    447:    if (!keep_ll_bit) {
                    448:       x86_clear_reg(b->jit_ptr,X86_EAX);
                    449:       x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,ll_bit),
                    450:                           X86_EAX,4);
                    451:    }
                    452: 
                    453:    /* ECX:EDX = sign-extended offset */
                    454:    mips64_load_imm(b,X86_ECX,X86_EDX,val);
                    455: 
                    456:    /* ECX:EDX = GPR[base] + sign-extended offset */
                    457:    x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EDX,X86_EDI,REG_OFFSET(base));
                    458:    x86_alu_reg_membase(b->jit_ptr,X86_ADC,X86_ECX,X86_EDI,REG_OFFSET(base)+4);
                    459: 
                    460:    /* EBX = target register */
                    461:    x86_mov_reg_imm(b->jit_ptr,X86_EBX,target);
                    462:    
                    463:    /* EAX = CPU instance pointer */
                    464:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                    465: 
                    466:    /* 
                    467:     * Push parameters on stack and call memory function.
                    468:     * Keep the stack aligned on a 16-byte boundary for Darwin/x86.
                    469:     */
                    470:    x86_alu_reg_imm(b->jit_ptr,X86_SUB,X86_ESP,8);
                    471:    x86_push_reg(b->jit_ptr,X86_EBX);
                    472:    x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(op));
                    473:    x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);
                    474: 
                    475:    /* Exception ? */
                    476:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                    477:    test1 = b->jit_ptr;
                    478:    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
                    479:    mips64_jit_tcb_push_epilog(b);
                    480:    x86_patch(test1,b->jit_ptr);
                    481: }
                    482: 
                    483: /* Coprocessor Register transfert operation */
                    484: static void mips64_emit_cp_xfr_op(mips64_jit_tcb_t *b,int rt,int rd,void *f)
                    485: {
                    486:    /* update pc */
                    487:    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
                    488: 
                    489:    /* cp0 register */
                    490:    x86_mov_reg_imm(b->jit_ptr,X86_ECX,rd);
                    491: 
                    492:    /* gpr */
                    493:    x86_mov_reg_imm(b->jit_ptr,X86_EDX,rt);
                    494: 
                    495:    /* cpu instance */
                    496:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                    497: 
                    498:    mips64_emit_basic_c_call(b,f);
                    499: }
                    500: 
                    501: /* Virtual Breakpoint */
                    502: void mips64_emit_breakpoint(mips64_jit_tcb_t *b)
                    503: {
                    504:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                    505:    mips64_emit_c_call(b,mips64_run_breakpoint);
                    506: }
                    507: 
                    508: /* Unknown opcode handler */
                    509: static asmlinkage void mips64_unknown_opcode(cpu_mips_t *cpu,m_uint32_t opcode)
                    510: {
                    511:    printf("MIPS64: unhandled opcode 0x%8.8x at 0x%llx (ra=0x%llx)\n",
                    512:           opcode,cpu->pc,cpu->gpr[MIPS_GPR_RA]);
                    513: 
                    514:    mips64_dump_regs(cpu->gen);
                    515: }
                    516: 
                    517: /* Emit unhandled instruction code */
                    518: static int mips64_emit_unknown(cpu_mips_t *cpu,mips64_jit_tcb_t *b,
                    519:                                mips_insn_t opcode)
                    520: {   
                    521:    x86_mov_reg_imm(b->jit_ptr,X86_EAX,opcode);
                    522:    x86_alu_reg_imm(b->jit_ptr,X86_SUB,X86_ESP,4);
                    523:    x86_push_reg(b->jit_ptr,X86_EAX);
                    524:    x86_push_reg(b->jit_ptr,X86_EDI);
                    525:    mips64_emit_c_call(b,mips64_unknown_opcode);
                    526:    x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);
                    527:    return(0);
                    528: }
                    529: 
                    530: /* Invalid delay slot handler */
                    531: static fastcall void mips64_invalid_delay_slot(cpu_mips_t *cpu)
                    532: {
                    533:    printf("MIPS64: invalid instruction in delay slot at 0x%llx (ra=0x%llx)\n",
                    534:           cpu->pc,cpu->gpr[MIPS_GPR_RA]);
                    535: 
                    536:    mips64_dump_regs(cpu->gen);
                    537: 
                    538:    /* Halt the virtual CPU */
                    539:    cpu->pc = 0;
                    540: }
                    541: 
                    542: /* Emit unhandled instruction code */
                    543: int mips64_emit_invalid_delay_slot(mips64_jit_tcb_t *b)
                    544: {   
                    545:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                    546:    mips64_emit_c_call(b,mips64_invalid_delay_slot);
                    547:    mips64_jit_tcb_push_epilog(b);
                    548:    return(0);
                    549: }
                    550: 
                    551: /* Located in external assembly module */
                    552: #ifdef FAST_ASM
                    553: extern void mips64_inc_cp0_cnt_asm(void);
                    554: #endif
                    555: 
                    556: /* 
                    557:  * Increment count register and trigger the timer IRQ if value in compare 
                    558:  * register is the same.
                    559:  */
                    560: void mips64_inc_cp0_count_reg(mips64_jit_tcb_t *b)
                    561: {
                    562:    x86_inc_membase(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,cp0_virt_cnt_reg));
                    563: 
                    564: #if 0 /* TIMER_IRQ */
                    565: #ifdef FAST_ASM
                    566:    mips64_emit_basic_c_call(b,mips64_inc_cp0_cnt_asm);
                    567: #else
                    568:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                    569:    mips64_emit_basic_c_call(b,mips64_exec_inc_cp0_cnt);
                    570: #endif
                    571: #endif
                    572: }
                    573: 
                    574: /* Check if there are pending IRQ */
                    575: void mips64_check_pending_irq(mips64_jit_tcb_t *b)
                    576: {
                    577:    u_char *test1;
                    578: 
                    579:    /* Check the pending IRQ flag */
                    580:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,
                    581:                        X86_EDI,OFFSET(cpu_mips_t,irq_pending),4);
                    582:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                    583:    test1 = b->jit_ptr;
                    584:    x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
                    585: 
                    586:    /* Save PC */
                    587:    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
                    588: 
                    589:    /* Trigger the IRQ */
                    590:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                    591:    mips64_emit_basic_c_call(b,mips64_trigger_irq);
                    592:    mips64_jit_tcb_push_epilog(b);
                    593: 
                    594:    x86_patch(test1,b->jit_ptr);
                    595: }
                    596: 
                    597: /* Increment the number of executed instructions (performance debugging) */
                    598: void mips64_inc_perf_counter(mips64_jit_tcb_t *b)
                    599: {
                    600:    x86_alu_membase_imm(b->jit_ptr,X86_ADD,
                    601:                        X86_EDI,OFFSET(cpu_mips_t,perf_counter),1);
                    602:    x86_alu_membase_imm(b->jit_ptr,X86_ADC,
                    603:                        X86_EDI,OFFSET(cpu_mips_t,perf_counter)+4,0);
                    604: }
                    605: 
                    606: /* ADD */
                    607: DECLARE_INSN(ADD)
                    608: {      
                    609:    int rs = bits(insn,21,25);
                    610:    int rt = bits(insn,16,20);
                    611:    int rd = bits(insn,11,15);
                    612: 
                    613:    /* TODO: Exception handling */
                    614: 
                    615:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                    616:    x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EAX,X86_EDI,REG_OFFSET(rt));
                    617:    
                    618:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                    619:    x86_cdq(b->jit_ptr);
                    620:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);
                    621:    return(0);
                    622: }
                    623: 
                    624: /* ADDI */
                    625: DECLARE_INSN(ADDI)
                    626: {
                    627:    int rs  = bits(insn,21,25);
                    628:    int rt  = bits(insn,16,20);
                    629:    int imm = bits(insn,0,15);
                    630:    m_uint64_t val = sign_extend(imm,16);
                    631: 
                    632:    /* TODO: Exception handling */
                    633: 
                    634:    x86_mov_reg_imm(b->jit_ptr,X86_EAX,val & 0xffffffff);
                    635:    x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EAX,X86_EDI,REG_OFFSET(rs));
                    636: 
                    637:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt),X86_EAX,4);
                    638:    x86_cdq(b->jit_ptr);
                    639:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt)+4,X86_EDX,4);
                    640:    return(0);
                    641: }
                    642: 
                    643: /* ADDIU */
                    644: DECLARE_INSN(ADDIU)
                    645: {
                    646:    int rs  = bits(insn,21,25);
                    647:    int rt  = bits(insn,16,20);
                    648:    int imm = bits(insn,0,15);
                    649:    m_uint64_t val = sign_extend(imm,16);
                    650: 
                    651:    x86_mov_reg_imm(b->jit_ptr,X86_EAX,val & 0xffffffff);
                    652:    x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EAX,X86_EDI,REG_OFFSET(rs));
                    653: 
                    654:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt),X86_EAX,4);
                    655:    x86_cdq(b->jit_ptr);
                    656:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt)+4,X86_EDX,4);
                    657:    return(0);
                    658: }
                    659: 
                    660: /* ADDU */
                    661: DECLARE_INSN(ADDU)
                    662: {      
                    663:    int rs = bits(insn,21,25);
                    664:    int rt = bits(insn,16,20);
                    665:    int rd = bits(insn,11,15);
                    666:    
                    667:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                    668:    x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EAX,X86_EDI,REG_OFFSET(rt));
                    669:    
                    670:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                    671:    x86_cdq(b->jit_ptr);
                    672:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);
                    673:    return(0);
                    674: }
                    675: 
                    676: /* AND */
                    677: DECLARE_INSN(AND)
                    678: {
                    679:    int rs = bits(insn,21,25);
                    680:    int rt = bits(insn,16,20);
                    681:    int rd = bits(insn,11,15);
                    682: 
                    683:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                    684:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                    685: 
                    686:    x86_alu_reg_membase(b->jit_ptr,X86_AND,X86_EAX,X86_EDI,REG_OFFSET(rt));
                    687:    x86_alu_reg_membase(b->jit_ptr,X86_AND,X86_EBX,X86_EDI,REG_OFFSET(rt)+4);
                    688: 
                    689:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                    690:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                    691: 
                    692:    return(0);
                    693: }
                    694: 
                    695: /* ANDI */
                    696: DECLARE_INSN(ANDI)
                    697: {
                    698:    int rs  = bits(insn,21,25);
                    699:    int rt  = bits(insn,16,20);
                    700:    int imm = bits(insn,0,15);
                    701: 
                    702:    x86_mov_reg_imm(b->jit_ptr,X86_EAX,imm);
                    703:    x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EBX,X86_EBX);
                    704: 
                    705:    x86_alu_reg_membase(b->jit_ptr,X86_AND,X86_EAX,X86_EDI,REG_OFFSET(rs));
                    706: 
                    707:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt),X86_EAX,4);
                    708:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt)+4,X86_EBX,4);
                    709: 
                    710:    return(0);
                    711: }
                    712: 
                    713: /* B (Branch, virtual instruction) */
                    714: DECLARE_INSN(B)
                    715: {
                    716:    int offset = bits(insn,0,15);
                    717:    m_uint64_t new_pc;
                    718: 
                    719:    /* compute the new pc */
                    720:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                    721:    new_pc += sign_extend(offset << 2,18);
                    722: 
                    723:    /* insert the instruction in the delay slot */
                    724:    mips64_jit_fetch_and_emit(cpu,b,1);
                    725: 
                    726:    /* set the new pc in cpu structure */
                    727:    mips64_set_jump(cpu,b,new_pc,1);
                    728:    return(0);
                    729: }
                    730: 
                    731: /* BAL (Branch and Link, virtual instruction) */
                    732: DECLARE_INSN(BAL)
                    733: {
                    734:    int offset = bits(insn,0,15);
                    735:    m_uint64_t new_pc;
                    736: 
                    737:    /* compute the new pc */
                    738:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                    739:    new_pc += sign_extend(offset << 2,18);
                    740: 
                    741:    /* set the return address (instruction after the delay slot) */
                    742:    mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2));
                    743: 
                    744:    /* insert the instruction in the delay slot */
                    745:    mips64_jit_fetch_and_emit(cpu,b,1);
                    746: 
                    747:    /* set the new pc in cpu structure */
                    748:    mips64_set_jump(cpu,b,new_pc,0);
                    749:    return(0);
                    750: }
                    751: 
                    752: /* BEQ (Branch On Equal) */
                    753: DECLARE_INSN(BEQ)
                    754: {
                    755:    int rs = bits(insn,21,25);
                    756:    int rt = bits(insn,16,20);
                    757:    int offset = bits(insn,0,15);
                    758:    u_char *test1,*test2;
                    759:    m_uint64_t new_pc;
                    760: 
                    761:    /* compute the new pc */
                    762:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                    763:    new_pc += sign_extend(offset << 2,18);
                    764:    
                    765:    /* 
                    766:     * compare gpr[rs] and gpr[rt]. 
                    767:     * compare the low 32 bits first (higher probability).
                    768:     */
                    769:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                    770:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EAX,X86_EDI,REG_OFFSET(rt));
                    771:    test1 = b->jit_ptr;
                    772:    x86_branch32(b->jit_ptr, X86_CC_NE, 0, 1);
                    773: 
                    774:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                    775:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EBX,X86_EDI,REG_OFFSET(rt)+4);
                    776:    test2 = b->jit_ptr;
                    777:    x86_branch32(b->jit_ptr, X86_CC_NE, 0, 1);
                    778: 
                    779:    /* insert the instruction in the delay slot */
                    780:    mips64_jit_fetch_and_emit(cpu,b,2);
                    781: 
                    782:    /* set the new pc in cpu structure */
                    783:    mips64_set_jump(cpu,b,new_pc,1);
                    784: 
                    785:    x86_patch(test1,b->jit_ptr);
                    786:    x86_patch(test2,b->jit_ptr);
                    787: 
                    788:    /* if the branch is not taken, we have to execute the delay slot too */
                    789:    mips64_jit_fetch_and_emit(cpu,b,1);
                    790:    return(0);
                    791: }
                    792: 
                    793: /* BEQL (Branch On Equal Likely) */
                    794: DECLARE_INSN(BEQL)
                    795: {
                    796:    int rs = bits(insn,21,25);
                    797:    int rt = bits(insn,16,20);
                    798:    int offset = bits(insn,0,15);
                    799:    u_char *test1,*test2;
                    800:    m_uint64_t new_pc;
                    801: 
                    802:    /* compute the new pc */
                    803:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                    804:    new_pc += sign_extend(offset << 2,18);
                    805: 
                    806:    /* 
                    807:     * compare gpr[rs] and gpr[rt]. 
                    808:     * compare the low 32 bits first (higher probability).
                    809:     */
                    810:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                    811:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EAX,X86_EDI,REG_OFFSET(rt));
                    812:    test1 = b->jit_ptr;
                    813:    x86_branch32(b->jit_ptr, X86_CC_NE, 0, 1);
                    814: 
                    815:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                    816:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EBX,X86_EDI,REG_OFFSET(rt)+4);
                    817:    test2 = b->jit_ptr;
                    818:    x86_branch32(b->jit_ptr, X86_CC_NE, 0, 1);
                    819: 
                    820:    /* insert the instruction in the delay slot */
                    821:    mips64_jit_fetch_and_emit(cpu,b,1);
                    822: 
                    823:    /* set the new pc in cpu structure */
                    824:    mips64_set_jump(cpu,b,new_pc,1);
                    825: 
                    826:    x86_patch(test1,b->jit_ptr);
                    827:    x86_patch(test2,b->jit_ptr);
                    828:    return(0);
                    829: }
                    830: 
                    831: /* BEQZ (Branch On Equal Zero - optimization) */
                    832: DECLARE_INSN(BEQZ)
                    833: {
                    834:    int rs = bits(insn,21,25);
                    835:    int offset = bits(insn,0,15);
                    836:    u_char *test1,*test2;
                    837:    m_uint64_t new_pc;
                    838: 
                    839:    /* compute the new pc */
                    840:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                    841:    new_pc += sign_extend(offset << 2,18);
                    842:    
                    843:    /* 
                    844:     * compare gpr[rs] with 0.
                    845:     * compare the low 32 bits first (higher probability).
                    846:     */
                    847:    x86_alu_membase_imm(b->jit_ptr,X86_CMP,X86_EDI,REG_OFFSET(rs),0);
                    848:    test1 = b->jit_ptr;
                    849:    x86_branch32(b->jit_ptr, X86_CC_NE, 0, 1);
                    850: 
                    851:    x86_alu_membase_imm(b->jit_ptr,X86_CMP,X86_EDI,REG_OFFSET(rs)+4,0);
                    852:    test2 = b->jit_ptr;
                    853:    x86_branch32(b->jit_ptr, X86_CC_NE, 0, 1);
                    854: 
                    855:    /* insert the instruction in the delay slot */
                    856:    mips64_jit_fetch_and_emit(cpu,b,2);
                    857: 
                    858:    /* set the new pc in cpu structure */
                    859:    mips64_set_jump(cpu,b,new_pc,1);
                    860: 
                    861:    x86_patch(test1,b->jit_ptr);
                    862:    x86_patch(test2,b->jit_ptr);
                    863: 
                    864:    /* if the branch is not taken, we have to execute the delay slot too */
                    865:    mips64_jit_fetch_and_emit(cpu,b,1);
                    866:    return(0);
                    867: }
                    868: 
                    869: /* BNEZ (Branch On Not Equal Zero - optimization) */
                    870: DECLARE_INSN(BNEZ)
                    871: {
                    872:    int rs = bits(insn,21,25);
                    873:    int offset = bits(insn,0,15);
                    874:    u_char *test1,*test2;
                    875:    m_uint64_t new_pc;
                    876: 
                    877:    /* compute the new pc */
                    878:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                    879:    new_pc += sign_extend(offset << 2,18);
                    880:    
                    881:    /* 
                    882:     * compare gpr[rs] with 0.
                    883:     * compare the low 32 bits first (higher probability).
                    884:     */
                    885:    x86_alu_membase_imm(b->jit_ptr,X86_CMP,X86_EDI,REG_OFFSET(rs),0);
                    886:    test1 = b->jit_ptr;
                    887:    x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);
                    888: 
                    889:    x86_alu_membase_imm(b->jit_ptr,X86_CMP,X86_EDI,REG_OFFSET(rs)+4,0);
                    890:    test2 = b->jit_ptr;
                    891:    x86_branch32(b->jit_ptr, X86_CC_E, 0, 1);
                    892: 
                    893:    x86_patch(test1,b->jit_ptr);
                    894: 
                    895:    /* insert the instruction in the delay slot */
                    896:    mips64_jit_fetch_and_emit(cpu,b,2);
                    897: 
                    898:    /* set the new pc in cpu structure */
                    899:    mips64_set_jump(cpu,b,new_pc,1);
                    900: 
                    901:    x86_patch(test2,b->jit_ptr);
                    902: 
                    903:    /* if the branch is not taken, we have to execute the delay slot too */
                    904:    mips64_jit_fetch_and_emit(cpu,b,1);
                    905:    return(0);
                    906: }
                    907: 
                    908: /* BGEZ (Branch On Greater or Equal Than Zero) */
                    909: DECLARE_INSN(BGEZ)
                    910: {
                    911:    int rs = bits(insn,21,25);
                    912:    int offset = bits(insn,0,15);
                    913:    u_char *test1;
                    914:    m_uint64_t new_pc;
                    915: 
                    916:    /* compute the new pc */
                    917:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                    918:    new_pc += sign_extend(offset << 2,18);
                    919: 
                    920:    /* If sign bit is set, don't take the branch */
                    921:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs)+4,4);
                    922:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                    923:    test1 = b->jit_ptr;
                    924:    x86_branch32(b->jit_ptr, X86_CC_S, 0, 1);
                    925: 
                    926:    /* insert the instruction in the delay slot */
                    927:    mips64_jit_fetch_and_emit(cpu,b,2);
                    928: 
                    929:    /* set the new pc in cpu structure */
                    930:    mips64_set_jump(cpu,b,new_pc,1);
                    931: 
                    932:    x86_patch(test1,b->jit_ptr);
                    933: 
                    934:    /* if the branch is not taken, we have to execute the delay slot too */
                    935:    mips64_jit_fetch_and_emit(cpu,b,1);
                    936:    return(0);
                    937: }
                    938: 
                    939: /* BGEZAL (Branch On Greater or Equal Than Zero And Link) */
                    940: DECLARE_INSN(BGEZAL)
                    941: {
                    942:    int rs = bits(insn,21,25);
                    943:    int offset = bits(insn,0,15);
                    944:    u_char *test1;
                    945:    m_uint64_t new_pc;
                    946: 
                    947:    /* compute the new pc */
                    948:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                    949:    new_pc += sign_extend(offset << 2,18);
                    950: 
                    951:    /* set the return address (instruction after the delay slot) */
                    952:    mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2));
                    953: 
                    954:    /* If sign bit is set, don't take the branch */
                    955:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs)+4,4);
                    956:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                    957:    test1 = b->jit_ptr;
                    958:    x86_branch32(b->jit_ptr, X86_CC_S, 0, 1);
                    959: 
                    960:    /* insert the instruction in the delay slot */
                    961:    mips64_jit_fetch_and_emit(cpu,b,2);
                    962: 
                    963:    /* set the new pc in cpu structure */
                    964:    mips64_set_jump(cpu,b,new_pc,1);
                    965: 
                    966:    x86_patch(test1,b->jit_ptr);
                    967: 
                    968:    /* if the branch is not taken, we have to execute the delay slot too */
                    969:    mips64_jit_fetch_and_emit(cpu,b,1);
                    970:    return(0);
                    971: }
                    972: 
                    973: /* BGEZALL (Branch On Greater or Equal Than Zero and Link Likely) */
                    974: DECLARE_INSN(BGEZALL)
                    975: {
                    976:    int rs = bits(insn,21,25);
                    977:    int offset = bits(insn,0,15);
                    978:    u_char *test1;
                    979:    m_uint64_t new_pc;
                    980: 
                    981:    /* compute the new pc */
                    982:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                    983:    new_pc += sign_extend(offset << 2,18);
                    984: 
                    985:    /* set the return address (instruction after the delay slot) */
                    986:    mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2));
                    987: 
                    988:    /* if sign bit is set, don't take the branch */
                    989:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs)+4,4);
                    990:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                    991:    test1 = b->jit_ptr;
                    992:    x86_branch32(b->jit_ptr, X86_CC_S, 0, 1);
                    993: 
                    994:    /* insert the instruction in the delay slot */
                    995:    mips64_jit_fetch_and_emit(cpu,b,1);
                    996: 
                    997:    /* set the new pc in cpu structure */
                    998:    mips64_set_jump(cpu,b,new_pc,1);
                    999: 
                   1000:    x86_patch(test1,b->jit_ptr);
                   1001:    return(0);
                   1002: }
                   1003: 
                   1004: /* BGEZL (Branch On Greater or Equal Than Zero Likely) */
                   1005: DECLARE_INSN(BGEZL)
                   1006: {
                   1007:    int rs = bits(insn,21,25);
                   1008:    int offset = bits(insn,0,15);
                   1009:    u_char *test1;
                   1010:    m_uint64_t new_pc;
                   1011: 
                   1012:    /* compute the new pc */
                   1013:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                   1014:    new_pc += sign_extend(offset << 2,18);
                   1015: 
                   1016:    /* if sign bit is set, don't take the branch */
                   1017:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs)+4,4);
                   1018:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                   1019:    test1 = b->jit_ptr;
                   1020:    x86_branch32(b->jit_ptr, X86_CC_S, 0, 1);
                   1021: 
                   1022:    /* insert the instruction in the delay slot */
                   1023:    mips64_jit_fetch_and_emit(cpu,b,1);
                   1024: 
                   1025:    /* set the new pc in cpu structure */
                   1026:    mips64_set_jump(cpu,b,new_pc,1);
                   1027: 
                   1028:    x86_patch(test1,b->jit_ptr);
                   1029:    return(0);
                   1030: }
                   1031: 
                   1032: /* BGTZ (Branch On Greater Than Zero) */
                   1033: DECLARE_INSN(BGTZ)
                   1034: {
                   1035:    int rs = bits(insn,21,25);
                   1036:    int offset = bits(insn,0,15);
                   1037:    u_char *test1,*test2,*test3;
                   1038:    m_uint64_t new_pc;
                   1039: 
                   1040:    /* compute the new pc */
                   1041:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                   1042:    new_pc += sign_extend(offset << 2,18);
                   1043: 
                   1044:    /* 
                   1045:     * test the hi word of gpr[rs]
                   1046:     */
                   1047:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs)+4,4);
                   1048:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                   1049:    test1 = b->jit_ptr;
                   1050:    x86_branch32(b->jit_ptr, X86_CC_S, 0, 1);
                   1051:    test2 = b->jit_ptr;
                   1052:    x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
                   1053: 
                   1054:    /* test the lo word of gpr[rs] (here hi word = 0) */
                   1055:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs),4);
                   1056:    x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                   1057:    test3 = b->jit_ptr;
                   1058:    x86_branch32(b->jit_ptr, X86_CC_Z, 0, 1);
                   1059: 
                   1060:    /* here, we take the branch */
                   1061:    x86_patch(test2,b->jit_ptr);
                   1062: 
                   1063:    /* insert the instruction in the delay slot */
                   1064:    mips64_jit_fetch_and_emit(cpu,b,2);
                   1065: 
                   1066:    /* set the new pc in cpu structure */
                   1067:    mips64_set_jump(cpu,b,new_pc,1);
                   1068: 
                   1069:    x86_patch(test1,b->jit_ptr);
                   1070:    x86_patch(test3,b->jit_ptr);
                   1071: 
                   1072:    /* if the branch is not taken, we have to execute the delay slot too */
                   1073:    mips64_jit_fetch_and_emit(cpu,b,1);
                   1074:    return(0);
                   1075: }
                   1076: 
                   1077: /* BGTZL (Branch On Greater Than Zero Likely) */
                   1078: DECLARE_INSN(BGTZL)
                   1079: {
                   1080:    int rs = bits(insn,21,25);
                   1081:    int offset = bits(insn,0,15);
                   1082:    u_char *test1,*test2,*test3;
                   1083:    m_uint64_t new_pc;
                   1084: 
                   1085:    /* compute the new pc */
                   1086:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                   1087:    new_pc += sign_extend(offset << 2,18);
                   1088: 
                   1089:    /* 
                   1090:     * test the hi word of gpr[rs]
                   1091:     */
                   1092:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs)+4,4);
                   1093:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                   1094:    test1 = b->jit_ptr;
                   1095:    x86_branch32(b->jit_ptr, X86_CC_S, 0, 1);
                   1096:    test2 = b->jit_ptr;
                   1097:    x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
                   1098: 
                   1099:    /* test the lo word of gpr[rs] (here hi word = 0) */
                   1100:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs),4);
                   1101:    x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                   1102:    test3 = b->jit_ptr;
                   1103:    x86_branch32(b->jit_ptr, X86_CC_Z, 0, 1);
                   1104: 
                   1105:    /* here, we take the branch */
                   1106:    x86_patch(test2,b->jit_ptr);
                   1107: 
                   1108:    /* insert the instruction in the delay slot */
                   1109:    mips64_jit_fetch_and_emit(cpu,b,1);
                   1110: 
                   1111:    /* set the new pc in cpu structure */
                   1112:    mips64_set_jump(cpu,b,new_pc,1);
                   1113: 
                   1114:    x86_patch(test1,b->jit_ptr);
                   1115:    x86_patch(test3,b->jit_ptr);
                   1116:    return(0);
                   1117: }
                   1118: 
                   1119: /* BLEZ (Branch On Less or Equal Than Zero) */
                   1120: DECLARE_INSN(BLEZ)
                   1121: {
                   1122:    int rs = bits(insn,21,25);
                   1123:    int offset = bits(insn,0,15);
                   1124:    u_char *test1,*test2,*test3;
                   1125:    m_uint64_t new_pc;
                   1126: 
                   1127:    /* compute the new pc */
                   1128:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                   1129:    new_pc += sign_extend(offset << 2,18);
                   1130: 
                   1131:    /* 
                   1132:     * test the hi word of gpr[rs]
                   1133:     */
                   1134:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs)+4,4);
                   1135:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                   1136:    test1 = b->jit_ptr;
                   1137:    x86_branch8(b->jit_ptr, X86_CC_S, 0, 1);
                   1138:    test2 = b->jit_ptr;
                   1139:    x86_branch32(b->jit_ptr, X86_CC_NZ, 0, 1);
                   1140: 
                   1141:    /* test the lo word of gpr[rs] (here hi word = 0) */
                   1142:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs),4);
                   1143:    x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                   1144:    test3 = b->jit_ptr;
                   1145:    x86_branch32(b->jit_ptr, X86_CC_NZ, 0, 1);
                   1146: 
                   1147:    /* here, we take the branch */
                   1148:    x86_patch(test1,b->jit_ptr);
                   1149: 
                   1150:    /* insert the instruction in the delay slot */
                   1151:    mips64_jit_fetch_and_emit(cpu,b,2);
                   1152: 
                   1153:    /* set the new pc in cpu structure */
                   1154:    mips64_set_jump(cpu,b,new_pc,1);
                   1155: 
                   1156:    x86_patch(test2,b->jit_ptr);
                   1157:    x86_patch(test3,b->jit_ptr);
                   1158: 
                   1159:    /* if the branch is not taken, we have to execute the delay slot too */
                   1160:    mips64_jit_fetch_and_emit(cpu,b,1);
                   1161:    return(0);
                   1162: }
                   1163: 
                   1164: /* BLEZL (Branch On Less or Equal Than Zero Likely) */
                   1165: DECLARE_INSN(BLEZL)
                   1166: {
                   1167:    int rs = bits(insn,21,25);
                   1168:    int offset = bits(insn,0,15);
                   1169:    u_char *test1,*test2,*test3;
                   1170:    m_uint64_t new_pc;
                   1171: 
                   1172:    /* compute the new pc */
                   1173:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                   1174:    new_pc += sign_extend(offset << 2,18);
                   1175: 
                   1176:    /* 
                   1177:     * test the hi word of gpr[rs]
                   1178:     */
                   1179:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs)+4,4);
                   1180:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                   1181:    test1 = b->jit_ptr;
                   1182:    x86_branch8(b->jit_ptr, X86_CC_S, 0, 1);
                   1183:    test2 = b->jit_ptr;
                   1184:    x86_branch32(b->jit_ptr, X86_CC_NZ, 0, 1);
                   1185: 
                   1186:    /* test the lo word of gpr[rs] (here hi word = 0) */
                   1187:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs),4);
                   1188:    x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
                   1189:    test3 = b->jit_ptr;
                   1190:    x86_branch32(b->jit_ptr, X86_CC_NZ, 0, 1);
                   1191: 
                   1192:    /* here, we take the branch */
                   1193:    x86_patch(test1,b->jit_ptr);
                   1194: 
                   1195:    /* insert the instruction in the delay slot */
                   1196:    mips64_jit_fetch_and_emit(cpu,b,1);
                   1197: 
                   1198:    /* set the new pc in cpu structure */
                   1199:    mips64_set_jump(cpu,b,new_pc,1);
                   1200: 
                   1201:    x86_patch(test2,b->jit_ptr);
                   1202:    x86_patch(test3,b->jit_ptr);
                   1203:    return(0);
                   1204: }
                   1205: 
                   1206: /* BLTZ (Branch On Less Than Zero) */
                   1207: DECLARE_INSN(BLTZ)
                   1208: {
                   1209:    int rs = bits(insn,21,25);
                   1210:    int offset = bits(insn,0,15);
                   1211:    u_char *test1;
                   1212:    m_uint64_t new_pc;
                   1213: 
                   1214:    /* compute the new pc */
                   1215:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                   1216:    new_pc += sign_extend(offset << 2,18);
                   1217: 
                   1218:    /* 
                   1219:     * test the sign bit of gpr[rs], if set, take the branch.
                   1220:     */
                   1221:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs)+4,4);
                   1222:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                   1223:    test1 = b->jit_ptr;
                   1224:    x86_branch32(b->jit_ptr, X86_CC_NS, 0, 1);
                   1225: 
                   1226:    /* insert the instruction in the delay slot */
                   1227:    mips64_jit_fetch_and_emit(cpu,b,2);
                   1228: 
                   1229:    /* set the new pc in cpu structure */
                   1230:    mips64_set_jump(cpu,b,new_pc,1);
                   1231: 
                   1232:    x86_patch(test1,b->jit_ptr);
                   1233: 
                   1234:    /* if the branch is not taken, we have to execute the delay slot too */
                   1235:    mips64_jit_fetch_and_emit(cpu,b,1);
                   1236:    return(0);
                   1237: }
                   1238: 
                   1239: /* BLTZAL (Branch On Less Than Zero And Link) */
                   1240: DECLARE_INSN(BLTZAL)
                   1241: {
                   1242:    int rs = bits(insn,21,25);
                   1243:    int offset = bits(insn,0,15);
                   1244:    u_char *test1;
                   1245:    m_uint64_t new_pc;
                   1246: 
                   1247:    /* compute the new pc */
                   1248:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                   1249:    new_pc += sign_extend(offset << 2,18);
                   1250: 
                   1251:    /* set the return address (instruction after the delay slot) */
                   1252:    mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2));
                   1253: 
                   1254:    /* 
                   1255:     * test the sign bit of gpr[rs], if set, take the branch.
                   1256:     */
                   1257:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs)+4,4);
                   1258:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                   1259:    test1 = b->jit_ptr;
                   1260:    x86_branch32(b->jit_ptr, X86_CC_NS, 0, 1);
                   1261: 
                   1262:    /* insert the instruction in the delay slot */
                   1263:    mips64_jit_fetch_and_emit(cpu,b,2);
                   1264: 
                   1265:    /* set the new pc in cpu structure */
                   1266:    mips64_set_jump(cpu,b,new_pc,1);
                   1267: 
                   1268:    x86_patch(test1,b->jit_ptr);
                   1269: 
                   1270:    /* if the branch is not taken, we have to execute the delay slot too */
                   1271:    mips64_jit_fetch_and_emit(cpu,b,1);
                   1272:    return(0);
                   1273: }
                   1274: 
                   1275: /* BLTZALL (Branch On Less Than Zero And Link Likely) */
                   1276: DECLARE_INSN(BLTZALL)
                   1277: {
                   1278:    int rs = bits(insn,21,25);
                   1279:    int offset = bits(insn,0,15);
                   1280:    u_char *test1;
                   1281:    m_uint64_t new_pc;
                   1282: 
                   1283:    /* compute the new pc */
                   1284:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                   1285:    new_pc += sign_extend(offset << 2,18);
                   1286: 
                   1287:    /* set the return address (instruction after the delay slot) */
                   1288:    mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2));
                   1289: 
                   1290:    /* 
                   1291:     * test the sign bit of gpr[rs], if set, take the branch.
                   1292:     */
                   1293:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs)+4,4);
                   1294:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                   1295:    test1 = b->jit_ptr;
                   1296:    x86_branch32(b->jit_ptr, X86_CC_NS, 0, 1);
                   1297: 
                   1298:    /* insert the instruction in the delay slot */
                   1299:    mips64_jit_fetch_and_emit(cpu,b,1);
                   1300: 
                   1301:    /* set the new pc in cpu structure */
                   1302:    mips64_set_jump(cpu,b,new_pc,1);
                   1303: 
                   1304:    x86_patch(test1,b->jit_ptr);
                   1305:    return(0);
                   1306: }
                   1307: 
                   1308: /* BLTZL (Branch On Less Than Zero Likely) */
                   1309: DECLARE_INSN(BLTZL)
                   1310: {
                   1311:    int rs = bits(insn,21,25);
                   1312:    int offset = bits(insn,0,15);
                   1313:    u_char *test1;
                   1314:    m_uint64_t new_pc;
                   1315: 
                   1316:    /* compute the new pc */
                   1317:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                   1318:    new_pc += sign_extend(offset << 2,18);
                   1319: 
                   1320:    /* 
                   1321:     * test the sign bit of gpr[rs], if set, take the branch.
                   1322:     */
                   1323:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs)+4,4);
                   1324:    x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
                   1325:    test1 = b->jit_ptr;
                   1326:    x86_branch32(b->jit_ptr, X86_CC_NS, 0, 1);
                   1327: 
                   1328:    /* insert the instruction in the delay slot */
                   1329:    mips64_jit_fetch_and_emit(cpu,b,1);
                   1330: 
                   1331:    /* set the new pc in cpu structure */
                   1332:    mips64_set_jump(cpu,b,new_pc,1);
                   1333: 
                   1334:    x86_patch(test1,b->jit_ptr);
                   1335:    return(0);
                   1336: }
                   1337: 
                   1338: /* BNE (Branch On Not Equal) */
                   1339: DECLARE_INSN(BNE)
                   1340: {
                   1341:    int rs = bits(insn,21,25);
                   1342:    int rt = bits(insn,16,20);
                   1343:    int offset = bits(insn,0,15);
                   1344:    u_char *test1,*test2;
                   1345:    m_uint64_t new_pc;
                   1346: 
                   1347:    /* compute the new pc */
                   1348:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                   1349:    new_pc += sign_extend(offset << 2,18);
                   1350: 
                   1351:    /* 
                   1352:     * compare gpr[rs] and gpr[rt]. 
                   1353:     * compare the low 32 bits first (higher probability).
                   1354:     */
                   1355:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   1356:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EAX,X86_EDI,REG_OFFSET(rt));
                   1357:    test1 = b->jit_ptr;
                   1358:    x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);
                   1359: 
                   1360:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   1361:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EBX,X86_EDI,REG_OFFSET(rt)+4);
                   1362:    test2 = b->jit_ptr;
                   1363:    x86_branch32(b->jit_ptr, X86_CC_E, 0, 1);
                   1364: 
                   1365:    x86_patch(test1,b->jit_ptr);
                   1366: 
                   1367:    /* insert the instruction in the delay slot */
                   1368:    mips64_jit_fetch_and_emit(cpu,b,2);
                   1369: 
                   1370:    /* set the new pc in cpu structure */
                   1371:    mips64_set_jump(cpu,b,new_pc,1);
                   1372: 
                   1373:    x86_patch(test2,b->jit_ptr);
                   1374: 
                   1375:    /* if the branch is not taken, we have to execute the delay slot too */
                   1376:    mips64_jit_fetch_and_emit(cpu,b,1);
                   1377:    return(0);
                   1378: }
                   1379: 
                   1380: /* BNEL (Branch On Not Equal Likely) */
                   1381: DECLARE_INSN(BNEL)
                   1382: {
                   1383:    int rs = bits(insn,21,25);
                   1384:    int rt = bits(insn,16,20);
                   1385:    int offset = bits(insn,0,15);
                   1386:    u_char *test1,*test2;
                   1387:    m_uint64_t new_pc;
                   1388: 
                   1389:    /* compute the new pc */
                   1390:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                   1391:    new_pc += sign_extend(offset << 2,18);
                   1392: 
                   1393:    /* 
                   1394:     * compare gpr[rs] and gpr[rt]. 
                   1395:     * compare the low 32 bits first (higher probability).
                   1396:     */
                   1397:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   1398:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EAX,X86_EDI,REG_OFFSET(rt));
                   1399:    test1 = b->jit_ptr;
                   1400:    x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);
                   1401: 
                   1402:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   1403:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EBX,X86_EDI,REG_OFFSET(rt)+4);
                   1404:    test2 = b->jit_ptr;
                   1405:    x86_branch32(b->jit_ptr, X86_CC_E, 0, 1);
                   1406: 
                   1407:    x86_patch(test1,b->jit_ptr);
                   1408: 
                   1409:    /* insert the instruction in the delay slot */
                   1410:    mips64_jit_fetch_and_emit(cpu,b,1);
                   1411: 
                   1412:    /* set the new pc in cpu structure */
                   1413:    mips64_set_jump(cpu,b,new_pc,1);
                   1414: 
                   1415:    x86_patch(test2,b->jit_ptr);
                   1416:    return(0);
                   1417: }
                   1418: 
                   1419: /* BREAK */
                   1420: DECLARE_INSN(BREAK)
                   1421: {      
                   1422:    u_int code = bits(insn,6,25);
                   1423: 
                   1424:    x86_mov_reg_imm(b->jit_ptr,X86_EDX,code);
                   1425:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                   1426:    mips64_emit_basic_c_call(b,mips64_exec_break);
                   1427:    mips64_jit_tcb_push_epilog(b);
                   1428:    return(0);
                   1429: }
                   1430: 
                   1431: /* CACHE */
                   1432: DECLARE_INSN(CACHE)
                   1433: {        
                   1434:    int base   = bits(insn,21,25);
                   1435:    int op     = bits(insn,16,20);
                   1436:    int offset = bits(insn,0,15);
                   1437: 
                   1438:    mips64_emit_memop(b,MIPS_MEMOP_CACHE,base,offset,op,FALSE);
                   1439:    return(0);
                   1440: }
                   1441: 
                   1442: /* CFC0 */
                   1443: DECLARE_INSN(CFC0)
                   1444: {      
                   1445:    int rt = bits(insn,16,20);
                   1446:    int rd = bits(insn,11,15);
                   1447: 
                   1448:    mips64_emit_cp_xfr_op(b,rt,rd,mips64_cp0_exec_cfc0);
                   1449:    return(0);
                   1450: }
                   1451: 
                   1452: /* CTC0 */
                   1453: DECLARE_INSN(CTC0)
                   1454: {      
                   1455:    int rt = bits(insn,16,20);
                   1456:    int rd = bits(insn,11,15);
                   1457: 
                   1458:    mips64_emit_cp_xfr_op(b,rt,rd,mips64_cp0_exec_ctc0);
                   1459:    return(0);
                   1460: }
                   1461: 
                   1462: /* DADDIU */
                   1463: DECLARE_INSN(DADDIU)
                   1464: {
                   1465:    int rs  = bits(insn,21,25);
                   1466:    int rt  = bits(insn,16,20);
                   1467:    int imm = bits(insn,0,15);
                   1468:    m_uint64_t val = sign_extend(imm,16);
                   1469:    
                   1470:    mips64_load_imm(b,X86_EBX,X86_EAX,val);
                   1471: 
                   1472:    x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EAX,X86_EDI,REG_OFFSET(rs));
                   1473:    x86_alu_reg_membase(b->jit_ptr,X86_ADC,X86_EBX,X86_EDI,REG_OFFSET(rs)+4);
                   1474: 
                   1475:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt),X86_EAX,4);
                   1476:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt)+4,X86_EBX,4);
                   1477: 
                   1478:    return(0);
                   1479: }
                   1480: 
                   1481: /* DADDU: rd = rs + rt */
                   1482: DECLARE_INSN(DADDU)
                   1483: {      
                   1484:    int rs = bits(insn,21,25);
                   1485:    int rt = bits(insn,16,20);
                   1486:    int rd = bits(insn,11,15);
                   1487: 
                   1488:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   1489:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   1490: 
                   1491:    x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EAX,X86_EDI,REG_OFFSET(rt));
                   1492:    x86_alu_reg_membase(b->jit_ptr,X86_ADC,X86_EBX,X86_EDI,REG_OFFSET(rt)+4);
                   1493: 
                   1494:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   1495:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                   1496: 
                   1497:    return(0);
                   1498: }
                   1499: 
                   1500: /* DIV */
                   1501: DECLARE_INSN(DIV)
                   1502: {
                   1503:    int rs = bits(insn,21,25);
                   1504:    int rt = bits(insn,16,20);
                   1505: 
                   1506:    /* eax = gpr[rs] */
                   1507:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   1508:    x86_cdq(b->jit_ptr);
                   1509:    /* ebx = gpr[rt] */
                   1510:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rt),4);
                   1511: 
                   1512:    /* eax = quotient (LO), edx = remainder (HI) */
                   1513:    x86_div_reg(b->jit_ptr,X86_EBX,1);
                   1514: 
                   1515:    /* store LO */
                   1516:    x86_mov_reg_reg(b->jit_ptr,X86_ECX,X86_EDX,4);
                   1517:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,lo),X86_EAX,4);
                   1518:    x86_cdq(b->jit_ptr);
                   1519:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,lo)+4,X86_EDX,4);
                   1520: 
                   1521:    /* store HI */
                   1522:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_ECX,4);
                   1523:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,hi),X86_EAX,4);
                   1524:    x86_cdq(b->jit_ptr);
                   1525:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,hi)+4,X86_EDX,4);
                   1526:    return(0);
                   1527: }
                   1528: 
                   1529: /* DIVU */
                   1530: DECLARE_INSN(DIVU)
                   1531: {
                   1532:    int rs = bits(insn,21,25);
                   1533:    int rt = bits(insn,16,20);
                   1534: 
                   1535:    /* eax = gpr[rs] */
                   1536:    x86_clear_reg(b->jit_ptr,X86_EDX);
                   1537:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   1538:    /* ebx = gpr[rt] */
                   1539:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rt),4);
                   1540: 
                   1541:    /* eax = quotient (LO), edx = remainder (HI) */
                   1542:    x86_div_reg(b->jit_ptr,X86_EBX,0);
                   1543: 
                   1544:    /* store LO */
                   1545:    x86_mov_reg_reg(b->jit_ptr,X86_ECX,X86_EDX,4);
                   1546:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,lo),X86_EAX,4);
                   1547:    x86_cdq(b->jit_ptr);
                   1548:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,lo)+4,X86_EDX,4);
                   1549: 
                   1550:    /* store HI */
                   1551:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_ECX,4);
                   1552:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,hi),X86_EAX,4);
                   1553:    x86_cdq(b->jit_ptr);
                   1554:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,hi)+4,X86_EDX,4);
                   1555:    return(0);
                   1556: }
                   1557: 
                   1558: /* DMFC0 */
                   1559: DECLARE_INSN(DMFC0)
                   1560: {      
                   1561:    int rt = bits(insn,16,20);
                   1562:    int rd = bits(insn,11,15);
                   1563: 
                   1564:    mips64_emit_cp_xfr_op(b,rt,rd,mips64_cp0_exec_dmfc0);
                   1565:    return(0);
                   1566: }
                   1567: 
                   1568: /* DMFC1 */
                   1569: DECLARE_INSN(DMFC1)
                   1570: {      
                   1571:    int rt = bits(insn,16,20);
                   1572:    int rd = bits(insn,11,15);
                   1573: 
                   1574:    mips64_emit_cp_xfr_op(b,rt,rd,mips64_exec_dmfc1);
                   1575:    return(0);
                   1576: }
                   1577: 
                   1578: /* DMTC0 */
                   1579: DECLARE_INSN(DMTC0)
                   1580: {      
                   1581:    int rt = bits(insn,16,20);
                   1582:    int rd = bits(insn,11,15);
                   1583: 
                   1584:    mips64_emit_cp_xfr_op(b,rt,rd,mips64_cp0_exec_dmtc0);
                   1585:    return(0);
                   1586: }
                   1587: 
                   1588: /* DMTC1 */
                   1589: DECLARE_INSN(DMTC1)
                   1590: {      
                   1591:    int rt = bits(insn,16,20);
                   1592:    int rd = bits(insn,11,15);
                   1593: 
                   1594:    mips64_emit_cp_xfr_op(b,rt,rd,mips64_exec_dmtc1);
                   1595:    return(0);
                   1596: }
                   1597: 
                   1598: /* DSLL */
                   1599: DECLARE_INSN(DSLL)
                   1600: {
                   1601:    int rt = bits(insn,16,20);
                   1602:    int rd = bits(insn,11,15);
                   1603:    int sa = bits(insn,6,10);
                   1604:    
                   1605:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt),4);
                   1606:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rt)+4,4);
                   1607: 
                   1608:    x86_shld_reg_imm(b->jit_ptr,X86_EBX,X86_EAX,sa);
                   1609:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EAX,sa);
                   1610: 
                   1611:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   1612:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                   1613: 
                   1614:    return(0);
                   1615: }
                   1616: 
                   1617: /* DSLL32 */
                   1618: DECLARE_INSN(DSLL32)
                   1619: {
                   1620:    int rt = bits(insn,16,20);
                   1621:    int rd = bits(insn,11,15);
                   1622:    int sa = bits(insn,6,10);
                   1623:    
                   1624:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt),4);
                   1625:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EAX,sa);
                   1626:    x86_clear_reg(b->jit_ptr,X86_EDX);
                   1627: 
                   1628:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EDX,4);
                   1629:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EAX,4);
                   1630:    return(0);
                   1631: }
                   1632: 
                   1633: /* DSLLV */
                   1634: DECLARE_INSN(DSLLV)
                   1635: {
                   1636:    int rs = bits(insn,21,25);
                   1637:    int rt = bits(insn,16,20);
                   1638:    int rd = bits(insn,11,15);
                   1639:    
                   1640:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt),4);
                   1641:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rt)+4,4);
                   1642: 
                   1643:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,REG_OFFSET(rs),4);
                   1644:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ECX,0x3f);
                   1645: 
                   1646:    x86_shld_reg(b->jit_ptr,X86_EBX,X86_EAX);
                   1647:    x86_shift_reg(b->jit_ptr,X86_SHL,X86_EAX);
                   1648: 
                   1649:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   1650:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                   1651: 
                   1652:    return(0);
                   1653: }
                   1654: 
                   1655: /* DSRA */
                   1656: DECLARE_INSN(DSRA)
                   1657: {
                   1658:    int rt = bits(insn,16,20);
                   1659:    int rd = bits(insn,11,15);
                   1660:    int sa = bits(insn,6,10);
                   1661:    
                   1662:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt),4);
                   1663:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rt)+4,4);
                   1664: 
                   1665:    x86_shrd_reg_imm(b->jit_ptr,X86_EAX,X86_EBX,sa);
                   1666:    x86_shift_reg_imm(b->jit_ptr,X86_SAR,X86_EBX,sa);
                   1667: 
                   1668:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   1669:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                   1670: 
                   1671:    return(0);
                   1672: }
                   1673: 
                   1674: /* DSRA32 */
                   1675: DECLARE_INSN(DSRA32)
                   1676: {
                   1677:    int rt = bits(insn,16,20);
                   1678:    int rd = bits(insn,11,15);
                   1679:    int sa = bits(insn,6,10);
                   1680:    
                   1681:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt)+4,4);
                   1682:    x86_shift_reg_imm(b->jit_ptr,X86_SAR,X86_EAX,sa);
                   1683:    x86_cdq(b->jit_ptr);
                   1684: 
                   1685:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   1686:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);
                   1687:    return(0);
                   1688: }
                   1689: 
                   1690: /* DSRAV */
                   1691: DECLARE_INSN(DSRAV)
                   1692: {
                   1693:    int rs = bits(insn,21,25);
                   1694:    int rt = bits(insn,16,20);
                   1695:    int rd = bits(insn,11,15);
                   1696:    
                   1697:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt),4);
                   1698:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rt)+4,4);
                   1699: 
                   1700:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,REG_OFFSET(rs),4);
                   1701:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ECX,0x3f);
                   1702: 
                   1703:    x86_shrd_reg(b->jit_ptr,X86_EAX,X86_EBX);
                   1704:    x86_shift_reg(b->jit_ptr,X86_SAR,X86_EBX);
                   1705: 
                   1706:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   1707:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                   1708: 
                   1709:    return(0);
                   1710: }
                   1711: 
                   1712: /* DSRL */
                   1713: DECLARE_INSN(DSRL)
                   1714: {
                   1715:    int rt = bits(insn,16,20);
                   1716:    int rd = bits(insn,11,15);
                   1717:    int sa = bits(insn,6,10);
                   1718:    
                   1719:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt),4);
                   1720:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rt)+4,4);
                   1721: 
                   1722:    x86_shrd_reg_imm(b->jit_ptr,X86_EAX,X86_EBX,sa);
                   1723:    x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_EBX,sa);
                   1724: 
                   1725:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   1726:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                   1727: 
                   1728:    return(0);
                   1729: }
                   1730: 
                   1731: /* DSRL32 */
                   1732: DECLARE_INSN(DSRL32)
                   1733: {
                   1734:    int rt = bits(insn,16,20);
                   1735:    int rd = bits(insn,11,15);
                   1736:    int sa = bits(insn,6,10);
                   1737:    
                   1738:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt)+4,4);
                   1739:    x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_EAX,sa);
                   1740:    x86_clear_reg(b->jit_ptr,X86_EDX);
                   1741: 
                   1742:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   1743:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);
                   1744:    return(0);
                   1745: }
                   1746: 
                   1747: /* DSRLV */
                   1748: DECLARE_INSN(DSRLV)
                   1749: {
                   1750:    int rs = bits(insn,21,25);
                   1751:    int rt = bits(insn,16,20);
                   1752:    int rd = bits(insn,11,15);
                   1753: 
                   1754:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt),4);
                   1755:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rt)+4,4);
                   1756: 
                   1757:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,REG_OFFSET(rs),4);
                   1758:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ECX,0x3f);
                   1759: 
                   1760:    x86_shrd_reg(b->jit_ptr,X86_EAX,X86_EBX);
                   1761:    x86_shift_reg(b->jit_ptr,X86_SHR,X86_EBX);
                   1762: 
                   1763:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   1764:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                   1765: 
                   1766:    return(0);
                   1767: }
                   1768: 
                   1769: /* DSUBU: rd = rs - rt */
                   1770: DECLARE_INSN(DSUBU)
                   1771: {
                   1772:    int rs = bits(insn,21,25);
                   1773:    int rt = bits(insn,16,20);
                   1774:    int rd = bits(insn,11,15);
                   1775: 
                   1776:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   1777:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   1778: 
                   1779:    x86_alu_reg_membase(b->jit_ptr,X86_SUB,X86_EAX,X86_EDI,REG_OFFSET(rt));
                   1780:    x86_alu_reg_membase(b->jit_ptr,X86_SBB,X86_EBX,X86_EDI,REG_OFFSET(rt)+4);
                   1781: 
                   1782:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   1783:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                   1784: 
                   1785:    return(0);
                   1786: }
                   1787: 
                   1788: /* ERET */
                   1789: DECLARE_INSN(ERET)
                   1790: {
                   1791:    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
                   1792: 
                   1793:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                   1794:    mips64_emit_basic_c_call(b,mips64_exec_eret);
                   1795:    mips64_jit_tcb_push_epilog(b);
                   1796:    return(0);
                   1797: }
                   1798: 
                   1799: /* J (Jump) */
                   1800: DECLARE_INSN(J)
                   1801: {
                   1802:    u_int instr_index = bits(insn,0,25);
                   1803:    m_uint64_t new_pc;
                   1804: 
                   1805:    /* compute the new pc */
                   1806:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                   1807:    new_pc &= ~((1 << 28) - 1);
                   1808:    new_pc |= instr_index << 2;
                   1809: 
                   1810:    /* insert the instruction in the delay slot */
                   1811:    mips64_jit_fetch_and_emit(cpu,b,1);
                   1812: 
                   1813:    /* set the new pc in cpu structure */
                   1814:    mips64_set_jump(cpu,b,new_pc,1);
                   1815:    return(0);
                   1816: }
                   1817: 
                   1818: /* JAL (Jump And Link) */
                   1819: DECLARE_INSN(JAL)
                   1820: {
                   1821:    u_int instr_index = bits(insn,0,25);
                   1822:    m_uint64_t new_pc,ret_pc;
                   1823: 
                   1824:    /* compute the new pc */
                   1825:    new_pc = b->start_pc + (b->mips_trans_pos << 2);
                   1826:    new_pc &= ~((1 << 28) - 1);
                   1827:    new_pc |= instr_index << 2;
                   1828: 
                   1829:    /* set the return address (instruction after the delay slot) */
                   1830:    ret_pc = b->start_pc + ((b->mips_trans_pos + 1) << 2);
                   1831:    mips64_set_ra(b,ret_pc);
                   1832: 
                   1833:    /* insert the instruction in the delay slot */
                   1834:    mips64_jit_fetch_and_emit(cpu,b,1);
                   1835: 
                   1836:    /* set the new pc in cpu structure */
                   1837:    mips64_set_jump(cpu,b,new_pc,0);
                   1838:    return(0);
                   1839: }
                   1840: 
                   1841: /* JALR (Jump and Link Register) */
                   1842: DECLARE_INSN(JALR)
                   1843: {
                   1844:    int rs = bits(insn,21,25);
                   1845:    int rd = bits(insn,11,15);
                   1846:    m_uint64_t ret_pc;
                   1847: 
                   1848:    /* set the return pc (instruction after the delay slot) in GPR[rd] */
                   1849:    ret_pc = b->start_pc + ((b->mips_trans_pos + 1) << 2);
                   1850:    mips64_load_imm(b,X86_EBX,X86_EAX,ret_pc);
                   1851: 
                   1852:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   1853:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                   1854: 
                   1855:    /* get the new pc */
                   1856:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,REG_OFFSET(rs),4);
                   1857:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,REG_OFFSET(rs)+4,4);
                   1858: 
                   1859:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,ret_pc),X86_ECX,4);
                   1860:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,ret_pc)+4,
                   1861:                        X86_EDX,4);
                   1862: 
                   1863:    /* insert the instruction in the delay slot */
                   1864:    mips64_jit_fetch_and_emit(cpu,b,1);
                   1865: 
                   1866:    /* set the new pc */
                   1867:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,
                   1868:                        X86_EDI,OFFSET(cpu_mips_t,ret_pc),4);
                   1869:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,
                   1870:                        X86_EDI,OFFSET(cpu_mips_t,ret_pc)+4,4);
                   1871: 
                   1872:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,pc),X86_ECX,4);
                   1873:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,pc)+4,X86_EDX,4);
                   1874: 
                   1875:    /* returns to the caller which will determine the next path */
                   1876:    mips64_jit_tcb_push_epilog(b);
                   1877:    return(0);
                   1878: }
                   1879: 
                   1880: /* JR (Jump Register) */
                   1881: DECLARE_INSN(JR)
                   1882: {      
                   1883:    int rs = bits(insn,21,25);
                   1884: 
                   1885:    /* get the new pc */
                   1886:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,REG_OFFSET(rs),4);
                   1887:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,REG_OFFSET(rs)+4,4);
                   1888: 
                   1889:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,ret_pc),X86_ECX,4);
                   1890:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,ret_pc)+4,
                   1891:                        X86_EDX,4);
                   1892: 
                   1893:    /* insert the instruction in the delay slot */
                   1894:    mips64_jit_fetch_and_emit(cpu,b,1);
                   1895: 
                   1896:    /* set the new pc */
                   1897:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,
                   1898:                        X86_EDI,OFFSET(cpu_mips_t,ret_pc),4);
                   1899:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,
                   1900:                        X86_EDI,OFFSET(cpu_mips_t,ret_pc)+4,4);
                   1901: 
                   1902:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,pc),X86_ECX,4);
                   1903:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,pc)+4,X86_EDX,4);
                   1904: 
                   1905:    /* returns to the caller which will determine the next path */
                   1906:    mips64_jit_tcb_push_epilog(b);
                   1907:    return(0);
                   1908: }
                   1909: 
                   1910: /* LB (Load Byte) */
                   1911: DECLARE_INSN(LB)
                   1912: {
                   1913:    int base   = bits(insn,21,25);
                   1914:    int rt     = bits(insn,16,20);
                   1915:    int offset = bits(insn,0,15);
                   1916: 
                   1917:    mips64_emit_memop(b,MIPS_MEMOP_LB,base,offset,rt,TRUE);
                   1918:    return(0);
                   1919: }
                   1920: 
                   1921: /* LBU (Load Byte Unsigned) */
                   1922: DECLARE_INSN(LBU)
                   1923: {
                   1924:    int base   = bits(insn,21,25);
                   1925:    int rt     = bits(insn,16,20);
                   1926:    int offset = bits(insn,0,15);
                   1927: 
                   1928:    mips64_emit_memop(b,MIPS_MEMOP_LBU,base,offset,rt,TRUE);
                   1929:    return(0);
                   1930: }
                   1931: 
                   1932: /* LD (Load Double-Word) */
                   1933: DECLARE_INSN(LD)
                   1934: {
                   1935:    int base   = bits(insn,21,25);
                   1936:    int rt     = bits(insn,16,20);
                   1937:    int offset = bits(insn,0,15);
                   1938: 
                   1939:    mips64_emit_memop(b,MIPS_MEMOP_LD,base,offset,rt,TRUE);
                   1940:    return(0);
                   1941: }
                   1942: 
                   1943: /* LDC1 (Load Double-Word to Coprocessor 1) */
                   1944: DECLARE_INSN(LDC1)
                   1945: {
                   1946:    int base   = bits(insn,21,25);
                   1947:    int ft     = bits(insn,16,20);
                   1948:    int offset = bits(insn,0,15);
                   1949: 
                   1950:    mips64_emit_memop(b,MIPS_MEMOP_LDC1,base,offset,ft,TRUE);
                   1951:    return(0);
                   1952: }
                   1953: 
                   1954: /* LDL (Load Double-Word Left) */
                   1955: DECLARE_INSN(LDL)
                   1956: {
                   1957:    int base   = bits(insn,21,25);
                   1958:    int rt     = bits(insn,16,20);
                   1959:    int offset = bits(insn,0,15);
                   1960: 
                   1961:    mips64_emit_memop(b,MIPS_MEMOP_LDL,base,offset,rt,TRUE);
                   1962:    return(0);
                   1963: }
                   1964: 
                   1965: /* LDR (Load Double-Word Right) */
                   1966: DECLARE_INSN(LDR)
                   1967: {
                   1968:    int base   = bits(insn,21,25);
                   1969:    int rt     = bits(insn,16,20);
                   1970:    int offset = bits(insn,0,15);
                   1971: 
                   1972:    mips64_emit_memop(b,MIPS_MEMOP_LDR,base,offset,rt,TRUE);
                   1973:    return(0);
                   1974: }
                   1975: 
                   1976: /* LH (Load Half-Word) */
                   1977: DECLARE_INSN(LH)
                   1978: {
                   1979:    int base   = bits(insn,21,25);
                   1980:    int rt     = bits(insn,16,20);
                   1981:    int offset = bits(insn,0,15);
                   1982: 
                   1983:    mips64_emit_memop(b,MIPS_MEMOP_LH,base,offset,rt,TRUE);
                   1984:    return(0);
                   1985: }
                   1986: 
                   1987: /* LHU (Load Half-Word Unsigned) */
                   1988: DECLARE_INSN(LHU)
                   1989: {
                   1990:    int base   = bits(insn,21,25);
                   1991:    int rt     = bits(insn,16,20);
                   1992:    int offset = bits(insn,0,15);
                   1993: 
                   1994:    mips64_emit_memop(b,MIPS_MEMOP_LHU,base,offset,rt,TRUE);
                   1995:    return(0);
                   1996: }
                   1997: 
                   1998: /* LI (virtual) */
                   1999: DECLARE_INSN(LI)
                   2000: {
                   2001:    int rt  = bits(insn,16,20);
                   2002:    int imm = bits(insn,0,15);
                   2003:    m_uint64_t val = sign_extend(imm,16);
                   2004: 
                   2005:    x86_mov_membase_imm(b->jit_ptr,X86_EDI,REG_OFFSET(rt),val & 0xffffffff,4);
                   2006:    x86_mov_membase_imm(b->jit_ptr,X86_EDI,REG_OFFSET(rt)+4,val >> 32,4);
                   2007:    return(0);
                   2008: }
                   2009: 
                   2010: /* LL (Load Linked) */
                   2011: DECLARE_INSN(LL)
                   2012: {
                   2013:    int base   = bits(insn,21,25);
                   2014:    int rt     = bits(insn,16,20);
                   2015:    int offset = bits(insn,0,15);
                   2016: 
                   2017:    mips64_emit_memop(b,MIPS_MEMOP_LL,base,offset,rt,TRUE);
                   2018:    return(0);
                   2019: }
                   2020: 
                   2021: /* LUI */
                   2022: DECLARE_INSN(LUI)
                   2023: {
                   2024:    int rt  = bits(insn,16,20);
                   2025:    int imm = bits(insn,0,15);
                   2026:    m_uint64_t val = sign_extend(imm,16) << 16;
                   2027: 
                   2028:    mips64_load_imm(b,X86_EBX,X86_EAX,val);
                   2029:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt),X86_EAX,4);
                   2030:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt)+4,X86_EBX,4);
                   2031: 
                   2032:    return(0);
                   2033: }
                   2034: 
                   2035: /* LW (Load Word) */
                   2036: DECLARE_INSN(LW)
                   2037: {
                   2038:    int base   = bits(insn,21,25);
                   2039:    int rt     = bits(insn,16,20);
                   2040:    int offset = bits(insn,0,15);
                   2041: 
                   2042:    if (cpu->fast_memop) {
                   2043:       mips64_emit_memop_fast(cpu,b,0,MIPS_MEMOP_LW,base,offset,rt,TRUE,
                   2044:                              mips64_memop_fast_lw);
                   2045:    } else {
                   2046:       mips64_emit_memop(b,MIPS_MEMOP_LW,base,offset,rt,TRUE);
                   2047:    }
                   2048:    return(0);
                   2049: }
                   2050: 
                   2051: /* LWL (Load Word Left) */
                   2052: DECLARE_INSN(LWL)
                   2053: {
                   2054:    int base   = bits(insn,21,25);
                   2055:    int rt     = bits(insn,16,20);
                   2056:    int offset = bits(insn,0,15);
                   2057: 
                   2058:    mips64_emit_memop(b,MIPS_MEMOP_LWL,base,offset,rt,TRUE);
                   2059:    return(0);
                   2060: }
                   2061: 
                   2062: /* LWR (Load Word Right) */
                   2063: DECLARE_INSN(LWR)
                   2064: {
                   2065:    int base   = bits(insn,21,25);
                   2066:    int rt     = bits(insn,16,20);
                   2067:    int offset = bits(insn,0,15);
                   2068: 
                   2069:    mips64_emit_memop(b,MIPS_MEMOP_LWR,base,offset,rt,TRUE);
                   2070:    return(0);
                   2071: }
                   2072: 
                   2073: /* LWU (Load Word Unsigned) */
                   2074: DECLARE_INSN(LWU)
                   2075: {
                   2076:    int base   = bits(insn,21,25);
                   2077:    int rt     = bits(insn,16,20);
                   2078:    int offset = bits(insn,0,15);
                   2079: 
                   2080:    mips64_emit_memop(b,MIPS_MEMOP_LWU,base,offset,rt,TRUE);
                   2081:    return(0);
                   2082: }
                   2083: 
                   2084: /* MFC0 */
                   2085: DECLARE_INSN(MFC0)
                   2086: {      
                   2087:    int rt = bits(insn,16,20);
                   2088:    int rd = bits(insn,11,15);
                   2089: 
                   2090:    mips64_emit_cp_xfr_op(b,rt,rd,mips64_cp0_exec_mfc0);
                   2091:    return(0);
                   2092: }
                   2093: 
                   2094: /* MFC1 */
                   2095: DECLARE_INSN(MFC1)
                   2096: {      
                   2097:    int rt = bits(insn,16,20);
                   2098:    int rd = bits(insn,11,15);
                   2099: 
                   2100:    mips64_emit_cp_xfr_op(b,rt,rd,mips64_exec_mfc1);
                   2101:    return(0);
                   2102: }
                   2103: 
                   2104: /* MFHI */
                   2105: DECLARE_INSN(MFHI)
                   2106: {
                   2107:    int rd = bits(insn,11,15);
                   2108: 
                   2109:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,OFFSET(cpu_mips_t,hi),4);
                   2110:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,OFFSET(cpu_mips_t,hi)+4,4);
                   2111: 
                   2112:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   2113:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                   2114: 
                   2115:    return(0);
                   2116: }
                   2117: 
                   2118: /* MFLO */
                   2119: DECLARE_INSN(MFLO)
                   2120: {
                   2121:    int rd = bits(insn,11,15);
                   2122: 
                   2123:    if (!rd) return(0);
                   2124: 
                   2125:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,OFFSET(cpu_mips_t,lo),4);
                   2126:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,OFFSET(cpu_mips_t,lo)+4,4);
                   2127: 
                   2128:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   2129:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                   2130: 
                   2131:    return(0);
                   2132: }
                   2133: 
                   2134: /* MOVE (virtual instruction, real: ADDU) */
                   2135: DECLARE_INSN(MOVE)
                   2136: {      
                   2137:    int rs = bits(insn,21,25);
                   2138:    int rd = bits(insn,11,15);
                   2139:    
                   2140:    if (rs != 0) {
                   2141:       x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);   
                   2142:       x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   2143:       x86_cdq(b->jit_ptr);
                   2144:       x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);
                   2145:    } else {
                   2146:       x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EBX,X86_EBX);
                   2147:       x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EBX,4);
                   2148:       x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                   2149:    }
                   2150: 
                   2151:    return(0);
                   2152: }
                   2153: 
                   2154: /* MTC0 */
                   2155: DECLARE_INSN(MTC0)
                   2156: {      
                   2157:    int rt = bits(insn,16,20);
                   2158:    int rd = bits(insn,11,15);
                   2159: 
                   2160:    mips64_emit_cp_xfr_op(b,rt,rd,mips64_cp0_exec_mtc0);
                   2161:    return(0);
                   2162: }
                   2163: 
                   2164: /* MTC1 */
                   2165: DECLARE_INSN(MTC1)
                   2166: {      
                   2167:    int rt = bits(insn,16,20);
                   2168:    int rd = bits(insn,11,15);
                   2169: 
                   2170:    mips64_emit_cp_xfr_op(b,rt,rd,mips64_exec_mtc1);
                   2171:    return(0);
                   2172: }
                   2173: 
                   2174: /* MTHI */
                   2175: DECLARE_INSN(MTHI)
                   2176: {
                   2177:    int rs = bits(insn,21,25);
                   2178: 
                   2179:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   2180:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   2181: 
                   2182:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,hi),X86_EAX,4);
                   2183:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,hi)+4,X86_EBX,4);
                   2184: 
                   2185:    return(0);
                   2186: }
                   2187: 
                   2188: /* MTLO */
                   2189: DECLARE_INSN(MTLO)
                   2190: {
                   2191:    int rs = bits(insn,21,25);
                   2192: 
                   2193:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   2194:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   2195: 
                   2196:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,lo),X86_EAX,4);
                   2197:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,lo)+4,X86_EBX,4);
                   2198: 
                   2199:    return(0);
                   2200: }
                   2201: 
                   2202: /* MUL */
                   2203: DECLARE_INSN(MUL)
                   2204: {
                   2205:    int rs = bits(insn,21,25);
                   2206:    int rt = bits(insn,16,20);
                   2207:    int rd = bits(insn,11,15);
                   2208: 
                   2209:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   2210:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rt),4);
                   2211: 
                   2212:    x86_mul_reg(b->jit_ptr,X86_EBX,1);
                   2213: 
                   2214:    /* store result in gpr[rd] */
                   2215:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   2216:    x86_cdq(b->jit_ptr);
                   2217:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);
                   2218:    return(0);
                   2219: }
                   2220: 
                   2221: /* MULT */
                   2222: DECLARE_INSN(MULT)
                   2223: {
                   2224:    int rs = bits(insn,21,25);
                   2225:    int rt = bits(insn,16,20);
                   2226: 
                   2227:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   2228:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rt),4);
                   2229: 
                   2230:    x86_mul_reg(b->jit_ptr,X86_EBX,1);
                   2231: 
                   2232:    /* store LO */
                   2233:    x86_mov_reg_reg(b->jit_ptr,X86_ECX,X86_EDX,4);
                   2234:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,lo),X86_EAX,4);
                   2235:    x86_cdq(b->jit_ptr);
                   2236:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,lo)+4,X86_EDX,4);
                   2237: 
                   2238:    /* store HI */
                   2239:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_ECX,4);
                   2240:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,hi),X86_EAX,4);
                   2241:    x86_cdq(b->jit_ptr);
                   2242:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,hi)+4,X86_EDX,4);
                   2243:    return(0);
                   2244: }
                   2245: 
                   2246: /* MULTU */
                   2247: DECLARE_INSN(MULTU)
                   2248: {
                   2249:    int rs = bits(insn,21,25);
                   2250:    int rt = bits(insn,16,20);
                   2251: 
                   2252:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   2253:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rt),4);
                   2254: 
                   2255:    x86_mul_reg(b->jit_ptr,X86_EBX,0);
                   2256: 
                   2257:    /* store LO */
                   2258:    x86_mov_reg_reg(b->jit_ptr,X86_ECX,X86_EDX,4);
                   2259:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,lo),X86_EAX,4);
                   2260:    x86_cdq(b->jit_ptr);
                   2261:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,lo)+4,X86_EDX,4);
                   2262: 
                   2263:    /* store HI */
                   2264:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_ECX,4);
                   2265:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,hi),X86_EAX,4);
                   2266:    x86_cdq(b->jit_ptr);
                   2267:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_mips_t,hi)+4,X86_EDX,4);
                   2268:    return(0);
                   2269: }
                   2270: 
                   2271: /* NOP */
                   2272: DECLARE_INSN(NOP)
                   2273: {
                   2274:    //x86_nop(b->jit_ptr);
                   2275:    return(0);
                   2276: }
                   2277: 
                   2278: /* NOR */
                   2279: DECLARE_INSN(NOR)
                   2280: {
                   2281:    int rs = bits(insn,21,25);
                   2282:    int rt = bits(insn,16,20);
                   2283:    int rd = bits(insn,11,15);
                   2284: 
                   2285:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   2286:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   2287: 
                   2288:    x86_alu_reg_membase(b->jit_ptr,X86_OR,X86_EAX,X86_EDI,REG_OFFSET(rt));
                   2289:    x86_alu_reg_membase(b->jit_ptr,X86_OR,X86_EBX,X86_EDI,REG_OFFSET(rt)+4);
                   2290: 
                   2291:    x86_not_reg(b->jit_ptr,X86_EAX);
                   2292:    x86_not_reg(b->jit_ptr,X86_EBX);
                   2293: 
                   2294:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   2295:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                   2296: 
                   2297:    return(0);
                   2298: }
                   2299: 
                   2300: /* OR */
                   2301: DECLARE_INSN(OR)
                   2302: {
                   2303:    int rs = bits(insn,21,25);
                   2304:    int rt = bits(insn,16,20);
                   2305:    int rd = bits(insn,11,15);
                   2306: 
                   2307:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   2308:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   2309: 
                   2310:    x86_alu_reg_membase(b->jit_ptr,X86_OR,X86_EAX,X86_EDI,REG_OFFSET(rt));
                   2311:    x86_alu_reg_membase(b->jit_ptr,X86_OR,X86_EBX,X86_EDI,REG_OFFSET(rt)+4);
                   2312: 
                   2313:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   2314:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                   2315: 
                   2316:    return(0);
                   2317: }
                   2318: 
                   2319: /* ORI */
                   2320: DECLARE_INSN(ORI)
                   2321: {
                   2322:    int rs  = bits(insn,21,25);
                   2323:    int rt  = bits(insn,16,20);
                   2324:    int imm = bits(insn,0,15);
                   2325:    m_uint64_t val = imm;
                   2326: 
                   2327:    x86_mov_reg_imm(b->jit_ptr,X86_EAX,val & 0xffff);
                   2328:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   2329: 
                   2330:    x86_alu_reg_membase(b->jit_ptr,X86_OR,X86_EAX,X86_EDI,REG_OFFSET(rs));
                   2331: 
                   2332:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt),X86_EAX,4);
                   2333:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt)+4,X86_EBX,4);
                   2334: 
                   2335:    return(0);
                   2336: }
                   2337: 
                   2338: /* PREF */
                   2339: DECLARE_INSN(PREF)
                   2340: {
                   2341:    x86_nop(b->jit_ptr);
                   2342:    return(0);
                   2343: }
                   2344: 
                   2345: /* PREFI */
                   2346: DECLARE_INSN(PREFI)
                   2347: {
                   2348:    x86_nop(b->jit_ptr);
                   2349:    return(0);
                   2350: }
                   2351: 
                   2352: /* SB (Store Byte) */
                   2353: DECLARE_INSN(SB)
                   2354: {
                   2355:    int base   = bits(insn,21,25);
                   2356:    int rt     = bits(insn,16,20);
                   2357:    int offset = bits(insn,0,15);
                   2358: 
                   2359:    mips64_emit_memop(b,MIPS_MEMOP_SB,base,offset,rt,FALSE);
                   2360:    return(0);
                   2361: }
                   2362: 
                   2363: /* SC (Store Conditional) */
                   2364: DECLARE_INSN(SC)
                   2365: {
                   2366:    int base   = bits(insn,21,25);
                   2367:    int rt     = bits(insn,16,20);
                   2368:    int offset = bits(insn,0,15);
                   2369: 
                   2370:    mips64_emit_memop(b,MIPS_MEMOP_SC,base,offset,rt,TRUE);
                   2371:    return(0);
                   2372: }
                   2373: 
                   2374: /* SD (Store Double-Word) */
                   2375: DECLARE_INSN(SD)
                   2376: {
                   2377:    int base   = bits(insn,21,25);
                   2378:    int rt     = bits(insn,16,20);
                   2379:    int offset = bits(insn,0,15);
                   2380: 
                   2381:    mips64_emit_memop(b,MIPS_MEMOP_SD,base,offset,rt,FALSE);
                   2382:    return(0);
                   2383: }
                   2384: 
                   2385: /* SDL (Store Double-Word Left) */
                   2386: DECLARE_INSN(SDL)
                   2387: {
                   2388:    int base   = bits(insn,21,25);
                   2389:    int rt     = bits(insn,16,20);
                   2390:    int offset = bits(insn,0,15);
                   2391: 
                   2392:    mips64_emit_memop(b,MIPS_MEMOP_SDL,base,offset,rt,FALSE);
                   2393:    return(0);
                   2394: }
                   2395: 
                   2396: /* SDR (Store Double-Word Right) */
                   2397: DECLARE_INSN(SDR)
                   2398: {
                   2399:    int base   = bits(insn,21,25);
                   2400:    int rt     = bits(insn,16,20);
                   2401:    int offset = bits(insn,0,15);
                   2402: 
                   2403:    mips64_emit_memop(b,MIPS_MEMOP_SDR,base,offset,rt,FALSE);
                   2404:    return(0);
                   2405: }
                   2406: 
                   2407: /* SDC1 (Store Double-Word from Coprocessor 1) */
                   2408: DECLARE_INSN(SDC1)
                   2409: {
                   2410:    int base   = bits(insn,21,25);
                   2411:    int ft     = bits(insn,16,20);
                   2412:    int offset = bits(insn,0,15);
                   2413: 
                   2414:    mips64_emit_memop(b,MIPS_MEMOP_SDC1,base,offset,ft,FALSE);
                   2415:    return(0);
                   2416: }
                   2417: 
                   2418: /* SH (Store Half-Word) */
                   2419: DECLARE_INSN(SH)
                   2420: {
                   2421:    int base   = bits(insn,21,25);
                   2422:    int rt     = bits(insn,16,20);
                   2423:    int offset = bits(insn,0,15);
                   2424: 
                   2425:    mips64_emit_memop(b,MIPS_MEMOP_SH,base,offset,rt,FALSE);
                   2426:    return(0);
                   2427: }
                   2428: 
                   2429: /* SLL */
                   2430: DECLARE_INSN(SLL)
                   2431: {      
                   2432:    int rt = bits(insn,16,20);
                   2433:    int rd = bits(insn,11,15);
                   2434:    int sa = bits(insn,6,10);
                   2435: 
                   2436:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt),4);
                   2437:    x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EAX,sa);
                   2438: 
                   2439:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   2440:    x86_cdq(b->jit_ptr);
                   2441:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);
                   2442:    return(0);
                   2443: }
                   2444: 
                   2445: /* SLLV */
                   2446: DECLARE_INSN(SLLV)
                   2447: {      
                   2448:    int rs = bits(insn,21,25);
                   2449:    int rt = bits(insn,16,20);
                   2450:    int rd = bits(insn,11,15);
                   2451: 
                   2452:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,REG_OFFSET(rs),4);
                   2453:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ECX,0x1f);
                   2454: 
                   2455:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt),4);
                   2456:    x86_shift_reg(b->jit_ptr,X86_SHL,X86_EAX);
                   2457: 
                   2458:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   2459:    x86_cdq(b->jit_ptr);
                   2460:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);
                   2461:    return(0);
                   2462: }
                   2463: 
                   2464: /* SLT */
                   2465: DECLARE_INSN(SLT)
                   2466: {
                   2467:    int rs = bits(insn,21,25);
                   2468:    int rt = bits(insn,16,20);
                   2469:    int rd = bits(insn,11,15);
                   2470:    u_char *test1,*test2,*test3;
                   2471: 
                   2472:    /* edx:eax = gpr[rt] */
                   2473:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt),4);
                   2474:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,REG_OFFSET(rt)+4,4);
                   2475: 
                   2476:    /* ebx:ecx = gpr[rs] */
                   2477:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,REG_OFFSET(rs),4);
                   2478:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   2479: 
                   2480:    /* we set rd to 1 when gpr[rs] < gpr[rt] */
                   2481:    x86_clear_reg(b->jit_ptr,X86_ESI);
                   2482:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_ESI,4);
                   2483:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_ESI,4);
                   2484: 
                   2485:    /* rs(high) > rt(high) => end */
                   2486:    x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_EBX,X86_EDX);
                   2487:    test1 = b->jit_ptr;
                   2488:    x86_branch8(b->jit_ptr, X86_CC_GT, 0, 1);
                   2489:    
                   2490:    /* rs(high) < rt(high) => set rd to 1 */
                   2491:    test2 = b->jit_ptr;
                   2492:    x86_branch8(b->jit_ptr, X86_CC_LT, 0, 1);
                   2493:    
                   2494:    /* rs(high) == rt(high), rs(low) >= rt(low) => end */
                   2495:    x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_ECX,X86_EAX);
                   2496:    test3 = b->jit_ptr;
                   2497:    x86_branch8(b->jit_ptr, X86_CC_AE, 0, 1);
                   2498:    
                   2499:    /* set rd to 1 */
                   2500:    x86_patch(test2,b->jit_ptr);
                   2501:    x86_inc_membase(b->jit_ptr,X86_EDI,REG_OFFSET(rd));
                   2502: 
                   2503:    /* end */
                   2504:    x86_patch(test1,b->jit_ptr);
                   2505:    x86_patch(test3,b->jit_ptr);
                   2506:    return(0);
                   2507: }
                   2508: 
                   2509: /* SLTI */
                   2510: DECLARE_INSN(SLTI)
                   2511: {
                   2512:    int rs = bits(insn,21,25);
                   2513:    int rt = bits(insn,16,20);
                   2514:    int imm = bits(insn,0,15);
                   2515:    m_uint64_t val = sign_extend(imm,16);
                   2516:    u_char *test1,*test2,*test3;
                   2517: 
                   2518:    /* we set rt to 1 when gpr[rs] < val, rt to 0 when gpr[rs] >= val */
                   2519: 
                   2520:    /* edx:eax = val */
                   2521:    mips64_load_imm(b,X86_EDX,X86_EAX,val);
                   2522: 
                   2523:    /* ebx:ecx = gpr[rs] */
                   2524:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,REG_OFFSET(rs),4);
                   2525:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   2526: 
                   2527:    /* we set rt to 1 when gpr[rs] < val */
                   2528:    x86_clear_reg(b->jit_ptr,X86_ESI);
                   2529:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt),X86_ESI,4);
                   2530:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt)+4,X86_ESI,4);
                   2531: 
                   2532:    /* rs(high) > val(high) => end */
                   2533:    x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_EBX,X86_EDX);
                   2534:    test1 = b->jit_ptr;
                   2535:    x86_branch8(b->jit_ptr, X86_CC_GT, 0, 1);
                   2536:    
                   2537:    /* rs(high) < val(high) => set rt to 1 */
                   2538:    test2 = b->jit_ptr;
                   2539:    x86_branch8(b->jit_ptr, X86_CC_LT, 0, 1);
                   2540:    
                   2541:    /* rs(high) == val(high), rs(low) >= val(low) => set rt to 0 */
                   2542:    x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_ECX,X86_EAX);
                   2543:    test3 = b->jit_ptr;
                   2544:    x86_branch8(b->jit_ptr, X86_CC_AE, 0, 1);
                   2545:    
                   2546:    /* set rt to 1 */
                   2547:    x86_patch(test2,b->jit_ptr);
                   2548:    x86_inc_membase(b->jit_ptr,X86_EDI,REG_OFFSET(rt));
                   2549: 
                   2550:    /* end */
                   2551:    x86_patch(test1,b->jit_ptr);
                   2552:    x86_patch(test3,b->jit_ptr);   
                   2553: 
                   2554:    return(0);
                   2555: }
                   2556: 
                   2557: /* SLTIU */
                   2558: DECLARE_INSN(SLTIU)
                   2559: {
                   2560:    int rs = bits(insn,21,25);
                   2561:    int rt = bits(insn,16,20);
                   2562:    int imm = bits(insn,0,15);
                   2563:    m_uint64_t val = sign_extend(imm,16);
                   2564:    u_char *test1,*test2,*test3;
                   2565: 
                   2566:    /* edx:eax = val */
                   2567:    mips64_load_imm(b,X86_EDX,X86_EAX,val);
                   2568: 
                   2569:    /* ebx:ecx = gpr[rs] */
                   2570:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,REG_OFFSET(rs),4);
                   2571:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   2572: 
                   2573:    /* we set rt to 1 when gpr[rs] < val */
                   2574:    x86_clear_reg(b->jit_ptr,X86_ESI);
                   2575:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt),X86_ESI,4);
                   2576:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt)+4,X86_ESI,4);
                   2577: 
                   2578:    /* rs(high) > val(high) => end */
                   2579:    x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_EBX,X86_EDX);
                   2580:    test1 = b->jit_ptr;
                   2581:    x86_branch8(b->jit_ptr, X86_CC_A, 0, 0);
                   2582:    
                   2583:    /* rs(high) < val(high) => set rt to 1 */
                   2584:    test2 = b->jit_ptr;
                   2585:    x86_branch8(b->jit_ptr, X86_CC_B, 0, 0);
                   2586:    
                   2587:    /* rs(high) == val(high), rs(low) >= val(low) => end */
                   2588:    x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_ECX,X86_EAX);
                   2589:    test3 = b->jit_ptr;
                   2590:    x86_branch8(b->jit_ptr, X86_CC_AE, 0, 1);
                   2591:    
                   2592:    /* set rt to 1 */
                   2593:    x86_patch(test2,b->jit_ptr);
                   2594:    x86_inc_membase(b->jit_ptr,X86_EDI,REG_OFFSET(rt));
                   2595: 
                   2596:    /* end */
                   2597:    x86_patch(test1,b->jit_ptr);
                   2598:    x86_patch(test3,b->jit_ptr);
                   2599:    return(0);
                   2600: }
                   2601: 
                   2602: /* SLTU */
                   2603: DECLARE_INSN(SLTU)
                   2604: {
                   2605:    int rs = bits(insn,21,25);
                   2606:    int rt = bits(insn,16,20);
                   2607:    int rd = bits(insn,11,15);
                   2608:    u_char *test1,*test2,*test3;
                   2609: 
                   2610:    /* edx:eax = gpr[rt] */
                   2611:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt),4);
                   2612:    x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,REG_OFFSET(rt)+4,4);
                   2613: 
                   2614:    /* ebx:ecx = gpr[rs] */
                   2615:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,REG_OFFSET(rs),4);
                   2616:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   2617: 
                   2618:    /* we set rd to 1 when gpr[rs] < gpr[rt] */
                   2619:    x86_clear_reg(b->jit_ptr,X86_ESI);
                   2620:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_ESI,4);
                   2621:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_ESI,4);
                   2622: 
                   2623:    /* rs(high) > rt(high) => end */
                   2624:    x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_EBX,X86_EDX);
                   2625:    test1 = b->jit_ptr;
                   2626:    x86_branch8(b->jit_ptr, X86_CC_A, 0, 0);
                   2627:    
                   2628:    /* rs(high) < rt(high) => set rd to 1 */
                   2629:    test2 = b->jit_ptr;
                   2630:    x86_branch8(b->jit_ptr, X86_CC_B, 0, 0);
                   2631:    
                   2632:    /* rs(high) == rt(high), rs(low) >= rt(low) => end */
                   2633:    x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_ECX,X86_EAX);
                   2634:    test3 = b->jit_ptr;
                   2635:    x86_branch8(b->jit_ptr, X86_CC_AE, 0, 1);
                   2636:    
                   2637:    /* set rd to 1 */
                   2638:    x86_patch(test2,b->jit_ptr);
                   2639:    x86_inc_membase(b->jit_ptr,X86_EDI,REG_OFFSET(rd));
                   2640: 
                   2641:    /* end */
                   2642:    x86_patch(test1,b->jit_ptr);
                   2643:    x86_patch(test3,b->jit_ptr);
                   2644:    return(0);
                   2645: }
                   2646: 
                   2647: /* SRA */
                   2648: DECLARE_INSN(SRA)
                   2649: {      
                   2650:    int rt = bits(insn,16,20);
                   2651:    int rd = bits(insn,11,15);
                   2652:    int sa = bits(insn,6,10);
                   2653: 
                   2654:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt),4);
                   2655:    x86_shift_reg_imm(b->jit_ptr,X86_SAR,X86_EAX,sa);
                   2656: 
                   2657:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   2658:    x86_cdq(b->jit_ptr);
                   2659:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);
                   2660:    return(0);
                   2661: }
                   2662: 
                   2663: /* SRAV */
                   2664: DECLARE_INSN(SRAV)
                   2665: {      
                   2666:    int rs = bits(insn,21,25);
                   2667:    int rt = bits(insn,16,20);
                   2668:    int rd = bits(insn,11,15);
                   2669: 
                   2670:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,REG_OFFSET(rs),4);
                   2671:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ECX,0x1f);
                   2672: 
                   2673:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt),4);
                   2674:    x86_shift_reg(b->jit_ptr,X86_SAR,X86_EAX);
                   2675: 
                   2676:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   2677:    x86_cdq(b->jit_ptr);
                   2678:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);
                   2679:    return(0);
                   2680: }
                   2681: 
                   2682: /* SRL */
                   2683: DECLARE_INSN(SRL)
                   2684: {      
                   2685:    int rt = bits(insn,16,20);
                   2686:    int rd = bits(insn,11,15);
                   2687:    int sa = bits(insn,6,10);
                   2688: 
                   2689:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt),4);
                   2690:    x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_EAX,sa);
                   2691: 
                   2692:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   2693:    x86_clear_reg(b->jit_ptr,X86_EDX);
                   2694:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);
                   2695:    return(0);
                   2696: }
                   2697: 
                   2698: /* SRLV */
                   2699: DECLARE_INSN(SRLV)
                   2700: {      
                   2701:    int rs = bits(insn,21,25);
                   2702:    int rt = bits(insn,16,20);
                   2703:    int rd = bits(insn,11,15);
                   2704: 
                   2705:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,REG_OFFSET(rs),4);
                   2706:    x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ECX,0x1f);
                   2707: 
                   2708:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rt),4);
                   2709:    x86_shift_reg(b->jit_ptr,X86_SHR,X86_EAX);
                   2710: 
                   2711:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   2712:    x86_clear_reg(b->jit_ptr,X86_EDX);
                   2713:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);
                   2714:    return(0);
                   2715: }
                   2716: 
                   2717: /* SUB */
                   2718: DECLARE_INSN(SUB)
                   2719: {
                   2720:    int rs = bits(insn,21,25);
                   2721:    int rt = bits(insn,16,20);
                   2722:    int rd = bits(insn,11,15);
                   2723:    
                   2724:    /* TODO: Exception handling */
                   2725:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   2726:    x86_alu_reg_membase(b->jit_ptr,X86_SUB,X86_EAX,X86_EDI,REG_OFFSET(rt));
                   2727:    
                   2728:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   2729:    x86_cdq(b->jit_ptr);
                   2730:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);
                   2731:    return(0);
                   2732: }
                   2733: 
                   2734: /* SUBU */
                   2735: DECLARE_INSN(SUBU)
                   2736: {
                   2737:    int rs = bits(insn,21,25);
                   2738:    int rt = bits(insn,16,20);
                   2739:    int rd = bits(insn,11,15);
                   2740:    
                   2741:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   2742:    x86_alu_reg_membase(b->jit_ptr,X86_SUB,X86_EAX,X86_EDI,REG_OFFSET(rt));
                   2743:    
                   2744:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   2745:    x86_cdq(b->jit_ptr);
                   2746:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EDX,4);
                   2747:    return(0);
                   2748: }
                   2749: 
                   2750: /* SW (Store Word) */
                   2751: DECLARE_INSN(SW)
                   2752: {
                   2753:    int base   = bits(insn,21,25);
                   2754:    int rt     = bits(insn,16,20);
                   2755:    int offset = bits(insn,0,15);
                   2756: 
                   2757:    if (cpu->fast_memop) {
                   2758:       mips64_emit_memop_fast(cpu,b,1,MIPS_MEMOP_SW,base,offset,rt,FALSE,
                   2759:                              mips64_memop_fast_sw);
                   2760:    } else {
                   2761:       mips64_emit_memop(b,MIPS_MEMOP_SW,base,offset,rt,FALSE);
                   2762:    }
                   2763:    return(0);
                   2764: }
                   2765: 
                   2766: /* SWL (Store Word Left) */
                   2767: DECLARE_INSN(SWL)
                   2768: {
                   2769:    int base   = bits(insn,21,25);
                   2770:    int rt     = bits(insn,16,20);
                   2771:    int offset = bits(insn,0,15);
                   2772: 
                   2773:    mips64_emit_memop(b,MIPS_MEMOP_SWL,base,offset,rt,FALSE);
                   2774:    return(0);
                   2775: }
                   2776: 
                   2777: /* SWR (Store Word Right) */
                   2778: DECLARE_INSN(SWR)
                   2779: {
                   2780:    int base   = bits(insn,21,25);
                   2781:    int rt     = bits(insn,16,20);
                   2782:    int offset = bits(insn,0,15);
                   2783: 
                   2784:    mips64_emit_memop(b,MIPS_MEMOP_SWR,base,offset,rt,FALSE);
                   2785:    return(0);
                   2786: }
                   2787: 
                   2788: /* SYNC */
                   2789: DECLARE_INSN(SYNC)
                   2790: {
                   2791:    return(0);
                   2792: }
                   2793: 
                   2794: /* SYSCALL */
                   2795: DECLARE_INSN(SYSCALL)
                   2796: {
                   2797:    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
                   2798: 
                   2799:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                   2800:    mips64_emit_basic_c_call(b,mips64_exec_syscall);
                   2801: 
                   2802:    mips64_jit_tcb_push_epilog(b);
                   2803:    return(0);
                   2804: }
                   2805: 
                   2806: /* TEQ (Trap If Equal) */
                   2807: DECLARE_INSN(TEQ)
                   2808: {
                   2809:    int rs = bits(insn,21,25);
                   2810:    int rt = bits(insn,16,20);
                   2811:    u_char *test1,*test2;
                   2812: 
                   2813:    /* Compare low part */
                   2814:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,REG_OFFSET(rs),4);
                   2815:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_ECX,X86_EDI,REG_OFFSET(rt));
                   2816:    test1 = b->jit_ptr;
                   2817:    x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);
                   2818: 
                   2819:    /* Compare high part */
                   2820:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   2821:    x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EBX,X86_EDI,REG_OFFSET(rt)+4);
                   2822:    test2 = b->jit_ptr;
                   2823:    x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);
                   2824: 
                   2825:    /* Generate trap exception */
                   2826:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                   2827:    mips64_emit_c_call(b,mips64_trigger_trap_exception);
                   2828:    mips64_jit_tcb_push_epilog(b);
                   2829: 
                   2830:    /* end */
                   2831:    x86_patch(test1,b->jit_ptr);
                   2832:    x86_patch(test2,b->jit_ptr);
                   2833:    return(0);
                   2834: }
                   2835: 
                   2836: /* TEQI (Trap If Equal Immediate) */
                   2837: DECLARE_INSN(TEQI)
                   2838: {
                   2839:    int rs  = bits(insn,21,25);
                   2840:    int imm = bits(insn,0,15);
                   2841:    m_uint64_t val = sign_extend(imm,16);
                   2842:    u_char *test1,*test2;
                   2843: 
                   2844:    /* edx:eax = val */
                   2845:    mips64_load_imm(b,X86_EDX,X86_EAX,val);
                   2846: 
                   2847:    /* Compare low part */
                   2848:    x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,REG_OFFSET(rs),4);
                   2849:    x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_ECX,X86_EAX);
                   2850:    test1 = b->jit_ptr;
                   2851:    x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);
                   2852: 
                   2853:    /* Compare high part */
                   2854:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   2855:    x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_EBX,X86_EDX);
                   2856:    test2 = b->jit_ptr;
                   2857:    x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);
                   2858: 
                   2859:    /* Generate trap exception */
                   2860:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                   2861:    mips64_emit_c_call(b,mips64_trigger_trap_exception);
                   2862:    mips64_jit_tcb_push_epilog(b);
                   2863: 
                   2864:    /* end */
                   2865:    x86_patch(test1,b->jit_ptr);
                   2866:    x86_patch(test2,b->jit_ptr);
                   2867:    return(0);
                   2868: }
                   2869: 
                   2870: /* TLBP */
                   2871: DECLARE_INSN(TLBP)
                   2872: {
                   2873:    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
                   2874:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                   2875:    mips64_emit_basic_c_call(b,mips64_cp0_exec_tlbp);
                   2876:    return(0);
                   2877: }
                   2878: 
                   2879: /* TLBR */
                   2880: DECLARE_INSN(TLBR)
                   2881: {  
                   2882:    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
                   2883:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                   2884:    mips64_emit_basic_c_call(b,mips64_cp0_exec_tlbr);
                   2885:    return(0);
                   2886: }
                   2887: 
                   2888: /* TLBWI */
                   2889: DECLARE_INSN(TLBWI)
                   2890: {   
                   2891:    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
                   2892:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                   2893:    mips64_emit_basic_c_call(b,mips64_cp0_exec_tlbwi);
                   2894:    return(0);
                   2895: }
                   2896: 
                   2897: /* TLBWR */
                   2898: DECLARE_INSN(TLBWR)
                   2899: {   
                   2900:    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
                   2901:    x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
                   2902:    mips64_emit_basic_c_call(b,mips64_cp0_exec_tlbwr);
                   2903:    return(0);
                   2904: }
                   2905: 
                   2906: /* XOR */
                   2907: DECLARE_INSN(XOR)
                   2908: {
                   2909:    int rs = bits(insn,21,25);
                   2910:    int rt = bits(insn,16,20);
                   2911:    int rd = bits(insn,11,15);
                   2912: 
                   2913:    x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,REG_OFFSET(rs),4);
                   2914:    x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,REG_OFFSET(rs)+4,4);
                   2915: 
                   2916:    x86_alu_reg_membase(b->jit_ptr,X86_XOR,X86_EAX,X86_EDI,REG_OFFSET(rt));
                   2917:    x86_alu_reg_membase(b->jit_ptr,X86_XOR,X86_EBX,X86_EDI,REG_OFFSET(rt)+4);
                   2918: 
                   2919:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd),X86_EAX,4);
                   2920:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rd)+4,X86_EBX,4);
                   2921: 
                   2922:    return(0);
                   2923: }
                   2924: 
                   2925: /* XORI */
                   2926: DECLARE_INSN(XORI)
                   2927: {
                   2928:    int rs  = bits(insn,21,25);
                   2929:    int rt  = bits(insn,16,20);
                   2930:    int imm = bits(insn,0,15);
                   2931:    m_uint64_t val = imm;
                   2932: 
                   2933:    mips64_load_imm(b,X86_EBX,X86_EAX,val);
                   2934: 
                   2935:    x86_alu_reg_membase(b->jit_ptr,X86_XOR,X86_EAX,X86_EDI,REG_OFFSET(rs));
                   2936:    x86_alu_reg_membase(b->jit_ptr,X86_XOR,X86_EBX,X86_EDI,REG_OFFSET(rs)+4);
                   2937: 
                   2938:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt),X86_EAX,4);
                   2939:    x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(rt)+4,X86_EBX,4);
                   2940: 
                   2941:    return(0);
                   2942: }
                   2943: 
                   2944: /* MIPS instruction array */
                   2945: struct mips64_insn_tag mips64_insn_tags[] = {
                   2946:    { mips64_emit_LI      , 0xffe00000 , 0x24000000, 1 },   /* virtual */
                   2947:    { mips64_emit_MOVE    , 0xfc1f07ff , 0x00000021, 1 },   /* virtual */
                   2948:    { mips64_emit_B       , 0xffff0000 , 0x10000000, 0 },   /* virtual */
                   2949:    { mips64_emit_BAL     , 0xffff0000 , 0x04110000, 0 },   /* virtual */
                   2950:    { mips64_emit_BEQZ    , 0xfc1f0000 , 0x10000000, 0 },   /* virtual */
                   2951:    { mips64_emit_BNEZ    , 0xfc1f0000 , 0x14000000, 0 },   /* virtual */
                   2952:    { mips64_emit_ADD     , 0xfc0007ff , 0x00000020, 1 },
                   2953:    { mips64_emit_ADDI    , 0xfc000000 , 0x20000000, 1 },
                   2954:    { mips64_emit_ADDIU   , 0xfc000000 , 0x24000000, 1 },
                   2955:    { mips64_emit_ADDU    , 0xfc0007ff , 0x00000021, 1 },
                   2956:    { mips64_emit_AND     , 0xfc0007ff , 0x00000024, 1 },
                   2957:    { mips64_emit_ANDI    , 0xfc000000 , 0x30000000, 1 },
                   2958:    { mips64_emit_BEQ     , 0xfc000000 , 0x10000000, 0 },
                   2959:    { mips64_emit_BEQL    , 0xfc000000 , 0x50000000, 0 },
                   2960:    { mips64_emit_BGEZ    , 0xfc1f0000 , 0x04010000, 0 },
                   2961:    { mips64_emit_BGEZAL  , 0xfc1f0000 , 0x04110000, 0 },
                   2962:    { mips64_emit_BGEZALL , 0xfc1f0000 , 0x04130000, 0 },
                   2963:    { mips64_emit_BGEZL   , 0xfc1f0000 , 0x04030000, 0 },
                   2964:    { mips64_emit_BGTZ    , 0xfc1f0000 , 0x1c000000, 0 },
                   2965:    { mips64_emit_BGTZL   , 0xfc1f0000 , 0x5c000000, 0 },
                   2966:    { mips64_emit_BLEZ    , 0xfc1f0000 , 0x18000000, 0 },
                   2967:    { mips64_emit_BLEZL   , 0xfc1f0000 , 0x58000000, 0 },
                   2968:    { mips64_emit_BLTZ    , 0xfc1f0000 , 0x04000000, 0 },
                   2969:    { mips64_emit_BLTZAL  , 0xfc1f0000 , 0x04100000, 0 },
                   2970:    { mips64_emit_BLTZALL , 0xfc1f0000 , 0x04120000, 0 },
                   2971:    { mips64_emit_BLTZL   , 0xfc1f0000 , 0x04020000, 0 },
                   2972:    { mips64_emit_BNE     , 0xfc000000 , 0x14000000, 0 },
                   2973:    { mips64_emit_BNEL    , 0xfc000000 , 0x54000000, 0 },
                   2974:    { mips64_emit_BREAK   , 0xfc00003f , 0x0000000d, 1 },
                   2975:    { mips64_emit_CACHE   , 0xfc000000 , 0xbc000000, 1 },
                   2976:    { mips64_emit_CFC0    , 0xffe007ff , 0x40400000, 1 },
                   2977:    { mips64_emit_CTC0    , 0xffe007ff , 0x40600000, 1 },
                   2978:    { mips64_emit_DADDIU  , 0xfc000000 , 0x64000000, 1 },
                   2979:    { mips64_emit_DADDU   , 0xfc0007ff , 0x0000002d, 1 },
                   2980:    { mips64_emit_DIV     , 0xfc00ffff , 0x0000001a, 1 },
                   2981:    { mips64_emit_DIVU    , 0xfc00ffff , 0x0000001b, 1 },
                   2982:    { mips64_emit_DMFC0   , 0xffe007f8 , 0x40200000, 1 },
                   2983:    { mips64_emit_DMFC1   , 0xffe007ff , 0x44200000, 1 },
                   2984:    { mips64_emit_DMTC0   , 0xffe007f8 , 0x40a00000, 1 },
                   2985:    { mips64_emit_DMTC1   , 0xffe007ff , 0x44a00000, 1 },
                   2986:    { mips64_emit_DSLL    , 0xffe0003f , 0x00000038, 1 },
                   2987:    { mips64_emit_DSLL32  , 0xffe0003f , 0x0000003c, 1 },
                   2988:    { mips64_emit_DSLLV   , 0xfc0007ff , 0x00000014, 1 },
                   2989:    { mips64_emit_DSRA    , 0xffe0003f , 0x0000003b, 1 },
                   2990:    { mips64_emit_DSRA32  , 0xffe0003f , 0x0000003f, 1 },
                   2991:    { mips64_emit_DSRAV   , 0xfc0007ff , 0x00000017, 1 },
                   2992:    { mips64_emit_DSRL    , 0xffe0003f , 0x0000003a, 1 },
                   2993:    { mips64_emit_DSRL32  , 0xffe0003f , 0x0000003e, 1 },
                   2994:    { mips64_emit_DSRLV   , 0xfc0007ff , 0x00000016, 1 },
                   2995:    { mips64_emit_DSUBU   , 0xfc0007ff , 0x0000002f, 1 },
                   2996:    { mips64_emit_ERET    , 0xffffffff , 0x42000018, 0 },
                   2997:    { mips64_emit_J       , 0xfc000000 , 0x08000000, 0 },
                   2998:    { mips64_emit_JAL     , 0xfc000000 , 0x0c000000, 0 },
                   2999:    { mips64_emit_JALR    , 0xfc1f003f , 0x00000009, 0 },
                   3000:    { mips64_emit_JR      , 0xfc1ff83f , 0x00000008, 0 },
                   3001:    { mips64_emit_LB      , 0xfc000000 , 0x80000000, 1 },
                   3002:    { mips64_emit_LBU     , 0xfc000000 , 0x90000000, 1 },
                   3003:    { mips64_emit_LD      , 0xfc000000 , 0xdc000000, 1 },
                   3004:    { mips64_emit_LDC1    , 0xfc000000 , 0xd4000000, 1 },
                   3005:    { mips64_emit_LDL     , 0xfc000000 , 0x68000000, 1 },
                   3006:    { mips64_emit_LDR     , 0xfc000000 , 0x6c000000, 1 },
                   3007:    { mips64_emit_LH      , 0xfc000000 , 0x84000000, 1 },
                   3008:    { mips64_emit_LHU     , 0xfc000000 , 0x94000000, 1 },
                   3009:    { mips64_emit_LL      , 0xfc000000 , 0xc0000000, 1 },
                   3010:    { mips64_emit_LUI     , 0xffe00000 , 0x3c000000, 1 },
                   3011:    { mips64_emit_LW      , 0xfc000000 , 0x8c000000, 1 },
                   3012:    { mips64_emit_LWL     , 0xfc000000 , 0x88000000, 1 },
                   3013:    { mips64_emit_LWR     , 0xfc000000 , 0x98000000, 1 },
                   3014:    { mips64_emit_LWU     , 0xfc000000 , 0x9c000000, 1 },
                   3015:    { mips64_emit_MFC0    , 0xffe007ff , 0x40000000, 1 },
                   3016:    { mips64_emit_CFC0    , 0xffe007ff , 0x40000001, 1 },  /* MFC0 / Set 1 */
                   3017:    { mips64_emit_MFC1    , 0xffe007ff , 0x44000000, 1 },
                   3018:    { mips64_emit_MFHI    , 0xffff07ff , 0x00000010, 1 },
                   3019:    { mips64_emit_MFLO    , 0xffff07ff , 0x00000012, 1 },
                   3020:    { mips64_emit_MTC0    , 0xffe007ff , 0x40800000, 1 },
                   3021:    { mips64_emit_MTC1    , 0xffe007ff , 0x44800000, 1 },
                   3022:    { mips64_emit_MTHI    , 0xfc1fffff , 0x00000011, 1 },
                   3023:    { mips64_emit_MTLO    , 0xfc1fffff , 0x00000013, 1 },
                   3024:    { mips64_emit_MUL     , 0xfc0007ff , 0x70000002, 1 },
                   3025:    { mips64_emit_MULT    , 0xfc00ffff , 0x00000018, 1 },
                   3026:    { mips64_emit_MULTU   , 0xfc00ffff , 0x00000019, 1 },
                   3027:    { mips64_emit_NOP     , 0xffffffff , 0x00000000, 1 },
                   3028:    { mips64_emit_NOR     , 0xfc0007ff , 0x00000027, 1 },
                   3029:    { mips64_emit_OR      , 0xfc0007ff , 0x00000025, 1 },
                   3030:    { mips64_emit_ORI     , 0xfc000000 , 0x34000000, 1 },
                   3031:    { mips64_emit_PREF    , 0xfc000000 , 0xcc000000, 1 },
                   3032:    { mips64_emit_PREFI   , 0xfc0007ff , 0x4c00000f, 1 },
                   3033:    { mips64_emit_SB      , 0xfc000000 , 0xa0000000, 1 },
                   3034:    { mips64_emit_SC      , 0xfc000000 , 0xe0000000, 1 },
                   3035:    { mips64_emit_SD      , 0xfc000000 , 0xfc000000, 1 },
                   3036:    { mips64_emit_SDC1    , 0xfc000000 , 0xf4000000, 1 },
                   3037:    { mips64_emit_SDL     , 0xfc000000 , 0xb0000000, 1 },
                   3038:    { mips64_emit_SDR     , 0xfc000000 , 0xb4000000, 1 },
                   3039:    { mips64_emit_SH      , 0xfc000000 , 0xa4000000, 1 },
                   3040:    { mips64_emit_SLL     , 0xffe0003f , 0x00000000, 1 },
                   3041:    { mips64_emit_SLLV    , 0xfc0007ff , 0x00000004, 1 },
                   3042:    { mips64_emit_SLT     , 0xfc0007ff , 0x0000002a, 1 },
                   3043:    { mips64_emit_SLTI    , 0xfc000000 , 0x28000000, 1 },
                   3044:    { mips64_emit_SLTIU   , 0xfc000000 , 0x2c000000, 1 },
                   3045:    { mips64_emit_SLTU    , 0xfc0007ff , 0x0000002b, 1 },
                   3046:    { mips64_emit_SRA     , 0xffe0003f , 0x00000003, 1 },
                   3047:    { mips64_emit_SRAV    , 0xfc0007ff , 0x00000007, 1 },
                   3048:    { mips64_emit_SRL     , 0xffe0003f , 0x00000002, 1 },
                   3049:    { mips64_emit_SRLV    , 0xfc0007ff , 0x00000006, 1 },
                   3050:    { mips64_emit_SUB     , 0xfc0007ff , 0x00000022, 1 },
                   3051:    { mips64_emit_SUBU    , 0xfc0007ff , 0x00000023, 1 },
                   3052:    { mips64_emit_SW      , 0xfc000000 , 0xac000000, 1 },
                   3053:    { mips64_emit_SWL     , 0xfc000000 , 0xa8000000, 1 },
                   3054:    { mips64_emit_SWR     , 0xfc000000 , 0xb8000000, 1 },
                   3055:    { mips64_emit_SYNC    , 0xfffff83f , 0x0000000f, 1 },
                   3056:    { mips64_emit_SYSCALL , 0xfc00003f , 0x0000000c, 1 },
                   3057:    { mips64_emit_TEQ     , 0xfc00003f , 0x00000034, 1 },
                   3058:    { mips64_emit_TEQI    , 0xfc1f0000 , 0x040c0000, 1 },
                   3059:    { mips64_emit_TLBP    , 0xffffffff , 0x42000008, 1 },
                   3060:    { mips64_emit_TLBR    , 0xffffffff , 0x42000001, 1 },
                   3061:    { mips64_emit_TLBWI   , 0xffffffff , 0x42000002, 1 },
                   3062:    { mips64_emit_TLBWR   , 0xffffffff , 0x42000006, 1 },
                   3063:    { mips64_emit_XOR     , 0xfc0007ff , 0x00000026, 1 },
                   3064:    { mips64_emit_XORI    , 0xfc000000 , 0x38000000, 1 },
                   3065:    { mips64_emit_unknown , 0x00000000 , 0x00000000, 1 },
1.1.1.2 ! root     3066:    { NULL                , 0x00000000 , 0x00000000, 0 },
1.1       root     3067: };

unix.superglobalmegacorp.com

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