Statistics
| Branch: | Revision:

root / target-alpha / op_helper.c @ b5f1aa64

History | View | Annotate | Download (28.1 kB)

1 4c9649a9 j_mayer
/*
2 4c9649a9 j_mayer
 *  Alpha emulation cpu micro-operations helpers for qemu.
3 5fafdf24 ths
 *
4 4c9649a9 j_mayer
 *  Copyright (c) 2007 Jocelyn Mayer
5 4c9649a9 j_mayer
 *
6 4c9649a9 j_mayer
 * This library is free software; you can redistribute it and/or
7 4c9649a9 j_mayer
 * modify it under the terms of the GNU Lesser General Public
8 4c9649a9 j_mayer
 * License as published by the Free Software Foundation; either
9 4c9649a9 j_mayer
 * version 2 of the License, or (at your option) any later version.
10 4c9649a9 j_mayer
 *
11 4c9649a9 j_mayer
 * This library is distributed in the hope that it will be useful,
12 4c9649a9 j_mayer
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 4c9649a9 j_mayer
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 4c9649a9 j_mayer
 * Lesser General Public License for more details.
15 4c9649a9 j_mayer
 *
16 4c9649a9 j_mayer
 * You should have received a copy of the GNU Lesser General Public
17 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 4c9649a9 j_mayer
 */
19 4c9649a9 j_mayer
20 4c9649a9 j_mayer
#include "exec.h"
21 603fccce j_mayer
#include "host-utils.h"
22 4c9649a9 j_mayer
#include "softfloat.h"
23 a7812ae4 pbrook
#include "helper.h"
24 18f8e2c0 Richard Henderson
#include "qemu-timer.h"
25 4c9649a9 j_mayer
26 4c9649a9 j_mayer
/*****************************************************************************/
27 4c9649a9 j_mayer
/* Exceptions processing helpers */
28 c2c789cf Richard Henderson
void QEMU_NORETURN helper_excp (int excp, int error)
29 4c9649a9 j_mayer
{
30 4c9649a9 j_mayer
    env->exception_index = excp;
31 4c9649a9 j_mayer
    env->error_code = error;
32 4c9649a9 j_mayer
    cpu_loop_exit();
33 4c9649a9 j_mayer
}
34 4c9649a9 j_mayer
35 b5f1aa64 Richard Henderson
static void QEMU_NORETURN arith_excp(int exc, uint64_t mask)
36 b5f1aa64 Richard Henderson
{
37 b5f1aa64 Richard Henderson
    env->exception_index = EXCP_ARITH;
38 b5f1aa64 Richard Henderson
    env->error_code = 0;
39 b5f1aa64 Richard Henderson
    env->trap_arg0 = exc;
40 b5f1aa64 Richard Henderson
    env->trap_arg1 = mask;
41 b5f1aa64 Richard Henderson
    cpu_loop_exit();
42 b5f1aa64 Richard Henderson
}
43 b5f1aa64 Richard Henderson
44 6ad02592 aurel32
uint64_t helper_load_pcc (void)
45 4c9649a9 j_mayer
{
46 18f8e2c0 Richard Henderson
    /* ??? This isn't a timer for which we have any rate info.  */
47 18f8e2c0 Richard Henderson
    return (uint32_t)cpu_get_real_ticks();
48 4c9649a9 j_mayer
}
49 4c9649a9 j_mayer
50 f18cd223 aurel32
uint64_t helper_load_fpcr (void)
51 4c9649a9 j_mayer
{
52 ba0e276d Richard Henderson
    return cpu_alpha_load_fpcr (env);
53 4c9649a9 j_mayer
}
54 4c9649a9 j_mayer
55 f18cd223 aurel32
void helper_store_fpcr (uint64_t val)
56 4c9649a9 j_mayer
{
57 ba0e276d Richard Henderson
    cpu_alpha_store_fpcr (env, val);
58 4c9649a9 j_mayer
}
59 4c9649a9 j_mayer
60 04acd307 aurel32
uint64_t helper_addqv (uint64_t op1, uint64_t op2)
61 4c9649a9 j_mayer
{
62 04acd307 aurel32
    uint64_t tmp = op1;
63 04acd307 aurel32
    op1 += op2;
64 04acd307 aurel32
    if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) {
65 b5f1aa64 Richard Henderson
        arith_excp(EXC_M_IOV, 0);
66 4c9649a9 j_mayer
    }
67 04acd307 aurel32
    return op1;
68 4c9649a9 j_mayer
}
69 4c9649a9 j_mayer
70 04acd307 aurel32
uint64_t helper_addlv (uint64_t op1, uint64_t op2)
71 4c9649a9 j_mayer
{
72 04acd307 aurel32
    uint64_t tmp = op1;
73 04acd307 aurel32
    op1 = (uint32_t)(op1 + op2);
74 04acd307 aurel32
    if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) {
75 b5f1aa64 Richard Henderson
        arith_excp(EXC_M_IOV, 0);
76 4c9649a9 j_mayer
    }
77 04acd307 aurel32
    return op1;
78 4c9649a9 j_mayer
}
79 4c9649a9 j_mayer
80 04acd307 aurel32
uint64_t helper_subqv (uint64_t op1, uint64_t op2)
81 4c9649a9 j_mayer
{
82 ecbb5ea1 aurel32
    uint64_t res;
83 ecbb5ea1 aurel32
    res = op1 - op2;
84 ecbb5ea1 aurel32
    if (unlikely((op1 ^ op2) & (res ^ op1) & (1ULL << 63))) {
85 b5f1aa64 Richard Henderson
        arith_excp(EXC_M_IOV, 0);
86 4c9649a9 j_mayer
    }
87 ecbb5ea1 aurel32
    return res;
88 4c9649a9 j_mayer
}
89 4c9649a9 j_mayer
90 04acd307 aurel32
uint64_t helper_sublv (uint64_t op1, uint64_t op2)
91 4c9649a9 j_mayer
{
92 ecbb5ea1 aurel32
    uint32_t res;
93 ecbb5ea1 aurel32
    res = op1 - op2;
94 ecbb5ea1 aurel32
    if (unlikely((op1 ^ op2) & (res ^ op1) & (1UL << 31))) {
95 b5f1aa64 Richard Henderson
        arith_excp(EXC_M_IOV, 0);
96 4c9649a9 j_mayer
    }
97 ecbb5ea1 aurel32
    return res;
98 4c9649a9 j_mayer
}
99 4c9649a9 j_mayer
100 04acd307 aurel32
uint64_t helper_mullv (uint64_t op1, uint64_t op2)
101 4c9649a9 j_mayer
{
102 04acd307 aurel32
    int64_t res = (int64_t)op1 * (int64_t)op2;
103 4c9649a9 j_mayer
104 4c9649a9 j_mayer
    if (unlikely((int32_t)res != res)) {
105 b5f1aa64 Richard Henderson
        arith_excp(EXC_M_IOV, 0);
106 4c9649a9 j_mayer
    }
107 04acd307 aurel32
    return (int64_t)((int32_t)res);
108 4c9649a9 j_mayer
}
109 4c9649a9 j_mayer
110 04acd307 aurel32
uint64_t helper_mulqv (uint64_t op1, uint64_t op2)
111 4c9649a9 j_mayer
{
112 e14fe0a9 j_mayer
    uint64_t tl, th;
113 e14fe0a9 j_mayer
114 04acd307 aurel32
    muls64(&tl, &th, op1, op2);
115 e14fe0a9 j_mayer
    /* If th != 0 && th != -1, then we had an overflow */
116 e14fe0a9 j_mayer
    if (unlikely((th + 1) > 1)) {
117 b5f1aa64 Richard Henderson
        arith_excp(EXC_M_IOV, 0);
118 4c9649a9 j_mayer
    }
119 04acd307 aurel32
    return tl;
120 04acd307 aurel32
}
121 04acd307 aurel32
122 04acd307 aurel32
uint64_t helper_umulh (uint64_t op1, uint64_t op2)
123 04acd307 aurel32
{
124 04acd307 aurel32
    uint64_t tl, th;
125 04acd307 aurel32
126 04acd307 aurel32
    mulu64(&tl, &th, op1, op2);
127 04acd307 aurel32
    return th;
128 4c9649a9 j_mayer
}
129 4c9649a9 j_mayer
130 ae8ecd42 aurel32
uint64_t helper_ctpop (uint64_t arg)
131 4c9649a9 j_mayer
{
132 ae8ecd42 aurel32
    return ctpop64(arg);
133 4c9649a9 j_mayer
}
134 4c9649a9 j_mayer
135 ae8ecd42 aurel32
uint64_t helper_ctlz (uint64_t arg)
136 4c9649a9 j_mayer
{
137 ae8ecd42 aurel32
    return clz64(arg);
138 4c9649a9 j_mayer
}
139 4c9649a9 j_mayer
140 ae8ecd42 aurel32
uint64_t helper_cttz (uint64_t arg)
141 4c9649a9 j_mayer
{
142 ae8ecd42 aurel32
    return ctz64(arg);
143 4c9649a9 j_mayer
}
144 4c9649a9 j_mayer
145 636aa200 Blue Swirl
static inline uint64_t byte_zap(uint64_t op, uint8_t mskb)
146 4c9649a9 j_mayer
{
147 4c9649a9 j_mayer
    uint64_t mask;
148 4c9649a9 j_mayer
149 4c9649a9 j_mayer
    mask = 0;
150 4c9649a9 j_mayer
    mask |= ((mskb >> 0) & 1) * 0x00000000000000FFULL;
151 4c9649a9 j_mayer
    mask |= ((mskb >> 1) & 1) * 0x000000000000FF00ULL;
152 4c9649a9 j_mayer
    mask |= ((mskb >> 2) & 1) * 0x0000000000FF0000ULL;
153 4c9649a9 j_mayer
    mask |= ((mskb >> 3) & 1) * 0x00000000FF000000ULL;
154 4c9649a9 j_mayer
    mask |= ((mskb >> 4) & 1) * 0x000000FF00000000ULL;
155 4c9649a9 j_mayer
    mask |= ((mskb >> 5) & 1) * 0x0000FF0000000000ULL;
156 4c9649a9 j_mayer
    mask |= ((mskb >> 6) & 1) * 0x00FF000000000000ULL;
157 4c9649a9 j_mayer
    mask |= ((mskb >> 7) & 1) * 0xFF00000000000000ULL;
158 4c9649a9 j_mayer
159 4c9649a9 j_mayer
    return op & ~mask;
160 4c9649a9 j_mayer
}
161 4c9649a9 j_mayer
162 b3249f63 aurel32
uint64_t helper_zap(uint64_t val, uint64_t mask)
163 4c9649a9 j_mayer
{
164 b3249f63 aurel32
    return byte_zap(val, mask);
165 4c9649a9 j_mayer
}
166 4c9649a9 j_mayer
167 b3249f63 aurel32
uint64_t helper_zapnot(uint64_t val, uint64_t mask)
168 4c9649a9 j_mayer
{
169 b3249f63 aurel32
    return byte_zap(val, ~mask);
170 4c9649a9 j_mayer
}
171 4c9649a9 j_mayer
172 04acd307 aurel32
uint64_t helper_cmpbge (uint64_t op1, uint64_t op2)
173 4c9649a9 j_mayer
{
174 4c9649a9 j_mayer
    uint8_t opa, opb, res;
175 4c9649a9 j_mayer
    int i;
176 4c9649a9 j_mayer
177 4c9649a9 j_mayer
    res = 0;
178 970d622e aurel32
    for (i = 0; i < 8; i++) {
179 04acd307 aurel32
        opa = op1 >> (i * 8);
180 04acd307 aurel32
        opb = op2 >> (i * 8);
181 4c9649a9 j_mayer
        if (opa >= opb)
182 4c9649a9 j_mayer
            res |= 1 << i;
183 4c9649a9 j_mayer
    }
184 04acd307 aurel32
    return res;
185 4c9649a9 j_mayer
}
186 4c9649a9 j_mayer
187 13e4df99 Richard Henderson
uint64_t helper_minub8 (uint64_t op1, uint64_t op2)
188 13e4df99 Richard Henderson
{
189 13e4df99 Richard Henderson
    uint64_t res = 0;
190 13e4df99 Richard Henderson
    uint8_t opa, opb, opr;
191 13e4df99 Richard Henderson
    int i;
192 13e4df99 Richard Henderson
193 13e4df99 Richard Henderson
    for (i = 0; i < 8; ++i) {
194 13e4df99 Richard Henderson
        opa = op1 >> (i * 8);
195 13e4df99 Richard Henderson
        opb = op2 >> (i * 8);
196 13e4df99 Richard Henderson
        opr = opa < opb ? opa : opb;
197 13e4df99 Richard Henderson
        res |= (uint64_t)opr << (i * 8);
198 13e4df99 Richard Henderson
    }
199 13e4df99 Richard Henderson
    return res;
200 13e4df99 Richard Henderson
}
201 13e4df99 Richard Henderson
202 13e4df99 Richard Henderson
uint64_t helper_minsb8 (uint64_t op1, uint64_t op2)
203 13e4df99 Richard Henderson
{
204 13e4df99 Richard Henderson
    uint64_t res = 0;
205 13e4df99 Richard Henderson
    int8_t opa, opb;
206 13e4df99 Richard Henderson
    uint8_t opr;
207 13e4df99 Richard Henderson
    int i;
208 13e4df99 Richard Henderson
209 13e4df99 Richard Henderson
    for (i = 0; i < 8; ++i) {
210 13e4df99 Richard Henderson
        opa = op1 >> (i * 8);
211 13e4df99 Richard Henderson
        opb = op2 >> (i * 8);
212 13e4df99 Richard Henderson
        opr = opa < opb ? opa : opb;
213 13e4df99 Richard Henderson
        res |= (uint64_t)opr << (i * 8);
214 13e4df99 Richard Henderson
    }
215 13e4df99 Richard Henderson
    return res;
216 13e4df99 Richard Henderson
}
217 13e4df99 Richard Henderson
218 13e4df99 Richard Henderson
uint64_t helper_minuw4 (uint64_t op1, uint64_t op2)
219 13e4df99 Richard Henderson
{
220 13e4df99 Richard Henderson
    uint64_t res = 0;
221 13e4df99 Richard Henderson
    uint16_t opa, opb, opr;
222 13e4df99 Richard Henderson
    int i;
223 13e4df99 Richard Henderson
224 13e4df99 Richard Henderson
    for (i = 0; i < 4; ++i) {
225 13e4df99 Richard Henderson
        opa = op1 >> (i * 16);
226 13e4df99 Richard Henderson
        opb = op2 >> (i * 16);
227 13e4df99 Richard Henderson
        opr = opa < opb ? opa : opb;
228 13e4df99 Richard Henderson
        res |= (uint64_t)opr << (i * 16);
229 13e4df99 Richard Henderson
    }
230 13e4df99 Richard Henderson
    return res;
231 13e4df99 Richard Henderson
}
232 13e4df99 Richard Henderson
233 13e4df99 Richard Henderson
uint64_t helper_minsw4 (uint64_t op1, uint64_t op2)
234 13e4df99 Richard Henderson
{
235 13e4df99 Richard Henderson
    uint64_t res = 0;
236 13e4df99 Richard Henderson
    int16_t opa, opb;
237 13e4df99 Richard Henderson
    uint16_t opr;
238 13e4df99 Richard Henderson
    int i;
239 13e4df99 Richard Henderson
240 13e4df99 Richard Henderson
    for (i = 0; i < 4; ++i) {
241 13e4df99 Richard Henderson
        opa = op1 >> (i * 16);
242 13e4df99 Richard Henderson
        opb = op2 >> (i * 16);
243 13e4df99 Richard Henderson
        opr = opa < opb ? opa : opb;
244 13e4df99 Richard Henderson
        res |= (uint64_t)opr << (i * 16);
245 13e4df99 Richard Henderson
    }
246 13e4df99 Richard Henderson
    return res;
247 13e4df99 Richard Henderson
}
248 13e4df99 Richard Henderson
249 13e4df99 Richard Henderson
uint64_t helper_maxub8 (uint64_t op1, uint64_t op2)
250 13e4df99 Richard Henderson
{
251 13e4df99 Richard Henderson
    uint64_t res = 0;
252 13e4df99 Richard Henderson
    uint8_t opa, opb, opr;
253 13e4df99 Richard Henderson
    int i;
254 13e4df99 Richard Henderson
255 13e4df99 Richard Henderson
    for (i = 0; i < 8; ++i) {
256 13e4df99 Richard Henderson
        opa = op1 >> (i * 8);
257 13e4df99 Richard Henderson
        opb = op2 >> (i * 8);
258 13e4df99 Richard Henderson
        opr = opa > opb ? opa : opb;
259 13e4df99 Richard Henderson
        res |= (uint64_t)opr << (i * 8);
260 13e4df99 Richard Henderson
    }
261 13e4df99 Richard Henderson
    return res;
262 13e4df99 Richard Henderson
}
263 13e4df99 Richard Henderson
264 13e4df99 Richard Henderson
uint64_t helper_maxsb8 (uint64_t op1, uint64_t op2)
265 13e4df99 Richard Henderson
{
266 13e4df99 Richard Henderson
    uint64_t res = 0;
267 13e4df99 Richard Henderson
    int8_t opa, opb;
268 13e4df99 Richard Henderson
    uint8_t opr;
269 13e4df99 Richard Henderson
    int i;
270 13e4df99 Richard Henderson
271 13e4df99 Richard Henderson
    for (i = 0; i < 8; ++i) {
272 13e4df99 Richard Henderson
        opa = op1 >> (i * 8);
273 13e4df99 Richard Henderson
        opb = op2 >> (i * 8);
274 13e4df99 Richard Henderson
        opr = opa > opb ? opa : opb;
275 13e4df99 Richard Henderson
        res |= (uint64_t)opr << (i * 8);
276 13e4df99 Richard Henderson
    }
277 13e4df99 Richard Henderson
    return res;
278 13e4df99 Richard Henderson
}
279 13e4df99 Richard Henderson
280 13e4df99 Richard Henderson
uint64_t helper_maxuw4 (uint64_t op1, uint64_t op2)
281 13e4df99 Richard Henderson
{
282 13e4df99 Richard Henderson
    uint64_t res = 0;
283 13e4df99 Richard Henderson
    uint16_t opa, opb, opr;
284 13e4df99 Richard Henderson
    int i;
285 13e4df99 Richard Henderson
286 13e4df99 Richard Henderson
    for (i = 0; i < 4; ++i) {
287 13e4df99 Richard Henderson
        opa = op1 >> (i * 16);
288 13e4df99 Richard Henderson
        opb = op2 >> (i * 16);
289 13e4df99 Richard Henderson
        opr = opa > opb ? opa : opb;
290 13e4df99 Richard Henderson
        res |= (uint64_t)opr << (i * 16);
291 13e4df99 Richard Henderson
    }
292 13e4df99 Richard Henderson
    return res;
293 13e4df99 Richard Henderson
}
294 13e4df99 Richard Henderson
295 13e4df99 Richard Henderson
uint64_t helper_maxsw4 (uint64_t op1, uint64_t op2)
296 13e4df99 Richard Henderson
{
297 13e4df99 Richard Henderson
    uint64_t res = 0;
298 13e4df99 Richard Henderson
    int16_t opa, opb;
299 13e4df99 Richard Henderson
    uint16_t opr;
300 13e4df99 Richard Henderson
    int i;
301 13e4df99 Richard Henderson
302 13e4df99 Richard Henderson
    for (i = 0; i < 4; ++i) {
303 13e4df99 Richard Henderson
        opa = op1 >> (i * 16);
304 13e4df99 Richard Henderson
        opb = op2 >> (i * 16);
305 13e4df99 Richard Henderson
        opr = opa > opb ? opa : opb;
306 13e4df99 Richard Henderson
        res |= (uint64_t)opr << (i * 16);
307 13e4df99 Richard Henderson
    }
308 13e4df99 Richard Henderson
    return res;
309 13e4df99 Richard Henderson
}
310 13e4df99 Richard Henderson
311 13e4df99 Richard Henderson
uint64_t helper_perr (uint64_t op1, uint64_t op2)
312 13e4df99 Richard Henderson
{
313 13e4df99 Richard Henderson
    uint64_t res = 0;
314 13e4df99 Richard Henderson
    uint8_t opa, opb, opr;
315 13e4df99 Richard Henderson
    int i;
316 13e4df99 Richard Henderson
317 13e4df99 Richard Henderson
    for (i = 0; i < 8; ++i) {
318 13e4df99 Richard Henderson
        opa = op1 >> (i * 8);
319 13e4df99 Richard Henderson
        opb = op2 >> (i * 8);
320 13e4df99 Richard Henderson
        if (opa >= opb)
321 13e4df99 Richard Henderson
            opr = opa - opb;
322 13e4df99 Richard Henderson
        else
323 13e4df99 Richard Henderson
            opr = opb - opa;
324 13e4df99 Richard Henderson
        res += opr;
325 13e4df99 Richard Henderson
    }
326 13e4df99 Richard Henderson
    return res;
327 13e4df99 Richard Henderson
}
328 13e4df99 Richard Henderson
329 13e4df99 Richard Henderson
uint64_t helper_pklb (uint64_t op1)
330 13e4df99 Richard Henderson
{
331 13e4df99 Richard Henderson
    return (op1 & 0xff) | ((op1 >> 24) & 0xff00);
332 13e4df99 Richard Henderson
}
333 13e4df99 Richard Henderson
334 13e4df99 Richard Henderson
uint64_t helper_pkwb (uint64_t op1)
335 13e4df99 Richard Henderson
{
336 13e4df99 Richard Henderson
    return ((op1 & 0xff)
337 13e4df99 Richard Henderson
            | ((op1 >> 8) & 0xff00)
338 13e4df99 Richard Henderson
            | ((op1 >> 16) & 0xff0000)
339 13e4df99 Richard Henderson
            | ((op1 >> 24) & 0xff000000));
340 13e4df99 Richard Henderson
}
341 13e4df99 Richard Henderson
342 13e4df99 Richard Henderson
uint64_t helper_unpkbl (uint64_t op1)
343 13e4df99 Richard Henderson
{
344 13e4df99 Richard Henderson
    return (op1 & 0xff) | ((op1 & 0xff00) << 24);
345 13e4df99 Richard Henderson
}
346 13e4df99 Richard Henderson
347 13e4df99 Richard Henderson
uint64_t helper_unpkbw (uint64_t op1)
348 13e4df99 Richard Henderson
{
349 13e4df99 Richard Henderson
    return ((op1 & 0xff)
350 13e4df99 Richard Henderson
            | ((op1 & 0xff00) << 8)
351 13e4df99 Richard Henderson
            | ((op1 & 0xff0000) << 16)
352 13e4df99 Richard Henderson
            | ((op1 & 0xff000000) << 24));
353 13e4df99 Richard Henderson
}
354 13e4df99 Richard Henderson
355 f18cd223 aurel32
/* Floating point helpers */
356 f18cd223 aurel32
357 f24518b5 Richard Henderson
void helper_setroundmode (uint32_t val)
358 f24518b5 Richard Henderson
{
359 f24518b5 Richard Henderson
    set_float_rounding_mode(val, &FP_STATUS);
360 f24518b5 Richard Henderson
}
361 f24518b5 Richard Henderson
362 f24518b5 Richard Henderson
void helper_setflushzero (uint32_t val)
363 f24518b5 Richard Henderson
{
364 f24518b5 Richard Henderson
    set_flush_to_zero(val, &FP_STATUS);
365 f24518b5 Richard Henderson
}
366 f24518b5 Richard Henderson
367 f24518b5 Richard Henderson
void helper_fp_exc_clear (void)
368 f24518b5 Richard Henderson
{
369 f24518b5 Richard Henderson
    set_float_exception_flags(0, &FP_STATUS);
370 f24518b5 Richard Henderson
}
371 f24518b5 Richard Henderson
372 f24518b5 Richard Henderson
uint32_t helper_fp_exc_get (void)
373 f24518b5 Richard Henderson
{
374 f24518b5 Richard Henderson
    return get_float_exception_flags(&FP_STATUS);
375 f24518b5 Richard Henderson
}
376 f24518b5 Richard Henderson
377 f24518b5 Richard Henderson
/* Raise exceptions for ieee fp insns without software completion.
378 f24518b5 Richard Henderson
   In that case there are no exceptions that don't trap; the mask
379 f24518b5 Richard Henderson
   doesn't apply.  */
380 f24518b5 Richard Henderson
void helper_fp_exc_raise(uint32_t exc, uint32_t regno)
381 f24518b5 Richard Henderson
{
382 f24518b5 Richard Henderson
    if (exc) {
383 f24518b5 Richard Henderson
        uint32_t hw_exc = 0;
384 f24518b5 Richard Henderson
385 f24518b5 Richard Henderson
        if (exc & float_flag_invalid) {
386 f24518b5 Richard Henderson
            hw_exc |= EXC_M_INV;
387 f24518b5 Richard Henderson
        }
388 f24518b5 Richard Henderson
        if (exc & float_flag_divbyzero) {
389 f24518b5 Richard Henderson
            hw_exc |= EXC_M_DZE;
390 f24518b5 Richard Henderson
        }
391 f24518b5 Richard Henderson
        if (exc & float_flag_overflow) {
392 f24518b5 Richard Henderson
            hw_exc |= EXC_M_FOV;
393 f24518b5 Richard Henderson
        }
394 f24518b5 Richard Henderson
        if (exc & float_flag_underflow) {
395 f24518b5 Richard Henderson
            hw_exc |= EXC_M_UNF;
396 f24518b5 Richard Henderson
        }
397 f24518b5 Richard Henderson
        if (exc & float_flag_inexact) {
398 f24518b5 Richard Henderson
            hw_exc |= EXC_M_INE;
399 f24518b5 Richard Henderson
        }
400 b5f1aa64 Richard Henderson
401 b5f1aa64 Richard Henderson
        arith_excp(hw_exc, 1ull << regno);
402 f24518b5 Richard Henderson
    }
403 f24518b5 Richard Henderson
}
404 f24518b5 Richard Henderson
405 f24518b5 Richard Henderson
/* Raise exceptions for ieee fp insns with software completion.  */
406 f24518b5 Richard Henderson
void helper_fp_exc_raise_s(uint32_t exc, uint32_t regno)
407 f24518b5 Richard Henderson
{
408 f24518b5 Richard Henderson
    if (exc) {
409 f24518b5 Richard Henderson
        env->fpcr_exc_status |= exc;
410 f24518b5 Richard Henderson
411 f24518b5 Richard Henderson
        exc &= ~env->fpcr_exc_mask;
412 f24518b5 Richard Henderson
        if (exc) {
413 f24518b5 Richard Henderson
            helper_fp_exc_raise(exc, regno);
414 f24518b5 Richard Henderson
        }
415 f24518b5 Richard Henderson
    }
416 f24518b5 Richard Henderson
}
417 f24518b5 Richard Henderson
418 f24518b5 Richard Henderson
/* Input remapping without software completion.  Handle denormal-map-to-zero
419 f24518b5 Richard Henderson
   and trap for all other non-finite numbers.  */
420 f24518b5 Richard Henderson
uint64_t helper_ieee_input(uint64_t val)
421 f24518b5 Richard Henderson
{
422 f24518b5 Richard Henderson
    uint32_t exp = (uint32_t)(val >> 52) & 0x7ff;
423 f24518b5 Richard Henderson
    uint64_t frac = val & 0xfffffffffffffull;
424 f24518b5 Richard Henderson
425 f24518b5 Richard Henderson
    if (exp == 0) {
426 f24518b5 Richard Henderson
        if (frac != 0) {
427 f24518b5 Richard Henderson
            /* If DNZ is set flush denormals to zero on input.  */
428 f24518b5 Richard Henderson
            if (env->fpcr_dnz) {
429 f24518b5 Richard Henderson
                val &= 1ull << 63;
430 f24518b5 Richard Henderson
            } else {
431 b5f1aa64 Richard Henderson
                arith_excp(EXC_M_UNF, 0);
432 f24518b5 Richard Henderson
            }
433 f24518b5 Richard Henderson
        }
434 f24518b5 Richard Henderson
    } else if (exp == 0x7ff) {
435 f24518b5 Richard Henderson
        /* Infinity or NaN.  */
436 f24518b5 Richard Henderson
        /* ??? I'm not sure these exception bit flags are correct.  I do
437 f24518b5 Richard Henderson
           know that the Linux kernel, at least, doesn't rely on them and
438 f24518b5 Richard Henderson
           just emulates the insn to figure out what exception to use.  */
439 b5f1aa64 Richard Henderson
        arith_excp(frac ? EXC_M_INV : EXC_M_FOV, 0);
440 f24518b5 Richard Henderson
    }
441 f24518b5 Richard Henderson
    return val;
442 f24518b5 Richard Henderson
}
443 f24518b5 Richard Henderson
444 f24518b5 Richard Henderson
/* Similar, but does not trap for infinities.  Used for comparisons.  */
445 f24518b5 Richard Henderson
uint64_t helper_ieee_input_cmp(uint64_t val)
446 f24518b5 Richard Henderson
{
447 f24518b5 Richard Henderson
    uint32_t exp = (uint32_t)(val >> 52) & 0x7ff;
448 f24518b5 Richard Henderson
    uint64_t frac = val & 0xfffffffffffffull;
449 f24518b5 Richard Henderson
450 f24518b5 Richard Henderson
    if (exp == 0) {
451 f24518b5 Richard Henderson
        if (frac != 0) {
452 f24518b5 Richard Henderson
            /* If DNZ is set flush denormals to zero on input.  */
453 f24518b5 Richard Henderson
            if (env->fpcr_dnz) {
454 f24518b5 Richard Henderson
                val &= 1ull << 63;
455 f24518b5 Richard Henderson
            } else {
456 b5f1aa64 Richard Henderson
                arith_excp(EXC_M_UNF, 0);
457 f24518b5 Richard Henderson
            }
458 f24518b5 Richard Henderson
        }
459 f24518b5 Richard Henderson
    } else if (exp == 0x7ff && frac) {
460 f24518b5 Richard Henderson
        /* NaN.  */
461 b5f1aa64 Richard Henderson
        arith_excp(EXC_M_INV, 0);
462 f24518b5 Richard Henderson
    }
463 f24518b5 Richard Henderson
    return val;
464 f24518b5 Richard Henderson
}
465 f24518b5 Richard Henderson
466 f24518b5 Richard Henderson
/* Input remapping with software completion enabled.  All we have to do
467 f24518b5 Richard Henderson
   is handle denormal-map-to-zero; all other inputs get exceptions as
468 f24518b5 Richard Henderson
   needed from the actual operation.  */
469 f24518b5 Richard Henderson
uint64_t helper_ieee_input_s(uint64_t val)
470 f24518b5 Richard Henderson
{
471 f24518b5 Richard Henderson
    if (env->fpcr_dnz) {
472 f24518b5 Richard Henderson
        uint32_t exp = (uint32_t)(val >> 52) & 0x7ff;
473 f24518b5 Richard Henderson
        if (exp == 0) {
474 f24518b5 Richard Henderson
            val &= 1ull << 63;
475 f24518b5 Richard Henderson
        }
476 f24518b5 Richard Henderson
    }
477 f24518b5 Richard Henderson
    return val;
478 f24518b5 Richard Henderson
}
479 f24518b5 Richard Henderson
480 f18cd223 aurel32
/* F floating (VAX) */
481 636aa200 Blue Swirl
static inline uint64_t float32_to_f(float32 fa)
482 4c9649a9 j_mayer
{
483 f18cd223 aurel32
    uint64_t r, exp, mant, sig;
484 e2eb2798 aurel32
    CPU_FloatU a;
485 f18cd223 aurel32
486 e2eb2798 aurel32
    a.f = fa;
487 e2eb2798 aurel32
    sig = ((uint64_t)a.l & 0x80000000) << 32;
488 e2eb2798 aurel32
    exp = (a.l >> 23) & 0xff;
489 e2eb2798 aurel32
    mant = ((uint64_t)a.l & 0x007fffff) << 29;
490 f18cd223 aurel32
491 f18cd223 aurel32
    if (exp == 255) {
492 f18cd223 aurel32
        /* NaN or infinity */
493 f18cd223 aurel32
        r = 1; /* VAX dirty zero */
494 f18cd223 aurel32
    } else if (exp == 0) {
495 f18cd223 aurel32
        if (mant == 0) {
496 f18cd223 aurel32
            /* Zero */
497 f18cd223 aurel32
            r = 0;
498 f18cd223 aurel32
        } else {
499 f18cd223 aurel32
            /* Denormalized */
500 f18cd223 aurel32
            r = sig | ((exp + 1) << 52) | mant;
501 f18cd223 aurel32
        }
502 f18cd223 aurel32
    } else {
503 f18cd223 aurel32
        if (exp >= 253) {
504 f18cd223 aurel32
            /* Overflow */
505 f18cd223 aurel32
            r = 1; /* VAX dirty zero */
506 f18cd223 aurel32
        } else {
507 f18cd223 aurel32
            r = sig | ((exp + 2) << 52);
508 f18cd223 aurel32
        }
509 f18cd223 aurel32
    }
510 f18cd223 aurel32
511 f18cd223 aurel32
    return r;
512 4c9649a9 j_mayer
}
513 4c9649a9 j_mayer
514 636aa200 Blue Swirl
static inline float32 f_to_float32(uint64_t a)
515 4c9649a9 j_mayer
{
516 e2eb2798 aurel32
    uint32_t exp, mant_sig;
517 e2eb2798 aurel32
    CPU_FloatU r;
518 f18cd223 aurel32
519 f18cd223 aurel32
    exp = ((a >> 55) & 0x80) | ((a >> 52) & 0x7f);
520 f18cd223 aurel32
    mant_sig = ((a >> 32) & 0x80000000) | ((a >> 29) & 0x007fffff);
521 f18cd223 aurel32
522 f18cd223 aurel32
    if (unlikely(!exp && mant_sig)) {
523 f18cd223 aurel32
        /* Reserved operands / Dirty zero */
524 f18cd223 aurel32
        helper_excp(EXCP_OPCDEC, 0);
525 f18cd223 aurel32
    }
526 f18cd223 aurel32
527 f18cd223 aurel32
    if (exp < 3) {
528 f18cd223 aurel32
        /* Underflow */
529 e2eb2798 aurel32
        r.l = 0;
530 f18cd223 aurel32
    } else {
531 e2eb2798 aurel32
        r.l = ((exp - 2) << 23) | mant_sig;
532 f18cd223 aurel32
    }
533 f18cd223 aurel32
534 e2eb2798 aurel32
    return r.f;
535 4c9649a9 j_mayer
}
536 4c9649a9 j_mayer
537 f18cd223 aurel32
uint32_t helper_f_to_memory (uint64_t a)
538 4c9649a9 j_mayer
{
539 f18cd223 aurel32
    uint32_t r;
540 f18cd223 aurel32
    r =  (a & 0x00001fffe0000000ull) >> 13;
541 f18cd223 aurel32
    r |= (a & 0x07ffe00000000000ull) >> 45;
542 f18cd223 aurel32
    r |= (a & 0xc000000000000000ull) >> 48;
543 f18cd223 aurel32
    return r;
544 f18cd223 aurel32
}
545 4c9649a9 j_mayer
546 f18cd223 aurel32
uint64_t helper_memory_to_f (uint32_t a)
547 f18cd223 aurel32
{
548 f18cd223 aurel32
    uint64_t r;
549 f18cd223 aurel32
    r =  ((uint64_t)(a & 0x0000c000)) << 48;
550 f18cd223 aurel32
    r |= ((uint64_t)(a & 0x003fffff)) << 45;
551 f18cd223 aurel32
    r |= ((uint64_t)(a & 0xffff0000)) << 13;
552 f18cd223 aurel32
    if (!(a & 0x00004000))
553 f18cd223 aurel32
        r |= 0x7ll << 59;
554 f18cd223 aurel32
    return r;
555 4c9649a9 j_mayer
}
556 4c9649a9 j_mayer
557 f24518b5 Richard Henderson
/* ??? Emulating VAX arithmetic with IEEE arithmetic is wrong.  We should
558 f24518b5 Richard Henderson
   either implement VAX arithmetic properly or just signal invalid opcode.  */
559 f24518b5 Richard Henderson
560 f18cd223 aurel32
uint64_t helper_addf (uint64_t a, uint64_t b)
561 4c9649a9 j_mayer
{
562 f18cd223 aurel32
    float32 fa, fb, fr;
563 4c9649a9 j_mayer
564 f18cd223 aurel32
    fa = f_to_float32(a);
565 f18cd223 aurel32
    fb = f_to_float32(b);
566 f18cd223 aurel32
    fr = float32_add(fa, fb, &FP_STATUS);
567 f18cd223 aurel32
    return float32_to_f(fr);
568 4c9649a9 j_mayer
}
569 4c9649a9 j_mayer
570 f18cd223 aurel32
uint64_t helper_subf (uint64_t a, uint64_t b)
571 4c9649a9 j_mayer
{
572 f18cd223 aurel32
    float32 fa, fb, fr;
573 4c9649a9 j_mayer
574 f18cd223 aurel32
    fa = f_to_float32(a);
575 f18cd223 aurel32
    fb = f_to_float32(b);
576 f18cd223 aurel32
    fr = float32_sub(fa, fb, &FP_STATUS);
577 f18cd223 aurel32
    return float32_to_f(fr);
578 4c9649a9 j_mayer
}
579 4c9649a9 j_mayer
580 f18cd223 aurel32
uint64_t helper_mulf (uint64_t a, uint64_t b)
581 4c9649a9 j_mayer
{
582 f18cd223 aurel32
    float32 fa, fb, fr;
583 4c9649a9 j_mayer
584 f18cd223 aurel32
    fa = f_to_float32(a);
585 f18cd223 aurel32
    fb = f_to_float32(b);
586 f18cd223 aurel32
    fr = float32_mul(fa, fb, &FP_STATUS);
587 f18cd223 aurel32
    return float32_to_f(fr);
588 4c9649a9 j_mayer
}
589 4c9649a9 j_mayer
590 f18cd223 aurel32
uint64_t helper_divf (uint64_t a, uint64_t b)
591 4c9649a9 j_mayer
{
592 f18cd223 aurel32
    float32 fa, fb, fr;
593 4c9649a9 j_mayer
594 f18cd223 aurel32
    fa = f_to_float32(a);
595 f18cd223 aurel32
    fb = f_to_float32(b);
596 f18cd223 aurel32
    fr = float32_div(fa, fb, &FP_STATUS);
597 f18cd223 aurel32
    return float32_to_f(fr);
598 4c9649a9 j_mayer
}
599 4c9649a9 j_mayer
600 f18cd223 aurel32
uint64_t helper_sqrtf (uint64_t t)
601 4c9649a9 j_mayer
{
602 f18cd223 aurel32
    float32 ft, fr;
603 f18cd223 aurel32
604 f18cd223 aurel32
    ft = f_to_float32(t);
605 f18cd223 aurel32
    fr = float32_sqrt(ft, &FP_STATUS);
606 f18cd223 aurel32
    return float32_to_f(fr);
607 4c9649a9 j_mayer
}
608 4c9649a9 j_mayer
609 f18cd223 aurel32
610 f18cd223 aurel32
/* G floating (VAX) */
611 636aa200 Blue Swirl
static inline uint64_t float64_to_g(float64 fa)
612 4c9649a9 j_mayer
{
613 e2eb2798 aurel32
    uint64_t r, exp, mant, sig;
614 e2eb2798 aurel32
    CPU_DoubleU a;
615 4c9649a9 j_mayer
616 e2eb2798 aurel32
    a.d = fa;
617 e2eb2798 aurel32
    sig = a.ll & 0x8000000000000000ull;
618 e2eb2798 aurel32
    exp = (a.ll >> 52) & 0x7ff;
619 e2eb2798 aurel32
    mant = a.ll & 0x000fffffffffffffull;
620 f18cd223 aurel32
621 f18cd223 aurel32
    if (exp == 2047) {
622 f18cd223 aurel32
        /* NaN or infinity */
623 f18cd223 aurel32
        r = 1; /* VAX dirty zero */
624 f18cd223 aurel32
    } else if (exp == 0) {
625 f18cd223 aurel32
        if (mant == 0) {
626 f18cd223 aurel32
            /* Zero */
627 f18cd223 aurel32
            r = 0;
628 f18cd223 aurel32
        } else {
629 f18cd223 aurel32
            /* Denormalized */
630 f18cd223 aurel32
            r = sig | ((exp + 1) << 52) | mant;
631 f18cd223 aurel32
        }
632 f18cd223 aurel32
    } else {
633 f18cd223 aurel32
        if (exp >= 2045) {
634 f18cd223 aurel32
            /* Overflow */
635 f18cd223 aurel32
            r = 1; /* VAX dirty zero */
636 f18cd223 aurel32
        } else {
637 f18cd223 aurel32
            r = sig | ((exp + 2) << 52);
638 f18cd223 aurel32
        }
639 f18cd223 aurel32
    }
640 f18cd223 aurel32
641 f18cd223 aurel32
    return r;
642 4c9649a9 j_mayer
}
643 4c9649a9 j_mayer
644 636aa200 Blue Swirl
static inline float64 g_to_float64(uint64_t a)
645 4c9649a9 j_mayer
{
646 e2eb2798 aurel32
    uint64_t exp, mant_sig;
647 e2eb2798 aurel32
    CPU_DoubleU r;
648 f18cd223 aurel32
649 f18cd223 aurel32
    exp = (a >> 52) & 0x7ff;
650 f18cd223 aurel32
    mant_sig = a & 0x800fffffffffffffull;
651 f18cd223 aurel32
652 f18cd223 aurel32
    if (!exp && mant_sig) {
653 f18cd223 aurel32
        /* Reserved operands / Dirty zero */
654 f18cd223 aurel32
        helper_excp(EXCP_OPCDEC, 0);
655 f18cd223 aurel32
    }
656 4c9649a9 j_mayer
657 f18cd223 aurel32
    if (exp < 3) {
658 f18cd223 aurel32
        /* Underflow */
659 e2eb2798 aurel32
        r.ll = 0;
660 f18cd223 aurel32
    } else {
661 e2eb2798 aurel32
        r.ll = ((exp - 2) << 52) | mant_sig;
662 f18cd223 aurel32
    }
663 f18cd223 aurel32
664 e2eb2798 aurel32
    return r.d;
665 4c9649a9 j_mayer
}
666 4c9649a9 j_mayer
667 f18cd223 aurel32
uint64_t helper_g_to_memory (uint64_t a)
668 4c9649a9 j_mayer
{
669 f18cd223 aurel32
    uint64_t r;
670 f18cd223 aurel32
    r =  (a & 0x000000000000ffffull) << 48;
671 f18cd223 aurel32
    r |= (a & 0x00000000ffff0000ull) << 16;
672 f18cd223 aurel32
    r |= (a & 0x0000ffff00000000ull) >> 16;
673 f18cd223 aurel32
    r |= (a & 0xffff000000000000ull) >> 48;
674 f18cd223 aurel32
    return r;
675 f18cd223 aurel32
}
676 4c9649a9 j_mayer
677 f18cd223 aurel32
uint64_t helper_memory_to_g (uint64_t a)
678 f18cd223 aurel32
{
679 f18cd223 aurel32
    uint64_t r;
680 f18cd223 aurel32
    r =  (a & 0x000000000000ffffull) << 48;
681 f18cd223 aurel32
    r |= (a & 0x00000000ffff0000ull) << 16;
682 f18cd223 aurel32
    r |= (a & 0x0000ffff00000000ull) >> 16;
683 f18cd223 aurel32
    r |= (a & 0xffff000000000000ull) >> 48;
684 f18cd223 aurel32
    return r;
685 4c9649a9 j_mayer
}
686 4c9649a9 j_mayer
687 f18cd223 aurel32
uint64_t helper_addg (uint64_t a, uint64_t b)
688 4c9649a9 j_mayer
{
689 f18cd223 aurel32
    float64 fa, fb, fr;
690 4c9649a9 j_mayer
691 f18cd223 aurel32
    fa = g_to_float64(a);
692 f18cd223 aurel32
    fb = g_to_float64(b);
693 f18cd223 aurel32
    fr = float64_add(fa, fb, &FP_STATUS);
694 f18cd223 aurel32
    return float64_to_g(fr);
695 4c9649a9 j_mayer
}
696 4c9649a9 j_mayer
697 f18cd223 aurel32
uint64_t helper_subg (uint64_t a, uint64_t b)
698 4c9649a9 j_mayer
{
699 f18cd223 aurel32
    float64 fa, fb, fr;
700 4c9649a9 j_mayer
701 f18cd223 aurel32
    fa = g_to_float64(a);
702 f18cd223 aurel32
    fb = g_to_float64(b);
703 f18cd223 aurel32
    fr = float64_sub(fa, fb, &FP_STATUS);
704 f18cd223 aurel32
    return float64_to_g(fr);
705 4c9649a9 j_mayer
}
706 4c9649a9 j_mayer
707 f18cd223 aurel32
uint64_t helper_mulg (uint64_t a, uint64_t b)
708 4c9649a9 j_mayer
{
709 f18cd223 aurel32
    float64 fa, fb, fr;
710 4c9649a9 j_mayer
711 f18cd223 aurel32
    fa = g_to_float64(a);
712 f18cd223 aurel32
    fb = g_to_float64(b);
713 f18cd223 aurel32
    fr = float64_mul(fa, fb, &FP_STATUS);
714 f18cd223 aurel32
    return float64_to_g(fr);
715 4c9649a9 j_mayer
}
716 4c9649a9 j_mayer
717 f18cd223 aurel32
uint64_t helper_divg (uint64_t a, uint64_t b)
718 4c9649a9 j_mayer
{
719 f18cd223 aurel32
    float64 fa, fb, fr;
720 4c9649a9 j_mayer
721 f18cd223 aurel32
    fa = g_to_float64(a);
722 f18cd223 aurel32
    fb = g_to_float64(b);
723 f18cd223 aurel32
    fr = float64_div(fa, fb, &FP_STATUS);
724 f18cd223 aurel32
    return float64_to_g(fr);
725 f18cd223 aurel32
}
726 f18cd223 aurel32
727 f18cd223 aurel32
uint64_t helper_sqrtg (uint64_t a)
728 f18cd223 aurel32
{
729 f18cd223 aurel32
    float64 fa, fr;
730 4c9649a9 j_mayer
731 f18cd223 aurel32
    fa = g_to_float64(a);
732 f18cd223 aurel32
    fr = float64_sqrt(fa, &FP_STATUS);
733 f18cd223 aurel32
    return float64_to_g(fr);
734 4c9649a9 j_mayer
}
735 4c9649a9 j_mayer
736 f18cd223 aurel32
737 f18cd223 aurel32
/* S floating (single) */
738 d0af5445 Richard Henderson
739 d0af5445 Richard Henderson
/* Taken from linux/arch/alpha/kernel/traps.c, s_mem_to_reg.  */
740 d0af5445 Richard Henderson
static inline uint64_t float32_to_s_int(uint32_t fi)
741 d0af5445 Richard Henderson
{
742 d0af5445 Richard Henderson
    uint32_t frac = fi & 0x7fffff;
743 d0af5445 Richard Henderson
    uint32_t sign = fi >> 31;
744 d0af5445 Richard Henderson
    uint32_t exp_msb = (fi >> 30) & 1;
745 d0af5445 Richard Henderson
    uint32_t exp_low = (fi >> 23) & 0x7f;
746 d0af5445 Richard Henderson
    uint32_t exp;
747 d0af5445 Richard Henderson
748 d0af5445 Richard Henderson
    exp = (exp_msb << 10) | exp_low;
749 d0af5445 Richard Henderson
    if (exp_msb) {
750 d0af5445 Richard Henderson
        if (exp_low == 0x7f)
751 d0af5445 Richard Henderson
            exp = 0x7ff;
752 d0af5445 Richard Henderson
    } else {
753 d0af5445 Richard Henderson
        if (exp_low != 0x00)
754 d0af5445 Richard Henderson
            exp |= 0x380;
755 d0af5445 Richard Henderson
    }
756 d0af5445 Richard Henderson
757 d0af5445 Richard Henderson
    return (((uint64_t)sign << 63)
758 d0af5445 Richard Henderson
            | ((uint64_t)exp << 52)
759 d0af5445 Richard Henderson
            | ((uint64_t)frac << 29));
760 d0af5445 Richard Henderson
}
761 d0af5445 Richard Henderson
762 636aa200 Blue Swirl
static inline uint64_t float32_to_s(float32 fa)
763 4c9649a9 j_mayer
{
764 e2eb2798 aurel32
    CPU_FloatU a;
765 e2eb2798 aurel32
    a.f = fa;
766 d0af5445 Richard Henderson
    return float32_to_s_int(a.l);
767 d0af5445 Richard Henderson
}
768 4c9649a9 j_mayer
769 d0af5445 Richard Henderson
static inline uint32_t s_to_float32_int(uint64_t a)
770 d0af5445 Richard Henderson
{
771 d0af5445 Richard Henderson
    return ((a >> 32) & 0xc0000000) | ((a >> 29) & 0x3fffffff);
772 4c9649a9 j_mayer
}
773 4c9649a9 j_mayer
774 636aa200 Blue Swirl
static inline float32 s_to_float32(uint64_t a)
775 4c9649a9 j_mayer
{
776 e2eb2798 aurel32
    CPU_FloatU r;
777 d0af5445 Richard Henderson
    r.l = s_to_float32_int(a);
778 e2eb2798 aurel32
    return r.f;
779 f18cd223 aurel32
}
780 4c9649a9 j_mayer
781 f18cd223 aurel32
uint32_t helper_s_to_memory (uint64_t a)
782 f18cd223 aurel32
{
783 d0af5445 Richard Henderson
    return s_to_float32_int(a);
784 f18cd223 aurel32
}
785 4c9649a9 j_mayer
786 f18cd223 aurel32
uint64_t helper_memory_to_s (uint32_t a)
787 f18cd223 aurel32
{
788 d0af5445 Richard Henderson
    return float32_to_s_int(a);
789 4c9649a9 j_mayer
}
790 4c9649a9 j_mayer
791 f18cd223 aurel32
uint64_t helper_adds (uint64_t a, uint64_t b)
792 4c9649a9 j_mayer
{
793 f18cd223 aurel32
    float32 fa, fb, fr;
794 4c9649a9 j_mayer
795 f18cd223 aurel32
    fa = s_to_float32(a);
796 f18cd223 aurel32
    fb = s_to_float32(b);
797 f18cd223 aurel32
    fr = float32_add(fa, fb, &FP_STATUS);
798 f18cd223 aurel32
    return float32_to_s(fr);
799 4c9649a9 j_mayer
}
800 4c9649a9 j_mayer
801 f18cd223 aurel32
uint64_t helper_subs (uint64_t a, uint64_t b)
802 4c9649a9 j_mayer
{
803 f18cd223 aurel32
    float32 fa, fb, fr;
804 4c9649a9 j_mayer
805 f18cd223 aurel32
    fa = s_to_float32(a);
806 f18cd223 aurel32
    fb = s_to_float32(b);
807 f18cd223 aurel32
    fr = float32_sub(fa, fb, &FP_STATUS);
808 f18cd223 aurel32
    return float32_to_s(fr);
809 4c9649a9 j_mayer
}
810 4c9649a9 j_mayer
811 f18cd223 aurel32
uint64_t helper_muls (uint64_t a, uint64_t b)
812 4c9649a9 j_mayer
{
813 f18cd223 aurel32
    float32 fa, fb, fr;
814 4c9649a9 j_mayer
815 f18cd223 aurel32
    fa = s_to_float32(a);
816 f18cd223 aurel32
    fb = s_to_float32(b);
817 f18cd223 aurel32
    fr = float32_mul(fa, fb, &FP_STATUS);
818 f18cd223 aurel32
    return float32_to_s(fr);
819 4c9649a9 j_mayer
}
820 4c9649a9 j_mayer
821 f18cd223 aurel32
uint64_t helper_divs (uint64_t a, uint64_t b)
822 4c9649a9 j_mayer
{
823 f18cd223 aurel32
    float32 fa, fb, fr;
824 4c9649a9 j_mayer
825 f18cd223 aurel32
    fa = s_to_float32(a);
826 f18cd223 aurel32
    fb = s_to_float32(b);
827 f18cd223 aurel32
    fr = float32_div(fa, fb, &FP_STATUS);
828 f18cd223 aurel32
    return float32_to_s(fr);
829 4c9649a9 j_mayer
}
830 4c9649a9 j_mayer
831 f18cd223 aurel32
uint64_t helper_sqrts (uint64_t a)
832 4c9649a9 j_mayer
{
833 f18cd223 aurel32
    float32 fa, fr;
834 4c9649a9 j_mayer
835 f18cd223 aurel32
    fa = s_to_float32(a);
836 f18cd223 aurel32
    fr = float32_sqrt(fa, &FP_STATUS);
837 f18cd223 aurel32
    return float32_to_s(fr);
838 4c9649a9 j_mayer
}
839 4c9649a9 j_mayer
840 f18cd223 aurel32
841 f18cd223 aurel32
/* T floating (double) */
842 636aa200 Blue Swirl
static inline float64 t_to_float64(uint64_t a)
843 4c9649a9 j_mayer
{
844 f18cd223 aurel32
    /* Memory format is the same as float64 */
845 e2eb2798 aurel32
    CPU_DoubleU r;
846 e2eb2798 aurel32
    r.ll = a;
847 e2eb2798 aurel32
    return r.d;
848 4c9649a9 j_mayer
}
849 4c9649a9 j_mayer
850 636aa200 Blue Swirl
static inline uint64_t float64_to_t(float64 fa)
851 4c9649a9 j_mayer
{
852 f18cd223 aurel32
    /* Memory format is the same as float64 */
853 e2eb2798 aurel32
    CPU_DoubleU r;
854 e2eb2798 aurel32
    r.d = fa;
855 e2eb2798 aurel32
    return r.ll;
856 f18cd223 aurel32
}
857 4c9649a9 j_mayer
858 f18cd223 aurel32
uint64_t helper_addt (uint64_t a, uint64_t b)
859 f18cd223 aurel32
{
860 f18cd223 aurel32
    float64 fa, fb, fr;
861 4c9649a9 j_mayer
862 f18cd223 aurel32
    fa = t_to_float64(a);
863 f18cd223 aurel32
    fb = t_to_float64(b);
864 f18cd223 aurel32
    fr = float64_add(fa, fb, &FP_STATUS);
865 f18cd223 aurel32
    return float64_to_t(fr);
866 4c9649a9 j_mayer
}
867 4c9649a9 j_mayer
868 f18cd223 aurel32
uint64_t helper_subt (uint64_t a, uint64_t b)
869 4c9649a9 j_mayer
{
870 f18cd223 aurel32
    float64 fa, fb, fr;
871 4c9649a9 j_mayer
872 f18cd223 aurel32
    fa = t_to_float64(a);
873 f18cd223 aurel32
    fb = t_to_float64(b);
874 f18cd223 aurel32
    fr = float64_sub(fa, fb, &FP_STATUS);
875 f18cd223 aurel32
    return float64_to_t(fr);
876 4c9649a9 j_mayer
}
877 4c9649a9 j_mayer
878 f18cd223 aurel32
uint64_t helper_mult (uint64_t a, uint64_t b)
879 4c9649a9 j_mayer
{
880 f18cd223 aurel32
    float64 fa, fb, fr;
881 4c9649a9 j_mayer
882 f18cd223 aurel32
    fa = t_to_float64(a);
883 f18cd223 aurel32
    fb = t_to_float64(b);
884 f18cd223 aurel32
    fr = float64_mul(fa, fb, &FP_STATUS);
885 f18cd223 aurel32
    return float64_to_t(fr);
886 4c9649a9 j_mayer
}
887 4c9649a9 j_mayer
888 f18cd223 aurel32
uint64_t helper_divt (uint64_t a, uint64_t b)
889 4c9649a9 j_mayer
{
890 f18cd223 aurel32
    float64 fa, fb, fr;
891 4c9649a9 j_mayer
892 f18cd223 aurel32
    fa = t_to_float64(a);
893 f18cd223 aurel32
    fb = t_to_float64(b);
894 f18cd223 aurel32
    fr = float64_div(fa, fb, &FP_STATUS);
895 f18cd223 aurel32
    return float64_to_t(fr);
896 4c9649a9 j_mayer
}
897 4c9649a9 j_mayer
898 f18cd223 aurel32
uint64_t helper_sqrtt (uint64_t a)
899 4c9649a9 j_mayer
{
900 f18cd223 aurel32
    float64 fa, fr;
901 4c9649a9 j_mayer
902 f18cd223 aurel32
    fa = t_to_float64(a);
903 f18cd223 aurel32
    fr = float64_sqrt(fa, &FP_STATUS);
904 f18cd223 aurel32
    return float64_to_t(fr);
905 4c9649a9 j_mayer
}
906 4c9649a9 j_mayer
907 f18cd223 aurel32
/* Comparisons */
908 f18cd223 aurel32
uint64_t helper_cmptun (uint64_t a, uint64_t b)
909 4c9649a9 j_mayer
{
910 f18cd223 aurel32
    float64 fa, fb;
911 4c9649a9 j_mayer
912 f18cd223 aurel32
    fa = t_to_float64(a);
913 f18cd223 aurel32
    fb = t_to_float64(b);
914 f18cd223 aurel32
915 a4d2d1a0 Aurelien Jarno
    if (float64_unordered_quiet(fa, fb, &FP_STATUS)) {
916 f18cd223 aurel32
        return 0x4000000000000000ULL;
917 a4d2d1a0 Aurelien Jarno
    } else {
918 f18cd223 aurel32
        return 0;
919 a4d2d1a0 Aurelien Jarno
    }
920 4c9649a9 j_mayer
}
921 4c9649a9 j_mayer
922 f18cd223 aurel32
uint64_t helper_cmpteq(uint64_t a, uint64_t b)
923 4c9649a9 j_mayer
{
924 f18cd223 aurel32
    float64 fa, fb;
925 4c9649a9 j_mayer
926 f18cd223 aurel32
    fa = t_to_float64(a);
927 f18cd223 aurel32
    fb = t_to_float64(b);
928 f18cd223 aurel32
929 211315fb Aurelien Jarno
    if (float64_eq_quiet(fa, fb, &FP_STATUS))
930 f18cd223 aurel32
        return 0x4000000000000000ULL;
931 f18cd223 aurel32
    else
932 f18cd223 aurel32
        return 0;
933 4c9649a9 j_mayer
}
934 4c9649a9 j_mayer
935 f18cd223 aurel32
uint64_t helper_cmptle(uint64_t a, uint64_t b)
936 4c9649a9 j_mayer
{
937 f18cd223 aurel32
    float64 fa, fb;
938 4c9649a9 j_mayer
939 f18cd223 aurel32
    fa = t_to_float64(a);
940 f18cd223 aurel32
    fb = t_to_float64(b);
941 f18cd223 aurel32
942 f18cd223 aurel32
    if (float64_le(fa, fb, &FP_STATUS))
943 f18cd223 aurel32
        return 0x4000000000000000ULL;
944 f18cd223 aurel32
    else
945 f18cd223 aurel32
        return 0;
946 4c9649a9 j_mayer
}
947 4c9649a9 j_mayer
948 f18cd223 aurel32
uint64_t helper_cmptlt(uint64_t a, uint64_t b)
949 4c9649a9 j_mayer
{
950 f18cd223 aurel32
    float64 fa, fb;
951 4c9649a9 j_mayer
952 f18cd223 aurel32
    fa = t_to_float64(a);
953 f18cd223 aurel32
    fb = t_to_float64(b);
954 f18cd223 aurel32
955 f18cd223 aurel32
    if (float64_lt(fa, fb, &FP_STATUS))
956 f18cd223 aurel32
        return 0x4000000000000000ULL;
957 f18cd223 aurel32
    else
958 f18cd223 aurel32
        return 0;
959 4c9649a9 j_mayer
}
960 4c9649a9 j_mayer
961 f18cd223 aurel32
uint64_t helper_cmpgeq(uint64_t a, uint64_t b)
962 4c9649a9 j_mayer
{
963 f18cd223 aurel32
    float64 fa, fb;
964 4c9649a9 j_mayer
965 f18cd223 aurel32
    fa = g_to_float64(a);
966 f18cd223 aurel32
    fb = g_to_float64(b);
967 f18cd223 aurel32
968 211315fb Aurelien Jarno
    if (float64_eq_quiet(fa, fb, &FP_STATUS))
969 f18cd223 aurel32
        return 0x4000000000000000ULL;
970 f18cd223 aurel32
    else
971 f18cd223 aurel32
        return 0;
972 4c9649a9 j_mayer
}
973 4c9649a9 j_mayer
974 f18cd223 aurel32
uint64_t helper_cmpgle(uint64_t a, uint64_t b)
975 4c9649a9 j_mayer
{
976 f18cd223 aurel32
    float64 fa, fb;
977 f18cd223 aurel32
978 f18cd223 aurel32
    fa = g_to_float64(a);
979 f18cd223 aurel32
    fb = g_to_float64(b);
980 4c9649a9 j_mayer
981 f18cd223 aurel32
    if (float64_le(fa, fb, &FP_STATUS))
982 f18cd223 aurel32
        return 0x4000000000000000ULL;
983 f18cd223 aurel32
    else
984 f18cd223 aurel32
        return 0;
985 4c9649a9 j_mayer
}
986 4c9649a9 j_mayer
987 f18cd223 aurel32
uint64_t helper_cmpglt(uint64_t a, uint64_t b)
988 4c9649a9 j_mayer
{
989 f18cd223 aurel32
    float64 fa, fb;
990 f18cd223 aurel32
991 f18cd223 aurel32
    fa = g_to_float64(a);
992 f18cd223 aurel32
    fb = g_to_float64(b);
993 4c9649a9 j_mayer
994 f18cd223 aurel32
    if (float64_lt(fa, fb, &FP_STATUS))
995 f18cd223 aurel32
        return 0x4000000000000000ULL;
996 f18cd223 aurel32
    else
997 f18cd223 aurel32
        return 0;
998 4c9649a9 j_mayer
}
999 4c9649a9 j_mayer
1000 f18cd223 aurel32
/* Floating point format conversion */
1001 f18cd223 aurel32
uint64_t helper_cvtts (uint64_t a)
1002 4c9649a9 j_mayer
{
1003 f18cd223 aurel32
    float64 fa;
1004 f18cd223 aurel32
    float32 fr;
1005 4c9649a9 j_mayer
1006 f18cd223 aurel32
    fa = t_to_float64(a);
1007 f18cd223 aurel32
    fr = float64_to_float32(fa, &FP_STATUS);
1008 f18cd223 aurel32
    return float32_to_s(fr);
1009 4c9649a9 j_mayer
}
1010 4c9649a9 j_mayer
1011 f18cd223 aurel32
uint64_t helper_cvtst (uint64_t a)
1012 4c9649a9 j_mayer
{
1013 f18cd223 aurel32
    float32 fa;
1014 f18cd223 aurel32
    float64 fr;
1015 f18cd223 aurel32
1016 f18cd223 aurel32
    fa = s_to_float32(a);
1017 f18cd223 aurel32
    fr = float32_to_float64(fa, &FP_STATUS);
1018 f18cd223 aurel32
    return float64_to_t(fr);
1019 4c9649a9 j_mayer
}
1020 4c9649a9 j_mayer
1021 f18cd223 aurel32
uint64_t helper_cvtqs (uint64_t a)
1022 4c9649a9 j_mayer
{
1023 f18cd223 aurel32
    float32 fr = int64_to_float32(a, &FP_STATUS);
1024 f18cd223 aurel32
    return float32_to_s(fr);
1025 4c9649a9 j_mayer
}
1026 4c9649a9 j_mayer
1027 f24518b5 Richard Henderson
/* Implement float64 to uint64 conversion without saturation -- we must
1028 f24518b5 Richard Henderson
   supply the truncated result.  This behaviour is used by the compiler
1029 f24518b5 Richard Henderson
   to get unsigned conversion for free with the same instruction.
1030 f24518b5 Richard Henderson

1031 f24518b5 Richard Henderson
   The VI flag is set when overflow or inexact exceptions should be raised.  */
1032 f24518b5 Richard Henderson
1033 f24518b5 Richard Henderson
static inline uint64_t helper_cvttq_internal(uint64_t a, int roundmode, int VI)
1034 4c9649a9 j_mayer
{
1035 f24518b5 Richard Henderson
    uint64_t frac, ret = 0;
1036 f24518b5 Richard Henderson
    uint32_t exp, sign, exc = 0;
1037 f24518b5 Richard Henderson
    int shift;
1038 f24518b5 Richard Henderson
1039 f24518b5 Richard Henderson
    sign = (a >> 63);
1040 f24518b5 Richard Henderson
    exp = (uint32_t)(a >> 52) & 0x7ff;
1041 f24518b5 Richard Henderson
    frac = a & 0xfffffffffffffull;
1042 f24518b5 Richard Henderson
1043 f24518b5 Richard Henderson
    if (exp == 0) {
1044 f24518b5 Richard Henderson
        if (unlikely(frac != 0)) {
1045 f24518b5 Richard Henderson
            goto do_underflow;
1046 f24518b5 Richard Henderson
        }
1047 f24518b5 Richard Henderson
    } else if (exp == 0x7ff) {
1048 f24518b5 Richard Henderson
        exc = (frac ? float_flag_invalid : VI ? float_flag_overflow : 0);
1049 f24518b5 Richard Henderson
    } else {
1050 f24518b5 Richard Henderson
        /* Restore implicit bit.  */
1051 f24518b5 Richard Henderson
        frac |= 0x10000000000000ull;
1052 f24518b5 Richard Henderson
1053 f24518b5 Richard Henderson
        shift = exp - 1023 - 52;
1054 f24518b5 Richard Henderson
        if (shift >= 0) {
1055 f24518b5 Richard Henderson
            /* In this case the number is so large that we must shift
1056 f24518b5 Richard Henderson
               the fraction left.  There is no rounding to do.  */
1057 f24518b5 Richard Henderson
            if (shift < 63) {
1058 f24518b5 Richard Henderson
                ret = frac << shift;
1059 f24518b5 Richard Henderson
                if (VI && (ret >> shift) != frac) {
1060 f24518b5 Richard Henderson
                    exc = float_flag_overflow;
1061 f24518b5 Richard Henderson
                }
1062 f24518b5 Richard Henderson
            }
1063 f24518b5 Richard Henderson
        } else {
1064 f24518b5 Richard Henderson
            uint64_t round;
1065 f24518b5 Richard Henderson
1066 f24518b5 Richard Henderson
            /* In this case the number is smaller than the fraction as
1067 f24518b5 Richard Henderson
               represented by the 52 bit number.  Here we must think
1068 f24518b5 Richard Henderson
               about rounding the result.  Handle this by shifting the
1069 f24518b5 Richard Henderson
               fractional part of the number into the high bits of ROUND.
1070 f24518b5 Richard Henderson
               This will let us efficiently handle round-to-nearest.  */
1071 f24518b5 Richard Henderson
            shift = -shift;
1072 f24518b5 Richard Henderson
            if (shift < 63) {
1073 f24518b5 Richard Henderson
                ret = frac >> shift;
1074 f24518b5 Richard Henderson
                round = frac << (64 - shift);
1075 f24518b5 Richard Henderson
            } else {
1076 f24518b5 Richard Henderson
                /* The exponent is so small we shift out everything.
1077 f24518b5 Richard Henderson
                   Leave a sticky bit for proper rounding below.  */
1078 f24518b5 Richard Henderson
            do_underflow:
1079 f24518b5 Richard Henderson
                round = 1;
1080 f24518b5 Richard Henderson
            }
1081 f24518b5 Richard Henderson
1082 f24518b5 Richard Henderson
            if (round) {
1083 f24518b5 Richard Henderson
                exc = (VI ? float_flag_inexact : 0);
1084 f24518b5 Richard Henderson
                switch (roundmode) {
1085 f24518b5 Richard Henderson
                case float_round_nearest_even:
1086 f24518b5 Richard Henderson
                    if (round == (1ull << 63)) {
1087 f24518b5 Richard Henderson
                        /* Fraction is exactly 0.5; round to even.  */
1088 f24518b5 Richard Henderson
                        ret += (ret & 1);
1089 f24518b5 Richard Henderson
                    } else if (round > (1ull << 63)) {
1090 f24518b5 Richard Henderson
                        ret += 1;
1091 f24518b5 Richard Henderson
                    }
1092 f24518b5 Richard Henderson
                    break;
1093 f24518b5 Richard Henderson
                case float_round_to_zero:
1094 f24518b5 Richard Henderson
                    break;
1095 f24518b5 Richard Henderson
                case float_round_up:
1096 f24518b5 Richard Henderson
                    ret += 1 - sign;
1097 f24518b5 Richard Henderson
                    break;
1098 f24518b5 Richard Henderson
                case float_round_down:
1099 f24518b5 Richard Henderson
                    ret += sign;
1100 f24518b5 Richard Henderson
                    break;
1101 f24518b5 Richard Henderson
                }
1102 f24518b5 Richard Henderson
            }
1103 f24518b5 Richard Henderson
        }
1104 f24518b5 Richard Henderson
        if (sign) {
1105 f24518b5 Richard Henderson
            ret = -ret;
1106 f24518b5 Richard Henderson
        }
1107 f24518b5 Richard Henderson
    }
1108 f24518b5 Richard Henderson
    if (unlikely(exc)) {
1109 f24518b5 Richard Henderson
        float_raise(exc, &FP_STATUS);
1110 f24518b5 Richard Henderson
    }
1111 f24518b5 Richard Henderson
1112 f24518b5 Richard Henderson
    return ret;
1113 f24518b5 Richard Henderson
}
1114 f24518b5 Richard Henderson
1115 f24518b5 Richard Henderson
uint64_t helper_cvttq(uint64_t a)
1116 f24518b5 Richard Henderson
{
1117 f24518b5 Richard Henderson
    return helper_cvttq_internal(a, FP_STATUS.float_rounding_mode, 1);
1118 f24518b5 Richard Henderson
}
1119 f24518b5 Richard Henderson
1120 f24518b5 Richard Henderson
uint64_t helper_cvttq_c(uint64_t a)
1121 f24518b5 Richard Henderson
{
1122 f24518b5 Richard Henderson
    return helper_cvttq_internal(a, float_round_to_zero, 0);
1123 f24518b5 Richard Henderson
}
1124 f24518b5 Richard Henderson
1125 f24518b5 Richard Henderson
uint64_t helper_cvttq_svic(uint64_t a)
1126 f24518b5 Richard Henderson
{
1127 f24518b5 Richard Henderson
    return helper_cvttq_internal(a, float_round_to_zero, 1);
1128 f18cd223 aurel32
}
1129 4c9649a9 j_mayer
1130 f18cd223 aurel32
uint64_t helper_cvtqt (uint64_t a)
1131 f18cd223 aurel32
{
1132 f18cd223 aurel32
    float64 fr = int64_to_float64(a, &FP_STATUS);
1133 f18cd223 aurel32
    return float64_to_t(fr);
1134 4c9649a9 j_mayer
}
1135 4c9649a9 j_mayer
1136 f18cd223 aurel32
uint64_t helper_cvtqf (uint64_t a)
1137 4c9649a9 j_mayer
{
1138 f18cd223 aurel32
    float32 fr = int64_to_float32(a, &FP_STATUS);
1139 f18cd223 aurel32
    return float32_to_f(fr);
1140 4c9649a9 j_mayer
}
1141 4c9649a9 j_mayer
1142 f18cd223 aurel32
uint64_t helper_cvtgf (uint64_t a)
1143 4c9649a9 j_mayer
{
1144 f18cd223 aurel32
    float64 fa;
1145 f18cd223 aurel32
    float32 fr;
1146 f18cd223 aurel32
1147 f18cd223 aurel32
    fa = g_to_float64(a);
1148 f18cd223 aurel32
    fr = float64_to_float32(fa, &FP_STATUS);
1149 f18cd223 aurel32
    return float32_to_f(fr);
1150 4c9649a9 j_mayer
}
1151 4c9649a9 j_mayer
1152 f18cd223 aurel32
uint64_t helper_cvtgq (uint64_t a)
1153 4c9649a9 j_mayer
{
1154 f18cd223 aurel32
    float64 fa = g_to_float64(a);
1155 f18cd223 aurel32
    return float64_to_int64_round_to_zero(fa, &FP_STATUS);
1156 4c9649a9 j_mayer
}
1157 4c9649a9 j_mayer
1158 f18cd223 aurel32
uint64_t helper_cvtqg (uint64_t a)
1159 4c9649a9 j_mayer
{
1160 f18cd223 aurel32
    float64 fr;
1161 f18cd223 aurel32
    fr = int64_to_float64(a, &FP_STATUS);
1162 f18cd223 aurel32
    return float64_to_g(fr);
1163 4c9649a9 j_mayer
}
1164 4c9649a9 j_mayer
1165 8bb6e981 aurel32
/* PALcode support special instructions */
1166 4c9649a9 j_mayer
#if !defined (CONFIG_USER_ONLY)
1167 8bb6e981 aurel32
void helper_hw_ret (uint64_t a)
1168 8bb6e981 aurel32
{
1169 8bb6e981 aurel32
    env->pc = a & ~3;
1170 129d8aa5 Richard Henderson
    env->pal_mode = a & 1;
1171 ac316ca4 Richard Henderson
    env->intr_flag = 0;
1172 6910b8f6 Richard Henderson
    env->lock_addr = -1;
1173 8bb6e981 aurel32
}
1174 4c9649a9 j_mayer
#endif
1175 4c9649a9 j_mayer
1176 4c9649a9 j_mayer
/*****************************************************************************/
1177 4c9649a9 j_mayer
/* Softmmu support */
1178 4c9649a9 j_mayer
#if !defined (CONFIG_USER_ONLY)
1179 2374e73e Richard Henderson
uint64_t helper_ldl_phys(uint64_t p)
1180 8bb6e981 aurel32
{
1181 2374e73e Richard Henderson
    return (int32_t)ldl_phys(p);
1182 8bb6e981 aurel32
}
1183 8bb6e981 aurel32
1184 2374e73e Richard Henderson
uint64_t helper_ldq_phys(uint64_t p)
1185 8bb6e981 aurel32
{
1186 2374e73e Richard Henderson
    return ldq_phys(p);
1187 8bb6e981 aurel32
}
1188 8bb6e981 aurel32
1189 2374e73e Richard Henderson
uint64_t helper_ldl_l_phys(uint64_t p)
1190 8bb6e981 aurel32
{
1191 2374e73e Richard Henderson
    env->lock_addr = p;
1192 2374e73e Richard Henderson
    return env->lock_value = (int32_t)ldl_phys(p);
1193 8bb6e981 aurel32
}
1194 8bb6e981 aurel32
1195 2374e73e Richard Henderson
uint64_t helper_ldq_l_phys(uint64_t p)
1196 8bb6e981 aurel32
{
1197 2374e73e Richard Henderson
    env->lock_addr = p;
1198 2374e73e Richard Henderson
    return env->lock_value = ldl_phys(p);
1199 8bb6e981 aurel32
}
1200 8bb6e981 aurel32
1201 2374e73e Richard Henderson
void helper_stl_phys(uint64_t p, uint64_t v)
1202 8bb6e981 aurel32
{
1203 2374e73e Richard Henderson
    stl_phys(p, v);
1204 8bb6e981 aurel32
}
1205 8bb6e981 aurel32
1206 2374e73e Richard Henderson
void helper_stq_phys(uint64_t p, uint64_t v)
1207 8bb6e981 aurel32
{
1208 2374e73e Richard Henderson
    stq_phys(p, v);
1209 8bb6e981 aurel32
}
1210 8bb6e981 aurel32
1211 2374e73e Richard Henderson
uint64_t helper_stl_c_phys(uint64_t p, uint64_t v)
1212 8bb6e981 aurel32
{
1213 2374e73e Richard Henderson
    uint64_t ret = 0;
1214 8bb6e981 aurel32
1215 2374e73e Richard Henderson
    if (p == env->lock_addr) {
1216 2374e73e Richard Henderson
        int32_t old = ldl_phys(p);
1217 2374e73e Richard Henderson
        if (old == (int32_t)env->lock_value) {
1218 2374e73e Richard Henderson
            stl_phys(p, v);
1219 2374e73e Richard Henderson
            ret = 1;
1220 2374e73e Richard Henderson
        }
1221 2374e73e Richard Henderson
    }
1222 2374e73e Richard Henderson
    env->lock_addr = -1;
1223 8bb6e981 aurel32
1224 8bb6e981 aurel32
    return ret;
1225 8bb6e981 aurel32
}
1226 8bb6e981 aurel32
1227 2374e73e Richard Henderson
uint64_t helper_stq_c_phys(uint64_t p, uint64_t v)
1228 8bb6e981 aurel32
{
1229 2374e73e Richard Henderson
    uint64_t ret = 0;
1230 8bb6e981 aurel32
1231 2374e73e Richard Henderson
    if (p == env->lock_addr) {
1232 2374e73e Richard Henderson
        uint64_t old = ldq_phys(p);
1233 2374e73e Richard Henderson
        if (old == env->lock_value) {
1234 2374e73e Richard Henderson
            stq_phys(p, v);
1235 2374e73e Richard Henderson
            ret = 1;
1236 2374e73e Richard Henderson
        }
1237 2374e73e Richard Henderson
    }
1238 2374e73e Richard Henderson
    env->lock_addr = -1;
1239 8bb6e981 aurel32
1240 8bb6e981 aurel32
    return ret;
1241 4c9649a9 j_mayer
}
1242 4c9649a9 j_mayer
1243 4c9649a9 j_mayer
#define MMUSUFFIX _mmu
1244 4c9649a9 j_mayer
1245 4c9649a9 j_mayer
#define SHIFT 0
1246 4c9649a9 j_mayer
#include "softmmu_template.h"
1247 4c9649a9 j_mayer
1248 4c9649a9 j_mayer
#define SHIFT 1
1249 4c9649a9 j_mayer
#include "softmmu_template.h"
1250 4c9649a9 j_mayer
1251 4c9649a9 j_mayer
#define SHIFT 2
1252 4c9649a9 j_mayer
#include "softmmu_template.h"
1253 4c9649a9 j_mayer
1254 4c9649a9 j_mayer
#define SHIFT 3
1255 4c9649a9 j_mayer
#include "softmmu_template.h"
1256 4c9649a9 j_mayer
1257 4c9649a9 j_mayer
/* try to fill the TLB and return an exception if error. If retaddr is
1258 4c9649a9 j_mayer
   NULL, it means that the function was called in C code (i.e. not
1259 4c9649a9 j_mayer
   from generated code or from helper.c) */
1260 4c9649a9 j_mayer
/* XXX: fix it to restore all registers */
1261 6ebbf390 j_mayer
void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
1262 4c9649a9 j_mayer
{
1263 4c9649a9 j_mayer
    TranslationBlock *tb;
1264 4c9649a9 j_mayer
    CPUState *saved_env;
1265 44f8625d bellard
    unsigned long pc;
1266 4c9649a9 j_mayer
    int ret;
1267 4c9649a9 j_mayer
1268 4c9649a9 j_mayer
    /* XXX: hack to restore env in all cases, even if not called from
1269 4c9649a9 j_mayer
       generated code */
1270 4c9649a9 j_mayer
    saved_env = env;
1271 4c9649a9 j_mayer
    env = cpu_single_env;
1272 6ebbf390 j_mayer
    ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
1273 4c9649a9 j_mayer
    if (!likely(ret == 0)) {
1274 4c9649a9 j_mayer
        if (likely(retaddr)) {
1275 4c9649a9 j_mayer
            /* now we have a real cpu fault */
1276 44f8625d bellard
            pc = (unsigned long)retaddr;
1277 4c9649a9 j_mayer
            tb = tb_find_pc(pc);
1278 4c9649a9 j_mayer
            if (likely(tb)) {
1279 4c9649a9 j_mayer
                /* the PC is inside the translated code. It means that we have
1280 4c9649a9 j_mayer
                   a virtual CPU fault */
1281 618ba8e6 Stefan Weil
                cpu_restore_state(tb, env, pc);
1282 4c9649a9 j_mayer
            }
1283 4c9649a9 j_mayer
        }
1284 4c9649a9 j_mayer
        /* Exception index and error code are already set */
1285 4c9649a9 j_mayer
        cpu_loop_exit();
1286 4c9649a9 j_mayer
    }
1287 4c9649a9 j_mayer
    env = saved_env;
1288 4c9649a9 j_mayer
}
1289 4c9649a9 j_mayer
1290 4c9649a9 j_mayer
#endif