Revision 8443effb

b/fpu/softfloat.h
187 187
    signed char float_detect_tininess;
188 188
    signed char float_rounding_mode;
189 189
    signed char float_exception_flags;
190
    signed char float_exception_mask;
191 190
#ifdef FLOATX80
192 191
    signed char floatx80_rounding_precision;
193 192
#endif
b/target-alpha/cpu.h
145 145
#define FPCR_UNFD		(1ULL << 61)
146 146
#define FPCR_UNDZ		(1ULL << 60)
147 147
#define FPCR_DYN_SHIFT		58
148
#define FPCR_DYN_CHOPPED	(0ULL << FPCR_DYN_SHIFT)
149
#define FPCR_DYN_MINUS		(1ULL << FPCR_DYN_SHIFT)
150
#define FPCR_DYN_NORMAL		(2ULL << FPCR_DYN_SHIFT)
151
#define FPCR_DYN_PLUS		(3ULL << FPCR_DYN_SHIFT)
148 152
#define FPCR_DYN_MASK		(3ULL << FPCR_DYN_SHIFT)
149 153
#define FPCR_IOV		(1ULL << 57)
150 154
#define FPCR_INE		(1ULL << 56)
......
341 345

  
342 346
struct CPUAlphaState {
343 347
    uint64_t ir[31];
344
    float64  fir[31];
345
    float_status fp_status;
346
    uint64_t fpcr;
348
    float64 fir[31];
347 349
    uint64_t pc;
348 350
    uint64_t lock;
349 351
    uint32_t pcc[2];
350 352
    uint64_t ipr[IPR_LAST];
351 353
    uint64_t ps;
352 354
    uint64_t unique;
353
    int saved_mode; /* Used for HW_LD / HW_ST */
354
    int intr_flag; /* For RC and RS */
355
    float_status fp_status;
356
    /* The following fields make up the FPCR, but in FP_STATUS format.  */
357
    uint8_t fpcr_exc_status;
358
    uint8_t fpcr_exc_mask;
359
    uint8_t fpcr_dyn_round;
360
    uint8_t fpcr_flush_to_zero;
361
    uint8_t fpcr_dnz;
362
    uint8_t fpcr_dnod;
363
    uint8_t fpcr_undz;
364

  
365
    /* Used for HW_LD / HW_ST */
366
    uint8_t saved_mode;
367
    /* For RC and RS */
368
    uint8_t intr_flag;
355 369

  
356 370
#if TARGET_LONG_BITS > HOST_LONG_BITS
357 371
    /* temporary fixed-point registers
b/target-alpha/helper.c
27 27

  
28 28
uint64_t cpu_alpha_load_fpcr (CPUState *env)
29 29
{
30
    uint64_t ret = 0;
31
    int flags, mask;
32

  
33
    flags = env->fp_status.float_exception_flags;
34
    ret |= (uint64_t) flags << 52;
35
    if (flags)
36
        ret |= FPCR_SUM;
37
    env->ipr[IPR_EXC_SUM] &= ~0x3E;
38
    env->ipr[IPR_EXC_SUM] |= flags << 1;
39

  
40
    mask = env->fp_status.float_exception_mask;
41
    if (mask & float_flag_invalid)
42
        ret |= FPCR_INVD;
43
    if (mask & float_flag_divbyzero)
44
        ret |= FPCR_DZED;
45
    if (mask & float_flag_overflow)
46
        ret |= FPCR_OVFD;
47
    if (mask & float_flag_underflow)
48
        ret |= FPCR_UNFD;
49
    if (mask & float_flag_inexact)
50
        ret |= FPCR_INED;
51

  
52
    switch (env->fp_status.float_rounding_mode) {
30
    uint64_t r = 0;
31
    uint8_t t;
32

  
33
    t = env->fpcr_exc_status;
34
    if (t) {
35
        r = FPCR_SUM;
36
        if (t & float_flag_invalid) {
37
            r |= FPCR_INV;
38
        }
39
        if (t & float_flag_divbyzero) {
40
            r |= FPCR_DZE;
41
        }
42
        if (t & float_flag_overflow) {
43
            r |= FPCR_OVF;
44
        }
45
        if (t & float_flag_underflow) {
46
            r |= FPCR_UNF;
47
        }
48
        if (t & float_flag_inexact) {
49
            r |= FPCR_INE;
50
        }
51
    }
52

  
53
    t = env->fpcr_exc_mask;
54
    if (t & float_flag_invalid) {
55
        r |= FPCR_INVD;
56
    }
57
    if (t & float_flag_divbyzero) {
58
        r |= FPCR_DZED;
59
    }
60
    if (t & float_flag_overflow) {
61
        r |= FPCR_OVFD;
62
    }
63
    if (t & float_flag_underflow) {
64
        r |= FPCR_UNFD;
65
    }
66
    if (t & float_flag_inexact) {
67
        r |= FPCR_INED;
68
    }
69

  
70
    switch (env->fpcr_dyn_round) {
53 71
    case float_round_nearest_even:
54
        ret |= 2ULL << FPCR_DYN_SHIFT;
72
        r |= FPCR_DYN_NORMAL;
55 73
        break;
56 74
    case float_round_down:
57
        ret |= 1ULL << FPCR_DYN_SHIFT;
75
        r |= FPCR_DYN_MINUS;
58 76
        break;
59 77
    case float_round_up:
60
        ret |= 3ULL << FPCR_DYN_SHIFT;
78
        r |= FPCR_DYN_PLUS;
61 79
        break;
62 80
    case float_round_to_zero:
81
        r |= FPCR_DYN_CHOPPED;
63 82
        break;
64 83
    }
65
    return ret;
84

  
85
    if (env->fpcr_dnz) {
86
        r |= FPCR_DNZ;
87
    }
88
    if (env->fpcr_dnod) {
89
        r |= FPCR_DNOD;
90
    }
91
    if (env->fpcr_undz) {
92
        r |= FPCR_UNDZ;
93
    }
94

  
95
    return r;
66 96
}
67 97

  
68 98
void cpu_alpha_store_fpcr (CPUState *env, uint64_t val)
69 99
{
70
    int round_mode, mask;
100
    uint8_t t;
71 101

  
72
    set_float_exception_flags((val >> 52) & 0x3F, &env->fp_status);
102
    t = 0;
103
    if (val & FPCR_INV) {
104
        t |= float_flag_invalid;
105
    }
106
    if (val & FPCR_DZE) {
107
        t |= float_flag_divbyzero;
108
    }
109
    if (val & FPCR_OVF) {
110
        t |= float_flag_overflow;
111
    }
112
    if (val & FPCR_UNF) {
113
        t |= float_flag_underflow;
114
    }
115
    if (val & FPCR_INE) {
116
        t |= float_flag_inexact;
117
    }
118
    env->fpcr_exc_status = t;
73 119

  
74
    mask = 0;
75
    if (val & FPCR_INVD)
76
        mask |= float_flag_invalid;
77
    if (val & FPCR_DZED)
78
        mask |= float_flag_divbyzero;
79
    if (val & FPCR_OVFD)
80
        mask |= float_flag_overflow;
81
    if (val & FPCR_UNFD)
82
        mask |= float_flag_underflow;
83
    if (val & FPCR_INED)
84
        mask |= float_flag_inexact;
85
    env->fp_status.float_exception_mask = mask;
120
    t = 0;
121
    if (val & FPCR_INVD) {
122
        t |= float_flag_invalid;
123
    }
124
    if (val & FPCR_DZED) {
125
        t |= float_flag_divbyzero;
126
    }
127
    if (val & FPCR_OVFD) {
128
        t |= float_flag_overflow;
129
    }
130
    if (val & FPCR_UNFD) {
131
        t |= float_flag_underflow;
132
    }
133
    if (val & FPCR_INED) {
134
        t |= float_flag_inexact;
135
    }
136
    env->fpcr_exc_mask = t;
86 137

  
87
    switch ((val >> FPCR_DYN_SHIFT) & 3) {
88
    case 0:
89
        round_mode = float_round_to_zero;
138
    switch (val & FPCR_DYN_MASK) {
139
    case FPCR_DYN_CHOPPED:
140
        t = float_round_to_zero;
90 141
        break;
91
    case 1:
92
        round_mode = float_round_down;
142
    case FPCR_DYN_MINUS:
143
        t = float_round_down;
93 144
        break;
94
    case 2:
95
        round_mode = float_round_nearest_even;
145
    case FPCR_DYN_NORMAL:
146
        t = float_round_nearest_even;
96 147
        break;
97
    case 3:
98
    default: /* this avoids a gcc (< 4.4) warning */
99
        round_mode = float_round_up;
148
    case FPCR_DYN_PLUS:
149
        t = float_round_up;
100 150
        break;
101 151
    }
102
    set_float_rounding_mode(round_mode, &env->fp_status);
152
    env->fpcr_dyn_round = t;
153

  
154
    env->fpcr_flush_to_zero
155
      = (val & (FPCR_UNDZ|FPCR_UNFD)) == (FPCR_UNDZ|FPCR_UNFD);
156

  
157
    env->fpcr_dnz = (val & FPCR_DNZ) != 0;
158
    env->fpcr_dnod = (val & FPCR_DNOD) != 0;
159
    env->fpcr_undz = (val & FPCR_UNDZ) != 0;
103 160
}
104 161

  
105 162
#if defined(CONFIG_USER_ONLY)

Also available in: Unified diff