Mercurial > repos > blastem
comparison m68k_to_x86.c @ 128:fe598ffd85ce
Cleanup bit instructions and fix bug in translate_m68k_move that caused incorrect results once translate_m68k_src was fixed
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 29 Dec 2012 23:08:14 -0800 |
parents | 4e45d75501cf |
children | 691e4b147cea |
comparison
equal
deleted
inserted
replaced
127:0a0743a30ca1 | 128:fe598ffd85ce |
---|---|
108 case MODE_REG: | 108 case MODE_REG: |
109 case MODE_AREG: | 109 case MODE_AREG: |
110 //We only get one memory parameter, so if the dst operand is a register in memory, | 110 //We only get one memory parameter, so if the dst operand is a register in memory, |
111 //we need to copy this to a temp register first | 111 //we need to copy this to a temp register first |
112 reg = native_reg(&(inst->dst), opts); | 112 reg = native_reg(&(inst->dst), opts); |
113 if (reg >= 0 || inst->dst.addr_mode == MODE_UNUSED || (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG) | 113 if (reg >= 0 || inst->dst.addr_mode == MODE_UNUSED || !(inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG) |
114 || inst->op == M68K_EXG) { | 114 || inst->op == M68K_EXG) { |
115 | 115 |
116 ea->mode = MODE_REG_DISPLACE8; | 116 ea->mode = MODE_REG_DISPLACE8; |
117 ea->base = CONTEXT; | 117 ea->base = CONTEXT; |
118 ea->disp = reg_offset(&(inst->src)); | 118 ea->disp = reg_offset(&(inst->src)); |
633 } | 633 } |
634 | 634 |
635 uint8_t * get_native_address(native_map_slot * native_code_map, uint32_t address) | 635 uint8_t * get_native_address(native_map_slot * native_code_map, uint32_t address) |
636 { | 636 { |
637 address &= 0xFFFFFF; | 637 address &= 0xFFFFFF; |
638 //if (address > 0x400000) { | 638 if (address > 0x400000) { |
639 printf("get_native_address: %X\n", address); | 639 printf("get_native_address: %X\n", address); |
640 //} | 640 } |
641 address /= 2; | 641 address /= 2; |
642 uint32_t chunk = address / NATIVE_CHUNK_SIZE; | 642 uint32_t chunk = address / NATIVE_CHUNK_SIZE; |
643 if (!native_code_map[chunk].base) { | 643 if (!native_code_map[chunk].base) { |
644 return NULL; | 644 return NULL; |
645 } | 645 } |
717 flags_reg = src.base; | 717 flags_reg = src.base; |
718 } else { | 718 } else { |
719 if (reg >= 0) { | 719 if (reg >= 0) { |
720 flags_reg = reg; | 720 flags_reg = reg; |
721 } else { | 721 } else { |
722 dst = mov_ir(dst, src.disp, SCRATCH1, SZ_D); | 722 if(src.mode == MODE_REG_DISPLACE8) { |
723 dst = mov_rdisp8r(dst, src.base, src.disp, SCRATCH1, inst->extra.size); | |
724 } else { | |
725 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size); | |
726 } | |
723 src.mode = MODE_REG_DIRECT; | 727 src.mode = MODE_REG_DIRECT; |
724 flags_reg = src.base = SCRATCH1; | 728 flags_reg = src.base = SCRATCH1; |
725 } | 729 } |
726 } | 730 } |
727 switch(inst->dst.addr_mode) | 731 switch(inst->dst.addr_mode) |
2114 if (inst->extra.size == OPSIZE_BYTE) { | 2118 if (inst->extra.size == OPSIZE_BYTE) { |
2115 src_op.disp &= 0x7; | 2119 src_op.disp &= 0x7; |
2116 } | 2120 } |
2117 if (inst->op == M68K_BTST) { | 2121 if (inst->op == M68K_BTST) { |
2118 if (dst_op.mode == MODE_REG_DIRECT) { | 2122 if (dst_op.mode == MODE_REG_DIRECT) { |
2119 dst = bt_ir(dst, src_op.disp, dst_op.base, SZ_D); | 2123 dst = bt_ir(dst, src_op.disp, dst_op.base, inst->extra.size); |
2120 } else { | 2124 } else { |
2121 dst = bt_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, SZ_D); | 2125 dst = bt_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); |
2122 } | 2126 } |
2123 } else if (inst->op == M68K_BSET) { | 2127 } else if (inst->op == M68K_BSET) { |
2124 if (dst_op.mode == MODE_REG_DIRECT) { | 2128 if (dst_op.mode == MODE_REG_DIRECT) { |
2125 dst = bts_ir(dst, src_op.disp, dst_op.base, SZ_D); | 2129 dst = bts_ir(dst, src_op.disp, dst_op.base, inst->extra.size); |
2126 } else { | 2130 } else { |
2127 dst = bts_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, SZ_D); | 2131 dst = bts_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); |
2128 } | 2132 } |
2129 } else if (inst->op == M68K_BCLR) { | 2133 } else if (inst->op == M68K_BCLR) { |
2130 if (dst_op.mode == MODE_REG_DIRECT) { | 2134 if (dst_op.mode == MODE_REG_DIRECT) { |
2131 dst = btr_ir(dst, src_op.disp, dst_op.base, SZ_D); | 2135 dst = btr_ir(dst, src_op.disp, dst_op.base, inst->extra.size); |
2132 } else { | 2136 } else { |
2133 dst = btr_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, SZ_D); | 2137 dst = btr_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); |
2134 } | 2138 } |
2135 } else { | 2139 } else { |
2136 if (dst_op.mode == MODE_REG_DIRECT) { | 2140 if (dst_op.mode == MODE_REG_DIRECT) { |
2137 dst = btc_ir(dst, src_op.disp, dst_op.base, SZ_D); | 2141 dst = btc_ir(dst, src_op.disp, dst_op.base, inst->extra.size); |
2138 } else { | 2142 } else { |
2139 dst = btc_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, SZ_D); | 2143 dst = btc_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); |
2140 } | 2144 } |
2141 } | 2145 } |
2142 } else { | 2146 } else { |
2143 if (src_op.mode == MODE_REG_DISPLACE8) { | 2147 if (src_op.mode == MODE_REG_DISPLACE8) { |
2144 if (dst_op.base == SCRATCH1) { | 2148 if (dst_op.base == SCRATCH1) { |
2145 dst = push_r(dst, SCRATCH2); | 2149 dst = push_r(dst, SCRATCH2); |
2146 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_B); | 2150 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_B); |
2147 src_op.base = SCRATCH1; | 2151 src_op.base = SCRATCH2; |
2148 } else { | 2152 } else { |
2149 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_B); | 2153 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_B); |
2150 src_op.base = SCRATCH1; | 2154 src_op.base = SCRATCH1; |
2151 } | 2155 } |
2152 } | 2156 } |
2153 if (inst->extra.size == OPSIZE_BYTE) { | |
2154 dst = and_ir(dst, 0x7, src_op.base, SZ_B); | |
2155 } | |
2156 if (inst->op == M68K_BTST) { | 2157 if (inst->op == M68K_BTST) { |
2157 if (dst_op.mode == MODE_REG_DIRECT) { | 2158 if (dst_op.mode == MODE_REG_DIRECT) { |
2158 dst = bt_rr(dst, src_op.base, dst_op.base, SZ_D); | 2159 dst = bt_rr(dst, src_op.base, dst_op.base, inst->extra.size); |
2159 } else { | 2160 } else { |
2160 dst = bt_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, SZ_D); | 2161 dst = bt_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); |
2161 } | 2162 } |
2162 } else if (inst->op == M68K_BSET) { | 2163 } else if (inst->op == M68K_BSET) { |
2163 if (dst_op.mode == MODE_REG_DIRECT) { | 2164 if (dst_op.mode == MODE_REG_DIRECT) { |
2164 dst = bts_rr(dst, src_op.base, dst_op.base, SZ_D); | 2165 dst = bts_rr(dst, src_op.base, dst_op.base, inst->extra.size); |
2165 } else { | 2166 } else { |
2166 dst = bts_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, SZ_D); | 2167 dst = bts_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); |
2167 } | 2168 } |
2168 } else if (inst->op == M68K_BCLR) { | 2169 } else if (inst->op == M68K_BCLR) { |
2169 if (dst_op.mode == MODE_REG_DIRECT) { | 2170 if (dst_op.mode == MODE_REG_DIRECT) { |
2170 dst = btr_rr(dst, src_op.base, dst_op.base, SZ_D); | 2171 dst = btr_rr(dst, src_op.base, dst_op.base, inst->extra.size); |
2171 } else { | 2172 } else { |
2172 dst = btr_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, SZ_D); | 2173 dst = btr_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); |
2173 } | 2174 } |
2174 } else { | 2175 } else { |
2175 if (dst_op.mode == MODE_REG_DIRECT) { | 2176 if (dst_op.mode == MODE_REG_DIRECT) { |
2176 dst = btc_rr(dst, src_op.base, dst_op.base, SZ_D); | 2177 dst = btc_rr(dst, src_op.base, dst_op.base, inst->extra.size); |
2177 } else { | 2178 } else { |
2178 dst = btc_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, SZ_D); | 2179 dst = btc_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); |
2179 } | 2180 } |
2180 } | 2181 } |
2182 } | |
2183 if (src_op.base == SCRATCH2) { | |
2184 dst = pop_r(dst, SCRATCH2); | |
2181 } | 2185 } |
2182 //x86 sets the carry flag to the value of the bit tested | 2186 //x86 sets the carry flag to the value of the bit tested |
2183 //68K sets the zero flag to the complement of the bit tested | 2187 //68K sets the zero flag to the complement of the bit tested |
2184 dst = setcc_r(dst, CC_NC, FLAG_Z); | 2188 dst = setcc_r(dst, CC_NC, FLAG_Z); |
2185 if (src_op.base == SCRATCH2) { | 2189 if (inst->op != M68K_BTST) { |
2186 dst = pop_r(dst, SCRATCH2); | 2190 dst = m68k_save_result(inst, dst, opts); |
2187 } | 2191 } |
2188 break; | 2192 break; |
2189 /*case M68K_CHK: | 2193 /*case M68K_CHK: |
2190 break;*/ | 2194 break;*/ |
2191 case M68K_CMP: | 2195 case M68K_CMP: |