Annotation of cf/amd64_trans.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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