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

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.1.10  root       21: #include "cpu.h"
                     22: #include "dyngen-exec.h"
1.1.1.4   root       23: #include "helper.h"
1.1       root       24: 
1.1.1.11! root       25: static void cpu_restore_state_from_retaddr(uintptr_t retaddr)
1.1.1.8   root       26: {
                     27:     TranslationBlock *tb;
                     28: 
                     29:     if (retaddr) {
1.1.1.11! root       30:         tb = tb_find_pc(retaddr);
1.1.1.8   root       31:         if (tb) {
                     32:             /* the PC is inside the translated code. It means that we have
                     33:                a virtual CPU fault */
1.1.1.11! root       34:             cpu_restore_state(tb, env, retaddr);
1.1.1.8   root       35:         }
                     36:     }
                     37: }
                     38: 
1.1       root       39: #ifndef CONFIG_USER_ONLY
1.1.1.10  root       40: #include "softmmu_exec.h"
1.1       root       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.11! root       56: void tlb_fill(CPUSH4State *env1, target_ulong addr, int is_write, int mmu_idx,
        !            57:               uintptr_t retaddr)
1.1       root       58: {
1.1.1.11! root       59:     CPUSH4State *saved_env;
1.1       root       60:     int ret;
                     61: 
                     62:     saved_env = env;
1.1.1.10  root       63:     env = env1;
                     64:     ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx);
1.1       root       65:     if (ret) {
1.1.1.8   root       66:         /* now we have a real cpu fault */
                     67:         cpu_restore_state_from_retaddr(retaddr);
1.1.1.9   root       68:         cpu_loop_exit(env);
1.1       root       69:     }
                     70:     env = saved_env;
                     71: }
                     72: 
                     73: #endif
                     74: 
1.1.1.4   root       75: void helper_ldtlb(void)
                     76: {
                     77: #ifdef CONFIG_USER_ONLY
                     78:     /* XXXXX */
1.1.1.7   root       79:     cpu_abort(env, "Unhandled ldtlb");
1.1.1.4   root       80: #else
                     81:     cpu_load_tlb(env);
                     82: #endif
                     83: }
                     84: 
1.1.1.11! root       85: static inline void raise_exception(int index, uintptr_t retaddr)
1.1.1.4   root       86: {
1.1.1.8   root       87:     env->exception_index = index;
                     88:     cpu_restore_state_from_retaddr(retaddr);
1.1.1.9   root       89:     cpu_loop_exit(env);
1.1.1.4   root       90: }
                     91: 
1.1.1.8   root       92: void helper_raise_illegal_instruction(void)
                     93: {
                     94:     raise_exception(0x180, GETPC());
                     95: }
                     96: 
1.1.1.4   root       97: void helper_raise_slot_illegal_instruction(void)
                     98: {
1.1.1.8   root       99:     raise_exception(0x1a0, GETPC());
1.1.1.4   root      100: }
                    101: 
                    102: void helper_raise_fpu_disable(void)
                    103: {
1.1.1.8   root      104:     raise_exception(0x800, GETPC());
1.1.1.4   root      105: }
                    106: 
                    107: void helper_raise_slot_fpu_disable(void)
                    108: {
1.1.1.8   root      109:     raise_exception(0x820, GETPC());
1.1.1.4   root      110: }
                    111: 
                    112: void helper_debug(void)
                    113: {
                    114:     env->exception_index = EXCP_DEBUG;
1.1.1.9   root      115:     cpu_loop_exit(env);
1.1.1.4   root      116: }
                    117: 
                    118: void helper_sleep(uint32_t next_pc)
                    119: {
                    120:     env->halted = 1;
1.1.1.9   root      121:     env->in_sleep = 1;
1.1.1.4   root      122:     env->exception_index = EXCP_HLT;
                    123:     env->pc = next_pc;
1.1.1.9   root      124:     cpu_loop_exit(env);
1.1.1.4   root      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: 
1.1.1.11! root      448: static void update_fpscr(uintptr_t retaddr)
1.1.1.8   root      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;
1.1.1.9   root      484:             cpu_loop_exit(env);
1.1.1.8   root      485:         }
                    486:     }
1.1       root      487: }
                    488: 
1.1.1.9   root      489: float32 helper_fabs_FT(float32 t0)
1.1       root      490: {
1.1.1.9   root      491:     return float32_abs(t0);
1.1.1.4   root      492: }
1.1       root      493: 
1.1.1.9   root      494: float64 helper_fabs_DT(float64 t0)
1.1.1.4   root      495: {
1.1.1.9   root      496:     return float64_abs(t0);
1.1.1.4   root      497: }
                    498: 
1.1.1.9   root      499: float32 helper_fadd_FT(float32 t0, float32 t1)
1.1.1.4   root      500: {
1.1.1.8   root      501:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      502:     t0 = float32_add(t0, t1, &env->fp_status);
1.1.1.8   root      503:     update_fpscr(GETPC());
1.1.1.9   root      504:     return t0;
1.1.1.4   root      505: }
                    506: 
1.1.1.9   root      507: float64 helper_fadd_DT(float64 t0, float64 t1)
1.1.1.4   root      508: {
1.1.1.8   root      509:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      510:     t0 = float64_add(t0, t1, &env->fp_status);
1.1.1.8   root      511:     update_fpscr(GETPC());
1.1.1.9   root      512:     return t0;
1.1.1.4   root      513: }
                    514: 
1.1.1.9   root      515: void helper_fcmp_eq_FT(float32 t0, float32 t1)
1.1.1.4   root      516: {
1.1.1.8   root      517:     int relation;
1.1.1.4   root      518: 
1.1.1.8   root      519:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      520:     relation = float32_compare(t0, t1, &env->fp_status);
1.1.1.8   root      521:     if (unlikely(relation == float_relation_unordered)) {
                    522:         update_fpscr(GETPC());
                    523:     } else if (relation == float_relation_equal) {
1.1.1.4   root      524:        set_t();
1.1.1.8   root      525:     } else {
1.1.1.4   root      526:        clr_t();
1.1.1.8   root      527:     }
1.1.1.4   root      528: }
                    529: 
1.1.1.9   root      530: void helper_fcmp_eq_DT(float64 t0, float64 t1)
1.1.1.4   root      531: {
1.1.1.8   root      532:     int relation;
1.1.1.4   root      533: 
1.1.1.8   root      534:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      535:     relation = float64_compare(t0, t1, &env->fp_status);
1.1.1.8   root      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: 
1.1.1.9   root      545: void helper_fcmp_gt_FT(float32 t0, float32 t1)
1.1.1.4   root      546: {
1.1.1.8   root      547:     int relation;
1.1.1.4   root      548: 
1.1.1.8   root      549:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      550:     relation = float32_compare(t0, t1, &env->fp_status);
1.1.1.8   root      551:     if (unlikely(relation == float_relation_unordered)) {
                    552:         update_fpscr(GETPC());
                    553:     } else if (relation == float_relation_greater) {
1.1.1.4   root      554:        set_t();
1.1.1.8   root      555:     } else {
1.1.1.4   root      556:        clr_t();
1.1.1.8   root      557:     }
1.1.1.4   root      558: }
                    559: 
1.1.1.9   root      560: void helper_fcmp_gt_DT(float64 t0, float64 t1)
1.1.1.4   root      561: {
1.1.1.8   root      562:     int relation;
1.1.1.4   root      563: 
1.1.1.8   root      564:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      565:     relation = float64_compare(t0, t1, &env->fp_status);
1.1.1.8   root      566:     if (unlikely(relation == float_relation_unordered)) {
                    567:         update_fpscr(GETPC());
                    568:     } else if (relation == float_relation_greater) {
1.1.1.4   root      569:        set_t();
1.1.1.8   root      570:     } else {
1.1.1.4   root      571:        clr_t();
1.1.1.8   root      572:     }
1.1.1.4   root      573: }
                    574: 
1.1.1.9   root      575: float64 helper_fcnvsd_FT_DT(float32 t0)
1.1.1.4   root      576: {
1.1.1.9   root      577:     float64 ret;
1.1.1.8   root      578:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      579:     ret = float32_to_float64(t0, &env->fp_status);
1.1.1.8   root      580:     update_fpscr(GETPC());
1.1.1.9   root      581:     return ret;
1.1.1.4   root      582: }
                    583: 
1.1.1.9   root      584: float32 helper_fcnvds_DT_FT(float64 t0)
1.1.1.4   root      585: {
1.1.1.9   root      586:     float32 ret;
1.1.1.8   root      587:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      588:     ret = float64_to_float32(t0, &env->fp_status);
1.1.1.8   root      589:     update_fpscr(GETPC());
1.1.1.9   root      590:     return ret;
1.1.1.4   root      591: }
                    592: 
1.1.1.9   root      593: float32 helper_fdiv_FT(float32 t0, float32 t1)
1.1.1.4   root      594: {
1.1.1.8   root      595:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      596:     t0 = float32_div(t0, t1, &env->fp_status);
1.1.1.8   root      597:     update_fpscr(GETPC());
1.1.1.9   root      598:     return t0;
1.1.1.4   root      599: }
                    600: 
1.1.1.9   root      601: float64 helper_fdiv_DT(float64 t0, float64 t1)
1.1.1.4   root      602: {
1.1.1.8   root      603:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      604:     t0 = float64_div(t0, t1, &env->fp_status);
1.1.1.8   root      605:     update_fpscr(GETPC());
1.1.1.9   root      606:     return t0;
1.1.1.4   root      607: }
                    608: 
1.1.1.9   root      609: float32 helper_float_FT(uint32_t t0)
1.1.1.4   root      610: {
1.1.1.9   root      611:     float32 ret;
1.1.1.8   root      612:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      613:     ret = int32_to_float32(t0, &env->fp_status);
1.1.1.8   root      614:     update_fpscr(GETPC());
1.1.1.9   root      615:     return ret;
1.1.1.4   root      616: }
                    617: 
1.1.1.9   root      618: float64 helper_float_DT(uint32_t t0)
1.1.1.4   root      619: {
1.1.1.9   root      620:     float64 ret;
1.1.1.8   root      621:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      622:     ret = int32_to_float64(t0, &env->fp_status);
1.1.1.8   root      623:     update_fpscr(GETPC());
1.1.1.9   root      624:     return ret;
1.1.1.4   root      625: }
                    626: 
1.1.1.9   root      627: float32 helper_fmac_FT(float32 t0, float32 t1, float32 t2)
1.1.1.4   root      628: {
1.1.1.8   root      629:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      630:     t0 = float32_mul(t0, t1, &env->fp_status);
                    631:     t0 = float32_add(t0, t2, &env->fp_status);
1.1.1.8   root      632:     update_fpscr(GETPC());
1.1.1.9   root      633:     return t0;
1.1.1.4   root      634: }
                    635: 
1.1.1.9   root      636: float32 helper_fmul_FT(float32 t0, float32 t1)
1.1.1.4   root      637: {
1.1.1.8   root      638:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      639:     t0 = float32_mul(t0, t1, &env->fp_status);
1.1.1.8   root      640:     update_fpscr(GETPC());
1.1.1.9   root      641:     return t0;
1.1.1.4   root      642: }
                    643: 
1.1.1.9   root      644: float64 helper_fmul_DT(float64 t0, float64 t1)
1.1.1.4   root      645: {
1.1.1.8   root      646:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      647:     t0 = float64_mul(t0, t1, &env->fp_status);
1.1.1.8   root      648:     update_fpscr(GETPC());
1.1.1.9   root      649:     return t0;
1.1.1.4   root      650: }
                    651: 
1.1.1.9   root      652: float32 helper_fneg_T(float32 t0)
1.1.1.4   root      653: {
1.1.1.9   root      654:     return float32_chs(t0);
1.1.1.4   root      655: }
                    656: 
1.1.1.9   root      657: float32 helper_fsqrt_FT(float32 t0)
1.1.1.4   root      658: {
1.1.1.8   root      659:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      660:     t0 = float32_sqrt(t0, &env->fp_status);
1.1.1.8   root      661:     update_fpscr(GETPC());
1.1.1.9   root      662:     return t0;
1.1.1.4   root      663: }
                    664: 
1.1.1.9   root      665: float64 helper_fsqrt_DT(float64 t0)
1.1.1.4   root      666: {
1.1.1.8   root      667:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      668:     t0 = float64_sqrt(t0, &env->fp_status);
1.1.1.8   root      669:     update_fpscr(GETPC());
1.1.1.9   root      670:     return t0;
1.1.1.4   root      671: }
                    672: 
1.1.1.9   root      673: float32 helper_fsub_FT(float32 t0, float32 t1)
1.1.1.4   root      674: {
1.1.1.8   root      675:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      676:     t0 = float32_sub(t0, t1, &env->fp_status);
1.1.1.8   root      677:     update_fpscr(GETPC());
1.1.1.9   root      678:     return t0;
1.1.1.4   root      679: }
                    680: 
1.1.1.9   root      681: float64 helper_fsub_DT(float64 t0, float64 t1)
1.1.1.4   root      682: {
1.1.1.8   root      683:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      684:     t0 = float64_sub(t0, t1, &env->fp_status);
1.1.1.8   root      685:     update_fpscr(GETPC());
1.1.1.9   root      686:     return t0;
1.1.1.4   root      687: }
                    688: 
1.1.1.9   root      689: uint32_t helper_ftrc_FT(float32 t0)
1.1.1.4   root      690: {
1.1.1.8   root      691:     uint32_t ret;
                    692:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      693:     ret = float32_to_int32_round_to_zero(t0, &env->fp_status);
1.1.1.8   root      694:     update_fpscr(GETPC());
                    695:     return ret;
1.1.1.4   root      696: }
                    697: 
1.1.1.9   root      698: uint32_t helper_ftrc_DT(float64 t0)
1.1.1.4   root      699: {
1.1.1.8   root      700:     uint32_t ret;
                    701:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9   root      702:     ret = float64_to_int32_round_to_zero(t0, &env->fp_status);
1.1.1.8   root      703:     update_fpscr(GETPC());
                    704:     return ret;
                    705: }
                    706: 
                    707: void helper_fipr(uint32_t m, uint32_t n)
                    708: {
                    709:     int bank, i;
                    710:     float32 r, p;
                    711: 
                    712:     bank = (env->sr & FPSCR_FR) ? 16 : 0;
                    713:     r = float32_zero;
                    714:     set_float_exception_flags(0, &env->fp_status);
                    715: 
                    716:     for (i = 0 ; i < 4 ; i++) {
                    717:         p = float32_mul(env->fregs[bank + m + i],
                    718:                         env->fregs[bank + n + i],
                    719:                         &env->fp_status);
                    720:         r = float32_add(r, p, &env->fp_status);
                    721:     }
                    722:     update_fpscr(GETPC());
                    723: 
                    724:     env->fregs[bank + n + 3] = r;
                    725: }
                    726: 
                    727: void helper_ftrv(uint32_t n)
                    728: {
                    729:     int bank_matrix, bank_vector;
                    730:     int i, j;
                    731:     float32 r[4];
                    732:     float32 p;
                    733: 
                    734:     bank_matrix = (env->sr & FPSCR_FR) ? 0 : 16;
                    735:     bank_vector = (env->sr & FPSCR_FR) ? 16 : 0;
                    736:     set_float_exception_flags(0, &env->fp_status);
                    737:     for (i = 0 ; i < 4 ; i++) {
                    738:         r[i] = float32_zero;
                    739:         for (j = 0 ; j < 4 ; j++) {
                    740:             p = float32_mul(env->fregs[bank_matrix + 4 * j + i],
                    741:                             env->fregs[bank_vector + j],
                    742:                             &env->fp_status);
                    743:             r[i] = float32_add(r[i], p, &env->fp_status);
                    744:         }
                    745:     }
                    746:     update_fpscr(GETPC());
                    747: 
                    748:     for (i = 0 ; i < 4 ; i++) {
                    749:         env->fregs[bank_vector + i] = r[i];
                    750:     }
1.1       root      751: }

unix.superglobalmegacorp.com

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