📄 ppc32_amd64_trans.c
字号:
iop = ppc32_op_emit_insn_output(cpu,4,"bl"); /* compute the new ia */ new_ia = b->start_ia + (b->ppc_trans_pos << 2); new_ia += sign_extend(offset << 2,26); /* set the return address */ ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2)); ppc32_set_jump(cpu,b,iop,new_ia,TRUE); ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB); ppc32_op_emit_branch_target(cpu,b,new_ia); ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2)); return(0);}/* BLA - Branch and Link Absolute */DECLARE_INSN(BLA){ m_uint32_t offset = bits(insn,2,25); m_uint32_t new_ia; jit_op_t *iop; iop = ppc32_op_emit_insn_output(cpu,4,"bla"); /* compute the new ia */ new_ia = sign_extend(offset << 2,26); /* set the return address */ ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2)); ppc32_set_jump(cpu,b,iop,new_ia,TRUE); ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB); ppc32_op_emit_branch_target(cpu,b,new_ia); ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2)); return(0);}/* BC - Branch Conditional (Condition Check only) */DECLARE_INSN(BCC){ int bo = bits(insn,21,25); int bi = bits(insn,16,20); int bd = bits(insn,2,15); jit_op_t *iop; u_int cr_field,cr_bit; m_uint32_t new_ia; u_char *jump_ptr; int local_jump; int cond; ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_JUMP); iop = ppc32_op_emit_insn_output(cpu,5,"bcc"); /* Get the wanted value for the condition bit */ cond = (bo >> 3) & 0x1; /* Set the return address */ if (insn & 1) { ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2)); ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1)<<2)); } /* Compute the new ia */ new_ia = sign_extend_32(bd << 2,16); if (!(insn & 0x02)) new_ia += b->start_ia + (b->ppc_trans_pos << 2); /* Test the condition bit */ cr_field = ppc32_get_cr_field(bi); cr_bit = ppc32_get_cr_bit(bi); ppc32_op_emit_require_flags(cpu,cr_field); amd64_test_membase_imm_size(iop->ob_ptr, AMD64_R15,PPC32_CR_FIELD_OFFSET(cr_field), (1 << cr_bit),4); local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr); /* * Optimize the jump, depending if the destination is in the same * page or not. */ if (local_jump) { ppc32_jit_tcb_record_patch(b,iop,iop->ob_ptr,new_ia); amd64_branch32(iop->ob_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,0,FALSE); } else { jump_ptr = iop->ob_ptr; amd64_branch32(iop->ob_ptr,(cond) ? X86_CC_Z : X86_CC_NZ,0,FALSE); ppc32_set_jump(cpu,b,iop,new_ia,TRUE); amd64_patch(jump_ptr,iop->ob_ptr); } ppc32_op_emit_branch_target(cpu,b,new_ia); return(0);}/* BC - Branch Conditional */DECLARE_INSN(BC){ int bo = bits(insn,21,25); int bi = bits(insn,16,20); int bd = bits(insn,2,15); int hreg_t0,hreg_t1; jit_op_t *iop; u_int cr_field,cr_bit; m_uint32_t new_ia; u_char *jump_ptr; int local_jump; int cond,ctr; ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_JUMP); iop = ppc32_op_emit_insn_output(cpu,5,"bc"); ppc32_jit_start_hreg_seq(cpu,"bc"); hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1); hreg_t1 = ppc32_jit_get_tmp_hreg(cpu); ppc32_op_emit_alter_host_reg(cpu,hreg_t0); /* Get the wanted value for the condition bit and CTR value */ cond = (bo >> 3) & 0x1; ctr = (bo >> 1) & 0x1; /* Set the return address */ if (insn & 1) { ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2)); ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1)<<2)); } /* Compute the new ia */ new_ia = sign_extend_32(bd << 2,16); if (!(insn & 0x02)) new_ia += b->start_ia + (b->ppc_trans_pos << 2); amd64_mov_reg_imm(iop->ob_ptr,hreg_t0,1); /* Decrement the count register */ if (!(bo & 0x04)) { amd64_dec_membase_size(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ctr),4); amd64_set_reg(iop->ob_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,hreg_t1,FALSE); amd64_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1); } /* Test the condition bit */ if (!((bo >> 4) & 0x01)) { cr_field = ppc32_get_cr_field(bi); cr_bit = ppc32_get_cr_bit(bi); ppc32_op_emit_require_flags(cpu,cr_field); amd64_test_membase_imm_size(iop->ob_ptr, AMD64_R15,PPC32_CR_FIELD_OFFSET(cr_field), (1 << cr_bit),4); amd64_set_reg(iop->ob_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,hreg_t1,FALSE); amd64_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1); } amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01); local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr); /* * Optimize the jump, depending if the destination is in the same * page or not. */ if (local_jump) { ppc32_jit_tcb_record_patch(b,iop,iop->ob_ptr,new_ia); amd64_branch32(iop->ob_ptr,X86_CC_NZ,0,FALSE); } else { jump_ptr = iop->ob_ptr; amd64_branch32(iop->ob_ptr,X86_CC_Z,0,FALSE); ppc32_set_jump(cpu,b,iop,new_ia,TRUE); amd64_patch(jump_ptr,iop->ob_ptr); } ppc32_op_emit_branch_target(cpu,b,new_ia); ppc32_jit_close_hreg_seq(cpu); return(0);}/* BCLR - Branch Conditional to Link register */DECLARE_INSN(BCLR){ int bo = bits(insn,21,25); int bi = bits(insn,16,20); int bd = bits(insn,2,15); int hreg_t0,hreg_t1; jit_op_t *iop; u_int cr_field,cr_bit; m_uint32_t new_ia; u_char *jump_ptr; int cond,ctr; ppc32_jit_start_hreg_seq(cpu,"bclr"); hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1); hreg_t1 = ppc32_jit_get_tmp_hreg(cpu); ppc32_op_emit_alter_host_reg(cpu,hreg_t0); iop = ppc32_op_emit_insn_output(cpu,5,"bclr"); /* Get the wanted value for the condition bit and CTR value */ cond = (bo >> 3) & 0x1; ctr = (bo >> 1) & 0x1; /* Compute the new ia */ new_ia = sign_extend_32(bd << 2,16); if (!(insn & 0x02)) new_ia += b->start_ia + (b->ppc_trans_pos << 2); amd64_mov_reg_imm(iop->ob_ptr,hreg_t0,1); /* Decrement the count register */ if (!(bo & 0x04)) { amd64_dec_membase_size(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ctr),4); amd64_set_reg(iop->ob_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,hreg_t1,FALSE); amd64_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1); } /* Test the condition bit */ if (!((bo >> 4) & 0x01)) { cr_field = ppc32_get_cr_field(bi); cr_bit = ppc32_get_cr_bit(bi); ppc32_op_emit_require_flags(cpu,cr_field); amd64_test_membase_imm_size(iop->ob_ptr, AMD64_R15,PPC32_CR_FIELD_OFFSET(cr_field), (1 << cr_bit),4); amd64_set_reg(iop->ob_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,hreg_t1,FALSE); amd64_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1); } /* Set the return address */ amd64_mov_reg_membase(iop->ob_ptr,hreg_t1,AMD64_R15,OFFSET(cpu_ppc_t,lr),4); if (insn & 1) { ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2)); ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1)<<2)); } /* Branching */ amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01); jump_ptr = iop->ob_ptr; amd64_branch32(iop->ob_ptr,X86_CC_Z,0,FALSE); amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t1,0xFFFFFFFC); amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ia),hreg_t1,4); ppc32_jit_tcb_push_epilog(&iop->ob_ptr); amd64_patch(jump_ptr,iop->ob_ptr); ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB); ppc32_jit_close_hreg_seq(cpu); return(0);}/* CMP - Compare */DECLARE_INSN(CMP){ int rd = bits(insn,23,25); int ra = bits(insn,16,20); int rb = bits(insn,11,15); int hreg_ra,hreg_rb; jit_op_t *iop; ppc32_jit_start_hreg_seq(cpu,"cmp"); 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,1,"cmp"); amd64_alu_reg_reg_size(iop->ob_ptr,X86_CMP,hreg_ra,hreg_rb,4); ppc32_op_emit_update_flags(cpu,rd,TRUE); ppc32_jit_close_hreg_seq(cpu); return(0);}/* CMPI - Compare Immediate */DECLARE_INSN(CMPI){ int rd = bits(insn,23,25); int ra = bits(insn,16,20); m_uint16_t imm = bits(insn,0,15); m_uint32_t tmp = sign_extend_32(imm,16); int hreg_ra; jit_op_t *iop; ppc32_jit_start_hreg_seq(cpu,"cmpi"); hreg_ra = ppc32_jit_alloc_hreg(cpu,ra); ppc32_op_emit_load_gpr(cpu,hreg_ra,ra); iop = ppc32_op_emit_insn_output(cpu,1,"cmpi"); amd64_alu_reg_imm_size(iop->ob_ptr,X86_CMP,hreg_ra,tmp,4); ppc32_op_emit_update_flags(cpu,rd,TRUE); ppc32_jit_close_hreg_seq(cpu); return(0);}/* CMPL - Compare Logical */DECLARE_INSN(CMPL){ int rd = bits(insn,23,25); int ra = bits(insn,16,20); int rb = bits(insn,11,15); int hreg_ra,hreg_rb; jit_op_t *iop; ppc32_jit_start_hreg_seq(cpu,"cmpl"); 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,1,"cmpl"); amd64_alu_reg_reg_size(iop->ob_ptr,X86_CMP,hreg_ra,hreg_rb,4); ppc32_op_emit_update_flags(cpu,rd,FALSE); ppc32_jit_close_hreg_seq(cpu); return(0);}/* CMPLI - Compare Immediate */DECLARE_INSN(CMPLI){ int rd = bits(insn,23,25); int ra = bits(insn,16,20); m_uint32_t imm = bits(insn,0,15); int hreg_ra; jit_op_t *iop; ppc32_jit_start_hreg_seq(cpu,"cmpli"); hreg_ra = ppc32_jit_alloc_hreg(cpu,ra); ppc32_op_emit_load_gpr(cpu,hreg_ra,ra); iop = ppc32_op_emit_insn_output(cpu,1,"cmpli"); amd64_alu_reg_imm_size(iop->ob_ptr,X86_CMP,hreg_ra,imm,4); ppc32_op_emit_update_flags(cpu,rd,FALSE); ppc32_jit_close_hreg_seq(cpu); return(0);}/* CRAND - Condition Register AND */DECLARE_INSN(CRAND){ int bd = bits(insn,21,25); int bb = bits(insn,16,20); int ba = bits(insn,11,15); int hreg_t0; jit_op_t *iop; ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX); ppc32_jit_start_hreg_seq(cpu,"crand"); hreg_t0 = ppc32_jit_get_tmp_hreg(cpu); ppc32_jit_alloc_hreg_forced(cpu,AMD64_RDX); ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba)); ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb)); ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd)); iop = ppc32_op_emit_insn_output(cpu,3,"crand"); /* test $ba bit */ amd64_test_membase_imm(iop->ob_ptr, AMD64_R15, PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)), (1 << ppc32_get_cr_bit(ba))); amd64_set_reg(iop->ob_ptr,X86_CC_NZ,AMD64_RDX,FALSE); /* test $bb bit */ amd64_test_membase_imm(iop->ob_ptr, AMD64_R15, PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)), (1 << ppc32_get_cr_bit(bb))); amd64_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE); /* result of AND between $ba and $bb */ amd64_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,AMD64_RDX); amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01); /* set/clear $bd bit depending on the result */ amd64_alu_membase_imm_size(iop->ob_ptr,X86_AND, AMD64_R15, PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), ~(1 << ppc32_get_cr_bit(bd)),4); amd64_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd)); amd64_alu_membase_reg_size(iop->ob_ptr,X86_OR, AMD64_R15, PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), hreg_t0,4); ppc32_jit_close_hreg_seq(cpu); return(0);}/* CRANDC - Condition Register AND with Complement */DECLARE_INSN(CRANDC){ int bd = bits(insn,21,25); int bb = bits(insn,16,20); int ba = bits(insn,11,15); int hreg_t0; jit_op_t *iop; ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX); ppc32_jit_start_hreg_seq(cpu,"crandc"); hreg_t0 = ppc32_jit_get_tmp_hreg(cpu); ppc32_jit_alloc_hreg_forced(cpu,AMD64_RDX); ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba)); ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb)); ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -