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