# HG changeset patch # User Michael Pavone # Date 1461818357 25200 # Node ID d70000fdff0bf7de6575d1be69c0110d5e87c598 # Parent ce9df7a5fdf28cab79b3457072f36605d6e9f89a Implemented IR and undefined bits of info word for address error exception frames diff -r ce9df7a5fdf2 -r d70000fdff0b m68k_core.c --- a/m68k_core.c Wed Apr 27 19:10:50 2016 -0700 +++ b/m68k_core.c Wed Apr 27 21:39:17 2016 -0700 @@ -702,6 +702,17 @@ } } +uint16_t m68k_get_ir(m68k_context *context) +{ + uint32_t inst_addr = get_instruction_start(context->options, context->native_code_map, context->last_prefetch_address-2); + uint16_t *native_addr = get_native_pointer(inst_addr, (void **)context->mem_pointers, &context->options->gen); + if (native_addr) { + return *native_addr; + } + fprintf(stderr, "M68K: Failed to calculate value of IR. Last prefetch address: %X\n", context->last_prefetch_address); + return 0xFFFF; +} + typedef enum { RAW_FUNC = 1, BINARY_ARITH, @@ -826,6 +837,7 @@ if ( (inst->src.addr_mode > MODE_AREG && inst->src.addr_mode < MODE_IMMEDIATE) || (inst->dst.addr_mode > MODE_AREG && inst->dst.addr_mode < MODE_IMMEDIATE) + || (inst->op == M68K_BCC && (inst->src.params.immed & 1)) ) { //Not accurate for all cases, but probably good enough for now m68k_set_last_prefetch(opts, inst->address + inst->bytes); diff -r ce9df7a5fdf2 -r d70000fdff0b m68k_core.h --- a/m68k_core.h Wed Apr 27 19:10:50 2016 -0700 +++ b/m68k_core.h Wed Apr 27 21:39:17 2016 -0700 @@ -79,6 +79,7 @@ void remove_breakpoint(m68k_context * context, uint32_t address); m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context); uint32_t get_instruction_start(m68k_options *opts, native_map_slot * native_code_map, uint32_t address); +uint16_t m68k_get_ir(m68k_context *context); #endif //M68K_CORE_H_ diff -r ce9df7a5fdf2 -r d70000fdff0b m68k_core_x86.c --- a/m68k_core_x86.c Wed Apr 27 19:10:50 2016 -0700 +++ b/m68k_core_x86.c Wed Apr 27 21:39:17 2016 -0700 @@ -2145,8 +2145,15 @@ call(code, opts->write_16); //save instruction register subi_areg(opts, 2, 7); - //TODO: Use actual value - mov_ir(code, 0, opts->gen.scratch1, SZ_W); + //calculate IR + push_r(code, opts->gen.context_reg); + call(code, opts->gen.save_context); + call_args_abi(code, (code_ptr)m68k_get_ir, 1, opts->gen.context_reg); + mov_rr(code, RAX, opts->gen.scratch1, SZ_W); + pop_r(code, opts->gen.context_reg); + push_r(code, RAX); //save it for use in the "info" word + call(code, opts->gen.load_context); + //write it to the stack areg_to_native(opts, 7, opts->gen.scratch2); call(code, opts->write_16); //save access address @@ -2162,7 +2169,10 @@ and_ir(code, 4, opts->gen.scratch1, SZ_B); //set FC1 to one to indicate instruction fetch, and R/W to indicate read or_ir(code, 0x12, opts->gen.scratch1, SZ_B); - //TODO: Figure out what undefined bits get set to, looks like it might be value of IR + //set undefined bits to IR value + pop_r(code, opts->gen.scratch2); + and_ir(code, 0xFFE0, opts->gen.scratch2, SZ_W); + or_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_W); subi_areg(opts, 2, 7); areg_to_native(opts, 7, opts->gen.scratch2); call(code, opts->write_16); @@ -2571,8 +2581,17 @@ call(code, opts->write_16); //save instruction register subi_areg(opts, 2, 7); - //TODO: Use actual value - mov_ir(code, 0, opts->gen.scratch1, SZ_W); + //calculate IR + push_r(code, opts->gen.context_reg); + call(code, opts->gen.save_context); + call_args_abi(code, (code_ptr)m68k_get_ir, 1, opts->gen.context_reg); + mov_rr(code, RAX, opts->gen.scratch1, SZ_W); + pop_r(code, opts->gen.context_reg); + pop_r(code, opts->gen.scratch2); //access address + push_r(code, RAX); //save it for use in the "info" word + push_r(code, opts->gen.scratch2); //access address + call(code, opts->gen.load_context); + //write it to the stack areg_to_native(opts, 7, opts->gen.scratch2); call(code, opts->write_16); //save access address @@ -2588,7 +2607,10 @@ and_ir(code, 4, opts->gen.scratch1, SZ_B); //set FC0 to one to indicate data access or_ir(code, 1, opts->gen.scratch1, SZ_B); - //TODO: Figure out what undefined bits get set to, looks like it might be value of IR + //set undefined bits to IR value + pop_r(code, opts->gen.scratch2); + and_ir(code, 0xFFE0, opts->gen.scratch2, SZ_W); + or_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_W); subi_areg(opts, 2, 7); areg_to_native(opts, 7, opts->gen.scratch2); call(code, opts->write_16); @@ -2621,8 +2643,17 @@ call(code, opts->write_16); //save instruction register subi_areg(opts, 2, 7); - //TODO: Use actual value - mov_ir(code, 0, opts->gen.scratch1, SZ_W); + //calculate IR + push_r(code, opts->gen.context_reg); + call(code, opts->gen.save_context); + call_args_abi(code, (code_ptr)m68k_get_ir, 1, opts->gen.context_reg); + mov_rr(code, RAX, opts->gen.scratch1, SZ_W); + pop_r(code, opts->gen.context_reg); + pop_r(code, opts->gen.scratch2); //access address + push_r(code, RAX); //save it for use in the "info" word + push_r(code, opts->gen.scratch2); //access address + call(code, opts->gen.load_context); + //write it to the stack areg_to_native(opts, 7, opts->gen.scratch2); call(code, opts->write_16); //save access address @@ -2638,7 +2669,10 @@ and_ir(code, 4, opts->gen.scratch1, SZ_B); //set FC0 to one to indicate data access, and R/W to indicate read or_ir(code, 0x11, opts->gen.scratch1, SZ_B); - //TODO: Figure out what undefined bits get set to, looks like it might be value of IR + //set undefined bits to IR value + pop_r(code, opts->gen.scratch2); + and_ir(code, 0xFFE0, opts->gen.scratch2, SZ_W); + or_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_W); subi_areg(opts, 2, 7); areg_to_native(opts, 7, opts->gen.scratch2); call(code, opts->write_16);