|
|
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: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.