Mercurial > repos > blastem
comparison m68k_to_x86.c @ 74:6396dc91f61e
Fix some bugs in movem with a register list destination
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 21 Dec 2012 16:38:40 -0800 |
parents | 8da611e69b32 |
children | 187c65f40a64 |
comparison
equal
deleted
inserted
replaced
73:8da611e69b32 | 74:6396dc91f61e |
---|---|
166 ea->mode = MODE_REG_DIRECT; | 166 ea->mode = MODE_REG_DIRECT; |
167 ea->base = SCRATCH1; | 167 ea->base = SCRATCH1; |
168 break; | 168 break; |
169 case MODE_PC_DISPLACE: | 169 case MODE_PC_DISPLACE: |
170 out = cycles(out, BUS); | 170 out = cycles(out, BUS); |
171 out = mov_ir(out, inst->src.params.regs.displacement + inst->address, SCRATCH1, SZ_D); | 171 out = mov_ir(out, inst->src.params.regs.displacement + inst->address+2, SCRATCH1, SZ_D); |
172 switch (inst->extra.size) | 172 switch (inst->extra.size) |
173 { | 173 { |
174 case OPSIZE_BYTE: | 174 case OPSIZE_BYTE: |
175 out = call(out, (char *)m68k_read_byte_scratch1); | 175 out = call(out, (char *)m68k_read_byte_scratch1); |
176 break; | 176 break; |
308 ea->mode = MODE_REG_DIRECT; | 308 ea->mode = MODE_REG_DIRECT; |
309 ea->base = SCRATCH1; | 309 ea->base = SCRATCH1; |
310 break; | 310 break; |
311 case MODE_PC_DISPLACE: | 311 case MODE_PC_DISPLACE: |
312 out = cycles(out, BUS); | 312 out = cycles(out, BUS); |
313 out = mov_ir(out, inst->dst.params.regs.displacement + inst->address, SCRATCH1, SZ_D); | 313 out = mov_ir(out, inst->dst.params.regs.displacement + inst->address+2, SCRATCH1, SZ_D); |
314 out = push_r(out, SCRATCH1); | 314 out = push_r(out, SCRATCH1); |
315 switch (inst->extra.size) | 315 switch (inst->extra.size) |
316 { | 316 { |
317 case OPSIZE_BYTE: | 317 case OPSIZE_BYTE: |
318 out = call(out, (char *)m68k_read_byte_scratch1); | 318 out = call(out, (char *)m68k_read_byte_scratch1); |
573 break; | 573 break; |
574 } | 574 } |
575 break; | 575 break; |
576 case MODE_PC_DISPLACE: | 576 case MODE_PC_DISPLACE: |
577 dst = cycles(dst, BUS); | 577 dst = cycles(dst, BUS); |
578 dst = mov_ir(dst, inst->dst.params.regs.displacement + inst->address, SCRATCH2, SZ_D); | 578 dst = mov_ir(dst, inst->dst.params.regs.displacement + inst->address+2, SCRATCH2, SZ_D); |
579 if (src.mode == MODE_REG_DIRECT) { | 579 if (src.mode == MODE_REG_DIRECT) { |
580 if (src.base != SCRATCH1) { | 580 if (src.base != SCRATCH1) { |
581 dst = mov_rr(dst, src.base, SCRATCH1, inst->extra.size); | 581 dst = mov_rr(dst, src.base, SCRATCH1, inst->extra.size); |
582 } | 582 } |
583 } else if (src.mode == MODE_REG_DISPLACE8) { | 583 } else if (src.mode == MODE_REG_DISPLACE8) { |
739 printf("address mode %d not implemented (movem src)\n", inst->src.addr_mode); | 739 printf("address mode %d not implemented (movem src)\n", inst->src.addr_mode); |
740 exit(1); | 740 exit(1); |
741 } | 741 } |
742 dst = cycles(dst, early_cycles); | 742 dst = cycles(dst, early_cycles); |
743 for(reg = 0; reg < 16; reg ++) { | 743 for(reg = 0; reg < 16; reg ++) { |
744 if (inst->src.params.immed & (1 << reg)) { | 744 if (inst->dst.params.immed & (1 << reg)) { |
745 dst = push_r(dst, SCRATCH1); | 745 dst = push_r(dst, SCRATCH1); |
746 if (inst->extra.size == OPSIZE_LONG) { | 746 if (inst->extra.size == OPSIZE_LONG) { |
747 dst = call(dst, (uint8_t *)m68k_read_long_scratch1); | 747 dst = call(dst, (uint8_t *)m68k_read_long_scratch1); |
748 } else { | 748 } else { |
749 dst = call(dst, (uint8_t *)m68k_read_word_scratch1); | 749 dst = call(dst, (uint8_t *)m68k_read_word_scratch1); |
750 } | 750 } |
751 if (reg > 7) { | 751 if (reg > 7) { |
752 printf("movem.%c to a%d\n", (inst->extra.size == OPSIZE_WORD ? 'w' : 'l'), reg-8); | |
752 if (opts->aregs[reg-8] >= 0) { | 753 if (opts->aregs[reg-8] >= 0) { |
753 dst = mov_rr(dst, SCRATCH1, opts->aregs[reg-8], inst->extra.size); | 754 dst = mov_rr(dst, SCRATCH1, opts->aregs[reg-8], inst->extra.size); |
754 } else { | 755 } else { |
755 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * (reg-8), inst->extra.size); | 756 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * (reg-8), inst->extra.size); |
756 } | 757 } |
757 } else { | 758 } else { |
759 printf("movem.%c to d%d\n", (inst->extra.size == OPSIZE_WORD ? 'w' : 'l'), reg); | |
758 if (opts->dregs[reg] >= 0) { | 760 if (opts->dregs[reg] >= 0) { |
759 dst = mov_rr(dst, SCRATCH1, opts->dregs[reg], inst->extra.size); | 761 dst = mov_rr(dst, SCRATCH1, opts->dregs[reg], inst->extra.size); |
760 } else { | 762 } else { |
761 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t) * (reg), inst->extra.size); | 763 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t) * (reg), inst->extra.size); |
762 } | 764 } |
765 dst = add_ir(dst, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, SCRATCH1, SZ_D); | 767 dst = add_ir(dst, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, SCRATCH1, SZ_D); |
766 } | 768 } |
767 } | 769 } |
768 if (inst->src.addr_mode == MODE_AREG_POSTINC) { | 770 if (inst->src.addr_mode == MODE_AREG_POSTINC) { |
769 if (opts->aregs[inst->src.params.regs.pri] >= 0) { | 771 if (opts->aregs[inst->src.params.regs.pri] >= 0) { |
770 dst = mov_rr(dst, SCRATCH2, opts->aregs[inst->src.params.regs.pri], SZ_D); | 772 dst = mov_rr(dst, SCRATCH1, opts->aregs[inst->src.params.regs.pri], SZ_D); |
771 } else { | 773 } else { |
772 dst = mov_rrdisp8(dst, SCRATCH2, CONTEXT, reg_offset(&(inst->src)), SZ_D); | 774 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->src)), SZ_D); |
773 } | 775 } |
774 } | 776 } |
775 } | 777 } |
776 //prefetch | 778 //prefetch |
777 dst = cycles(dst, 4); | 779 dst = cycles(dst, 4); |
885 } | 887 } |
886 break; | 888 break; |
887 case MODE_PC_DISPLACE: | 889 case MODE_PC_DISPLACE: |
888 dst = cycles(dst, 8); | 890 dst = cycles(dst, 8); |
889 if (dst_reg >= 0) { | 891 if (dst_reg >= 0) { |
890 dst = mov_ir(dst, inst->src.params.regs.displacement + inst->address, dst_reg, SZ_D); | 892 dst = mov_ir(dst, inst->src.params.regs.displacement + inst->address+2, dst_reg, SZ_D); |
891 } else { | 893 } else { |
892 dst = mov_irdisp8(dst, inst->src.params.regs.displacement + inst->address, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->dst.params.regs.pri, SZ_D); | 894 dst = mov_irdisp8(dst, inst->src.params.regs.displacement + inst->address+2, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->dst.params.regs.pri, SZ_D); |
893 } | 895 } |
894 break; | 896 break; |
895 case MODE_ABSOLUTE: | 897 case MODE_ABSOLUTE: |
896 case MODE_ABSOLUTE_SHORT: | 898 case MODE_ABSOLUTE_SHORT: |
897 dst = cycles(dst, (inst->src.addr_mode == MODE_ABSOLUTE) ? BUS * 3 : BUS * 2); | 899 dst = cycles(dst, (inst->src.addr_mode == MODE_ABSOLUTE) ? BUS * 3 : BUS * 2); |