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;