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

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

unix.superglobalmegacorp.com

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