📄 ppc32_amd64_trans.c
字号:
amd64_mov_reg_reg(iop->ob_ptr,AMD64_R14,AMD64_RSI,4); /* RDX = target register */ amd64_mov_reg_imm(iop->ob_ptr,AMD64_RDX,target); /* RDI = CPU instance pointer */ amd64_mov_reg_reg(iop->ob_ptr,AMD64_RDI,AMD64_R15,8); /* Call memory function */ amd64_call_membase(iop->ob_ptr,AMD64_R15,MEMOP_OFFSET(op)); if (update) ppc32_store_gpr(&iop->ob_ptr,ra,AMD64_R14);}typedef void (*memop_fast_access)(jit_op_t *iop,int target);/* Fast LBZ */static void ppc32_memop_fast_lbz(jit_op_t *iop,int target){ amd64_clear_reg(iop->ob_ptr,AMD64_RCX); amd64_mov_reg_memindex(iop->ob_ptr,AMD64_RCX,AMD64_RBX,0,AMD64_RSI,0,1); ppc32_store_gpr(&iop->ob_ptr,target,AMD64_RCX);}/* Fast STB */static void ppc32_memop_fast_stb(jit_op_t *iop,int target){ ppc32_load_gpr(&iop->ob_ptr,AMD64_RDX,target); amd64_mov_memindex_reg(iop->ob_ptr,AMD64_RBX,0,AMD64_RSI,0,AMD64_RDX,1);}/* Fast LWZ */static void ppc32_memop_fast_lwz(jit_op_t *iop,int target){ amd64_mov_reg_memindex(iop->ob_ptr,AMD64_RAX,AMD64_RBX,0,AMD64_RSI,0,4); amd64_bswap32(iop->ob_ptr,AMD64_RAX); ppc32_store_gpr(&iop->ob_ptr,target,AMD64_RAX);}/* Fast STW */static void ppc32_memop_fast_stw(jit_op_t *iop,int target){ ppc32_load_gpr(&iop->ob_ptr,AMD64_RDX,target); amd64_bswap32(iop->ob_ptr,AMD64_RDX); amd64_mov_memindex_reg(iop->ob_ptr,AMD64_RBX,0,AMD64_RSI,0,AMD64_RDX,4);}/* Fast memory operation */static void ppc32_emit_memop_fast(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, int write_op,int opcode, int base,int offset,int target, memop_fast_access op_handler){ m_uint32_t val = sign_extend(offset,16); u_char *test1,*test2,*p_exit; jit_op_t *iop; /* * Since an exception can be triggered, clear JIT state. This allows * to use branch target tag (we can directly branch on this instruction). */ ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_TARGET); ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB); iop = ppc32_op_emit_insn_output(cpu,5,"memop_fast"); test2 = NULL; /* RSI = GPR[base] + sign-extended offset */ ppc32_load_imm(&iop->ob_ptr,AMD64_RSI,val); if (base != 0) ppc32_alu_gpr(&iop->ob_ptr,X86_ADD,AMD64_RSI,base); /* RBX = mts32_entry index */ amd64_mov_reg_reg_size(iop->ob_ptr,X86_EBX,X86_ESI,4); amd64_shift_reg_imm_size(iop->ob_ptr,X86_SHR,X86_EBX,MTS32_HASH_SHIFT,4); amd64_alu_reg_imm_size(iop->ob_ptr,X86_AND,X86_EBX,MTS32_HASH_MASK,4); /* RCX = mts32 entry */ amd64_mov_reg_membase(iop->ob_ptr,AMD64_RCX, AMD64_R15, OFFSET(cpu_ppc_t,mts_cache[PPC32_MTS_DCACHE]),8); amd64_shift_reg_imm(iop->ob_ptr,X86_SHL,AMD64_RBX,5); /* TO FIX */ amd64_alu_reg_reg(iop->ob_ptr,X86_ADD,AMD64_RCX,AMD64_RBX); /* Compare virtual page address (EAX = vpage) */ amd64_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_ESI,4); amd64_alu_reg_imm(iop->ob_ptr,X86_AND,X86_EAX,PPC32_MIN_PAGE_MASK); amd64_alu_reg_membase_size(iop->ob_ptr,X86_CMP,X86_EAX,AMD64_RCX, OFFSET(mts32_entry_t,gvpa),4); test1 = iop->ob_ptr; amd64_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1); /* Test if we are writing to a COW page */ if (write_op) { amd64_test_membase_imm_size(iop->ob_ptr, AMD64_RCX,OFFSET(mts32_entry_t,flags), MTS_FLAG_COW|MTS_FLAG_EXEC,4); test2 = iop->ob_ptr; amd64_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1); } /* ESI = offset in page, RBX = Host Page Address */ amd64_alu_reg_imm(iop->ob_ptr,X86_AND,X86_ESI,PPC32_MIN_PAGE_IMASK); amd64_mov_reg_membase(iop->ob_ptr,AMD64_RBX, AMD64_RCX,OFFSET(mts32_entry_t,hpa),8); /* Memory access */ op_handler(iop,target); p_exit = iop->ob_ptr; amd64_jump8(iop->ob_ptr,0); /* === Slow lookup === */ amd64_patch(test1,iop->ob_ptr); if (test2) amd64_patch(test2,iop->ob_ptr); /* Save IA for exception handling */ ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2)); /* RDX = target register */ amd64_mov_reg_imm(iop->ob_ptr,AMD64_RDX,target); /* RDI = CPU instance */ amd64_mov_reg_reg(iop->ob_ptr,AMD64_RDI,AMD64_R15,8); /* Call memory access function */ amd64_call_membase(iop->ob_ptr,AMD64_R15,MEMOP_OFFSET(opcode)); amd64_patch(p_exit,iop->ob_ptr);}/* Emit unhandled instruction code */static int ppc32_emit_unknown(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, ppc_insn_t opcode){ u_char *test1; jit_op_t *iop; iop = ppc32_op_emit_insn_output(cpu,3,"unknown"); /* Update IA */ ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2)); /* Fallback to non-JIT mode */ amd64_mov_reg_reg(iop->ob_ptr,AMD64_RDI,AMD64_R15,8); amd64_mov_reg_imm(iop->ob_ptr,AMD64_RSI,opcode); ppc32_emit_c_call(b,iop,ppc32_exec_single_insn_ext); amd64_test_reg_reg_size(iop->ob_ptr,AMD64_RAX,AMD64_RAX,4); test1 = iop->ob_ptr; amd64_branch8(iop->ob_ptr, X86_CC_Z, 0, 1); ppc32_jit_tcb_push_epilog(&iop->ob_ptr); amd64_patch(test1,iop->ob_ptr); /* Signal this as an EOB to reset JIT state */ ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB); return(0);}/* Virtual Breakpoint */void ppc32_emit_breakpoint(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b){ jit_op_t *iop; iop = ppc32_op_emit_insn_output(cpu,2,"breakpoint"); amd64_mov_reg_reg(iop->ob_ptr,AMD64_RDI,AMD64_R15,8); ppc32_emit_c_call(b,iop,ppc32_run_breakpoint); /* Signal this as an EOB to to reset JIT state */ ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);}/* Increment the number of executed instructions (performance debugging) */void ppc32_inc_perf_counter(cpu_ppc_t *cpu){ jit_op_t *iop; iop = ppc32_op_emit_insn_output(cpu,1,"perf_cnt"); amd64_inc_membase_size(iop->ob_ptr, AMD64_R15,OFFSET(cpu_ppc_t,perf_counter),4);}/* ======================================================================== *//* BLR - Branch to Link Register */DECLARE_INSN(BLR){ jit_op_t *iop; int hreg; ppc32_jit_start_hreg_seq(cpu,"blr"); hreg = ppc32_jit_alloc_hreg(cpu,-1); ppc32_op_emit_alter_host_reg(cpu,hreg); iop = ppc32_op_emit_insn_output(cpu,2,"blr"); amd64_mov_reg_membase(iop->ob_ptr,hreg,AMD64_R15,OFFSET(cpu_ppc_t,lr),4); amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ia),hreg,4); /* set the return address */ if (insn & 1) ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2)); ppc32_jit_tcb_push_epilog(&iop->ob_ptr); ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB); ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2)); ppc32_jit_close_hreg_seq(cpu); return(0);}/* BCTR - Branch to Count Register */DECLARE_INSN(BCTR){ jit_op_t *iop; int hreg; ppc32_jit_start_hreg_seq(cpu,"bctr"); hreg = ppc32_jit_alloc_hreg(cpu,-1); ppc32_op_emit_alter_host_reg(cpu,hreg); iop = ppc32_op_emit_insn_output(cpu,2,"bctr"); amd64_mov_reg_membase(iop->ob_ptr,hreg,AMD64_R15,OFFSET(cpu_ppc_t,ctr),4); amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ia),hreg,4); /* set the return address */ if (insn & 1) ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2)); ppc32_jit_tcb_push_epilog(&iop->ob_ptr); ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB); ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2)); ppc32_jit_close_hreg_seq(cpu); return(0);}/* MFLR - Move From Link Register */DECLARE_INSN(MFLR){ int rd = bits(insn,21,25); int hreg_rd; jit_op_t *iop; ppc32_jit_start_hreg_seq(cpu,"mflr"); hreg_rd = ppc32_jit_alloc_hreg(cpu,rd); iop = ppc32_op_emit_insn_output(cpu,1,"mflr"); amd64_mov_reg_membase(iop->ob_ptr,hreg_rd,AMD64_R15,OFFSET(cpu_ppc_t,lr),4); ppc32_op_emit_store_gpr(cpu,rd,hreg_rd); ppc32_jit_close_hreg_seq(cpu); return(0);}/* MTLR - Move To Link Register */DECLARE_INSN(MTLR){ int rs = bits(insn,21,25); int hreg_rs; jit_op_t *iop; ppc32_jit_start_hreg_seq(cpu,"mtlr"); hreg_rs = ppc32_jit_alloc_hreg(cpu,rs); ppc32_op_emit_load_gpr(cpu,hreg_rs,rs); iop = ppc32_op_emit_insn_output(cpu,1,"mtlr"); amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,lr),hreg_rs,4); return(0);}/* MFCTR - Move From Counter Register */DECLARE_INSN(MFCTR){ int rd = bits(insn,21,25); int hreg_rd; jit_op_t *iop; ppc32_jit_start_hreg_seq(cpu,"mfctr"); hreg_rd = ppc32_jit_alloc_hreg(cpu,rd); iop = ppc32_op_emit_insn_output(cpu,1,"mfctr"); amd64_mov_reg_membase(iop->ob_ptr,hreg_rd, AMD64_R15,OFFSET(cpu_ppc_t,ctr),4); ppc32_op_emit_store_gpr(cpu,rd,hreg_rd); ppc32_jit_close_hreg_seq(cpu); return(0);}/* MTCTR - Move To Counter Register */DECLARE_INSN(MTCTR){ int rs = bits(insn,21,25); int hreg_rs; jit_op_t *iop; ppc32_jit_start_hreg_seq(cpu,"mtctr"); hreg_rs = ppc32_jit_alloc_hreg(cpu,rs); ppc32_op_emit_load_gpr(cpu,hreg_rs,rs); iop = ppc32_op_emit_insn_output(cpu,1,"mtctr"); amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ctr), hreg_rs,4); ppc32_jit_close_hreg_seq(cpu); return(0);}/* MFTBU - Move from Time Base (Up) */DECLARE_INSN(MFTBU){ int rd = bits(insn,21,25); int hreg_rd; jit_op_t *iop; ppc32_jit_start_hreg_seq(cpu,"mftbu"); hreg_rd = ppc32_jit_alloc_hreg(cpu,rd); iop = ppc32_op_emit_insn_output(cpu,1,"mftbu"); amd64_mov_reg_membase(iop->ob_ptr,hreg_rd, AMD64_R15,OFFSET(cpu_ppc_t,tb)+4,4); ppc32_op_emit_store_gpr(cpu,rd,hreg_rd); ppc32_jit_close_hreg_seq(cpu); return(0);}#define PPC32_TB_INCREMENT 50/* MFTBL - Move from Time Base (Lo) */DECLARE_INSN(MFTBL){ int rd = bits(insn,21,25); int hreg_rd; jit_op_t *iop; ppc32_jit_start_hreg_seq(cpu,"mftbl"); hreg_rd = ppc32_jit_alloc_hreg(cpu,rd); iop = ppc32_op_emit_insn_output(cpu,3,"mftbl"); amd64_mov_reg_membase(iop->ob_ptr,hreg_rd, AMD64_R15,OFFSET(cpu_ppc_t,tb),8); amd64_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_rd,PPC32_TB_INCREMENT); amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,tb), hreg_rd,8); ppc32_op_emit_store_gpr(cpu,rd,hreg_rd); ppc32_jit_close_hreg_seq(cpu); return(0);}/* ADD */DECLARE_INSN(ADD){ int rd = bits(insn,21,25); int ra = bits(insn,16,20); int rb = bits(insn,11,15); int hreg_rd,hreg_ra,hreg_rb; jit_op_t *iop; /* $rd = $ra + $rb */ ppc32_jit_start_hreg_seq(cpu,"add"); hreg_rd = ppc32_jit_alloc_hreg(cpu,rd); hreg_ra = ppc32_jit_alloc_hreg(cpu,ra); hreg_rb = ppc32_jit_alloc_hreg(cpu,rb); ppc32_op_emit_load_gpr(cpu,hreg_ra,ra); ppc32_op_emit_load_gpr(cpu,hreg_rb,rb); iop = ppc32_op_emit_insn_output(cpu,2,"add"); if (rd == ra) amd64_alu_reg_reg_size(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb,4); else if (rd == rb) amd64_alu_reg_reg_size(iop->ob_ptr,X86_ADD,hreg_rd,hreg_ra,4); else { amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4); amd64_alu_reg_reg_size(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb,4); } ppc32_op_emit_store_gpr(cpu,rd,hreg_rd); if (insn & 1) ppc32_op_emit_update_flags(cpu,0,TRUE); ppc32_jit_close_hreg_seq(cpu); return(0);}/* ADDC */DECLARE_INSN(ADDC){ int rd = bits(insn,21,25); int ra = bits(insn,16,20); int rb = bits(insn,11,15); int hreg_rd,hreg_ra,hreg_rb,hreg_t0; jit_op_t *iop; /* $rd = $ra + $rb */ ppc32_jit_start_hreg_seq(cpu,"addc"); hreg_rd = ppc32_jit_alloc_hreg(cpu,rd); hreg_ra = ppc32_jit_alloc_hreg(cpu,ra); hreg_rb = ppc32_jit_alloc_hreg(cpu,rb); /* store the carry flag */ hreg_t0 = ppc32_jit_get_tmp_hreg(cpu); ppc32_op_emit_load_gpr(cpu,hreg_ra,ra); ppc32_op_emit_load_gpr(cpu,hreg_rb,rb); iop = ppc32_op_emit_insn_output(cpu,2,"addc"); if (rd == ra) amd64_alu_reg_reg_size(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb,4); else if (rd == rb) amd64_alu_reg_reg_size(iop->ob_ptr,X86_ADD,hreg_rd,hreg_ra,4); else { amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4); amd64_alu_reg_reg_size(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb,4); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -