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 }