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

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 */
1.1.1.9 ! root       35:             cpu_restore_state(tb, env, pc);
1.1.1.8   root       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.9 ! root       69:         cpu_loop_exit(env);
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.9 ! root       90:     cpu_loop_exit(env);
1.1.1.4   root       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;
1.1.1.9 ! root      116:     cpu_loop_exit(env);
1.1.1.4   root      117: }
                    118: 
                    119: void helper_sleep(uint32_t next_pc)
                    120: {
                    121:     env->halted = 1;
1.1.1.9 ! root      122:     env->in_sleep = 1;
1.1.1.4   root      123:     env->exception_index = EXCP_HLT;
                    124:     env->pc = next_pc;
1.1.1.9 ! root      125:     cpu_loop_exit(env);
1.1.1.4   root      126: }
                    127: 
                    128: void helper_trapa(uint32_t tra)
                    129: {
                    130:     env->tra = tra << 2;
1.1.1.8   root      131:     raise_exception(0x160, GETPC());
1.1.1.4   root      132: }
                    133: 
1.1.1.5   root      134: void helper_movcal(uint32_t address, uint32_t value)
                    135: {
                    136:     if (cpu_sh4_is_cached (env, address))
                    137:     {
                    138:        memory_content *r = malloc (sizeof(memory_content));
                    139:        r->address = address;
                    140:        r->value = value;
                    141:        r->next = NULL;
                    142: 
                    143:        *(env->movcal_backup_tail) = r;
                    144:        env->movcal_backup_tail = &(r->next);
                    145:     }
                    146: }
                    147: 
                    148: void helper_discard_movcal_backup(void)
                    149: {
                    150:     memory_content *current = env->movcal_backup;
                    151: 
                    152:     while(current)
                    153:     {
                    154:        memory_content *next = current->next;
                    155:        free (current);
                    156:        env->movcal_backup = current = next;
1.1.1.6   root      157:        if (current == NULL)
1.1.1.5   root      158:            env->movcal_backup_tail = &(env->movcal_backup);
                    159:     } 
                    160: }
                    161: 
                    162: void helper_ocbi(uint32_t address)
                    163: {
                    164:     memory_content **current = &(env->movcal_backup);
                    165:     while (*current)
                    166:     {
                    167:        uint32_t a = (*current)->address;
                    168:        if ((a & ~0x1F) == (address & ~0x1F))
                    169:        {
                    170:            memory_content *next = (*current)->next;
                    171:            stl(a, (*current)->value);
                    172:            
1.1.1.6   root      173:            if (next == NULL)
1.1.1.5   root      174:            {
                    175:                env->movcal_backup_tail = current;
                    176:            }
                    177: 
                    178:            free (*current);
                    179:            *current = next;
                    180:            break;
                    181:        }
                    182:     }
                    183: }
                    184: 
1.1.1.4   root      185: uint32_t helper_addc(uint32_t arg0, uint32_t arg1)
1.1       root      186: {
                    187:     uint32_t tmp0, tmp1;
                    188: 
1.1.1.4   root      189:     tmp1 = arg0 + arg1;
                    190:     tmp0 = arg1;
                    191:     arg1 = tmp1 + (env->sr & 1);
1.1       root      192:     if (tmp0 > tmp1)
                    193:        env->sr |= SR_T;
                    194:     else
                    195:        env->sr &= ~SR_T;
1.1.1.4   root      196:     if (tmp1 > arg1)
1.1       root      197:        env->sr |= SR_T;
1.1.1.4   root      198:     return arg1;
1.1       root      199: }
                    200: 
1.1.1.4   root      201: uint32_t helper_addv(uint32_t arg0, uint32_t arg1)
1.1       root      202: {
                    203:     uint32_t dest, src, ans;
                    204: 
1.1.1.4   root      205:     if ((int32_t) arg1 >= 0)
1.1       root      206:        dest = 0;
                    207:     else
                    208:        dest = 1;
1.1.1.4   root      209:     if ((int32_t) arg0 >= 0)
1.1       root      210:        src = 0;
                    211:     else
                    212:        src = 1;
                    213:     src += dest;
1.1.1.4   root      214:     arg1 += arg0;
                    215:     if ((int32_t) arg1 >= 0)
1.1       root      216:        ans = 0;
                    217:     else
                    218:        ans = 1;
                    219:     ans += dest;
                    220:     if (src == 0 || src == 2) {
                    221:        if (ans == 1)
                    222:            env->sr |= SR_T;
                    223:        else
                    224:            env->sr &= ~SR_T;
                    225:     } else
                    226:        env->sr &= ~SR_T;
1.1.1.4   root      227:     return arg1;
1.1       root      228: }
                    229: 
                    230: #define T (env->sr & SR_T)
                    231: #define Q (env->sr & SR_Q ? 1 : 0)
                    232: #define M (env->sr & SR_M ? 1 : 0)
                    233: #define SETT env->sr |= SR_T
                    234: #define CLRT env->sr &= ~SR_T
                    235: #define SETQ env->sr |= SR_Q
                    236: #define CLRQ env->sr &= ~SR_Q
                    237: #define SETM env->sr |= SR_M
                    238: #define CLRM env->sr &= ~SR_M
                    239: 
1.1.1.4   root      240: uint32_t helper_div1(uint32_t arg0, uint32_t arg1)
1.1       root      241: {
                    242:     uint32_t tmp0, tmp2;
                    243:     uint8_t old_q, tmp1 = 0xff;
                    244: 
1.1.1.4   root      245:     //printf("div1 arg0=0x%08x arg1=0x%08x M=%d Q=%d T=%d\n", arg0, arg1, M, Q, T);
1.1       root      246:     old_q = Q;
1.1.1.4   root      247:     if ((0x80000000 & arg1) != 0)
1.1       root      248:        SETQ;
                    249:     else
                    250:        CLRQ;
1.1.1.4   root      251:     tmp2 = arg0;
                    252:     arg1 <<= 1;
                    253:     arg1 |= T;
1.1       root      254:     switch (old_q) {
                    255:     case 0:
                    256:        switch (M) {
                    257:        case 0:
1.1.1.4   root      258:            tmp0 = arg1;
                    259:            arg1 -= tmp2;
                    260:            tmp1 = arg1 > tmp0;
1.1       root      261:            switch (Q) {
                    262:            case 0:
                    263:                if (tmp1)
                    264:                    SETQ;
                    265:                else
                    266:                    CLRQ;
                    267:                break;
                    268:            case 1:
                    269:                if (tmp1 == 0)
                    270:                    SETQ;
                    271:                else
                    272:                    CLRQ;
                    273:                break;
                    274:            }
                    275:            break;
                    276:        case 1:
1.1.1.4   root      277:            tmp0 = arg1;
                    278:            arg1 += tmp2;
                    279:            tmp1 = arg1 < tmp0;
1.1       root      280:            switch (Q) {
                    281:            case 0:
                    282:                if (tmp1 == 0)
                    283:                    SETQ;
                    284:                else
                    285:                    CLRQ;
                    286:                break;
                    287:            case 1:
                    288:                if (tmp1)
                    289:                    SETQ;
                    290:                else
                    291:                    CLRQ;
                    292:                break;
                    293:            }
                    294:            break;
                    295:        }
                    296:        break;
                    297:     case 1:
                    298:        switch (M) {
                    299:        case 0:
1.1.1.4   root      300:            tmp0 = arg1;
                    301:            arg1 += tmp2;
                    302:            tmp1 = arg1 < tmp0;
1.1       root      303:            switch (Q) {
                    304:            case 0:
                    305:                if (tmp1)
                    306:                    SETQ;
                    307:                else
                    308:                    CLRQ;
                    309:                break;
                    310:            case 1:
                    311:                if (tmp1 == 0)
                    312:                    SETQ;
                    313:                else
                    314:                    CLRQ;
                    315:                break;
                    316:            }
                    317:            break;
                    318:        case 1:
1.1.1.4   root      319:            tmp0 = arg1;
                    320:            arg1 -= tmp2;
                    321:            tmp1 = arg1 > tmp0;
1.1       root      322:            switch (Q) {
                    323:            case 0:
                    324:                if (tmp1 == 0)
                    325:                    SETQ;
                    326:                else
                    327:                    CLRQ;
                    328:                break;
                    329:            case 1:
                    330:                if (tmp1)
                    331:                    SETQ;
                    332:                else
                    333:                    CLRQ;
                    334:                break;
                    335:            }
                    336:            break;
                    337:        }
                    338:        break;
                    339:     }
                    340:     if (Q == M)
                    341:        SETT;
                    342:     else
                    343:        CLRT;
1.1.1.4   root      344:     //printf("Output: arg1=0x%08x M=%d Q=%d T=%d\n", arg1, M, Q, T);
                    345:     return arg1;
1.1       root      346: }
                    347: 
1.1.1.4   root      348: void helper_macl(uint32_t arg0, uint32_t arg1)
1.1       root      349: {
                    350:     int64_t res;
                    351: 
                    352:     res = ((uint64_t) env->mach << 32) | env->macl;
1.1.1.4   root      353:     res += (int64_t) (int32_t) arg0 *(int64_t) (int32_t) arg1;
1.1       root      354:     env->mach = (res >> 32) & 0xffffffff;
                    355:     env->macl = res & 0xffffffff;
                    356:     if (env->sr & SR_S) {
                    357:        if (res < 0)
                    358:            env->mach |= 0xffff0000;
                    359:        else
                    360:            env->mach &= 0x00007fff;
                    361:     }
                    362: }
                    363: 
1.1.1.4   root      364: void helper_macw(uint32_t arg0, uint32_t arg1)
1.1       root      365: {
                    366:     int64_t res;
                    367: 
                    368:     res = ((uint64_t) env->mach << 32) | env->macl;
1.1.1.4   root      369:     res += (int64_t) (int16_t) arg0 *(int64_t) (int16_t) arg1;
1.1       root      370:     env->mach = (res >> 32) & 0xffffffff;
                    371:     env->macl = res & 0xffffffff;
                    372:     if (env->sr & SR_S) {
                    373:        if (res < -0x80000000) {
                    374:            env->mach = 1;
                    375:            env->macl = 0x80000000;
                    376:        } else if (res > 0x000000007fffffff) {
                    377:            env->mach = 1;
                    378:            env->macl = 0x7fffffff;
                    379:        }
                    380:     }
                    381: }
                    382: 
1.1.1.4   root      383: uint32_t helper_subc(uint32_t arg0, uint32_t arg1)
1.1       root      384: {
                    385:     uint32_t tmp0, tmp1;
                    386: 
1.1.1.4   root      387:     tmp1 = arg1 - arg0;
                    388:     tmp0 = arg1;
                    389:     arg1 = tmp1 - (env->sr & SR_T);
1.1       root      390:     if (tmp0 < tmp1)
                    391:        env->sr |= SR_T;
                    392:     else
                    393:        env->sr &= ~SR_T;
1.1.1.4   root      394:     if (tmp1 < arg1)
1.1       root      395:        env->sr |= SR_T;
1.1.1.4   root      396:     return arg1;
1.1       root      397: }
                    398: 
1.1.1.4   root      399: uint32_t helper_subv(uint32_t arg0, uint32_t arg1)
1.1       root      400: {
                    401:     int32_t dest, src, ans;
                    402: 
1.1.1.4   root      403:     if ((int32_t) arg1 >= 0)
1.1       root      404:        dest = 0;
                    405:     else
                    406:        dest = 1;
1.1.1.4   root      407:     if ((int32_t) arg0 >= 0)
1.1       root      408:        src = 0;
                    409:     else
                    410:        src = 1;
                    411:     src += dest;
1.1.1.4   root      412:     arg1 -= arg0;
                    413:     if ((int32_t) arg1 >= 0)
1.1       root      414:        ans = 0;
                    415:     else
                    416:        ans = 1;
                    417:     ans += dest;
                    418:     if (src == 1) {
                    419:        if (ans == 1)
                    420:            env->sr |= SR_T;
                    421:        else
                    422:            env->sr &= ~SR_T;
                    423:     } else
                    424:        env->sr &= ~SR_T;
1.1.1.4   root      425:     return arg1;
1.1       root      426: }
                    427: 
1.1.1.4   root      428: static inline void set_t(void)
1.1       root      429: {
1.1.1.4   root      430:     env->sr |= SR_T;
                    431: }
1.1       root      432: 
1.1.1.4   root      433: static inline void clr_t(void)
                    434: {
                    435:     env->sr &= ~SR_T;
                    436: }
                    437: 
                    438: void helper_ld_fpscr(uint32_t val)
                    439: {
1.1.1.8   root      440:     env->fpscr = val & FPSCR_MASK;
                    441:     if ((val & FPSCR_RM_MASK) == FPSCR_RM_ZERO) {
1.1.1.4   root      442:        set_float_rounding_mode(float_round_to_zero, &env->fp_status);
1.1.1.8   root      443:     } else {
1.1.1.4   root      444:        set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1.1.1.8   root      445:     }
                    446:     set_flush_to_zero((val & FPSCR_DN) != 0, &env->fp_status);
                    447: }
                    448: 
                    449: static void update_fpscr(void *retaddr)
                    450: {
                    451:     int xcpt, cause, enable;
                    452: 
                    453:     xcpt = get_float_exception_flags(&env->fp_status);
                    454: 
                    455:     /* Clear the flag entries */
                    456:     env->fpscr &= ~FPSCR_FLAG_MASK;
                    457: 
                    458:     if (unlikely(xcpt)) {
                    459:         if (xcpt & float_flag_invalid) {
                    460:             env->fpscr |= FPSCR_FLAG_V;
                    461:         }
                    462:         if (xcpt & float_flag_divbyzero) {
                    463:             env->fpscr |= FPSCR_FLAG_Z;
                    464:         }
                    465:         if (xcpt & float_flag_overflow) {
                    466:             env->fpscr |= FPSCR_FLAG_O;
                    467:         }
                    468:         if (xcpt & float_flag_underflow) {
                    469:             env->fpscr |= FPSCR_FLAG_U;
                    470:         }
                    471:         if (xcpt & float_flag_inexact) {
                    472:             env->fpscr |= FPSCR_FLAG_I;
                    473:         }
                    474: 
                    475:         /* Accumulate in cause entries */
                    476:         env->fpscr |= (env->fpscr & FPSCR_FLAG_MASK)
                    477:                       << (FPSCR_CAUSE_SHIFT - FPSCR_FLAG_SHIFT);
                    478: 
                    479:         /* Generate an exception if enabled */
                    480:         cause = (env->fpscr & FPSCR_CAUSE_MASK) >> FPSCR_CAUSE_SHIFT;
                    481:         enable = (env->fpscr & FPSCR_ENABLE_MASK) >> FPSCR_ENABLE_SHIFT;
                    482:         if (cause & enable) {
                    483:             cpu_restore_state_from_retaddr(retaddr);
                    484:             env->exception_index = 0x120;
1.1.1.9 ! root      485:             cpu_loop_exit(env);
1.1.1.8   root      486:         }
                    487:     }
1.1       root      488: }
                    489: 
1.1.1.9 ! root      490: float32 helper_fabs_FT(float32 t0)
1.1       root      491: {
1.1.1.9 ! root      492:     return float32_abs(t0);
1.1.1.4   root      493: }
1.1       root      494: 
1.1.1.9 ! root      495: float64 helper_fabs_DT(float64 t0)
1.1.1.4   root      496: {
1.1.1.9 ! root      497:     return float64_abs(t0);
1.1.1.4   root      498: }
                    499: 
1.1.1.9 ! root      500: float32 helper_fadd_FT(float32 t0, float32 t1)
1.1.1.4   root      501: {
1.1.1.8   root      502:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      503:     t0 = float32_add(t0, t1, &env->fp_status);
1.1.1.8   root      504:     update_fpscr(GETPC());
1.1.1.9 ! root      505:     return t0;
1.1.1.4   root      506: }
                    507: 
1.1.1.9 ! root      508: float64 helper_fadd_DT(float64 t0, float64 t1)
1.1.1.4   root      509: {
1.1.1.8   root      510:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      511:     t0 = float64_add(t0, t1, &env->fp_status);
1.1.1.8   root      512:     update_fpscr(GETPC());
1.1.1.9 ! root      513:     return t0;
1.1.1.4   root      514: }
                    515: 
1.1.1.9 ! root      516: void helper_fcmp_eq_FT(float32 t0, float32 t1)
1.1.1.4   root      517: {
1.1.1.8   root      518:     int relation;
1.1.1.4   root      519: 
1.1.1.8   root      520:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      521:     relation = float32_compare(t0, t1, &env->fp_status);
1.1.1.8   root      522:     if (unlikely(relation == float_relation_unordered)) {
                    523:         update_fpscr(GETPC());
                    524:     } else if (relation == float_relation_equal) {
1.1.1.4   root      525:        set_t();
1.1.1.8   root      526:     } else {
1.1.1.4   root      527:        clr_t();
1.1.1.8   root      528:     }
1.1.1.4   root      529: }
                    530: 
1.1.1.9 ! root      531: void helper_fcmp_eq_DT(float64 t0, float64 t1)
1.1.1.4   root      532: {
1.1.1.8   root      533:     int relation;
1.1.1.4   root      534: 
1.1.1.8   root      535:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      536:     relation = float64_compare(t0, t1, &env->fp_status);
1.1.1.8   root      537:     if (unlikely(relation == float_relation_unordered)) {
                    538:         update_fpscr(GETPC());
                    539:     } else if (relation == float_relation_equal) {
1.1.1.4   root      540:        set_t();
1.1.1.8   root      541:     } else {
1.1.1.4   root      542:        clr_t();
1.1.1.8   root      543:     }
1.1.1.4   root      544: }
                    545: 
1.1.1.9 ! root      546: void helper_fcmp_gt_FT(float32 t0, float32 t1)
1.1.1.4   root      547: {
1.1.1.8   root      548:     int relation;
1.1.1.4   root      549: 
1.1.1.8   root      550:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      551:     relation = float32_compare(t0, t1, &env->fp_status);
1.1.1.8   root      552:     if (unlikely(relation == float_relation_unordered)) {
                    553:         update_fpscr(GETPC());
                    554:     } else if (relation == float_relation_greater) {
1.1.1.4   root      555:        set_t();
1.1.1.8   root      556:     } else {
1.1.1.4   root      557:        clr_t();
1.1.1.8   root      558:     }
1.1.1.4   root      559: }
                    560: 
1.1.1.9 ! root      561: void helper_fcmp_gt_DT(float64 t0, float64 t1)
1.1.1.4   root      562: {
1.1.1.8   root      563:     int relation;
1.1.1.4   root      564: 
1.1.1.8   root      565:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      566:     relation = float64_compare(t0, t1, &env->fp_status);
1.1.1.8   root      567:     if (unlikely(relation == float_relation_unordered)) {
                    568:         update_fpscr(GETPC());
                    569:     } else if (relation == float_relation_greater) {
1.1.1.4   root      570:        set_t();
1.1.1.8   root      571:     } else {
1.1.1.4   root      572:        clr_t();
1.1.1.8   root      573:     }
1.1.1.4   root      574: }
                    575: 
1.1.1.9 ! root      576: float64 helper_fcnvsd_FT_DT(float32 t0)
1.1.1.4   root      577: {
1.1.1.9 ! root      578:     float64 ret;
1.1.1.8   root      579:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      580:     ret = float32_to_float64(t0, &env->fp_status);
1.1.1.8   root      581:     update_fpscr(GETPC());
1.1.1.9 ! root      582:     return ret;
1.1.1.4   root      583: }
                    584: 
1.1.1.9 ! root      585: float32 helper_fcnvds_DT_FT(float64 t0)
1.1.1.4   root      586: {
1.1.1.9 ! root      587:     float32 ret;
1.1.1.8   root      588:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      589:     ret = float64_to_float32(t0, &env->fp_status);
1.1.1.8   root      590:     update_fpscr(GETPC());
1.1.1.9 ! root      591:     return ret;
1.1.1.4   root      592: }
                    593: 
1.1.1.9 ! root      594: float32 helper_fdiv_FT(float32 t0, float32 t1)
1.1.1.4   root      595: {
1.1.1.8   root      596:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      597:     t0 = float32_div(t0, t1, &env->fp_status);
1.1.1.8   root      598:     update_fpscr(GETPC());
1.1.1.9 ! root      599:     return t0;
1.1.1.4   root      600: }
                    601: 
1.1.1.9 ! root      602: float64 helper_fdiv_DT(float64 t0, float64 t1)
1.1.1.4   root      603: {
1.1.1.8   root      604:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      605:     t0 = float64_div(t0, t1, &env->fp_status);
1.1.1.8   root      606:     update_fpscr(GETPC());
1.1.1.9 ! root      607:     return t0;
1.1.1.4   root      608: }
                    609: 
1.1.1.9 ! root      610: float32 helper_float_FT(uint32_t t0)
1.1.1.4   root      611: {
1.1.1.9 ! root      612:     float32 ret;
1.1.1.8   root      613:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      614:     ret = int32_to_float32(t0, &env->fp_status);
1.1.1.8   root      615:     update_fpscr(GETPC());
1.1.1.9 ! root      616:     return ret;
1.1.1.4   root      617: }
                    618: 
1.1.1.9 ! root      619: float64 helper_float_DT(uint32_t t0)
1.1.1.4   root      620: {
1.1.1.9 ! root      621:     float64 ret;
1.1.1.8   root      622:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      623:     ret = int32_to_float64(t0, &env->fp_status);
1.1.1.8   root      624:     update_fpscr(GETPC());
1.1.1.9 ! root      625:     return ret;
1.1.1.4   root      626: }
                    627: 
1.1.1.9 ! root      628: float32 helper_fmac_FT(float32 t0, float32 t1, float32 t2)
1.1.1.4   root      629: {
1.1.1.8   root      630:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      631:     t0 = float32_mul(t0, t1, &env->fp_status);
        !           632:     t0 = float32_add(t0, t2, &env->fp_status);
1.1.1.8   root      633:     update_fpscr(GETPC());
1.1.1.9 ! root      634:     return t0;
1.1.1.4   root      635: }
                    636: 
1.1.1.9 ! root      637: float32 helper_fmul_FT(float32 t0, float32 t1)
1.1.1.4   root      638: {
1.1.1.8   root      639:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      640:     t0 = float32_mul(t0, t1, &env->fp_status);
1.1.1.8   root      641:     update_fpscr(GETPC());
1.1.1.9 ! root      642:     return t0;
1.1.1.4   root      643: }
                    644: 
1.1.1.9 ! root      645: float64 helper_fmul_DT(float64 t0, float64 t1)
1.1.1.4   root      646: {
1.1.1.8   root      647:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      648:     t0 = float64_mul(t0, t1, &env->fp_status);
1.1.1.8   root      649:     update_fpscr(GETPC());
1.1.1.9 ! root      650:     return t0;
1.1.1.4   root      651: }
                    652: 
1.1.1.9 ! root      653: float32 helper_fneg_T(float32 t0)
1.1.1.4   root      654: {
1.1.1.9 ! root      655:     return float32_chs(t0);
1.1.1.4   root      656: }
                    657: 
1.1.1.9 ! root      658: float32 helper_fsqrt_FT(float32 t0)
1.1.1.4   root      659: {
1.1.1.8   root      660:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      661:     t0 = float32_sqrt(t0, &env->fp_status);
1.1.1.8   root      662:     update_fpscr(GETPC());
1.1.1.9 ! root      663:     return t0;
1.1.1.4   root      664: }
                    665: 
1.1.1.9 ! root      666: float64 helper_fsqrt_DT(float64 t0)
1.1.1.4   root      667: {
1.1.1.8   root      668:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      669:     t0 = float64_sqrt(t0, &env->fp_status);
1.1.1.8   root      670:     update_fpscr(GETPC());
1.1.1.9 ! root      671:     return t0;
1.1.1.4   root      672: }
                    673: 
1.1.1.9 ! root      674: float32 helper_fsub_FT(float32 t0, float32 t1)
1.1.1.4   root      675: {
1.1.1.8   root      676:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      677:     t0 = float32_sub(t0, t1, &env->fp_status);
1.1.1.8   root      678:     update_fpscr(GETPC());
1.1.1.9 ! root      679:     return t0;
1.1.1.4   root      680: }
                    681: 
1.1.1.9 ! root      682: float64 helper_fsub_DT(float64 t0, float64 t1)
1.1.1.4   root      683: {
1.1.1.8   root      684:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      685:     t0 = float64_sub(t0, t1, &env->fp_status);
1.1.1.8   root      686:     update_fpscr(GETPC());
1.1.1.9 ! root      687:     return t0;
1.1.1.4   root      688: }
                    689: 
1.1.1.9 ! root      690: uint32_t helper_ftrc_FT(float32 t0)
1.1.1.4   root      691: {
1.1.1.8   root      692:     uint32_t ret;
                    693:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      694:     ret = float32_to_int32_round_to_zero(t0, &env->fp_status);
1.1.1.8   root      695:     update_fpscr(GETPC());
                    696:     return ret;
1.1.1.4   root      697: }
                    698: 
1.1.1.9 ! root      699: uint32_t helper_ftrc_DT(float64 t0)
1.1.1.4   root      700: {
1.1.1.8   root      701:     uint32_t ret;
                    702:     set_float_exception_flags(0, &env->fp_status);
1.1.1.9 ! root      703:     ret = float64_to_int32_round_to_zero(t0, &env->fp_status);
1.1.1.8   root      704:     update_fpscr(GETPC());
                    705:     return ret;
                    706: }
                    707: 
                    708: void helper_fipr(uint32_t m, uint32_t n)
                    709: {
                    710:     int bank, i;
                    711:     float32 r, p;
                    712: 
                    713:     bank = (env->sr & FPSCR_FR) ? 16 : 0;
                    714:     r = float32_zero;
                    715:     set_float_exception_flags(0, &env->fp_status);
                    716: 
                    717:     for (i = 0 ; i < 4 ; i++) {
                    718:         p = float32_mul(env->fregs[bank + m + i],
                    719:                         env->fregs[bank + n + i],
                    720:                         &env->fp_status);
                    721:         r = float32_add(r, p, &env->fp_status);
                    722:     }
                    723:     update_fpscr(GETPC());
                    724: 
                    725:     env->fregs[bank + n + 3] = r;
                    726: }
                    727: 
                    728: void helper_ftrv(uint32_t n)
                    729: {
                    730:     int bank_matrix, bank_vector;
                    731:     int i, j;
                    732:     float32 r[4];
                    733:     float32 p;
                    734: 
                    735:     bank_matrix = (env->sr & FPSCR_FR) ? 0 : 16;
                    736:     bank_vector = (env->sr & FPSCR_FR) ? 16 : 0;
                    737:     set_float_exception_flags(0, &env->fp_status);
                    738:     for (i = 0 ; i < 4 ; i++) {
                    739:         r[i] = float32_zero;
                    740:         for (j = 0 ; j < 4 ; j++) {
                    741:             p = float32_mul(env->fregs[bank_matrix + 4 * j + i],
                    742:                             env->fregs[bank_vector + j],
                    743:                             &env->fp_status);
                    744:             r[i] = float32_add(r[i], p, &env->fp_status);
                    745:         }
                    746:     }
                    747:     update_fpscr(GETPC());
                    748: 
                    749:     for (i = 0 ; i < 4 ; i++) {
                    750:         env->fregs[bank_vector + i] = r[i];
                    751:     }
1.1       root      752: }

unix.superglobalmegacorp.com

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