Annotation of qemu/target-m68k/helper.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.