|
|
1.1 ! root 1: /* ! 2: * m68k op helpers ! 3: * ! 4: * Copyright (c) 2006 CodeSourcery ! 5: * Written by Paul Brook ! 6: * ! 7: * This library is free software; you can redistribute it and/or ! 8: * modify it under the terms of the GNU Lesser General Public ! 9: * License as published by the Free Software Foundation; either ! 10: * version 2 of the License, or (at your option) any later version. ! 11: * ! 12: * This library is distributed in the hope that it will be useful, ! 13: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 15: * General Public License for more details. ! 16: * ! 17: * You should have received a copy of the GNU Lesser General Public ! 18: * License along with this library; if not, write to the Free Software ! 19: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! 20: */ ! 21: ! 22: #include <stdio.h> ! 23: ! 24: #include "config.h" ! 25: #include "cpu.h" ! 26: #include "exec-all.h" ! 27: ! 28: void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op) ! 29: { ! 30: int flags; ! 31: uint32_t src; ! 32: uint32_t dest; ! 33: uint32_t tmp; ! 34: ! 35: #define HIGHBIT 0x80000000u ! 36: ! 37: #define SET_NZ(x) do { \ ! 38: if ((x) == 0) \ ! 39: flags |= CCF_Z; \ ! 40: else if ((int32_t)(x) < 0) \ ! 41: flags |= CCF_N; \ ! 42: } while (0) ! 43: ! 44: #define SET_FLAGS_SUB(type, utype) do { \ ! 45: SET_NZ((type)dest); \ ! 46: tmp = dest + src; \ ! 47: if ((utype) tmp < (utype) src) \ ! 48: flags |= CCF_C; \ ! 49: if ((1u << (sizeof(type) * 8 - 1)) & (tmp ^ dest) & (tmp ^ src)) \ ! 50: flags |= CCF_V; \ ! 51: } while (0) ! 52: ! 53: flags = 0; ! 54: src = env->cc_src; ! 55: dest = env->cc_dest; ! 56: switch (cc_op) { ! 57: case CC_OP_FLAGS: ! 58: flags = dest; ! 59: break; ! 60: case CC_OP_LOGIC: ! 61: SET_NZ(dest); ! 62: break; ! 63: case CC_OP_ADD: ! 64: SET_NZ(dest); ! 65: if (dest < src) ! 66: flags |= CCF_C; ! 67: tmp = dest - src; ! 68: if (HIGHBIT & (src ^ dest) & ~(tmp ^ src)) ! 69: flags |= CCF_V; ! 70: break; ! 71: case CC_OP_SUB: ! 72: SET_FLAGS_SUB(int32_t, uint32_t); ! 73: break; ! 74: case CC_OP_CMPB: ! 75: SET_FLAGS_SUB(int8_t, uint8_t); ! 76: break; ! 77: case CC_OP_CMPW: ! 78: SET_FLAGS_SUB(int16_t, uint16_t); ! 79: break; ! 80: case CC_OP_ADDX: ! 81: SET_NZ(dest); ! 82: if (dest <= src) ! 83: flags |= CCF_C; ! 84: tmp = dest - src - 1; ! 85: if (HIGHBIT & (src ^ dest) & ~(tmp ^ src)) ! 86: flags |= CCF_V; ! 87: break; ! 88: case CC_OP_SUBX: ! 89: SET_NZ(dest); ! 90: tmp = dest + src + 1; ! 91: if (tmp <= src) ! 92: flags |= CCF_C; ! 93: if (HIGHBIT & (tmp ^ dest) & (tmp ^ src)) ! 94: flags |= CCF_V; ! 95: break; ! 96: case CC_OP_SHL: ! 97: if (src >= 32) { ! 98: SET_NZ(0); ! 99: } else { ! 100: tmp = dest << src; ! 101: SET_NZ(tmp); ! 102: } ! 103: if (src && src <= 32 && (dest & (1 << (32 - src)))) ! 104: flags |= CCF_C; ! 105: break; ! 106: case CC_OP_SHR: ! 107: if (src >= 32) { ! 108: SET_NZ(0); ! 109: } else { ! 110: tmp = dest >> src; ! 111: SET_NZ(tmp); ! 112: } ! 113: if (src && src <= 32 && ((dest >> (src - 1)) & 1)) ! 114: flags |= CCF_C; ! 115: break; ! 116: case CC_OP_SAR: ! 117: if (src >= 32) { ! 118: SET_NZ(-1); ! 119: } else { ! 120: tmp = (int32_t)dest >> src; ! 121: SET_NZ(tmp); ! 122: } ! 123: if (src && src <= 32 && (((int32_t)dest >> (src - 1)) & 1)) ! 124: flags |= CCF_C; ! 125: break; ! 126: default: ! 127: cpu_abort(env, "Bad CC_OP %d", cc_op); ! 128: } ! 129: env->cc_op = CC_OP_FLAGS; ! 130: env->cc_dest = flags; ! 131: } ! 132: ! 133: float64 helper_sub_cmpf64(CPUM68KState *env, float64 src0, float64 src1) ! 134: { ! 135: /* ??? This may incorrectly raise exceptions. */ ! 136: /* ??? Should flush denormals to zero. */ ! 137: float64 res; ! 138: res = float64_sub(src0, src1, &env->fp_status); ! 139: if (float64_is_nan(res)) { ! 140: /* +/-inf compares equal against itself, but sub returns nan. */ ! 141: if (!float64_is_nan(src0) ! 142: && !float64_is_nan(src1)) { ! 143: res = 0; ! 144: if (float64_lt_quiet(src0, res, &env->fp_status)) ! 145: res = float64_chs(res); ! 146: } ! 147: } ! 148: return res; ! 149: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.