~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to target/openrisc/fpu_helper.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * OpenRISC float helper routines
 
3
 *
 
4
 * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
 
5
 *                         Feng Gao <gf91597@gmail.com>
 
6
 *
 
7
 * This library is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU Lesser General Public
 
9
 * License as published by the Free Software Foundation; either
 
10
 * version 2 of the License, or (at your option) any later version.
 
11
 *
 
12
 * This library is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * Lesser General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Lesser General Public
 
18
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 
19
 */
 
20
 
 
21
#include "qemu/osdep.h"
 
22
#include "cpu.h"
 
23
#include "exec/helper-proto.h"
 
24
#include "exception.h"
 
25
 
 
26
static inline uint32_t ieee_ex_to_openrisc(OpenRISCCPU *cpu, int fexcp)
 
27
{
 
28
    int ret = 0;
 
29
    if (fexcp) {
 
30
        if (fexcp & float_flag_invalid) {
 
31
            cpu->env.fpcsr |= FPCSR_IVF;
 
32
            ret = 1;
 
33
        }
 
34
        if (fexcp & float_flag_overflow) {
 
35
            cpu->env.fpcsr |= FPCSR_OVF;
 
36
            ret = 1;
 
37
        }
 
38
        if (fexcp & float_flag_underflow) {
 
39
            cpu->env.fpcsr |= FPCSR_UNF;
 
40
            ret = 1;
 
41
        }
 
42
        if (fexcp & float_flag_divbyzero) {
 
43
            cpu->env.fpcsr |= FPCSR_DZF;
 
44
            ret = 1;
 
45
        }
 
46
        if (fexcp & float_flag_inexact) {
 
47
            cpu->env.fpcsr |= FPCSR_IXF;
 
48
            ret = 1;
 
49
        }
 
50
    }
 
51
 
 
52
    return ret;
 
53
}
 
54
 
 
55
static inline void update_fpcsr(OpenRISCCPU *cpu)
 
56
{
 
57
    int tmp = ieee_ex_to_openrisc(cpu,
 
58
                              get_float_exception_flags(&cpu->env.fp_status));
 
59
 
 
60
    SET_FP_CAUSE(cpu->env.fpcsr, tmp);
 
61
    if ((GET_FP_ENABLE(cpu->env.fpcsr) & tmp) &&
 
62
        (cpu->env.fpcsr & FPCSR_FPEE)) {
 
63
        helper_exception(&cpu->env, EXCP_FPE);
 
64
    } else {
 
65
        UPDATE_FP_FLAGS(cpu->env.fpcsr, tmp);
 
66
    }
 
67
}
 
68
 
 
69
uint64_t HELPER(itofd)(CPUOpenRISCState *env, uint64_t val)
 
70
{
 
71
    uint64_t itofd;
 
72
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
 
73
 
 
74
    set_float_exception_flags(0, &cpu->env.fp_status);
 
75
    itofd = int32_to_float64(val, &cpu->env.fp_status);
 
76
    update_fpcsr(cpu);
 
77
 
 
78
    return itofd;
 
79
}
 
80
 
 
81
uint32_t HELPER(itofs)(CPUOpenRISCState *env, uint32_t val)
 
82
{
 
83
    uint32_t itofs;
 
84
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
 
85
 
 
86
    set_float_exception_flags(0, &cpu->env.fp_status);
 
87
    itofs = int32_to_float32(val, &cpu->env.fp_status);
 
88
    update_fpcsr(cpu);
 
89
 
 
90
    return itofs;
 
91
}
 
92
 
 
93
uint64_t HELPER(ftoid)(CPUOpenRISCState *env, uint64_t val)
 
94
{
 
95
    uint64_t ftoid;
 
96
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
 
97
 
 
98
    set_float_exception_flags(0, &cpu->env.fp_status);
 
99
    ftoid = float32_to_int64(val, &cpu->env.fp_status);
 
100
    update_fpcsr(cpu);
 
101
 
 
102
    return ftoid;
 
103
}
 
104
 
 
105
uint32_t HELPER(ftois)(CPUOpenRISCState *env, uint32_t val)
 
106
{
 
107
    uint32_t ftois;
 
108
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
 
109
 
 
110
    set_float_exception_flags(0, &cpu->env.fp_status);
 
111
    ftois = float32_to_int32(val, &cpu->env.fp_status);
 
112
    update_fpcsr(cpu);
 
113
 
 
114
    return ftois;
 
115
}
 
116
 
 
117
#define FLOAT_OP(name, p) void helper_float_##_##p(void)
 
118
 
 
119
#define FLOAT_CALC(name)                                                  \
 
120
uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
 
121
                                     uint64_t fdt0, uint64_t fdt1)        \
 
122
{                                                                         \
 
123
    uint64_t result;                                                      \
 
124
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
 
125
    set_float_exception_flags(0, &cpu->env.fp_status);                    \
 
126
    result = float64_ ## name(fdt0, fdt1, &cpu->env.fp_status);           \
 
127
    update_fpcsr(cpu);                                                    \
 
128
    return result;                                                        \
 
129
}                                                                         \
 
130
                                                                          \
 
131
uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env,               \
 
132
                                     uint32_t fdt0, uint32_t fdt1)        \
 
133
{                                                                         \
 
134
    uint32_t result;                                                      \
 
135
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
 
136
    set_float_exception_flags(0, &cpu->env.fp_status);                    \
 
137
    result = float32_ ## name(fdt0, fdt1, &cpu->env.fp_status);           \
 
138
    update_fpcsr(cpu);                                                    \
 
139
    return result;                                                        \
 
140
}                                                                         \
 
141
 
 
142
FLOAT_CALC(add)
 
143
FLOAT_CALC(sub)
 
144
FLOAT_CALC(mul)
 
145
FLOAT_CALC(div)
 
146
FLOAT_CALC(rem)
 
147
#undef FLOAT_CALC
 
148
 
 
149
 
 
150
uint64_t helper_float_madd_d(CPUOpenRISCState *env, uint64_t a,
 
151
                             uint64_t b, uint64_t c)
 
152
{
 
153
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
 
154
    uint64_t result;
 
155
    set_float_exception_flags(0, &cpu->env.fp_status);
 
156
    /* Note that or1ksim doesn't use merged operation.  */
 
157
    result = float64_mul(b, c, &cpu->env.fp_status);
 
158
    result = float64_add(result, a, &cpu->env.fp_status);
 
159
    update_fpcsr(cpu);
 
160
    return result;
 
161
}
 
162
 
 
163
uint32_t helper_float_madd_s(CPUOpenRISCState *env, uint32_t a,
 
164
                             uint32_t b, uint32_t c)
 
165
{
 
166
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
 
167
    uint32_t result;
 
168
    set_float_exception_flags(0, &cpu->env.fp_status);
 
169
    /* Note that or1ksim doesn't use merged operation.  */
 
170
    result = float32_mul(b, c, &cpu->env.fp_status);
 
171
    result = float32_add(result, a, &cpu->env.fp_status);
 
172
    update_fpcsr(cpu);
 
173
    return result;
 
174
}
 
175
 
 
176
 
 
177
#define FLOAT_CMP(name)                                                   \
 
178
uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
 
179
                                     uint64_t fdt0, uint64_t fdt1)        \
 
180
{                                                                         \
 
181
    int res;                                                              \
 
182
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
 
183
    set_float_exception_flags(0, &cpu->env.fp_status);                    \
 
184
    res = float64_ ## name(fdt0, fdt1, &cpu->env.fp_status);              \
 
185
    update_fpcsr(cpu);                                                    \
 
186
    return res;                                                           \
 
187
}                                                                         \
 
188
                                                                          \
 
189
uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env,               \
 
190
                                             uint32_t fdt0, uint32_t fdt1)\
 
191
{                                                                         \
 
192
    int res;                                                              \
 
193
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
 
194
    set_float_exception_flags(0, &cpu->env.fp_status);                    \
 
195
    res = float32_ ## name(fdt0, fdt1, &cpu->env.fp_status);              \
 
196
    update_fpcsr(cpu);                                                    \
 
197
    return res;                                                           \
 
198
}
 
199
 
 
200
FLOAT_CMP(le)
 
201
FLOAT_CMP(eq)
 
202
FLOAT_CMP(lt)
 
203
#undef FLOAT_CMP
 
204
 
 
205
 
 
206
#define FLOAT_CMPNE(name)                                                 \
 
207
uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
 
208
                                     uint64_t fdt0, uint64_t fdt1)        \
 
209
{                                                                         \
 
210
    int res;                                                              \
 
211
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
 
212
    set_float_exception_flags(0, &cpu->env.fp_status);                    \
 
213
    res = !float64_eq_quiet(fdt0, fdt1, &cpu->env.fp_status);             \
 
214
    update_fpcsr(cpu);                                                    \
 
215
    return res;                                                           \
 
216
}                                                                         \
 
217
                                                                          \
 
218
uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env,               \
 
219
                                     uint32_t fdt0, uint32_t fdt1)        \
 
220
{                                                                         \
 
221
    int res;                                                              \
 
222
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
 
223
    set_float_exception_flags(0, &cpu->env.fp_status);                    \
 
224
    res = !float32_eq_quiet(fdt0, fdt1, &cpu->env.fp_status);             \
 
225
    update_fpcsr(cpu);                                                    \
 
226
    return res;                                                           \
 
227
}
 
228
 
 
229
FLOAT_CMPNE(ne)
 
230
#undef FLOAT_CMPNE
 
231
 
 
232
#define FLOAT_CMPGT(name)                                                 \
 
233
uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
 
234
                                     uint64_t fdt0, uint64_t fdt1)        \
 
235
{                                                                         \
 
236
    int res;                                                              \
 
237
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
 
238
    set_float_exception_flags(0, &cpu->env.fp_status);                    \
 
239
    res = !float64_le(fdt0, fdt1, &cpu->env.fp_status);                   \
 
240
    update_fpcsr(cpu);                                                    \
 
241
    return res;                                                           \
 
242
}                                                                         \
 
243
                                                                          \
 
244
uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env,               \
 
245
                                     uint32_t fdt0, uint32_t fdt1)        \
 
246
{                                                                         \
 
247
    int res;                                                              \
 
248
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
 
249
    set_float_exception_flags(0, &cpu->env.fp_status);                    \
 
250
    res = !float32_le(fdt0, fdt1, &cpu->env.fp_status);                   \
 
251
    update_fpcsr(cpu);                                                    \
 
252
    return res;                                                           \
 
253
}
 
254
FLOAT_CMPGT(gt)
 
255
#undef FLOAT_CMPGT
 
256
 
 
257
#define FLOAT_CMPGE(name)                                                 \
 
258
uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
 
259
                                     uint64_t fdt0, uint64_t fdt1)        \
 
260
{                                                                         \
 
261
    int res;                                                              \
 
262
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
 
263
    set_float_exception_flags(0, &cpu->env.fp_status);                    \
 
264
    res = !float64_lt(fdt0, fdt1, &cpu->env.fp_status);                   \
 
265
    update_fpcsr(cpu);                                                    \
 
266
    return res;                                                           \
 
267
}                                                                         \
 
268
                                                                          \
 
269
uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env,               \
 
270
                                     uint32_t fdt0, uint32_t fdt1)        \
 
271
{                                                                         \
 
272
    int res;                                                              \
 
273
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
 
274
    set_float_exception_flags(0, &cpu->env.fp_status);                    \
 
275
    res = !float32_lt(fdt0, fdt1, &cpu->env.fp_status);                   \
 
276
    update_fpcsr(cpu);                                                    \
 
277
    return res;                                                           \
 
278
}
 
279
 
 
280
FLOAT_CMPGE(ge)
 
281
#undef FLOAT_CMPGE