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

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

unix.superglobalmegacorp.com

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