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: