|
|
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 "ppc32_jit.h" ! 17: #include "ppc32_amd64_trans.h" ! 18: #include "memory.h" ! 19: ! 20: /* Macros for CPU structure access */ ! 21: #define REG_OFFSET(reg) (OFFSET(cpu_ppc_t,gpr[(reg)])) ! 22: #define MEMOP_OFFSET(op) (OFFSET(cpu_ppc_t,mem_op_fn[(op)])) ! 23: ! 24: #define DECLARE_INSN(name) \ ! 25: static int ppc32_emit_##name(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, \ ! 26: ppc_insn_t insn) ! 27: ! 28: /* Load a 32 bit immediate value */ ! 29: static inline void ppc32_load_imm(ppc32_jit_tcb_t *b,u_int reg,m_uint32_t val) ! 30: { ! 31: if (val) ! 32: amd64_mov_reg_imm_size(b->jit_ptr,reg,val,4); ! 33: else ! 34: amd64_alu_reg_reg_size(b->jit_ptr,X86_XOR,reg,reg,4); ! 35: } ! 36: ! 37: /* Set the Instruction Address (IA) register */ ! 38: void ppc32_set_ia(ppc32_jit_tcb_t *b,m_uint32_t new_ia) ! 39: { ! 40: amd64_mov_membase_imm(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ia),new_ia,4); ! 41: } ! 42: ! 43: /* Set the Link Register (LR) */ ! 44: void ppc32_set_lr(ppc32_jit_tcb_t *b,m_uint32_t new_lr) ! 45: { ! 46: amd64_mov_membase_imm(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,lr),new_lr,4); ! 47: } ! 48: ! 49: /* Set Jump */ ! 50: static void ppc32_set_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, ! 51: m_uint32_t new_ia,int local_jump) ! 52: { ! 53: int return_to_caller = FALSE; ! 54: u_char *jump_ptr; ! 55: ! 56: #if 0 ! 57: if (cpu->sym_trace && !local_jump) ! 58: return_to_caller = TRUE; ! 59: #endif ! 60: ! 61: if (!return_to_caller && ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr)) { ! 62: if (jump_ptr) { ! 63: amd64_jump_code(b->jit_ptr,jump_ptr); ! 64: } else { ! 65: ppc32_jit_tcb_record_patch(b,b->jit_ptr,new_ia); ! 66: amd64_jump32(b->jit_ptr,0); ! 67: } ! 68: } else { ! 69: /* save PC */ ! 70: ppc32_set_ia(b,new_ia); ! 71: ! 72: /* address is in another block, for now, returns to caller */ ! 73: ppc32_jit_tcb_push_epilog(b); ! 74: } ! 75: } ! 76: ! 77: /* Load the Condition Register (CR) into the specified host register */ ! 78: static forced_inline void ppc32_load_cr(ppc32_jit_tcb_t *b,u_int host_reg) ! 79: { ! 80: amd64_mov_reg_membase(b->jit_ptr,host_reg,AMD64_R15,OFFSET(cpu_ppc_t,cr),4); ! 81: } ! 82: ! 83: /* Store the Condition Register (CR) from the specified host register */ ! 84: static forced_inline void ppc32_store_cr(ppc32_jit_tcb_t *b,u_int host_reg) ! 85: { ! 86: amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,cr),host_reg,4); ! 87: } ! 88: ! 89: /* Load a GPR into the specified host register */ ! 90: static forced_inline void ppc32_load_gpr(ppc32_jit_tcb_t *b,u_int host_reg, ! 91: u_int ppc_reg) ! 92: { ! 93: amd64_mov_reg_membase(b->jit_ptr,host_reg,AMD64_R15,REG_OFFSET(ppc_reg),4); ! 94: } ! 95: ! 96: /* Store contents for a host register into a GPR register */ ! 97: static forced_inline void ppc32_store_gpr(ppc32_jit_tcb_t *b,u_int ppc_reg, ! 98: u_int host_reg) ! 99: { ! 100: amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,REG_OFFSET(ppc_reg),host_reg,4); ! 101: } ! 102: ! 103: /* Apply an ALU operation on a GPR register and a host register */ ! 104: static forced_inline void ppc32_alu_gpr(ppc32_jit_tcb_t *b,u_int op, ! 105: u_int host_reg,u_int ppc_reg) ! 106: { ! 107: amd64_alu_reg_membase_size(b->jit_ptr,op,host_reg, ! 108: AMD64_R15,REG_OFFSET(ppc_reg),4); ! 109: } ! 110: ! 111: /* ! 112: * Update CR from %eflags ! 113: * %eax, %ecx, %edx, %esi are modified. ! 114: */ ! 115: #define PPC32_CR_LT_BIT 3 ! 116: #define PPC32_CR_GT_BIT 2 ! 117: #define PPC32_CR_EQ_BIT 1 ! 118: #define PPC32_CR_SO_BIT 0 ! 119: ! 120: static void ppc32_update_cr(ppc32_jit_tcb_t *b,int field,int is_signed) ! 121: { ! 122: m_uint32_t cr_mask; ! 123: u_int cfb; ! 124: ! 125: cr_mask = 0xF0000000 >> (field << 2); ! 126: cfb = 28 - (field << 2); ! 127: ! 128: amd64_set_reg(b->jit_ptr,X86_CC_LT,AMD64_RAX,is_signed); ! 129: amd64_set_reg(b->jit_ptr,X86_CC_GT,AMD64_RCX,is_signed); ! 130: amd64_set_reg(b->jit_ptr,X86_CC_Z,AMD64_RDX,is_signed); ! 131: ! 132: amd64_shift_reg_imm(b->jit_ptr,X86_SHL,AMD64_RAX,(cfb + PPC32_CR_LT_BIT)); ! 133: amd64_shift_reg_imm(b->jit_ptr,X86_SHL,AMD64_RCX,(cfb + PPC32_CR_GT_BIT)); ! 134: amd64_shift_reg_imm(b->jit_ptr,X86_SHL,AMD64_RDX,(cfb + PPC32_CR_EQ_BIT)); ! 135: ! 136: amd64_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ECX); ! 137: amd64_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_EDX); ! 138: ! 139: /* Load Condition Register */ ! 140: ppc32_load_cr(b,AMD64_RDX); ! 141: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RDX,~cr_mask); ! 142: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RAX,cr_mask); ! 143: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RDX,AMD64_RAX); ! 144: ! 145: /* Check XER Summary of Overflow and report it */ ! 146: amd64_mov_reg_membase(b->jit_ptr,AMD64_RCX, ! 147: AMD64_R15,OFFSET(cpu_ppc_t,xer),4); ! 148: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RCX,PPC32_XER_SO); ! 149: amd64_shift_reg_imm(b->jit_ptr,X86_SHR,AMD64_RCX,(field << 2) + 3); ! 150: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RDX,AMD64_RCX); ! 151: ! 152: /* Store modified CR */ ! 153: ppc32_store_cr(b,AMD64_RDX); ! 154: } ! 155: ! 156: /* ! 157: * Update CR0 from %eflags ! 158: * %eax, %ecx, %edx, %esi are modified. ! 159: */ ! 160: static void ppc32_update_cr0(ppc32_jit_tcb_t *b) ! 161: { ! 162: ppc32_update_cr(b,0,TRUE); ! 163: } ! 164: ! 165: /* Basic C call */ ! 166: static forced_inline void ppc32_emit_basic_c_call(ppc32_jit_tcb_t *b,void *f) ! 167: { ! 168: amd64_mov_reg_imm(b->jit_ptr,AMD64_RCX,f); ! 169: amd64_call_reg(b->jit_ptr,AMD64_RCX); ! 170: } ! 171: ! 172: /* Emit a simple call to a C function without any parameter */ ! 173: static void ppc32_emit_c_call(ppc32_jit_tcb_t *b,void *f) ! 174: { ! 175: ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2)); ! 176: ppc32_emit_basic_c_call(b,f); ! 177: } ! 178: ! 179: /* Memory operation */ ! 180: static void ppc32_emit_memop(ppc32_jit_tcb_t *b,int op,int base,int offset, ! 181: int target,int update) ! 182: { ! 183: m_uint32_t val = sign_extend(offset,16); ! 184: u_char *test1; ! 185: ! 186: /* Save PC for exception handling */ ! 187: ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2)); ! 188: ! 189: /* RSI = sign-extended offset */ ! 190: ppc32_load_imm(b,AMD64_RSI,val); ! 191: ! 192: /* RSI = GPR[base] + sign-extended offset */ ! 193: if (update || (base != 0)) ! 194: ppc32_alu_gpr(b,X86_ADD,AMD64_RSI,base); ! 195: ! 196: if (update) ! 197: amd64_mov_reg_reg(b->jit_ptr,AMD64_R14,AMD64_RSI,4); ! 198: ! 199: /* RDX = target register */ ! 200: amd64_mov_reg_imm(b->jit_ptr,AMD64_RDX,target); ! 201: ! 202: /* RDI = CPU instance pointer */ ! 203: amd64_mov_reg_reg(b->jit_ptr,AMD64_RDI,AMD64_R15,8); ! 204: ! 205: /* Call memory function */ ! 206: amd64_call_membase(b->jit_ptr,AMD64_R15,MEMOP_OFFSET(op)); ! 207: ! 208: /* Exception ? */ ! 209: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RAX,AMD64_RAX,4); ! 210: test1 = b->jit_ptr; ! 211: amd64_branch8(b->jit_ptr, X86_CC_Z, 0, 1); ! 212: ppc32_jit_tcb_push_epilog(b); ! 213: amd64_patch(test1,b->jit_ptr); ! 214: ! 215: if (update) ! 216: ppc32_store_gpr(b,base,AMD64_R14); ! 217: } ! 218: ! 219: /* Memory operation (indexed) */ ! 220: static void ppc32_emit_memop_idx(ppc32_jit_tcb_t *b,int op,int ra,int rb, ! 221: int target,int update) ! 222: { ! 223: u_char *test1; ! 224: ! 225: /* Save PC for exception handling */ ! 226: ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2)); ! 227: ! 228: /* RSI = $rb */ ! 229: ppc32_load_gpr(b,AMD64_RSI,rb); ! 230: ! 231: /* RSI = GPR[base] + sign-extended offset */ ! 232: if (update || (ra != 0)) ! 233: ppc32_alu_gpr(b,X86_ADD,AMD64_RSI,ra); ! 234: ! 235: if (update) ! 236: amd64_mov_reg_reg(b->jit_ptr,AMD64_R14,AMD64_RSI,4); ! 237: ! 238: /* RDX = target register */ ! 239: amd64_mov_reg_imm(b->jit_ptr,AMD64_RDX,target); ! 240: ! 241: /* RDI = CPU instance pointer */ ! 242: amd64_mov_reg_reg(b->jit_ptr,AMD64_RDI,AMD64_R15,8); ! 243: ! 244: /* Call memory function */ ! 245: amd64_call_membase(b->jit_ptr,AMD64_R15,MEMOP_OFFSET(op)); ! 246: ! 247: /* Exception ? */ ! 248: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RAX,AMD64_RAX,4); ! 249: test1 = b->jit_ptr; ! 250: amd64_branch8(b->jit_ptr, X86_CC_Z, 0, 1); ! 251: ppc32_jit_tcb_push_epilog(b); ! 252: amd64_patch(test1,b->jit_ptr); ! 253: ! 254: if (update) ! 255: ppc32_store_gpr(b,ra,AMD64_R14); ! 256: } ! 257: ! 258: typedef void (*memop_fast_access)(ppc32_jit_tcb_t *b,int target); ! 259: ! 260: /* Fast LBZ */ ! 261: static void ppc32_memop_fast_lbz(ppc32_jit_tcb_t *b,int target) ! 262: { ! 263: amd64_clear_reg(b->jit_ptr,AMD64_RCX); ! 264: amd64_mov_reg_memindex(b->jit_ptr,AMD64_RCX,AMD64_RBX,0,AMD64_RSI,0,1); ! 265: ppc32_store_gpr(b,target,AMD64_RCX); ! 266: } ! 267: ! 268: /* Fast STB */ ! 269: static void ppc32_memop_fast_stb(ppc32_jit_tcb_t *b,int target) ! 270: { ! 271: ppc32_load_gpr(b,AMD64_RDX,target); ! 272: amd64_mov_memindex_reg(b->jit_ptr,AMD64_RBX,0,AMD64_RSI,0,AMD64_RDX,1); ! 273: } ! 274: ! 275: /* Fast LWZ */ ! 276: static void ppc32_memop_fast_lwz(ppc32_jit_tcb_t *b,int target) ! 277: { ! 278: amd64_mov_reg_memindex(b->jit_ptr,AMD64_RAX,AMD64_RBX,0,AMD64_RSI,0,4); ! 279: amd64_bswap32(b->jit_ptr,AMD64_RAX); ! 280: ppc32_store_gpr(b,target,AMD64_RAX); ! 281: } ! 282: ! 283: /* Fast STW */ ! 284: static void ppc32_memop_fast_stw(ppc32_jit_tcb_t *b,int target) ! 285: { ! 286: ppc32_load_gpr(b,AMD64_RDX,target); ! 287: amd64_bswap32(b->jit_ptr,AMD64_RDX); ! 288: amd64_mov_memindex_reg(b->jit_ptr,AMD64_RBX,0,AMD64_RSI,0,AMD64_RDX,4); ! 289: } ! 290: ! 291: /* Fast memory operation */ ! 292: static void ppc32_emit_memop_fast(ppc32_jit_tcb_t *b,int write_op, ! 293: int opcode,int base,int offset,int target, ! 294: memop_fast_access op_handler) ! 295: { ! 296: m_uint32_t val = sign_extend(offset,16); ! 297: u_char *test1,*test2,*p_exception,*p_exit; ! 298: ! 299: test2 = NULL; ! 300: ! 301: /* RSI = GPR[base] + sign-extended offset */ ! 302: ppc32_load_imm(b,AMD64_RSI,val); ! 303: if (base != 0) ! 304: ppc32_alu_gpr(b,X86_ADD,AMD64_RSI,base); ! 305: ! 306: /* RBX = mts32_entry index */ ! 307: amd64_mov_reg_reg_size(b->jit_ptr,X86_EBX,X86_ESI,4); ! 308: amd64_shift_reg_imm_size(b->jit_ptr,X86_SHR,X86_EBX,MTS32_HASH_SHIFT,4); ! 309: amd64_alu_reg_imm_size(b->jit_ptr,X86_AND,X86_EBX,MTS32_HASH_MASK,4); ! 310: ! 311: /* RCX = mts32 entry */ ! 312: amd64_mov_reg_membase(b->jit_ptr,AMD64_RCX, ! 313: AMD64_R15, ! 314: OFFSET(cpu_ppc_t,mts_cache[PPC32_MTS_DCACHE]),8); ! 315: amd64_shift_reg_imm(b->jit_ptr,X86_SHL,AMD64_RBX,5); /* TO FIX */ ! 316: amd64_alu_reg_reg(b->jit_ptr,X86_ADD,AMD64_RCX,AMD64_RBX); ! 317: ! 318: /* Compare virtual page address (EAX = vpage) */ ! 319: amd64_mov_reg_reg(b->jit_ptr,X86_EAX,X86_ESI,4); ! 320: amd64_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,PPC32_MIN_PAGE_MASK); ! 321: ! 322: amd64_alu_reg_membase_size(b->jit_ptr,X86_CMP,X86_EAX,AMD64_RCX, ! 323: OFFSET(mts32_entry_t,gvpa),4); ! 324: test1 = b->jit_ptr; ! 325: x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1); ! 326: ! 327: /* Test if we are writing to a COW page */ ! 328: if (write_op) { ! 329: amd64_test_membase_imm_size(b->jit_ptr, ! 330: AMD64_RCX,OFFSET(mts32_entry_t,flags), ! 331: MTS_FLAG_COW,4); ! 332: test2 = b->jit_ptr; ! 333: amd64_branch8(b->jit_ptr, X86_CC_NZ, 0, 1); ! 334: } ! 335: ! 336: /* ESI = offset in page, RBX = Host Page Address */ ! 337: amd64_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,PPC32_MIN_PAGE_IMASK); ! 338: amd64_mov_reg_membase(b->jit_ptr,AMD64_RBX, ! 339: AMD64_RCX,OFFSET(mts32_entry_t,hpa),8); ! 340: ! 341: /* Memory access */ ! 342: op_handler(b,target); ! 343: ! 344: p_exit = b->jit_ptr; ! 345: amd64_jump8(b->jit_ptr,0); ! 346: ! 347: /* === Slow lookup === */ ! 348: amd64_patch(test1,b->jit_ptr); ! 349: if (test2) ! 350: amd64_patch(test2,b->jit_ptr); ! 351: ! 352: /* Save IA for exception handling */ ! 353: ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2)); ! 354: ! 355: /* RDX = target register */ ! 356: amd64_mov_reg_imm(b->jit_ptr,AMD64_RDX,target); ! 357: ! 358: /* RDI = CPU instance */ ! 359: amd64_mov_reg_reg(b->jit_ptr,AMD64_RDI,AMD64_R15,8); ! 360: ! 361: /* Call memory access function */ ! 362: amd64_call_membase(b->jit_ptr,AMD64_R15,MEMOP_OFFSET(opcode)); ! 363: ! 364: /* Exception ? */ ! 365: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RAX,AMD64_RAX,4); ! 366: p_exception = b->jit_ptr; ! 367: amd64_branch8(b->jit_ptr, X86_CC_Z, 0, 1); ! 368: ppc32_jit_tcb_push_epilog(b); ! 369: ! 370: amd64_patch(p_exit,b->jit_ptr); ! 371: amd64_patch(p_exception,b->jit_ptr); ! 372: } ! 373: ! 374: /* Emit unhandled instruction code */ ! 375: static int ppc32_emit_unknown(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, ! 376: ppc_insn_t opcode) ! 377: { ! 378: u_char *test1; ! 379: ! 380: #if 0 ! 381: x86_mov_reg_imm(b->jit_ptr,X86_EAX,opcode); ! 382: x86_alu_reg_imm(b->jit_ptr,X86_SUB,X86_ESP,4); ! 383: x86_push_reg(b->jit_ptr,X86_EAX); ! 384: x86_push_reg(b->jit_ptr,X86_EDI); ! 385: ppc32_emit_c_call(b,ppc32_unknown_opcode); ! 386: x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12); ! 387: #endif ! 388: ! 389: /* Fallback to non-JIT mode */ ! 390: amd64_mov_reg_reg(b->jit_ptr,AMD64_RDI,AMD64_R15,8); ! 391: amd64_mov_reg_imm(b->jit_ptr,AMD64_RSI,opcode); ! 392: ! 393: ppc32_emit_c_call(b,ppc32_exec_single_insn_ext); ! 394: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RAX,AMD64_RAX,4); ! 395: test1 = b->jit_ptr; ! 396: amd64_branch8(b->jit_ptr, X86_CC_Z, 0, 1); ! 397: ppc32_jit_tcb_push_epilog(b); ! 398: ! 399: amd64_patch(test1,b->jit_ptr); ! 400: return(0); ! 401: } ! 402: ! 403: /* Increment the number of executed instructions (performance debugging) */ ! 404: void ppc32_inc_perf_counter(ppc32_jit_tcb_t *b) ! 405: { ! 406: amd64_inc_membase(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,perf_counter)); ! 407: } ! 408: ! 409: /* ======================================================================== */ ! 410: ! 411: /* BLR - Branch to Link Register */ ! 412: DECLARE_INSN(BLR) ! 413: { ! 414: amd64_mov_reg_membase(b->jit_ptr,AMD64_RDX, ! 415: AMD64_R15,OFFSET(cpu_ppc_t,lr),4); ! 416: amd64_mov_membase_reg(b->jit_ptr, ! 417: AMD64_R15,OFFSET(cpu_ppc_t,ia),AMD64_RDX,4); ! 418: ! 419: /* set the return address */ ! 420: if (insn & 1) ! 421: ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2)); ! 422: ! 423: ppc32_jit_tcb_push_epilog(b); ! 424: return(0); ! 425: } ! 426: ! 427: /* BCTR - Branch to Count Register */ ! 428: DECLARE_INSN(BCTR) ! 429: { ! 430: amd64_mov_reg_membase(b->jit_ptr,AMD64_RDX, ! 431: AMD64_R15,OFFSET(cpu_ppc_t,ctr),4); ! 432: amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ia), ! 433: AMD64_RDX,4); ! 434: ! 435: /* set the return address */ ! 436: if (insn & 1) ! 437: ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2)); ! 438: ! 439: ppc32_jit_tcb_push_epilog(b); ! 440: return(0); ! 441: } ! 442: ! 443: /* MFLR - Move From Link Register */ ! 444: DECLARE_INSN(MFLR) ! 445: { ! 446: int rd = bits(insn,21,25); ! 447: ! 448: amd64_mov_reg_membase(b->jit_ptr,AMD64_RDX, ! 449: AMD64_R15,OFFSET(cpu_ppc_t,lr),4); ! 450: ppc32_store_gpr(b,rd,X86_EDX); ! 451: return(0); ! 452: } ! 453: ! 454: /* MTLR - Move To Link Register */ ! 455: DECLARE_INSN(MTLR) ! 456: { ! 457: int rs = bits(insn,21,25); ! 458: ! 459: ppc32_load_gpr(b,X86_EDX,rs); ! 460: amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,lr), ! 461: AMD64_RDX,4); ! 462: return(0); ! 463: } ! 464: ! 465: /* MFCTR - Move From Counter Register */ ! 466: DECLARE_INSN(MFCTR) ! 467: { ! 468: int rd = bits(insn,21,25); ! 469: ! 470: amd64_mov_reg_membase(b->jit_ptr,AMD64_RDX, ! 471: AMD64_R15,OFFSET(cpu_ppc_t,ctr),4); ! 472: ppc32_store_gpr(b,rd,AMD64_RDX); ! 473: return(0); ! 474: } ! 475: ! 476: /* MTCTR - Move To Counter Register */ ! 477: DECLARE_INSN(MTCTR) ! 478: { ! 479: int rs = bits(insn,21,25); ! 480: ! 481: ppc32_load_gpr(b,AMD64_RDX,rs); ! 482: amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ctr), ! 483: AMD64_RDX,4); ! 484: return(0); ! 485: } ! 486: ! 487: /* MFTBU - Move from Time Base (Up) */ ! 488: DECLARE_INSN(MFTBU) ! 489: { ! 490: int rd = bits(insn,21,25); ! 491: ! 492: amd64_mov_reg_membase(b->jit_ptr,AMD64_RDX, ! 493: AMD64_R15,OFFSET(cpu_ppc_t,tb)+4,4); ! 494: ppc32_store_gpr(b,rd,AMD64_RDX); ! 495: return(0); ! 496: } ! 497: ! 498: #define PPC32_TB_INCREMENT 50 ! 499: ! 500: /* MFTBL - Move from Time Base (Lo) */ ! 501: DECLARE_INSN(MFTBL) ! 502: { ! 503: int rd = bits(insn,21,25); ! 504: ! 505: /* Increment the time base register */ ! 506: amd64_mov_reg_membase(b->jit_ptr,AMD64_RDX, ! 507: AMD64_R15,OFFSET(cpu_ppc_t,tb),8); ! 508: amd64_alu_reg_imm(b->jit_ptr,X86_ADD,AMD64_RDX,PPC32_TB_INCREMENT); ! 509: amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,tb), ! 510: AMD64_RDX,8); ! 511: ! 512: ppc32_store_gpr(b,rd,AMD64_RDX); ! 513: return(0); ! 514: } ! 515: ! 516: /* ADD */ ! 517: DECLARE_INSN(ADD) ! 518: { ! 519: int rd = bits(insn,21,25); ! 520: int ra = bits(insn,16,20); ! 521: int rb = bits(insn,11,15); ! 522: ! 523: /* $rd = $ra + $rb */ ! 524: ppc32_load_gpr(b,AMD64_RBX,ra); ! 525: ppc32_alu_gpr(b,X86_ADD,AMD64_RBX,rb); ! 526: ppc32_store_gpr(b,rd,AMD64_RBX); ! 527: ! 528: if (insn & 1) ! 529: ppc32_update_cr0(b); ! 530: ! 531: return(0); ! 532: } ! 533: ! 534: /* ADDC */ ! 535: DECLARE_INSN(ADDC) ! 536: { ! 537: int rd = bits(insn,21,25); ! 538: int ra = bits(insn,16,20); ! 539: int rb = bits(insn,11,15); ! 540: ! 541: /* $rd = $ra + $rb */ ! 542: ppc32_load_gpr(b,AMD64_RBX,ra); ! 543: ppc32_alu_gpr(b,X86_ADD,AMD64_RBX,rb); ! 544: ppc32_store_gpr(b,rd,AMD64_RBX); ! 545: ! 546: /* store the carry flag */ ! 547: amd64_set_reg(b->jit_ptr,X86_CC_C,AMD64_RAX,FALSE); ! 548: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RAX,0x1); ! 549: amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,xer_ca), ! 550: AMD64_RAX,4); ! 551: ! 552: if (insn & 1) { ! 553: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RBX,AMD64_RBX,4); ! 554: ppc32_update_cr0(b); ! 555: } ! 556: ! 557: return(0); ! 558: } ! 559: ! 560: /* ADDE - Add Extended */ ! 561: DECLARE_INSN(ADDE) ! 562: { ! 563: int rd = bits(insn,21,25); ! 564: int ra = bits(insn,16,20); ! 565: int rb = bits(insn,11,15); ! 566: ! 567: /* $ra + carry */ ! 568: ppc32_load_gpr(b,AMD64_RSI,ra); ! 569: amd64_alu_reg_membase_size(b->jit_ptr,X86_ADD,AMD64_RSI, ! 570: AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),4); ! 571: amd64_set_reg(b->jit_ptr,X86_CC_C,AMD64_RAX,FALSE); ! 572: ! 573: /* add $rb */ ! 574: ppc32_alu_gpr(b,X86_ADD,AMD64_RSI,rb); ! 575: amd64_set_reg(b->jit_ptr,X86_CC_C,AMD64_RCX,FALSE); ! 576: ! 577: ppc32_store_gpr(b,rd,AMD64_RSI); ! 578: ! 579: /* store the carry flag */ ! 580: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RAX,AMD64_RCX); ! 581: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RAX,0x1); ! 582: ! 583: amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,xer_ca), ! 584: AMD64_RAX,4); ! 585: ! 586: /* update cr0 */ ! 587: if (insn & 1) { ! 588: x86_test_reg_reg(b->jit_ptr,AMD64_RSI,AMD64_RSI); ! 589: ppc32_update_cr0(b); ! 590: } ! 591: ! 592: return(0); ! 593: } ! 594: ! 595: /* ADDI - ADD Immediate */ ! 596: DECLARE_INSN(ADDI) ! 597: { ! 598: int rd = bits(insn,21,25); ! 599: int ra = bits(insn,16,20); ! 600: int imm = bits(insn,0,15); ! 601: m_uint32_t tmp = sign_extend_32(imm,16); ! 602: ! 603: ppc32_load_imm(b,AMD64_RBX,tmp); ! 604: ! 605: if (ra != 0) ! 606: amd64_alu_reg_membase_size(b->jit_ptr,X86_ADD,AMD64_RBX, ! 607: AMD64_R15,REG_OFFSET(ra),4); ! 608: ! 609: ppc32_store_gpr(b,rd,AMD64_RBX); ! 610: return(0); ! 611: } ! 612: ! 613: /* ADDIC - ADD Immediate with Carry */ ! 614: DECLARE_INSN(ADDIC) ! 615: { ! 616: int rd = bits(insn,21,25); ! 617: int ra = bits(insn,16,20); ! 618: int imm = bits(insn,0,15); ! 619: m_uint32_t tmp = sign_extend_32(imm,16); ! 620: ! 621: ppc32_load_imm(b,AMD64_RAX,tmp); ! 622: ppc32_alu_gpr(b,X86_ADD,AMD64_RAX,ra); ! 623: ppc32_store_gpr(b,rd,AMD64_RAX); ! 624: amd64_set_membase_size(b->jit_ptr,X86_CC_C, ! 625: AMD64_R15,OFFSET(cpu_ppc_t,xer_ca), ! 626: FALSE,4); ! 627: return(0); ! 628: } ! 629: ! 630: /* ADDIC. */ ! 631: DECLARE_INSN(ADDIC_dot) ! 632: { ! 633: int rd = bits(insn,21,25); ! 634: int ra = bits(insn,16,20); ! 635: int imm = bits(insn,0,15); ! 636: m_uint32_t tmp = sign_extend_32(imm,16); ! 637: ! 638: ppc32_load_imm(b,AMD64_RAX,tmp); ! 639: ppc32_alu_gpr(b,X86_ADD,AMD64_RAX,ra); ! 640: ppc32_store_gpr(b,rd,AMD64_RAX); ! 641: amd64_set_membase_size(b->jit_ptr,X86_CC_C, ! 642: AMD64_R15,OFFSET(cpu_ppc_t,xer_ca), ! 643: FALSE,4); ! 644: ! 645: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RAX,AMD64_RAX,4); ! 646: ppc32_update_cr0(b); ! 647: return(0); ! 648: } ! 649: ! 650: /* ADDIS - ADD Immediate Shifted */ ! 651: DECLARE_INSN(ADDIS) ! 652: { ! 653: int rd = bits(insn,21,25); ! 654: int ra = bits(insn,16,20); ! 655: m_uint32_t imm = bits(insn,0,15); ! 656: ! 657: ppc32_load_imm(b,AMD64_RBX,imm << 16); ! 658: ! 659: if (ra != 0) ! 660: amd64_alu_reg_membase_size(b->jit_ptr,X86_ADD,AMD64_RBX, ! 661: AMD64_R15,REG_OFFSET(ra),4); ! 662: ! 663: ppc32_store_gpr(b,rd,AMD64_RBX); ! 664: return(0); ! 665: } ! 666: ! 667: /* AND */ ! 668: DECLARE_INSN(AND) ! 669: { ! 670: int rs = bits(insn,21,25); ! 671: int ra = bits(insn,16,20); ! 672: int rb = bits(insn,11,15); ! 673: ! 674: ppc32_load_gpr(b,AMD64_RBX,rs); ! 675: ppc32_alu_gpr(b,X86_AND,AMD64_RBX,rb); ! 676: ppc32_store_gpr(b,ra,AMD64_RBX); ! 677: ! 678: if (insn & 1) ! 679: ppc32_update_cr0(b); ! 680: ! 681: return(0); ! 682: } ! 683: ! 684: /* ANDC */ ! 685: DECLARE_INSN(ANDC) ! 686: { ! 687: int rs = bits(insn,21,25); ! 688: int ra = bits(insn,16,20); ! 689: int rb = bits(insn,11,15); ! 690: ! 691: /* $ra = $rs & ~$rb */ ! 692: ppc32_load_gpr(b,AMD64_RBX,rb); ! 693: x86_not_reg(b->jit_ptr,AMD64_RBX); ! 694: ppc32_alu_gpr(b,X86_AND,AMD64_RBX,rs); ! 695: ppc32_store_gpr(b,ra,AMD64_RBX); ! 696: ! 697: if (insn & 1) ! 698: ppc32_update_cr0(b); ! 699: ! 700: return(0); ! 701: } ! 702: ! 703: /* AND Immediate */ ! 704: DECLARE_INSN(ANDI) ! 705: { ! 706: int rs = bits(insn,21,25); ! 707: int ra = bits(insn,16,20); ! 708: m_uint16_t imm = bits(insn,0,15); ! 709: ! 710: /* $ra = $rs & imm */ ! 711: ppc32_load_imm(b,AMD64_RBX,imm); ! 712: ppc32_alu_gpr(b,X86_AND,AMD64_RBX,rs); ! 713: ppc32_store_gpr(b,ra,AMD64_RBX); ! 714: ! 715: ppc32_update_cr0(b); ! 716: return(0); ! 717: } ! 718: ! 719: /* AND Immediate Shifted */ ! 720: DECLARE_INSN(ANDIS) ! 721: { ! 722: int rs = bits(insn,21,25); ! 723: int ra = bits(insn,16,20); ! 724: m_uint32_t imm = bits(insn,0,15); ! 725: ! 726: /* $ra = $rs & imm */ ! 727: ppc32_load_imm(b,AMD64_RBX,imm << 16); ! 728: ppc32_alu_gpr(b,X86_AND,AMD64_RBX,rs); ! 729: ppc32_store_gpr(b,ra,AMD64_RBX); ! 730: ! 731: ppc32_update_cr0(b); ! 732: return(0); ! 733: } ! 734: ! 735: /* B - Branch */ ! 736: DECLARE_INSN(B) ! 737: { ! 738: m_uint32_t offset = bits(insn,2,25); ! 739: m_uint64_t new_ia; ! 740: ! 741: /* compute the new ia */ ! 742: new_ia = b->start_ia + ((b->ppc_trans_pos-1) << 2); ! 743: new_ia += sign_extend(offset << 2,26); ! 744: ppc32_set_jump(cpu,b,new_ia,1); ! 745: return(0); ! 746: } ! 747: ! 748: /* BA - Branch Absolute */ ! 749: DECLARE_INSN(BA) ! 750: { ! 751: m_uint32_t offset = bits(insn,2,25); ! 752: m_uint64_t new_ia; ! 753: ! 754: /* compute the new ia */ ! 755: new_ia = sign_extend(offset << 2,26); ! 756: ppc32_set_jump(cpu,b,new_ia,1); ! 757: return(0); ! 758: } ! 759: ! 760: /* BL - Branch and Link */ ! 761: DECLARE_INSN(BL) ! 762: { ! 763: m_uint32_t offset = bits(insn,2,25); ! 764: m_uint64_t new_ia; ! 765: ! 766: /* compute the new ia */ ! 767: new_ia = b->start_ia + ((b->ppc_trans_pos-1) << 2); ! 768: new_ia += sign_extend(offset << 2,26); ! 769: ! 770: /* set the return address */ ! 771: ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2)); ! 772: ! 773: ppc32_set_jump(cpu,b,new_ia,1); ! 774: return(0); ! 775: } ! 776: ! 777: /* BLA - Branch and Link Absolute */ ! 778: DECLARE_INSN(BLA) ! 779: { ! 780: m_uint32_t offset = bits(insn,2,25); ! 781: m_uint64_t new_ia; ! 782: ! 783: /* compute the new ia */ ! 784: new_ia = sign_extend(offset << 2,26); ! 785: ! 786: /* set the return address */ ! 787: ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2)); ! 788: ! 789: ppc32_set_jump(cpu,b,new_ia,1); ! 790: return(0); ! 791: } ! 792: ! 793: /* BC - Branch Conditional (Condition Check only) */ ! 794: DECLARE_INSN(BCC) ! 795: { ! 796: int bo = bits(insn,21,25); ! 797: int bi = bits(insn,16,20); ! 798: int bd = bits(insn,2,15); ! 799: m_uint32_t new_ia; ! 800: u_char *jump_ptr; ! 801: int local_jump; ! 802: int cond; ! 803: ! 804: /* Get the wanted value for the condition bit */ ! 805: cond = (bo >> 3) & 0x1; ! 806: ! 807: /* Set the return address */ ! 808: if (insn & 1) ! 809: ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2)); ! 810: ! 811: /* Compute the new ia */ ! 812: new_ia = sign_extend_32(bd << 2,16); ! 813: if (!(insn & 0x02)) ! 814: new_ia += b->start_ia + ((b->ppc_trans_pos-1) << 2); ! 815: ! 816: /* Test the condition bit */ ! 817: amd64_test_membase_imm_size(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,cr), ! 818: (1 << (31 - bi)),4); ! 819: ! 820: local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr); ! 821: ! 822: /* ! 823: * Optimize the jump, depending if the destination is in the same ! 824: * page or not. ! 825: */ ! 826: if (local_jump) { ! 827: if (jump_ptr) { ! 828: amd64_branch(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,jump_ptr,FALSE); ! 829: } else { ! 830: ppc32_jit_tcb_record_patch(b,b->jit_ptr,new_ia); ! 831: amd64_branch32(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,0,FALSE); ! 832: } ! 833: } else { ! 834: jump_ptr = b->jit_ptr; ! 835: amd64_branch32(b->jit_ptr,(cond) ? X86_CC_Z : X86_CC_NZ,0,FALSE); ! 836: ppc32_set_jump(cpu,b,new_ia,TRUE); ! 837: amd64_patch(jump_ptr,b->jit_ptr); ! 838: } ! 839: ! 840: return(0); ! 841: } ! 842: ! 843: /* BC - Branch Conditional */ ! 844: DECLARE_INSN(BC) ! 845: { ! 846: int bo = bits(insn,21,25); ! 847: int bi = bits(insn,16,20); ! 848: int bd = bits(insn,2,15); ! 849: m_uint32_t new_ia; ! 850: u_char *jump_ptr; ! 851: int local_jump; ! 852: int cond,ctr; ! 853: ! 854: /* Get the wanted value for the condition bit and CTR value */ ! 855: cond = (bo >> 3) & 0x1; ! 856: ctr = (bo >> 1) & 0x1; ! 857: ! 858: /* Set the return address */ ! 859: if (insn & 1) ! 860: ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2)); ! 861: ! 862: /* Compute the new ia */ ! 863: new_ia = sign_extend_32(bd << 2,16); ! 864: if (!(insn & 0x02)) ! 865: new_ia += b->start_ia + ((b->ppc_trans_pos-1) << 2); ! 866: ! 867: ppc32_load_imm(b,AMD64_RAX,1); ! 868: ! 869: /* Decrement the count register */ ! 870: if (!(bo & 0x04)) { ! 871: amd64_dec_membase_size(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ctr),4); ! 872: amd64_set_reg(b->jit_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,AMD64_RBX,FALSE); ! 873: amd64_alu_reg_reg(b->jit_ptr,X86_AND,AMD64_RAX,AMD64_RBX); ! 874: } ! 875: ! 876: /* Test the condition bit */ ! 877: if (!((bo >> 4) & 0x01)) { ! 878: amd64_test_membase_imm_size(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,cr), ! 879: (1 << (31 - bi)),4); ! 880: amd64_set_reg(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,AMD64_RCX,FALSE); ! 881: amd64_alu_reg_reg(b->jit_ptr,X86_AND,AMD64_RAX,AMD64_RCX); ! 882: } ! 883: ! 884: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RAX,0x01); ! 885: ! 886: local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr); ! 887: ! 888: /* ! 889: * Optimize the jump, depending if the destination is in the same ! 890: * page or not. ! 891: */ ! 892: if (local_jump) { ! 893: if (jump_ptr) { ! 894: amd64_branch(b->jit_ptr,X86_CC_NZ,jump_ptr,FALSE); ! 895: } else { ! 896: ppc32_jit_tcb_record_patch(b,b->jit_ptr,new_ia); ! 897: amd64_branch32(b->jit_ptr,X86_CC_NZ,0,FALSE); ! 898: } ! 899: } else { ! 900: jump_ptr = b->jit_ptr; ! 901: amd64_branch32(b->jit_ptr,X86_CC_Z,0,FALSE); ! 902: ppc32_set_jump(cpu,b,new_ia,TRUE); ! 903: amd64_patch(jump_ptr,b->jit_ptr); ! 904: } ! 905: ! 906: return(0); ! 907: } ! 908: ! 909: /* BCLR - Branch Conditional to Link register */ ! 910: DECLARE_INSN(BCLR) ! 911: { ! 912: int bo = bits(insn,21,25); ! 913: int bi = bits(insn,16,20); ! 914: int bd = bits(insn,2,15); ! 915: m_uint32_t new_ia; ! 916: u_char *jump_ptr; ! 917: int cond,ctr; ! 918: ! 919: /* Get the wanted value for the condition bit and CTR value */ ! 920: cond = (bo >> 3) & 0x1; ! 921: ctr = (bo >> 1) & 0x1; ! 922: ! 923: /* Compute the new ia */ ! 924: new_ia = sign_extend_32(bd << 2,16); ! 925: if (!(insn & 0x02)) ! 926: new_ia += b->start_ia + ((b->ppc_trans_pos-1) << 2); ! 927: ! 928: ppc32_load_imm(b,AMD64_RAX,1); ! 929: ! 930: /* Decrement the count register */ ! 931: if (!(bo & 0x04)) { ! 932: amd64_dec_membase_size(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ctr),4); ! 933: amd64_set_reg(b->jit_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,AMD64_RBX,FALSE); ! 934: amd64_alu_reg_reg(b->jit_ptr,X86_AND,AMD64_RAX,AMD64_RBX); ! 935: } ! 936: ! 937: /* Test the condition bit */ ! 938: if (!((bo >> 4) & 0x01)) { ! 939: amd64_test_membase_imm_size(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,cr), ! 940: (1 << (31 - bi)),4); ! 941: amd64_set_reg(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,AMD64_RCX,FALSE); ! 942: amd64_alu_reg_reg(b->jit_ptr,X86_AND,AMD64_RAX,AMD64_RCX); ! 943: } ! 944: ! 945: /* Set the return address */ ! 946: amd64_mov_reg_membase(b->jit_ptr,AMD64_RDX, ! 947: AMD64_R15,OFFSET(cpu_ppc_t,lr),4); ! 948: ! 949: if (insn & 1) ! 950: ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2)); ! 951: ! 952: /* Branching */ ! 953: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RAX,0x01); ! 954: ! 955: jump_ptr = b->jit_ptr; ! 956: amd64_branch32(b->jit_ptr,X86_CC_Z,0,FALSE); ! 957: ! 958: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RDX,0xFFFFFFFC); ! 959: amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ia), ! 960: AMD64_RDX,4); ! 961: ppc32_jit_tcb_push_epilog(b); ! 962: ! 963: amd64_patch(jump_ptr,b->jit_ptr); ! 964: return(0); ! 965: } ! 966: ! 967: /* CMP - Compare */ ! 968: DECLARE_INSN(CMP) ! 969: { ! 970: int rd = bits(insn,23,25); ! 971: int ra = bits(insn,16,20); ! 972: int rb = bits(insn,11,15); ! 973: ! 974: ppc32_load_gpr(b,AMD64_RBX,ra); ! 975: ppc32_alu_gpr(b,X86_CMP,AMD64_RBX,rb); ! 976: ppc32_update_cr(b,rd,TRUE); ! 977: return(0); ! 978: } ! 979: ! 980: /* CMPI - Compare Immediate */ ! 981: DECLARE_INSN(CMPI) ! 982: { ! 983: int rd = bits(insn,23,25); ! 984: int ra = bits(insn,16,20); ! 985: m_uint16_t imm = bits(insn,0,15); ! 986: m_uint32_t tmp = sign_extend_32(imm,16); ! 987: ! 988: ppc32_load_imm(b,AMD64_RBX,tmp); ! 989: ppc32_load_gpr(b,AMD64_RSI,ra); ! 990: amd64_alu_reg_reg_size(b->jit_ptr,X86_CMP,AMD64_RSI,AMD64_RBX,4); ! 991: ! 992: ppc32_update_cr(b,rd,TRUE); ! 993: return(0); ! 994: } ! 995: ! 996: /* CMPL - Compare Logical */ ! 997: DECLARE_INSN(CMPL) ! 998: { ! 999: int rd = bits(insn,23,25); ! 1000: int ra = bits(insn,16,20); ! 1001: int rb = bits(insn,11,15); ! 1002: ! 1003: ppc32_load_gpr(b,AMD64_RAX,ra); ! 1004: ppc32_alu_gpr(b,X86_CMP,AMD64_RAX,rb); ! 1005: ppc32_update_cr(b,rd,FALSE); ! 1006: return(0); ! 1007: } ! 1008: ! 1009: /* CMPLI - Compare Immediate */ ! 1010: DECLARE_INSN(CMPLI) ! 1011: { ! 1012: int rd = bits(insn,23,25); ! 1013: int ra = bits(insn,16,20); ! 1014: m_uint16_t imm = bits(insn,0,15); ! 1015: ! 1016: ppc32_load_imm(b,AMD64_RBX,imm); ! 1017: ppc32_load_gpr(b,AMD64_RSI,ra); ! 1018: amd64_alu_reg_reg_size(b->jit_ptr,X86_CMP,AMD64_RSI,AMD64_RBX,4); ! 1019: ! 1020: ppc32_update_cr(b,rd,FALSE); ! 1021: return(0); ! 1022: } ! 1023: ! 1024: /* CRAND - Condition Register AND */ ! 1025: DECLARE_INSN(CRAND) ! 1026: { ! 1027: int bd = bits(insn,21,25); ! 1028: int bb = bits(insn,16,20); ! 1029: int ba = bits(insn,11,15); ! 1030: ! 1031: ppc32_load_cr(b,AMD64_RSI); ! 1032: ! 1033: /* test $ba bit */ ! 1034: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - ba)),4); ! 1035: amd64_set_reg(b->jit_ptr,X86_CC_NZ,AMD64_RAX,FALSE); ! 1036: ! 1037: /* test $bb bit */ ! 1038: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - bb)),4); ! 1039: amd64_set_reg(b->jit_ptr,X86_CC_NZ,AMD64_RBX,FALSE); ! 1040: ! 1041: /* result of AND between $ba and $bb */ ! 1042: amd64_alu_reg_reg(b->jit_ptr,X86_AND,AMD64_RBX,AMD64_RAX); ! 1043: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RBX,0x01); ! 1044: ! 1045: /* set/clear $bd bit depending on the result */ ! 1046: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RSI,~(1 << (31 - bd))); ! 1047: amd64_shift_reg_imm(b->jit_ptr,X86_SHL,AMD64_RBX,(31 - bd)); ! 1048: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RSI,AMD64_RBX); ! 1049: ! 1050: ppc32_store_cr(b,AMD64_RSI); ! 1051: return(0); ! 1052: } ! 1053: ! 1054: /* CRANDC - Condition Register AND with Complement */ ! 1055: DECLARE_INSN(CRANDC) ! 1056: { ! 1057: int bd = bits(insn,21,25); ! 1058: int bb = bits(insn,16,20); ! 1059: int ba = bits(insn,11,15); ! 1060: ! 1061: ppc32_load_cr(b,AMD64_RSI); ! 1062: ! 1063: /* test $ba bit */ ! 1064: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - ba)),4); ! 1065: amd64_set_reg(b->jit_ptr,X86_CC_NZ,AMD64_RAX,FALSE); ! 1066: ! 1067: /* test $bb bit */ ! 1068: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - bb)),4); ! 1069: amd64_set_reg(b->jit_ptr,X86_CC_Z,AMD64_RBX,FALSE); ! 1070: ! 1071: /* result of AND between $ba and $bb */ ! 1072: amd64_alu_reg_reg(b->jit_ptr,X86_AND,AMD64_RBX,AMD64_RAX); ! 1073: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RBX,0x01); ! 1074: ! 1075: /* set/clear $bd bit depending on the result */ ! 1076: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RSI,~(1 << (31 - bd))); ! 1077: amd64_shift_reg_imm(b->jit_ptr,X86_SHL,AMD64_RBX,(31 - bd)); ! 1078: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RSI,AMD64_RBX); ! 1079: ! 1080: ppc32_store_cr(b,AMD64_RSI); ! 1081: return(0); ! 1082: } ! 1083: ! 1084: /* CREQV - Condition Register EQV */ ! 1085: DECLARE_INSN(CREQV) ! 1086: { ! 1087: int bd = bits(insn,21,25); ! 1088: int bb = bits(insn,16,20); ! 1089: int ba = bits(insn,11,15); ! 1090: ! 1091: ppc32_load_cr(b,AMD64_RSI); ! 1092: ! 1093: /* test $ba bit */ ! 1094: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - ba)),4); ! 1095: amd64_set_reg(b->jit_ptr,X86_CC_NZ,AMD64_RAX,FALSE); ! 1096: ! 1097: /* test $bb bit */ ! 1098: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - bb)),4); ! 1099: amd64_set_reg(b->jit_ptr,X86_CC_NZ,AMD64_RBX,FALSE); ! 1100: ! 1101: /* result of XOR between $ba and $bb */ ! 1102: amd64_alu_reg_reg(b->jit_ptr,X86_XOR,AMD64_RBX,AMD64_RAX); ! 1103: amd64_not_reg(b->jit_ptr,AMD64_RBX); ! 1104: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RBX,0x01); ! 1105: ! 1106: /* set/clear $bd bit depending on the result */ ! 1107: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RSI,~(1 << (31 - bd))); ! 1108: amd64_shift_reg_imm(b->jit_ptr,X86_SHL,AMD64_RBX,(31 - bd)); ! 1109: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RSI,AMD64_RBX); ! 1110: ! 1111: ppc32_store_cr(b,AMD64_RSI); ! 1112: return(0); ! 1113: } ! 1114: ! 1115: /* CRNAND - Condition Register NAND */ ! 1116: DECLARE_INSN(CRNAND) ! 1117: { ! 1118: int bd = bits(insn,21,25); ! 1119: int bb = bits(insn,16,20); ! 1120: int ba = bits(insn,11,15); ! 1121: ! 1122: ppc32_load_cr(b,AMD64_RSI); ! 1123: ! 1124: /* test $ba bit */ ! 1125: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - ba)),4); ! 1126: amd64_set_reg(b->jit_ptr,X86_CC_NZ,AMD64_RAX,FALSE); ! 1127: ! 1128: /* test $bb bit */ ! 1129: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - bb)),4); ! 1130: amd64_set_reg(b->jit_ptr,X86_CC_NZ,AMD64_RBX,FALSE); ! 1131: ! 1132: /* result of NAND between $ba and $bb */ ! 1133: amd64_alu_reg_reg(b->jit_ptr,X86_AND,AMD64_RBX,AMD64_RAX); ! 1134: amd64_not_reg(b->jit_ptr,AMD64_RBX); ! 1135: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RBX,0x01); ! 1136: ! 1137: /* set/clear $bd bit depending on the result */ ! 1138: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RSI,~(1 << (31 - bd))); ! 1139: amd64_shift_reg_imm(b->jit_ptr,X86_SHL,AMD64_RBX,(31 - bd)); ! 1140: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RSI,AMD64_RBX); ! 1141: ! 1142: ppc32_store_cr(b,AMD64_RSI); ! 1143: return(0); ! 1144: } ! 1145: ! 1146: /* CRNOR - Condition Register NOR */ ! 1147: DECLARE_INSN(CRNOR) ! 1148: { ! 1149: int bd = bits(insn,21,25); ! 1150: int bb = bits(insn,16,20); ! 1151: int ba = bits(insn,11,15); ! 1152: ! 1153: ppc32_load_cr(b,AMD64_RSI); ! 1154: ! 1155: /* test $ba bit */ ! 1156: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - ba)),4); ! 1157: amd64_set_reg(b->jit_ptr,X86_CC_NZ,AMD64_RAX,FALSE); ! 1158: ! 1159: /* test $bb bit */ ! 1160: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - bb)),4); ! 1161: amd64_set_reg(b->jit_ptr,X86_CC_NZ,AMD64_RBX,FALSE); ! 1162: ! 1163: /* result of NOR between $ba and $bb */ ! 1164: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RBX,AMD64_RAX); ! 1165: amd64_not_reg(b->jit_ptr,AMD64_RBX); ! 1166: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RBX,0x01); ! 1167: ! 1168: /* set/clear $bd bit depending on the result */ ! 1169: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RSI,~(1 << (31 - bd))); ! 1170: amd64_shift_reg_imm(b->jit_ptr,X86_SHL,AMD64_RBX,(31 - bd)); ! 1171: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RSI,AMD64_RBX); ! 1172: ! 1173: ppc32_store_cr(b,AMD64_RSI); ! 1174: return(0); ! 1175: } ! 1176: ! 1177: /* CROR - Condition Register OR */ ! 1178: DECLARE_INSN(CROR) ! 1179: { ! 1180: int bd = bits(insn,21,25); ! 1181: int bb = bits(insn,16,20); ! 1182: int ba = bits(insn,11,15); ! 1183: ! 1184: ppc32_load_cr(b,AMD64_RSI); ! 1185: ! 1186: /* test $ba bit */ ! 1187: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - ba)),4); ! 1188: amd64_set_reg(b->jit_ptr,X86_CC_NZ,AMD64_RAX,FALSE); ! 1189: ! 1190: /* test $bb bit */ ! 1191: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - bb)),4); ! 1192: amd64_set_reg(b->jit_ptr,X86_CC_NZ,AMD64_RBX,FALSE); ! 1193: ! 1194: /* result of NOR between $ba and $bb */ ! 1195: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RBX,AMD64_RAX); ! 1196: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RBX,0x01); ! 1197: ! 1198: /* set/clear $bd bit depending on the result */ ! 1199: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RSI,~(1 << (31 - bd))); ! 1200: amd64_shift_reg_imm(b->jit_ptr,X86_SHL,AMD64_RBX,(31 - bd)); ! 1201: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RSI,AMD64_RBX); ! 1202: ! 1203: ppc32_store_cr(b,AMD64_RSI); ! 1204: return(0); ! 1205: } ! 1206: ! 1207: /* CRORC - Condition Register OR with Complement */ ! 1208: DECLARE_INSN(CRORC) ! 1209: { ! 1210: int bd = bits(insn,21,25); ! 1211: int bb = bits(insn,16,20); ! 1212: int ba = bits(insn,11,15); ! 1213: ! 1214: ppc32_load_cr(b,AMD64_RSI); ! 1215: ! 1216: /* test $ba bit */ ! 1217: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - ba)),4); ! 1218: amd64_set_reg(b->jit_ptr,X86_CC_NZ,AMD64_RAX,FALSE); ! 1219: ! 1220: /* test $bb bit */ ! 1221: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - bb)),4); ! 1222: amd64_set_reg(b->jit_ptr,X86_CC_Z,AMD64_RBX,FALSE); ! 1223: ! 1224: /* result of ORC between $ba and $bb */ ! 1225: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RBX,AMD64_RAX); ! 1226: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RBX,0x01); ! 1227: ! 1228: /* set/clear $bd bit depending on the result */ ! 1229: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RSI,~(1 << (31 - bd))); ! 1230: amd64_shift_reg_imm(b->jit_ptr,X86_SHL,AMD64_RBX,(31 - bd)); ! 1231: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RSI,AMD64_RBX); ! 1232: ! 1233: ppc32_store_cr(b,AMD64_RSI); ! 1234: return(0); ! 1235: } ! 1236: ! 1237: /* CRXOR - Condition Register XOR */ ! 1238: DECLARE_INSN(CRXOR) ! 1239: { ! 1240: int bd = bits(insn,21,25); ! 1241: int bb = bits(insn,16,20); ! 1242: int ba = bits(insn,11,15); ! 1243: ! 1244: ppc32_load_cr(b,AMD64_RSI); ! 1245: ! 1246: /* test $ba bit */ ! 1247: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - ba)),4); ! 1248: amd64_set_reg(b->jit_ptr,X86_CC_NZ,AMD64_RAX,FALSE); ! 1249: ! 1250: /* test $bb bit */ ! 1251: amd64_test_reg_imm_size(b->jit_ptr,AMD64_RSI,(1 << (31 - bb)),4); ! 1252: amd64_set_reg(b->jit_ptr,X86_CC_NZ,AMD64_RBX,FALSE); ! 1253: ! 1254: /* result of XOR between $ba and $bb */ ! 1255: amd64_alu_reg_reg(b->jit_ptr,X86_XOR,AMD64_RBX,AMD64_RAX); ! 1256: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RBX,0x01); ! 1257: ! 1258: /* set/clear $bd bit depending on the result */ ! 1259: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RSI,~(1 << (31 - bd))); ! 1260: amd64_shift_reg_imm(b->jit_ptr,X86_SHL,AMD64_RBX,(31 - bd)); ! 1261: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RSI,AMD64_RBX); ! 1262: ! 1263: ppc32_store_cr(b,AMD64_RSI); ! 1264: return(0); ! 1265: } ! 1266: ! 1267: /* DIVWU - Divide Word Unsigned */ ! 1268: DECLARE_INSN(DIVWU) ! 1269: { ! 1270: int rd = bits(insn,21,25); ! 1271: int ra = bits(insn,16,20); ! 1272: int rb = bits(insn,11,15); ! 1273: ! 1274: ppc32_load_gpr(b,AMD64_RAX,ra); ! 1275: ppc32_load_gpr(b,AMD64_RBX,rb); ! 1276: ppc32_load_imm(b,AMD64_RDX,0); ! 1277: ! 1278: amd64_div_reg_size(b->jit_ptr,AMD64_RBX,0,4); ! 1279: ppc32_store_gpr(b,rd,AMD64_RAX); ! 1280: ! 1281: if (insn & 1) { ! 1282: amd64_test_reg_reg(b->jit_ptr,AMD64_RAX,AMD64_RAX); ! 1283: ppc32_update_cr0(b); ! 1284: } ! 1285: ! 1286: return(0); ! 1287: } ! 1288: ! 1289: /* EQV */ ! 1290: DECLARE_INSN(EQV) ! 1291: { ! 1292: int rs = bits(insn,21,25); ! 1293: int ra = bits(insn,16,20); ! 1294: int rb = bits(insn,11,15); ! 1295: ! 1296: /* $ra = ~($rs ^ $rb) */ ! 1297: ppc32_load_gpr(b,AMD64_RBX,rs); ! 1298: ppc32_alu_gpr(b,X86_XOR,AMD64_RBX,rb); ! 1299: amd64_not_reg(b->jit_ptr,AMD64_RBX); ! 1300: ppc32_store_gpr(b,ra,AMD64_RBX); ! 1301: ! 1302: if (insn & 1) { ! 1303: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RBX,AMD64_RBX,4); ! 1304: ppc32_update_cr0(b); ! 1305: } ! 1306: ! 1307: return(0); ! 1308: } ! 1309: ! 1310: /* EXTSB - Extend Sign Byte */ ! 1311: DECLARE_INSN(EXTSB) ! 1312: { ! 1313: int rs = bits(insn,21,25); ! 1314: int ra = bits(insn,16,20); ! 1315: ! 1316: ppc32_load_gpr(b,AMD64_RBX,rs); ! 1317: amd64_shift_reg_imm_size(b->jit_ptr,X86_SHL,AMD64_RBX,24,4); ! 1318: amd64_shift_reg_imm_size(b->jit_ptr,X86_SAR,AMD64_RBX,24,4); ! 1319: ppc32_store_gpr(b,ra,AMD64_RBX); ! 1320: ! 1321: if (insn & 1) { ! 1322: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RBX,AMD64_RBX,4); ! 1323: ppc32_update_cr0(b); ! 1324: } ! 1325: ! 1326: return(0); ! 1327: } ! 1328: ! 1329: /* EXTSH - Extend Sign Word */ ! 1330: DECLARE_INSN(EXTSH) ! 1331: { ! 1332: int rs = bits(insn,21,25); ! 1333: int ra = bits(insn,16,20); ! 1334: ! 1335: ppc32_load_gpr(b,AMD64_RBX,rs); ! 1336: amd64_shift_reg_imm_size(b->jit_ptr,X86_SHL,AMD64_RBX,16,4); ! 1337: amd64_shift_reg_imm_size(b->jit_ptr,X86_SAR,AMD64_RBX,16,4); ! 1338: ppc32_store_gpr(b,ra,AMD64_RBX); ! 1339: ! 1340: if (insn & 1) { ! 1341: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RBX,AMD64_RBX,4); ! 1342: ppc32_update_cr0(b); ! 1343: } ! 1344: ! 1345: return(0); ! 1346: } ! 1347: ! 1348: /* LBZ - Load Byte and Zero */ ! 1349: DECLARE_INSN(LBZ) ! 1350: { ! 1351: int rs = bits(insn,21,25); ! 1352: int ra = bits(insn,16,20); ! 1353: m_uint16_t offset = bits(insn,0,15); ! 1354: ! 1355: //ppc32_emit_memop(b,PPC_MEMOP_LBZ,ra,offset,rs,0); ! 1356: ppc32_emit_memop_fast(b,0,PPC_MEMOP_LBZ,ra,offset,rs,ppc32_memop_fast_lbz); ! 1357: return(0); ! 1358: } ! 1359: ! 1360: /* LBZU - Load Byte and Zero with Update */ ! 1361: DECLARE_INSN(LBZU) ! 1362: { ! 1363: int rs = bits(insn,21,25); ! 1364: int ra = bits(insn,16,20); ! 1365: m_uint16_t offset = bits(insn,0,15); ! 1366: ! 1367: ppc32_emit_memop(b,PPC_MEMOP_LBZ,ra,offset,rs,1); ! 1368: return(0); ! 1369: } ! 1370: ! 1371: /* LBZUX - Load Byte and Zero with Update Indexed */ ! 1372: DECLARE_INSN(LBZUX) ! 1373: { ! 1374: int rs = bits(insn,21,25); ! 1375: int ra = bits(insn,16,20); ! 1376: int rb = bits(insn,11,15); ! 1377: ! 1378: ppc32_emit_memop_idx(b,PPC_MEMOP_LBZ,ra,rb,rs,1); ! 1379: return(0); ! 1380: } ! 1381: ! 1382: /* LBZX - Load Byte and Zero Indexed */ ! 1383: DECLARE_INSN(LBZX) ! 1384: { ! 1385: int rs = bits(insn,21,25); ! 1386: int ra = bits(insn,16,20); ! 1387: int rb = bits(insn,11,15); ! 1388: ! 1389: ppc32_emit_memop_idx(b,PPC_MEMOP_LBZ,ra,rb,rs,0); ! 1390: return(0); ! 1391: } ! 1392: ! 1393: /* LHA - Load Half-Word Algebraic */ ! 1394: DECLARE_INSN(LHA) ! 1395: { ! 1396: int rs = bits(insn,21,25); ! 1397: int ra = bits(insn,16,20); ! 1398: m_uint16_t offset = bits(insn,0,15); ! 1399: ! 1400: ppc32_emit_memop(b,PPC_MEMOP_LHA,ra,offset,rs,0); ! 1401: return(0); ! 1402: } ! 1403: ! 1404: /* LHAU - Load Half-Word Algebraic with Update */ ! 1405: DECLARE_INSN(LHAU) ! 1406: { ! 1407: int rs = bits(insn,21,25); ! 1408: int ra = bits(insn,16,20); ! 1409: m_uint16_t offset = bits(insn,0,15); ! 1410: ! 1411: ppc32_emit_memop(b,PPC_MEMOP_LHA,ra,offset,rs,1); ! 1412: return(0); ! 1413: } ! 1414: ! 1415: /* LHAUX - Load Half-Word Algebraic with Update Indexed */ ! 1416: DECLARE_INSN(LHAUX) ! 1417: { ! 1418: int rs = bits(insn,21,25); ! 1419: int ra = bits(insn,16,20); ! 1420: int rb = bits(insn,11,15); ! 1421: ! 1422: ppc32_emit_memop_idx(b,PPC_MEMOP_LHA,ra,rb,rs,1); ! 1423: return(0); ! 1424: } ! 1425: ! 1426: /* LHAX - Load Half-Word Algebraic Indexed */ ! 1427: DECLARE_INSN(LHAX) ! 1428: { ! 1429: int rs = bits(insn,21,25); ! 1430: int ra = bits(insn,16,20); ! 1431: int rb = bits(insn,11,15); ! 1432: ! 1433: ppc32_emit_memop_idx(b,PPC_MEMOP_LHA,ra,rb,rs,0); ! 1434: return(0); ! 1435: } ! 1436: ! 1437: /* LHZ - Load Half-Word and Zero */ ! 1438: DECLARE_INSN(LHZ) ! 1439: { ! 1440: int rs = bits(insn,21,25); ! 1441: int ra = bits(insn,16,20); ! 1442: m_uint16_t offset = bits(insn,0,15); ! 1443: ! 1444: ppc32_emit_memop(b,PPC_MEMOP_LHZ,ra,offset,rs,0); ! 1445: return(0); ! 1446: } ! 1447: ! 1448: /* LHZU - Load Half-Word and Zero with Update */ ! 1449: DECLARE_INSN(LHZU) ! 1450: { ! 1451: int rs = bits(insn,21,25); ! 1452: int ra = bits(insn,16,20); ! 1453: m_uint16_t offset = bits(insn,0,15); ! 1454: ! 1455: ppc32_emit_memop(b,PPC_MEMOP_LHZ,ra,offset,rs,1); ! 1456: return(0); ! 1457: } ! 1458: ! 1459: /* LHZUX - Load Half-Word and Zero with Update Indexed */ ! 1460: DECLARE_INSN(LHZUX) ! 1461: { ! 1462: int rs = bits(insn,21,25); ! 1463: int ra = bits(insn,16,20); ! 1464: int rb = bits(insn,11,15); ! 1465: ! 1466: ppc32_emit_memop_idx(b,PPC_MEMOP_LHZ,ra,rb,rs,1); ! 1467: return(0); ! 1468: } ! 1469: ! 1470: /* LHZX - Load Half-Word and Zero Indexed */ ! 1471: DECLARE_INSN(LHZX) ! 1472: { ! 1473: int rs = bits(insn,21,25); ! 1474: int ra = bits(insn,16,20); ! 1475: int rb = bits(insn,11,15); ! 1476: ! 1477: ppc32_emit_memop_idx(b,PPC_MEMOP_LHZ,ra,rb,rs,0); ! 1478: return(0); ! 1479: } ! 1480: ! 1481: /* LWZ - Load Word and Zero */ ! 1482: DECLARE_INSN(LWZ) ! 1483: { ! 1484: int rs = bits(insn,21,25); ! 1485: int ra = bits(insn,16,20); ! 1486: m_uint16_t offset = bits(insn,0,15); ! 1487: ! 1488: //ppc32_emit_memop(b,PPC_MEMOP_LWZ,ra,offset,rs,0); ! 1489: ppc32_emit_memop_fast(b,0,PPC_MEMOP_LWZ,ra,offset,rs,ppc32_memop_fast_lwz); ! 1490: return(0); ! 1491: } ! 1492: ! 1493: /* LWZU - Load Word and Zero with Update */ ! 1494: DECLARE_INSN(LWZU) ! 1495: { ! 1496: int rs = bits(insn,21,25); ! 1497: int ra = bits(insn,16,20); ! 1498: m_uint16_t offset = bits(insn,0,15); ! 1499: ! 1500: ppc32_emit_memop(b,PPC_MEMOP_LWZ,ra,offset,rs,1); ! 1501: return(0); ! 1502: } ! 1503: ! 1504: /* LWZUX - Load Word and Zero with Update Indexed */ ! 1505: DECLARE_INSN(LWZUX) ! 1506: { ! 1507: int rs = bits(insn,21,25); ! 1508: int ra = bits(insn,16,20); ! 1509: int rb = bits(insn,11,15); ! 1510: ! 1511: ppc32_emit_memop_idx(b,PPC_MEMOP_LWZ,ra,rb,rs,1); ! 1512: return(0); ! 1513: } ! 1514: ! 1515: /* LWZX - Load Word and Zero Indexed */ ! 1516: DECLARE_INSN(LWZX) ! 1517: { ! 1518: int rs = bits(insn,21,25); ! 1519: int ra = bits(insn,16,20); ! 1520: int rb = bits(insn,11,15); ! 1521: ! 1522: ppc32_emit_memop_idx(b,PPC_MEMOP_LWZ,ra,rb,rs,0); ! 1523: return(0); ! 1524: } ! 1525: ! 1526: /* MCRF - Move Condition Register Field */ ! 1527: DECLARE_INSN(MCRF) ! 1528: { ! 1529: int rd = bits(insn,23,25); ! 1530: int rs = bits(insn,18,20); ! 1531: m_uint32_t dmask; ! 1532: ! 1533: /* %rax = %rbx = CR */ ! 1534: ppc32_load_cr(b,AMD64_RAX); ! 1535: amd64_mov_reg_reg(b->jit_ptr,X86_EBX,X86_EAX,8); ! 1536: ! 1537: amd64_shift_reg_imm(b->jit_ptr,X86_SHR,AMD64_RBX,(28 - (rs << 2))); ! 1538: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RBX,0x0F); ! 1539: amd64_shift_reg_imm(b->jit_ptr,X86_SHL,AMD64_RBX,(28 - (rd << 2))); ! 1540: ! 1541: /* clear the destination bits */ ! 1542: dmask = (0xF0000000 >> (rd << 2)); ! 1543: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RAX,~dmask); ! 1544: ! 1545: /* set the new field value */ ! 1546: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RAX,AMD64_RBX); ! 1547: ppc32_store_cr(b,AMD64_RAX); ! 1548: return(0); ! 1549: } ! 1550: ! 1551: /* MFCR - Move from Condition Register */ ! 1552: DECLARE_INSN(MFCR) ! 1553: { ! 1554: int rd = bits(insn,21,25); ! 1555: ! 1556: ppc32_load_cr(b,AMD64_RAX); ! 1557: ppc32_store_gpr(b,rd,AMD64_RAX); ! 1558: return(0); ! 1559: } ! 1560: ! 1561: /* MFMSR - Move from Machine State Register */ ! 1562: DECLARE_INSN(MFMSR) ! 1563: { ! 1564: int rd = bits(insn,21,25); ! 1565: ! 1566: amd64_mov_reg_membase(b->jit_ptr,AMD64_RAX, ! 1567: AMD64_R15,OFFSET(cpu_ppc_t,msr),4); ! 1568: ppc32_store_gpr(b,rd,AMD64_RAX); ! 1569: return(0); ! 1570: } ! 1571: ! 1572: /* MFSR - Move From Segment Register */ ! 1573: DECLARE_INSN(MFSR) ! 1574: { ! 1575: int rd = bits(insn,21,25); ! 1576: int sr = bits(insn,16,19); ! 1577: ! 1578: amd64_mov_reg_membase(b->jit_ptr,AMD64_RAX, ! 1579: AMD64_R15,(OFFSET(cpu_ppc_t,sr) + (sr << 2)),4); ! 1580: ppc32_store_gpr(b,rd,AMD64_RAX); ! 1581: return(0); ! 1582: } ! 1583: ! 1584: /* MTCRF - Move to Condition Register Fields */ ! 1585: DECLARE_INSN(MTCRF) ! 1586: { ! 1587: int rs = bits(insn,21,25); ! 1588: int crm = bits(insn,12,19); ! 1589: m_uint32_t mask = 0; ! 1590: int i; ! 1591: ! 1592: for(i=0;i<8;i++) ! 1593: if (crm & (1 << i)) ! 1594: mask |= 0xF << (i << 2); ! 1595: ! 1596: ppc32_load_cr(b,AMD64_RAX); ! 1597: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RAX,~mask); ! 1598: ! 1599: ppc32_load_gpr(b,AMD64_RDX,rs); ! 1600: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RDX,mask); ! 1601: ! 1602: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RDX,AMD64_RAX); ! 1603: ppc32_store_cr(b,AMD64_RDX); ! 1604: return(0); ! 1605: } ! 1606: ! 1607: /* MULHW - Multiply High Word */ ! 1608: DECLARE_INSN(MULHW) ! 1609: { ! 1610: int rd = bits(insn,21,25); ! 1611: int ra = bits(insn,16,20); ! 1612: int rb = bits(insn,11,15); ! 1613: ! 1614: ppc32_load_gpr(b,AMD64_RAX,ra); ! 1615: ppc32_load_gpr(b,AMD64_RBX,rb); ! 1616: amd64_mul_reg_size(b->jit_ptr,AMD64_RBX,1,4); ! 1617: ppc32_store_gpr(b,rd,AMD64_RDX); ! 1618: ! 1619: if (insn & 1) { ! 1620: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RDX,AMD64_RDX,4); ! 1621: ppc32_update_cr0(b); ! 1622: } ! 1623: ! 1624: return(0); ! 1625: } ! 1626: ! 1627: /* MULHWU - Multiply High Word Unsigned */ ! 1628: DECLARE_INSN(MULHWU) ! 1629: { ! 1630: int rd = bits(insn,21,25); ! 1631: int ra = bits(insn,16,20); ! 1632: int rb = bits(insn,11,15); ! 1633: ! 1634: ppc32_load_gpr(b,AMD64_RAX,ra); ! 1635: ppc32_load_gpr(b,AMD64_RBX,rb); ! 1636: amd64_mul_reg_size(b->jit_ptr,AMD64_RBX,0,4); ! 1637: ppc32_store_gpr(b,rd,AMD64_RDX); ! 1638: ! 1639: if (insn & 1) { ! 1640: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RDX,AMD64_RDX,4); ! 1641: ppc32_update_cr0(b); ! 1642: } ! 1643: ! 1644: return(0); ! 1645: } ! 1646: ! 1647: /* MULLI - Multiply Low Immediate */ ! 1648: DECLARE_INSN(MULLI) ! 1649: { ! 1650: int rd = bits(insn,21,25); ! 1651: int ra = bits(insn,16,20); ! 1652: m_uint32_t imm = bits(insn,0,15); ! 1653: ! 1654: ppc32_load_gpr(b,AMD64_RAX,ra); ! 1655: ppc32_load_imm(b,AMD64_RBX,sign_extend_32(imm,16)); ! 1656: ! 1657: amd64_mul_reg_size(b->jit_ptr,AMD64_RBX,1,4); ! 1658: ppc32_store_gpr(b,rd,X86_EAX); ! 1659: return(0); ! 1660: } ! 1661: ! 1662: /* MULLW - Multiply Low Word */ ! 1663: DECLARE_INSN(MULLW) ! 1664: { ! 1665: int rd = bits(insn,21,25); ! 1666: int ra = bits(insn,16,20); ! 1667: int rb = bits(insn,11,15); ! 1668: ! 1669: ppc32_load_gpr(b,AMD64_RAX,ra); ! 1670: ppc32_load_gpr(b,AMD64_RBX,rb); ! 1671: amd64_mul_reg_size(b->jit_ptr,AMD64_RBX,1,4); ! 1672: ppc32_store_gpr(b,rd,AMD64_RAX); ! 1673: ! 1674: if (insn & 1) { ! 1675: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RAX,AMD64_RAX,4); ! 1676: ppc32_update_cr0(b); ! 1677: } ! 1678: ! 1679: return(0); ! 1680: } ! 1681: ! 1682: /* NAND */ ! 1683: DECLARE_INSN(NAND) ! 1684: { ! 1685: int rs = bits(insn,21,25); ! 1686: int ra = bits(insn,16,20); ! 1687: int rb = bits(insn,11,15); ! 1688: ! 1689: /* $ra = ~($rs & $rb) */ ! 1690: ppc32_load_gpr(b,AMD64_RBX,rs); ! 1691: ppc32_alu_gpr(b,X86_AND,AMD64_RBX,rb); ! 1692: amd64_not_reg(b->jit_ptr,AMD64_RBX); ! 1693: ppc32_store_gpr(b,ra,AMD64_RBX); ! 1694: ! 1695: if (insn & 1) { ! 1696: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RBX,AMD64_RBX,4); ! 1697: ppc32_update_cr0(b); ! 1698: } ! 1699: ! 1700: return(0); ! 1701: } ! 1702: ! 1703: /* NEG */ ! 1704: DECLARE_INSN(NEG) ! 1705: { ! 1706: int rd = bits(insn,21,25); ! 1707: int ra = bits(insn,16,20); ! 1708: ! 1709: ppc32_load_gpr(b,AMD64_RBX,ra); ! 1710: amd64_neg_reg(b->jit_ptr,AMD64_RBX); ! 1711: ppc32_store_gpr(b,rd,AMD64_RBX); ! 1712: ! 1713: if (insn & 1) { ! 1714: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RBX,AMD64_RBX,4); ! 1715: ppc32_update_cr0(b); ! 1716: } ! 1717: ! 1718: return(0); ! 1719: } ! 1720: ! 1721: /* NOR */ ! 1722: DECLARE_INSN(NOR) ! 1723: { ! 1724: int rs = bits(insn,21,25); ! 1725: int ra = bits(insn,16,20); ! 1726: int rb = bits(insn,11,15); ! 1727: ! 1728: /* $ra = ~($rs | $rb) */ ! 1729: ppc32_load_gpr(b,AMD64_RBX,rs); ! 1730: ppc32_alu_gpr(b,X86_OR,AMD64_RBX,rb); ! 1731: amd64_not_reg(b->jit_ptr,AMD64_RBX); ! 1732: ppc32_store_gpr(b,ra,AMD64_RBX); ! 1733: ! 1734: if (insn & 1) { ! 1735: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RBX,AMD64_RBX,4); ! 1736: ppc32_update_cr0(b); ! 1737: } ! 1738: ! 1739: return(0); ! 1740: } ! 1741: ! 1742: /* OR */ ! 1743: DECLARE_INSN(OR) ! 1744: { ! 1745: int rs = bits(insn,21,25); ! 1746: int ra = bits(insn,16,20); ! 1747: int rb = bits(insn,11,15); ! 1748: ! 1749: ppc32_load_gpr(b,AMD64_RCX,rs); ! 1750: ! 1751: if (rs != rb) ! 1752: ppc32_alu_gpr(b,X86_OR,AMD64_RCX,rb); ! 1753: ! 1754: ppc32_store_gpr(b,ra,AMD64_RCX); ! 1755: ! 1756: if (insn & 1) { ! 1757: if (rs == rb) ! 1758: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RCX,AMD64_RCX,4); ! 1759: ppc32_update_cr0(b); ! 1760: } ! 1761: ! 1762: return(0); ! 1763: } ! 1764: ! 1765: /* OR with Complement */ ! 1766: DECLARE_INSN(ORC) ! 1767: { ! 1768: int rs = bits(insn,21,25); ! 1769: int ra = bits(insn,16,20); ! 1770: int rb = bits(insn,11,15); ! 1771: ! 1772: /* $ra = $rs | ~$rb */ ! 1773: ppc32_load_gpr(b,AMD64_RBX,rb); ! 1774: amd64_not_reg(b->jit_ptr,AMD64_RBX); ! 1775: ppc32_alu_gpr(b,X86_OR,AMD64_RBX,rs); ! 1776: ppc32_store_gpr(b,ra,AMD64_RBX); ! 1777: ! 1778: if (insn & 1) ! 1779: ppc32_update_cr0(b); ! 1780: ! 1781: return(0); ! 1782: } ! 1783: ! 1784: /* OR Immediate */ ! 1785: DECLARE_INSN(ORI) ! 1786: { ! 1787: int rs = bits(insn,21,25); ! 1788: int ra = bits(insn,16,20); ! 1789: m_uint16_t imm = bits(insn,0,15); ! 1790: ! 1791: /* $ra = $rs | imm */ ! 1792: ppc32_load_imm(b,AMD64_RBX,imm); ! 1793: ppc32_alu_gpr(b,X86_OR,AMD64_RBX,rs); ! 1794: ppc32_store_gpr(b,ra,AMD64_RBX); ! 1795: return(0); ! 1796: } ! 1797: ! 1798: /* OR Immediate Shifted */ ! 1799: DECLARE_INSN(ORIS) ! 1800: { ! 1801: int rs = bits(insn,21,25); ! 1802: int ra = bits(insn,16,20); ! 1803: m_uint32_t imm = bits(insn,0,15); ! 1804: ! 1805: /* $ra = $rs | (imm << 16) */ ! 1806: ppc32_load_imm(b,AMD64_RBX,imm << 16); ! 1807: ppc32_alu_gpr(b,X86_OR,AMD64_RBX,rs); ! 1808: ppc32_store_gpr(b,ra,AMD64_RBX); ! 1809: return(0); ! 1810: } ! 1811: ! 1812: /* RLWIMI - Rotate Left Word Immediate then Mask Insert */ ! 1813: DECLARE_INSN(RLWIMI) ! 1814: { ! 1815: int rs = bits(insn,21,25); ! 1816: int ra = bits(insn,16,20); ! 1817: int sh = bits(insn,11,15); ! 1818: int mb = bits(insn,6,10); ! 1819: int me = bits(insn,1,5); ! 1820: register m_uint32_t mask; ! 1821: ! 1822: mask = ppc32_rotate_mask(mb,me); ! 1823: ! 1824: /* Apply inverse mask to %eax "ra" */ ! 1825: ppc32_load_gpr(b,AMD64_RAX,ra); ! 1826: if (mask != 0) ! 1827: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RAX,~mask); ! 1828: ! 1829: /* Rotate %ebx ("rs") of "sh" bits and apply the mask */ ! 1830: ppc32_load_gpr(b,AMD64_RBX,rs); ! 1831: ! 1832: if (sh != 0) ! 1833: amd64_shift_reg_imm_size(b->jit_ptr,X86_ROL,AMD64_RBX,sh,4); ! 1834: ! 1835: if (mask != 0xFFFFFFFF) ! 1836: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RBX,mask); ! 1837: ! 1838: /* Store the result */ ! 1839: amd64_alu_reg_reg_size(b->jit_ptr,X86_OR,AMD64_RBX,AMD64_RAX,4); ! 1840: ppc32_store_gpr(b,ra,AMD64_RBX); ! 1841: ! 1842: if (insn & 1) ! 1843: ppc32_update_cr0(b); ! 1844: ! 1845: return(0); ! 1846: } ! 1847: ! 1848: /* RLWINM - Rotate Left Word Immediate AND with Mask */ ! 1849: DECLARE_INSN(RLWINM) ! 1850: { ! 1851: int rs = bits(insn,21,25); ! 1852: int ra = bits(insn,16,20); ! 1853: int sh = bits(insn,11,15); ! 1854: int mb = bits(insn,6,10); ! 1855: int me = bits(insn,1,5); ! 1856: register m_uint32_t mask; ! 1857: ! 1858: mask = ppc32_rotate_mask(mb,me); ! 1859: ! 1860: /* Rotate %ebx ("rs") of "sh" bits and apply the mask */ ! 1861: ppc32_load_gpr(b,AMD64_RBX,rs); ! 1862: ! 1863: if (sh != 0) ! 1864: amd64_shift_reg_imm_size(b->jit_ptr,X86_ROL,AMD64_RBX,sh,4); ! 1865: ! 1866: if (mask != 0xFFFFFFFF) ! 1867: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RBX,mask); ! 1868: ! 1869: ppc32_store_gpr(b,ra,AMD64_RBX); ! 1870: ! 1871: if (insn & 1) { ! 1872: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RBX,AMD64_RBX,4); ! 1873: ppc32_update_cr0(b); ! 1874: } ! 1875: ! 1876: return(0); ! 1877: } ! 1878: ! 1879: /* RLWNM - Rotate Left Word then Mask Insert */ ! 1880: DECLARE_INSN(RLWNM) ! 1881: { ! 1882: int rs = bits(insn,21,25); ! 1883: int ra = bits(insn,16,20); ! 1884: int rb = bits(insn,11,15); ! 1885: int mb = bits(insn,6,10); ! 1886: int me = bits(insn,1,5); ! 1887: register m_uint32_t mask; ! 1888: ! 1889: mask = ppc32_rotate_mask(mb,me); ! 1890: ! 1891: /* Load the shift register ("sh") */ ! 1892: ppc32_load_gpr(b,AMD64_RCX,rb); ! 1893: ! 1894: /* Rotate %ebx ("rs") and apply the mask */ ! 1895: ppc32_load_gpr(b,AMD64_RBX,rs); ! 1896: amd64_shift_reg_size(b->jit_ptr,X86_ROL,AMD64_RBX,4); ! 1897: ! 1898: if (mask != 0xFFFFFFFF) ! 1899: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RBX,mask); ! 1900: ! 1901: ppc32_store_gpr(b,ra,AMD64_RBX); ! 1902: ! 1903: if (insn & 1) { ! 1904: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RBX,AMD64_RBX,4); ! 1905: ppc32_update_cr0(b); ! 1906: } ! 1907: ! 1908: return(0); ! 1909: } ! 1910: ! 1911: /* Shift Left Word */ ! 1912: DECLARE_INSN(SLW) ! 1913: { ! 1914: int rs = bits(insn,21,25); ! 1915: int ra = bits(insn,16,20); ! 1916: int rb = bits(insn,11,15); ! 1917: ! 1918: /* If count >= 32, then null result */ ! 1919: ppc32_load_gpr(b,AMD64_RCX,rb); ! 1920: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RCX,0x3f); ! 1921: ! 1922: ppc32_load_gpr(b,AMD64_RBX,rs); ! 1923: amd64_shift_reg(b->jit_ptr,X86_SHL,AMD64_RBX); ! 1924: ! 1925: /* Store the result */ ! 1926: ppc32_store_gpr(b,ra,AMD64_RBX); ! 1927: ! 1928: if (insn & 1) { ! 1929: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RBX,AMD64_RBX,4); ! 1930: ppc32_update_cr0(b); ! 1931: } ! 1932: ! 1933: return(0); ! 1934: } ! 1935: ! 1936: /* SRAWI - Shift Right Algebraic Word Immediate */ ! 1937: DECLARE_INSN(SRAWI) ! 1938: { ! 1939: int rs = bits(insn,21,25); ! 1940: int ra = bits(insn,16,20); ! 1941: int sh = bits(insn,11,15); ! 1942: register m_uint32_t mask; ! 1943: ! 1944: mask = ~(0xFFFFFFFFU << sh); ! 1945: ! 1946: /* $ra = (int32)$rs >> sh */ ! 1947: ppc32_load_gpr(b,AMD64_RBX,rs); ! 1948: amd64_mov_reg_reg(b->jit_ptr,AMD64_RSI,AMD64_RBX,4); ! 1949: amd64_shift_reg_imm_size(b->jit_ptr,X86_SAR,AMD64_RBX,sh,4); ! 1950: ppc32_store_gpr(b,ra,AMD64_RBX); ! 1951: ! 1952: /* test the sign-bit of gpr[rs] */ ! 1953: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RSI,AMD64_RSI,4); ! 1954: amd64_set_reg(b->jit_ptr,X86_CC_LT,AMD64_RAX,TRUE); ! 1955: ! 1956: amd64_alu_reg_imm_size(b->jit_ptr,X86_AND,AMD64_RSI,mask,4); ! 1957: amd64_set_reg(b->jit_ptr,X86_CC_NZ,AMD64_RCX,TRUE); ! 1958: ! 1959: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RCX,AMD64_RAX); ! 1960: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RCX,0x1); ! 1961: amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,xer_ca), ! 1962: AMD64_RCX,4); ! 1963: ! 1964: if (insn & 1) { ! 1965: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RBX,AMD64_RBX,4); ! 1966: ppc32_update_cr0(b); ! 1967: } ! 1968: ! 1969: return(0); ! 1970: } ! 1971: ! 1972: /* Shift Right Word */ ! 1973: DECLARE_INSN(SRW) ! 1974: { ! 1975: int rs = bits(insn,21,25); ! 1976: int ra = bits(insn,16,20); ! 1977: int rb = bits(insn,11,15); ! 1978: ! 1979: /* If count >= 32, then null result */ ! 1980: ppc32_load_gpr(b,AMD64_RCX,rb); ! 1981: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RCX,0x3f); ! 1982: ! 1983: ppc32_load_gpr(b,AMD64_RBX,rs); ! 1984: amd64_shift_reg(b->jit_ptr,X86_SHR,AMD64_RBX); ! 1985: ! 1986: /* Store the result */ ! 1987: ppc32_store_gpr(b,ra,AMD64_RBX); ! 1988: ! 1989: if (insn & 1) { ! 1990: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RBX,AMD64_RBX,4); ! 1991: ppc32_update_cr0(b); ! 1992: } ! 1993: ! 1994: return(0); ! 1995: } ! 1996: ! 1997: /* STB - Store Byte */ ! 1998: DECLARE_INSN(STB) ! 1999: { ! 2000: int rs = bits(insn,21,25); ! 2001: int ra = bits(insn,16,20); ! 2002: m_uint16_t offset = bits(insn,0,15); ! 2003: ! 2004: //ppc32_emit_memop(b,PPC_MEMOP_STB,ra,offset,rs,0); ! 2005: ppc32_emit_memop_fast(b,1,PPC_MEMOP_STB,ra,offset,rs,ppc32_memop_fast_stb); ! 2006: return(0); ! 2007: } ! 2008: ! 2009: /* STBU - Store Byte with Update */ ! 2010: DECLARE_INSN(STBU) ! 2011: { ! 2012: int rs = bits(insn,21,25); ! 2013: int ra = bits(insn,16,20); ! 2014: m_uint16_t offset = bits(insn,0,15); ! 2015: ! 2016: ppc32_emit_memop(b,PPC_MEMOP_STB,ra,offset,rs,1); ! 2017: return(0); ! 2018: } ! 2019: ! 2020: /* STBUX - Store Byte with Update Indexed */ ! 2021: DECLARE_INSN(STBUX) ! 2022: { ! 2023: int rs = bits(insn,21,25); ! 2024: int ra = bits(insn,16,20); ! 2025: int rb = bits(insn,11,15); ! 2026: ! 2027: ppc32_emit_memop_idx(b,PPC_MEMOP_STB,ra,rb,rs,1); ! 2028: return(0); ! 2029: } ! 2030: ! 2031: /* STBUX - Store Byte Indexed */ ! 2032: DECLARE_INSN(STBX) ! 2033: { ! 2034: int rs = bits(insn,21,25); ! 2035: int ra = bits(insn,16,20); ! 2036: int rb = bits(insn,11,15); ! 2037: ! 2038: ppc32_emit_memop_idx(b,PPC_MEMOP_STB,ra,rb,rs,0); ! 2039: return(0); ! 2040: } ! 2041: ! 2042: /* STH - Store Half-Word */ ! 2043: DECLARE_INSN(STH) ! 2044: { ! 2045: int rs = bits(insn,21,25); ! 2046: int ra = bits(insn,16,20); ! 2047: m_uint16_t offset = bits(insn,0,15); ! 2048: ! 2049: ppc32_emit_memop(b,PPC_MEMOP_STH,ra,offset,rs,0); ! 2050: return(0); ! 2051: } ! 2052: ! 2053: /* STHU - Store Half-Word with Update */ ! 2054: DECLARE_INSN(STHU) ! 2055: { ! 2056: int rs = bits(insn,21,25); ! 2057: int ra = bits(insn,16,20); ! 2058: m_uint16_t offset = bits(insn,0,15); ! 2059: ! 2060: ppc32_emit_memop(b,PPC_MEMOP_STH,ra,offset,rs,1); ! 2061: return(0); ! 2062: } ! 2063: ! 2064: /* STHUX - Store Half-Word with Update Indexed */ ! 2065: DECLARE_INSN(STHUX) ! 2066: { ! 2067: int rs = bits(insn,21,25); ! 2068: int ra = bits(insn,16,20); ! 2069: int rb = bits(insn,11,15); ! 2070: ! 2071: ppc32_emit_memop_idx(b,PPC_MEMOP_STH,ra,rb,rs,1); ! 2072: return(0); ! 2073: } ! 2074: ! 2075: /* STHUX - Store Half-Word Indexed */ ! 2076: DECLARE_INSN(STHX) ! 2077: { ! 2078: int rs = bits(insn,21,25); ! 2079: int ra = bits(insn,16,20); ! 2080: int rb = bits(insn,11,15); ! 2081: ! 2082: ppc32_emit_memop_idx(b,PPC_MEMOP_STH,ra,rb,rs,0); ! 2083: return(0); ! 2084: } ! 2085: ! 2086: /* STW - Store Word */ ! 2087: DECLARE_INSN(STW) ! 2088: { ! 2089: int rs = bits(insn,21,25); ! 2090: int ra = bits(insn,16,20); ! 2091: m_uint16_t offset = bits(insn,0,15); ! 2092: ! 2093: //ppc32_emit_memop(b,PPC_MEMOP_STW,ra,offset,rs,0); ! 2094: ppc32_emit_memop_fast(b,1,PPC_MEMOP_STW,ra,offset,rs,ppc32_memop_fast_stw); ! 2095: return(0); ! 2096: } ! 2097: ! 2098: /* STWU - Store Word with Update */ ! 2099: DECLARE_INSN(STWU) ! 2100: { ! 2101: int rs = bits(insn,21,25); ! 2102: int ra = bits(insn,16,20); ! 2103: m_uint16_t offset = bits(insn,0,15); ! 2104: ! 2105: ppc32_emit_memop(b,PPC_MEMOP_STW,ra,offset,rs,1); ! 2106: return(0); ! 2107: } ! 2108: ! 2109: /* STWUX - Store Word with Update Indexed */ ! 2110: DECLARE_INSN(STWUX) ! 2111: { ! 2112: int rs = bits(insn,21,25); ! 2113: int ra = bits(insn,16,20); ! 2114: int rb = bits(insn,11,15); ! 2115: ! 2116: ppc32_emit_memop_idx(b,PPC_MEMOP_STW,ra,rb,rs,1); ! 2117: return(0); ! 2118: } ! 2119: ! 2120: /* STWUX - Store Word Indexed */ ! 2121: DECLARE_INSN(STWX) ! 2122: { ! 2123: int rs = bits(insn,21,25); ! 2124: int ra = bits(insn,16,20); ! 2125: int rb = bits(insn,11,15); ! 2126: ! 2127: ppc32_emit_memop_idx(b,PPC_MEMOP_STW,ra,rb,rs,0); ! 2128: return(0); ! 2129: } ! 2130: ! 2131: /* SUBF - Subtract From */ ! 2132: DECLARE_INSN(SUBF) ! 2133: { ! 2134: int rd = bits(insn,21,25); ! 2135: int ra = bits(insn,16,20); ! 2136: int rb = bits(insn,11,15); ! 2137: ! 2138: /* $rd = $rb - $rb */ ! 2139: ppc32_load_gpr(b,AMD64_RBX,rb); ! 2140: ppc32_alu_gpr(b,X86_SUB,AMD64_RBX,ra); ! 2141: ppc32_store_gpr(b,rd,AMD64_RBX); ! 2142: ! 2143: if (insn & 1) ! 2144: ppc32_update_cr0(b); ! 2145: ! 2146: return(0); ! 2147: } ! 2148: ! 2149: /* SUBFC - Subtract From Carrying */ ! 2150: DECLARE_INSN(SUBFC) ! 2151: { ! 2152: int rd = bits(insn,21,25); ! 2153: int ra = bits(insn,16,20); ! 2154: int rb = bits(insn,11,15); ! 2155: ! 2156: /* ~$ra + 1 */ ! 2157: ppc32_load_gpr(b,AMD64_RSI,ra); ! 2158: amd64_not_reg(b->jit_ptr,AMD64_RSI); ! 2159: amd64_alu_reg_imm_size(b->jit_ptr,X86_ADD,AMD64_RSI,1,4); ! 2160: amd64_set_reg(b->jit_ptr,X86_CC_C,AMD64_RAX,FALSE); ! 2161: ! 2162: /* add $rb */ ! 2163: ppc32_alu_gpr(b,X86_ADD,AMD64_RSI,rb); ! 2164: amd64_set_reg(b->jit_ptr,X86_CC_C,AMD64_RCX,FALSE); ! 2165: ! 2166: ppc32_store_gpr(b,rd,AMD64_RSI); ! 2167: ! 2168: /* store the carry flag */ ! 2169: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RAX,AMD64_RCX); ! 2170: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RAX,0x1); ! 2171: ! 2172: amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,xer_ca), ! 2173: AMD64_RAX,4); ! 2174: ! 2175: /* update cr0 */ ! 2176: if (insn & 1) { ! 2177: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RSI,AMD64_RSI,4); ! 2178: ppc32_update_cr0(b); ! 2179: } ! 2180: ! 2181: return(0); ! 2182: } ! 2183: ! 2184: /* SUBFE - Subtract From Extended */ ! 2185: DECLARE_INSN(SUBFE) ! 2186: { ! 2187: int rd = bits(insn,21,25); ! 2188: int ra = bits(insn,16,20); ! 2189: int rb = bits(insn,11,15); ! 2190: ! 2191: /* ~$ra + carry */ ! 2192: ppc32_load_gpr(b,AMD64_RSI,ra); ! 2193: amd64_not_reg(b->jit_ptr,AMD64_RSI); ! 2194: amd64_alu_reg_membase_size(b->jit_ptr,X86_ADD,AMD64_RSI, ! 2195: AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),4); ! 2196: amd64_set_reg(b->jit_ptr,X86_CC_C,AMD64_RAX,FALSE); ! 2197: ! 2198: /* add $rb */ ! 2199: ppc32_alu_gpr(b,X86_ADD,AMD64_RSI,rb); ! 2200: amd64_set_reg(b->jit_ptr,X86_CC_C,AMD64_RCX,FALSE); ! 2201: ! 2202: ppc32_store_gpr(b,rd,AMD64_RSI); ! 2203: ! 2204: /* store the carry flag */ ! 2205: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RAX,AMD64_RCX); ! 2206: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RAX,0x1); ! 2207: amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,xer_ca), ! 2208: AMD64_RAX,4); ! 2209: ! 2210: /* update cr0 */ ! 2211: if (insn & 1) { ! 2212: amd64_test_reg_reg_size(b->jit_ptr,AMD64_RSI,AMD64_RSI,4); ! 2213: ppc32_update_cr0(b); ! 2214: } ! 2215: ! 2216: return(0); ! 2217: } ! 2218: ! 2219: /* SUBFIC - Subtract From Immediate Carrying */ ! 2220: DECLARE_INSN(SUBFIC) ! 2221: { ! 2222: int rd = bits(insn,21,25); ! 2223: int ra = bits(insn,16,20); ! 2224: m_uint16_t imm = bits(insn,0,15); ! 2225: m_uint32_t tmp = sign_extend_32(imm,16); ! 2226: ! 2227: /* ~$ra + 1 */ ! 2228: ppc32_load_gpr(b,AMD64_RSI,ra); ! 2229: amd64_not_reg(b->jit_ptr,AMD64_RSI); ! 2230: amd64_alu_reg_imm_size(b->jit_ptr,X86_ADD,AMD64_RSI,1,4); ! 2231: amd64_set_reg(b->jit_ptr,X86_CC_C,AMD64_RAX,FALSE); ! 2232: ! 2233: /* add sign-extended $immediate */ ! 2234: amd64_alu_reg_imm_size(b->jit_ptr,X86_ADD,AMD64_RSI,tmp,4); ! 2235: amd64_set_reg(b->jit_ptr,X86_CC_C,AMD64_RCX,FALSE); ! 2236: ! 2237: ppc32_store_gpr(b,rd,AMD64_RSI); ! 2238: ! 2239: /* store the carry flag */ ! 2240: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RAX,AMD64_RCX); ! 2241: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RAX,0x1); ! 2242: ! 2243: amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,OFFSET(cpu_ppc_t,xer_ca), ! 2244: AMD64_RAX,4); ! 2245: return(0); ! 2246: } ! 2247: ! 2248: /* SYNC - Synchronize */ ! 2249: DECLARE_INSN(SYNC) ! 2250: { ! 2251: return(0); ! 2252: } ! 2253: ! 2254: /* XOR */ ! 2255: DECLARE_INSN(XOR) ! 2256: { ! 2257: int rs = bits(insn,21,25); ! 2258: int ra = bits(insn,16,20); ! 2259: int rb = bits(insn,11,15); ! 2260: ! 2261: ppc32_load_gpr(b,AMD64_RBX,rs); ! 2262: ppc32_alu_gpr(b,X86_XOR,AMD64_RBX,rb); ! 2263: ppc32_store_gpr(b,ra,AMD64_RBX); ! 2264: ! 2265: if (insn & 1) ! 2266: ppc32_update_cr0(b); ! 2267: ! 2268: return(0); ! 2269: } ! 2270: ! 2271: /* XORI - XOR Immediate */ ! 2272: DECLARE_INSN(XORI) ! 2273: { ! 2274: int rs = bits(insn,21,25); ! 2275: int ra = bits(insn,16,20); ! 2276: m_uint32_t imm = bits(insn,0,15); ! 2277: ! 2278: ppc32_load_imm(b,AMD64_RBX,imm); ! 2279: ppc32_alu_gpr(b,X86_XOR,AMD64_RBX,rs); ! 2280: ppc32_store_gpr(b,ra,AMD64_RBX); ! 2281: return(0); ! 2282: } ! 2283: ! 2284: /* XORIS - XOR Immediate Shifted */ ! 2285: DECLARE_INSN(XORIS) ! 2286: { ! 2287: int rs = bits(insn,21,25); ! 2288: int ra = bits(insn,16,20); ! 2289: m_uint32_t imm = bits(insn,0,15); ! 2290: ! 2291: ppc32_load_imm(b,AMD64_RBX,imm << 16); ! 2292: ppc32_alu_gpr(b,X86_XOR,AMD64_RBX,rs); ! 2293: ppc32_store_gpr(b,ra,AMD64_RBX); ! 2294: return(0); ! 2295: } ! 2296: ! 2297: /* PPC instruction array */ ! 2298: struct ppc32_insn_tag ppc32_insn_tags[] = { ! 2299: { ppc32_emit_BLR , 0xfffffffe , 0x4e800020 }, ! 2300: { ppc32_emit_BCTR , 0xfffffffe , 0x4e800420 }, ! 2301: { ppc32_emit_MFLR , 0xfc1fffff , 0x7c0802a6 }, ! 2302: { ppc32_emit_MTLR , 0xfc1fffff , 0x7c0803a6 }, ! 2303: { ppc32_emit_MFCTR , 0xfc1fffff , 0x7c0902a6 }, ! 2304: { ppc32_emit_MTCTR , 0xfc1fffff , 0x7c0903a6 }, ! 2305: { ppc32_emit_MFTBL , 0xfc1ff7ff , 0x7c0c42e6 }, ! 2306: { ppc32_emit_MFTBU , 0xfc1ff7ff , 0x7c0d42e6 }, ! 2307: { ppc32_emit_ADD , 0xfc0007fe , 0x7c000214 }, ! 2308: { ppc32_emit_ADDC , 0xfc0007fe , 0x7c000014 }, ! 2309: { ppc32_emit_ADDE , 0xfc0007fe , 0x7c000114 }, ! 2310: { ppc32_emit_ADDI , 0xfc000000 , 0x38000000 }, ! 2311: { ppc32_emit_ADDIC , 0xfc000000 , 0x30000000 }, ! 2312: { ppc32_emit_ADDIC_dot , 0xfc000000 , 0x34000000 }, ! 2313: { ppc32_emit_ADDIS , 0xfc000000 , 0x3c000000 }, ! 2314: { ppc32_emit_AND , 0xfc0007fe , 0x7c000038 }, ! 2315: { ppc32_emit_ANDC , 0xfc0007fe , 0x7c000078 }, ! 2316: { ppc32_emit_ANDI , 0xfc000000 , 0x70000000 }, ! 2317: { ppc32_emit_ANDIS , 0xfc000000 , 0x74000000 }, ! 2318: { ppc32_emit_B , 0xfc000003 , 0x48000000 }, ! 2319: { ppc32_emit_BA , 0xfc000003 , 0x48000002 }, ! 2320: { ppc32_emit_BL , 0xfc000003 , 0x48000001 }, ! 2321: { ppc32_emit_BLA , 0xfc000003 , 0x48000003 }, ! 2322: { ppc32_emit_BCC , 0xfe800000 , 0x40800000 }, ! 2323: { ppc32_emit_BC , 0xfc000000 , 0x40000000 }, ! 2324: { ppc32_emit_BCLR , 0xfc00fffe , 0x4c000020 }, ! 2325: { ppc32_emit_CMP , 0xfc6007ff , 0x7c000000 }, ! 2326: { ppc32_emit_CMPI , 0xfc600000 , 0x2c000000 }, ! 2327: { ppc32_emit_CMPL , 0xfc6007ff , 0x7c000040 }, ! 2328: { ppc32_emit_CMPLI , 0xfc600000 , 0x28000000 }, ! 2329: { ppc32_emit_CRAND , 0xfc0007ff , 0x4c000202 }, ! 2330: { ppc32_emit_CRANDC , 0xfc0007ff , 0x4c000102 }, ! 2331: { ppc32_emit_CREQV , 0xfc0007ff , 0x4c000242 }, ! 2332: { ppc32_emit_CRNAND , 0xfc0007ff , 0x4c0001c2 }, ! 2333: { ppc32_emit_CRNOR , 0xfc0007ff , 0x4c000042 }, ! 2334: { ppc32_emit_CROR , 0xfc0007ff , 0x4c000382 }, ! 2335: { ppc32_emit_CRORC , 0xfc0007ff , 0x4c000342 }, ! 2336: { ppc32_emit_CRXOR , 0xfc0007ff , 0x4c000182 }, ! 2337: { ppc32_emit_DIVWU , 0xfc0007fe , 0x7c000396 }, ! 2338: { ppc32_emit_EQV , 0xfc0007fe , 0x7c000238 }, ! 2339: { ppc32_emit_EXTSB , 0xfc00fffe , 0x7c000774 }, ! 2340: { ppc32_emit_EXTSH , 0xfc00fffe , 0x7c000734 }, ! 2341: { ppc32_emit_LBZ , 0xfc000000 , 0x88000000 }, ! 2342: { ppc32_emit_LBZU , 0xfc000000 , 0x8c000000 }, ! 2343: { ppc32_emit_LBZUX , 0xfc0007ff , 0x7c0000ee }, ! 2344: { ppc32_emit_LBZX , 0xfc0007ff , 0x7c0000ae }, ! 2345: { ppc32_emit_LHA , 0xfc000000 , 0xa8000000 }, ! 2346: { ppc32_emit_LHAU , 0xfc000000 , 0xac000000 }, ! 2347: { ppc32_emit_LHAUX , 0xfc0007ff , 0x7c0002ee }, ! 2348: { ppc32_emit_LHAX , 0xfc0007ff , 0x7c0002ae }, ! 2349: { ppc32_emit_LHZ , 0xfc000000 , 0xa0000000 }, ! 2350: { ppc32_emit_LHZU , 0xfc000000 , 0xa4000000 }, ! 2351: { ppc32_emit_LHZUX , 0xfc0007ff , 0x7c00026e }, ! 2352: { ppc32_emit_LHZX , 0xfc0007ff , 0x7c00022e }, ! 2353: { ppc32_emit_LWZ , 0xfc000000 , 0x80000000 }, ! 2354: { ppc32_emit_LWZU , 0xfc000000 , 0x84000000 }, ! 2355: { ppc32_emit_LWZUX , 0xfc0007ff , 0x7c00006e }, ! 2356: { ppc32_emit_LWZX , 0xfc0007ff , 0x7c00002e }, ! 2357: { ppc32_emit_MCRF , 0xfc63ffff , 0x4c000000 }, ! 2358: { ppc32_emit_MFCR , 0xfc1fffff , 0x7c000026 }, ! 2359: { ppc32_emit_MFMSR , 0xfc1fffff , 0x7c0000a6 }, ! 2360: { ppc32_emit_MFSR , 0xfc10ffff , 0x7c0004a6 }, ! 2361: { ppc32_emit_MTCRF , 0xfc100fff , 0x7c000120 }, ! 2362: { ppc32_emit_MULHW , 0xfc0007fe , 0x7c000096 }, ! 2363: { ppc32_emit_MULHWU , 0xfc0007fe , 0x7c000016 }, ! 2364: { ppc32_emit_MULLI , 0xfc000000 , 0x1c000000 }, ! 2365: { ppc32_emit_MULLW , 0xfc0007fe , 0x7c0001d6 }, ! 2366: { ppc32_emit_NAND , 0xfc0007fe , 0x7c0003b8 }, ! 2367: { ppc32_emit_NEG , 0xfc00fffe , 0x7c0000d0 }, ! 2368: { ppc32_emit_NOR , 0xfc0007fe , 0x7c0000f8 }, ! 2369: { ppc32_emit_OR , 0xfc0007fe , 0x7c000378 }, ! 2370: { ppc32_emit_ORC , 0xfc0007fe , 0x7c000338 }, ! 2371: { ppc32_emit_ORI , 0xfc000000 , 0x60000000 }, ! 2372: { ppc32_emit_ORIS , 0xfc000000 , 0x64000000 }, ! 2373: { ppc32_emit_RLWIMI , 0xfc000000 , 0x50000000 }, ! 2374: { ppc32_emit_RLWINM , 0xfc000000 , 0x54000000 }, ! 2375: { ppc32_emit_RLWNM , 0xfc000000 , 0x5c000000 }, ! 2376: { ppc32_emit_SLW , 0xfc0007fe , 0x7c000030 }, ! 2377: { ppc32_emit_SRAWI , 0xfc0007fe , 0x7c000670 }, ! 2378: { ppc32_emit_SRW , 0xfc0007fe , 0x7c000430 }, ! 2379: { ppc32_emit_STB , 0xfc000000 , 0x98000000 }, ! 2380: { ppc32_emit_STBU , 0xfc000000 , 0x9c000000 }, ! 2381: { ppc32_emit_STBUX , 0xfc0007ff , 0x7c0001ee }, ! 2382: { ppc32_emit_STBX , 0xfc0007ff , 0x7c0001ae }, ! 2383: { ppc32_emit_STH , 0xfc000000 , 0xb0000000 }, ! 2384: { ppc32_emit_STHU , 0xfc000000 , 0xb4000000 }, ! 2385: { ppc32_emit_STHUX , 0xfc0007ff , 0x7c00036e }, ! 2386: { ppc32_emit_STHX , 0xfc0007ff , 0x7c00032e }, ! 2387: { ppc32_emit_STW , 0xfc000000 , 0x90000000 }, ! 2388: { ppc32_emit_STWU , 0xfc000000 , 0x94000000 }, ! 2389: { ppc32_emit_STWUX , 0xfc0007ff , 0x7c00016e }, ! 2390: { ppc32_emit_STWX , 0xfc0007ff , 0x7c00012e }, ! 2391: { ppc32_emit_SUBF , 0xfc0007fe , 0x7c000050 }, ! 2392: { ppc32_emit_SUBFC , 0xfc0007fe , 0x7c000010 }, ! 2393: { ppc32_emit_SUBFE , 0xfc0007fe , 0x7c000110 }, ! 2394: { ppc32_emit_SUBFIC , 0xfc000000 , 0x20000000 }, ! 2395: { ppc32_emit_SYNC , 0xffffffff , 0x7c0004ac }, ! 2396: { ppc32_emit_XOR , 0xfc0007fe , 0x7c000278 }, ! 2397: { ppc32_emit_XORI , 0xfc000000 , 0x68000000 }, ! 2398: { ppc32_emit_XORIS , 0xfc000000 , 0x6c000000 }, ! 2399: { ppc32_emit_unknown , 0x00000000 , 0x00000000 }, ! 2400: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.