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

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
1.1.1.5   root       17:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1.1       root       18:  */
                     19: #include <assert.h>
1.1.1.5   root       20: #include <stdlib.h>
1.1       root       21: #include "exec.h"
1.1.1.4   root       22: #include "helper.h"
1.1       root       23: 
1.1.1.8 ! root       24: static void cpu_restore_state_from_retaddr(void *retaddr)
        !            25: {
        !            26:     TranslationBlock *tb;
        !            27:     unsigned long pc;
        !            28: 
        !            29:     if (retaddr) {
        !            30:         pc = (unsigned long) retaddr;
        !            31:         tb = tb_find_pc(pc);
        !            32:         if (tb) {
        !            33:             /* the PC is inside the translated code. It means that we have
        !            34:                a virtual CPU fault */
        !            35:             cpu_restore_state(tb, env, pc, NULL);
        !            36:         }
        !            37:     }
        !            38: }
        !            39: 
1.1       root       40: #ifndef CONFIG_USER_ONLY
                     41: 
                     42: #define MMUSUFFIX _mmu
                     43: 
                     44: #define SHIFT 0
                     45: #include "softmmu_template.h"
                     46: 
                     47: #define SHIFT 1
                     48: #include "softmmu_template.h"
                     49: 
                     50: #define SHIFT 2
                     51: #include "softmmu_template.h"
                     52: 
                     53: #define SHIFT 3
                     54: #include "softmmu_template.h"
                     55: 
1.1.1.3   root       56: void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
1.1       root       57: {
                     58:     CPUState *saved_env;
                     59:     int ret;
                     60: 
                     61:     /* XXX: hack to restore env in all cases, even if not called from
                     62:        generated code */
                     63:     saved_env = env;
                     64:     env = cpu_single_env;
1.1.1.3   root       65:     ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
1.1       root       66:     if (ret) {
1.1.1.8 ! root       67:         /* now we have a real cpu fault */
        !            68:         cpu_restore_state_from_retaddr(retaddr);
1.1.1.4   root       69:        cpu_loop_exit();
1.1       root       70:     }
                     71:     env = saved_env;
                     72: }
                     73: 
                     74: #endif
                     75: 
1.1.1.4   root       76: void helper_ldtlb(void)
                     77: {
                     78: #ifdef CONFIG_USER_ONLY
                     79:     /* XXXXX */
1.1.1.7   root       80:     cpu_abort(env, "Unhandled ldtlb");
1.1.1.4   root       81: #else
                     82:     cpu_load_tlb(env);
                     83: #endif
                     84: }
                     85: 
1.1.1.8 ! root       86: static inline void raise_exception(int index, void *retaddr)
1.1.1.4   root       87: {
1.1.1.8 ! root       88:     env->exception_index = index;
        !            89:     cpu_restore_state_from_retaddr(retaddr);
1.1.1.4   root       90:     cpu_loop_exit();
                     91: }
                     92: 
1.1.1.8 ! root       93: void helper_raise_illegal_instruction(void)
        !            94: {
        !            95:     raise_exception(0x180, GETPC());
        !            96: }
        !            97: 
1.1.1.4   root       98: void helper_raise_slot_illegal_instruction(void)
                     99: {
1.1.1.8 ! root      100:     raise_exception(0x1a0, GETPC());
1.1.1.4   root      101: }
                    102: 
                    103: void helper_raise_fpu_disable(void)
                    104: {
1.1.1.8 ! root      105:     raise_exception(0x800, GETPC());
1.1.1.4   root      106: }
                    107: 
                    108: void helper_raise_slot_fpu_disable(void)
                    109: {
1.1.1.8 ! root      110:     raise_exception(0x820, GETPC());
1.1.1.4   root      111: }
                    112: 
                    113: void helper_debug(void)
                    114: {
                    115:     env->exception_index = EXCP_DEBUG;
                    116:     cpu_loop_exit();
                    117: }
                    118: 
                    119: void helper_sleep(uint32_t next_pc)
                    120: {
                    121:     env->halted = 1;
                    122:     env->exception_index = EXCP_HLT;
                    123:     env->pc = next_pc;
                    124:     cpu_loop_exit();
                    125: }
                    126: 
                    127: void helper_trapa(uint32_t tra)
                    128: {
                    129:     env->tra = tra << 2;
1.1.1.8 ! root      130:     raise_exception(0x160, GETPC());
1.1.1.4   root      131: }
                    132: 
1.1.1.5   root      133: void helper_movcal(uint32_t address, uint32_t value)
                    134: {
                    135:     if (cpu_sh4_is_cached (env, address))
                    136:     {
                    137:        memory_content *r = malloc (sizeof(memory_content));
                    138:        r->address = address;
                    139:        r->value = value;
                    140:        r->next = NULL;
                    141: 
                    142:        *(env->movcal_backup_tail) = r;
                    143:        env->movcal_backup_tail = &(r->next);
                    144:     }
                    145: }
                    146: 
                    147: void helper_discard_movcal_backup(void)
                    148: {
                    149:     memory_content *current = env->movcal_backup;
                    150: 
                    151:     while(current)
                    152:     {
                    153:        memory_content *next = current->next;
                    154:        free (current);
                    155:        env->movcal_backup = current = next;
1.1.1.6   root      156:        if (current == NULL)
1.1.1.5   root      157:            env->movcal_backup_tail = &(env->movcal_backup);
                    158:     } 
                    159: }
                    160: 
                    161: void helper_ocbi(uint32_t address)
                    162: {
                    163:     memory_content **current = &(env->movcal_backup);
                    164:     while (*current)
                    165:     {
                    166:        uint32_t a = (*current)->address;
                    167:        if ((a & ~0x1F) == (address & ~0x1F))
                    168:        {
                    169:            memory_content *next = (*current)->next;
                    170:            stl(a, (*current)->value);
                    171:            
1.1.1.6   root      172:            if (next == NULL)
1.1.1.5   root      173:            {
                    174:                env->movcal_backup_tail = current;
                    175:            }
                    176: 
                    177:            free (*current);
                    178:            *current = next;
                    179:            break;
                    180:        }
                    181:     }
                    182: }
                    183: 
1.1.1.4   root      184: uint32_t helper_addc(uint32_t arg0, uint32_t arg1)
1.1       root      185: {
                    186:     uint32_t tmp0, tmp1;
                    187: 
1.1.1.4   root      188:     tmp1 = arg0 + arg1;
                    189:     tmp0 = arg1;
                    190:     arg1 = tmp1 + (env->sr & 1);
1.1       root      191:     if (tmp0 > tmp1)
                    192:        env->sr |= SR_T;
                    193:     else
                    194:        env->sr &= ~SR_T;
1.1.1.4   root      195:     if (tmp1 > arg1)
1.1       root      196:        env->sr |= SR_T;
1.1.1.4   root      197:     return arg1;
1.1       root      198: }
                    199: 
1.1.1.4   root      200: uint32_t helper_addv(uint32_t arg0, uint32_t arg1)
1.1       root      201: {
                    202:     uint32_t dest, src, ans;
                    203: 
1.1.1.4   root      204:     if ((int32_t) arg1 >= 0)
1.1       root      205:        dest = 0;
                    206:     else
                    207:        dest = 1;
1.1.1.4   root      208:     if ((int32_t) arg0 >= 0)
1.1       root      209:        src = 0;
                    210:     else
                    211:        src = 1;
                    212:     src += dest;
1.1.1.4   root      213:     arg1 += arg0;
                    214:     if ((int32_t) arg1 >= 0)
1.1       root      215:        ans = 0;
                    216:     else
                    217:        ans = 1;
                    218:     ans += dest;
                    219:     if (src == 0 || src == 2) {
                    220:        if (ans == 1)
                    221:            env->sr |= SR_T;
                    222:        else
                    223:            env->sr &= ~SR_T;
                    224:     } else
                    225:        env->sr &= ~SR_T;
1.1.1.4   root      226:     return arg1;
1.1       root      227: }
                    228: 
                    229: #define T (env->sr & SR_T)
                    230: #define Q (env->sr & SR_Q ? 1 : 0)
                    231: #define M (env->sr & SR_M ? 1 : 0)
                    232: #define SETT env->sr |= SR_T
                    233: #define CLRT env->sr &= ~SR_T
                    234: #define SETQ env->sr |= SR_Q
                    235: #define CLRQ env->sr &= ~SR_Q
                    236: #define SETM env->sr |= SR_M
                    237: #define CLRM env->sr &= ~SR_M
                    238: 
1.1.1.4   root      239: uint32_t helper_div1(uint32_t arg0, uint32_t arg1)
1.1       root      240: {
                    241:     uint32_t tmp0, tmp2;
                    242:     uint8_t old_q, tmp1 = 0xff;
                    243: 
1.1.1.4   root      244:     //printf("div1 arg0=0x%08x arg1=0x%08x M=%d Q=%d T=%d\n", arg0, arg1, M, Q, T);
1.1       root      245:     old_q = Q;
1.1.1.4   root      246:     if ((0x80000000 & arg1) != 0)
1.1       root      247:        SETQ;
                    248:     else
                    249:        CLRQ;
1.1.1.4   root      250:     tmp2 = arg0;
                    251:     arg1 <<= 1;
                    252:     arg1 |= T;
1.1       root      253:     switch (old_q) {
                    254:     case 0:
                    255:        switch (M) {
                    256:        case 0:
1.1.1.4   root      257:            tmp0 = arg1;
                    258:            arg1 -= tmp2;
                    259:            tmp1 = arg1 > tmp0;
1.1       root      260:            switch (Q) {
                    261:            case 0:
                    262:                if (tmp1)
                    263:                    SETQ;
                    264:                else
                    265:                    CLRQ;
                    266:                break;
                    267:            case 1:
                    268:                if (tmp1 == 0)
                    269:                    SETQ;
                    270:                else
                    271:                    CLRQ;
                    272:                break;
                    273:            }
                    274:            break;
                    275:        case 1:
1.1.1.4   root      276:            tmp0 = arg1;
                    277:            arg1 += tmp2;
                    278:            tmp1 = arg1 < tmp0;
1.1       root      279:            switch (Q) {
                    280:            case 0:
                    281:                if (tmp1 == 0)
                    282:                    SETQ;
                    283:                else
                    284:                    CLRQ;
                    285:                break;
                    286:            case 1:
                    287:                if (tmp1)
                    288:                    SETQ;
                    289:                else
                    290:                    CLRQ;
                    291:                break;
                    292:            }
                    293:            break;
                    294:        }
                    295:        break;
                    296:     case 1:
                    297:        switch (M) {
                    298:        case 0:
1.1.1.4   root      299:            tmp0 = arg1;
                    300:            arg1 += tmp2;
                    301:            tmp1 = arg1 < tmp0;
1.1       root      302:            switch (Q) {
                    303:            case 0:
                    304:                if (tmp1)
                    305:                    SETQ;
                    306:                else
                    307:                    CLRQ;
                    308:                break;
                    309:            case 1:
                    310:                if (tmp1 == 0)
                    311:                    SETQ;
                    312:                else
                    313:                    CLRQ;
                    314:                break;
                    315:            }
                    316:            break;
                    317:        case 1:
1.1.1.4   root      318:            tmp0 = arg1;
                    319:            arg1 -= tmp2;
                    320:            tmp1 = arg1 > tmp0;
1.1       root      321:            switch (Q) {
                    322:            case 0:
                    323:                if (tmp1 == 0)
                    324:                    SETQ;
                    325:                else
                    326:                    CLRQ;
                    327:                break;
                    328:            case 1:
                    329:                if (tmp1)
                    330:                    SETQ;
                    331:                else
                    332:                    CLRQ;
                    333:                break;
                    334:            }
                    335:            break;
                    336:        }
                    337:        break;
                    338:     }
                    339:     if (Q == M)
                    340:        SETT;
                    341:     else
                    342:        CLRT;
1.1.1.4   root      343:     //printf("Output: arg1=0x%08x M=%d Q=%d T=%d\n", arg1, M, Q, T);
                    344:     return arg1;
1.1       root      345: }
                    346: 
1.1.1.4   root      347: void helper_macl(uint32_t arg0, uint32_t arg1)
1.1       root      348: {
                    349:     int64_t res;
                    350: 
                    351:     res = ((uint64_t) env->mach << 32) | env->macl;
1.1.1.4   root      352:     res += (int64_t) (int32_t) arg0 *(int64_t) (int32_t) arg1;
1.1       root      353:     env->mach = (res >> 32) & 0xffffffff;
                    354:     env->macl = res & 0xffffffff;
                    355:     if (env->sr & SR_S) {
                    356:        if (res < 0)
                    357:            env->mach |= 0xffff0000;
                    358:        else
                    359:            env->mach &= 0x00007fff;
                    360:     }
                    361: }
                    362: 
1.1.1.4   root      363: void helper_macw(uint32_t arg0, uint32_t arg1)
1.1       root      364: {
                    365:     int64_t res;
                    366: 
                    367:     res = ((uint64_t) env->mach << 32) | env->macl;
1.1.1.4   root      368:     res += (int64_t) (int16_t) arg0 *(int64_t) (int16_t) arg1;
1.1       root      369:     env->mach = (res >> 32) & 0xffffffff;
                    370:     env->macl = res & 0xffffffff;
                    371:     if (env->sr & SR_S) {
                    372:        if (res < -0x80000000) {
                    373:            env->mach = 1;
                    374:            env->macl = 0x80000000;
                    375:        } else if (res > 0x000000007fffffff) {
                    376:            env->mach = 1;
                    377:            env->macl = 0x7fffffff;
                    378:        }
                    379:     }
                    380: }
                    381: 
1.1.1.4   root      382: uint32_t helper_subc(uint32_t arg0, uint32_t arg1)
1.1       root      383: {
                    384:     uint32_t tmp0, tmp1;
                    385: 
1.1.1.4   root      386:     tmp1 = arg1 - arg0;
                    387:     tmp0 = arg1;
                    388:     arg1 = tmp1 - (env->sr & SR_T);
1.1       root      389:     if (tmp0 < tmp1)
                    390:        env->sr |= SR_T;
                    391:     else
                    392:        env->sr &= ~SR_T;
1.1.1.4   root      393:     if (tmp1 < arg1)
1.1       root      394:        env->sr |= SR_T;
1.1.1.4   root      395:     return arg1;
1.1       root      396: }
                    397: 
1.1.1.4   root      398: uint32_t helper_subv(uint32_t arg0, uint32_t arg1)
1.1       root      399: {
                    400:     int32_t dest, src, ans;
                    401: 
1.1.1.4   root      402:     if ((int32_t) arg1 >= 0)
1.1       root      403:        dest = 0;
                    404:     else
                    405:        dest = 1;
1.1.1.4   root      406:     if ((int32_t) arg0 >= 0)
1.1       root      407:        src = 0;
                    408:     else
                    409:        src = 1;
                    410:     src += dest;
1.1.1.4   root      411:     arg1 -= arg0;
                    412:     if ((int32_t) arg1 >= 0)
1.1       root      413:        ans = 0;
                    414:     else
                    415:        ans = 1;
                    416:     ans += dest;
                    417:     if (src == 1) {
                    418:        if (ans == 1)
                    419:            env->sr |= SR_T;
                    420:        else
                    421:            env->sr &= ~SR_T;
                    422:     } else
                    423:        env->sr &= ~SR_T;
1.1.1.4   root      424:     return arg1;
1.1       root      425: }
                    426: 
1.1.1.4   root      427: static inline void set_t(void)
1.1       root      428: {
1.1.1.4   root      429:     env->sr |= SR_T;
                    430: }
1.1       root      431: 
1.1.1.4   root      432: static inline void clr_t(void)
                    433: {
                    434:     env->sr &= ~SR_T;
                    435: }
                    436: 
                    437: void helper_ld_fpscr(uint32_t val)
                    438: {
1.1.1.8 ! root      439:     env->fpscr = val & FPSCR_MASK;
        !           440:     if ((val & FPSCR_RM_MASK) == FPSCR_RM_ZERO) {
1.1.1.4   root      441:        set_float_rounding_mode(float_round_to_zero, &env->fp_status);
1.1.1.8 ! root      442:     } else {
1.1.1.4   root      443:        set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1.1.1.8 ! root      444:     }
        !           445:     set_flush_to_zero((val & FPSCR_DN) != 0, &env->fp_status);
        !           446: }
        !           447: 
        !           448: static void update_fpscr(void *retaddr)
        !           449: {
        !           450:     int xcpt, cause, enable;
        !           451: 
        !           452:     xcpt = get_float_exception_flags(&env->fp_status);
        !           453: 
        !           454:     /* Clear the flag entries */
        !           455:     env->fpscr &= ~FPSCR_FLAG_MASK;
        !           456: 
        !           457:     if (unlikely(xcpt)) {
        !           458:         if (xcpt & float_flag_invalid) {
        !           459:             env->fpscr |= FPSCR_FLAG_V;
        !           460:         }
        !           461:         if (xcpt & float_flag_divbyzero) {
        !           462:             env->fpscr |= FPSCR_FLAG_Z;
        !           463:         }
        !           464:         if (xcpt & float_flag_overflow) {
        !           465:             env->fpscr |= FPSCR_FLAG_O;
        !           466:         }
        !           467:         if (xcpt & float_flag_underflow) {
        !           468:             env->fpscr |= FPSCR_FLAG_U;
        !           469:         }
        !           470:         if (xcpt & float_flag_inexact) {
        !           471:             env->fpscr |= FPSCR_FLAG_I;
        !           472:         }
        !           473: 
        !           474:         /* Accumulate in cause entries */
        !           475:         env->fpscr |= (env->fpscr & FPSCR_FLAG_MASK)
        !           476:                       << (FPSCR_CAUSE_SHIFT - FPSCR_FLAG_SHIFT);
        !           477: 
        !           478:         /* Generate an exception if enabled */
        !           479:         cause = (env->fpscr & FPSCR_CAUSE_MASK) >> FPSCR_CAUSE_SHIFT;
        !           480:         enable = (env->fpscr & FPSCR_ENABLE_MASK) >> FPSCR_ENABLE_SHIFT;
        !           481:         if (cause & enable) {
        !           482:             cpu_restore_state_from_retaddr(retaddr);
        !           483:             env->exception_index = 0x120;
        !           484:             cpu_loop_exit();
        !           485:         }
        !           486:     }
1.1       root      487: }
                    488: 
1.1.1.4   root      489: uint32_t helper_fabs_FT(uint32_t t0)
1.1       root      490: {
1.1.1.4   root      491:     CPU_FloatU f;
                    492:     f.l = t0;
                    493:     f.f = float32_abs(f.f);
                    494:     return f.l;
                    495: }
1.1       root      496: 
1.1.1.4   root      497: uint64_t helper_fabs_DT(uint64_t t0)
                    498: {
                    499:     CPU_DoubleU d;
                    500:     d.ll = t0;
                    501:     d.d = float64_abs(d.d);
                    502:     return d.ll;
                    503: }
                    504: 
                    505: uint32_t helper_fadd_FT(uint32_t t0, uint32_t t1)
                    506: {
                    507:     CPU_FloatU f0, f1;
                    508:     f0.l = t0;
                    509:     f1.l = t1;
1.1.1.8 ! root      510:     set_float_exception_flags(0, &env->fp_status);
1.1.1.4   root      511:     f0.f = float32_add(f0.f, f1.f, &env->fp_status);
1.1.1.8 ! root      512:     update_fpscr(GETPC());
1.1.1.4   root      513:     return f0.l;
                    514: }
                    515: 
                    516: uint64_t helper_fadd_DT(uint64_t t0, uint64_t t1)
                    517: {
                    518:     CPU_DoubleU d0, d1;
                    519:     d0.ll = t0;
                    520:     d1.ll = t1;
1.1.1.8 ! root      521:     set_float_exception_flags(0, &env->fp_status);
1.1.1.4   root      522:     d0.d = float64_add(d0.d, d1.d, &env->fp_status);
1.1.1.8 ! root      523:     update_fpscr(GETPC());
1.1.1.4   root      524:     return d0.ll;
                    525: }
                    526: 
                    527: void helper_fcmp_eq_FT(uint32_t t0, uint32_t t1)
                    528: {
                    529:     CPU_FloatU f0, f1;
1.1.1.8 ! root      530:     int relation;
1.1.1.4   root      531:     f0.l = t0;
                    532:     f1.l = t1;
                    533: 
1.1.1.8 ! root      534:     set_float_exception_flags(0, &env->fp_status);
        !           535:     relation = float32_compare(f0.f, f1.f, &env->fp_status);
        !           536:     if (unlikely(relation == float_relation_unordered)) {
        !           537:         update_fpscr(GETPC());
        !           538:     } else if (relation == float_relation_equal) {
1.1.1.4   root      539:        set_t();
1.1.1.8 ! root      540:     } else {
1.1.1.4   root      541:        clr_t();
1.1.1.8 ! root      542:     }
1.1.1.4   root      543: }
                    544: 
                    545: void helper_fcmp_eq_DT(uint64_t t0, uint64_t t1)
                    546: {
                    547:     CPU_DoubleU d0, d1;
1.1.1.8 ! root      548:     int relation;
1.1.1.4   root      549:     d0.ll = t0;
                    550:     d1.ll = t1;
                    551: 
1.1.1.8 ! root      552:     set_float_exception_flags(0, &env->fp_status);
        !           553:     relation = float64_compare(d0.d, d1.d, &env->fp_status);
        !           554:     if (unlikely(relation == float_relation_unordered)) {
        !           555:         update_fpscr(GETPC());
        !           556:     } else if (relation == float_relation_equal) {
1.1.1.4   root      557:        set_t();
1.1.1.8 ! root      558:     } else {
1.1.1.4   root      559:        clr_t();
1.1.1.8 ! root      560:     }
1.1.1.4   root      561: }
                    562: 
                    563: void helper_fcmp_gt_FT(uint32_t t0, uint32_t t1)
                    564: {
                    565:     CPU_FloatU f0, f1;
1.1.1.8 ! root      566:     int relation;
1.1.1.4   root      567:     f0.l = t0;
                    568:     f1.l = t1;
                    569: 
1.1.1.8 ! root      570:     set_float_exception_flags(0, &env->fp_status);
        !           571:     relation = float32_compare(f0.f, f1.f, &env->fp_status);
        !           572:     if (unlikely(relation == float_relation_unordered)) {
        !           573:         update_fpscr(GETPC());
        !           574:     } else if (relation == float_relation_greater) {
1.1.1.4   root      575:        set_t();
1.1.1.8 ! root      576:     } else {
1.1.1.4   root      577:        clr_t();
1.1.1.8 ! root      578:     }
1.1.1.4   root      579: }
                    580: 
                    581: void helper_fcmp_gt_DT(uint64_t t0, uint64_t t1)
                    582: {
                    583:     CPU_DoubleU d0, d1;
1.1.1.8 ! root      584:     int relation;
1.1.1.4   root      585:     d0.ll = t0;
                    586:     d1.ll = t1;
                    587: 
1.1.1.8 ! root      588:     set_float_exception_flags(0, &env->fp_status);
        !           589:     relation = float64_compare(d0.d, d1.d, &env->fp_status);
        !           590:     if (unlikely(relation == float_relation_unordered)) {
        !           591:         update_fpscr(GETPC());
        !           592:     } else if (relation == float_relation_greater) {
1.1.1.4   root      593:        set_t();
1.1.1.8 ! root      594:     } else {
1.1.1.4   root      595:        clr_t();
1.1.1.8 ! root      596:     }
1.1.1.4   root      597: }
                    598: 
                    599: uint64_t helper_fcnvsd_FT_DT(uint32_t t0)
                    600: {
                    601:     CPU_DoubleU d;
                    602:     CPU_FloatU f;
                    603:     f.l = t0;
1.1.1.8 ! root      604:     set_float_exception_flags(0, &env->fp_status);
1.1.1.4   root      605:     d.d = float32_to_float64(f.f, &env->fp_status);
1.1.1.8 ! root      606:     update_fpscr(GETPC());
1.1.1.4   root      607:     return d.ll;
                    608: }
                    609: 
                    610: uint32_t helper_fcnvds_DT_FT(uint64_t t0)
                    611: {
                    612:     CPU_DoubleU d;
                    613:     CPU_FloatU f;
                    614:     d.ll = t0;
1.1.1.8 ! root      615:     set_float_exception_flags(0, &env->fp_status);
1.1.1.4   root      616:     f.f = float64_to_float32(d.d, &env->fp_status);
1.1.1.8 ! root      617:     update_fpscr(GETPC());
1.1.1.4   root      618:     return f.l;
                    619: }
                    620: 
                    621: uint32_t helper_fdiv_FT(uint32_t t0, uint32_t t1)
                    622: {
                    623:     CPU_FloatU f0, f1;
                    624:     f0.l = t0;
                    625:     f1.l = t1;
1.1.1.8 ! root      626:     set_float_exception_flags(0, &env->fp_status);
1.1.1.4   root      627:     f0.f = float32_div(f0.f, f1.f, &env->fp_status);
1.1.1.8 ! root      628:     update_fpscr(GETPC());
1.1.1.4   root      629:     return f0.l;
                    630: }
                    631: 
                    632: uint64_t helper_fdiv_DT(uint64_t t0, uint64_t t1)
                    633: {
                    634:     CPU_DoubleU d0, d1;
                    635:     d0.ll = t0;
                    636:     d1.ll = t1;
1.1.1.8 ! root      637:     set_float_exception_flags(0, &env->fp_status);
1.1.1.4   root      638:     d0.d = float64_div(d0.d, d1.d, &env->fp_status);
1.1.1.8 ! root      639:     update_fpscr(GETPC());
1.1.1.4   root      640:     return d0.ll;
                    641: }
                    642: 
                    643: uint32_t helper_float_FT(uint32_t t0)
                    644: {
                    645:     CPU_FloatU f;
1.1.1.8 ! root      646: 
        !           647:     set_float_exception_flags(0, &env->fp_status);
1.1.1.4   root      648:     f.f = int32_to_float32(t0, &env->fp_status);
1.1.1.8 ! root      649:     update_fpscr(GETPC());
        !           650: 
1.1.1.4   root      651:     return f.l;
                    652: }
                    653: 
                    654: uint64_t helper_float_DT(uint32_t t0)
                    655: {
                    656:     CPU_DoubleU d;
1.1.1.8 ! root      657:     set_float_exception_flags(0, &env->fp_status);
1.1.1.4   root      658:     d.d = int32_to_float64(t0, &env->fp_status);
1.1.1.8 ! root      659:     update_fpscr(GETPC());
1.1.1.4   root      660:     return d.ll;
                    661: }
                    662: 
                    663: uint32_t helper_fmac_FT(uint32_t t0, uint32_t t1, uint32_t t2)
                    664: {
                    665:     CPU_FloatU f0, f1, f2;
                    666:     f0.l = t0;
                    667:     f1.l = t1;
                    668:     f2.l = t2;
1.1.1.8 ! root      669:     set_float_exception_flags(0, &env->fp_status);
1.1.1.4   root      670:     f0.f = float32_mul(f0.f, f1.f, &env->fp_status);
                    671:     f0.f = float32_add(f0.f, f2.f, &env->fp_status);
1.1.1.8 ! root      672:     update_fpscr(GETPC());
        !           673: 
1.1.1.4   root      674:     return f0.l;
                    675: }
                    676: 
                    677: uint32_t helper_fmul_FT(uint32_t t0, uint32_t t1)
                    678: {
                    679:     CPU_FloatU f0, f1;
                    680:     f0.l = t0;
                    681:     f1.l = t1;
1.1.1.8 ! root      682:     set_float_exception_flags(0, &env->fp_status);
1.1.1.4   root      683:     f0.f = float32_mul(f0.f, f1.f, &env->fp_status);
1.1.1.8 ! root      684:     update_fpscr(GETPC());
1.1.1.4   root      685:     return f0.l;
                    686: }
                    687: 
                    688: uint64_t helper_fmul_DT(uint64_t t0, uint64_t t1)
                    689: {
                    690:     CPU_DoubleU d0, d1;
                    691:     d0.ll = t0;
                    692:     d1.ll = t1;
1.1.1.8 ! root      693:     set_float_exception_flags(0, &env->fp_status);
1.1.1.4   root      694:     d0.d = float64_mul(d0.d, d1.d, &env->fp_status);
1.1.1.8 ! root      695:     update_fpscr(GETPC());
        !           696: 
1.1.1.4   root      697:     return d0.ll;
                    698: }
                    699: 
                    700: uint32_t helper_fneg_T(uint32_t t0)
                    701: {
                    702:     CPU_FloatU f;
                    703:     f.l = t0;
                    704:     f.f = float32_chs(f.f);
                    705:     return f.l;
                    706: }
                    707: 
                    708: uint32_t helper_fsqrt_FT(uint32_t t0)
                    709: {
                    710:     CPU_FloatU f;
                    711:     f.l = t0;
1.1.1.8 ! root      712:     set_float_exception_flags(0, &env->fp_status);
1.1.1.4   root      713:     f.f = float32_sqrt(f.f, &env->fp_status);
1.1.1.8 ! root      714:     update_fpscr(GETPC());
1.1.1.4   root      715:     return f.l;
                    716: }
                    717: 
                    718: uint64_t helper_fsqrt_DT(uint64_t t0)
                    719: {
                    720:     CPU_DoubleU d;
                    721:     d.ll = t0;
1.1.1.8 ! root      722:     set_float_exception_flags(0, &env->fp_status);
1.1.1.4   root      723:     d.d = float64_sqrt(d.d, &env->fp_status);
1.1.1.8 ! root      724:     update_fpscr(GETPC());
1.1.1.4   root      725:     return d.ll;
                    726: }
                    727: 
                    728: uint32_t helper_fsub_FT(uint32_t t0, uint32_t t1)
                    729: {
                    730:     CPU_FloatU f0, f1;
                    731:     f0.l = t0;
                    732:     f1.l = t1;
1.1.1.8 ! root      733:     set_float_exception_flags(0, &env->fp_status);
1.1.1.4   root      734:     f0.f = float32_sub(f0.f, f1.f, &env->fp_status);
1.1.1.8 ! root      735:     update_fpscr(GETPC());
1.1.1.4   root      736:     return f0.l;
                    737: }
                    738: 
                    739: uint64_t helper_fsub_DT(uint64_t t0, uint64_t t1)
                    740: {
                    741:     CPU_DoubleU d0, d1;
1.1.1.8 ! root      742: 
1.1.1.4   root      743:     d0.ll = t0;
                    744:     d1.ll = t1;
1.1.1.8 ! root      745:     set_float_exception_flags(0, &env->fp_status);
1.1.1.4   root      746:     d0.d = float64_sub(d0.d, d1.d, &env->fp_status);
1.1.1.8 ! root      747:     update_fpscr(GETPC());
1.1.1.4   root      748:     return d0.ll;
                    749: }
                    750: 
                    751: uint32_t helper_ftrc_FT(uint32_t t0)
                    752: {
                    753:     CPU_FloatU f;
1.1.1.8 ! root      754:     uint32_t ret;
1.1.1.4   root      755:     f.l = t0;
1.1.1.8 ! root      756:     set_float_exception_flags(0, &env->fp_status);
        !           757:     ret = float32_to_int32_round_to_zero(f.f, &env->fp_status);
        !           758:     update_fpscr(GETPC());
        !           759:     return ret;
1.1.1.4   root      760: }
                    761: 
                    762: uint32_t helper_ftrc_DT(uint64_t t0)
                    763: {
                    764:     CPU_DoubleU d;
1.1.1.8 ! root      765:     uint32_t ret;
1.1.1.4   root      766:     d.ll = t0;
1.1.1.8 ! root      767:     set_float_exception_flags(0, &env->fp_status);
        !           768:     ret = float64_to_int32_round_to_zero(d.d, &env->fp_status);
        !           769:     update_fpscr(GETPC());
        !           770:     return ret;
        !           771: }
        !           772: 
        !           773: void helper_fipr(uint32_t m, uint32_t n)
        !           774: {
        !           775:     int bank, i;
        !           776:     float32 r, p;
        !           777: 
        !           778:     bank = (env->sr & FPSCR_FR) ? 16 : 0;
        !           779:     r = float32_zero;
        !           780:     set_float_exception_flags(0, &env->fp_status);
        !           781: 
        !           782:     for (i = 0 ; i < 4 ; i++) {
        !           783:         p = float32_mul(env->fregs[bank + m + i],
        !           784:                         env->fregs[bank + n + i],
        !           785:                         &env->fp_status);
        !           786:         r = float32_add(r, p, &env->fp_status);
        !           787:     }
        !           788:     update_fpscr(GETPC());
        !           789: 
        !           790:     env->fregs[bank + n + 3] = r;
        !           791: }
        !           792: 
        !           793: void helper_ftrv(uint32_t n)
        !           794: {
        !           795:     int bank_matrix, bank_vector;
        !           796:     int i, j;
        !           797:     float32 r[4];
        !           798:     float32 p;
        !           799: 
        !           800:     bank_matrix = (env->sr & FPSCR_FR) ? 0 : 16;
        !           801:     bank_vector = (env->sr & FPSCR_FR) ? 16 : 0;
        !           802:     set_float_exception_flags(0, &env->fp_status);
        !           803:     for (i = 0 ; i < 4 ; i++) {
        !           804:         r[i] = float32_zero;
        !           805:         for (j = 0 ; j < 4 ; j++) {
        !           806:             p = float32_mul(env->fregs[bank_matrix + 4 * j + i],
        !           807:                             env->fregs[bank_vector + j],
        !           808:                             &env->fp_status);
        !           809:             r[i] = float32_add(r[i], p, &env->fp_status);
        !           810:         }
        !           811:     }
        !           812:     update_fpscr(GETPC());
        !           813: 
        !           814:     for (i = 0 ; i < 4 ; i++) {
        !           815:         env->fregs[bank_vector + i] = r[i];
        !           816:     }
1.1       root      817: }

unix.superglobalmegacorp.com

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