Statistics
| Branch: | Revision:

root / target-alpha / op_helper.c @ f0685f6e

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