Statistics
| Branch: | Revision:

root / target-alpha / op_helper.c @ b881c2c6

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