Annotation of qemu/target-sh4/op_helper.c, revision 1.1.1.4

1.1       root        1: /*
                      2:  *  SH4 emulation
1.1.1.3   root        3:  *
1.1       root        4:  *  Copyright (c) 2005 Samuel Tardieu
                      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, write to the Free Software
1.1.1.4 ! root       18:  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
1.1       root       19:  */
                     20: #include <assert.h>
                     21: #include "exec.h"
1.1.1.4 ! root       22: #include "helper.h"
1.1       root       23: 
                     24: #ifndef CONFIG_USER_ONLY
                     25: 
                     26: #define MMUSUFFIX _mmu
                     27: 
                     28: #define SHIFT 0
                     29: #include "softmmu_template.h"
                     30: 
                     31: #define SHIFT 1
                     32: #include "softmmu_template.h"
                     33: 
                     34: #define SHIFT 2
                     35: #include "softmmu_template.h"
                     36: 
                     37: #define SHIFT 3
                     38: #include "softmmu_template.h"
                     39: 
1.1.1.3   root       40: void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
1.1       root       41: {
                     42:     TranslationBlock *tb;
                     43:     CPUState *saved_env;
                     44:     unsigned long pc;
                     45:     int ret;
                     46: 
                     47:     /* XXX: hack to restore env in all cases, even if not called from
                     48:        generated code */
                     49:     saved_env = env;
                     50:     env = cpu_single_env;
1.1.1.3   root       51:     ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
1.1       root       52:     if (ret) {
                     53:        if (retaddr) {
                     54:            /* now we have a real cpu fault */
                     55:            pc = (unsigned long) retaddr;
                     56:            tb = tb_find_pc(pc);
                     57:            if (tb) {
                     58:                /* the PC is inside the translated code. It means that we have
                     59:                   a virtual CPU fault */
                     60:                cpu_restore_state(tb, env, pc, NULL);
                     61:            }
                     62:        }
1.1.1.4 ! root       63:        cpu_loop_exit();
1.1       root       64:     }
                     65:     env = saved_env;
                     66: }
                     67: 
                     68: #endif
                     69: 
1.1.1.4 ! root       70: void helper_ldtlb(void)
        !            71: {
        !            72: #ifdef CONFIG_USER_ONLY
        !            73:     /* XXXXX */
        !            74:     assert(0);
        !            75: #else
        !            76:     cpu_load_tlb(env);
        !            77: #endif
        !            78: }
        !            79: 
        !            80: void helper_raise_illegal_instruction(void)
        !            81: {
        !            82:     env->exception_index = 0x180;
        !            83:     cpu_loop_exit();
        !            84: }
        !            85: 
        !            86: void helper_raise_slot_illegal_instruction(void)
        !            87: {
        !            88:     env->exception_index = 0x1a0;
        !            89:     cpu_loop_exit();
        !            90: }
        !            91: 
        !            92: void helper_raise_fpu_disable(void)
        !            93: {
        !            94:   env->exception_index = 0x800;
        !            95:   cpu_loop_exit();
        !            96: }
        !            97: 
        !            98: void helper_raise_slot_fpu_disable(void)
        !            99: {
        !           100:   env->exception_index = 0x820;
        !           101:   cpu_loop_exit();
        !           102: }
        !           103: 
        !           104: void helper_debug(void)
        !           105: {
        !           106:     env->exception_index = EXCP_DEBUG;
        !           107:     cpu_loop_exit();
        !           108: }
        !           109: 
        !           110: void helper_sleep(uint32_t next_pc)
        !           111: {
        !           112:     env->halted = 1;
        !           113:     env->exception_index = EXCP_HLT;
        !           114:     env->pc = next_pc;
        !           115:     cpu_loop_exit();
        !           116: }
        !           117: 
        !           118: void helper_trapa(uint32_t tra)
        !           119: {
        !           120:     env->tra = tra << 2;
        !           121:     env->exception_index = 0x160;
        !           122:     cpu_loop_exit();
        !           123: }
        !           124: 
        !           125: uint32_t helper_addc(uint32_t arg0, uint32_t arg1)
1.1       root      126: {
                    127:     uint32_t tmp0, tmp1;
                    128: 
1.1.1.4 ! root      129:     tmp1 = arg0 + arg1;
        !           130:     tmp0 = arg1;
        !           131:     arg1 = tmp1 + (env->sr & 1);
1.1       root      132:     if (tmp0 > tmp1)
                    133:        env->sr |= SR_T;
                    134:     else
                    135:        env->sr &= ~SR_T;
1.1.1.4 ! root      136:     if (tmp1 > arg1)
1.1       root      137:        env->sr |= SR_T;
1.1.1.4 ! root      138:     return arg1;
1.1       root      139: }
                    140: 
1.1.1.4 ! root      141: uint32_t helper_addv(uint32_t arg0, uint32_t arg1)
1.1       root      142: {
                    143:     uint32_t dest, src, ans;
                    144: 
1.1.1.4 ! root      145:     if ((int32_t) arg1 >= 0)
1.1       root      146:        dest = 0;
                    147:     else
                    148:        dest = 1;
1.1.1.4 ! root      149:     if ((int32_t) arg0 >= 0)
1.1       root      150:        src = 0;
                    151:     else
                    152:        src = 1;
                    153:     src += dest;
1.1.1.4 ! root      154:     arg1 += arg0;
        !           155:     if ((int32_t) arg1 >= 0)
1.1       root      156:        ans = 0;
                    157:     else
                    158:        ans = 1;
                    159:     ans += dest;
                    160:     if (src == 0 || src == 2) {
                    161:        if (ans == 1)
                    162:            env->sr |= SR_T;
                    163:        else
                    164:            env->sr &= ~SR_T;
                    165:     } else
                    166:        env->sr &= ~SR_T;
1.1.1.4 ! root      167:     return arg1;
1.1       root      168: }
                    169: 
                    170: #define T (env->sr & SR_T)
                    171: #define Q (env->sr & SR_Q ? 1 : 0)
                    172: #define M (env->sr & SR_M ? 1 : 0)
                    173: #define SETT env->sr |= SR_T
                    174: #define CLRT env->sr &= ~SR_T
                    175: #define SETQ env->sr |= SR_Q
                    176: #define CLRQ env->sr &= ~SR_Q
                    177: #define SETM env->sr |= SR_M
                    178: #define CLRM env->sr &= ~SR_M
                    179: 
1.1.1.4 ! root      180: uint32_t helper_div1(uint32_t arg0, uint32_t arg1)
1.1       root      181: {
                    182:     uint32_t tmp0, tmp2;
                    183:     uint8_t old_q, tmp1 = 0xff;
                    184: 
1.1.1.4 ! root      185:     //printf("div1 arg0=0x%08x arg1=0x%08x M=%d Q=%d T=%d\n", arg0, arg1, M, Q, T);
1.1       root      186:     old_q = Q;
1.1.1.4 ! root      187:     if ((0x80000000 & arg1) != 0)
1.1       root      188:        SETQ;
                    189:     else
                    190:        CLRQ;
1.1.1.4 ! root      191:     tmp2 = arg0;
        !           192:     arg1 <<= 1;
        !           193:     arg1 |= T;
1.1       root      194:     switch (old_q) {
                    195:     case 0:
                    196:        switch (M) {
                    197:        case 0:
1.1.1.4 ! root      198:            tmp0 = arg1;
        !           199:            arg1 -= tmp2;
        !           200:            tmp1 = arg1 > tmp0;
1.1       root      201:            switch (Q) {
                    202:            case 0:
                    203:                if (tmp1)
                    204:                    SETQ;
                    205:                else
                    206:                    CLRQ;
                    207:                break;
                    208:            case 1:
                    209:                if (tmp1 == 0)
                    210:                    SETQ;
                    211:                else
                    212:                    CLRQ;
                    213:                break;
                    214:            }
                    215:            break;
                    216:        case 1:
1.1.1.4 ! root      217:            tmp0 = arg1;
        !           218:            arg1 += tmp2;
        !           219:            tmp1 = arg1 < tmp0;
1.1       root      220:            switch (Q) {
                    221:            case 0:
                    222:                if (tmp1 == 0)
                    223:                    SETQ;
                    224:                else
                    225:                    CLRQ;
                    226:                break;
                    227:            case 1:
                    228:                if (tmp1)
                    229:                    SETQ;
                    230:                else
                    231:                    CLRQ;
                    232:                break;
                    233:            }
                    234:            break;
                    235:        }
                    236:        break;
                    237:     case 1:
                    238:        switch (M) {
                    239:        case 0:
1.1.1.4 ! root      240:            tmp0 = arg1;
        !           241:            arg1 += tmp2;
        !           242:            tmp1 = arg1 < tmp0;
1.1       root      243:            switch (Q) {
                    244:            case 0:
                    245:                if (tmp1)
                    246:                    SETQ;
                    247:                else
                    248:                    CLRQ;
                    249:                break;
                    250:            case 1:
                    251:                if (tmp1 == 0)
                    252:                    SETQ;
                    253:                else
                    254:                    CLRQ;
                    255:                break;
                    256:            }
                    257:            break;
                    258:        case 1:
1.1.1.4 ! root      259:            tmp0 = arg1;
        !           260:            arg1 -= tmp2;
        !           261:            tmp1 = arg1 > tmp0;
1.1       root      262:            switch (Q) {
                    263:            case 0:
                    264:                if (tmp1 == 0)
                    265:                    SETQ;
                    266:                else
                    267:                    CLRQ;
                    268:                break;
                    269:            case 1:
                    270:                if (tmp1)
                    271:                    SETQ;
                    272:                else
                    273:                    CLRQ;
                    274:                break;
                    275:            }
                    276:            break;
                    277:        }
                    278:        break;
                    279:     }
                    280:     if (Q == M)
                    281:        SETT;
                    282:     else
                    283:        CLRT;
1.1.1.4 ! root      284:     //printf("Output: arg1=0x%08x M=%d Q=%d T=%d\n", arg1, M, Q, T);
        !           285:     return arg1;
1.1       root      286: }
                    287: 
1.1.1.4 ! root      288: void helper_macl(uint32_t arg0, uint32_t arg1)
1.1       root      289: {
                    290:     int64_t res;
                    291: 
                    292:     res = ((uint64_t) env->mach << 32) | env->macl;
1.1.1.4 ! root      293:     res += (int64_t) (int32_t) arg0 *(int64_t) (int32_t) arg1;
1.1       root      294:     env->mach = (res >> 32) & 0xffffffff;
                    295:     env->macl = res & 0xffffffff;
                    296:     if (env->sr & SR_S) {
                    297:        if (res < 0)
                    298:            env->mach |= 0xffff0000;
                    299:        else
                    300:            env->mach &= 0x00007fff;
                    301:     }
                    302: }
                    303: 
1.1.1.4 ! root      304: void helper_macw(uint32_t arg0, uint32_t arg1)
1.1       root      305: {
                    306:     int64_t res;
                    307: 
                    308:     res = ((uint64_t) env->mach << 32) | env->macl;
1.1.1.4 ! root      309:     res += (int64_t) (int16_t) arg0 *(int64_t) (int16_t) arg1;
1.1       root      310:     env->mach = (res >> 32) & 0xffffffff;
                    311:     env->macl = res & 0xffffffff;
                    312:     if (env->sr & SR_S) {
                    313:        if (res < -0x80000000) {
                    314:            env->mach = 1;
                    315:            env->macl = 0x80000000;
                    316:        } else if (res > 0x000000007fffffff) {
                    317:            env->mach = 1;
                    318:            env->macl = 0x7fffffff;
                    319:        }
                    320:     }
                    321: }
                    322: 
1.1.1.4 ! root      323: uint32_t helper_negc(uint32_t arg)
1.1       root      324: {
                    325:     uint32_t temp;
                    326: 
1.1.1.4 ! root      327:     temp = -arg;
        !           328:     arg = temp - (env->sr & SR_T);
1.1       root      329:     if (0 < temp)
                    330:        env->sr |= SR_T;
                    331:     else
                    332:        env->sr &= ~SR_T;
1.1.1.4 ! root      333:     if (temp < arg)
1.1       root      334:        env->sr |= SR_T;
1.1.1.4 ! root      335:     return arg;
1.1       root      336: }
                    337: 
1.1.1.4 ! root      338: uint32_t helper_subc(uint32_t arg0, uint32_t arg1)
1.1       root      339: {
                    340:     uint32_t tmp0, tmp1;
                    341: 
1.1.1.4 ! root      342:     tmp1 = arg1 - arg0;
        !           343:     tmp0 = arg1;
        !           344:     arg1 = tmp1 - (env->sr & SR_T);
1.1       root      345:     if (tmp0 < tmp1)
                    346:        env->sr |= SR_T;
                    347:     else
                    348:        env->sr &= ~SR_T;
1.1.1.4 ! root      349:     if (tmp1 < arg1)
1.1       root      350:        env->sr |= SR_T;
1.1.1.4 ! root      351:     return arg1;
1.1       root      352: }
                    353: 
1.1.1.4 ! root      354: uint32_t helper_subv(uint32_t arg0, uint32_t arg1)
1.1       root      355: {
                    356:     int32_t dest, src, ans;
                    357: 
1.1.1.4 ! root      358:     if ((int32_t) arg1 >= 0)
1.1       root      359:        dest = 0;
                    360:     else
                    361:        dest = 1;
1.1.1.4 ! root      362:     if ((int32_t) arg0 >= 0)
1.1       root      363:        src = 0;
                    364:     else
                    365:        src = 1;
                    366:     src += dest;
1.1.1.4 ! root      367:     arg1 -= arg0;
        !           368:     if ((int32_t) arg1 >= 0)
1.1       root      369:        ans = 0;
                    370:     else
                    371:        ans = 1;
                    372:     ans += dest;
                    373:     if (src == 1) {
                    374:        if (ans == 1)
                    375:            env->sr |= SR_T;
                    376:        else
                    377:            env->sr &= ~SR_T;
                    378:     } else
                    379:        env->sr &= ~SR_T;
1.1.1.4 ! root      380:     return arg1;
1.1       root      381: }
                    382: 
1.1.1.4 ! root      383: static inline void set_t(void)
1.1       root      384: {
1.1.1.4 ! root      385:     env->sr |= SR_T;
        !           386: }
1.1       root      387: 
1.1.1.4 ! root      388: static inline void clr_t(void)
        !           389: {
        !           390:     env->sr &= ~SR_T;
        !           391: }
        !           392: 
        !           393: void helper_ld_fpscr(uint32_t val)
        !           394: {
        !           395:     env->fpscr = val & 0x003fffff;
        !           396:     if (val & 0x01)
        !           397:        set_float_rounding_mode(float_round_to_zero, &env->fp_status);
1.1       root      398:     else
1.1.1.4 ! root      399:        set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1.1       root      400: }
                    401: 
1.1.1.4 ! root      402: uint32_t helper_fabs_FT(uint32_t t0)
1.1       root      403: {
1.1.1.4 ! root      404:     CPU_FloatU f;
        !           405:     f.l = t0;
        !           406:     f.f = float32_abs(f.f);
        !           407:     return f.l;
        !           408: }
1.1       root      409: 
1.1.1.4 ! root      410: uint64_t helper_fabs_DT(uint64_t t0)
        !           411: {
        !           412:     CPU_DoubleU d;
        !           413:     d.ll = t0;
        !           414:     d.d = float64_abs(d.d);
        !           415:     return d.ll;
        !           416: }
        !           417: 
        !           418: uint32_t helper_fadd_FT(uint32_t t0, uint32_t t1)
        !           419: {
        !           420:     CPU_FloatU f0, f1;
        !           421:     f0.l = t0;
        !           422:     f1.l = t1;
        !           423:     f0.f = float32_add(f0.f, f1.f, &env->fp_status);
        !           424:     return f0.l;
        !           425: }
        !           426: 
        !           427: uint64_t helper_fadd_DT(uint64_t t0, uint64_t t1)
        !           428: {
        !           429:     CPU_DoubleU d0, d1;
        !           430:     d0.ll = t0;
        !           431:     d1.ll = t1;
        !           432:     d0.d = float64_add(d0.d, d1.d, &env->fp_status);
        !           433:     return d0.ll;
        !           434: }
        !           435: 
        !           436: void helper_fcmp_eq_FT(uint32_t t0, uint32_t t1)
        !           437: {
        !           438:     CPU_FloatU f0, f1;
        !           439:     f0.l = t0;
        !           440:     f1.l = t1;
        !           441: 
        !           442:     if (float32_compare(f0.f, f1.f, &env->fp_status) == 0)
        !           443:        set_t();
1.1       root      444:     else
1.1.1.4 ! root      445:        clr_t();
        !           446: }
        !           447: 
        !           448: void helper_fcmp_eq_DT(uint64_t t0, uint64_t t1)
        !           449: {
        !           450:     CPU_DoubleU d0, d1;
        !           451:     d0.ll = t0;
        !           452:     d1.ll = t1;
        !           453: 
        !           454:     if (float64_compare(d0.d, d1.d, &env->fp_status) == 0)
        !           455:        set_t();
        !           456:     else
        !           457:        clr_t();
        !           458: }
        !           459: 
        !           460: void helper_fcmp_gt_FT(uint32_t t0, uint32_t t1)
        !           461: {
        !           462:     CPU_FloatU f0, f1;
        !           463:     f0.l = t0;
        !           464:     f1.l = t1;
        !           465: 
        !           466:     if (float32_compare(f0.f, f1.f, &env->fp_status) == 1)
        !           467:        set_t();
        !           468:     else
        !           469:        clr_t();
        !           470: }
        !           471: 
        !           472: void helper_fcmp_gt_DT(uint64_t t0, uint64_t t1)
        !           473: {
        !           474:     CPU_DoubleU d0, d1;
        !           475:     d0.ll = t0;
        !           476:     d1.ll = t1;
        !           477: 
        !           478:     if (float64_compare(d0.d, d1.d, &env->fp_status) == 1)
        !           479:        set_t();
        !           480:     else
        !           481:        clr_t();
        !           482: }
        !           483: 
        !           484: uint64_t helper_fcnvsd_FT_DT(uint32_t t0)
        !           485: {
        !           486:     CPU_DoubleU d;
        !           487:     CPU_FloatU f;
        !           488:     f.l = t0;
        !           489:     d.d = float32_to_float64(f.f, &env->fp_status);
        !           490:     return d.ll;
        !           491: }
        !           492: 
        !           493: uint32_t helper_fcnvds_DT_FT(uint64_t t0)
        !           494: {
        !           495:     CPU_DoubleU d;
        !           496:     CPU_FloatU f;
        !           497:     d.ll = t0;
        !           498:     f.f = float64_to_float32(d.d, &env->fp_status);
        !           499:     return f.l;
        !           500: }
        !           501: 
        !           502: uint32_t helper_fdiv_FT(uint32_t t0, uint32_t t1)
        !           503: {
        !           504:     CPU_FloatU f0, f1;
        !           505:     f0.l = t0;
        !           506:     f1.l = t1;
        !           507:     f0.f = float32_div(f0.f, f1.f, &env->fp_status);
        !           508:     return f0.l;
        !           509: }
        !           510: 
        !           511: uint64_t helper_fdiv_DT(uint64_t t0, uint64_t t1)
        !           512: {
        !           513:     CPU_DoubleU d0, d1;
        !           514:     d0.ll = t0;
        !           515:     d1.ll = t1;
        !           516:     d0.d = float64_div(d0.d, d1.d, &env->fp_status);
        !           517:     return d0.ll;
        !           518: }
        !           519: 
        !           520: uint32_t helper_float_FT(uint32_t t0)
        !           521: {
        !           522:     CPU_FloatU f;
        !           523:     f.f = int32_to_float32(t0, &env->fp_status);
        !           524:     return f.l;
        !           525: }
        !           526: 
        !           527: uint64_t helper_float_DT(uint32_t t0)
        !           528: {
        !           529:     CPU_DoubleU d;
        !           530:     d.d = int32_to_float64(t0, &env->fp_status);
        !           531:     return d.ll;
        !           532: }
        !           533: 
        !           534: uint32_t helper_fmac_FT(uint32_t t0, uint32_t t1, uint32_t t2)
        !           535: {
        !           536:     CPU_FloatU f0, f1, f2;
        !           537:     f0.l = t0;
        !           538:     f1.l = t1;
        !           539:     f2.l = t2;
        !           540:     f0.f = float32_mul(f0.f, f1.f, &env->fp_status);
        !           541:     f0.f = float32_add(f0.f, f2.f, &env->fp_status);
        !           542:     return f0.l;
        !           543: }
        !           544: 
        !           545: uint32_t helper_fmul_FT(uint32_t t0, uint32_t t1)
        !           546: {
        !           547:     CPU_FloatU f0, f1;
        !           548:     f0.l = t0;
        !           549:     f1.l = t1;
        !           550:     f0.f = float32_mul(f0.f, f1.f, &env->fp_status);
        !           551:     return f0.l;
        !           552: }
        !           553: 
        !           554: uint64_t helper_fmul_DT(uint64_t t0, uint64_t t1)
        !           555: {
        !           556:     CPU_DoubleU d0, d1;
        !           557:     d0.ll = t0;
        !           558:     d1.ll = t1;
        !           559:     d0.d = float64_mul(d0.d, d1.d, &env->fp_status);
        !           560:     return d0.ll;
        !           561: }
        !           562: 
        !           563: uint32_t helper_fneg_T(uint32_t t0)
        !           564: {
        !           565:     CPU_FloatU f;
        !           566:     f.l = t0;
        !           567:     f.f = float32_chs(f.f);
        !           568:     return f.l;
        !           569: }
        !           570: 
        !           571: uint32_t helper_fsqrt_FT(uint32_t t0)
        !           572: {
        !           573:     CPU_FloatU f;
        !           574:     f.l = t0;
        !           575:     f.f = float32_sqrt(f.f, &env->fp_status);
        !           576:     return f.l;
        !           577: }
        !           578: 
        !           579: uint64_t helper_fsqrt_DT(uint64_t t0)
        !           580: {
        !           581:     CPU_DoubleU d;
        !           582:     d.ll = t0;
        !           583:     d.d = float64_sqrt(d.d, &env->fp_status);
        !           584:     return d.ll;
        !           585: }
        !           586: 
        !           587: uint32_t helper_fsub_FT(uint32_t t0, uint32_t t1)
        !           588: {
        !           589:     CPU_FloatU f0, f1;
        !           590:     f0.l = t0;
        !           591:     f1.l = t1;
        !           592:     f0.f = float32_sub(f0.f, f1.f, &env->fp_status);
        !           593:     return f0.l;
        !           594: }
        !           595: 
        !           596: uint64_t helper_fsub_DT(uint64_t t0, uint64_t t1)
        !           597: {
        !           598:     CPU_DoubleU d0, d1;
        !           599:     d0.ll = t0;
        !           600:     d1.ll = t1;
        !           601:     d0.d = float64_sub(d0.d, d1.d, &env->fp_status);
        !           602:     return d0.ll;
        !           603: }
        !           604: 
        !           605: uint32_t helper_ftrc_FT(uint32_t t0)
        !           606: {
        !           607:     CPU_FloatU f;
        !           608:     f.l = t0;
        !           609:     return float32_to_int32_round_to_zero(f.f, &env->fp_status);
        !           610: }
        !           611: 
        !           612: uint32_t helper_ftrc_DT(uint64_t t0)
        !           613: {
        !           614:     CPU_DoubleU d;
        !           615:     d.ll = t0;
        !           616:     return float64_to_int32_round_to_zero(d.d, &env->fp_status);
1.1       root      617: }

unix.superglobalmegacorp.com

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