Mercurial > repos > blastem
comparison m68k_to_x86.c @ 221:71f6b76639db
Fix modulo on bit operations with a memory destination
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 20 Apr 2013 16:53:01 -0700 |
parents | 8d3c16071559 |
children | 17534fb7c4f5 |
comparison
equal
deleted
inserted
replaced
220:cb72780e17b1 | 221:71f6b76639db |
---|---|
3006 } else { | 3006 } else { |
3007 dst = btc_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); | 3007 dst = btc_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); |
3008 } | 3008 } |
3009 } | 3009 } |
3010 } else { | 3010 } else { |
3011 if (src_op.mode == MODE_REG_DISPLACE8) { | 3011 if (src_op.mode == MODE_REG_DISPLACE8 || (inst->dst.addr_mode != MODE_REG && src_op.base != SCRATCH1 && src_op.base != SCRATCH2)) { |
3012 if (dst_op.base == SCRATCH1) { | 3012 if (dst_op.base == SCRATCH1) { |
3013 dst = push_r(dst, SCRATCH2); | 3013 dst = push_r(dst, SCRATCH2); |
3014 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_B); | 3014 if (src_op.mode == MODE_REG_DIRECT) { |
3015 dst = mov_rr(dst, src_op.base, SCRATCH2, SZ_B); | |
3016 } else { | |
3017 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_B); | |
3018 } | |
3015 src_op.base = SCRATCH2; | 3019 src_op.base = SCRATCH2; |
3016 } else { | 3020 } else { |
3017 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_B); | 3021 if (src_op.mode == MODE_REG_DIRECT) { |
3022 dst = mov_rr(dst, src_op.base, SCRATCH1, SZ_B); | |
3023 } else { | |
3024 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_B); | |
3025 } | |
3018 src_op.base = SCRATCH1; | 3026 src_op.base = SCRATCH1; |
3019 } | 3027 } |
3020 } | 3028 } |
3029 uint8_t size = inst->extra.size; | |
3021 if (dst_op.mode == MODE_REG_DISPLACE8) { | 3030 if (dst_op.mode == MODE_REG_DISPLACE8) { |
3022 if (src_op.base != SCRATCH1 && src_op.base != SCRATCH2) { | 3031 if (src_op.base != SCRATCH1 && src_op.base != SCRATCH2) { |
3023 if (src_op.mode == MODE_REG_DIRECT) { | 3032 if (src_op.mode == MODE_REG_DIRECT) { |
3024 dst = mov_rr(dst, src_op.base, SCRATCH1, SZ_D); | 3033 dst = mov_rr(dst, src_op.base, SCRATCH1, SZ_D); |
3025 } else { | 3034 } else { |
3026 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_D); | 3035 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_D); |
3027 src_op.mode = MODE_REG_DIRECT; | 3036 src_op.mode = MODE_REG_DIRECT; |
3028 } | 3037 } |
3029 src_op.base = SCRATCH1; | 3038 src_op.base = SCRATCH1; |
3030 } | 3039 } |
3040 //b### with register destination is modulo 32 | |
3041 //x86 with a memory destination isn't modulo anything | |
3042 //so use an and here to force the value to be modulo 32 | |
3031 dst = and_ir(dst, 31, SCRATCH1, SZ_D); | 3043 dst = and_ir(dst, 31, SCRATCH1, SZ_D); |
3044 } else if(inst->dst.addr_mode != MODE_REG) { | |
3045 //b### with memory destination is modulo 8 | |
3046 //x86-64 doesn't support 8-bit bit operations | |
3047 //so we fake it by forcing the bit number to be modulo 8 | |
3048 dst = and_ir(dst, 7, src_op.base, SZ_D); | |
3049 size = SZ_D; | |
3032 } | 3050 } |
3033 if (inst->op == M68K_BTST) { | 3051 if (inst->op == M68K_BTST) { |
3034 if (dst_op.mode == MODE_REG_DIRECT) { | 3052 if (dst_op.mode == MODE_REG_DIRECT) { |
3035 dst = bt_rr(dst, src_op.base, dst_op.base, inst->extra.size); | 3053 dst = bt_rr(dst, src_op.base, dst_op.base, size); |
3036 } else { | 3054 } else { |
3037 dst = bt_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); | 3055 dst = bt_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, size); |
3038 } | 3056 } |
3039 } else if (inst->op == M68K_BSET) { | 3057 } else if (inst->op == M68K_BSET) { |
3040 if (dst_op.mode == MODE_REG_DIRECT) { | 3058 if (dst_op.mode == MODE_REG_DIRECT) { |
3041 dst = bts_rr(dst, src_op.base, dst_op.base, inst->extra.size); | 3059 dst = bts_rr(dst, src_op.base, dst_op.base, size); |
3042 } else { | 3060 } else { |
3043 dst = bts_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); | 3061 dst = bts_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, size); |
3044 } | 3062 } |
3045 } else if (inst->op == M68K_BCLR) { | 3063 } else if (inst->op == M68K_BCLR) { |
3046 if (dst_op.mode == MODE_REG_DIRECT) { | 3064 if (dst_op.mode == MODE_REG_DIRECT) { |
3047 dst = btr_rr(dst, src_op.base, dst_op.base, inst->extra.size); | 3065 dst = btr_rr(dst, src_op.base, dst_op.base, size); |
3048 } else { | 3066 } else { |
3049 dst = btr_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); | 3067 dst = btr_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, size); |
3050 } | 3068 } |
3051 } else { | 3069 } else { |
3052 if (dst_op.mode == MODE_REG_DIRECT) { | 3070 if (dst_op.mode == MODE_REG_DIRECT) { |
3053 dst = btc_rr(dst, src_op.base, dst_op.base, inst->extra.size); | 3071 dst = btc_rr(dst, src_op.base, dst_op.base, size); |
3054 } else { | 3072 } else { |
3055 dst = btc_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); | 3073 dst = btc_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, size); |
3056 } | 3074 } |
3057 } | 3075 } |
3058 if (src_op.base == SCRATCH2) { | 3076 if (src_op.base == SCRATCH2) { |
3059 dst = pop_r(dst, SCRATCH2); | 3077 dst = pop_r(dst, SCRATCH2); |
3060 } | 3078 } |