Annotation of cf/mips64_x86_trans.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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