Annotation of qemu/target-alpha/op_helper.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  *  Alpha emulation cpu micro-operations helpers for qemu.
                      3:  *
                      4:  *  Copyright (c) 2007 Jocelyn Mayer
                      5:  *
                      6:  * This library is free software; you can redistribute it and/or
                      7:  * modify it under the terms of the GNU Lesser General Public
                      8:  * License as published by the Free Software Foundation; either
                      9:  * version 2 of the License, or (at your option) any later version.
                     10:  *
                     11:  * This library is distributed in the hope that it will be useful,
                     12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * Lesser General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU Lesser General Public
                     17:  * License along with this library; if not, write to the Free Software
1.1.1.2 ! root       18:  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
1.1       root       19:  */
                     20: 
                     21: #include "exec.h"
                     22: #include "host-utils.h"
                     23: #include "softfloat.h"
1.1.1.2 ! root       24: #include "helper.h"
1.1       root       25: 
                     26: void helper_tb_flush (void)
                     27: {
                     28:     tlb_flush(env, 1);
                     29: }
                     30: 
                     31: /*****************************************************************************/
                     32: /* Exceptions processing helpers */
1.1.1.2 ! root       33: void helper_excp (int excp, int error)
1.1       root       34: {
                     35:     env->exception_index = excp;
                     36:     env->error_code = error;
                     37:     cpu_loop_exit();
                     38: }
                     39: 
1.1.1.2 ! root       40: uint64_t helper_amask (uint64_t arg)
1.1       root       41: {
                     42:     switch (env->implver) {
                     43:     case IMPLVER_2106x:
                     44:         /* EV4, EV45, LCA, LCA45 & EV5 */
                     45:         break;
                     46:     case IMPLVER_21164:
                     47:     case IMPLVER_21264:
                     48:     case IMPLVER_21364:
1.1.1.2 ! root       49:         arg &= ~env->amask;
1.1       root       50:         break;
                     51:     }
1.1.1.2 ! root       52:     return arg;
1.1       root       53: }
                     54: 
1.1.1.2 ! root       55: uint64_t helper_load_pcc (void)
1.1       root       56: {
                     57:     /* XXX: TODO */
1.1.1.2 ! root       58:     return 0;
1.1       root       59: }
                     60: 
1.1.1.2 ! root       61: uint64_t helper_load_implver (void)
1.1       root       62: {
1.1.1.2 ! root       63:     return env->implver;
1.1       root       64: }
                     65: 
1.1.1.2 ! root       66: uint64_t helper_load_fpcr (void)
1.1       root       67: {
1.1.1.2 ! root       68:     uint64_t ret = 0;
1.1       root       69: #ifdef CONFIG_SOFTFLOAT
1.1.1.2 ! root       70:     ret |= env->fp_status.float_exception_flags << 52;
1.1       root       71:     if (env->fp_status.float_exception_flags)
1.1.1.2 ! root       72:         ret |= 1ULL << 63;
1.1       root       73:     env->ipr[IPR_EXC_SUM] &= ~0x3E:
                     74:     env->ipr[IPR_EXC_SUM] |= env->fp_status.float_exception_flags << 1;
                     75: #endif
                     76:     switch (env->fp_status.float_rounding_mode) {
                     77:     case float_round_nearest_even:
1.1.1.2 ! root       78:         ret |= 2ULL << 58;
1.1       root       79:         break;
                     80:     case float_round_down:
1.1.1.2 ! root       81:         ret |= 1ULL << 58;
1.1       root       82:         break;
                     83:     case float_round_up:
1.1.1.2 ! root       84:         ret |= 3ULL << 58;
1.1       root       85:         break;
                     86:     case float_round_to_zero:
                     87:         break;
                     88:     }
1.1.1.2 ! root       89:     return ret;
1.1       root       90: }
                     91: 
1.1.1.2 ! root       92: void helper_store_fpcr (uint64_t val)
1.1       root       93: {
                     94: #ifdef CONFIG_SOFTFLOAT
1.1.1.2 ! root       95:     set_float_exception_flags((val >> 52) & 0x3F, &FP_STATUS);
1.1       root       96: #endif
1.1.1.2 ! root       97:     switch ((val >> 58) & 3) {
1.1       root       98:     case 0:
                     99:         set_float_rounding_mode(float_round_to_zero, &FP_STATUS);
                    100:         break;
                    101:     case 1:
                    102:         set_float_rounding_mode(float_round_down, &FP_STATUS);
                    103:         break;
                    104:     case 2:
                    105:         set_float_rounding_mode(float_round_nearest_even, &FP_STATUS);
                    106:         break;
                    107:     case 3:
                    108:         set_float_rounding_mode(float_round_up, &FP_STATUS);
                    109:         break;
                    110:     }
                    111: }
                    112: 
1.1.1.2 ! root      113: spinlock_t intr_cpu_lock = SPIN_LOCK_UNLOCKED;
1.1       root      114: 
1.1.1.2 ! root      115: uint64_t helper_rs(void)
1.1       root      116: {
1.1.1.2 ! root      117:     uint64_t tmp;
        !           118: 
        !           119:     spin_lock(&intr_cpu_lock);
        !           120:     tmp = env->intr_flag;
        !           121:     env->intr_flag = 1;
        !           122:     spin_unlock(&intr_cpu_lock);
        !           123: 
        !           124:     return tmp;
1.1       root      125: }
                    126: 
1.1.1.2 ! root      127: uint64_t helper_rc(void)
1.1       root      128: {
1.1.1.2 ! root      129:     uint64_t tmp;
        !           130: 
        !           131:     spin_lock(&intr_cpu_lock);
        !           132:     tmp = env->intr_flag;
        !           133:     env->intr_flag = 0;
        !           134:     spin_unlock(&intr_cpu_lock);
        !           135: 
        !           136:     return tmp;
1.1       root      137: }
                    138: 
1.1.1.2 ! root      139: uint64_t helper_addqv (uint64_t op1, uint64_t op2)
1.1       root      140: {
1.1.1.2 ! root      141:     uint64_t tmp = op1;
        !           142:     op1 += op2;
        !           143:     if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) {
1.1       root      144:         helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
                    145:     }
1.1.1.2 ! root      146:     return op1;
1.1       root      147: }
                    148: 
1.1.1.2 ! root      149: uint64_t helper_addlv (uint64_t op1, uint64_t op2)
1.1       root      150: {
1.1.1.2 ! root      151:     uint64_t tmp = op1;
        !           152:     op1 = (uint32_t)(op1 + op2);
        !           153:     if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) {
1.1       root      154:         helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
                    155:     }
1.1.1.2 ! root      156:     return op1;
1.1       root      157: }
                    158: 
1.1.1.2 ! root      159: uint64_t helper_subqv (uint64_t op1, uint64_t op2)
1.1       root      160: {
1.1.1.2 ! root      161:     uint64_t tmp = op1;
        !           162:     op1 -= op2;
        !           163:     if (unlikely(((~tmp) ^ op1 ^ (-1ULL)) & ((~tmp) ^ op2) & (1ULL << 63))) {
1.1       root      164:         helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
                    165:     }
1.1.1.2 ! root      166:     return op1;
1.1       root      167: }
                    168: 
1.1.1.2 ! root      169: uint64_t helper_sublv (uint64_t op1, uint64_t op2)
1.1       root      170: {
1.1.1.2 ! root      171:     uint64_t tmp = op1;
        !           172:     op1 = (uint32_t)(op1 - op2);
        !           173:     if (unlikely(((~tmp) ^ op1 ^ (-1UL)) & ((~tmp) ^ op2) & (1UL << 31))) {
1.1       root      174:         helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
                    175:     }
1.1.1.2 ! root      176:     return op1;
1.1       root      177: }
                    178: 
1.1.1.2 ! root      179: uint64_t helper_mullv (uint64_t op1, uint64_t op2)
1.1       root      180: {
1.1.1.2 ! root      181:     int64_t res = (int64_t)op1 * (int64_t)op2;
1.1       root      182: 
                    183:     if (unlikely((int32_t)res != res)) {
                    184:         helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
                    185:     }
1.1.1.2 ! root      186:     return (int64_t)((int32_t)res);
1.1       root      187: }
                    188: 
1.1.1.2 ! root      189: uint64_t helper_mulqv (uint64_t op1, uint64_t op2)
1.1       root      190: {
                    191:     uint64_t tl, th;
                    192: 
1.1.1.2 ! root      193:     muls64(&tl, &th, op1, op2);
1.1       root      194:     /* If th != 0 && th != -1, then we had an overflow */
                    195:     if (unlikely((th + 1) > 1)) {
                    196:         helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
                    197:     }
1.1.1.2 ! root      198:     return tl;
1.1       root      199: }
                    200: 
1.1.1.2 ! root      201: uint64_t helper_umulh (uint64_t op1, uint64_t op2)
1.1       root      202: {
1.1.1.2 ! root      203:     uint64_t tl, th;
        !           204: 
        !           205:     mulu64(&tl, &th, op1, op2);
        !           206:     return th;
1.1       root      207: }
                    208: 
1.1.1.2 ! root      209: uint64_t helper_ctpop (uint64_t arg)
1.1       root      210: {
1.1.1.2 ! root      211:     return ctpop64(arg);
1.1       root      212: }
                    213: 
1.1.1.2 ! root      214: uint64_t helper_ctlz (uint64_t arg)
1.1       root      215: {
1.1.1.2 ! root      216:     return clz64(arg);
        !           217: }
        !           218: 
        !           219: uint64_t helper_cttz (uint64_t arg)
        !           220: {
        !           221:     return ctz64(arg);
1.1       root      222: }
                    223: 
                    224: static always_inline uint64_t byte_zap (uint64_t op, uint8_t mskb)
                    225: {
                    226:     uint64_t mask;
                    227: 
                    228:     mask = 0;
                    229:     mask |= ((mskb >> 0) & 1) * 0x00000000000000FFULL;
                    230:     mask |= ((mskb >> 1) & 1) * 0x000000000000FF00ULL;
                    231:     mask |= ((mskb >> 2) & 1) * 0x0000000000FF0000ULL;
                    232:     mask |= ((mskb >> 3) & 1) * 0x00000000FF000000ULL;
                    233:     mask |= ((mskb >> 4) & 1) * 0x000000FF00000000ULL;
                    234:     mask |= ((mskb >> 5) & 1) * 0x0000FF0000000000ULL;
                    235:     mask |= ((mskb >> 6) & 1) * 0x00FF000000000000ULL;
                    236:     mask |= ((mskb >> 7) & 1) * 0xFF00000000000000ULL;
                    237: 
                    238:     return op & ~mask;
                    239: }
                    240: 
1.1.1.2 ! root      241: uint64_t helper_mskbl(uint64_t val, uint64_t mask)
1.1       root      242: {
1.1.1.2 ! root      243:     return byte_zap(val, 0x01 << (mask & 7));
1.1       root      244: }
                    245: 
1.1.1.2 ! root      246: uint64_t helper_insbl(uint64_t val, uint64_t mask)
1.1       root      247: {
1.1.1.2 ! root      248:     val <<= (mask & 7) * 8;
        !           249:     return byte_zap(val, ~(0x01 << (mask & 7)));
1.1       root      250: }
                    251: 
1.1.1.2 ! root      252: uint64_t helper_mskwl(uint64_t val, uint64_t mask)
1.1       root      253: {
1.1.1.2 ! root      254:     return byte_zap(val, 0x03 << (mask & 7));
1.1       root      255: }
                    256: 
1.1.1.2 ! root      257: uint64_t helper_inswl(uint64_t val, uint64_t mask)
1.1       root      258: {
1.1.1.2 ! root      259:     val <<= (mask & 7) * 8;
        !           260:     return byte_zap(val, ~(0x03 << (mask & 7)));
1.1       root      261: }
                    262: 
1.1.1.2 ! root      263: uint64_t helper_mskll(uint64_t val, uint64_t mask)
1.1       root      264: {
1.1.1.2 ! root      265:     return byte_zap(val, 0x0F << (mask & 7));
1.1       root      266: }
                    267: 
1.1.1.2 ! root      268: uint64_t helper_insll(uint64_t val, uint64_t mask)
1.1       root      269: {
1.1.1.2 ! root      270:     val <<= (mask & 7) * 8;
        !           271:     return byte_zap(val, ~(0x0F << (mask & 7)));
1.1       root      272: }
                    273: 
1.1.1.2 ! root      274: uint64_t helper_zap(uint64_t val, uint64_t mask)
1.1       root      275: {
1.1.1.2 ! root      276:     return byte_zap(val, mask);
1.1       root      277: }
                    278: 
1.1.1.2 ! root      279: uint64_t helper_zapnot(uint64_t val, uint64_t mask)
1.1       root      280: {
1.1.1.2 ! root      281:     return byte_zap(val, ~mask);
1.1       root      282: }
                    283: 
1.1.1.2 ! root      284: uint64_t helper_mskql(uint64_t val, uint64_t mask)
1.1       root      285: {
1.1.1.2 ! root      286:     return byte_zap(val, 0xFF << (mask & 7));
1.1       root      287: }
                    288: 
1.1.1.2 ! root      289: uint64_t helper_insql(uint64_t val, uint64_t mask)
1.1       root      290: {
1.1.1.2 ! root      291:     val <<= (mask & 7) * 8;
        !           292:     return byte_zap(val, ~(0xFF << (mask & 7)));
1.1       root      293: }
                    294: 
1.1.1.2 ! root      295: uint64_t helper_mskwh(uint64_t val, uint64_t mask)
1.1       root      296: {
1.1.1.2 ! root      297:     return byte_zap(val, (0x03 << (mask & 7)) >> 8);
1.1       root      298: }
                    299: 
1.1.1.2 ! root      300: uint64_t helper_inswh(uint64_t val, uint64_t mask)
1.1       root      301: {
1.1.1.2 ! root      302:     val >>= 64 - ((mask & 7) * 8);
        !           303:     return byte_zap(val, ~((0x03 << (mask & 7)) >> 8));
1.1       root      304: }
                    305: 
1.1.1.2 ! root      306: uint64_t helper_msklh(uint64_t val, uint64_t mask)
1.1       root      307: {
1.1.1.2 ! root      308:     return byte_zap(val, (0x0F << (mask & 7)) >> 8);
1.1       root      309: }
                    310: 
1.1.1.2 ! root      311: uint64_t helper_inslh(uint64_t val, uint64_t mask)
1.1       root      312: {
1.1.1.2 ! root      313:     val >>= 64 - ((mask & 7) * 8);
        !           314:     return byte_zap(val, ~((0x0F << (mask & 7)) >> 8));
1.1       root      315: }
                    316: 
1.1.1.2 ! root      317: uint64_t helper_mskqh(uint64_t val, uint64_t mask)
1.1       root      318: {
1.1.1.2 ! root      319:     return byte_zap(val, (0xFF << (mask & 7)) >> 8);
1.1       root      320: }
                    321: 
1.1.1.2 ! root      322: uint64_t helper_insqh(uint64_t val, uint64_t mask)
1.1       root      323: {
1.1.1.2 ! root      324:     val >>= 64 - ((mask & 7) * 8);
        !           325:     return byte_zap(val, ~((0xFF << (mask & 7)) >> 8));
1.1       root      326: }
                    327: 
1.1.1.2 ! root      328: uint64_t helper_cmpbge (uint64_t op1, uint64_t op2)
1.1       root      329: {
1.1.1.2 ! root      330:     uint8_t opa, opb, res;
        !           331:     int i;
1.1       root      332: 
1.1.1.2 ! root      333:     res = 0;
        !           334:     for (i = 0; i < 8; i++) {
        !           335:         opa = op1 >> (i * 8);
        !           336:         opb = op2 >> (i * 8);
        !           337:         if (opa >= opb)
        !           338:             res |= 1 << i;
        !           339:     }
        !           340:     return res;
1.1       root      341: }
                    342: 
1.1.1.2 ! root      343: /* Floating point helpers */
1.1       root      344: 
1.1.1.2 ! root      345: /* F floating (VAX) */
        !           346: static always_inline uint64_t float32_to_f (float32 fa)
1.1       root      347: {
1.1.1.2 ! root      348:     uint64_t r, exp, mant, sig;
        !           349:     CPU_FloatU a;
        !           350: 
        !           351:     a.f = fa;
        !           352:     sig = ((uint64_t)a.l & 0x80000000) << 32;
        !           353:     exp = (a.l >> 23) & 0xff;
        !           354:     mant = ((uint64_t)a.l & 0x007fffff) << 29;
        !           355: 
        !           356:     if (exp == 255) {
        !           357:         /* NaN or infinity */
        !           358:         r = 1; /* VAX dirty zero */
        !           359:     } else if (exp == 0) {
        !           360:         if (mant == 0) {
        !           361:             /* Zero */
        !           362:             r = 0;
        !           363:         } else {
        !           364:             /* Denormalized */
        !           365:             r = sig | ((exp + 1) << 52) | mant;
        !           366:         }
        !           367:     } else {
        !           368:         if (exp >= 253) {
        !           369:             /* Overflow */
        !           370:             r = 1; /* VAX dirty zero */
        !           371:         } else {
        !           372:             r = sig | ((exp + 2) << 52);
        !           373:         }
        !           374:     }
        !           375: 
        !           376:     return r;
1.1       root      377: }
                    378: 
1.1.1.2 ! root      379: static always_inline float32 f_to_float32 (uint64_t a)
1.1       root      380: {
1.1.1.2 ! root      381:     uint32_t exp, mant_sig;
        !           382:     CPU_FloatU r;
        !           383: 
        !           384:     exp = ((a >> 55) & 0x80) | ((a >> 52) & 0x7f);
        !           385:     mant_sig = ((a >> 32) & 0x80000000) | ((a >> 29) & 0x007fffff);
        !           386: 
        !           387:     if (unlikely(!exp && mant_sig)) {
        !           388:         /* Reserved operands / Dirty zero */
        !           389:         helper_excp(EXCP_OPCDEC, 0);
        !           390:     }
        !           391: 
        !           392:     if (exp < 3) {
        !           393:         /* Underflow */
        !           394:         r.l = 0;
        !           395:     } else {
        !           396:         r.l = ((exp - 2) << 23) | mant_sig;
        !           397:     }
        !           398: 
        !           399:     return r.f;
1.1       root      400: }
                    401: 
1.1.1.2 ! root      402: uint32_t helper_f_to_memory (uint64_t a)
1.1       root      403: {
1.1.1.2 ! root      404:     uint32_t r;
        !           405:     r =  (a & 0x00001fffe0000000ull) >> 13;
        !           406:     r |= (a & 0x07ffe00000000000ull) >> 45;
        !           407:     r |= (a & 0xc000000000000000ull) >> 48;
        !           408:     return r;
1.1       root      409: }
                    410: 
1.1.1.2 ! root      411: uint64_t helper_memory_to_f (uint32_t a)
1.1       root      412: {
1.1.1.2 ! root      413:     uint64_t r;
        !           414:     r =  ((uint64_t)(a & 0x0000c000)) << 48;
        !           415:     r |= ((uint64_t)(a & 0x003fffff)) << 45;
        !           416:     r |= ((uint64_t)(a & 0xffff0000)) << 13;
        !           417:     if (!(a & 0x00004000))
        !           418:         r |= 0x7ll << 59;
        !           419:     return r;
1.1       root      420: }
                    421: 
1.1.1.2 ! root      422: uint64_t helper_addf (uint64_t a, uint64_t b)
1.1       root      423: {
1.1.1.2 ! root      424:     float32 fa, fb, fr;
1.1       root      425: 
1.1.1.2 ! root      426:     fa = f_to_float32(a);
        !           427:     fb = f_to_float32(b);
        !           428:     fr = float32_add(fa, fb, &FP_STATUS);
        !           429:     return float32_to_f(fr);
1.1       root      430: }
                    431: 
1.1.1.2 ! root      432: uint64_t helper_subf (uint64_t a, uint64_t b)
1.1       root      433: {
1.1.1.2 ! root      434:     float32 fa, fb, fr;
1.1       root      435: 
1.1.1.2 ! root      436:     fa = f_to_float32(a);
        !           437:     fb = f_to_float32(b);
        !           438:     fr = float32_sub(fa, fb, &FP_STATUS);
        !           439:     return float32_to_f(fr);
1.1       root      440: }
                    441: 
1.1.1.2 ! root      442: uint64_t helper_mulf (uint64_t a, uint64_t b)
1.1       root      443: {
1.1.1.2 ! root      444:     float32 fa, fb, fr;
1.1       root      445: 
1.1.1.2 ! root      446:     fa = f_to_float32(a);
        !           447:     fb = f_to_float32(b);
        !           448:     fr = float32_mul(fa, fb, &FP_STATUS);
        !           449:     return float32_to_f(fr);
1.1       root      450: }
                    451: 
1.1.1.2 ! root      452: uint64_t helper_divf (uint64_t a, uint64_t b)
1.1       root      453: {
1.1.1.2 ! root      454:     float32 fa, fb, fr;
1.1       root      455: 
1.1.1.2 ! root      456:     fa = f_to_float32(a);
        !           457:     fb = f_to_float32(b);
        !           458:     fr = float32_div(fa, fb, &FP_STATUS);
        !           459:     return float32_to_f(fr);
1.1       root      460: }
                    461: 
1.1.1.2 ! root      462: uint64_t helper_sqrtf (uint64_t t)
1.1       root      463: {
1.1.1.2 ! root      464:     float32 ft, fr;
1.1       root      465: 
1.1.1.2 ! root      466:     ft = f_to_float32(t);
        !           467:     fr = float32_sqrt(ft, &FP_STATUS);
        !           468:     return float32_to_f(fr);
1.1       root      469: }
                    470: 
1.1.1.2 ! root      471: 
        !           472: /* G floating (VAX) */
        !           473: static always_inline uint64_t float64_to_g (float64 fa)
1.1       root      474: {
1.1.1.2 ! root      475:     uint64_t r, exp, mant, sig;
        !           476:     CPU_DoubleU a;
        !           477: 
        !           478:     a.d = fa;
        !           479:     sig = a.ll & 0x8000000000000000ull;
        !           480:     exp = (a.ll >> 52) & 0x7ff;
        !           481:     mant = a.ll & 0x000fffffffffffffull;
        !           482: 
        !           483:     if (exp == 2047) {
        !           484:         /* NaN or infinity */
        !           485:         r = 1; /* VAX dirty zero */
        !           486:     } else if (exp == 0) {
        !           487:         if (mant == 0) {
        !           488:             /* Zero */
        !           489:             r = 0;
        !           490:         } else {
        !           491:             /* Denormalized */
        !           492:             r = sig | ((exp + 1) << 52) | mant;
        !           493:         }
        !           494:     } else {
        !           495:         if (exp >= 2045) {
        !           496:             /* Overflow */
        !           497:             r = 1; /* VAX dirty zero */
        !           498:         } else {
        !           499:             r = sig | ((exp + 2) << 52);
        !           500:         }
        !           501:     }
1.1       root      502: 
1.1.1.2 ! root      503:     return r;
1.1       root      504: }
                    505: 
1.1.1.2 ! root      506: static always_inline float64 g_to_float64 (uint64_t a)
1.1       root      507: {
1.1.1.2 ! root      508:     uint64_t exp, mant_sig;
        !           509:     CPU_DoubleU r;
        !           510: 
        !           511:     exp = (a >> 52) & 0x7ff;
        !           512:     mant_sig = a & 0x800fffffffffffffull;
        !           513: 
        !           514:     if (!exp && mant_sig) {
        !           515:         /* Reserved operands / Dirty zero */
        !           516:         helper_excp(EXCP_OPCDEC, 0);
        !           517:     }
1.1       root      518: 
1.1.1.2 ! root      519:     if (exp < 3) {
        !           520:         /* Underflow */
        !           521:         r.ll = 0;
        !           522:     } else {
        !           523:         r.ll = ((exp - 2) << 52) | mant_sig;
        !           524:     }
        !           525: 
        !           526:     return r.d;
1.1       root      527: }
                    528: 
1.1.1.2 ! root      529: uint64_t helper_g_to_memory (uint64_t a)
1.1       root      530: {
1.1.1.2 ! root      531:     uint64_t r;
        !           532:     r =  (a & 0x000000000000ffffull) << 48;
        !           533:     r |= (a & 0x00000000ffff0000ull) << 16;
        !           534:     r |= (a & 0x0000ffff00000000ull) >> 16;
        !           535:     r |= (a & 0xffff000000000000ull) >> 48;
        !           536:     return r;
1.1       root      537: }
                    538: 
1.1.1.2 ! root      539: uint64_t helper_memory_to_g (uint64_t a)
1.1       root      540: {
1.1.1.2 ! root      541:     uint64_t r;
        !           542:     r =  (a & 0x000000000000ffffull) << 48;
        !           543:     r |= (a & 0x00000000ffff0000ull) << 16;
        !           544:     r |= (a & 0x0000ffff00000000ull) >> 16;
        !           545:     r |= (a & 0xffff000000000000ull) >> 48;
        !           546:     return r;
1.1       root      547: }
                    548: 
1.1.1.2 ! root      549: uint64_t helper_addg (uint64_t a, uint64_t b)
1.1       root      550: {
1.1.1.2 ! root      551:     float64 fa, fb, fr;
1.1       root      552: 
1.1.1.2 ! root      553:     fa = g_to_float64(a);
        !           554:     fb = g_to_float64(b);
        !           555:     fr = float64_add(fa, fb, &FP_STATUS);
        !           556:     return float64_to_g(fr);
1.1       root      557: }
                    558: 
1.1.1.2 ! root      559: uint64_t helper_subg (uint64_t a, uint64_t b)
1.1       root      560: {
1.1.1.2 ! root      561:     float64 fa, fb, fr;
1.1       root      562: 
1.1.1.2 ! root      563:     fa = g_to_float64(a);
        !           564:     fb = g_to_float64(b);
        !           565:     fr = float64_sub(fa, fb, &FP_STATUS);
        !           566:     return float64_to_g(fr);
1.1       root      567: }
                    568: 
1.1.1.2 ! root      569: uint64_t helper_mulg (uint64_t a, uint64_t b)
1.1       root      570: {
1.1.1.2 ! root      571:     float64 fa, fb, fr;
1.1       root      572: 
1.1.1.2 ! root      573:     fa = g_to_float64(a);
        !           574:     fb = g_to_float64(b);
        !           575:     fr = float64_mul(fa, fb, &FP_STATUS);
        !           576:     return float64_to_g(fr);
1.1       root      577: }
                    578: 
1.1.1.2 ! root      579: uint64_t helper_divg (uint64_t a, uint64_t b)
1.1       root      580: {
1.1.1.2 ! root      581:     float64 fa, fb, fr;
1.1       root      582: 
1.1.1.2 ! root      583:     fa = g_to_float64(a);
        !           584:     fb = g_to_float64(b);
        !           585:     fr = float64_div(fa, fb, &FP_STATUS);
        !           586:     return float64_to_g(fr);
1.1       root      587: }
                    588: 
1.1.1.2 ! root      589: uint64_t helper_sqrtg (uint64_t a)
1.1       root      590: {
1.1.1.2 ! root      591:     float64 fa, fr;
1.1       root      592: 
1.1.1.2 ! root      593:     fa = g_to_float64(a);
        !           594:     fr = float64_sqrt(fa, &FP_STATUS);
        !           595:     return float64_to_g(fr);
1.1       root      596: }
                    597: 
1.1.1.2 ! root      598: 
        !           599: /* S floating (single) */
        !           600: static always_inline uint64_t float32_to_s (float32 fa)
1.1       root      601: {
1.1.1.2 ! root      602:     CPU_FloatU a;
        !           603:     uint64_t r;
1.1       root      604: 
1.1.1.2 ! root      605:     a.f = fa;
1.1       root      606: 
1.1.1.2 ! root      607:     r = (((uint64_t)(a.l & 0xc0000000)) << 32) | (((uint64_t)(a.l & 0x3fffffff)) << 29);
        !           608:     if (((a.l & 0x7f800000) != 0x7f800000) && (!(a.l & 0x40000000)))
        !           609:         r |= 0x7ll << 59;
        !           610:     return r;
1.1       root      611: }
                    612: 
1.1.1.2 ! root      613: static always_inline float32 s_to_float32 (uint64_t a)
1.1       root      614: {
1.1.1.2 ! root      615:     CPU_FloatU r;
        !           616:     r.l = ((a >> 32) & 0xc0000000) | ((a >> 29) & 0x3fffffff);
        !           617:     return r.f;
        !           618: }
1.1       root      619: 
1.1.1.2 ! root      620: uint32_t helper_s_to_memory (uint64_t a)
        !           621: {
        !           622:     /* Memory format is the same as float32 */
        !           623:     float32 fa = s_to_float32(a);
        !           624:     return *(uint32_t*)(&fa);
1.1       root      625: }
                    626: 
1.1.1.2 ! root      627: uint64_t helper_memory_to_s (uint32_t a)
1.1       root      628: {
1.1.1.2 ! root      629:     /* Memory format is the same as float32 */
        !           630:     return float32_to_s(*(float32*)(&a));
        !           631: }
1.1       root      632: 
1.1.1.2 ! root      633: uint64_t helper_adds (uint64_t a, uint64_t b)
        !           634: {
        !           635:     float32 fa, fb, fr;
1.1       root      636: 
1.1.1.2 ! root      637:     fa = s_to_float32(a);
        !           638:     fb = s_to_float32(b);
        !           639:     fr = float32_add(fa, fb, &FP_STATUS);
        !           640:     return float32_to_s(fr);
1.1       root      641: }
                    642: 
1.1.1.2 ! root      643: uint64_t helper_subs (uint64_t a, uint64_t b)
1.1       root      644: {
1.1.1.2 ! root      645:     float32 fa, fb, fr;
1.1       root      646: 
1.1.1.2 ! root      647:     fa = s_to_float32(a);
        !           648:     fb = s_to_float32(b);
        !           649:     fr = float32_sub(fa, fb, &FP_STATUS);
        !           650:     return float32_to_s(fr);
1.1       root      651: }
                    652: 
1.1.1.2 ! root      653: uint64_t helper_muls (uint64_t a, uint64_t b)
1.1       root      654: {
1.1.1.2 ! root      655:     float32 fa, fb, fr;
1.1       root      656: 
1.1.1.2 ! root      657:     fa = s_to_float32(a);
        !           658:     fb = s_to_float32(b);
        !           659:     fr = float32_mul(fa, fb, &FP_STATUS);
        !           660:     return float32_to_s(fr);
1.1       root      661: }
                    662: 
1.1.1.2 ! root      663: uint64_t helper_divs (uint64_t a, uint64_t b)
1.1       root      664: {
1.1.1.2 ! root      665:     float32 fa, fb, fr;
1.1       root      666: 
1.1.1.2 ! root      667:     fa = s_to_float32(a);
        !           668:     fb = s_to_float32(b);
        !           669:     fr = float32_div(fa, fb, &FP_STATUS);
        !           670:     return float32_to_s(fr);
1.1       root      671: }
                    672: 
1.1.1.2 ! root      673: uint64_t helper_sqrts (uint64_t a)
1.1       root      674: {
1.1.1.2 ! root      675:     float32 fa, fr;
1.1       root      676: 
1.1.1.2 ! root      677:     fa = s_to_float32(a);
        !           678:     fr = float32_sqrt(fa, &FP_STATUS);
        !           679:     return float32_to_s(fr);
1.1       root      680: }
                    681: 
                    682: 
1.1.1.2 ! root      683: /* T floating (double) */
        !           684: static always_inline float64 t_to_float64 (uint64_t a)
        !           685: {
        !           686:     /* Memory format is the same as float64 */
        !           687:     CPU_DoubleU r;
        !           688:     r.ll = a;
        !           689:     return r.d;
1.1       root      690: }
                    691: 
1.1.1.2 ! root      692: static always_inline uint64_t float64_to_t (float64 fa)
1.1       root      693: {
1.1.1.2 ! root      694:     /* Memory format is the same as float64 */
        !           695:     CPU_DoubleU r;
        !           696:     r.d = fa;
        !           697:     return r.ll;
1.1       root      698: }
                    699: 
1.1.1.2 ! root      700: uint64_t helper_addt (uint64_t a, uint64_t b)
1.1       root      701: {
1.1.1.2 ! root      702:     float64 fa, fb, fr;
1.1       root      703: 
1.1.1.2 ! root      704:     fa = t_to_float64(a);
        !           705:     fb = t_to_float64(b);
        !           706:     fr = float64_add(fa, fb, &FP_STATUS);
        !           707:     return float64_to_t(fr);
1.1       root      708: }
                    709: 
1.1.1.2 ! root      710: uint64_t helper_subt (uint64_t a, uint64_t b)
1.1       root      711: {
1.1.1.2 ! root      712:     float64 fa, fb, fr;
1.1       root      713: 
1.1.1.2 ! root      714:     fa = t_to_float64(a);
        !           715:     fb = t_to_float64(b);
        !           716:     fr = float64_sub(fa, fb, &FP_STATUS);
        !           717:     return float64_to_t(fr);
1.1       root      718: }
                    719: 
1.1.1.2 ! root      720: uint64_t helper_mult (uint64_t a, uint64_t b)
1.1       root      721: {
1.1.1.2 ! root      722:     float64 fa, fb, fr;
1.1       root      723: 
1.1.1.2 ! root      724:     fa = t_to_float64(a);
        !           725:     fb = t_to_float64(b);
        !           726:     fr = float64_mul(fa, fb, &FP_STATUS);
        !           727:     return float64_to_t(fr);
1.1       root      728: }
                    729: 
1.1.1.2 ! root      730: uint64_t helper_divt (uint64_t a, uint64_t b)
1.1       root      731: {
1.1.1.2 ! root      732:     float64 fa, fb, fr;
1.1       root      733: 
1.1.1.2 ! root      734:     fa = t_to_float64(a);
        !           735:     fb = t_to_float64(b);
        !           736:     fr = float64_div(fa, fb, &FP_STATUS);
        !           737:     return float64_to_t(fr);
1.1       root      738: }
                    739: 
1.1.1.2 ! root      740: uint64_t helper_sqrtt (uint64_t a)
1.1       root      741: {
1.1.1.2 ! root      742:     float64 fa, fr;
1.1       root      743: 
1.1.1.2 ! root      744:     fa = t_to_float64(a);
        !           745:     fr = float64_sqrt(fa, &FP_STATUS);
        !           746:     return float64_to_t(fr);
1.1       root      747: }
                    748: 
                    749: 
1.1.1.2 ! root      750: /* Sign copy */
        !           751: uint64_t helper_cpys(uint64_t a, uint64_t b)
        !           752: {
        !           753:     return (a & 0x8000000000000000ULL) | (b & ~0x8000000000000000ULL);
1.1       root      754: }
                    755: 
1.1.1.2 ! root      756: uint64_t helper_cpysn(uint64_t a, uint64_t b)
1.1       root      757: {
1.1.1.2 ! root      758:     return ((~a) & 0x8000000000000000ULL) | (b & ~0x8000000000000000ULL);
        !           759: }
1.1       root      760: 
1.1.1.2 ! root      761: uint64_t helper_cpyse(uint64_t a, uint64_t b)
        !           762: {
        !           763:     return (a & 0xFFF0000000000000ULL) | (b & ~0xFFF0000000000000ULL);
1.1       root      764: }
                    765: 
1.1.1.2 ! root      766: 
        !           767: /* Comparisons */
        !           768: uint64_t helper_cmptun (uint64_t a, uint64_t b)
1.1       root      769: {
1.1.1.2 ! root      770:     float64 fa, fb;
1.1       root      771: 
1.1.1.2 ! root      772:     fa = t_to_float64(a);
        !           773:     fb = t_to_float64(b);
        !           774: 
        !           775:     if (float64_is_nan(fa) || float64_is_nan(fb))
        !           776:         return 0x4000000000000000ULL;
        !           777:     else
        !           778:         return 0;
1.1       root      779: }
                    780: 
1.1.1.2 ! root      781: uint64_t helper_cmpteq(uint64_t a, uint64_t b)
1.1       root      782: {
1.1.1.2 ! root      783:     float64 fa, fb;
1.1       root      784: 
1.1.1.2 ! root      785:     fa = t_to_float64(a);
        !           786:     fb = t_to_float64(b);
        !           787: 
        !           788:     if (float64_eq(fa, fb, &FP_STATUS))
        !           789:         return 0x4000000000000000ULL;
        !           790:     else
        !           791:         return 0;
1.1       root      792: }
                    793: 
1.1.1.2 ! root      794: uint64_t helper_cmptle(uint64_t a, uint64_t b)
1.1       root      795: {
1.1.1.2 ! root      796:     float64 fa, fb;
1.1       root      797: 
1.1.1.2 ! root      798:     fa = t_to_float64(a);
        !           799:     fb = t_to_float64(b);
        !           800: 
        !           801:     if (float64_le(fa, fb, &FP_STATUS))
        !           802:         return 0x4000000000000000ULL;
        !           803:     else
        !           804:         return 0;
1.1       root      805: }
                    806: 
1.1.1.2 ! root      807: uint64_t helper_cmptlt(uint64_t a, uint64_t b)
1.1       root      808: {
1.1.1.2 ! root      809:     float64 fa, fb;
1.1       root      810: 
1.1.1.2 ! root      811:     fa = t_to_float64(a);
        !           812:     fb = t_to_float64(b);
        !           813: 
        !           814:     if (float64_lt(fa, fb, &FP_STATUS))
        !           815:         return 0x4000000000000000ULL;
        !           816:     else
        !           817:         return 0;
1.1       root      818: }
                    819: 
1.1.1.2 ! root      820: uint64_t helper_cmpgeq(uint64_t a, uint64_t b)
1.1       root      821: {
1.1.1.2 ! root      822:     float64 fa, fb;
        !           823: 
        !           824:     fa = g_to_float64(a);
        !           825:     fb = g_to_float64(b);
1.1       root      826: 
1.1.1.2 ! root      827:     if (float64_eq(fa, fb, &FP_STATUS))
        !           828:         return 0x4000000000000000ULL;
        !           829:     else
        !           830:         return 0;
1.1       root      831: }
                    832: 
1.1.1.2 ! root      833: uint64_t helper_cmpgle(uint64_t a, uint64_t b)
1.1       root      834: {
1.1.1.2 ! root      835:     float64 fa, fb;
1.1       root      836: 
1.1.1.2 ! root      837:     fa = g_to_float64(a);
        !           838:     fb = g_to_float64(b);
        !           839: 
        !           840:     if (float64_le(fa, fb, &FP_STATUS))
        !           841:         return 0x4000000000000000ULL;
        !           842:     else
        !           843:         return 0;
1.1       root      844: }
                    845: 
1.1.1.2 ! root      846: uint64_t helper_cmpglt(uint64_t a, uint64_t b)
1.1       root      847: {
1.1.1.2 ! root      848:     float64 fa, fb;
        !           849: 
        !           850:     fa = g_to_float64(a);
        !           851:     fb = g_to_float64(b);
1.1       root      852: 
1.1.1.2 ! root      853:     if (float64_lt(fa, fb, &FP_STATUS))
        !           854:         return 0x4000000000000000ULL;
        !           855:     else
        !           856:         return 0;
1.1       root      857: }
                    858: 
1.1.1.2 ! root      859: uint64_t helper_cmpfeq (uint64_t a)
1.1       root      860: {
1.1.1.2 ! root      861:     return !(a & 0x7FFFFFFFFFFFFFFFULL);
        !           862: }
1.1       root      863: 
1.1.1.2 ! root      864: uint64_t helper_cmpfne (uint64_t a)
        !           865: {
        !           866:     return (a & 0x7FFFFFFFFFFFFFFFULL);
1.1       root      867: }
                    868: 
1.1.1.2 ! root      869: uint64_t helper_cmpflt (uint64_t a)
1.1       root      870: {
1.1.1.2 ! root      871:     return (a & 0x8000000000000000ULL) && (a & 0x7FFFFFFFFFFFFFFFULL);
        !           872: }
1.1       root      873: 
1.1.1.2 ! root      874: uint64_t helper_cmpfle (uint64_t a)
        !           875: {
        !           876:     return (a & 0x8000000000000000ULL) || !(a & 0x7FFFFFFFFFFFFFFFULL);
1.1       root      877: }
                    878: 
1.1.1.2 ! root      879: uint64_t helper_cmpfgt (uint64_t a)
1.1       root      880: {
1.1.1.2 ! root      881:     return !(a & 0x8000000000000000ULL) && (a & 0x7FFFFFFFFFFFFFFFULL);
1.1       root      882: }
                    883: 
1.1.1.2 ! root      884: uint64_t helper_cmpfge (uint64_t a)
1.1       root      885: {
1.1.1.2 ! root      886:     return !(a & 0x8000000000000000ULL) || !(a & 0x7FFFFFFFFFFFFFFFULL);
        !           887: }
        !           888: 
1.1       root      889: 
1.1.1.2 ! root      890: /* Floating point format conversion */
        !           891: uint64_t helper_cvtts (uint64_t a)
        !           892: {
        !           893:     float64 fa;
        !           894:     float32 fr;
        !           895: 
        !           896:     fa = t_to_float64(a);
        !           897:     fr = float64_to_float32(fa, &FP_STATUS);
        !           898:     return float32_to_s(fr);
1.1       root      899: }
                    900: 
1.1.1.2 ! root      901: uint64_t helper_cvtst (uint64_t a)
1.1       root      902: {
1.1.1.2 ! root      903:     float32 fa;
        !           904:     float64 fr;
1.1       root      905: 
1.1.1.2 ! root      906:     fa = s_to_float32(a);
        !           907:     fr = float32_to_float64(fa, &FP_STATUS);
        !           908:     return float64_to_t(fr);
1.1       root      909: }
                    910: 
1.1.1.2 ! root      911: uint64_t helper_cvtqs (uint64_t a)
1.1       root      912: {
1.1.1.2 ! root      913:     float32 fr = int64_to_float32(a, &FP_STATUS);
        !           914:     return float32_to_s(fr);
1.1       root      915: }
                    916: 
1.1.1.2 ! root      917: uint64_t helper_cvttq (uint64_t a)
1.1       root      918: {
1.1.1.2 ! root      919:     float64 fa = t_to_float64(a);
        !           920:     return float64_to_int64_round_to_zero(fa, &FP_STATUS);
1.1       root      921: }
                    922: 
1.1.1.2 ! root      923: uint64_t helper_cvtqt (uint64_t a)
1.1       root      924: {
1.1.1.2 ! root      925:     float64 fr = int64_to_float64(a, &FP_STATUS);
        !           926:     return float64_to_t(fr);
1.1       root      927: }
                    928: 
1.1.1.2 ! root      929: uint64_t helper_cvtqf (uint64_t a)
1.1       root      930: {
1.1.1.2 ! root      931:     float32 fr = int64_to_float32(a, &FP_STATUS);
        !           932:     return float32_to_f(fr);
1.1       root      933: }
                    934: 
1.1.1.2 ! root      935: uint64_t helper_cvtgf (uint64_t a)
1.1       root      936: {
1.1.1.2 ! root      937:     float64 fa;
        !           938:     float32 fr;
        !           939: 
        !           940:     fa = g_to_float64(a);
        !           941:     fr = float64_to_float32(fa, &FP_STATUS);
        !           942:     return float32_to_f(fr);
1.1       root      943: }
                    944: 
1.1.1.2 ! root      945: uint64_t helper_cvtgq (uint64_t a)
1.1       root      946: {
1.1.1.2 ! root      947:     float64 fa = g_to_float64(a);
        !           948:     return float64_to_int64_round_to_zero(fa, &FP_STATUS);
1.1       root      949: }
                    950: 
1.1.1.2 ! root      951: uint64_t helper_cvtqg (uint64_t a)
1.1       root      952: {
1.1.1.2 ! root      953:     float64 fr;
        !           954:     fr = int64_to_float64(a, &FP_STATUS);
        !           955:     return float64_to_g(fr);
1.1       root      956: }
                    957: 
1.1.1.2 ! root      958: uint64_t helper_cvtlq (uint64_t a)
1.1       root      959: {
1.1.1.2 ! root      960:     return (int64_t)((int32_t)((a >> 32) | ((a >> 29) & 0x3FFFFFFF)));
1.1       root      961: }
                    962: 
1.1.1.2 ! root      963: static always_inline uint64_t __helper_cvtql (uint64_t a, int s, int v)
1.1       root      964: {
1.1.1.2 ! root      965:     uint64_t r;
        !           966: 
        !           967:     r = ((uint64_t)(a & 0xC0000000)) << 32;
        !           968:     r |= ((uint64_t)(a & 0x7FFFFFFF)) << 29;
        !           969: 
        !           970:     if (v && (int64_t)((int32_t)r) != (int64_t)r) {
        !           971:         helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
        !           972:     }
        !           973:     if (s) {
        !           974:         /* TODO */
        !           975:     }
        !           976:     return r;
1.1       root      977: }
                    978: 
1.1.1.2 ! root      979: uint64_t helper_cvtql (uint64_t a)
1.1       root      980: {
1.1.1.2 ! root      981:     return __helper_cvtql(a, 0, 0);
1.1       root      982: }
                    983: 
1.1.1.2 ! root      984: uint64_t helper_cvtqlv (uint64_t a)
1.1       root      985: {
1.1.1.2 ! root      986:     return __helper_cvtql(a, 0, 1);
        !           987: }
        !           988: 
        !           989: uint64_t helper_cvtqlsv (uint64_t a)
        !           990: {
        !           991:     return __helper_cvtql(a, 1, 1);
1.1       root      992: }
                    993: 
1.1.1.2 ! root      994: /* PALcode support special instructions */
1.1       root      995: #if !defined (CONFIG_USER_ONLY)
1.1.1.2 ! root      996: void helper_hw_rei (void)
1.1       root      997: {
1.1.1.2 ! root      998:     env->pc = env->ipr[IPR_EXC_ADDR] & ~3;
        !           999:     env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
        !          1000:     /* XXX: re-enable interrupts and memory mapping */
        !          1001: }
1.1       root     1002: 
1.1.1.2 ! root     1003: void helper_hw_ret (uint64_t a)
        !          1004: {
        !          1005:     env->pc = a & ~3;
        !          1006:     env->ipr[IPR_EXC_ADDR] = a & 1;
        !          1007:     /* XXX: re-enable interrupts and memory mapping */
1.1       root     1008: }
                   1009: 
1.1.1.2 ! root     1010: uint64_t helper_mfpr (int iprn, uint64_t val)
1.1       root     1011: {
1.1.1.2 ! root     1012:     uint64_t tmp;
        !          1013: 
        !          1014:     if (cpu_alpha_mfpr(env, iprn, &tmp) == 0)
        !          1015:         val = tmp;
        !          1016: 
        !          1017:     return val;
1.1       root     1018: }
                   1019: 
1.1.1.2 ! root     1020: void helper_mtpr (int iprn, uint64_t val)
1.1       root     1021: {
1.1.1.2 ! root     1022:     cpu_alpha_mtpr(env, iprn, val, NULL);
1.1       root     1023: }
                   1024: 
1.1.1.2 ! root     1025: void helper_set_alt_mode (void)
1.1       root     1026: {
1.1.1.2 ! root     1027:     env->saved_mode = env->ps & 0xC;
        !          1028:     env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC);
1.1       root     1029: }
                   1030: 
1.1.1.2 ! root     1031: void helper_restore_mode (void)
1.1       root     1032: {
1.1.1.2 ! root     1033:     env->ps = (env->ps & ~0xC) | env->saved_mode;
1.1       root     1034: }
1.1.1.2 ! root     1035: 
1.1       root     1036: #endif
                   1037: 
                   1038: /*****************************************************************************/
                   1039: /* Softmmu support */
                   1040: #if !defined (CONFIG_USER_ONLY)
                   1041: 
                   1042: /* XXX: the two following helpers are pure hacks.
                   1043:  *      Hopefully, we emulate the PALcode, then we should never see
                   1044:  *      HW_LD / HW_ST instructions.
                   1045:  */
1.1.1.2 ! root     1046: uint64_t helper_ld_virt_to_phys (uint64_t virtaddr)
1.1       root     1047: {
                   1048:     uint64_t tlb_addr, physaddr;
                   1049:     int index, mmu_idx;
                   1050:     void *retaddr;
                   1051: 
                   1052:     mmu_idx = cpu_mmu_index(env);
1.1.1.2 ! root     1053:     index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1.1       root     1054:  redo:
                   1055:     tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
1.1.1.2 ! root     1056:     if ((virtaddr & TARGET_PAGE_MASK) ==
1.1       root     1057:         (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
1.1.1.2 ! root     1058:         physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend;
1.1       root     1059:     } else {
                   1060:         /* the page is not in the TLB : fill it */
                   1061:         retaddr = GETPC();
1.1.1.2 ! root     1062:         tlb_fill(virtaddr, 0, mmu_idx, retaddr);
1.1       root     1063:         goto redo;
                   1064:     }
1.1.1.2 ! root     1065:     return physaddr;
1.1       root     1066: }
                   1067: 
1.1.1.2 ! root     1068: uint64_t helper_st_virt_to_phys (uint64_t virtaddr)
1.1       root     1069: {
                   1070:     uint64_t tlb_addr, physaddr;
                   1071:     int index, mmu_idx;
                   1072:     void *retaddr;
                   1073: 
                   1074:     mmu_idx = cpu_mmu_index(env);
1.1.1.2 ! root     1075:     index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1.1       root     1076:  redo:
                   1077:     tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
1.1.1.2 ! root     1078:     if ((virtaddr & TARGET_PAGE_MASK) ==
1.1       root     1079:         (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
1.1.1.2 ! root     1080:         physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend;
1.1       root     1081:     } else {
                   1082:         /* the page is not in the TLB : fill it */
                   1083:         retaddr = GETPC();
1.1.1.2 ! root     1084:         tlb_fill(virtaddr, 1, mmu_idx, retaddr);
1.1       root     1085:         goto redo;
                   1086:     }
1.1.1.2 ! root     1087:     return physaddr;
        !          1088: }
        !          1089: 
        !          1090: void helper_ldl_raw(uint64_t t0, uint64_t t1)
        !          1091: {
        !          1092:     ldl_raw(t1, t0);
        !          1093: }
        !          1094: 
        !          1095: void helper_ldq_raw(uint64_t t0, uint64_t t1)
        !          1096: {
        !          1097:     ldq_raw(t1, t0);
        !          1098: }
        !          1099: 
        !          1100: void helper_ldl_l_raw(uint64_t t0, uint64_t t1)
        !          1101: {
        !          1102:     env->lock = t1;
        !          1103:     ldl_raw(t1, t0);
        !          1104: }
        !          1105: 
        !          1106: void helper_ldq_l_raw(uint64_t t0, uint64_t t1)
        !          1107: {
        !          1108:     env->lock = t1;
        !          1109:     ldl_raw(t1, t0);
        !          1110: }
        !          1111: 
        !          1112: void helper_ldl_kernel(uint64_t t0, uint64_t t1)
        !          1113: {
        !          1114:     ldl_kernel(t1, t0);
        !          1115: }
        !          1116: 
        !          1117: void helper_ldq_kernel(uint64_t t0, uint64_t t1)
        !          1118: {
        !          1119:     ldq_kernel(t1, t0);
        !          1120: }
        !          1121: 
        !          1122: void helper_ldl_data(uint64_t t0, uint64_t t1)
        !          1123: {
        !          1124:     ldl_data(t1, t0);
        !          1125: }
        !          1126: 
        !          1127: void helper_ldq_data(uint64_t t0, uint64_t t1)
        !          1128: {
        !          1129:     ldq_data(t1, t0);
        !          1130: }
        !          1131: 
        !          1132: void helper_stl_raw(uint64_t t0, uint64_t t1)
        !          1133: {
        !          1134:     stl_raw(t1, t0);
        !          1135: }
        !          1136: 
        !          1137: void helper_stq_raw(uint64_t t0, uint64_t t1)
        !          1138: {
        !          1139:     stq_raw(t1, t0);
        !          1140: }
        !          1141: 
        !          1142: uint64_t helper_stl_c_raw(uint64_t t0, uint64_t t1)
        !          1143: {
        !          1144:     uint64_t ret;
        !          1145: 
        !          1146:     if (t1 == env->lock) {
        !          1147:         stl_raw(t1, t0);
        !          1148:         ret = 0;
        !          1149:     } else
        !          1150:         ret = 1;
        !          1151: 
        !          1152:     env->lock = 1;
        !          1153: 
        !          1154:     return ret;
        !          1155: }
        !          1156: 
        !          1157: uint64_t helper_stq_c_raw(uint64_t t0, uint64_t t1)
        !          1158: {
        !          1159:     uint64_t ret;
        !          1160: 
        !          1161:     if (t1 == env->lock) {
        !          1162:         stq_raw(t1, t0);
        !          1163:         ret = 0;
        !          1164:     } else
        !          1165:         ret = 1;
        !          1166: 
        !          1167:     env->lock = 1;
        !          1168: 
        !          1169:     return ret;
1.1       root     1170: }
                   1171: 
                   1172: #define MMUSUFFIX _mmu
                   1173: 
                   1174: #define SHIFT 0
                   1175: #include "softmmu_template.h"
                   1176: 
                   1177: #define SHIFT 1
                   1178: #include "softmmu_template.h"
                   1179: 
                   1180: #define SHIFT 2
                   1181: #include "softmmu_template.h"
                   1182: 
                   1183: #define SHIFT 3
                   1184: #include "softmmu_template.h"
                   1185: 
                   1186: /* try to fill the TLB and return an exception if error. If retaddr is
                   1187:    NULL, it means that the function was called in C code (i.e. not
                   1188:    from generated code or from helper.c) */
                   1189: /* XXX: fix it to restore all registers */
                   1190: void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
                   1191: {
                   1192:     TranslationBlock *tb;
                   1193:     CPUState *saved_env;
                   1194:     unsigned long pc;
                   1195:     int ret;
                   1196: 
                   1197:     /* XXX: hack to restore env in all cases, even if not called from
                   1198:        generated code */
                   1199:     saved_env = env;
                   1200:     env = cpu_single_env;
                   1201:     ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
                   1202:     if (!likely(ret == 0)) {
                   1203:         if (likely(retaddr)) {
                   1204:             /* now we have a real cpu fault */
                   1205:             pc = (unsigned long)retaddr;
                   1206:             tb = tb_find_pc(pc);
                   1207:             if (likely(tb)) {
                   1208:                 /* the PC is inside the translated code. It means that we have
                   1209:                    a virtual CPU fault */
                   1210:                 cpu_restore_state(tb, env, pc, NULL);
                   1211:             }
                   1212:         }
                   1213:         /* Exception index and error code are already set */
                   1214:         cpu_loop_exit();
                   1215:     }
                   1216:     env = saved_env;
                   1217: }
                   1218: 
                   1219: #endif

unix.superglobalmegacorp.com

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