Mercurial > repos > blastem
comparison m68k_to_x86.c @ 161:6748022656b7
Implement more address modes for movem dst and fix a missing break statement in translate_m68k_dst
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 05 Jan 2013 01:55:11 -0800 |
parents | c1530501c215 |
children | eba78ad49a11 |
comparison
equal
deleted
inserted
replaced
160:69ac23d42897 | 161:6748022656b7 |
---|---|
505 } | 505 } |
506 out = pop_r(out, SCRATCH2); | 506 out = pop_r(out, SCRATCH2); |
507 } | 507 } |
508 ea->mode = MODE_REG_DIRECT; | 508 ea->mode = MODE_REG_DIRECT; |
509 ea->base = SCRATCH1; | 509 ea->base = SCRATCH1; |
510 break; | |
510 case MODE_PC_DISPLACE: | 511 case MODE_PC_DISPLACE: |
511 out = cycles(out, fake_read ? BUS+(inst->extra.size == OPSIZE_LONG ? BUS*2 : BUS) : BUS); | 512 out = cycles(out, fake_read ? BUS+(inst->extra.size == OPSIZE_LONG ? BUS*2 : BUS) : BUS); |
512 out = mov_ir(out, inst->dst.params.regs.displacement + inst->address+2, fake_read ? SCRATCH2 : SCRATCH1, SZ_D); | 513 out = mov_ir(out, inst->dst.params.regs.displacement + inst->address+2, fake_read ? SCRATCH2 : SCRATCH1, SZ_D); |
513 if (!fake_read) { | 514 if (!fake_read) { |
514 out = push_r(out, SCRATCH1); | 515 out = push_r(out, SCRATCH1); |
970 return dst; | 971 return dst; |
971 } | 972 } |
972 | 973 |
973 uint8_t * translate_m68k_movem(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) | 974 uint8_t * translate_m68k_movem(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) |
974 { | 975 { |
975 int8_t bit,reg; | 976 int8_t bit,reg,sec_reg; |
976 uint8_t early_cycles; | 977 uint8_t early_cycles; |
977 if(inst->src.addr_mode == MODE_REG) { | 978 if(inst->src.addr_mode == MODE_REG) { |
978 //reg to mem | 979 //reg to mem |
979 early_cycles = 8; | 980 early_cycles = 8; |
980 int8_t dir; | 981 int8_t dir; |
991 case MODE_AREG_PREDEC: | 992 case MODE_AREG_PREDEC: |
992 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { | 993 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { |
993 dst = mov_rr(dst, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); | 994 dst = mov_rr(dst, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); |
994 } else { | 995 } else { |
995 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); | 996 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); |
997 } | |
998 break; | |
999 case MODE_AREG_DISPLACE: | |
1000 early_cycles += BUS; | |
1001 reg = SCRATCH2; | |
1002 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { | |
1003 dst = mov_rr(dst, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); | |
1004 } else { | |
1005 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); | |
1006 } | |
1007 dst = add_ir(dst, inst->dst.params.regs.displacement, SCRATCH2, SZ_D); | |
1008 break; | |
1009 case MODE_AREG_INDEX_DISP8: | |
1010 early_cycles += 6; | |
1011 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { | |
1012 dst = mov_rr(dst, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); | |
1013 } else { | |
1014 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); | |
1015 } | |
1016 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7; | |
1017 if (inst->dst.params.regs.sec & 1) { | |
1018 if (inst->dst.params.regs.sec & 0x10) { | |
1019 if (opts->aregs[sec_reg] >= 0) { | |
1020 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_D); | |
1021 } else { | |
1022 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_D); | |
1023 } | |
1024 } else { | |
1025 if (opts->dregs[sec_reg] >= 0) { | |
1026 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_D); | |
1027 } else { | |
1028 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_D); | |
1029 } | |
1030 } | |
1031 } else { | |
1032 if (inst->dst.params.regs.sec & 0x10) { | |
1033 if (opts->aregs[sec_reg] >= 0) { | |
1034 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_W, SZ_D); | |
1035 } else { | |
1036 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_W, SZ_D); | |
1037 } | |
1038 } else { | |
1039 if (opts->dregs[sec_reg] >= 0) { | |
1040 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_W, SZ_D); | |
1041 } else { | |
1042 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_W, SZ_D); | |
1043 } | |
1044 } | |
1045 dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_D); | |
1046 } | |
1047 if (inst->dst.params.regs.displacement) { | |
1048 dst = add_ir(dst, inst->dst.params.regs.displacement, SCRATCH2, SZ_D); | |
1049 } | |
1050 break; | |
1051 case MODE_PC_DISPLACE: | |
1052 early_cycles += BUS; | |
1053 dst = mov_ir(dst, inst->dst.params.regs.displacement + inst->address+2, SCRATCH2, SZ_D); | |
1054 break; | |
1055 case MODE_PC_INDEX_DISP8: | |
1056 early_cycles += 6; | |
1057 dst = mov_ir(dst, inst->address+2, SCRATCH2, SZ_D); | |
1058 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7; | |
1059 if (inst->dst.params.regs.sec & 1) { | |
1060 if (inst->dst.params.regs.sec & 0x10) { | |
1061 if (opts->aregs[sec_reg] >= 0) { | |
1062 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_D); | |
1063 } else { | |
1064 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_D); | |
1065 } | |
1066 } else { | |
1067 if (opts->dregs[sec_reg] >= 0) { | |
1068 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_D); | |
1069 } else { | |
1070 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_D); | |
1071 } | |
1072 } | |
1073 } else { | |
1074 if (inst->dst.params.regs.sec & 0x10) { | |
1075 if (opts->aregs[sec_reg] >= 0) { | |
1076 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_W, SZ_D); | |
1077 } else { | |
1078 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_W, SZ_D); | |
1079 } | |
1080 } else { | |
1081 if (opts->dregs[sec_reg] >= 0) { | |
1082 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_W, SZ_D); | |
1083 } else { | |
1084 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_W, SZ_D); | |
1085 } | |
1086 } | |
1087 dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_D); | |
1088 } | |
1089 if (inst->dst.params.regs.displacement) { | |
1090 dst = add_ir(dst, inst->dst.params.regs.displacement, SCRATCH2, SZ_D); | |
996 } | 1091 } |
997 break; | 1092 break; |
998 case MODE_ABSOLUTE: | 1093 case MODE_ABSOLUTE: |
999 early_cycles += 4; | 1094 early_cycles += 4; |
1000 case MODE_ABSOLUTE_SHORT: | 1095 case MODE_ABSOLUTE_SHORT: |