Revision f24518b5 target-alpha/op_helper.c

b/target-alpha/op_helper.c
370 370

  
371 371
/* Floating point helpers */
372 372

  
373
void helper_setroundmode (uint32_t val)
374
{
375
    set_float_rounding_mode(val, &FP_STATUS);
376
}
377

  
378
void helper_setflushzero (uint32_t val)
379
{
380
    set_flush_to_zero(val, &FP_STATUS);
381
}
382

  
383
void helper_fp_exc_clear (void)
384
{
385
    set_float_exception_flags(0, &FP_STATUS);
386
}
387

  
388
uint32_t helper_fp_exc_get (void)
389
{
390
    return get_float_exception_flags(&FP_STATUS);
391
}
392

  
393
/* Raise exceptions for ieee fp insns without software completion.
394
   In that case there are no exceptions that don't trap; the mask
395
   doesn't apply.  */
396
void helper_fp_exc_raise(uint32_t exc, uint32_t regno)
397
{
398
    if (exc) {
399
        uint32_t hw_exc = 0;
400

  
401
        env->ipr[IPR_EXC_MASK] |= 1ull << regno;
402

  
403
        if (exc & float_flag_invalid) {
404
            hw_exc |= EXC_M_INV;
405
        }
406
        if (exc & float_flag_divbyzero) {
407
            hw_exc |= EXC_M_DZE;
408
        }
409
        if (exc & float_flag_overflow) {
410
            hw_exc |= EXC_M_FOV;
411
        }
412
        if (exc & float_flag_underflow) {
413
            hw_exc |= EXC_M_UNF;
414
        }
415
        if (exc & float_flag_inexact) {
416
            hw_exc |= EXC_M_INE;
417
        }
418
        helper_excp(EXCP_ARITH, hw_exc);
419
    }
420
}
421

  
422
/* Raise exceptions for ieee fp insns with software completion.  */
423
void helper_fp_exc_raise_s(uint32_t exc, uint32_t regno)
424
{
425
    if (exc) {
426
        env->fpcr_exc_status |= exc;
427

  
428
        exc &= ~env->fpcr_exc_mask;
429
        if (exc) {
430
            helper_fp_exc_raise(exc, regno);
431
        }
432
    }
433
}
434

  
435
/* Input remapping without software completion.  Handle denormal-map-to-zero
436
   and trap for all other non-finite numbers.  */
437
uint64_t helper_ieee_input(uint64_t val)
438
{
439
    uint32_t exp = (uint32_t)(val >> 52) & 0x7ff;
440
    uint64_t frac = val & 0xfffffffffffffull;
441

  
442
    if (exp == 0) {
443
        if (frac != 0) {
444
            /* If DNZ is set flush denormals to zero on input.  */
445
            if (env->fpcr_dnz) {
446
                val &= 1ull << 63;
447
            } else {
448
                helper_excp(EXCP_ARITH, EXC_M_UNF);
449
            }
450
        }
451
    } else if (exp == 0x7ff) {
452
        /* Infinity or NaN.  */
453
        /* ??? I'm not sure these exception bit flags are correct.  I do
454
           know that the Linux kernel, at least, doesn't rely on them and
455
           just emulates the insn to figure out what exception to use.  */
456
        helper_excp(EXCP_ARITH, frac ? EXC_M_INV : EXC_M_FOV);
457
    }
458
    return val;
459
}
460

  
461
/* Similar, but does not trap for infinities.  Used for comparisons.  */
462
uint64_t helper_ieee_input_cmp(uint64_t val)
463
{
464
    uint32_t exp = (uint32_t)(val >> 52) & 0x7ff;
465
    uint64_t frac = val & 0xfffffffffffffull;
466

  
467
    if (exp == 0) {
468
        if (frac != 0) {
469
            /* If DNZ is set flush denormals to zero on input.  */
470
            if (env->fpcr_dnz) {
471
                val &= 1ull << 63;
472
            } else {
473
                helper_excp(EXCP_ARITH, EXC_M_UNF);
474
            }
475
        }
476
    } else if (exp == 0x7ff && frac) {
477
        /* NaN.  */
478
        helper_excp(EXCP_ARITH, EXC_M_INV);
479
    }
480
    return val;
481
}
482

  
483
/* Input remapping with software completion enabled.  All we have to do
484
   is handle denormal-map-to-zero; all other inputs get exceptions as
485
   needed from the actual operation.  */
486
uint64_t helper_ieee_input_s(uint64_t val)
487
{
488
    if (env->fpcr_dnz) {
489
        uint32_t exp = (uint32_t)(val >> 52) & 0x7ff;
490
        if (exp == 0) {
491
            val &= 1ull << 63;
492
        }
493
    }
494
    return val;
495
}
496

  
373 497
/* F floating (VAX) */
374 498
static inline uint64_t float32_to_f(float32 fa)
375 499
{
......
447 571
    return r;
448 572
}
449 573

  
574
/* ??? Emulating VAX arithmetic with IEEE arithmetic is wrong.  We should
575
   either implement VAX arithmetic properly or just signal invalid opcode.  */
576

  
450 577
uint64_t helper_addf (uint64_t a, uint64_t b)
451 578
{
452 579
    float32 fa, fb, fr;
......
931 1058
    return float32_to_s(fr);
932 1059
}
933 1060

  
934
uint64_t helper_cvttq (uint64_t a)
1061
/* Implement float64 to uint64 conversion without saturation -- we must
1062
   supply the truncated result.  This behaviour is used by the compiler
1063
   to get unsigned conversion for free with the same instruction.
1064

  
1065
   The VI flag is set when overflow or inexact exceptions should be raised.  */
1066

  
1067
static inline uint64_t helper_cvttq_internal(uint64_t a, int roundmode, int VI)
935 1068
{
936
    float64 fa = t_to_float64(a);
937
    return float64_to_int64_round_to_zero(fa, &FP_STATUS);
1069
    uint64_t frac, ret = 0;
1070
    uint32_t exp, sign, exc = 0;
1071
    int shift;
1072

  
1073
    sign = (a >> 63);
1074
    exp = (uint32_t)(a >> 52) & 0x7ff;
1075
    frac = a & 0xfffffffffffffull;
1076

  
1077
    if (exp == 0) {
1078
        if (unlikely(frac != 0)) {
1079
            goto do_underflow;
1080
        }
1081
    } else if (exp == 0x7ff) {
1082
        exc = (frac ? float_flag_invalid : VI ? float_flag_overflow : 0);
1083
    } else {
1084
        /* Restore implicit bit.  */
1085
        frac |= 0x10000000000000ull;
1086

  
1087
        shift = exp - 1023 - 52;
1088
        if (shift >= 0) {
1089
            /* In this case the number is so large that we must shift
1090
               the fraction left.  There is no rounding to do.  */
1091
            if (shift < 63) {
1092
                ret = frac << shift;
1093
                if (VI && (ret >> shift) != frac) {
1094
                    exc = float_flag_overflow;
1095
                }
1096
            }
1097
        } else {
1098
            uint64_t round;
1099

  
1100
            /* In this case the number is smaller than the fraction as
1101
               represented by the 52 bit number.  Here we must think
1102
               about rounding the result.  Handle this by shifting the
1103
               fractional part of the number into the high bits of ROUND.
1104
               This will let us efficiently handle round-to-nearest.  */
1105
            shift = -shift;
1106
            if (shift < 63) {
1107
                ret = frac >> shift;
1108
                round = frac << (64 - shift);
1109
            } else {
1110
                /* The exponent is so small we shift out everything.
1111
                   Leave a sticky bit for proper rounding below.  */
1112
            do_underflow:
1113
                round = 1;
1114
            }
1115

  
1116
            if (round) {
1117
                exc = (VI ? float_flag_inexact : 0);
1118
                switch (roundmode) {
1119
                case float_round_nearest_even:
1120
                    if (round == (1ull << 63)) {
1121
                        /* Fraction is exactly 0.5; round to even.  */
1122
                        ret += (ret & 1);
1123
                    } else if (round > (1ull << 63)) {
1124
                        ret += 1;
1125
                    }
1126
                    break;
1127
                case float_round_to_zero:
1128
                    break;
1129
                case float_round_up:
1130
                    ret += 1 - sign;
1131
                    break;
1132
                case float_round_down:
1133
                    ret += sign;
1134
                    break;
1135
                }
1136
            }
1137
        }
1138
        if (sign) {
1139
            ret = -ret;
1140
        }
1141
    }
1142
    if (unlikely(exc)) {
1143
        float_raise(exc, &FP_STATUS);
1144
    }
1145

  
1146
    return ret;
1147
}
1148

  
1149
uint64_t helper_cvttq(uint64_t a)
1150
{
1151
    return helper_cvttq_internal(a, FP_STATUS.float_rounding_mode, 1);
1152
}
1153

  
1154
uint64_t helper_cvttq_c(uint64_t a)
1155
{
1156
    return helper_cvttq_internal(a, float_round_to_zero, 0);
1157
}
1158

  
1159
uint64_t helper_cvttq_svic(uint64_t a)
1160
{
1161
    return helper_cvttq_internal(a, float_round_to_zero, 1);
938 1162
}
939 1163

  
940 1164
uint64_t helper_cvtqt (uint64_t a)
......
979 1203
    return (lo & 0x3FFFFFFF) | (hi & 0xc0000000);
980 1204
}
981 1205

  
982
static inline uint64_t __helper_cvtql(uint64_t a, int s, int v)
983
{
984
    uint64_t r;
985

  
986
    r = ((uint64_t)(a & 0xC0000000)) << 32;
987
    r |= ((uint64_t)(a & 0x7FFFFFFF)) << 29;
988

  
989
    if (v && (int64_t)((int32_t)r) != (int64_t)r) {
990
        helper_excp(EXCP_ARITH, EXC_M_IOV);
991
    }
992
    if (s) {
993
        /* TODO */
994
    }
995
    return r;
996
}
997

  
998 1206
uint64_t helper_cvtql (uint64_t a)
999 1207
{
1000
    return __helper_cvtql(a, 0, 0);
1208
    return ((a & 0xC0000000) << 32) | ((a & 0x7FFFFFFF) << 29);
1001 1209
}
1002 1210

  
1003
uint64_t helper_cvtqlv (uint64_t a)
1211
uint64_t helper_cvtql_v (uint64_t a)
1004 1212
{
1005
    return __helper_cvtql(a, 0, 1);
1213
    if ((int32_t)a != (int64_t)a)
1214
        helper_excp(EXCP_ARITH, EXC_M_IOV);
1215
    return helper_cvtql(a);
1006 1216
}
1007 1217

  
1008
uint64_t helper_cvtqlsv (uint64_t a)
1218
uint64_t helper_cvtql_sv (uint64_t a)
1009 1219
{
1010
    return __helper_cvtql(a, 1, 1);
1220
    /* ??? I'm pretty sure there's nothing that /sv needs to do that /v
1221
       doesn't do.  The only thing I can think is that /sv is a valid
1222
       instruction merely for completeness in the ISA.  */
1223
    return helper_cvtql_v(a);
1011 1224
}
1012 1225

  
1013 1226
/* PALcode support special instructions */

Also available in: Unified diff