Statistics
| Branch: | Revision:

root / target-alpha / op_helper.c @ 86cc1ce0

History | View | Annotate | Download (22.9 kB)

1 4c9649a9 j_mayer
/*
2 4c9649a9 j_mayer
 *  Alpha emulation cpu micro-operations helpers for qemu.
3 4c9649a9 j_mayer
 * 
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 4c9649a9 j_mayer
 * License along with this library; if not, write to the Free Software
18 4c9649a9 j_mayer
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 4c9649a9 j_mayer
 */
20 4c9649a9 j_mayer
21 4c9649a9 j_mayer
#include "exec.h"
22 4c9649a9 j_mayer
#include "softfloat.h"
23 4c9649a9 j_mayer
24 4c9649a9 j_mayer
#include "op_helper.h"
25 4c9649a9 j_mayer
26 4c9649a9 j_mayer
#define MEMSUFFIX _raw
27 4c9649a9 j_mayer
#include "op_helper_mem.h"
28 4c9649a9 j_mayer
29 4c9649a9 j_mayer
#if !defined(CONFIG_USER_ONLY)
30 4c9649a9 j_mayer
#define MEMSUFFIX _user
31 4c9649a9 j_mayer
#include "op_helper_mem.h"
32 4c9649a9 j_mayer
33 4c9649a9 j_mayer
#define MEMSUFFIX _kernel
34 4c9649a9 j_mayer
#include "op_helper_mem.h"
35 4c9649a9 j_mayer
36 4c9649a9 j_mayer
/* Those are used for supervisor and executive modes */
37 4c9649a9 j_mayer
#define MEMSUFFIX _data
38 4c9649a9 j_mayer
#include "op_helper_mem.h"
39 4c9649a9 j_mayer
#endif
40 4c9649a9 j_mayer
41 4c9649a9 j_mayer
void helper_tb_flush (void)
42 4c9649a9 j_mayer
{
43 4c9649a9 j_mayer
    tlb_flush(env, 1);
44 4c9649a9 j_mayer
}
45 4c9649a9 j_mayer
46 4c9649a9 j_mayer
void cpu_dump_EA (target_ulong EA);
47 4c9649a9 j_mayer
void helper_print_mem_EA (target_ulong EA)
48 4c9649a9 j_mayer
{
49 4c9649a9 j_mayer
    cpu_dump_EA(EA);
50 4c9649a9 j_mayer
}
51 4c9649a9 j_mayer
52 4c9649a9 j_mayer
/*****************************************************************************/
53 4c9649a9 j_mayer
/* Exceptions processing helpers */
54 4c9649a9 j_mayer
void helper_excp (uint32_t excp, uint32_t error)
55 4c9649a9 j_mayer
{
56 4c9649a9 j_mayer
    env->exception_index = excp;
57 4c9649a9 j_mayer
    env->error_code = error;
58 4c9649a9 j_mayer
    cpu_loop_exit();
59 4c9649a9 j_mayer
}
60 4c9649a9 j_mayer
61 4c9649a9 j_mayer
void helper_amask (void)
62 4c9649a9 j_mayer
{
63 4c9649a9 j_mayer
    switch (env->implver) {
64 4c9649a9 j_mayer
    case IMPLVER_2106x:
65 4c9649a9 j_mayer
        /* EV4, EV45, LCA, LCA45 & EV5 */
66 4c9649a9 j_mayer
        break;
67 4c9649a9 j_mayer
    case IMPLVER_21164:
68 4c9649a9 j_mayer
    case IMPLVER_21264:
69 4c9649a9 j_mayer
    case IMPLVER_21364:
70 4c9649a9 j_mayer
        T0 &= ~env->amask;
71 4c9649a9 j_mayer
        break;
72 4c9649a9 j_mayer
    }
73 4c9649a9 j_mayer
}
74 4c9649a9 j_mayer
75 4c9649a9 j_mayer
void helper_load_pcc (void)
76 4c9649a9 j_mayer
{
77 4c9649a9 j_mayer
    /* XXX: TODO */
78 4c9649a9 j_mayer
    T0 = 0;
79 4c9649a9 j_mayer
}
80 4c9649a9 j_mayer
81 4c9649a9 j_mayer
void helper_load_implver (void)
82 4c9649a9 j_mayer
{
83 4c9649a9 j_mayer
    T0 = env->implver;
84 4c9649a9 j_mayer
}
85 4c9649a9 j_mayer
86 4c9649a9 j_mayer
void helper_load_fpcr (void)
87 4c9649a9 j_mayer
{
88 4c9649a9 j_mayer
    T0 = 0;
89 4c9649a9 j_mayer
#ifdef CONFIG_SOFTFLOAT
90 4c9649a9 j_mayer
    T0 |= env->fp_status.float_exception_flags << 52;
91 4c9649a9 j_mayer
    if (env->fp_status.float_exception_flags)
92 4c9649a9 j_mayer
        T0 |= 1ULL << 63;
93 4c9649a9 j_mayer
    env->ipr[IPR_EXC_SUM] &= ~0x3E:
94 4c9649a9 j_mayer
    env->ipr[IPR_EXC_SUM] |= env->fp_status.float_exception_flags << 1;
95 4c9649a9 j_mayer
#endif
96 4c9649a9 j_mayer
    switch (env->fp_status.float_rounding_mode) {
97 4c9649a9 j_mayer
    case float_round_nearest_even:
98 4c9649a9 j_mayer
        T0 |= 2ULL << 58;
99 4c9649a9 j_mayer
        break;
100 4c9649a9 j_mayer
    case float_round_down:
101 4c9649a9 j_mayer
        T0 |= 1ULL << 58;
102 4c9649a9 j_mayer
        break;
103 4c9649a9 j_mayer
    case float_round_up:
104 4c9649a9 j_mayer
        T0 |= 3ULL << 58;
105 4c9649a9 j_mayer
        break;
106 4c9649a9 j_mayer
    case float_round_to_zero:
107 4c9649a9 j_mayer
        break;
108 4c9649a9 j_mayer
    }
109 4c9649a9 j_mayer
}
110 4c9649a9 j_mayer
111 4c9649a9 j_mayer
void helper_store_fpcr (void)
112 4c9649a9 j_mayer
{
113 4c9649a9 j_mayer
#ifdef CONFIG_SOFTFLOAT
114 4c9649a9 j_mayer
    set_float_exception_flags((T0 >> 52) & 0x3F, &FP_STATUS);
115 4c9649a9 j_mayer
#endif
116 4c9649a9 j_mayer
    switch ((T0 >> 58) & 3) {
117 4c9649a9 j_mayer
    case 0:
118 4c9649a9 j_mayer
        set_float_rounding_mode(float_round_to_zero, &FP_STATUS);
119 4c9649a9 j_mayer
        break;
120 4c9649a9 j_mayer
    case 1:
121 4c9649a9 j_mayer
        set_float_rounding_mode(float_round_down, &FP_STATUS);
122 4c9649a9 j_mayer
        break;
123 4c9649a9 j_mayer
    case 2:
124 4c9649a9 j_mayer
        set_float_rounding_mode(float_round_nearest_even, &FP_STATUS);
125 4c9649a9 j_mayer
        break;
126 4c9649a9 j_mayer
    case 3:
127 4c9649a9 j_mayer
        set_float_rounding_mode(float_round_up, &FP_STATUS);
128 4c9649a9 j_mayer
        break;
129 4c9649a9 j_mayer
    }
130 4c9649a9 j_mayer
}
131 4c9649a9 j_mayer
132 4c9649a9 j_mayer
void helper_load_irf (void)
133 4c9649a9 j_mayer
{
134 4c9649a9 j_mayer
    /* XXX: TODO */
135 4c9649a9 j_mayer
    T0 = 0;
136 4c9649a9 j_mayer
}
137 4c9649a9 j_mayer
138 4c9649a9 j_mayer
void helper_set_irf (void)
139 4c9649a9 j_mayer
{
140 4c9649a9 j_mayer
    /* XXX: TODO */
141 4c9649a9 j_mayer
}
142 4c9649a9 j_mayer
143 4c9649a9 j_mayer
void helper_clear_irf (void)
144 4c9649a9 j_mayer
{
145 4c9649a9 j_mayer
    /* XXX: TODO */
146 4c9649a9 j_mayer
}
147 4c9649a9 j_mayer
148 4c9649a9 j_mayer
void helper_addqv (void)
149 4c9649a9 j_mayer
{
150 4c9649a9 j_mayer
    T2 = T0;
151 4c9649a9 j_mayer
    T0 += T1;
152 4c9649a9 j_mayer
    if (unlikely((T2 ^ T1 ^ (-1ULL)) & (T2 ^ T0) & (1ULL << 63))) {
153 4c9649a9 j_mayer
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
154 4c9649a9 j_mayer
    }
155 4c9649a9 j_mayer
}
156 4c9649a9 j_mayer
157 4c9649a9 j_mayer
void helper_addlv (void)
158 4c9649a9 j_mayer
{
159 4c9649a9 j_mayer
    T2 = T0;
160 4c9649a9 j_mayer
    T0 = (uint32_t)(T0 + T1);
161 4c9649a9 j_mayer
    if (unlikely((T2 ^ T1 ^ (-1UL)) & (T2 ^ T0) & (1UL << 31))) {
162 4c9649a9 j_mayer
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
163 4c9649a9 j_mayer
    }
164 4c9649a9 j_mayer
}
165 4c9649a9 j_mayer
166 4c9649a9 j_mayer
void helper_subqv (void)
167 4c9649a9 j_mayer
{
168 4c9649a9 j_mayer
    T2 = T0;
169 4c9649a9 j_mayer
    T0 -= T1;
170 4c9649a9 j_mayer
    if (unlikely(((~T2) ^ T0 ^ (-1ULL)) & ((~T2) ^ T1) & (1ULL << 63))) {
171 4c9649a9 j_mayer
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
172 4c9649a9 j_mayer
    }
173 4c9649a9 j_mayer
}
174 4c9649a9 j_mayer
175 4c9649a9 j_mayer
void helper_sublv (void)
176 4c9649a9 j_mayer
{
177 4c9649a9 j_mayer
    T2 = T0;
178 4c9649a9 j_mayer
    T0 = (uint32_t)(T0 - T1);
179 4c9649a9 j_mayer
    if (unlikely(((~T2) ^ T0 ^ (-1UL)) & ((~T2) ^ T1) & (1UL << 31))) {
180 4c9649a9 j_mayer
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
181 4c9649a9 j_mayer
    }
182 4c9649a9 j_mayer
}
183 4c9649a9 j_mayer
184 4c9649a9 j_mayer
void helper_mullv (void)
185 4c9649a9 j_mayer
{
186 4c9649a9 j_mayer
    int64_t res = (int64_t)T0 * (int64_t)T1;
187 4c9649a9 j_mayer
188 4c9649a9 j_mayer
    if (unlikely((int32_t)res != res)) {
189 4c9649a9 j_mayer
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
190 4c9649a9 j_mayer
    }
191 4c9649a9 j_mayer
    T0 = (int64_t)((int32_t)res);
192 4c9649a9 j_mayer
}
193 4c9649a9 j_mayer
194 4c9649a9 j_mayer
void helper_mulqv ()
195 4c9649a9 j_mayer
{
196 4c9649a9 j_mayer
    uint64_t res, tmp0, tmp1;
197 4c9649a9 j_mayer
198 4c9649a9 j_mayer
    res = (T0 >> 32) * (T1 >> 32);
199 4c9649a9 j_mayer
    tmp0 = ((T0 & 0xFFFFFFFF) * (T1 >> 32)) +
200 4c9649a9 j_mayer
        ((T0 >> 32) * (T1 & 0xFFFFFFFF));
201 4c9649a9 j_mayer
    tmp1 = (T0 & 0xFFFFFFFF) * (T1 & 0xFFFFFFFF);
202 4c9649a9 j_mayer
    tmp0 += tmp1 >> 32;
203 4c9649a9 j_mayer
    res += tmp0 >> 32;
204 4c9649a9 j_mayer
    T0 *= T1;
205 4c9649a9 j_mayer
    if (unlikely(res != 0)) {
206 4c9649a9 j_mayer
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
207 4c9649a9 j_mayer
    }
208 4c9649a9 j_mayer
}
209 4c9649a9 j_mayer
210 4c9649a9 j_mayer
void helper_umulh (void)
211 4c9649a9 j_mayer
{
212 4c9649a9 j_mayer
    uint64_t tmp0, tmp1;
213 4c9649a9 j_mayer
214 4c9649a9 j_mayer
    tmp0 = ((T0 & 0xFFFFFFFF) * (T1 >> 32)) +
215 4c9649a9 j_mayer
        ((T0 >> 32) * (T1 & 0xFFFFFFFF));
216 4c9649a9 j_mayer
    tmp1 = (T0 & 0xFFFFFFFF) * (T1 & 0xFFFFFFFF);
217 4c9649a9 j_mayer
    tmp0 += tmp1 >> 32;
218 4c9649a9 j_mayer
    T0 = (T0 >> 32) * (T0 >> 32);
219 4c9649a9 j_mayer
    T0 += tmp0 >> 32;
220 4c9649a9 j_mayer
}
221 4c9649a9 j_mayer
222 4c9649a9 j_mayer
void helper_ctpop (void)
223 4c9649a9 j_mayer
{
224 4c9649a9 j_mayer
    int n;
225 4c9649a9 j_mayer
226 4c9649a9 j_mayer
    for (n = 0; T0 != 0; n++)
227 4c9649a9 j_mayer
        T0 = T0 ^ (T0 - 1);
228 4c9649a9 j_mayer
    T0 = n;
229 4c9649a9 j_mayer
}
230 4c9649a9 j_mayer
231 4c9649a9 j_mayer
void helper_ctlz (void)
232 4c9649a9 j_mayer
{
233 4c9649a9 j_mayer
    uint32_t op32;
234 4c9649a9 j_mayer
    int n;
235 4c9649a9 j_mayer
236 4c9649a9 j_mayer
    n = 0;
237 4c9649a9 j_mayer
    if (!(T0 & 0xFFFFFFFF00000000ULL)) {
238 4c9649a9 j_mayer
        n += 32;
239 4c9649a9 j_mayer
        T0 <<= 32;
240 4c9649a9 j_mayer
    }
241 4c9649a9 j_mayer
    /* Make it easier for 32 bits hosts */
242 4c9649a9 j_mayer
    op32 = T0 >> 32;
243 4c9649a9 j_mayer
    if (!(op32 & 0xFFFF0000UL)) {
244 4c9649a9 j_mayer
        n += 16;
245 4c9649a9 j_mayer
        op32 <<= 16;
246 4c9649a9 j_mayer
    }
247 4c9649a9 j_mayer
    if (!(op32 & 0xFF000000UL)) {
248 4c9649a9 j_mayer
        n += 8;
249 4c9649a9 j_mayer
        op32 <<= 8;
250 4c9649a9 j_mayer
    }
251 4c9649a9 j_mayer
    if (!(op32 & 0xF0000000UL)) {
252 4c9649a9 j_mayer
        n += 4;
253 4c9649a9 j_mayer
        op32 <<= 4;
254 4c9649a9 j_mayer
    }
255 4c9649a9 j_mayer
    if (!(op32 & 0xC0000000UL)) {
256 4c9649a9 j_mayer
        n += 2;
257 4c9649a9 j_mayer
        op32 <<= 2;
258 4c9649a9 j_mayer
    }
259 4c9649a9 j_mayer
    if (!(op32 & 0x80000000UL)) {
260 4c9649a9 j_mayer
        n++;
261 4c9649a9 j_mayer
        op32 <<= 1;
262 4c9649a9 j_mayer
    }
263 4c9649a9 j_mayer
    if (!(op32 & 0x80000000UL)) {
264 4c9649a9 j_mayer
        n++;
265 4c9649a9 j_mayer
    }
266 4c9649a9 j_mayer
    T0 = n;
267 4c9649a9 j_mayer
}
268 4c9649a9 j_mayer
269 4c9649a9 j_mayer
void helper_cttz (void)
270 4c9649a9 j_mayer
{
271 4c9649a9 j_mayer
    uint32_t op32;
272 4c9649a9 j_mayer
    int n;
273 4c9649a9 j_mayer
274 4c9649a9 j_mayer
    n = 0;
275 4c9649a9 j_mayer
    if (!(T0 & 0x00000000FFFFFFFFULL)) {
276 4c9649a9 j_mayer
        n += 32;
277 4c9649a9 j_mayer
        T0 >>= 32;
278 4c9649a9 j_mayer
    }
279 4c9649a9 j_mayer
    /* Make it easier for 32 bits hosts */
280 4c9649a9 j_mayer
    op32 = T0;
281 4c9649a9 j_mayer
    if (!(op32 & 0x0000FFFFUL)) {
282 4c9649a9 j_mayer
        n += 16;
283 4c9649a9 j_mayer
        op32 >>= 16;
284 4c9649a9 j_mayer
    }
285 4c9649a9 j_mayer
    if (!(op32 & 0x000000FFUL)) {
286 4c9649a9 j_mayer
        n += 8;
287 4c9649a9 j_mayer
        op32 >>= 8;
288 4c9649a9 j_mayer
    }
289 4c9649a9 j_mayer
    if (!(op32 & 0x0000000FUL)) {
290 4c9649a9 j_mayer
        n += 4;
291 4c9649a9 j_mayer
        op32 >>= 4;
292 4c9649a9 j_mayer
    }
293 4c9649a9 j_mayer
    if (!(op32 & 0x00000003UL)) {
294 4c9649a9 j_mayer
        n += 2;
295 4c9649a9 j_mayer
        op32 >>= 2;
296 4c9649a9 j_mayer
    }
297 4c9649a9 j_mayer
    if (!(op32 & 0x00000001UL)) {
298 4c9649a9 j_mayer
        n++;
299 4c9649a9 j_mayer
        op32 >>= 1;
300 4c9649a9 j_mayer
    }
301 4c9649a9 j_mayer
    if (!(op32 & 0x00000001UL)) {
302 4c9649a9 j_mayer
        n++;
303 4c9649a9 j_mayer
    }
304 4c9649a9 j_mayer
    T0 = n;
305 4c9649a9 j_mayer
}
306 4c9649a9 j_mayer
307 4c9649a9 j_mayer
static inline uint64_t byte_zap (uint64_t op, uint8_t mskb)
308 4c9649a9 j_mayer
{
309 4c9649a9 j_mayer
    uint64_t mask;
310 4c9649a9 j_mayer
311 4c9649a9 j_mayer
    mask = 0;
312 4c9649a9 j_mayer
    mask |= ((mskb >> 0) & 1) * 0x00000000000000FFULL;
313 4c9649a9 j_mayer
    mask |= ((mskb >> 1) & 1) * 0x000000000000FF00ULL;
314 4c9649a9 j_mayer
    mask |= ((mskb >> 2) & 1) * 0x0000000000FF0000ULL;
315 4c9649a9 j_mayer
    mask |= ((mskb >> 3) & 1) * 0x00000000FF000000ULL;
316 4c9649a9 j_mayer
    mask |= ((mskb >> 4) & 1) * 0x000000FF00000000ULL;
317 4c9649a9 j_mayer
    mask |= ((mskb >> 5) & 1) * 0x0000FF0000000000ULL;
318 4c9649a9 j_mayer
    mask |= ((mskb >> 6) & 1) * 0x00FF000000000000ULL;
319 4c9649a9 j_mayer
    mask |= ((mskb >> 7) & 1) * 0xFF00000000000000ULL;
320 4c9649a9 j_mayer
321 4c9649a9 j_mayer
    return op & ~mask;
322 4c9649a9 j_mayer
}
323 4c9649a9 j_mayer
324 4c9649a9 j_mayer
void helper_mskbl (void)
325 4c9649a9 j_mayer
{
326 4c9649a9 j_mayer
    T0 = byte_zap(T0, 0x01 << (T1 & 7));
327 4c9649a9 j_mayer
}
328 4c9649a9 j_mayer
329 4c9649a9 j_mayer
void helper_extbl (void)
330 4c9649a9 j_mayer
{
331 4c9649a9 j_mayer
    T0 >>= (T1 & 7) * 8;
332 4c9649a9 j_mayer
    T0 = byte_zap(T0, 0xFE);
333 4c9649a9 j_mayer
}
334 4c9649a9 j_mayer
335 4c9649a9 j_mayer
void helper_insbl (void)
336 4c9649a9 j_mayer
{
337 4c9649a9 j_mayer
    T0 <<= (T1 & 7) * 8;
338 4c9649a9 j_mayer
    T0 = byte_zap(T0, ~(0x01 << (T1 & 7)));
339 4c9649a9 j_mayer
}
340 4c9649a9 j_mayer
341 4c9649a9 j_mayer
void helper_mskwl (void)
342 4c9649a9 j_mayer
{
343 4c9649a9 j_mayer
    T0 = byte_zap(T0, 0x03 << (T1 & 7));
344 4c9649a9 j_mayer
}
345 4c9649a9 j_mayer
346 4c9649a9 j_mayer
void helper_extwl (void)
347 4c9649a9 j_mayer
{
348 4c9649a9 j_mayer
    T0 >>= (T1 & 7) * 8;
349 4c9649a9 j_mayer
    T0 = byte_zap(T0, 0xFC);
350 4c9649a9 j_mayer
}
351 4c9649a9 j_mayer
352 4c9649a9 j_mayer
void helper_inswl (void)
353 4c9649a9 j_mayer
{
354 4c9649a9 j_mayer
    T0 <<= (T1 & 7) * 8;
355 4c9649a9 j_mayer
    T0 = byte_zap(T0, ~(0x03 << (T1 & 7)));
356 4c9649a9 j_mayer
}
357 4c9649a9 j_mayer
358 4c9649a9 j_mayer
void helper_mskll (void)
359 4c9649a9 j_mayer
{
360 4c9649a9 j_mayer
    T0 = byte_zap(T0, 0x0F << (T1 & 7));
361 4c9649a9 j_mayer
}
362 4c9649a9 j_mayer
363 4c9649a9 j_mayer
void helper_extll (void)
364 4c9649a9 j_mayer
{
365 4c9649a9 j_mayer
    T0 >>= (T1 & 7) * 8;
366 4c9649a9 j_mayer
    T0 = byte_zap(T0, 0xF0);
367 4c9649a9 j_mayer
}
368 4c9649a9 j_mayer
369 4c9649a9 j_mayer
void helper_insll (void)
370 4c9649a9 j_mayer
{
371 4c9649a9 j_mayer
    T0 <<= (T1 & 7) * 8;
372 4c9649a9 j_mayer
    T0 = byte_zap(T0, ~(0x0F << (T1 & 7)));
373 4c9649a9 j_mayer
}
374 4c9649a9 j_mayer
375 4c9649a9 j_mayer
void helper_zap (void)
376 4c9649a9 j_mayer
{
377 4c9649a9 j_mayer
    T0 = byte_zap(T0, T1);
378 4c9649a9 j_mayer
}
379 4c9649a9 j_mayer
380 4c9649a9 j_mayer
void helper_zapnot (void)
381 4c9649a9 j_mayer
{
382 4c9649a9 j_mayer
    T0 = byte_zap(T0, ~T1);
383 4c9649a9 j_mayer
}
384 4c9649a9 j_mayer
385 4c9649a9 j_mayer
void helper_mskql (void)
386 4c9649a9 j_mayer
{
387 4c9649a9 j_mayer
    T0 = byte_zap(T0, 0xFF << (T1 & 7));
388 4c9649a9 j_mayer
}
389 4c9649a9 j_mayer
390 4c9649a9 j_mayer
void helper_extql (void)
391 4c9649a9 j_mayer
{
392 4c9649a9 j_mayer
    T0 >>= (T1 & 7) * 8;
393 4c9649a9 j_mayer
    T0 = byte_zap(T0, 0x00);
394 4c9649a9 j_mayer
}
395 4c9649a9 j_mayer
396 4c9649a9 j_mayer
void helper_insql (void)
397 4c9649a9 j_mayer
{
398 4c9649a9 j_mayer
    T0 <<= (T1 & 7) * 8;
399 4c9649a9 j_mayer
    T0 = byte_zap(T0, ~(0xFF << (T1 & 7)));
400 4c9649a9 j_mayer
}
401 4c9649a9 j_mayer
402 4c9649a9 j_mayer
void helper_mskwh (void)
403 4c9649a9 j_mayer
{
404 4c9649a9 j_mayer
    T0 = byte_zap(T0, (0x03 << (T1 & 7)) >> 8);
405 4c9649a9 j_mayer
}
406 4c9649a9 j_mayer
407 4c9649a9 j_mayer
void helper_inswh (void)
408 4c9649a9 j_mayer
{
409 4c9649a9 j_mayer
    T0 >>= 64 - ((T1 & 7) * 8);
410 4c9649a9 j_mayer
    T0 = byte_zap(T0, ~((0x03 << (T1 & 7)) >> 8));
411 4c9649a9 j_mayer
}
412 4c9649a9 j_mayer
413 4c9649a9 j_mayer
void helper_extwh (void)
414 4c9649a9 j_mayer
{
415 4c9649a9 j_mayer
    T0 <<= 64 - ((T1 & 7) * 8);
416 4c9649a9 j_mayer
    T0 = byte_zap(T0, ~0x07);
417 4c9649a9 j_mayer
}
418 4c9649a9 j_mayer
419 4c9649a9 j_mayer
void helper_msklh (void)
420 4c9649a9 j_mayer
{
421 4c9649a9 j_mayer
    T0 = byte_zap(T0, (0x0F << (T1 & 7)) >> 8);
422 4c9649a9 j_mayer
}
423 4c9649a9 j_mayer
424 4c9649a9 j_mayer
void helper_inslh (void)
425 4c9649a9 j_mayer
{
426 4c9649a9 j_mayer
    T0 >>= 64 - ((T1 & 7) * 8);
427 4c9649a9 j_mayer
    T0 = byte_zap(T0, ~((0x0F << (T1 & 7)) >> 8));
428 4c9649a9 j_mayer
}
429 4c9649a9 j_mayer
430 4c9649a9 j_mayer
void helper_extlh (void)
431 4c9649a9 j_mayer
{
432 4c9649a9 j_mayer
    T0 <<= 64 - ((T1 & 7) * 8);
433 4c9649a9 j_mayer
    T0 = byte_zap(T0, ~0x0F);
434 4c9649a9 j_mayer
}
435 4c9649a9 j_mayer
436 4c9649a9 j_mayer
void helper_mskqh (void)
437 4c9649a9 j_mayer
{
438 4c9649a9 j_mayer
    T0 = byte_zap(T0, (0xFF << (T1 & 7)) >> 8);
439 4c9649a9 j_mayer
}
440 4c9649a9 j_mayer
441 4c9649a9 j_mayer
void helper_insqh (void)
442 4c9649a9 j_mayer
{
443 4c9649a9 j_mayer
    T0 >>= 64 - ((T1 & 7) * 8);
444 4c9649a9 j_mayer
    T0 = byte_zap(T0, ~((0xFF << (T1 & 7)) >> 8));
445 4c9649a9 j_mayer
}
446 4c9649a9 j_mayer
447 4c9649a9 j_mayer
void helper_extqh (void)
448 4c9649a9 j_mayer
{
449 4c9649a9 j_mayer
    T0 <<= 64 - ((T1 & 7) * 8);
450 4c9649a9 j_mayer
    T0 = byte_zap(T0, 0x00);
451 4c9649a9 j_mayer
}
452 4c9649a9 j_mayer
453 4c9649a9 j_mayer
void helper_cmpbge (void)
454 4c9649a9 j_mayer
{
455 4c9649a9 j_mayer
    uint8_t opa, opb, res;
456 4c9649a9 j_mayer
    int i;
457 4c9649a9 j_mayer
458 4c9649a9 j_mayer
    res = 0;
459 4c9649a9 j_mayer
    for (i = 0; i < 7; i++) {
460 4c9649a9 j_mayer
        opa = T0 >> (i * 8);
461 4c9649a9 j_mayer
        opb = T1 >> (i * 8);
462 4c9649a9 j_mayer
        if (opa >= opb)
463 4c9649a9 j_mayer
            res |= 1 << i;
464 4c9649a9 j_mayer
    }
465 4c9649a9 j_mayer
    T0 = res;
466 4c9649a9 j_mayer
}
467 4c9649a9 j_mayer
468 4c9649a9 j_mayer
void helper_cmov_fir (int freg)
469 4c9649a9 j_mayer
{
470 4c9649a9 j_mayer
    if (FT0 != 0)
471 4c9649a9 j_mayer
        env->fir[freg] = FT1;
472 4c9649a9 j_mayer
}
473 4c9649a9 j_mayer
474 4c9649a9 j_mayer
void helper_sqrts (void)
475 4c9649a9 j_mayer
{
476 4c9649a9 j_mayer
    FT0 = float32_sqrt(FT0, &FP_STATUS);
477 4c9649a9 j_mayer
}
478 4c9649a9 j_mayer
479 4c9649a9 j_mayer
void helper_cpys (void)
480 4c9649a9 j_mayer
{
481 4c9649a9 j_mayer
    union {
482 4c9649a9 j_mayer
        double d;
483 4c9649a9 j_mayer
        uint64_t i;
484 4c9649a9 j_mayer
    } p, q, r;
485 4c9649a9 j_mayer
486 4c9649a9 j_mayer
    p.d = FT0;
487 4c9649a9 j_mayer
    q.d = FT1;
488 4c9649a9 j_mayer
    r.i = p.i & 0x8000000000000000ULL;
489 4c9649a9 j_mayer
    r.i |= q.i & ~0x8000000000000000ULL;
490 4c9649a9 j_mayer
    FT0 = r.d;
491 4c9649a9 j_mayer
}
492 4c9649a9 j_mayer
493 4c9649a9 j_mayer
void helper_cpysn (void)
494 4c9649a9 j_mayer
{
495 4c9649a9 j_mayer
    union {
496 4c9649a9 j_mayer
        double d;
497 4c9649a9 j_mayer
        uint64_t i;
498 4c9649a9 j_mayer
    } p, q, r;
499 4c9649a9 j_mayer
500 4c9649a9 j_mayer
    p.d = FT0;
501 4c9649a9 j_mayer
    q.d = FT1;
502 4c9649a9 j_mayer
    r.i = (~p.i) & 0x8000000000000000ULL;
503 4c9649a9 j_mayer
    r.i |= q.i & ~0x8000000000000000ULL;
504 4c9649a9 j_mayer
    FT0 = r.d;
505 4c9649a9 j_mayer
}
506 4c9649a9 j_mayer
507 4c9649a9 j_mayer
void helper_cpyse (void)
508 4c9649a9 j_mayer
{
509 4c9649a9 j_mayer
    union {
510 4c9649a9 j_mayer
        double d;
511 4c9649a9 j_mayer
        uint64_t i;
512 4c9649a9 j_mayer
    } p, q, r;
513 4c9649a9 j_mayer
514 4c9649a9 j_mayer
    p.d = FT0;
515 4c9649a9 j_mayer
    q.d = FT1;
516 4c9649a9 j_mayer
    r.i = p.i & 0xFFF0000000000000ULL;
517 4c9649a9 j_mayer
    r.i |= q.i & ~0xFFF0000000000000ULL;
518 4c9649a9 j_mayer
    FT0 = r.d;
519 4c9649a9 j_mayer
}
520 4c9649a9 j_mayer
521 4c9649a9 j_mayer
void helper_itofs (void)
522 4c9649a9 j_mayer
{
523 4c9649a9 j_mayer
    union {
524 4c9649a9 j_mayer
        double d;
525 4c9649a9 j_mayer
        uint64_t i;
526 4c9649a9 j_mayer
    } p;
527 4c9649a9 j_mayer
528 4c9649a9 j_mayer
    p.d = FT0;
529 4c9649a9 j_mayer
    FT0 = int64_to_float32(p.i, &FP_STATUS);
530 4c9649a9 j_mayer
}
531 4c9649a9 j_mayer
532 4c9649a9 j_mayer
void helper_ftois (void)
533 4c9649a9 j_mayer
{
534 4c9649a9 j_mayer
    union {
535 4c9649a9 j_mayer
        double d;
536 4c9649a9 j_mayer
        uint64_t i;
537 4c9649a9 j_mayer
    } p;
538 4c9649a9 j_mayer
539 4c9649a9 j_mayer
    p.i = float32_to_int64(FT0, &FP_STATUS);
540 4c9649a9 j_mayer
    FT0 = p.d;
541 4c9649a9 j_mayer
}
542 4c9649a9 j_mayer
543 4c9649a9 j_mayer
void helper_sqrtt (void)
544 4c9649a9 j_mayer
{
545 4c9649a9 j_mayer
    FT0 = float64_sqrt(FT0, &FP_STATUS);
546 4c9649a9 j_mayer
}
547 4c9649a9 j_mayer
548 4c9649a9 j_mayer
void helper_cmptun (void)
549 4c9649a9 j_mayer
{
550 4c9649a9 j_mayer
    union {
551 4c9649a9 j_mayer
        double d;
552 4c9649a9 j_mayer
        uint64_t i;
553 4c9649a9 j_mayer
    } p;
554 4c9649a9 j_mayer
555 4c9649a9 j_mayer
    p.i = 0;
556 4c9649a9 j_mayer
    if (float64_is_nan(FT0) || float64_is_nan(FT1))
557 4c9649a9 j_mayer
        p.i = 0x4000000000000000ULL;
558 4c9649a9 j_mayer
    FT0 = p.d;
559 4c9649a9 j_mayer
}
560 4c9649a9 j_mayer
561 4c9649a9 j_mayer
void helper_cmpteq (void)
562 4c9649a9 j_mayer
{
563 4c9649a9 j_mayer
    union {
564 4c9649a9 j_mayer
        double d;
565 4c9649a9 j_mayer
        uint64_t i;
566 4c9649a9 j_mayer
    } p;
567 4c9649a9 j_mayer
568 4c9649a9 j_mayer
    p.i = 0;
569 4c9649a9 j_mayer
    if (float64_eq(FT0, FT1, &FP_STATUS))
570 4c9649a9 j_mayer
        p.i = 0x4000000000000000ULL;
571 4c9649a9 j_mayer
    FT0 = p.d;
572 4c9649a9 j_mayer
}
573 4c9649a9 j_mayer
574 4c9649a9 j_mayer
void helper_cmptle (void)
575 4c9649a9 j_mayer
{
576 4c9649a9 j_mayer
    union {
577 4c9649a9 j_mayer
        double d;
578 4c9649a9 j_mayer
        uint64_t i;
579 4c9649a9 j_mayer
    } p;
580 4c9649a9 j_mayer
581 4c9649a9 j_mayer
    p.i = 0;
582 4c9649a9 j_mayer
    if (float64_le(FT0, FT1, &FP_STATUS))
583 4c9649a9 j_mayer
        p.i = 0x4000000000000000ULL;
584 4c9649a9 j_mayer
    FT0 = p.d;
585 4c9649a9 j_mayer
}
586 4c9649a9 j_mayer
587 4c9649a9 j_mayer
void helper_cmptlt (void)
588 4c9649a9 j_mayer
{
589 4c9649a9 j_mayer
    union {
590 4c9649a9 j_mayer
        double d;
591 4c9649a9 j_mayer
        uint64_t i;
592 4c9649a9 j_mayer
    } p;
593 4c9649a9 j_mayer
594 4c9649a9 j_mayer
    p.i = 0;
595 4c9649a9 j_mayer
    if (float64_lt(FT0, FT1, &FP_STATUS))
596 4c9649a9 j_mayer
        p.i = 0x4000000000000000ULL;
597 4c9649a9 j_mayer
    FT0 = p.d;
598 4c9649a9 j_mayer
}
599 4c9649a9 j_mayer
600 4c9649a9 j_mayer
void helper_itoft (void)
601 4c9649a9 j_mayer
{
602 4c9649a9 j_mayer
    union {
603 4c9649a9 j_mayer
        double d;
604 4c9649a9 j_mayer
        uint64_t i;
605 4c9649a9 j_mayer
    } p;
606 4c9649a9 j_mayer
607 4c9649a9 j_mayer
    p.d = FT0;
608 4c9649a9 j_mayer
    FT0 = int64_to_float64(p.i, &FP_STATUS);
609 4c9649a9 j_mayer
}
610 4c9649a9 j_mayer
611 4c9649a9 j_mayer
void helper_ftoit (void)
612 4c9649a9 j_mayer
{
613 4c9649a9 j_mayer
    union {
614 4c9649a9 j_mayer
        double d;
615 4c9649a9 j_mayer
        uint64_t i;
616 4c9649a9 j_mayer
    } p;
617 4c9649a9 j_mayer
618 4c9649a9 j_mayer
    p.i = float64_to_int64(FT0, &FP_STATUS);
619 4c9649a9 j_mayer
    FT0 = p.d;
620 4c9649a9 j_mayer
}
621 4c9649a9 j_mayer
622 4c9649a9 j_mayer
static int vaxf_is_valid (float ff)
623 4c9649a9 j_mayer
{
624 4c9649a9 j_mayer
    union {
625 4c9649a9 j_mayer
        float f;
626 4c9649a9 j_mayer
        uint32_t i;
627 4c9649a9 j_mayer
    } p;
628 4c9649a9 j_mayer
    uint32_t exp, mant;
629 4c9649a9 j_mayer
630 4c9649a9 j_mayer
    p.f = ff;
631 4c9649a9 j_mayer
    exp = (p.i >> 23) & 0xFF;
632 4c9649a9 j_mayer
    mant = p.i & 0x007FFFFF;
633 4c9649a9 j_mayer
    if (exp == 0 && ((p.i & 0x80000000) || mant != 0)) {
634 4c9649a9 j_mayer
        /* Reserved operands / Dirty zero */
635 4c9649a9 j_mayer
        return 0;
636 4c9649a9 j_mayer
    }
637 4c9649a9 j_mayer
638 4c9649a9 j_mayer
    return 1;
639 4c9649a9 j_mayer
}
640 4c9649a9 j_mayer
641 4c9649a9 j_mayer
static float vaxf_to_ieee32 (float ff)
642 4c9649a9 j_mayer
{
643 4c9649a9 j_mayer
    union {
644 4c9649a9 j_mayer
        float f;
645 4c9649a9 j_mayer
        uint32_t i;
646 4c9649a9 j_mayer
    } p;
647 4c9649a9 j_mayer
    uint32_t exp;
648 4c9649a9 j_mayer
649 4c9649a9 j_mayer
    p.f = ff;
650 4c9649a9 j_mayer
    exp = (p.i >> 23) & 0xFF;
651 4c9649a9 j_mayer
    if (exp < 3) {
652 4c9649a9 j_mayer
        /* Underflow */
653 4c9649a9 j_mayer
        p.f = 0.0;
654 4c9649a9 j_mayer
    } else {
655 4c9649a9 j_mayer
        p.f *= 0.25;
656 4c9649a9 j_mayer
    }
657 4c9649a9 j_mayer
658 4c9649a9 j_mayer
    return p.f;
659 4c9649a9 j_mayer
}
660 4c9649a9 j_mayer
661 4c9649a9 j_mayer
static float ieee32_to_vaxf (float fi)
662 4c9649a9 j_mayer
{
663 4c9649a9 j_mayer
    union {
664 4c9649a9 j_mayer
        float f;
665 4c9649a9 j_mayer
        uint32_t i;
666 4c9649a9 j_mayer
    } p;
667 4c9649a9 j_mayer
    uint32_t exp, mant;
668 4c9649a9 j_mayer
669 4c9649a9 j_mayer
    p.f = fi;
670 4c9649a9 j_mayer
    exp = (p.i >> 23) & 0xFF;
671 4c9649a9 j_mayer
    mant = p.i & 0x007FFFFF;
672 4c9649a9 j_mayer
    if (exp == 255) {
673 4c9649a9 j_mayer
        /* NaN or infinity */
674 4c9649a9 j_mayer
        p.i = 1;
675 4c9649a9 j_mayer
    } else if (exp == 0) {
676 4c9649a9 j_mayer
        if (mant == 0) {
677 4c9649a9 j_mayer
            /* Zero */
678 4c9649a9 j_mayer
            p.i = 0;
679 4c9649a9 j_mayer
        } else {
680 4c9649a9 j_mayer
            /* Denormalized */
681 4c9649a9 j_mayer
            p.f *= 2.0;
682 4c9649a9 j_mayer
        }
683 4c9649a9 j_mayer
    } else {
684 4c9649a9 j_mayer
        if (exp >= 253) {
685 4c9649a9 j_mayer
            /* Overflow */
686 4c9649a9 j_mayer
            p.i = 1;
687 4c9649a9 j_mayer
        } else {
688 4c9649a9 j_mayer
            p.f *= 4.0;
689 4c9649a9 j_mayer
        }
690 4c9649a9 j_mayer
    }
691 4c9649a9 j_mayer
692 4c9649a9 j_mayer
    return p.f;
693 4c9649a9 j_mayer
}
694 4c9649a9 j_mayer
695 4c9649a9 j_mayer
void helper_addf (void)
696 4c9649a9 j_mayer
{
697 4c9649a9 j_mayer
    float ft0, ft1, ft2;
698 4c9649a9 j_mayer
699 4c9649a9 j_mayer
    if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
700 4c9649a9 j_mayer
        /* XXX: TODO */
701 4c9649a9 j_mayer
    }
702 4c9649a9 j_mayer
    ft0 = vaxf_to_ieee32(FT0);
703 4c9649a9 j_mayer
    ft1 = vaxf_to_ieee32(FT1);
704 4c9649a9 j_mayer
    ft2 = float32_add(ft0, ft1, &FP_STATUS);
705 4c9649a9 j_mayer
    FT0 = ieee32_to_vaxf(ft2);
706 4c9649a9 j_mayer
}
707 4c9649a9 j_mayer
708 4c9649a9 j_mayer
void helper_subf (void)
709 4c9649a9 j_mayer
{
710 4c9649a9 j_mayer
    float ft0, ft1, ft2;
711 4c9649a9 j_mayer
712 4c9649a9 j_mayer
    if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
713 4c9649a9 j_mayer
        /* XXX: TODO */
714 4c9649a9 j_mayer
    }
715 4c9649a9 j_mayer
    ft0 = vaxf_to_ieee32(FT0);
716 4c9649a9 j_mayer
    ft1 = vaxf_to_ieee32(FT1);
717 4c9649a9 j_mayer
    ft2 = float32_sub(ft0, ft1, &FP_STATUS);
718 4c9649a9 j_mayer
    FT0 = ieee32_to_vaxf(ft2);
719 4c9649a9 j_mayer
}
720 4c9649a9 j_mayer
721 4c9649a9 j_mayer
void helper_mulf (void)
722 4c9649a9 j_mayer
{
723 4c9649a9 j_mayer
    float ft0, ft1, ft2;
724 4c9649a9 j_mayer
725 4c9649a9 j_mayer
    if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
726 4c9649a9 j_mayer
        /* XXX: TODO */
727 4c9649a9 j_mayer
    }
728 4c9649a9 j_mayer
    ft0 = vaxf_to_ieee32(FT0);
729 4c9649a9 j_mayer
    ft1 = vaxf_to_ieee32(FT1);
730 4c9649a9 j_mayer
    ft2 = float32_mul(ft0, ft1, &FP_STATUS);
731 4c9649a9 j_mayer
    FT0 = ieee32_to_vaxf(ft2);
732 4c9649a9 j_mayer
}
733 4c9649a9 j_mayer
734 4c9649a9 j_mayer
void helper_divf (void)
735 4c9649a9 j_mayer
{
736 4c9649a9 j_mayer
    float ft0, ft1, ft2;
737 4c9649a9 j_mayer
738 4c9649a9 j_mayer
    if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
739 4c9649a9 j_mayer
        /* XXX: TODO */
740 4c9649a9 j_mayer
    }
741 4c9649a9 j_mayer
    ft0 = vaxf_to_ieee32(FT0);
742 4c9649a9 j_mayer
    ft1 = vaxf_to_ieee32(FT1);
743 4c9649a9 j_mayer
    ft2 = float32_div(ft0, ft1, &FP_STATUS);
744 4c9649a9 j_mayer
    FT0 = ieee32_to_vaxf(ft2);
745 4c9649a9 j_mayer
}
746 4c9649a9 j_mayer
747 4c9649a9 j_mayer
void helper_sqrtf (void)
748 4c9649a9 j_mayer
{
749 4c9649a9 j_mayer
    float ft0, ft1;
750 4c9649a9 j_mayer
751 4c9649a9 j_mayer
    if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
752 4c9649a9 j_mayer
        /* XXX: TODO */
753 4c9649a9 j_mayer
    }
754 4c9649a9 j_mayer
    ft0 = vaxf_to_ieee32(FT0);
755 4c9649a9 j_mayer
    ft1 = float32_sqrt(ft0, &FP_STATUS);
756 4c9649a9 j_mayer
    FT0 = ieee32_to_vaxf(ft1);
757 4c9649a9 j_mayer
}
758 4c9649a9 j_mayer
759 4c9649a9 j_mayer
void helper_itoff (void)
760 4c9649a9 j_mayer
{
761 4c9649a9 j_mayer
    /* XXX: TODO */
762 4c9649a9 j_mayer
}
763 4c9649a9 j_mayer
764 4c9649a9 j_mayer
static int vaxg_is_valid (double ff)
765 4c9649a9 j_mayer
{
766 4c9649a9 j_mayer
    union {
767 4c9649a9 j_mayer
        double f;
768 4c9649a9 j_mayer
        uint64_t i;
769 4c9649a9 j_mayer
    } p;
770 4c9649a9 j_mayer
    uint64_t exp, mant;
771 4c9649a9 j_mayer
772 4c9649a9 j_mayer
    p.f = ff;
773 4c9649a9 j_mayer
    exp = (p.i >> 52) & 0x7FF;
774 4c9649a9 j_mayer
    mant = p.i & 0x000FFFFFFFFFFFFFULL;
775 4c9649a9 j_mayer
    if (exp == 0 && ((p.i & 0x8000000000000000ULL) || mant != 0)) {
776 4c9649a9 j_mayer
        /* Reserved operands / Dirty zero */
777 4c9649a9 j_mayer
        return 0;
778 4c9649a9 j_mayer
    }
779 4c9649a9 j_mayer
780 4c9649a9 j_mayer
    return 1;
781 4c9649a9 j_mayer
}
782 4c9649a9 j_mayer
783 4c9649a9 j_mayer
static double vaxg_to_ieee64 (double fg)
784 4c9649a9 j_mayer
{
785 4c9649a9 j_mayer
    union {
786 4c9649a9 j_mayer
        double f;
787 4c9649a9 j_mayer
        uint64_t i;
788 4c9649a9 j_mayer
    } p;
789 4c9649a9 j_mayer
    uint32_t exp;
790 4c9649a9 j_mayer
791 4c9649a9 j_mayer
    p.f = fg;
792 4c9649a9 j_mayer
    exp = (p.i >> 52) & 0x7FF;
793 4c9649a9 j_mayer
    if (exp < 3) {
794 4c9649a9 j_mayer
        /* Underflow */
795 4c9649a9 j_mayer
        p.f = 0.0;
796 4c9649a9 j_mayer
    } else {
797 4c9649a9 j_mayer
        p.f *= 0.25;
798 4c9649a9 j_mayer
    }
799 4c9649a9 j_mayer
800 4c9649a9 j_mayer
    return p.f;
801 4c9649a9 j_mayer
}
802 4c9649a9 j_mayer
803 4c9649a9 j_mayer
static double ieee64_to_vaxg (double fi)
804 4c9649a9 j_mayer
{
805 4c9649a9 j_mayer
    union {
806 4c9649a9 j_mayer
        double f;
807 4c9649a9 j_mayer
        uint64_t i;
808 4c9649a9 j_mayer
    } p;
809 4c9649a9 j_mayer
    uint64_t mant;
810 4c9649a9 j_mayer
    uint32_t exp;
811 4c9649a9 j_mayer
812 4c9649a9 j_mayer
    p.f = fi;
813 4c9649a9 j_mayer
    exp = (p.i >> 52) & 0x7FF;
814 4c9649a9 j_mayer
    mant = p.i & 0x000FFFFFFFFFFFFFULL;
815 4c9649a9 j_mayer
    if (exp == 255) {
816 4c9649a9 j_mayer
        /* NaN or infinity */
817 4c9649a9 j_mayer
        p.i = 1; /* VAX dirty zero */
818 4c9649a9 j_mayer
    } else if (exp == 0) {
819 4c9649a9 j_mayer
        if (mant == 0) {
820 4c9649a9 j_mayer
            /* Zero */
821 4c9649a9 j_mayer
            p.i = 0;
822 4c9649a9 j_mayer
        } else {
823 4c9649a9 j_mayer
            /* Denormalized */
824 4c9649a9 j_mayer
            p.f *= 2.0;
825 4c9649a9 j_mayer
        }
826 4c9649a9 j_mayer
    } else {
827 4c9649a9 j_mayer
        if (exp >= 2045) {
828 4c9649a9 j_mayer
            /* Overflow */
829 4c9649a9 j_mayer
            p.i = 1; /* VAX dirty zero */
830 4c9649a9 j_mayer
        } else {
831 4c9649a9 j_mayer
            p.f *= 4.0;
832 4c9649a9 j_mayer
        }
833 4c9649a9 j_mayer
    }
834 4c9649a9 j_mayer
835 4c9649a9 j_mayer
    return p.f;
836 4c9649a9 j_mayer
}
837 4c9649a9 j_mayer
838 4c9649a9 j_mayer
void helper_addg (void)
839 4c9649a9 j_mayer
{
840 4c9649a9 j_mayer
    double ft0, ft1, ft2;
841 4c9649a9 j_mayer
842 4c9649a9 j_mayer
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
843 4c9649a9 j_mayer
        /* XXX: TODO */
844 4c9649a9 j_mayer
    }
845 4c9649a9 j_mayer
    ft0 = vaxg_to_ieee64(FT0);
846 4c9649a9 j_mayer
    ft1 = vaxg_to_ieee64(FT1);
847 4c9649a9 j_mayer
    ft2 = float64_add(ft0, ft1, &FP_STATUS);
848 4c9649a9 j_mayer
    FT0 = ieee64_to_vaxg(ft2);
849 4c9649a9 j_mayer
}
850 4c9649a9 j_mayer
851 4c9649a9 j_mayer
void helper_subg (void)
852 4c9649a9 j_mayer
{
853 4c9649a9 j_mayer
    double ft0, ft1, ft2;
854 4c9649a9 j_mayer
855 4c9649a9 j_mayer
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
856 4c9649a9 j_mayer
        /* XXX: TODO */
857 4c9649a9 j_mayer
    }
858 4c9649a9 j_mayer
    ft0 = vaxg_to_ieee64(FT0);
859 4c9649a9 j_mayer
    ft1 = vaxg_to_ieee64(FT1);
860 4c9649a9 j_mayer
    ft2 = float64_sub(ft0, ft1, &FP_STATUS);
861 4c9649a9 j_mayer
    FT0 = ieee64_to_vaxg(ft2);
862 4c9649a9 j_mayer
}
863 4c9649a9 j_mayer
864 4c9649a9 j_mayer
void helper_mulg (void)
865 4c9649a9 j_mayer
{
866 4c9649a9 j_mayer
    double ft0, ft1, ft2;
867 4c9649a9 j_mayer
868 4c9649a9 j_mayer
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
869 4c9649a9 j_mayer
        /* XXX: TODO */
870 4c9649a9 j_mayer
    }
871 4c9649a9 j_mayer
    ft0 = vaxg_to_ieee64(FT0);
872 4c9649a9 j_mayer
    ft1 = vaxg_to_ieee64(FT1);
873 4c9649a9 j_mayer
    ft2 = float64_mul(ft0, ft1, &FP_STATUS);
874 4c9649a9 j_mayer
    FT0 = ieee64_to_vaxg(ft2);
875 4c9649a9 j_mayer
}
876 4c9649a9 j_mayer
877 4c9649a9 j_mayer
void helper_divg (void)
878 4c9649a9 j_mayer
{
879 4c9649a9 j_mayer
    double ft0, ft1, ft2;
880 4c9649a9 j_mayer
881 4c9649a9 j_mayer
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
882 4c9649a9 j_mayer
        /* XXX: TODO */
883 4c9649a9 j_mayer
    }
884 4c9649a9 j_mayer
    ft0 = vaxg_to_ieee64(FT0);
885 4c9649a9 j_mayer
    ft1 = vaxg_to_ieee64(FT1);
886 4c9649a9 j_mayer
    ft2 = float64_div(ft0, ft1, &FP_STATUS);
887 4c9649a9 j_mayer
    FT0 = ieee64_to_vaxg(ft2);
888 4c9649a9 j_mayer
}
889 4c9649a9 j_mayer
890 4c9649a9 j_mayer
void helper_sqrtg (void)
891 4c9649a9 j_mayer
{
892 4c9649a9 j_mayer
    double ft0, ft1;
893 4c9649a9 j_mayer
894 4c9649a9 j_mayer
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
895 4c9649a9 j_mayer
        /* XXX: TODO */
896 4c9649a9 j_mayer
    }
897 4c9649a9 j_mayer
    ft0 = vaxg_to_ieee64(FT0);
898 4c9649a9 j_mayer
    ft1 = float64_sqrt(ft0, &FP_STATUS);
899 4c9649a9 j_mayer
    FT0 = ieee64_to_vaxg(ft1);
900 4c9649a9 j_mayer
}
901 4c9649a9 j_mayer
902 4c9649a9 j_mayer
void helper_cmpgeq (void)
903 4c9649a9 j_mayer
{
904 4c9649a9 j_mayer
    union {
905 4c9649a9 j_mayer
        double d;
906 4c9649a9 j_mayer
        uint64_t u;
907 4c9649a9 j_mayer
    } p;
908 4c9649a9 j_mayer
    double ft0, ft1;
909 4c9649a9 j_mayer
910 4c9649a9 j_mayer
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
911 4c9649a9 j_mayer
        /* XXX: TODO */
912 4c9649a9 j_mayer
    }
913 4c9649a9 j_mayer
    ft0 = vaxg_to_ieee64(FT0);
914 4c9649a9 j_mayer
    ft1 = vaxg_to_ieee64(FT1);
915 4c9649a9 j_mayer
    p.u = 0;
916 4c9649a9 j_mayer
    if (float64_eq(ft0, ft1, &FP_STATUS))
917 4c9649a9 j_mayer
        p.u = 0x4000000000000000ULL;
918 4c9649a9 j_mayer
    FT0 = p.d;
919 4c9649a9 j_mayer
}
920 4c9649a9 j_mayer
921 4c9649a9 j_mayer
void helper_cmpglt (void)
922 4c9649a9 j_mayer
{
923 4c9649a9 j_mayer
    union {
924 4c9649a9 j_mayer
        double d;
925 4c9649a9 j_mayer
        uint64_t u;
926 4c9649a9 j_mayer
    } p;
927 4c9649a9 j_mayer
    double ft0, ft1;
928 4c9649a9 j_mayer
929 4c9649a9 j_mayer
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
930 4c9649a9 j_mayer
        /* XXX: TODO */
931 4c9649a9 j_mayer
    }
932 4c9649a9 j_mayer
    ft0 = vaxg_to_ieee64(FT0);
933 4c9649a9 j_mayer
    ft1 = vaxg_to_ieee64(FT1);
934 4c9649a9 j_mayer
    p.u = 0;
935 4c9649a9 j_mayer
    if (float64_lt(ft0, ft1, &FP_STATUS))
936 4c9649a9 j_mayer
        p.u = 0x4000000000000000ULL;
937 4c9649a9 j_mayer
    FT0 = p.d;
938 4c9649a9 j_mayer
}
939 4c9649a9 j_mayer
940 4c9649a9 j_mayer
void helper_cmpgle (void)
941 4c9649a9 j_mayer
{
942 4c9649a9 j_mayer
    union {
943 4c9649a9 j_mayer
        double d;
944 4c9649a9 j_mayer
        uint64_t u;
945 4c9649a9 j_mayer
    } p;
946 4c9649a9 j_mayer
    double ft0, ft1;
947 4c9649a9 j_mayer
948 4c9649a9 j_mayer
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
949 4c9649a9 j_mayer
        /* XXX: TODO */
950 4c9649a9 j_mayer
    }
951 4c9649a9 j_mayer
    ft0 = vaxg_to_ieee64(FT0);
952 4c9649a9 j_mayer
    ft1 = vaxg_to_ieee64(FT1);
953 4c9649a9 j_mayer
    p.u = 0;
954 4c9649a9 j_mayer
    if (float64_le(ft0, ft1, &FP_STATUS))
955 4c9649a9 j_mayer
        p.u = 0x4000000000000000ULL;
956 4c9649a9 j_mayer
    FT0 = p.d;
957 4c9649a9 j_mayer
}
958 4c9649a9 j_mayer
959 4c9649a9 j_mayer
void helper_cvtqs (void)
960 4c9649a9 j_mayer
{
961 4c9649a9 j_mayer
    union {
962 4c9649a9 j_mayer
        double d;
963 4c9649a9 j_mayer
        uint64_t u;
964 4c9649a9 j_mayer
    } p;
965 4c9649a9 j_mayer
966 4c9649a9 j_mayer
    p.d = FT0;
967 4c9649a9 j_mayer
    FT0 = (float)p.u;
968 4c9649a9 j_mayer
}
969 4c9649a9 j_mayer
970 4c9649a9 j_mayer
void helper_cvttq (void)
971 4c9649a9 j_mayer
{
972 4c9649a9 j_mayer
    union {
973 4c9649a9 j_mayer
        double d;
974 4c9649a9 j_mayer
        uint64_t u;
975 4c9649a9 j_mayer
    } p;
976 4c9649a9 j_mayer
977 4c9649a9 j_mayer
    p.u = FT0;
978 4c9649a9 j_mayer
    FT0 = p.d;
979 4c9649a9 j_mayer
}
980 4c9649a9 j_mayer
981 4c9649a9 j_mayer
void helper_cvtqt (void)
982 4c9649a9 j_mayer
{
983 4c9649a9 j_mayer
    union {
984 4c9649a9 j_mayer
        double d;
985 4c9649a9 j_mayer
        uint64_t u;
986 4c9649a9 j_mayer
    } p;
987 4c9649a9 j_mayer
988 4c9649a9 j_mayer
    p.d = FT0;
989 4c9649a9 j_mayer
    FT0 = p.u;
990 4c9649a9 j_mayer
}
991 4c9649a9 j_mayer
992 4c9649a9 j_mayer
void helper_cvtqf (void)
993 4c9649a9 j_mayer
{
994 4c9649a9 j_mayer
    union {
995 4c9649a9 j_mayer
        double d;
996 4c9649a9 j_mayer
        uint64_t u;
997 4c9649a9 j_mayer
    } p;
998 4c9649a9 j_mayer
999 4c9649a9 j_mayer
    p.d = FT0;
1000 4c9649a9 j_mayer
    FT0 = ieee32_to_vaxf(p.u);
1001 4c9649a9 j_mayer
}
1002 4c9649a9 j_mayer
1003 4c9649a9 j_mayer
void helper_cvtgf (void)
1004 4c9649a9 j_mayer
{
1005 4c9649a9 j_mayer
    double ft0;
1006 4c9649a9 j_mayer
1007 4c9649a9 j_mayer
    ft0 = vaxg_to_ieee64(FT0);
1008 4c9649a9 j_mayer
    FT0 = ieee32_to_vaxf(ft0);
1009 4c9649a9 j_mayer
}
1010 4c9649a9 j_mayer
1011 4c9649a9 j_mayer
void helper_cvtgd (void)
1012 4c9649a9 j_mayer
{
1013 4c9649a9 j_mayer
    /* XXX: TODO */
1014 4c9649a9 j_mayer
}
1015 4c9649a9 j_mayer
1016 4c9649a9 j_mayer
void helper_cvtgq (void)
1017 4c9649a9 j_mayer
{
1018 4c9649a9 j_mayer
    union {
1019 4c9649a9 j_mayer
        double d;
1020 4c9649a9 j_mayer
        uint64_t u;
1021 4c9649a9 j_mayer
    } p;
1022 4c9649a9 j_mayer
1023 4c9649a9 j_mayer
    p.u = vaxg_to_ieee64(FT0);
1024 4c9649a9 j_mayer
    FT0 = p.d;
1025 4c9649a9 j_mayer
}
1026 4c9649a9 j_mayer
1027 4c9649a9 j_mayer
void helper_cvtqg (void)
1028 4c9649a9 j_mayer
{
1029 4c9649a9 j_mayer
    union {
1030 4c9649a9 j_mayer
        double d;
1031 4c9649a9 j_mayer
        uint64_t u;
1032 4c9649a9 j_mayer
    } p;
1033 4c9649a9 j_mayer
1034 4c9649a9 j_mayer
    p.d = FT0;
1035 4c9649a9 j_mayer
    FT0 = ieee64_to_vaxg(p.u);
1036 4c9649a9 j_mayer
}
1037 4c9649a9 j_mayer
1038 4c9649a9 j_mayer
void helper_cvtdg (void)
1039 4c9649a9 j_mayer
{
1040 4c9649a9 j_mayer
    /* XXX: TODO */
1041 4c9649a9 j_mayer
}
1042 4c9649a9 j_mayer
1043 4c9649a9 j_mayer
void helper_cvtlq (void)
1044 4c9649a9 j_mayer
{
1045 4c9649a9 j_mayer
    union {
1046 4c9649a9 j_mayer
        double d;
1047 4c9649a9 j_mayer
        uint64_t u;
1048 4c9649a9 j_mayer
    } p, q;
1049 4c9649a9 j_mayer
1050 4c9649a9 j_mayer
    p.d = FT0;
1051 4c9649a9 j_mayer
    q.u = (p.u >> 29) & 0x3FFFFFFF;
1052 4c9649a9 j_mayer
    q.u |= (p.u >> 32);
1053 4c9649a9 j_mayer
    q.u = (int64_t)((int32_t)q.u);
1054 4c9649a9 j_mayer
    FT0 = q.d;
1055 4c9649a9 j_mayer
}
1056 4c9649a9 j_mayer
1057 4c9649a9 j_mayer
static inline void __helper_cvtql (int s, int v)
1058 4c9649a9 j_mayer
{
1059 4c9649a9 j_mayer
    union {
1060 4c9649a9 j_mayer
        double d;
1061 4c9649a9 j_mayer
        uint64_t u;
1062 4c9649a9 j_mayer
    } p, q;
1063 4c9649a9 j_mayer
1064 4c9649a9 j_mayer
    p.d = FT0;
1065 4c9649a9 j_mayer
    q.u = ((uint64_t)(p.u & 0xC0000000)) << 32;
1066 4c9649a9 j_mayer
    q.u |= ((uint64_t)(p.u & 0x7FFFFFFF)) << 29;
1067 4c9649a9 j_mayer
    FT0 = q.d;
1068 4c9649a9 j_mayer
    if (v && (int64_t)((int32_t)p.u) != (int64_t)p.u) {
1069 4c9649a9 j_mayer
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
1070 4c9649a9 j_mayer
    }
1071 4c9649a9 j_mayer
    if (s) {
1072 4c9649a9 j_mayer
        /* TODO */
1073 4c9649a9 j_mayer
    }
1074 4c9649a9 j_mayer
}
1075 4c9649a9 j_mayer
1076 4c9649a9 j_mayer
void helper_cvtql (void)
1077 4c9649a9 j_mayer
{
1078 4c9649a9 j_mayer
    __helper_cvtql(0, 0);
1079 4c9649a9 j_mayer
}
1080 4c9649a9 j_mayer
1081 4c9649a9 j_mayer
void helper_cvtqlv (void)
1082 4c9649a9 j_mayer
{
1083 4c9649a9 j_mayer
    __helper_cvtql(0, 1);
1084 4c9649a9 j_mayer
}
1085 4c9649a9 j_mayer
1086 4c9649a9 j_mayer
void helper_cvtqlsv (void)
1087 4c9649a9 j_mayer
{
1088 4c9649a9 j_mayer
    __helper_cvtql(1, 1);
1089 4c9649a9 j_mayer
}
1090 4c9649a9 j_mayer
1091 4c9649a9 j_mayer
void helper_cmpfeq (void)
1092 4c9649a9 j_mayer
{
1093 4c9649a9 j_mayer
    if (float64_eq(FT0, FT1, &FP_STATUS))
1094 4c9649a9 j_mayer
        T0 = 1;
1095 4c9649a9 j_mayer
    else
1096 4c9649a9 j_mayer
        T0 = 0;
1097 4c9649a9 j_mayer
}
1098 4c9649a9 j_mayer
1099 4c9649a9 j_mayer
void helper_cmpfne (void)
1100 4c9649a9 j_mayer
{
1101 4c9649a9 j_mayer
    if (float64_eq(FT0, FT1, &FP_STATUS))
1102 4c9649a9 j_mayer
        T0 = 0;
1103 4c9649a9 j_mayer
    else
1104 4c9649a9 j_mayer
        T0 = 1;
1105 4c9649a9 j_mayer
}
1106 4c9649a9 j_mayer
1107 4c9649a9 j_mayer
void helper_cmpflt (void)
1108 4c9649a9 j_mayer
{
1109 4c9649a9 j_mayer
    if (float64_lt(FT0, FT1, &FP_STATUS))
1110 4c9649a9 j_mayer
        T0 = 1;
1111 4c9649a9 j_mayer
    else
1112 4c9649a9 j_mayer
        T0 = 0;
1113 4c9649a9 j_mayer
}
1114 4c9649a9 j_mayer
1115 4c9649a9 j_mayer
void helper_cmpfle (void)
1116 4c9649a9 j_mayer
{
1117 4c9649a9 j_mayer
    if (float64_lt(FT0, FT1, &FP_STATUS))
1118 4c9649a9 j_mayer
        T0 = 1;
1119 4c9649a9 j_mayer
    else
1120 4c9649a9 j_mayer
        T0 = 0;
1121 4c9649a9 j_mayer
}
1122 4c9649a9 j_mayer
1123 4c9649a9 j_mayer
void helper_cmpfgt (void)
1124 4c9649a9 j_mayer
{
1125 4c9649a9 j_mayer
    if (float64_le(FT0, FT1, &FP_STATUS))
1126 4c9649a9 j_mayer
        T0 = 0;
1127 4c9649a9 j_mayer
    else
1128 4c9649a9 j_mayer
        T0 = 1;
1129 4c9649a9 j_mayer
}
1130 4c9649a9 j_mayer
1131 4c9649a9 j_mayer
void helper_cmpfge (void)
1132 4c9649a9 j_mayer
{
1133 4c9649a9 j_mayer
    if (float64_lt(FT0, FT1, &FP_STATUS))
1134 4c9649a9 j_mayer
        T0 = 0;
1135 4c9649a9 j_mayer
    else
1136 4c9649a9 j_mayer
        T0 = 1;
1137 4c9649a9 j_mayer
}
1138 4c9649a9 j_mayer
1139 4c9649a9 j_mayer
#if !defined (CONFIG_USER_ONLY)
1140 4c9649a9 j_mayer
void helper_mfpr (int iprn)
1141 4c9649a9 j_mayer
{
1142 4c9649a9 j_mayer
    uint64_t val;
1143 4c9649a9 j_mayer
1144 4c9649a9 j_mayer
    if (cpu_alpha_mfpr(env, iprn, &val) == 0)
1145 4c9649a9 j_mayer
        T0 = val;
1146 4c9649a9 j_mayer
}
1147 4c9649a9 j_mayer
1148 4c9649a9 j_mayer
void helper_mtpr (int iprn)
1149 4c9649a9 j_mayer
{
1150 4c9649a9 j_mayer
    cpu_alpha_mtpr(env, iprn, T0, NULL);
1151 4c9649a9 j_mayer
}
1152 4c9649a9 j_mayer
#endif
1153 4c9649a9 j_mayer
1154 4c9649a9 j_mayer
/*****************************************************************************/
1155 4c9649a9 j_mayer
/* Softmmu support */
1156 4c9649a9 j_mayer
#if !defined (CONFIG_USER_ONLY)
1157 4c9649a9 j_mayer
1158 4c9649a9 j_mayer
#define GETPC() (__builtin_return_address(0))
1159 4c9649a9 j_mayer
1160 4c9649a9 j_mayer
/* XXX: the two following helpers are pure hacks.
1161 4c9649a9 j_mayer
 *      Hopefully, we emulate the PALcode, then we should never see
1162 4c9649a9 j_mayer
 *      HW_LD / HW_ST instructions.
1163 4c9649a9 j_mayer
 */
1164 4c9649a9 j_mayer
void helper_ld_phys_to_virt (void)
1165 4c9649a9 j_mayer
{
1166 4c9649a9 j_mayer
    uint64_t tlb_addr, physaddr;
1167 4c9649a9 j_mayer
    int index, is_user;
1168 4c9649a9 j_mayer
    void *retaddr;
1169 4c9649a9 j_mayer
1170 4c9649a9 j_mayer
    is_user = (env->ps >> 3) & 3;
1171 4c9649a9 j_mayer
    index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1172 4c9649a9 j_mayer
 redo:
1173 4c9649a9 j_mayer
    tlb_addr = env->tlb_table[is_user][index].addr_read;
1174 4c9649a9 j_mayer
    if ((T0 & TARGET_PAGE_MASK) ==
1175 4c9649a9 j_mayer
        (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
1176 4c9649a9 j_mayer
        physaddr = T0 + env->tlb_table[is_user][index].addend;
1177 4c9649a9 j_mayer
    } else {
1178 4c9649a9 j_mayer
        /* the page is not in the TLB : fill it */
1179 4c9649a9 j_mayer
        retaddr = GETPC();
1180 4c9649a9 j_mayer
        tlb_fill(T0, 0, is_user, retaddr);
1181 4c9649a9 j_mayer
        goto redo;
1182 4c9649a9 j_mayer
    }
1183 4c9649a9 j_mayer
    T0 = physaddr;
1184 4c9649a9 j_mayer
}
1185 4c9649a9 j_mayer
1186 4c9649a9 j_mayer
void helper_st_phys_to_virt (void)
1187 4c9649a9 j_mayer
{
1188 4c9649a9 j_mayer
    uint64_t tlb_addr, physaddr;
1189 4c9649a9 j_mayer
    int index, is_user;
1190 4c9649a9 j_mayer
    void *retaddr;
1191 4c9649a9 j_mayer
1192 4c9649a9 j_mayer
    is_user = (env->ps >> 3) & 3;
1193 4c9649a9 j_mayer
    index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1194 4c9649a9 j_mayer
 redo:
1195 4c9649a9 j_mayer
    tlb_addr = env->tlb_table[is_user][index].addr_write;
1196 4c9649a9 j_mayer
    if ((T0 & TARGET_PAGE_MASK) ==
1197 4c9649a9 j_mayer
        (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
1198 4c9649a9 j_mayer
        physaddr = T0 + env->tlb_table[is_user][index].addend;
1199 4c9649a9 j_mayer
    } else {
1200 4c9649a9 j_mayer
        /* the page is not in the TLB : fill it */
1201 4c9649a9 j_mayer
        retaddr = GETPC();
1202 4c9649a9 j_mayer
        tlb_fill(T0, 1, is_user, retaddr);
1203 4c9649a9 j_mayer
        goto redo;
1204 4c9649a9 j_mayer
    }
1205 4c9649a9 j_mayer
    T0 = physaddr;
1206 4c9649a9 j_mayer
}
1207 4c9649a9 j_mayer
1208 4c9649a9 j_mayer
#define MMUSUFFIX _mmu
1209 4c9649a9 j_mayer
1210 4c9649a9 j_mayer
#define SHIFT 0
1211 4c9649a9 j_mayer
#include "softmmu_template.h"
1212 4c9649a9 j_mayer
1213 4c9649a9 j_mayer
#define SHIFT 1
1214 4c9649a9 j_mayer
#include "softmmu_template.h"
1215 4c9649a9 j_mayer
1216 4c9649a9 j_mayer
#define SHIFT 2
1217 4c9649a9 j_mayer
#include "softmmu_template.h"
1218 4c9649a9 j_mayer
1219 4c9649a9 j_mayer
#define SHIFT 3
1220 4c9649a9 j_mayer
#include "softmmu_template.h"
1221 4c9649a9 j_mayer
1222 4c9649a9 j_mayer
/* try to fill the TLB and return an exception if error. If retaddr is
1223 4c9649a9 j_mayer
   NULL, it means that the function was called in C code (i.e. not
1224 4c9649a9 j_mayer
   from generated code or from helper.c) */
1225 4c9649a9 j_mayer
/* XXX: fix it to restore all registers */
1226 4c9649a9 j_mayer
void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
1227 4c9649a9 j_mayer
{
1228 4c9649a9 j_mayer
    TranslationBlock *tb;
1229 4c9649a9 j_mayer
    CPUState *saved_env;
1230 4c9649a9 j_mayer
    target_phys_addr_t pc;
1231 4c9649a9 j_mayer
    int ret;
1232 4c9649a9 j_mayer
1233 4c9649a9 j_mayer
    /* XXX: hack to restore env in all cases, even if not called from
1234 4c9649a9 j_mayer
       generated code */
1235 4c9649a9 j_mayer
    saved_env = env;
1236 4c9649a9 j_mayer
    env = cpu_single_env;
1237 4c9649a9 j_mayer
    ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, is_user, 1);
1238 4c9649a9 j_mayer
    if (!likely(ret == 0)) {
1239 4c9649a9 j_mayer
        if (likely(retaddr)) {
1240 4c9649a9 j_mayer
            /* now we have a real cpu fault */
1241 4c9649a9 j_mayer
            pc = (target_phys_addr_t)retaddr;
1242 4c9649a9 j_mayer
            tb = tb_find_pc(pc);
1243 4c9649a9 j_mayer
            if (likely(tb)) {
1244 4c9649a9 j_mayer
                /* the PC is inside the translated code. It means that we have
1245 4c9649a9 j_mayer
                   a virtual CPU fault */
1246 4c9649a9 j_mayer
                cpu_restore_state(tb, env, pc, NULL);
1247 4c9649a9 j_mayer
            }
1248 4c9649a9 j_mayer
        }
1249 4c9649a9 j_mayer
        /* Exception index and error code are already set */
1250 4c9649a9 j_mayer
        cpu_loop_exit();
1251 4c9649a9 j_mayer
    }
1252 4c9649a9 j_mayer
    env = saved_env;
1253 4c9649a9 j_mayer
}
1254 4c9649a9 j_mayer
1255 4c9649a9 j_mayer
#endif