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);