#include "cpu/exec.h" #include "cpu/cc.h" namespace EHelperImpl { make_EHelper(jmp) { // the target address is calculated at the decode stage rtl_j(decoding.jmp_eip); print_asm("jmp %x", decoding.jmp_eip); } make_EHelper(jcc) { // the target address is calculated at the decode stage uint32_t cc = decoding.opcode & 0xf; rtl_setcc(&t0, cc); rtl_li(&t1, 0); rtl_jrelop(RELOP_NE, &t0, &t1, decoding.jmp_eip); print_asm("j%s %x", get_cc_name(cc), decoding.jmp_eip); } make_EHelper(jmp_rm) { rtl_jr(&id_dest->val); print_asm("jmp *%s", id_dest->str); } make_EHelper(call) { // the target address is calculated at the decode stage const bool near = true; if(near) { if(decoding.is_operand_size_16) { throw std::runtime_error("call operand size 16 not implemented."); } else { // operand size 32b rtl_push<4>(&decoding.seq_eip); rtl_j(decoding.jmp_eip); } decoding_set_jmp(true); } // TODO: support far call // TODO(); print_asm("call %x", decoding.jmp_eip); } make_EHelper(ret) { const bool near = true; if(near) { if(decoding.is_operand_size_16) { throw std::runtime_error("call operand size 16 not implemented."); } else { // operand size 32b rtl_pop<4>(&cpu.eip); } decoding_set_jmp(true); } // TODO: support far ret // TODO(); print_asm("ret"); } make_EHelper(call_rm) { RLIB_MACRO_DEBUG_ASSERT(decoding.is_operand_size_16 == false); rlib::println("Reach call_rm. WARNING: this instruction impl is heavily broken."); rtl_push<4>(&decoding.seq_eip); rtl_jr(&id_dest->val); // TODO: this far call logic is absolutely wrong. print_asm("call *%s", id_dest->str); } } // end namespace