Annotation of cf/amd64_trans.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

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