Mercurial > repos > blastem
comparison m68k_to_x86.c @ 216:0b5ec22dcda2
Fix some bugs related to sign-extension of address registers and pre-decrement amount for a7 when used as a source.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 19 Apr 2013 21:36:54 -0700 |
parents | 4d4559b04c59 |
children | 1abf8e967b33 |
comparison
equal
deleted
inserted
replaced
215:2b1c2c28b261 | 216:0b5ec22dcda2 |
---|---|
135 //we're explicitly handling the areg dest here, so we exit immediately | 135 //we're explicitly handling the areg dest here, so we exit immediately |
136 return out; | 136 return out; |
137 } | 137 } |
138 break; | 138 break; |
139 case MODE_AREG_PREDEC: | 139 case MODE_AREG_PREDEC: |
140 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : 1); | 140 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->src.params.regs.pri == 7 ? 2 :1)); |
141 out = cycles(out, PREDEC_PENALTY); | 141 out = cycles(out, PREDEC_PENALTY); |
142 if (opts->aregs[inst->src.params.regs.pri] >= 0) { | 142 if (opts->aregs[inst->src.params.regs.pri] >= 0) { |
143 out = sub_ir(out, dec_amount, opts->aregs[inst->src.params.regs.pri], SZ_D); | 143 out = sub_ir(out, dec_amount, opts->aregs[inst->src.params.regs.pri], SZ_D); |
144 } else { | 144 } else { |
145 out = sub_irdisp8(out, dec_amount, CONTEXT, reg_offset(&(inst->src)), SZ_D); | 145 out = sub_irdisp8(out, dec_amount, CONTEXT, reg_offset(&(inst->src)), SZ_D); |
352 if (inst->variant != VAR_QUICK) { | 352 if (inst->variant != VAR_QUICK) { |
353 out = cycles(out, (inst->extra.size == OPSIZE_LONG && inst->src.addr_mode == MODE_IMMEDIATE) ? BUS*2 : BUS); | 353 out = cycles(out, (inst->extra.size == OPSIZE_LONG && inst->src.addr_mode == MODE_IMMEDIATE) ? BUS*2 : BUS); |
354 } | 354 } |
355 ea->mode = MODE_IMMED; | 355 ea->mode = MODE_IMMED; |
356 ea->disp = inst->src.params.immed; | 356 ea->disp = inst->src.params.immed; |
357 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD && ea->disp & 0x8000) { | |
358 ea->disp |= 0xFFFF0000; | |
359 } | |
357 return out; | 360 return out; |
358 default: | 361 default: |
359 m68k_disasm(inst, disasm_buf); | 362 m68k_disasm(inst, disasm_buf); |
360 printf("%X: %s\naddress mode %d not implemented (src)\n", inst->address, disasm_buf, inst->src.addr_mode); | 363 printf("%X: %s\naddress mode %d not implemented (src)\n", inst->address, disasm_buf, inst->src.addr_mode); |
361 exit(1); | 364 exit(1); |
803 //update statically set flags | 806 //update statically set flags |
804 dst = mov_ir(dst, 0, FLAG_V, SZ_B); | 807 dst = mov_ir(dst, 0, FLAG_V, SZ_B); |
805 dst = mov_ir(dst, 0, FLAG_C, SZ_B); | 808 dst = mov_ir(dst, 0, FLAG_C, SZ_B); |
806 } | 809 } |
807 | 810 |
808 if (src.mode == MODE_REG_DIRECT) { | 811 if (inst->dst.addr_mode != MODE_AREG) { |
809 flags_reg = src.base; | 812 if (src.mode == MODE_REG_DIRECT) { |
810 } else { | 813 flags_reg = src.base; |
811 if (reg >= 0) { | 814 } else { |
812 flags_reg = reg; | 815 if (reg >= 0) { |
813 } else { | 816 flags_reg = reg; |
814 if(src.mode == MODE_REG_DISPLACE8) { | 817 } else { |
815 dst = mov_rdisp8r(dst, src.base, src.disp, SCRATCH1, inst->extra.size); | 818 if(src.mode == MODE_REG_DISPLACE8) { |
816 } else { | 819 dst = mov_rdisp8r(dst, src.base, src.disp, SCRATCH1, inst->extra.size); |
817 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size); | 820 } else { |
818 } | 821 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size); |
819 src.mode = MODE_REG_DIRECT; | 822 } |
820 flags_reg = src.base = SCRATCH1; | 823 src.mode = MODE_REG_DIRECT; |
824 flags_reg = src.base = SCRATCH1; | |
825 } | |
821 } | 826 } |
822 } | 827 } |
823 uint8_t size = inst->extra.size; | 828 uint8_t size = inst->extra.size; |
824 switch(inst->dst.addr_mode) | 829 switch(inst->dst.addr_mode) |
825 { | 830 { |
3877 //m68k_disasm(&instbuf, disbuf); | 3882 //m68k_disasm(&instbuf, disbuf); |
3878 //printf("%X: %s\n", instbuf.address, disbuf); | 3883 //printf("%X: %s\n", instbuf.address, disbuf); |
3879 uint8_t * after = translate_m68k(dst, &instbuf, opts); | 3884 uint8_t * after = translate_m68k(dst, &instbuf, opts); |
3880 map_native_address(context, instbuf.address, dst, m68k_size, after-dst); | 3885 map_native_address(context, instbuf.address, dst, m68k_size, after-dst); |
3881 dst = after; | 3886 dst = after; |
3882 } while(instbuf.op != M68K_ILLEGAL && instbuf.op != M68K_INVALID && instbuf.op != M68K_TRAP && instbuf.op != M68K_RTS && instbuf.op != M68K_RTR && instbuf.op != M68K_RTE && !(instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) && instbuf.op != M68K_JMP); | 3887 } while(instbuf.op != M68K_ILLEGAL && instbuf.op != M68K_RESET && instbuf.op != M68K_INVALID && instbuf.op != M68K_TRAP && instbuf.op != M68K_RTS && instbuf.op != M68K_RTR && instbuf.op != M68K_RTE && !(instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) && instbuf.op != M68K_JMP); |
3883 process_deferred(opts); | 3888 process_deferred(opts); |
3884 if (opts->deferred) { | 3889 if (opts->deferred) { |
3885 address = opts->deferred->address; | 3890 address = opts->deferred->address; |
3886 if ((address & 0xFFFFFF) < 0x400000) { | 3891 if ((address & 0xFFFFFF) < 0x400000) { |
3887 encoded = context->mem_pointers[0] + (address & 0xFFFFFF)/2; | 3892 encoded = context->mem_pointers[0] + (address & 0xFFFFFF)/2; |