Annotation of qemu/target-sparc/cc_helper.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Helpers for lazy condition code handling
                      3:  *
                      4:  *  Copyright (c) 2003-2005 Fabrice Bellard
                      5:  *
                      6:  * This library is free software; you can redistribute it and/or
                      7:  * modify it under the terms of the GNU Lesser General Public
                      8:  * License as published by the Free Software Foundation; either
                      9:  * version 2 of the License, or (at your option) any later version.
                     10:  *
                     11:  * This library is distributed in the hope that it will be useful,
                     12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * Lesser General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU Lesser General Public
                     17:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
                     18:  */
                     19: 
                     20: #include "cpu.h"
                     21: #include "helper.h"
                     22: 
                     23: static uint32_t compute_all_flags(CPUState *env)
                     24: {
                     25:     return env->psr & PSR_ICC;
                     26: }
                     27: 
                     28: static uint32_t compute_C_flags(CPUState *env)
                     29: {
                     30:     return env->psr & PSR_CARRY;
                     31: }
                     32: 
                     33: static inline uint32_t get_NZ_icc(int32_t dst)
                     34: {
                     35:     uint32_t ret = 0;
                     36: 
                     37:     if (dst == 0) {
                     38:         ret = PSR_ZERO;
                     39:     } else if (dst < 0) {
                     40:         ret = PSR_NEG;
                     41:     }
                     42:     return ret;
                     43: }
                     44: 
                     45: #ifdef TARGET_SPARC64
                     46: static uint32_t compute_all_flags_xcc(CPUState *env)
                     47: {
                     48:     return env->xcc & PSR_ICC;
                     49: }
                     50: 
                     51: static uint32_t compute_C_flags_xcc(CPUState *env)
                     52: {
                     53:     return env->xcc & PSR_CARRY;
                     54: }
                     55: 
                     56: static inline uint32_t get_NZ_xcc(target_long dst)
                     57: {
                     58:     uint32_t ret = 0;
                     59: 
                     60:     if (!dst) {
                     61:         ret = PSR_ZERO;
                     62:     } else if (dst < 0) {
                     63:         ret = PSR_NEG;
                     64:     }
                     65:     return ret;
                     66: }
                     67: #endif
                     68: 
                     69: static inline uint32_t get_V_div_icc(target_ulong src2)
                     70: {
                     71:     uint32_t ret = 0;
                     72: 
                     73:     if (src2 != 0) {
                     74:         ret = PSR_OVF;
                     75:     }
                     76:     return ret;
                     77: }
                     78: 
                     79: static uint32_t compute_all_div(CPUState *env)
                     80: {
                     81:     uint32_t ret;
                     82: 
                     83:     ret = get_NZ_icc(CC_DST);
                     84:     ret |= get_V_div_icc(CC_SRC2);
                     85:     return ret;
                     86: }
                     87: 
                     88: static uint32_t compute_C_div(CPUState *env)
                     89: {
                     90:     return 0;
                     91: }
                     92: 
                     93: static inline uint32_t get_C_add_icc(uint32_t dst, uint32_t src1)
                     94: {
                     95:     uint32_t ret = 0;
                     96: 
                     97:     if (dst < src1) {
                     98:         ret = PSR_CARRY;
                     99:     }
                    100:     return ret;
                    101: }
                    102: 
                    103: static inline uint32_t get_C_addx_icc(uint32_t dst, uint32_t src1,
                    104:                                       uint32_t src2)
                    105: {
                    106:     uint32_t ret = 0;
                    107: 
                    108:     if (((src1 & src2) | (~dst & (src1 | src2))) & (1U << 31)) {
                    109:         ret = PSR_CARRY;
                    110:     }
                    111:     return ret;
                    112: }
                    113: 
                    114: static inline uint32_t get_V_add_icc(uint32_t dst, uint32_t src1,
                    115:                                      uint32_t src2)
                    116: {
                    117:     uint32_t ret = 0;
                    118: 
                    119:     if (((src1 ^ src2 ^ -1) & (src1 ^ dst)) & (1U << 31)) {
                    120:         ret = PSR_OVF;
                    121:     }
                    122:     return ret;
                    123: }
                    124: 
                    125: #ifdef TARGET_SPARC64
                    126: static inline uint32_t get_C_add_xcc(target_ulong dst, target_ulong src1)
                    127: {
                    128:     uint32_t ret = 0;
                    129: 
                    130:     if (dst < src1) {
                    131:         ret = PSR_CARRY;
                    132:     }
                    133:     return ret;
                    134: }
                    135: 
                    136: static inline uint32_t get_C_addx_xcc(target_ulong dst, target_ulong src1,
                    137:                                       target_ulong src2)
                    138: {
                    139:     uint32_t ret = 0;
                    140: 
                    141:     if (((src1 & src2) | (~dst & (src1 | src2))) & (1ULL << 63)) {
                    142:         ret = PSR_CARRY;
                    143:     }
                    144:     return ret;
                    145: }
                    146: 
                    147: static inline uint32_t get_V_add_xcc(target_ulong dst, target_ulong src1,
                    148:                                      target_ulong src2)
                    149: {
                    150:     uint32_t ret = 0;
                    151: 
                    152:     if (((src1 ^ src2 ^ -1) & (src1 ^ dst)) & (1ULL << 63)) {
                    153:         ret = PSR_OVF;
                    154:     }
                    155:     return ret;
                    156: }
                    157: 
                    158: static uint32_t compute_all_add_xcc(CPUState *env)
                    159: {
                    160:     uint32_t ret;
                    161: 
                    162:     ret = get_NZ_xcc(CC_DST);
                    163:     ret |= get_C_add_xcc(CC_DST, CC_SRC);
                    164:     ret |= get_V_add_xcc(CC_DST, CC_SRC, CC_SRC2);
                    165:     return ret;
                    166: }
                    167: 
                    168: static uint32_t compute_C_add_xcc(CPUState *env)
                    169: {
                    170:     return get_C_add_xcc(CC_DST, CC_SRC);
                    171: }
                    172: #endif
                    173: 
                    174: static uint32_t compute_all_add(CPUState *env)
                    175: {
                    176:     uint32_t ret;
                    177: 
                    178:     ret = get_NZ_icc(CC_DST);
                    179:     ret |= get_C_add_icc(CC_DST, CC_SRC);
                    180:     ret |= get_V_add_icc(CC_DST, CC_SRC, CC_SRC2);
                    181:     return ret;
                    182: }
                    183: 
                    184: static uint32_t compute_C_add(CPUState *env)
                    185: {
                    186:     return get_C_add_icc(CC_DST, CC_SRC);
                    187: }
                    188: 
                    189: #ifdef TARGET_SPARC64
                    190: static uint32_t compute_all_addx_xcc(CPUState *env)
                    191: {
                    192:     uint32_t ret;
                    193: 
                    194:     ret = get_NZ_xcc(CC_DST);
                    195:     ret |= get_C_addx_xcc(CC_DST, CC_SRC, CC_SRC2);
                    196:     ret |= get_V_add_xcc(CC_DST, CC_SRC, CC_SRC2);
                    197:     return ret;
                    198: }
                    199: 
                    200: static uint32_t compute_C_addx_xcc(CPUState *env)
                    201: {
                    202:     uint32_t ret;
                    203: 
                    204:     ret = get_C_addx_xcc(CC_DST, CC_SRC, CC_SRC2);
                    205:     return ret;
                    206: }
                    207: #endif
                    208: 
                    209: static uint32_t compute_all_addx(CPUState *env)
                    210: {
                    211:     uint32_t ret;
                    212: 
                    213:     ret = get_NZ_icc(CC_DST);
                    214:     ret |= get_C_addx_icc(CC_DST, CC_SRC, CC_SRC2);
                    215:     ret |= get_V_add_icc(CC_DST, CC_SRC, CC_SRC2);
                    216:     return ret;
                    217: }
                    218: 
                    219: static uint32_t compute_C_addx(CPUState *env)
                    220: {
                    221:     uint32_t ret;
                    222: 
                    223:     ret = get_C_addx_icc(CC_DST, CC_SRC, CC_SRC2);
                    224:     return ret;
                    225: }
                    226: 
                    227: static inline uint32_t get_V_tag_icc(target_ulong src1, target_ulong src2)
                    228: {
                    229:     uint32_t ret = 0;
                    230: 
                    231:     if ((src1 | src2) & 0x3) {
                    232:         ret = PSR_OVF;
                    233:     }
                    234:     return ret;
                    235: }
                    236: 
                    237: static uint32_t compute_all_tadd(CPUState *env)
                    238: {
                    239:     uint32_t ret;
                    240: 
                    241:     ret = get_NZ_icc(CC_DST);
                    242:     ret |= get_C_add_icc(CC_DST, CC_SRC);
                    243:     ret |= get_V_add_icc(CC_DST, CC_SRC, CC_SRC2);
                    244:     ret |= get_V_tag_icc(CC_SRC, CC_SRC2);
                    245:     return ret;
                    246: }
                    247: 
                    248: static uint32_t compute_all_taddtv(CPUState *env)
                    249: {
                    250:     uint32_t ret;
                    251: 
                    252:     ret = get_NZ_icc(CC_DST);
                    253:     ret |= get_C_add_icc(CC_DST, CC_SRC);
                    254:     return ret;
                    255: }
                    256: 
                    257: static inline uint32_t get_C_sub_icc(uint32_t src1, uint32_t src2)
                    258: {
                    259:     uint32_t ret = 0;
                    260: 
                    261:     if (src1 < src2) {
                    262:         ret = PSR_CARRY;
                    263:     }
                    264:     return ret;
                    265: }
                    266: 
                    267: static inline uint32_t get_C_subx_icc(uint32_t dst, uint32_t src1,
                    268:                                       uint32_t src2)
                    269: {
                    270:     uint32_t ret = 0;
                    271: 
                    272:     if (((~src1 & src2) | (dst & (~src1 | src2))) & (1U << 31)) {
                    273:         ret = PSR_CARRY;
                    274:     }
                    275:     return ret;
                    276: }
                    277: 
                    278: static inline uint32_t get_V_sub_icc(uint32_t dst, uint32_t src1,
                    279:                                      uint32_t src2)
                    280: {
                    281:     uint32_t ret = 0;
                    282: 
                    283:     if (((src1 ^ src2) & (src1 ^ dst)) & (1U << 31)) {
                    284:         ret = PSR_OVF;
                    285:     }
                    286:     return ret;
                    287: }
                    288: 
                    289: 
                    290: #ifdef TARGET_SPARC64
                    291: static inline uint32_t get_C_sub_xcc(target_ulong src1, target_ulong src2)
                    292: {
                    293:     uint32_t ret = 0;
                    294: 
                    295:     if (src1 < src2) {
                    296:         ret = PSR_CARRY;
                    297:     }
                    298:     return ret;
                    299: }
                    300: 
                    301: static inline uint32_t get_C_subx_xcc(target_ulong dst, target_ulong src1,
                    302:                                       target_ulong src2)
                    303: {
                    304:     uint32_t ret = 0;
                    305: 
                    306:     if (((~src1 & src2) | (dst & (~src1 | src2))) & (1ULL << 63)) {
                    307:         ret = PSR_CARRY;
                    308:     }
                    309:     return ret;
                    310: }
                    311: 
                    312: static inline uint32_t get_V_sub_xcc(target_ulong dst, target_ulong src1,
                    313:                                      target_ulong src2)
                    314: {
                    315:     uint32_t ret = 0;
                    316: 
                    317:     if (((src1 ^ src2) & (src1 ^ dst)) & (1ULL << 63)) {
                    318:         ret = PSR_OVF;
                    319:     }
                    320:     return ret;
                    321: }
                    322: 
                    323: static uint32_t compute_all_sub_xcc(CPUState *env)
                    324: {
                    325:     uint32_t ret;
                    326: 
                    327:     ret = get_NZ_xcc(CC_DST);
                    328:     ret |= get_C_sub_xcc(CC_SRC, CC_SRC2);
                    329:     ret |= get_V_sub_xcc(CC_DST, CC_SRC, CC_SRC2);
                    330:     return ret;
                    331: }
                    332: 
                    333: static uint32_t compute_C_sub_xcc(CPUState *env)
                    334: {
                    335:     return get_C_sub_xcc(CC_SRC, CC_SRC2);
                    336: }
                    337: #endif
                    338: 
                    339: static uint32_t compute_all_sub(CPUState *env)
                    340: {
                    341:     uint32_t ret;
                    342: 
                    343:     ret = get_NZ_icc(CC_DST);
                    344:     ret |= get_C_sub_icc(CC_SRC, CC_SRC2);
                    345:     ret |= get_V_sub_icc(CC_DST, CC_SRC, CC_SRC2);
                    346:     return ret;
                    347: }
                    348: 
                    349: static uint32_t compute_C_sub(CPUState *env)
                    350: {
                    351:     return get_C_sub_icc(CC_SRC, CC_SRC2);
                    352: }
                    353: 
                    354: #ifdef TARGET_SPARC64
                    355: static uint32_t compute_all_subx_xcc(CPUState *env)
                    356: {
                    357:     uint32_t ret;
                    358: 
                    359:     ret = get_NZ_xcc(CC_DST);
                    360:     ret |= get_C_subx_xcc(CC_DST, CC_SRC, CC_SRC2);
                    361:     ret |= get_V_sub_xcc(CC_DST, CC_SRC, CC_SRC2);
                    362:     return ret;
                    363: }
                    364: 
                    365: static uint32_t compute_C_subx_xcc(CPUState *env)
                    366: {
                    367:     uint32_t ret;
                    368: 
                    369:     ret = get_C_subx_xcc(CC_DST, CC_SRC, CC_SRC2);
                    370:     return ret;
                    371: }
                    372: #endif
                    373: 
                    374: static uint32_t compute_all_subx(CPUState *env)
                    375: {
                    376:     uint32_t ret;
                    377: 
                    378:     ret = get_NZ_icc(CC_DST);
                    379:     ret |= get_C_subx_icc(CC_DST, CC_SRC, CC_SRC2);
                    380:     ret |= get_V_sub_icc(CC_DST, CC_SRC, CC_SRC2);
                    381:     return ret;
                    382: }
                    383: 
                    384: static uint32_t compute_C_subx(CPUState *env)
                    385: {
                    386:     uint32_t ret;
                    387: 
                    388:     ret = get_C_subx_icc(CC_DST, CC_SRC, CC_SRC2);
                    389:     return ret;
                    390: }
                    391: 
                    392: static uint32_t compute_all_tsub(CPUState *env)
                    393: {
                    394:     uint32_t ret;
                    395: 
                    396:     ret = get_NZ_icc(CC_DST);
                    397:     ret |= get_C_sub_icc(CC_SRC, CC_SRC2);
                    398:     ret |= get_V_sub_icc(CC_DST, CC_SRC, CC_SRC2);
                    399:     ret |= get_V_tag_icc(CC_SRC, CC_SRC2);
                    400:     return ret;
                    401: }
                    402: 
                    403: static uint32_t compute_all_tsubtv(CPUState *env)
                    404: {
                    405:     uint32_t ret;
                    406: 
                    407:     ret = get_NZ_icc(CC_DST);
                    408:     ret |= get_C_sub_icc(CC_SRC, CC_SRC2);
                    409:     return ret;
                    410: }
                    411: 
                    412: static uint32_t compute_all_logic(CPUState *env)
                    413: {
                    414:     return get_NZ_icc(CC_DST);
                    415: }
                    416: 
                    417: static uint32_t compute_C_logic(CPUState *env)
                    418: {
                    419:     return 0;
                    420: }
                    421: 
                    422: #ifdef TARGET_SPARC64
                    423: static uint32_t compute_all_logic_xcc(CPUState *env)
                    424: {
                    425:     return get_NZ_xcc(CC_DST);
                    426: }
                    427: #endif
                    428: 
                    429: typedef struct CCTable {
                    430:     uint32_t (*compute_all)(CPUState *env); /* return all the flags */
                    431:     uint32_t (*compute_c)(CPUState *env);  /* return the C flag */
                    432: } CCTable;
                    433: 
                    434: static const CCTable icc_table[CC_OP_NB] = {
                    435:     /* CC_OP_DYNAMIC should never happen */
                    436:     [CC_OP_FLAGS] = { compute_all_flags, compute_C_flags },
                    437:     [CC_OP_DIV] = { compute_all_div, compute_C_div },
                    438:     [CC_OP_ADD] = { compute_all_add, compute_C_add },
                    439:     [CC_OP_ADDX] = { compute_all_addx, compute_C_addx },
                    440:     [CC_OP_TADD] = { compute_all_tadd, compute_C_add },
                    441:     [CC_OP_TADDTV] = { compute_all_taddtv, compute_C_add },
                    442:     [CC_OP_SUB] = { compute_all_sub, compute_C_sub },
                    443:     [CC_OP_SUBX] = { compute_all_subx, compute_C_subx },
                    444:     [CC_OP_TSUB] = { compute_all_tsub, compute_C_sub },
                    445:     [CC_OP_TSUBTV] = { compute_all_tsubtv, compute_C_sub },
                    446:     [CC_OP_LOGIC] = { compute_all_logic, compute_C_logic },
                    447: };
                    448: 
                    449: #ifdef TARGET_SPARC64
                    450: static const CCTable xcc_table[CC_OP_NB] = {
                    451:     /* CC_OP_DYNAMIC should never happen */
                    452:     [CC_OP_FLAGS] = { compute_all_flags_xcc, compute_C_flags_xcc },
                    453:     [CC_OP_DIV] = { compute_all_logic_xcc, compute_C_logic },
                    454:     [CC_OP_ADD] = { compute_all_add_xcc, compute_C_add_xcc },
                    455:     [CC_OP_ADDX] = { compute_all_addx_xcc, compute_C_addx_xcc },
                    456:     [CC_OP_TADD] = { compute_all_add_xcc, compute_C_add_xcc },
                    457:     [CC_OP_TADDTV] = { compute_all_add_xcc, compute_C_add_xcc },
                    458:     [CC_OP_SUB] = { compute_all_sub_xcc, compute_C_sub_xcc },
                    459:     [CC_OP_SUBX] = { compute_all_subx_xcc, compute_C_subx_xcc },
                    460:     [CC_OP_TSUB] = { compute_all_sub_xcc, compute_C_sub_xcc },
                    461:     [CC_OP_TSUBTV] = { compute_all_sub_xcc, compute_C_sub_xcc },
                    462:     [CC_OP_LOGIC] = { compute_all_logic_xcc, compute_C_logic },
                    463: };
                    464: #endif
                    465: 
                    466: void helper_compute_psr(CPUState *env)
                    467: {
                    468:     uint32_t new_psr;
                    469: 
                    470:     new_psr = icc_table[CC_OP].compute_all(env);
                    471:     env->psr = new_psr;
                    472: #ifdef TARGET_SPARC64
                    473:     new_psr = xcc_table[CC_OP].compute_all(env);
                    474:     env->xcc = new_psr;
                    475: #endif
                    476:     CC_OP = CC_OP_FLAGS;
                    477: }
                    478: 
                    479: uint32_t helper_compute_C_icc(CPUState *env)
                    480: {
                    481:     uint32_t ret;
                    482: 
                    483:     ret = icc_table[CC_OP].compute_c(env) >> PSR_CARRY_SHIFT;
                    484:     return ret;
                    485: }

unix.superglobalmegacorp.com

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