Statistics
| Branch: | Revision:

root / target-alpha / op_helper.c @ 866be65d

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