Statistics
| Branch: | Revision:

root / target-s390x / op_helper.c @ 22486aa0

History | View | Annotate | Download (73.8 kB)

1 10ec5117 Alexander Graf
/*
2 10ec5117 Alexander Graf
 *  S/390 helper routines
3 10ec5117 Alexander Graf
 *
4 defb0e31 Alexander Graf
 *  Copyright (c) 2009 Ulrich Hecht
5 10ec5117 Alexander Graf
 *  Copyright (c) 2009 Alexander Graf
6 10ec5117 Alexander Graf
 *
7 10ec5117 Alexander Graf
 * This library is free software; you can redistribute it and/or
8 10ec5117 Alexander Graf
 * modify it under the terms of the GNU Lesser General Public
9 10ec5117 Alexander Graf
 * License as published by the Free Software Foundation; either
10 10ec5117 Alexander Graf
 * version 2 of the License, or (at your option) any later version.
11 10ec5117 Alexander Graf
 *
12 10ec5117 Alexander Graf
 * This library is distributed in the hope that it will be useful,
13 10ec5117 Alexander Graf
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 10ec5117 Alexander Graf
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 10ec5117 Alexander Graf
 * Lesser General Public License for more details.
16 10ec5117 Alexander Graf
 *
17 10ec5117 Alexander Graf
 * You should have received a copy of the GNU Lesser General Public
18 70539e18 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 10ec5117 Alexander Graf
 */
20 10ec5117 Alexander Graf
21 10ec5117 Alexander Graf
#include "exec.h"
22 defb0e31 Alexander Graf
#include "host-utils.h"
23 defb0e31 Alexander Graf
#include "helpers.h"
24 defb0e31 Alexander Graf
#include <string.h>
25 defb0e31 Alexander Graf
#include "kvm.h"
26 defb0e31 Alexander Graf
#include "qemu-timer.h"
27 10ec5117 Alexander Graf
28 10ec5117 Alexander Graf
/*****************************************************************************/
29 10ec5117 Alexander Graf
/* Softmmu support */
30 10ec5117 Alexander Graf
#if !defined (CONFIG_USER_ONLY)
31 10ec5117 Alexander Graf
32 10ec5117 Alexander Graf
#define MMUSUFFIX _mmu
33 10ec5117 Alexander Graf
34 10ec5117 Alexander Graf
#define SHIFT 0
35 10ec5117 Alexander Graf
#include "softmmu_template.h"
36 10ec5117 Alexander Graf
37 10ec5117 Alexander Graf
#define SHIFT 1
38 10ec5117 Alexander Graf
#include "softmmu_template.h"
39 10ec5117 Alexander Graf
40 10ec5117 Alexander Graf
#define SHIFT 2
41 10ec5117 Alexander Graf
#include "softmmu_template.h"
42 10ec5117 Alexander Graf
43 10ec5117 Alexander Graf
#define SHIFT 3
44 10ec5117 Alexander Graf
#include "softmmu_template.h"
45 10ec5117 Alexander Graf
46 10ec5117 Alexander Graf
/* try to fill the TLB and return an exception if error. If retaddr is
47 10ec5117 Alexander Graf
   NULL, it means that the function was called in C code (i.e. not
48 10ec5117 Alexander Graf
   from generated code or from helper.c) */
49 10ec5117 Alexander Graf
/* XXX: fix it to restore all registers */
50 10ec5117 Alexander Graf
void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
51 10ec5117 Alexander Graf
{
52 10ec5117 Alexander Graf
    TranslationBlock *tb;
53 10ec5117 Alexander Graf
    CPUState *saved_env;
54 10ec5117 Alexander Graf
    unsigned long pc;
55 10ec5117 Alexander Graf
    int ret;
56 10ec5117 Alexander Graf
57 10ec5117 Alexander Graf
    /* XXX: hack to restore env in all cases, even if not called from
58 10ec5117 Alexander Graf
       generated code */
59 10ec5117 Alexander Graf
    saved_env = env;
60 10ec5117 Alexander Graf
    env = cpu_single_env;
61 10ec5117 Alexander Graf
    ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
62 10ec5117 Alexander Graf
    if (unlikely(ret != 0)) {
63 10ec5117 Alexander Graf
        if (likely(retaddr)) {
64 10ec5117 Alexander Graf
            /* now we have a real cpu fault */
65 10ec5117 Alexander Graf
            pc = (unsigned long)retaddr;
66 10ec5117 Alexander Graf
            tb = tb_find_pc(pc);
67 10ec5117 Alexander Graf
            if (likely(tb)) {
68 10ec5117 Alexander Graf
                /* the PC is inside the translated code. It means that we have
69 10ec5117 Alexander Graf
                   a virtual CPU fault */
70 618ba8e6 Stefan Weil
                cpu_restore_state(tb, env, pc);
71 10ec5117 Alexander Graf
            }
72 10ec5117 Alexander Graf
        }
73 defb0e31 Alexander Graf
        cpu_loop_exit();
74 10ec5117 Alexander Graf
    }
75 10ec5117 Alexander Graf
    env = saved_env;
76 10ec5117 Alexander Graf
}
77 10ec5117 Alexander Graf
78 10ec5117 Alexander Graf
#endif
79 d5a43964 Alexander Graf
80 defb0e31 Alexander Graf
/* #define DEBUG_HELPER */
81 defb0e31 Alexander Graf
#ifdef DEBUG_HELPER
82 defb0e31 Alexander Graf
#define HELPER_LOG(x...) qemu_log(x)
83 defb0e31 Alexander Graf
#else
84 defb0e31 Alexander Graf
#define HELPER_LOG(x...)
85 defb0e31 Alexander Graf
#endif
86 defb0e31 Alexander Graf
87 defb0e31 Alexander Graf
/* raise an exception */
88 defb0e31 Alexander Graf
void HELPER(exception)(uint32_t excp)
89 defb0e31 Alexander Graf
{
90 defb0e31 Alexander Graf
    HELPER_LOG("%s: exception %d\n", __FUNCTION__, excp);
91 defb0e31 Alexander Graf
    env->exception_index = excp;
92 defb0e31 Alexander Graf
    cpu_loop_exit();
93 defb0e31 Alexander Graf
}
94 defb0e31 Alexander Graf
95 defb0e31 Alexander Graf
#ifndef CONFIG_USER_ONLY
96 defb0e31 Alexander Graf
static void mvc_fast_memset(CPUState *env, uint32_t l, uint64_t dest,
97 defb0e31 Alexander Graf
                            uint8_t byte)
98 defb0e31 Alexander Graf
{
99 defb0e31 Alexander Graf
    target_phys_addr_t dest_phys;
100 defb0e31 Alexander Graf
    target_phys_addr_t len = l;
101 defb0e31 Alexander Graf
    void *dest_p;
102 defb0e31 Alexander Graf
    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
103 defb0e31 Alexander Graf
    int flags;
104 defb0e31 Alexander Graf
105 defb0e31 Alexander Graf
    if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
106 defb0e31 Alexander Graf
        stb(dest, byte);
107 defb0e31 Alexander Graf
        cpu_abort(env, "should never reach here");
108 defb0e31 Alexander Graf
    }
109 defb0e31 Alexander Graf
    dest_phys |= dest & ~TARGET_PAGE_MASK;
110 defb0e31 Alexander Graf
111 defb0e31 Alexander Graf
    dest_p = cpu_physical_memory_map(dest_phys, &len, 1);
112 defb0e31 Alexander Graf
113 defb0e31 Alexander Graf
    memset(dest_p, byte, len);
114 defb0e31 Alexander Graf
115 defb0e31 Alexander Graf
    cpu_physical_memory_unmap(dest_p, 1, len, len);
116 defb0e31 Alexander Graf
}
117 defb0e31 Alexander Graf
118 defb0e31 Alexander Graf
static void mvc_fast_memmove(CPUState *env, uint32_t l, uint64_t dest,
119 defb0e31 Alexander Graf
                             uint64_t src)
120 defb0e31 Alexander Graf
{
121 defb0e31 Alexander Graf
    target_phys_addr_t dest_phys;
122 defb0e31 Alexander Graf
    target_phys_addr_t src_phys;
123 defb0e31 Alexander Graf
    target_phys_addr_t len = l;
124 defb0e31 Alexander Graf
    void *dest_p;
125 defb0e31 Alexander Graf
    void *src_p;
126 defb0e31 Alexander Graf
    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
127 defb0e31 Alexander Graf
    int flags;
128 defb0e31 Alexander Graf
129 defb0e31 Alexander Graf
    if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
130 defb0e31 Alexander Graf
        stb(dest, 0);
131 defb0e31 Alexander Graf
        cpu_abort(env, "should never reach here");
132 defb0e31 Alexander Graf
    }
133 defb0e31 Alexander Graf
    dest_phys |= dest & ~TARGET_PAGE_MASK;
134 defb0e31 Alexander Graf
135 defb0e31 Alexander Graf
    if (mmu_translate(env, src, 0, asc, &src_phys, &flags)) {
136 defb0e31 Alexander Graf
        ldub(src);
137 defb0e31 Alexander Graf
        cpu_abort(env, "should never reach here");
138 defb0e31 Alexander Graf
    }
139 defb0e31 Alexander Graf
    src_phys |= src & ~TARGET_PAGE_MASK;
140 defb0e31 Alexander Graf
141 defb0e31 Alexander Graf
    dest_p = cpu_physical_memory_map(dest_phys, &len, 1);
142 defb0e31 Alexander Graf
    src_p = cpu_physical_memory_map(src_phys, &len, 0);
143 defb0e31 Alexander Graf
144 defb0e31 Alexander Graf
    memmove(dest_p, src_p, len);
145 defb0e31 Alexander Graf
146 defb0e31 Alexander Graf
    cpu_physical_memory_unmap(dest_p, 1, len, len);
147 defb0e31 Alexander Graf
    cpu_physical_memory_unmap(src_p, 0, len, len);
148 defb0e31 Alexander Graf
}
149 defb0e31 Alexander Graf
#endif
150 defb0e31 Alexander Graf
151 defb0e31 Alexander Graf
/* and on array */
152 defb0e31 Alexander Graf
uint32_t HELPER(nc)(uint32_t l, uint64_t dest, uint64_t src)
153 defb0e31 Alexander Graf
{
154 defb0e31 Alexander Graf
    int i;
155 defb0e31 Alexander Graf
    unsigned char x;
156 defb0e31 Alexander Graf
    uint32_t cc = 0;
157 defb0e31 Alexander Graf
158 defb0e31 Alexander Graf
    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
159 defb0e31 Alexander Graf
               __FUNCTION__, l, dest, src);
160 defb0e31 Alexander Graf
    for (i = 0; i <= l; i++) {
161 defb0e31 Alexander Graf
        x = ldub(dest + i) & ldub(src + i);
162 defb0e31 Alexander Graf
        if (x) {
163 defb0e31 Alexander Graf
            cc = 1;
164 defb0e31 Alexander Graf
        }
165 defb0e31 Alexander Graf
        stb(dest + i, x);
166 defb0e31 Alexander Graf
    }
167 defb0e31 Alexander Graf
    return cc;
168 defb0e31 Alexander Graf
}
169 defb0e31 Alexander Graf
170 defb0e31 Alexander Graf
/* xor on array */
171 defb0e31 Alexander Graf
uint32_t HELPER(xc)(uint32_t l, uint64_t dest, uint64_t src)
172 defb0e31 Alexander Graf
{
173 defb0e31 Alexander Graf
    int i;
174 defb0e31 Alexander Graf
    unsigned char x;
175 defb0e31 Alexander Graf
    uint32_t cc = 0;
176 defb0e31 Alexander Graf
177 defb0e31 Alexander Graf
    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
178 defb0e31 Alexander Graf
               __FUNCTION__, l, dest, src);
179 defb0e31 Alexander Graf
180 defb0e31 Alexander Graf
#ifndef CONFIG_USER_ONLY
181 defb0e31 Alexander Graf
    /* xor with itself is the same as memset(0) */
182 defb0e31 Alexander Graf
    if ((l > 32) && (src == dest) &&
183 defb0e31 Alexander Graf
        (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK)) {
184 defb0e31 Alexander Graf
        mvc_fast_memset(env, l + 1, dest, 0);
185 defb0e31 Alexander Graf
        return 0;
186 defb0e31 Alexander Graf
    }
187 defb0e31 Alexander Graf
#else
188 defb0e31 Alexander Graf
    if (src == dest) {
189 defb0e31 Alexander Graf
        memset(g2h(dest), 0, l + 1);
190 defb0e31 Alexander Graf
        return 0;
191 defb0e31 Alexander Graf
    }
192 defb0e31 Alexander Graf
#endif
193 defb0e31 Alexander Graf
194 defb0e31 Alexander Graf
    for (i = 0; i <= l; i++) {
195 defb0e31 Alexander Graf
        x = ldub(dest + i) ^ ldub(src + i);
196 defb0e31 Alexander Graf
        if (x) {
197 defb0e31 Alexander Graf
            cc = 1;
198 defb0e31 Alexander Graf
        }
199 defb0e31 Alexander Graf
        stb(dest + i, x);
200 defb0e31 Alexander Graf
    }
201 defb0e31 Alexander Graf
    return cc;
202 defb0e31 Alexander Graf
}
203 defb0e31 Alexander Graf
204 defb0e31 Alexander Graf
/* or on array */
205 defb0e31 Alexander Graf
uint32_t HELPER(oc)(uint32_t l, uint64_t dest, uint64_t src)
206 defb0e31 Alexander Graf
{
207 defb0e31 Alexander Graf
    int i;
208 defb0e31 Alexander Graf
    unsigned char x;
209 defb0e31 Alexander Graf
    uint32_t cc = 0;
210 defb0e31 Alexander Graf
211 defb0e31 Alexander Graf
    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
212 defb0e31 Alexander Graf
               __FUNCTION__, l, dest, src);
213 defb0e31 Alexander Graf
    for (i = 0; i <= l; i++) {
214 defb0e31 Alexander Graf
        x = ldub(dest + i) | ldub(src + i);
215 defb0e31 Alexander Graf
        if (x) {
216 defb0e31 Alexander Graf
            cc = 1;
217 defb0e31 Alexander Graf
        }
218 defb0e31 Alexander Graf
        stb(dest + i, x);
219 defb0e31 Alexander Graf
    }
220 defb0e31 Alexander Graf
    return cc;
221 defb0e31 Alexander Graf
}
222 defb0e31 Alexander Graf
223 defb0e31 Alexander Graf
/* memmove */
224 defb0e31 Alexander Graf
void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
225 defb0e31 Alexander Graf
{
226 defb0e31 Alexander Graf
    int i = 0;
227 defb0e31 Alexander Graf
    int x = 0;
228 defb0e31 Alexander Graf
    uint32_t l_64 = (l + 1) / 8;
229 defb0e31 Alexander Graf
230 defb0e31 Alexander Graf
    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
231 defb0e31 Alexander Graf
               __FUNCTION__, l, dest, src);
232 defb0e31 Alexander Graf
233 defb0e31 Alexander Graf
#ifndef CONFIG_USER_ONLY
234 defb0e31 Alexander Graf
    if ((l > 32) &&
235 defb0e31 Alexander Graf
        (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK) &&
236 defb0e31 Alexander Graf
        (dest & TARGET_PAGE_MASK) == ((dest + l) & TARGET_PAGE_MASK)) {
237 defb0e31 Alexander Graf
        if (dest == (src + 1)) {
238 defb0e31 Alexander Graf
            mvc_fast_memset(env, l + 1, dest, ldub(src));
239 defb0e31 Alexander Graf
            return;
240 defb0e31 Alexander Graf
        } else if ((src & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
241 defb0e31 Alexander Graf
            mvc_fast_memmove(env, l + 1, dest, src);
242 defb0e31 Alexander Graf
            return;
243 defb0e31 Alexander Graf
        }
244 defb0e31 Alexander Graf
    }
245 defb0e31 Alexander Graf
#else
246 defb0e31 Alexander Graf
    if (dest == (src + 1)) {
247 defb0e31 Alexander Graf
        memset(g2h(dest), ldub(src), l + 1);
248 defb0e31 Alexander Graf
        return;
249 defb0e31 Alexander Graf
    } else {
250 defb0e31 Alexander Graf
        memmove(g2h(dest), g2h(src), l + 1);
251 defb0e31 Alexander Graf
        return;
252 defb0e31 Alexander Graf
    }
253 defb0e31 Alexander Graf
#endif
254 defb0e31 Alexander Graf
255 defb0e31 Alexander Graf
    /* handle the parts that fit into 8-byte loads/stores */
256 defb0e31 Alexander Graf
    if (dest != (src + 1)) {
257 defb0e31 Alexander Graf
        for (i = 0; i < l_64; i++) {
258 defb0e31 Alexander Graf
            stq(dest + x, ldq(src + x));
259 defb0e31 Alexander Graf
            x += 8;
260 defb0e31 Alexander Graf
        }
261 defb0e31 Alexander Graf
    }
262 defb0e31 Alexander Graf
263 defb0e31 Alexander Graf
    /* slow version crossing pages with byte accesses */
264 defb0e31 Alexander Graf
    for (i = x; i <= l; i++) {
265 defb0e31 Alexander Graf
        stb(dest + i, ldub(src + i));
266 defb0e31 Alexander Graf
    }
267 defb0e31 Alexander Graf
}
268 defb0e31 Alexander Graf
269 defb0e31 Alexander Graf
/* compare unsigned byte arrays */
270 defb0e31 Alexander Graf
uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
271 defb0e31 Alexander Graf
{
272 defb0e31 Alexander Graf
    int i;
273 defb0e31 Alexander Graf
    unsigned char x,y;
274 defb0e31 Alexander Graf
    uint32_t cc;
275 defb0e31 Alexander Graf
    HELPER_LOG("%s l %d s1 %" PRIx64 " s2 %" PRIx64 "\n",
276 defb0e31 Alexander Graf
               __FUNCTION__, l, s1, s2);
277 defb0e31 Alexander Graf
    for (i = 0; i <= l; i++) {
278 defb0e31 Alexander Graf
        x = ldub(s1 + i);
279 defb0e31 Alexander Graf
        y = ldub(s2 + i);
280 defb0e31 Alexander Graf
        HELPER_LOG("%02x (%c)/%02x (%c) ", x, x, y, y);
281 defb0e31 Alexander Graf
        if (x < y) {
282 defb0e31 Alexander Graf
            cc = 1;
283 defb0e31 Alexander Graf
            goto done;
284 defb0e31 Alexander Graf
        } else if (x > y) {
285 defb0e31 Alexander Graf
            cc = 2;
286 defb0e31 Alexander Graf
            goto done;
287 defb0e31 Alexander Graf
        }
288 defb0e31 Alexander Graf
    }
289 defb0e31 Alexander Graf
    cc = 0;
290 defb0e31 Alexander Graf
done:
291 defb0e31 Alexander Graf
    HELPER_LOG("\n");
292 defb0e31 Alexander Graf
    return cc;
293 defb0e31 Alexander Graf
}
294 defb0e31 Alexander Graf
295 defb0e31 Alexander Graf
/* compare logical under mask */
296 defb0e31 Alexander Graf
uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
297 defb0e31 Alexander Graf
{
298 defb0e31 Alexander Graf
    uint8_t r,d;
299 defb0e31 Alexander Graf
    uint32_t cc;
300 defb0e31 Alexander Graf
    HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __FUNCTION__, r1,
301 defb0e31 Alexander Graf
               mask, addr);
302 defb0e31 Alexander Graf
    cc = 0;
303 defb0e31 Alexander Graf
    while (mask) {
304 defb0e31 Alexander Graf
        if (mask & 8) {
305 defb0e31 Alexander Graf
            d = ldub(addr);
306 defb0e31 Alexander Graf
            r = (r1 & 0xff000000UL) >> 24;
307 defb0e31 Alexander Graf
            HELPER_LOG("mask 0x%x %02x/%02x (0x%" PRIx64 ") ", mask, r, d,
308 defb0e31 Alexander Graf
                        addr);
309 defb0e31 Alexander Graf
            if (r < d) {
310 defb0e31 Alexander Graf
                cc = 1;
311 defb0e31 Alexander Graf
                break;
312 defb0e31 Alexander Graf
            } else if (r > d) {
313 defb0e31 Alexander Graf
                cc = 2;
314 defb0e31 Alexander Graf
                break;
315 defb0e31 Alexander Graf
            }
316 defb0e31 Alexander Graf
            addr++;
317 defb0e31 Alexander Graf
        }
318 defb0e31 Alexander Graf
        mask = (mask << 1) & 0xf;
319 defb0e31 Alexander Graf
        r1 <<= 8;
320 defb0e31 Alexander Graf
    }
321 defb0e31 Alexander Graf
    HELPER_LOG("\n");
322 defb0e31 Alexander Graf
    return cc;
323 defb0e31 Alexander Graf
}
324 defb0e31 Alexander Graf
325 defb0e31 Alexander Graf
/* store character under mask */
326 defb0e31 Alexander Graf
void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
327 defb0e31 Alexander Graf
{
328 defb0e31 Alexander Graf
    uint8_t r;
329 defb0e31 Alexander Graf
    HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n", __FUNCTION__, r1, mask,
330 defb0e31 Alexander Graf
               addr);
331 defb0e31 Alexander Graf
    while (mask) {
332 defb0e31 Alexander Graf
        if (mask & 8) {
333 defb0e31 Alexander Graf
            r = (r1 & 0xff000000UL) >> 24;
334 defb0e31 Alexander Graf
            stb(addr, r);
335 defb0e31 Alexander Graf
            HELPER_LOG("mask 0x%x %02x (0x%lx) ", mask, r, addr);
336 defb0e31 Alexander Graf
            addr++;
337 defb0e31 Alexander Graf
        }
338 defb0e31 Alexander Graf
        mask = (mask << 1) & 0xf;
339 defb0e31 Alexander Graf
        r1 <<= 8;
340 defb0e31 Alexander Graf
    }
341 defb0e31 Alexander Graf
    HELPER_LOG("\n");
342 defb0e31 Alexander Graf
}
343 defb0e31 Alexander Graf
344 defb0e31 Alexander Graf
/* 64/64 -> 128 unsigned multiplication */
345 defb0e31 Alexander Graf
void HELPER(mlg)(uint32_t r1, uint64_t v2)
346 defb0e31 Alexander Graf
{
347 defb0e31 Alexander Graf
#if HOST_LONG_BITS == 64 && defined(__GNUC__)
348 defb0e31 Alexander Graf
    /* assuming 64-bit hosts have __uint128_t */
349 defb0e31 Alexander Graf
    __uint128_t res = (__uint128_t)env->regs[r1 + 1];
350 defb0e31 Alexander Graf
    res *= (__uint128_t)v2;
351 defb0e31 Alexander Graf
    env->regs[r1] = (uint64_t)(res >> 64);
352 defb0e31 Alexander Graf
    env->regs[r1 + 1] = (uint64_t)res;
353 defb0e31 Alexander Graf
#else
354 defb0e31 Alexander Graf
    mulu64(&env->regs[r1 + 1], &env->regs[r1], env->regs[r1 + 1], v2);
355 defb0e31 Alexander Graf
#endif
356 defb0e31 Alexander Graf
}
357 defb0e31 Alexander Graf
358 defb0e31 Alexander Graf
/* 128 -> 64/64 unsigned division */
359 defb0e31 Alexander Graf
void HELPER(dlg)(uint32_t r1, uint64_t v2)
360 defb0e31 Alexander Graf
{
361 defb0e31 Alexander Graf
    uint64_t divisor = v2;
362 defb0e31 Alexander Graf
363 defb0e31 Alexander Graf
    if (!env->regs[r1]) {
364 defb0e31 Alexander Graf
        /* 64 -> 64/64 case */
365 defb0e31 Alexander Graf
        env->regs[r1] = env->regs[r1+1] % divisor;
366 defb0e31 Alexander Graf
        env->regs[r1+1] = env->regs[r1+1] / divisor;
367 defb0e31 Alexander Graf
        return;
368 defb0e31 Alexander Graf
    } else {
369 defb0e31 Alexander Graf
370 defb0e31 Alexander Graf
#if HOST_LONG_BITS == 64 && defined(__GNUC__)
371 defb0e31 Alexander Graf
        /* assuming 64-bit hosts have __uint128_t */
372 defb0e31 Alexander Graf
        __uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) |
373 defb0e31 Alexander Graf
                               (env->regs[r1+1]);
374 defb0e31 Alexander Graf
        __uint128_t quotient = dividend / divisor;
375 defb0e31 Alexander Graf
        env->regs[r1+1] = quotient;
376 defb0e31 Alexander Graf
        __uint128_t remainder = dividend % divisor;
377 defb0e31 Alexander Graf
        env->regs[r1] = remainder;
378 defb0e31 Alexander Graf
#else
379 defb0e31 Alexander Graf
        /* 32-bit hosts would need special wrapper functionality - just abort if
380 defb0e31 Alexander Graf
           we encounter such a case; it's very unlikely anyways. */
381 defb0e31 Alexander Graf
        cpu_abort(env, "128 -> 64/64 division not implemented\n");
382 defb0e31 Alexander Graf
#endif
383 defb0e31 Alexander Graf
    }
384 defb0e31 Alexander Graf
}
385 defb0e31 Alexander Graf
386 defb0e31 Alexander Graf
static inline uint64_t get_address(int x2, int b2, int d2)
387 defb0e31 Alexander Graf
{
388 defb0e31 Alexander Graf
    uint64_t r = d2;
389 defb0e31 Alexander Graf
390 defb0e31 Alexander Graf
    if (x2) {
391 defb0e31 Alexander Graf
        r += env->regs[x2];
392 defb0e31 Alexander Graf
    }
393 defb0e31 Alexander Graf
394 defb0e31 Alexander Graf
    if (b2) {
395 defb0e31 Alexander Graf
        r += env->regs[b2];
396 defb0e31 Alexander Graf
    }
397 defb0e31 Alexander Graf
398 defb0e31 Alexander Graf
    /* 31-Bit mode */
399 defb0e31 Alexander Graf
    if (!(env->psw.mask & PSW_MASK_64)) {
400 defb0e31 Alexander Graf
        r &= 0x7fffffff;
401 defb0e31 Alexander Graf
    }
402 defb0e31 Alexander Graf
403 defb0e31 Alexander Graf
    return r;
404 defb0e31 Alexander Graf
}
405 defb0e31 Alexander Graf
406 defb0e31 Alexander Graf
static inline uint64_t get_address_31fix(int reg)
407 defb0e31 Alexander Graf
{
408 defb0e31 Alexander Graf
    uint64_t r = env->regs[reg];
409 defb0e31 Alexander Graf
410 defb0e31 Alexander Graf
    /* 31-Bit mode */
411 defb0e31 Alexander Graf
    if (!(env->psw.mask & PSW_MASK_64)) {
412 defb0e31 Alexander Graf
        r &= 0x7fffffff;
413 defb0e31 Alexander Graf
    }
414 defb0e31 Alexander Graf
415 defb0e31 Alexander Graf
    return r;
416 defb0e31 Alexander Graf
}
417 defb0e31 Alexander Graf
418 defb0e31 Alexander Graf
/* search string (c is byte to search, r2 is string, r1 end of string) */
419 defb0e31 Alexander Graf
uint32_t HELPER(srst)(uint32_t c, uint32_t r1, uint32_t r2)
420 defb0e31 Alexander Graf
{
421 defb0e31 Alexander Graf
    uint64_t i;
422 defb0e31 Alexander Graf
    uint32_t cc = 2;
423 defb0e31 Alexander Graf
    uint64_t str = get_address_31fix(r2);
424 defb0e31 Alexander Graf
    uint64_t end = get_address_31fix(r1);
425 defb0e31 Alexander Graf
426 defb0e31 Alexander Graf
    HELPER_LOG("%s: c %d *r1 0x%" PRIx64 " *r2 0x%" PRIx64 "\n", __FUNCTION__,
427 defb0e31 Alexander Graf
               c, env->regs[r1], env->regs[r2]);
428 defb0e31 Alexander Graf
429 defb0e31 Alexander Graf
    for (i = str; i != end; i++) {
430 defb0e31 Alexander Graf
        if (ldub(i) == c) {
431 defb0e31 Alexander Graf
            env->regs[r1] = i;
432 defb0e31 Alexander Graf
            cc = 1;
433 defb0e31 Alexander Graf
            break;
434 defb0e31 Alexander Graf
        }
435 defb0e31 Alexander Graf
    }
436 defb0e31 Alexander Graf
437 defb0e31 Alexander Graf
    return cc;
438 defb0e31 Alexander Graf
}
439 defb0e31 Alexander Graf
440 defb0e31 Alexander Graf
/* unsigned string compare (c is string terminator) */
441 defb0e31 Alexander Graf
uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2)
442 defb0e31 Alexander Graf
{
443 defb0e31 Alexander Graf
    uint64_t s1 = get_address_31fix(r1);
444 defb0e31 Alexander Graf
    uint64_t s2 = get_address_31fix(r2);
445 defb0e31 Alexander Graf
    uint8_t v1, v2;
446 defb0e31 Alexander Graf
    uint32_t cc;
447 defb0e31 Alexander Graf
    c = c & 0xff;
448 defb0e31 Alexander Graf
#ifdef CONFIG_USER_ONLY
449 defb0e31 Alexander Graf
    if (!c) {
450 defb0e31 Alexander Graf
        HELPER_LOG("%s: comparing '%s' and '%s'\n",
451 defb0e31 Alexander Graf
                   __FUNCTION__, (char*)g2h(s1), (char*)g2h(s2));
452 defb0e31 Alexander Graf
    }
453 defb0e31 Alexander Graf
#endif
454 defb0e31 Alexander Graf
    for (;;) {
455 defb0e31 Alexander Graf
        v1 = ldub(s1);
456 defb0e31 Alexander Graf
        v2 = ldub(s2);
457 defb0e31 Alexander Graf
        if ((v1 == c || v2 == c) || (v1 != v2)) {
458 defb0e31 Alexander Graf
            break;
459 defb0e31 Alexander Graf
        }
460 defb0e31 Alexander Graf
        s1++;
461 defb0e31 Alexander Graf
        s2++;
462 defb0e31 Alexander Graf
    }
463 defb0e31 Alexander Graf
464 defb0e31 Alexander Graf
    if (v1 == v2) {
465 defb0e31 Alexander Graf
        cc = 0;
466 defb0e31 Alexander Graf
    } else {
467 defb0e31 Alexander Graf
        cc = (v1 < v2) ? 1 : 2;
468 defb0e31 Alexander Graf
        /* FIXME: 31-bit mode! */
469 defb0e31 Alexander Graf
        env->regs[r1] = s1;
470 defb0e31 Alexander Graf
        env->regs[r2] = s2;
471 defb0e31 Alexander Graf
    }
472 defb0e31 Alexander Graf
    return cc;
473 defb0e31 Alexander Graf
}
474 defb0e31 Alexander Graf
475 defb0e31 Alexander Graf
/* move page */
476 defb0e31 Alexander Graf
void HELPER(mvpg)(uint64_t r0, uint64_t r1, uint64_t r2)
477 defb0e31 Alexander Graf
{
478 defb0e31 Alexander Graf
    /* XXX missing r0 handling */
479 defb0e31 Alexander Graf
#ifdef CONFIG_USER_ONLY
480 defb0e31 Alexander Graf
    int i;
481 defb0e31 Alexander Graf
482 defb0e31 Alexander Graf
    for (i = 0; i < TARGET_PAGE_SIZE; i++) {
483 defb0e31 Alexander Graf
        stb(r1 + i, ldub(r2 + i));
484 defb0e31 Alexander Graf
    }
485 defb0e31 Alexander Graf
#else
486 defb0e31 Alexander Graf
    mvc_fast_memmove(env, TARGET_PAGE_SIZE, r1, r2);
487 defb0e31 Alexander Graf
#endif
488 defb0e31 Alexander Graf
}
489 defb0e31 Alexander Graf
490 defb0e31 Alexander Graf
/* string copy (c is string terminator) */
491 defb0e31 Alexander Graf
void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2)
492 defb0e31 Alexander Graf
{
493 defb0e31 Alexander Graf
    uint64_t dest = get_address_31fix(r1);
494 defb0e31 Alexander Graf
    uint64_t src = get_address_31fix(r2);
495 defb0e31 Alexander Graf
    uint8_t v;
496 defb0e31 Alexander Graf
    c = c & 0xff;
497 defb0e31 Alexander Graf
#ifdef CONFIG_USER_ONLY
498 defb0e31 Alexander Graf
    if (!c) {
499 defb0e31 Alexander Graf
        HELPER_LOG("%s: copy '%s' to 0x%lx\n", __FUNCTION__, (char*)g2h(src),
500 defb0e31 Alexander Graf
                   dest);
501 defb0e31 Alexander Graf
    }
502 defb0e31 Alexander Graf
#endif
503 defb0e31 Alexander Graf
    for (;;) {
504 defb0e31 Alexander Graf
        v = ldub(src);
505 defb0e31 Alexander Graf
        stb(dest, v);
506 defb0e31 Alexander Graf
        if (v == c) {
507 defb0e31 Alexander Graf
            break;
508 defb0e31 Alexander Graf
        }
509 defb0e31 Alexander Graf
        src++;
510 defb0e31 Alexander Graf
        dest++;
511 defb0e31 Alexander Graf
    }
512 defb0e31 Alexander Graf
    env->regs[r1] = dest; /* FIXME: 31-bit mode! */
513 defb0e31 Alexander Graf
}
514 defb0e31 Alexander Graf
515 defb0e31 Alexander Graf
/* compare and swap 64-bit */
516 defb0e31 Alexander Graf
uint32_t HELPER(csg)(uint32_t r1, uint64_t a2, uint32_t r3)
517 defb0e31 Alexander Graf
{
518 defb0e31 Alexander Graf
    /* FIXME: locking? */
519 defb0e31 Alexander Graf
    uint32_t cc;
520 defb0e31 Alexander Graf
    uint64_t v2 = ldq(a2);
521 defb0e31 Alexander Graf
    if (env->regs[r1] == v2) {
522 defb0e31 Alexander Graf
        cc = 0;
523 defb0e31 Alexander Graf
        stq(a2, env->regs[r3]);
524 defb0e31 Alexander Graf
    } else {
525 defb0e31 Alexander Graf
        cc = 1;
526 defb0e31 Alexander Graf
        env->regs[r1] = v2;
527 defb0e31 Alexander Graf
    }
528 defb0e31 Alexander Graf
    return cc;
529 defb0e31 Alexander Graf
}
530 defb0e31 Alexander Graf
531 defb0e31 Alexander Graf
/* compare double and swap 64-bit */
532 defb0e31 Alexander Graf
uint32_t HELPER(cdsg)(uint32_t r1, uint64_t a2, uint32_t r3)
533 defb0e31 Alexander Graf
{
534 defb0e31 Alexander Graf
    /* FIXME: locking? */
535 defb0e31 Alexander Graf
    uint32_t cc;
536 defb0e31 Alexander Graf
    uint64_t v2_hi = ldq(a2);
537 defb0e31 Alexander Graf
    uint64_t v2_lo = ldq(a2 + 8);
538 defb0e31 Alexander Graf
    uint64_t v1_hi = env->regs[r1];
539 defb0e31 Alexander Graf
    uint64_t v1_lo = env->regs[r1 + 1];
540 defb0e31 Alexander Graf
541 defb0e31 Alexander Graf
    if ((v1_hi == v2_hi) && (v1_lo == v2_lo)) {
542 defb0e31 Alexander Graf
        cc = 0;
543 defb0e31 Alexander Graf
        stq(a2, env->regs[r3]);
544 defb0e31 Alexander Graf
        stq(a2 + 8, env->regs[r3 + 1]);
545 defb0e31 Alexander Graf
    } else {
546 defb0e31 Alexander Graf
        cc = 1;
547 defb0e31 Alexander Graf
        env->regs[r1] = v2_hi;
548 defb0e31 Alexander Graf
        env->regs[r1 + 1] = v2_lo;
549 defb0e31 Alexander Graf
    }
550 defb0e31 Alexander Graf
551 defb0e31 Alexander Graf
    return cc;
552 defb0e31 Alexander Graf
}
553 defb0e31 Alexander Graf
554 defb0e31 Alexander Graf
/* compare and swap 32-bit */
555 defb0e31 Alexander Graf
uint32_t HELPER(cs)(uint32_t r1, uint64_t a2, uint32_t r3)
556 defb0e31 Alexander Graf
{
557 defb0e31 Alexander Graf
    /* FIXME: locking? */
558 defb0e31 Alexander Graf
    uint32_t cc;
559 defb0e31 Alexander Graf
    HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __FUNCTION__, r1, a2, r3);
560 defb0e31 Alexander Graf
    uint32_t v2 = ldl(a2);
561 defb0e31 Alexander Graf
    if (((uint32_t)env->regs[r1]) == v2) {
562 defb0e31 Alexander Graf
        cc = 0;
563 defb0e31 Alexander Graf
        stl(a2, (uint32_t)env->regs[r3]);
564 defb0e31 Alexander Graf
    } else {
565 defb0e31 Alexander Graf
        cc = 1;
566 defb0e31 Alexander Graf
        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | v2;
567 defb0e31 Alexander Graf
    }
568 defb0e31 Alexander Graf
    return cc;
569 defb0e31 Alexander Graf
}
570 defb0e31 Alexander Graf
571 defb0e31 Alexander Graf
static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask)
572 defb0e31 Alexander Graf
{
573 defb0e31 Alexander Graf
    int pos = 24; /* top of the lower half of r1 */
574 defb0e31 Alexander Graf
    uint64_t rmask = 0xff000000ULL;
575 defb0e31 Alexander Graf
    uint8_t val = 0;
576 defb0e31 Alexander Graf
    int ccd = 0;
577 defb0e31 Alexander Graf
    uint32_t cc = 0;
578 defb0e31 Alexander Graf
579 defb0e31 Alexander Graf
    while (mask) {
580 defb0e31 Alexander Graf
        if (mask & 8) {
581 defb0e31 Alexander Graf
            env->regs[r1] &= ~rmask;
582 defb0e31 Alexander Graf
            val = ldub(address);
583 defb0e31 Alexander Graf
            if ((val & 0x80) && !ccd) {
584 defb0e31 Alexander Graf
                cc = 1;
585 defb0e31 Alexander Graf
            }
586 defb0e31 Alexander Graf
            ccd = 1;
587 defb0e31 Alexander Graf
            if (val && cc == 0) {
588 defb0e31 Alexander Graf
                cc = 2;
589 defb0e31 Alexander Graf
            }
590 defb0e31 Alexander Graf
            env->regs[r1] |= (uint64_t)val << pos;
591 defb0e31 Alexander Graf
            address++;
592 defb0e31 Alexander Graf
        }
593 defb0e31 Alexander Graf
        mask = (mask << 1) & 0xf;
594 defb0e31 Alexander Graf
        pos -= 8;
595 defb0e31 Alexander Graf
        rmask >>= 8;
596 defb0e31 Alexander Graf
    }
597 defb0e31 Alexander Graf
598 defb0e31 Alexander Graf
    return cc;
599 defb0e31 Alexander Graf
}
600 defb0e31 Alexander Graf
601 defb0e31 Alexander Graf
/* execute instruction
602 defb0e31 Alexander Graf
   this instruction executes an insn modified with the contents of r1
603 defb0e31 Alexander Graf
   it does not change the executed instruction in memory
604 defb0e31 Alexander Graf
   it does not change the program counter
605 defb0e31 Alexander Graf
   in other words: tricky...
606 defb0e31 Alexander Graf
   currently implemented by interpreting the cases it is most commonly used in
607 defb0e31 Alexander Graf
 */
608 defb0e31 Alexander Graf
uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
609 defb0e31 Alexander Graf
{
610 defb0e31 Alexander Graf
    uint16_t insn = lduw_code(addr);
611 defb0e31 Alexander Graf
    HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __FUNCTION__, v1, addr,
612 defb0e31 Alexander Graf
             insn);
613 defb0e31 Alexander Graf
    if ((insn & 0xf0ff) == 0xd000) {
614 defb0e31 Alexander Graf
        uint32_t l, insn2, b1, b2, d1, d2;
615 defb0e31 Alexander Graf
        l = v1 & 0xff;
616 defb0e31 Alexander Graf
        insn2 = ldl_code(addr + 2);
617 defb0e31 Alexander Graf
        b1 = (insn2 >> 28) & 0xf;
618 defb0e31 Alexander Graf
        b2 = (insn2 >> 12) & 0xf;
619 defb0e31 Alexander Graf
        d1 = (insn2 >> 16) & 0xfff;
620 defb0e31 Alexander Graf
        d2 = insn2 & 0xfff;
621 defb0e31 Alexander Graf
        switch (insn & 0xf00) {
622 defb0e31 Alexander Graf
        case 0x200:
623 defb0e31 Alexander Graf
            helper_mvc(l, get_address(0, b1, d1), get_address(0, b2, d2));
624 defb0e31 Alexander Graf
            break;
625 defb0e31 Alexander Graf
        case 0x500:
626 defb0e31 Alexander Graf
            cc = helper_clc(l, get_address(0, b1, d1), get_address(0, b2, d2));
627 defb0e31 Alexander Graf
            break;
628 defb0e31 Alexander Graf
        case 0x700:
629 defb0e31 Alexander Graf
            cc = helper_xc(l, get_address(0, b1, d1), get_address(0, b2, d2));
630 defb0e31 Alexander Graf
            break;
631 defb0e31 Alexander Graf
        default:
632 defb0e31 Alexander Graf
            goto abort;
633 defb0e31 Alexander Graf
            break;
634 defb0e31 Alexander Graf
        }
635 defb0e31 Alexander Graf
    } else if ((insn & 0xff00) == 0x0a00) {
636 defb0e31 Alexander Graf
        /* supervisor call */
637 defb0e31 Alexander Graf
        HELPER_LOG("%s: svc %ld via execute\n", __FUNCTION__, (insn|v1) & 0xff);
638 defb0e31 Alexander Graf
        env->psw.addr = ret - 4;
639 defb0e31 Alexander Graf
        env->int_svc_code = (insn|v1) & 0xff;
640 defb0e31 Alexander Graf
        env->int_svc_ilc = 4;
641 defb0e31 Alexander Graf
        helper_exception(EXCP_SVC);
642 defb0e31 Alexander Graf
    } else if ((insn & 0xff00) == 0xbf00) {
643 defb0e31 Alexander Graf
        uint32_t insn2, r1, r3, b2, d2;
644 defb0e31 Alexander Graf
        insn2 = ldl_code(addr + 2);
645 defb0e31 Alexander Graf
        r1 = (insn2 >> 20) & 0xf;
646 defb0e31 Alexander Graf
        r3 = (insn2 >> 16) & 0xf;
647 defb0e31 Alexander Graf
        b2 = (insn2 >> 12) & 0xf;
648 defb0e31 Alexander Graf
        d2 = insn2 & 0xfff;
649 defb0e31 Alexander Graf
        cc = helper_icm(r1, get_address(0, b2, d2), r3);
650 defb0e31 Alexander Graf
    } else {
651 defb0e31 Alexander Graf
abort:
652 defb0e31 Alexander Graf
        cpu_abort(env, "EXECUTE on instruction prefix 0x%x not implemented\n",
653 defb0e31 Alexander Graf
                  insn);
654 defb0e31 Alexander Graf
    }
655 defb0e31 Alexander Graf
    return cc;
656 defb0e31 Alexander Graf
}
657 defb0e31 Alexander Graf
658 defb0e31 Alexander Graf
/* absolute value 32-bit */
659 defb0e31 Alexander Graf
uint32_t HELPER(abs_i32)(int32_t val)
660 defb0e31 Alexander Graf
{
661 defb0e31 Alexander Graf
    if (val < 0) {
662 defb0e31 Alexander Graf
        return -val;
663 defb0e31 Alexander Graf
    } else {
664 defb0e31 Alexander Graf
        return val;
665 defb0e31 Alexander Graf
    }
666 defb0e31 Alexander Graf
}
667 defb0e31 Alexander Graf
668 defb0e31 Alexander Graf
/* negative absolute value 32-bit */
669 defb0e31 Alexander Graf
int32_t HELPER(nabs_i32)(int32_t val)
670 defb0e31 Alexander Graf
{
671 defb0e31 Alexander Graf
    if (val < 0) {
672 defb0e31 Alexander Graf
        return val;
673 defb0e31 Alexander Graf
    } else {
674 defb0e31 Alexander Graf
        return -val;
675 defb0e31 Alexander Graf
    }
676 defb0e31 Alexander Graf
}
677 defb0e31 Alexander Graf
678 defb0e31 Alexander Graf
/* absolute value 64-bit */
679 defb0e31 Alexander Graf
uint64_t HELPER(abs_i64)(int64_t val)
680 defb0e31 Alexander Graf
{
681 defb0e31 Alexander Graf
    HELPER_LOG("%s: val 0x%" PRIx64 "\n", __FUNCTION__, val);
682 defb0e31 Alexander Graf
683 defb0e31 Alexander Graf
    if (val < 0) {
684 defb0e31 Alexander Graf
        return -val;
685 defb0e31 Alexander Graf
    } else {
686 defb0e31 Alexander Graf
        return val;
687 defb0e31 Alexander Graf
    }
688 defb0e31 Alexander Graf
}
689 defb0e31 Alexander Graf
690 defb0e31 Alexander Graf
/* negative absolute value 64-bit */
691 defb0e31 Alexander Graf
int64_t HELPER(nabs_i64)(int64_t val)
692 defb0e31 Alexander Graf
{
693 defb0e31 Alexander Graf
    if (val < 0) {
694 defb0e31 Alexander Graf
        return val;
695 defb0e31 Alexander Graf
    } else {
696 defb0e31 Alexander Graf
        return -val;
697 defb0e31 Alexander Graf
    }
698 defb0e31 Alexander Graf
}
699 defb0e31 Alexander Graf
700 defb0e31 Alexander Graf
/* add with carry 32-bit unsigned */
701 defb0e31 Alexander Graf
uint32_t HELPER(addc_u32)(uint32_t cc, uint32_t v1, uint32_t v2)
702 defb0e31 Alexander Graf
{
703 defb0e31 Alexander Graf
    uint32_t res;
704 defb0e31 Alexander Graf
705 defb0e31 Alexander Graf
    res = v1 + v2;
706 defb0e31 Alexander Graf
    if (cc & 2) {
707 defb0e31 Alexander Graf
        res++;
708 defb0e31 Alexander Graf
    }
709 defb0e31 Alexander Graf
710 defb0e31 Alexander Graf
    return res;
711 defb0e31 Alexander Graf
}
712 defb0e31 Alexander Graf
713 defb0e31 Alexander Graf
/* store character under mask high operates on the upper half of r1 */
714 defb0e31 Alexander Graf
void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask)
715 defb0e31 Alexander Graf
{
716 defb0e31 Alexander Graf
    int pos = 56; /* top of the upper half of r1 */
717 defb0e31 Alexander Graf
718 defb0e31 Alexander Graf
    while (mask) {
719 defb0e31 Alexander Graf
        if (mask & 8) {
720 defb0e31 Alexander Graf
            stb(address, (env->regs[r1] >> pos) & 0xff);
721 defb0e31 Alexander Graf
            address++;
722 defb0e31 Alexander Graf
        }
723 defb0e31 Alexander Graf
        mask = (mask << 1) & 0xf;
724 defb0e31 Alexander Graf
        pos -= 8;
725 defb0e31 Alexander Graf
    }
726 defb0e31 Alexander Graf
}
727 defb0e31 Alexander Graf
728 defb0e31 Alexander Graf
/* insert character under mask high; same as icm, but operates on the
729 defb0e31 Alexander Graf
   upper half of r1 */
730 defb0e31 Alexander Graf
uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask)
731 defb0e31 Alexander Graf
{
732 defb0e31 Alexander Graf
    int pos = 56; /* top of the upper half of r1 */
733 defb0e31 Alexander Graf
    uint64_t rmask = 0xff00000000000000ULL;
734 defb0e31 Alexander Graf
    uint8_t val = 0;
735 defb0e31 Alexander Graf
    int ccd = 0;
736 defb0e31 Alexander Graf
    uint32_t cc = 0;
737 defb0e31 Alexander Graf
738 defb0e31 Alexander Graf
    while (mask) {
739 defb0e31 Alexander Graf
        if (mask & 8) {
740 defb0e31 Alexander Graf
            env->regs[r1] &= ~rmask;
741 defb0e31 Alexander Graf
            val = ldub(address);
742 defb0e31 Alexander Graf
            if ((val & 0x80) && !ccd) {
743 defb0e31 Alexander Graf
                cc = 1;
744 defb0e31 Alexander Graf
            }
745 defb0e31 Alexander Graf
            ccd = 1;
746 defb0e31 Alexander Graf
            if (val && cc == 0) {
747 defb0e31 Alexander Graf
                cc = 2;
748 defb0e31 Alexander Graf
            }
749 defb0e31 Alexander Graf
            env->regs[r1] |= (uint64_t)val << pos;
750 defb0e31 Alexander Graf
            address++;
751 defb0e31 Alexander Graf
        }
752 defb0e31 Alexander Graf
        mask = (mask << 1) & 0xf;
753 defb0e31 Alexander Graf
        pos -= 8;
754 defb0e31 Alexander Graf
        rmask >>= 8;
755 defb0e31 Alexander Graf
    }
756 defb0e31 Alexander Graf
757 defb0e31 Alexander Graf
    return cc;
758 defb0e31 Alexander Graf
}
759 defb0e31 Alexander Graf
760 defb0e31 Alexander Graf
/* insert psw mask and condition code into r1 */
761 defb0e31 Alexander Graf
void HELPER(ipm)(uint32_t cc, uint32_t r1)
762 defb0e31 Alexander Graf
{
763 defb0e31 Alexander Graf
    uint64_t r = env->regs[r1];
764 defb0e31 Alexander Graf
765 defb0e31 Alexander Graf
    r &= 0xffffffff00ffffffULL;
766 defb0e31 Alexander Graf
    r |= (cc << 28) | ( (env->psw.mask >> 40) & 0xf );
767 defb0e31 Alexander Graf
    env->regs[r1] = r;
768 defb0e31 Alexander Graf
    HELPER_LOG("%s: cc %d psw.mask 0x%lx r1 0x%lx\n", __FUNCTION__,
769 defb0e31 Alexander Graf
               cc, env->psw.mask, r);
770 defb0e31 Alexander Graf
}
771 defb0e31 Alexander Graf
772 defb0e31 Alexander Graf
/* load access registers r1 to r3 from memory at a2 */
773 defb0e31 Alexander Graf
void HELPER(lam)(uint32_t r1, uint64_t a2, uint32_t r3)
774 defb0e31 Alexander Graf
{
775 defb0e31 Alexander Graf
    int i;
776 defb0e31 Alexander Graf
777 defb0e31 Alexander Graf
    for (i = r1;; i = (i + 1) % 16) {
778 defb0e31 Alexander Graf
        env->aregs[i] = ldl(a2);
779 defb0e31 Alexander Graf
        a2 += 4;
780 defb0e31 Alexander Graf
781 defb0e31 Alexander Graf
        if (i == r3) {
782 defb0e31 Alexander Graf
            break;
783 defb0e31 Alexander Graf
        }
784 defb0e31 Alexander Graf
    }
785 defb0e31 Alexander Graf
}
786 defb0e31 Alexander Graf
787 defb0e31 Alexander Graf
/* store access registers r1 to r3 in memory at a2 */
788 defb0e31 Alexander Graf
void HELPER(stam)(uint32_t r1, uint64_t a2, uint32_t r3)
789 defb0e31 Alexander Graf
{
790 defb0e31 Alexander Graf
    int i;
791 defb0e31 Alexander Graf
792 defb0e31 Alexander Graf
    for (i = r1;; i = (i + 1) % 16) {
793 defb0e31 Alexander Graf
        stl(a2, env->aregs[i]);
794 defb0e31 Alexander Graf
        a2 += 4;
795 defb0e31 Alexander Graf
796 defb0e31 Alexander Graf
        if (i == r3) {
797 defb0e31 Alexander Graf
            break;
798 defb0e31 Alexander Graf
        }
799 defb0e31 Alexander Graf
    }
800 defb0e31 Alexander Graf
}
801 defb0e31 Alexander Graf
802 defb0e31 Alexander Graf
/* move long */
803 defb0e31 Alexander Graf
uint32_t HELPER(mvcl)(uint32_t r1, uint32_t r2)
804 defb0e31 Alexander Graf
{
805 defb0e31 Alexander Graf
    uint64_t destlen = env->regs[r1 + 1] & 0xffffff;
806 defb0e31 Alexander Graf
    uint64_t dest = get_address_31fix(r1);
807 defb0e31 Alexander Graf
    uint64_t srclen = env->regs[r2 + 1] & 0xffffff;
808 defb0e31 Alexander Graf
    uint64_t src = get_address_31fix(r2);
809 defb0e31 Alexander Graf
    uint8_t pad = src >> 24;
810 defb0e31 Alexander Graf
    uint8_t v;
811 defb0e31 Alexander Graf
    uint32_t cc;
812 defb0e31 Alexander Graf
813 defb0e31 Alexander Graf
    if (destlen == srclen) {
814 defb0e31 Alexander Graf
        cc = 0;
815 defb0e31 Alexander Graf
    } else if (destlen < srclen) {
816 defb0e31 Alexander Graf
        cc = 1;
817 defb0e31 Alexander Graf
    } else {
818 defb0e31 Alexander Graf
        cc = 2;
819 defb0e31 Alexander Graf
    }
820 defb0e31 Alexander Graf
821 defb0e31 Alexander Graf
    if (srclen > destlen) {
822 defb0e31 Alexander Graf
        srclen = destlen;
823 defb0e31 Alexander Graf
    }
824 defb0e31 Alexander Graf
825 defb0e31 Alexander Graf
    for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
826 defb0e31 Alexander Graf
        v = ldub(src);
827 defb0e31 Alexander Graf
        stb(dest, v);
828 defb0e31 Alexander Graf
    }
829 defb0e31 Alexander Graf
830 defb0e31 Alexander Graf
    for (; destlen; dest++, destlen--) {
831 defb0e31 Alexander Graf
        stb(dest, pad);
832 defb0e31 Alexander Graf
    }
833 defb0e31 Alexander Graf
834 defb0e31 Alexander Graf
    env->regs[r1 + 1] = destlen;
835 defb0e31 Alexander Graf
    /* can't use srclen here, we trunc'ed it */
836 defb0e31 Alexander Graf
    env->regs[r2 + 1] -= src - env->regs[r2];
837 defb0e31 Alexander Graf
    env->regs[r1] = dest;
838 defb0e31 Alexander Graf
    env->regs[r2] = src;
839 defb0e31 Alexander Graf
840 defb0e31 Alexander Graf
    return cc;
841 defb0e31 Alexander Graf
}
842 defb0e31 Alexander Graf
843 defb0e31 Alexander Graf
/* move long extended another memcopy insn with more bells and whistles */
844 defb0e31 Alexander Graf
uint32_t HELPER(mvcle)(uint32_t r1, uint64_t a2, uint32_t r3)
845 defb0e31 Alexander Graf
{
846 defb0e31 Alexander Graf
    uint64_t destlen = env->regs[r1 + 1];
847 defb0e31 Alexander Graf
    uint64_t dest = env->regs[r1];
848 defb0e31 Alexander Graf
    uint64_t srclen = env->regs[r3 + 1];
849 defb0e31 Alexander Graf
    uint64_t src = env->regs[r3];
850 defb0e31 Alexander Graf
    uint8_t pad = a2 & 0xff;
851 defb0e31 Alexander Graf
    uint8_t v;
852 defb0e31 Alexander Graf
    uint32_t cc;
853 defb0e31 Alexander Graf
854 defb0e31 Alexander Graf
    if (!(env->psw.mask & PSW_MASK_64)) {
855 defb0e31 Alexander Graf
        destlen = (uint32_t)destlen;
856 defb0e31 Alexander Graf
        srclen = (uint32_t)srclen;
857 defb0e31 Alexander Graf
        dest &= 0x7fffffff;
858 defb0e31 Alexander Graf
        src &= 0x7fffffff;
859 defb0e31 Alexander Graf
    }
860 defb0e31 Alexander Graf
861 defb0e31 Alexander Graf
    if (destlen == srclen) {
862 defb0e31 Alexander Graf
        cc = 0;
863 defb0e31 Alexander Graf
    } else if (destlen < srclen) {
864 defb0e31 Alexander Graf
        cc = 1;
865 defb0e31 Alexander Graf
    } else {
866 defb0e31 Alexander Graf
        cc = 2;
867 defb0e31 Alexander Graf
    }
868 defb0e31 Alexander Graf
869 defb0e31 Alexander Graf
    if (srclen > destlen) {
870 defb0e31 Alexander Graf
        srclen = destlen;
871 defb0e31 Alexander Graf
    }
872 defb0e31 Alexander Graf
873 defb0e31 Alexander Graf
    for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
874 defb0e31 Alexander Graf
        v = ldub(src);
875 defb0e31 Alexander Graf
        stb(dest, v);
876 defb0e31 Alexander Graf
    }
877 defb0e31 Alexander Graf
878 defb0e31 Alexander Graf
    for (; destlen; dest++, destlen--) {
879 defb0e31 Alexander Graf
        stb(dest, pad);
880 defb0e31 Alexander Graf
    }
881 defb0e31 Alexander Graf
882 defb0e31 Alexander Graf
    env->regs[r1 + 1] = destlen;
883 defb0e31 Alexander Graf
    /* can't use srclen here, we trunc'ed it */
884 defb0e31 Alexander Graf
    /* FIXME: 31-bit mode! */
885 defb0e31 Alexander Graf
    env->regs[r3 + 1] -= src - env->regs[r3];
886 defb0e31 Alexander Graf
    env->regs[r1] = dest;
887 defb0e31 Alexander Graf
    env->regs[r3] = src;
888 defb0e31 Alexander Graf
889 defb0e31 Alexander Graf
    return cc;
890 defb0e31 Alexander Graf
}
891 defb0e31 Alexander Graf
892 defb0e31 Alexander Graf
/* compare logical long extended memcompare insn with padding */
893 defb0e31 Alexander Graf
uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
894 defb0e31 Alexander Graf
{
895 defb0e31 Alexander Graf
    uint64_t destlen = env->regs[r1 + 1];
896 defb0e31 Alexander Graf
    uint64_t dest = get_address_31fix(r1);
897 defb0e31 Alexander Graf
    uint64_t srclen = env->regs[r3 + 1];
898 defb0e31 Alexander Graf
    uint64_t src = get_address_31fix(r3);
899 defb0e31 Alexander Graf
    uint8_t pad = a2 & 0xff;
900 defb0e31 Alexander Graf
    uint8_t v1 = 0,v2 = 0;
901 defb0e31 Alexander Graf
    uint32_t cc = 0;
902 defb0e31 Alexander Graf
903 defb0e31 Alexander Graf
    if (!(destlen || srclen)) {
904 defb0e31 Alexander Graf
        return cc;
905 defb0e31 Alexander Graf
    }
906 defb0e31 Alexander Graf
907 defb0e31 Alexander Graf
    if (srclen > destlen) {
908 defb0e31 Alexander Graf
        srclen = destlen;
909 defb0e31 Alexander Graf
    }
910 defb0e31 Alexander Graf
911 defb0e31 Alexander Graf
    for (; destlen || srclen; src++, dest++, destlen--, srclen--) {
912 defb0e31 Alexander Graf
        v1 = srclen ? ldub(src) : pad;
913 defb0e31 Alexander Graf
        v2 = destlen ? ldub(dest) : pad;
914 defb0e31 Alexander Graf
        if (v1 != v2) {
915 defb0e31 Alexander Graf
            cc = (v1 < v2) ? 1 : 2;
916 defb0e31 Alexander Graf
            break;
917 defb0e31 Alexander Graf
        }
918 defb0e31 Alexander Graf
    }
919 defb0e31 Alexander Graf
920 defb0e31 Alexander Graf
    env->regs[r1 + 1] = destlen;
921 defb0e31 Alexander Graf
    /* can't use srclen here, we trunc'ed it */
922 defb0e31 Alexander Graf
    env->regs[r3 + 1] -= src - env->regs[r3];
923 defb0e31 Alexander Graf
    env->regs[r1] = dest;
924 defb0e31 Alexander Graf
    env->regs[r3] = src;
925 defb0e31 Alexander Graf
926 defb0e31 Alexander Graf
    return cc;
927 defb0e31 Alexander Graf
}
928 defb0e31 Alexander Graf
929 defb0e31 Alexander Graf
/* subtract unsigned v2 from v1 with borrow */
930 defb0e31 Alexander Graf
uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2)
931 defb0e31 Alexander Graf
{
932 defb0e31 Alexander Graf
    uint32_t v1 = env->regs[r1];
933 defb0e31 Alexander Graf
    uint32_t res = v1 + (~v2) + (cc >> 1);
934 defb0e31 Alexander Graf
935 defb0e31 Alexander Graf
    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | res;
936 defb0e31 Alexander Graf
    if (cc & 2) {
937 defb0e31 Alexander Graf
        /* borrow */
938 defb0e31 Alexander Graf
        return v1 ? 1 : 0;
939 defb0e31 Alexander Graf
    } else {
940 defb0e31 Alexander Graf
        return v1 ? 3 : 2;
941 defb0e31 Alexander Graf
    }
942 defb0e31 Alexander Graf
}
943 defb0e31 Alexander Graf
944 defb0e31 Alexander Graf
/* subtract unsigned v2 from v1 with borrow */
945 defb0e31 Alexander Graf
uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
946 defb0e31 Alexander Graf
{
947 defb0e31 Alexander Graf
    uint64_t res = v1 + (~v2) + (cc >> 1);
948 defb0e31 Alexander Graf
949 defb0e31 Alexander Graf
    env->regs[r1] = res;
950 defb0e31 Alexander Graf
    if (cc & 2) {
951 defb0e31 Alexander Graf
        /* borrow */
952 defb0e31 Alexander Graf
        return v1 ? 1 : 0;
953 defb0e31 Alexander Graf
    } else {
954 defb0e31 Alexander Graf
        return v1 ? 3 : 2;
955 defb0e31 Alexander Graf
    }
956 defb0e31 Alexander Graf
}
957 defb0e31 Alexander Graf
958 defb0e31 Alexander Graf
static inline int float_comp_to_cc(int float_compare)
959 defb0e31 Alexander Graf
{
960 defb0e31 Alexander Graf
    switch (float_compare) {
961 defb0e31 Alexander Graf
    case float_relation_equal:
962 defb0e31 Alexander Graf
        return 0;
963 defb0e31 Alexander Graf
    case float_relation_less:
964 defb0e31 Alexander Graf
        return 1;
965 defb0e31 Alexander Graf
    case float_relation_greater:
966 defb0e31 Alexander Graf
        return 2;
967 defb0e31 Alexander Graf
    case float_relation_unordered:
968 defb0e31 Alexander Graf
        return 3;
969 defb0e31 Alexander Graf
    default:
970 defb0e31 Alexander Graf
        cpu_abort(env, "unknown return value for float compare\n");
971 defb0e31 Alexander Graf
    }
972 defb0e31 Alexander Graf
}
973 defb0e31 Alexander Graf
974 defb0e31 Alexander Graf
/* condition codes for binary FP ops */
975 defb0e31 Alexander Graf
static uint32_t set_cc_f32(float32 v1, float32 v2)
976 defb0e31 Alexander Graf
{
977 defb0e31 Alexander Graf
    return float_comp_to_cc(float32_compare_quiet(v1, v2, &env->fpu_status));
978 defb0e31 Alexander Graf
}
979 defb0e31 Alexander Graf
980 defb0e31 Alexander Graf
static uint32_t set_cc_f64(float64 v1, float64 v2)
981 defb0e31 Alexander Graf
{
982 defb0e31 Alexander Graf
    return float_comp_to_cc(float64_compare_quiet(v1, v2, &env->fpu_status));
983 defb0e31 Alexander Graf
}
984 defb0e31 Alexander Graf
985 defb0e31 Alexander Graf
/* condition codes for unary FP ops */
986 defb0e31 Alexander Graf
static uint32_t set_cc_nz_f32(float32 v)
987 defb0e31 Alexander Graf
{
988 defb0e31 Alexander Graf
    if (float32_is_any_nan(v)) {
989 defb0e31 Alexander Graf
        return 3;
990 defb0e31 Alexander Graf
    } else if (float32_is_zero(v)) {
991 defb0e31 Alexander Graf
        return 0;
992 defb0e31 Alexander Graf
    } else if (float32_is_neg(v)) {
993 defb0e31 Alexander Graf
        return 1;
994 defb0e31 Alexander Graf
    } else {
995 defb0e31 Alexander Graf
        return 2;
996 defb0e31 Alexander Graf
    }
997 defb0e31 Alexander Graf
}
998 defb0e31 Alexander Graf
999 defb0e31 Alexander Graf
static uint32_t set_cc_nz_f64(float64 v)
1000 defb0e31 Alexander Graf
{
1001 defb0e31 Alexander Graf
    if (float64_is_any_nan(v)) {
1002 defb0e31 Alexander Graf
        return 3;
1003 defb0e31 Alexander Graf
    } else if (float64_is_zero(v)) {
1004 defb0e31 Alexander Graf
        return 0;
1005 defb0e31 Alexander Graf
    } else if (float64_is_neg(v)) {
1006 defb0e31 Alexander Graf
        return 1;
1007 defb0e31 Alexander Graf
    } else {
1008 defb0e31 Alexander Graf
        return 2;
1009 defb0e31 Alexander Graf
    }
1010 defb0e31 Alexander Graf
}
1011 defb0e31 Alexander Graf
1012 defb0e31 Alexander Graf
static uint32_t set_cc_nz_f128(float128 v)
1013 defb0e31 Alexander Graf
{
1014 defb0e31 Alexander Graf
    if (float128_is_any_nan(v)) {
1015 defb0e31 Alexander Graf
        return 3;
1016 defb0e31 Alexander Graf
    } else if (float128_is_zero(v)) {
1017 defb0e31 Alexander Graf
        return 0;
1018 defb0e31 Alexander Graf
    } else if (float128_is_neg(v)) {
1019 defb0e31 Alexander Graf
        return 1;
1020 defb0e31 Alexander Graf
    } else {
1021 defb0e31 Alexander Graf
        return 2;
1022 defb0e31 Alexander Graf
    }
1023 defb0e31 Alexander Graf
}
1024 defb0e31 Alexander Graf
1025 defb0e31 Alexander Graf
/* convert 32-bit int to 64-bit float */
1026 defb0e31 Alexander Graf
void HELPER(cdfbr)(uint32_t f1, int32_t v2)
1027 defb0e31 Alexander Graf
{
1028 defb0e31 Alexander Graf
    HELPER_LOG("%s: converting %d to f%d\n", __FUNCTION__, v2, f1);
1029 defb0e31 Alexander Graf
    env->fregs[f1].d = int32_to_float64(v2, &env->fpu_status);
1030 defb0e31 Alexander Graf
}
1031 defb0e31 Alexander Graf
1032 defb0e31 Alexander Graf
/* convert 32-bit int to 128-bit float */
1033 defb0e31 Alexander Graf
void HELPER(cxfbr)(uint32_t f1, int32_t v2)
1034 defb0e31 Alexander Graf
{
1035 defb0e31 Alexander Graf
    CPU_QuadU v1;
1036 defb0e31 Alexander Graf
    v1.q = int32_to_float128(v2, &env->fpu_status);
1037 defb0e31 Alexander Graf
    env->fregs[f1].ll = v1.ll.upper;
1038 defb0e31 Alexander Graf
    env->fregs[f1 + 2].ll = v1.ll.lower;
1039 defb0e31 Alexander Graf
}
1040 defb0e31 Alexander Graf
1041 defb0e31 Alexander Graf
/* convert 64-bit int to 32-bit float */
1042 defb0e31 Alexander Graf
void HELPER(cegbr)(uint32_t f1, int64_t v2)
1043 defb0e31 Alexander Graf
{
1044 defb0e31 Alexander Graf
    HELPER_LOG("%s: converting %ld to f%d\n", __FUNCTION__, v2, f1);
1045 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = int64_to_float32(v2, &env->fpu_status);
1046 defb0e31 Alexander Graf
}
1047 defb0e31 Alexander Graf
1048 defb0e31 Alexander Graf
/* convert 64-bit int to 64-bit float */
1049 defb0e31 Alexander Graf
void HELPER(cdgbr)(uint32_t f1, int64_t v2)
1050 defb0e31 Alexander Graf
{
1051 defb0e31 Alexander Graf
    HELPER_LOG("%s: converting %ld to f%d\n", __FUNCTION__, v2, f1);
1052 defb0e31 Alexander Graf
    env->fregs[f1].d = int64_to_float64(v2, &env->fpu_status);
1053 defb0e31 Alexander Graf
}
1054 defb0e31 Alexander Graf
1055 defb0e31 Alexander Graf
/* convert 64-bit int to 128-bit float */
1056 defb0e31 Alexander Graf
void HELPER(cxgbr)(uint32_t f1, int64_t v2)
1057 defb0e31 Alexander Graf
{
1058 defb0e31 Alexander Graf
    CPU_QuadU x1;
1059 defb0e31 Alexander Graf
    x1.q = int64_to_float128(v2, &env->fpu_status);
1060 defb0e31 Alexander Graf
    HELPER_LOG("%s: converted %ld to 0x%lx and 0x%lx\n", __FUNCTION__, v2,
1061 defb0e31 Alexander Graf
               x1.ll.upper, x1.ll.lower);
1062 defb0e31 Alexander Graf
    env->fregs[f1].ll = x1.ll.upper;
1063 defb0e31 Alexander Graf
    env->fregs[f1 + 2].ll = x1.ll.lower;
1064 defb0e31 Alexander Graf
}
1065 defb0e31 Alexander Graf
1066 defb0e31 Alexander Graf
/* convert 32-bit int to 32-bit float */
1067 defb0e31 Alexander Graf
void HELPER(cefbr)(uint32_t f1, int32_t v2)
1068 defb0e31 Alexander Graf
{
1069 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = int32_to_float32(v2, &env->fpu_status);
1070 defb0e31 Alexander Graf
    HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __FUNCTION__, v2,
1071 defb0e31 Alexander Graf
               env->fregs[f1].l.upper, f1);
1072 defb0e31 Alexander Graf
}
1073 defb0e31 Alexander Graf
1074 defb0e31 Alexander Graf
/* 32-bit FP addition RR */
1075 defb0e31 Alexander Graf
uint32_t HELPER(aebr)(uint32_t f1, uint32_t f2)
1076 defb0e31 Alexander Graf
{
1077 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
1078 defb0e31 Alexander Graf
                                         env->fregs[f2].l.upper,
1079 defb0e31 Alexander Graf
                                         &env->fpu_status);
1080 defb0e31 Alexander Graf
    HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __FUNCTION__,
1081 defb0e31 Alexander Graf
               env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1);
1082 defb0e31 Alexander Graf
1083 defb0e31 Alexander Graf
    return set_cc_nz_f32(env->fregs[f1].l.upper);
1084 defb0e31 Alexander Graf
}
1085 defb0e31 Alexander Graf
1086 defb0e31 Alexander Graf
/* 64-bit FP addition RR */
1087 defb0e31 Alexander Graf
uint32_t HELPER(adbr)(uint32_t f1, uint32_t f2)
1088 defb0e31 Alexander Graf
{
1089 defb0e31 Alexander Graf
    env->fregs[f1].d = float64_add(env->fregs[f1].d, env->fregs[f2].d,
1090 defb0e31 Alexander Graf
                                   &env->fpu_status);
1091 defb0e31 Alexander Graf
    HELPER_LOG("%s: adding 0x%ld resulting in 0x%ld in f%d\n", __FUNCTION__,
1092 defb0e31 Alexander Graf
               env->fregs[f2].d, env->fregs[f1].d, f1);
1093 defb0e31 Alexander Graf
1094 defb0e31 Alexander Graf
    return set_cc_nz_f64(env->fregs[f1].d);
1095 defb0e31 Alexander Graf
}
1096 defb0e31 Alexander Graf
1097 defb0e31 Alexander Graf
/* 32-bit FP subtraction RR */
1098 defb0e31 Alexander Graf
uint32_t HELPER(sebr)(uint32_t f1, uint32_t f2)
1099 defb0e31 Alexander Graf
{
1100 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = float32_sub(env->fregs[f1].l.upper,
1101 defb0e31 Alexander Graf
                                         env->fregs[f2].l.upper,
1102 defb0e31 Alexander Graf
                                         &env->fpu_status);
1103 defb0e31 Alexander Graf
    HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __FUNCTION__,
1104 defb0e31 Alexander Graf
               env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1);
1105 defb0e31 Alexander Graf
1106 defb0e31 Alexander Graf
    return set_cc_nz_f32(env->fregs[f1].l.upper);
1107 defb0e31 Alexander Graf
}
1108 defb0e31 Alexander Graf
1109 defb0e31 Alexander Graf
/* 64-bit FP subtraction RR */
1110 defb0e31 Alexander Graf
uint32_t HELPER(sdbr)(uint32_t f1, uint32_t f2)
1111 defb0e31 Alexander Graf
{
1112 defb0e31 Alexander Graf
    env->fregs[f1].d = float64_sub(env->fregs[f1].d, env->fregs[f2].d,
1113 defb0e31 Alexander Graf
                                   &env->fpu_status);
1114 defb0e31 Alexander Graf
    HELPER_LOG("%s: subtracting 0x%ld resulting in 0x%ld in f%d\n",
1115 defb0e31 Alexander Graf
               __FUNCTION__, env->fregs[f2].d, env->fregs[f1].d, f1);
1116 defb0e31 Alexander Graf
1117 defb0e31 Alexander Graf
    return set_cc_nz_f64(env->fregs[f1].d);
1118 defb0e31 Alexander Graf
}
1119 defb0e31 Alexander Graf
1120 defb0e31 Alexander Graf
/* 32-bit FP division RR */
1121 defb0e31 Alexander Graf
void HELPER(debr)(uint32_t f1, uint32_t f2)
1122 defb0e31 Alexander Graf
{
1123 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = float32_div(env->fregs[f1].l.upper,
1124 defb0e31 Alexander Graf
                                         env->fregs[f2].l.upper,
1125 defb0e31 Alexander Graf
                                         &env->fpu_status);
1126 defb0e31 Alexander Graf
}
1127 defb0e31 Alexander Graf
1128 defb0e31 Alexander Graf
/* 128-bit FP division RR */
1129 defb0e31 Alexander Graf
void HELPER(dxbr)(uint32_t f1, uint32_t f2)
1130 defb0e31 Alexander Graf
{
1131 defb0e31 Alexander Graf
    CPU_QuadU v1;
1132 defb0e31 Alexander Graf
    v1.ll.upper = env->fregs[f1].ll;
1133 defb0e31 Alexander Graf
    v1.ll.lower = env->fregs[f1 + 2].ll;
1134 defb0e31 Alexander Graf
    CPU_QuadU v2;
1135 defb0e31 Alexander Graf
    v2.ll.upper = env->fregs[f2].ll;
1136 defb0e31 Alexander Graf
    v2.ll.lower = env->fregs[f2 + 2].ll;
1137 defb0e31 Alexander Graf
    CPU_QuadU res;
1138 defb0e31 Alexander Graf
    res.q = float128_div(v1.q, v2.q, &env->fpu_status);
1139 defb0e31 Alexander Graf
    env->fregs[f1].ll = res.ll.upper;
1140 defb0e31 Alexander Graf
    env->fregs[f1 + 2].ll = res.ll.lower;
1141 defb0e31 Alexander Graf
}
1142 defb0e31 Alexander Graf
1143 defb0e31 Alexander Graf
/* 64-bit FP multiplication RR */
1144 defb0e31 Alexander Graf
void HELPER(mdbr)(uint32_t f1, uint32_t f2)
1145 defb0e31 Alexander Graf
{
1146 defb0e31 Alexander Graf
    env->fregs[f1].d = float64_mul(env->fregs[f1].d, env->fregs[f2].d,
1147 defb0e31 Alexander Graf
                                   &env->fpu_status);
1148 defb0e31 Alexander Graf
}
1149 defb0e31 Alexander Graf
1150 defb0e31 Alexander Graf
/* 128-bit FP multiplication RR */
1151 defb0e31 Alexander Graf
void HELPER(mxbr)(uint32_t f1, uint32_t f2)
1152 defb0e31 Alexander Graf
{
1153 defb0e31 Alexander Graf
    CPU_QuadU v1;
1154 defb0e31 Alexander Graf
    v1.ll.upper = env->fregs[f1].ll;
1155 defb0e31 Alexander Graf
    v1.ll.lower = env->fregs[f1 + 2].ll;
1156 defb0e31 Alexander Graf
    CPU_QuadU v2;
1157 defb0e31 Alexander Graf
    v2.ll.upper = env->fregs[f2].ll;
1158 defb0e31 Alexander Graf
    v2.ll.lower = env->fregs[f2 + 2].ll;
1159 defb0e31 Alexander Graf
    CPU_QuadU res;
1160 defb0e31 Alexander Graf
    res.q = float128_mul(v1.q, v2.q, &env->fpu_status);
1161 defb0e31 Alexander Graf
    env->fregs[f1].ll = res.ll.upper;
1162 defb0e31 Alexander Graf
    env->fregs[f1 + 2].ll = res.ll.lower;
1163 defb0e31 Alexander Graf
}
1164 defb0e31 Alexander Graf
1165 defb0e31 Alexander Graf
/* convert 32-bit float to 64-bit float */
1166 defb0e31 Alexander Graf
void HELPER(ldebr)(uint32_t r1, uint32_t r2)
1167 defb0e31 Alexander Graf
{
1168 defb0e31 Alexander Graf
    env->fregs[r1].d = float32_to_float64(env->fregs[r2].l.upper,
1169 defb0e31 Alexander Graf
                                          &env->fpu_status);
1170 defb0e31 Alexander Graf
}
1171 defb0e31 Alexander Graf
1172 defb0e31 Alexander Graf
/* convert 128-bit float to 64-bit float */
1173 defb0e31 Alexander Graf
void HELPER(ldxbr)(uint32_t f1, uint32_t f2)
1174 defb0e31 Alexander Graf
{
1175 defb0e31 Alexander Graf
    CPU_QuadU x2;
1176 defb0e31 Alexander Graf
    x2.ll.upper = env->fregs[f2].ll;
1177 defb0e31 Alexander Graf
    x2.ll.lower = env->fregs[f2 + 2].ll;
1178 defb0e31 Alexander Graf
    env->fregs[f1].d = float128_to_float64(x2.q, &env->fpu_status);
1179 defb0e31 Alexander Graf
    HELPER_LOG("%s: to 0x%ld\n", __FUNCTION__, env->fregs[f1].d);
1180 defb0e31 Alexander Graf
}
1181 defb0e31 Alexander Graf
1182 defb0e31 Alexander Graf
/* convert 64-bit float to 128-bit float */
1183 defb0e31 Alexander Graf
void HELPER(lxdbr)(uint32_t f1, uint32_t f2)
1184 defb0e31 Alexander Graf
{
1185 defb0e31 Alexander Graf
    CPU_QuadU res;
1186 defb0e31 Alexander Graf
    res.q = float64_to_float128(env->fregs[f2].d, &env->fpu_status);
1187 defb0e31 Alexander Graf
    env->fregs[f1].ll = res.ll.upper;
1188 defb0e31 Alexander Graf
    env->fregs[f1 + 2].ll = res.ll.lower;
1189 defb0e31 Alexander Graf
}
1190 defb0e31 Alexander Graf
1191 defb0e31 Alexander Graf
/* convert 64-bit float to 32-bit float */
1192 defb0e31 Alexander Graf
void HELPER(ledbr)(uint32_t f1, uint32_t f2)
1193 defb0e31 Alexander Graf
{
1194 defb0e31 Alexander Graf
    float64 d2 = env->fregs[f2].d;
1195 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = float64_to_float32(d2, &env->fpu_status);
1196 defb0e31 Alexander Graf
}
1197 defb0e31 Alexander Graf
1198 defb0e31 Alexander Graf
/* convert 128-bit float to 32-bit float */
1199 defb0e31 Alexander Graf
void HELPER(lexbr)(uint32_t f1, uint32_t f2)
1200 defb0e31 Alexander Graf
{
1201 defb0e31 Alexander Graf
    CPU_QuadU x2;
1202 defb0e31 Alexander Graf
    x2.ll.upper = env->fregs[f2].ll;
1203 defb0e31 Alexander Graf
    x2.ll.lower = env->fregs[f2 + 2].ll;
1204 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = float128_to_float32(x2.q, &env->fpu_status);
1205 defb0e31 Alexander Graf
    HELPER_LOG("%s: to 0x%d\n", __FUNCTION__, env->fregs[f1].l.upper);
1206 defb0e31 Alexander Graf
}
1207 defb0e31 Alexander Graf
1208 defb0e31 Alexander Graf
/* absolute value of 32-bit float */
1209 defb0e31 Alexander Graf
uint32_t HELPER(lpebr)(uint32_t f1, uint32_t f2)
1210 defb0e31 Alexander Graf
{
1211 defb0e31 Alexander Graf
    float32 v1;
1212 defb0e31 Alexander Graf
    float32 v2 = env->fregs[f2].d;
1213 defb0e31 Alexander Graf
    v1 = float32_abs(v2);
1214 defb0e31 Alexander Graf
    env->fregs[f1].d = v1;
1215 defb0e31 Alexander Graf
    return set_cc_nz_f32(v1);
1216 defb0e31 Alexander Graf
}
1217 defb0e31 Alexander Graf
1218 defb0e31 Alexander Graf
/* absolute value of 64-bit float */
1219 defb0e31 Alexander Graf
uint32_t HELPER(lpdbr)(uint32_t f1, uint32_t f2)
1220 defb0e31 Alexander Graf
{
1221 defb0e31 Alexander Graf
    float64 v1;
1222 defb0e31 Alexander Graf
    float64 v2 = env->fregs[f2].d;
1223 defb0e31 Alexander Graf
    v1 = float64_abs(v2);
1224 defb0e31 Alexander Graf
    env->fregs[f1].d = v1;
1225 defb0e31 Alexander Graf
    return set_cc_nz_f64(v1);
1226 defb0e31 Alexander Graf
}
1227 defb0e31 Alexander Graf
1228 defb0e31 Alexander Graf
/* absolute value of 128-bit float */
1229 defb0e31 Alexander Graf
uint32_t HELPER(lpxbr)(uint32_t f1, uint32_t f2)
1230 defb0e31 Alexander Graf
{
1231 defb0e31 Alexander Graf
    CPU_QuadU v1;
1232 defb0e31 Alexander Graf
    CPU_QuadU v2;
1233 defb0e31 Alexander Graf
    v2.ll.upper = env->fregs[f2].ll;
1234 defb0e31 Alexander Graf
    v2.ll.lower = env->fregs[f2 + 2].ll;
1235 defb0e31 Alexander Graf
    v1.q = float128_abs(v2.q);
1236 defb0e31 Alexander Graf
    env->fregs[f1].ll = v1.ll.upper;
1237 defb0e31 Alexander Graf
    env->fregs[f1 + 2].ll = v1.ll.lower;
1238 defb0e31 Alexander Graf
    return set_cc_nz_f128(v1.q);
1239 defb0e31 Alexander Graf
}
1240 defb0e31 Alexander Graf
1241 defb0e31 Alexander Graf
/* load and test 64-bit float */
1242 defb0e31 Alexander Graf
uint32_t HELPER(ltdbr)(uint32_t f1, uint32_t f2)
1243 defb0e31 Alexander Graf
{
1244 defb0e31 Alexander Graf
    env->fregs[f1].d = env->fregs[f2].d;
1245 defb0e31 Alexander Graf
    return set_cc_nz_f64(env->fregs[f1].d);
1246 defb0e31 Alexander Graf
}
1247 defb0e31 Alexander Graf
1248 defb0e31 Alexander Graf
/* load and test 32-bit float */
1249 defb0e31 Alexander Graf
uint32_t HELPER(ltebr)(uint32_t f1, uint32_t f2)
1250 defb0e31 Alexander Graf
{
1251 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = env->fregs[f2].l.upper;
1252 defb0e31 Alexander Graf
    return set_cc_nz_f32(env->fregs[f1].l.upper);
1253 defb0e31 Alexander Graf
}
1254 defb0e31 Alexander Graf
1255 defb0e31 Alexander Graf
/* load and test 128-bit float */
1256 defb0e31 Alexander Graf
uint32_t HELPER(ltxbr)(uint32_t f1, uint32_t f2)
1257 defb0e31 Alexander Graf
{
1258 defb0e31 Alexander Graf
    CPU_QuadU x;
1259 defb0e31 Alexander Graf
    x.ll.upper = env->fregs[f2].ll;
1260 defb0e31 Alexander Graf
    x.ll.lower = env->fregs[f2 + 2].ll;
1261 defb0e31 Alexander Graf
    env->fregs[f1].ll = x.ll.upper;
1262 defb0e31 Alexander Graf
    env->fregs[f1 + 2].ll = x.ll.lower;
1263 defb0e31 Alexander Graf
    return set_cc_nz_f128(x.q);
1264 defb0e31 Alexander Graf
}
1265 defb0e31 Alexander Graf
1266 defb0e31 Alexander Graf
/* load complement of 32-bit float */
1267 defb0e31 Alexander Graf
uint32_t HELPER(lcebr)(uint32_t f1, uint32_t f2)
1268 defb0e31 Alexander Graf
{
1269 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = float32_chs(env->fregs[f2].l.upper);
1270 defb0e31 Alexander Graf
1271 defb0e31 Alexander Graf
    return set_cc_nz_f32(env->fregs[f1].l.upper);
1272 defb0e31 Alexander Graf
}
1273 defb0e31 Alexander Graf
1274 defb0e31 Alexander Graf
/* load complement of 64-bit float */
1275 defb0e31 Alexander Graf
uint32_t HELPER(lcdbr)(uint32_t f1, uint32_t f2)
1276 defb0e31 Alexander Graf
{
1277 defb0e31 Alexander Graf
    env->fregs[f1].d = float64_chs(env->fregs[f2].d);
1278 defb0e31 Alexander Graf
1279 defb0e31 Alexander Graf
    return set_cc_nz_f64(env->fregs[f1].d);
1280 defb0e31 Alexander Graf
}
1281 defb0e31 Alexander Graf
1282 defb0e31 Alexander Graf
/* load complement of 128-bit float */
1283 defb0e31 Alexander Graf
uint32_t HELPER(lcxbr)(uint32_t f1, uint32_t f2)
1284 defb0e31 Alexander Graf
{
1285 defb0e31 Alexander Graf
    CPU_QuadU x1, x2;
1286 defb0e31 Alexander Graf
    x2.ll.upper = env->fregs[f2].ll;
1287 defb0e31 Alexander Graf
    x2.ll.lower = env->fregs[f2 + 2].ll;
1288 defb0e31 Alexander Graf
    x1.q = float128_chs(x2.q);
1289 defb0e31 Alexander Graf
    env->fregs[f1].ll = x1.ll.upper;
1290 defb0e31 Alexander Graf
    env->fregs[f1 + 2].ll = x1.ll.lower;
1291 defb0e31 Alexander Graf
    return set_cc_nz_f128(x1.q);
1292 defb0e31 Alexander Graf
}
1293 defb0e31 Alexander Graf
1294 defb0e31 Alexander Graf
/* 32-bit FP addition RM */
1295 defb0e31 Alexander Graf
void HELPER(aeb)(uint32_t f1, uint32_t val)
1296 defb0e31 Alexander Graf
{
1297 defb0e31 Alexander Graf
    float32 v1 = env->fregs[f1].l.upper;
1298 defb0e31 Alexander Graf
    CPU_FloatU v2;
1299 defb0e31 Alexander Graf
    v2.l = val;
1300 defb0e31 Alexander Graf
    HELPER_LOG("%s: adding 0x%d from f%d and 0x%d\n", __FUNCTION__,
1301 defb0e31 Alexander Graf
               v1, f1, v2.f);
1302 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = float32_add(v1, v2.f, &env->fpu_status);
1303 defb0e31 Alexander Graf
}
1304 defb0e31 Alexander Graf
1305 defb0e31 Alexander Graf
/* 32-bit FP division RM */
1306 defb0e31 Alexander Graf
void HELPER(deb)(uint32_t f1, uint32_t val)
1307 defb0e31 Alexander Graf
{
1308 defb0e31 Alexander Graf
    float32 v1 = env->fregs[f1].l.upper;
1309 defb0e31 Alexander Graf
    CPU_FloatU v2;
1310 defb0e31 Alexander Graf
    v2.l = val;
1311 defb0e31 Alexander Graf
    HELPER_LOG("%s: dividing 0x%d from f%d by 0x%d\n", __FUNCTION__,
1312 defb0e31 Alexander Graf
               v1, f1, v2.f);
1313 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = float32_div(v1, v2.f, &env->fpu_status);
1314 defb0e31 Alexander Graf
}
1315 defb0e31 Alexander Graf
1316 defb0e31 Alexander Graf
/* 32-bit FP multiplication RM */
1317 defb0e31 Alexander Graf
void HELPER(meeb)(uint32_t f1, uint32_t val)
1318 defb0e31 Alexander Graf
{
1319 defb0e31 Alexander Graf
    float32 v1 = env->fregs[f1].l.upper;
1320 defb0e31 Alexander Graf
    CPU_FloatU v2;
1321 defb0e31 Alexander Graf
    v2.l = val;
1322 defb0e31 Alexander Graf
    HELPER_LOG("%s: multiplying 0x%d from f%d and 0x%d\n", __FUNCTION__,
1323 defb0e31 Alexander Graf
               v1, f1, v2.f);
1324 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = float32_mul(v1, v2.f, &env->fpu_status);
1325 defb0e31 Alexander Graf
}
1326 defb0e31 Alexander Graf
1327 defb0e31 Alexander Graf
/* 32-bit FP compare RR */
1328 defb0e31 Alexander Graf
uint32_t HELPER(cebr)(uint32_t f1, uint32_t f2)
1329 defb0e31 Alexander Graf
{
1330 defb0e31 Alexander Graf
    float32 v1 = env->fregs[f1].l.upper;
1331 defb0e31 Alexander Graf
    float32 v2 = env->fregs[f2].l.upper;;
1332 defb0e31 Alexander Graf
    HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __FUNCTION__,
1333 defb0e31 Alexander Graf
               v1, f1, v2);
1334 defb0e31 Alexander Graf
    return set_cc_f32(v1, v2);
1335 defb0e31 Alexander Graf
}
1336 defb0e31 Alexander Graf
1337 defb0e31 Alexander Graf
/* 64-bit FP compare RR */
1338 defb0e31 Alexander Graf
uint32_t HELPER(cdbr)(uint32_t f1, uint32_t f2)
1339 defb0e31 Alexander Graf
{
1340 defb0e31 Alexander Graf
    float64 v1 = env->fregs[f1].d;
1341 defb0e31 Alexander Graf
    float64 v2 = env->fregs[f2].d;;
1342 defb0e31 Alexander Graf
    HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%ld\n", __FUNCTION__,
1343 defb0e31 Alexander Graf
               v1, f1, v2);
1344 defb0e31 Alexander Graf
    return set_cc_f64(v1, v2);
1345 defb0e31 Alexander Graf
}
1346 defb0e31 Alexander Graf
1347 defb0e31 Alexander Graf
/* 128-bit FP compare RR */
1348 defb0e31 Alexander Graf
uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2)
1349 defb0e31 Alexander Graf
{
1350 defb0e31 Alexander Graf
    CPU_QuadU v1;
1351 defb0e31 Alexander Graf
    v1.ll.upper = env->fregs[f1].ll;
1352 defb0e31 Alexander Graf
    v1.ll.lower = env->fregs[f1 + 2].ll;
1353 defb0e31 Alexander Graf
    CPU_QuadU v2;
1354 defb0e31 Alexander Graf
    v2.ll.upper = env->fregs[f2].ll;
1355 defb0e31 Alexander Graf
    v2.ll.lower = env->fregs[f2 + 2].ll;
1356 defb0e31 Alexander Graf
1357 defb0e31 Alexander Graf
    return float_comp_to_cc(float128_compare_quiet(v1.q, v2.q,
1358 defb0e31 Alexander Graf
                            &env->fpu_status));
1359 defb0e31 Alexander Graf
}
1360 defb0e31 Alexander Graf
1361 defb0e31 Alexander Graf
/* 64-bit FP compare RM */
1362 defb0e31 Alexander Graf
uint32_t HELPER(cdb)(uint32_t f1, uint64_t a2)
1363 defb0e31 Alexander Graf
{
1364 defb0e31 Alexander Graf
    float64 v1 = env->fregs[f1].d;
1365 defb0e31 Alexander Graf
    CPU_DoubleU v2;
1366 defb0e31 Alexander Graf
    v2.ll = ldq(a2);
1367 defb0e31 Alexander Graf
    HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%lx\n", __FUNCTION__, v1,
1368 defb0e31 Alexander Graf
               f1, v2.d);
1369 defb0e31 Alexander Graf
    return set_cc_f64(v1, v2.d);
1370 defb0e31 Alexander Graf
}
1371 defb0e31 Alexander Graf
1372 defb0e31 Alexander Graf
/* 64-bit FP addition RM */
1373 defb0e31 Alexander Graf
uint32_t HELPER(adb)(uint32_t f1, uint64_t a2)
1374 defb0e31 Alexander Graf
{
1375 defb0e31 Alexander Graf
    float64 v1 = env->fregs[f1].d;
1376 defb0e31 Alexander Graf
    CPU_DoubleU v2;
1377 defb0e31 Alexander Graf
    v2.ll = ldq(a2);
1378 defb0e31 Alexander Graf
    HELPER_LOG("%s: adding 0x%lx from f%d and 0x%lx\n", __FUNCTION__,
1379 defb0e31 Alexander Graf
               v1, f1, v2.d);
1380 defb0e31 Alexander Graf
    env->fregs[f1].d = v1 = float64_add(v1, v2.d, &env->fpu_status);
1381 defb0e31 Alexander Graf
    return set_cc_nz_f64(v1);
1382 defb0e31 Alexander Graf
}
1383 defb0e31 Alexander Graf
1384 defb0e31 Alexander Graf
/* 32-bit FP subtraction RM */
1385 defb0e31 Alexander Graf
void HELPER(seb)(uint32_t f1, uint32_t val)
1386 defb0e31 Alexander Graf
{
1387 defb0e31 Alexander Graf
    float32 v1 = env->fregs[f1].l.upper;
1388 defb0e31 Alexander Graf
    CPU_FloatU v2;
1389 defb0e31 Alexander Graf
    v2.l = val;
1390 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = float32_sub(v1, v2.f, &env->fpu_status);
1391 defb0e31 Alexander Graf
}
1392 defb0e31 Alexander Graf
1393 defb0e31 Alexander Graf
/* 64-bit FP subtraction RM */
1394 defb0e31 Alexander Graf
uint32_t HELPER(sdb)(uint32_t f1, uint64_t a2)
1395 defb0e31 Alexander Graf
{
1396 defb0e31 Alexander Graf
    float64 v1 = env->fregs[f1].d;
1397 defb0e31 Alexander Graf
    CPU_DoubleU v2;
1398 defb0e31 Alexander Graf
    v2.ll = ldq(a2);
1399 defb0e31 Alexander Graf
    env->fregs[f1].d = v1 = float64_sub(v1, v2.d, &env->fpu_status);
1400 defb0e31 Alexander Graf
    return set_cc_nz_f64(v1);
1401 defb0e31 Alexander Graf
}
1402 defb0e31 Alexander Graf
1403 defb0e31 Alexander Graf
/* 64-bit FP multiplication RM */
1404 defb0e31 Alexander Graf
void HELPER(mdb)(uint32_t f1, uint64_t a2)
1405 defb0e31 Alexander Graf
{
1406 defb0e31 Alexander Graf
    float64 v1 = env->fregs[f1].d;
1407 defb0e31 Alexander Graf
    CPU_DoubleU v2;
1408 defb0e31 Alexander Graf
    v2.ll = ldq(a2);
1409 defb0e31 Alexander Graf
    HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __FUNCTION__,
1410 defb0e31 Alexander Graf
               v1, f1, v2.d);
1411 defb0e31 Alexander Graf
    env->fregs[f1].d = float64_mul(v1, v2.d, &env->fpu_status);
1412 defb0e31 Alexander Graf
}
1413 defb0e31 Alexander Graf
1414 defb0e31 Alexander Graf
/* 64-bit FP division RM */
1415 defb0e31 Alexander Graf
void HELPER(ddb)(uint32_t f1, uint64_t a2)
1416 defb0e31 Alexander Graf
{
1417 defb0e31 Alexander Graf
    float64 v1 = env->fregs[f1].d;
1418 defb0e31 Alexander Graf
    CPU_DoubleU v2;
1419 defb0e31 Alexander Graf
    v2.ll = ldq(a2);
1420 defb0e31 Alexander Graf
    HELPER_LOG("%s: dividing 0x%lx from f%d by 0x%ld\n", __FUNCTION__,
1421 defb0e31 Alexander Graf
               v1, f1, v2.d);
1422 defb0e31 Alexander Graf
    env->fregs[f1].d = float64_div(v1, v2.d, &env->fpu_status);
1423 defb0e31 Alexander Graf
}
1424 defb0e31 Alexander Graf
1425 defb0e31 Alexander Graf
static void set_round_mode(int m3)
1426 defb0e31 Alexander Graf
{
1427 defb0e31 Alexander Graf
    switch (m3) {
1428 defb0e31 Alexander Graf
    case 0:
1429 defb0e31 Alexander Graf
        /* current mode */
1430 defb0e31 Alexander Graf
        break;
1431 defb0e31 Alexander Graf
    case 1:
1432 defb0e31 Alexander Graf
        /* biased round no nearest */
1433 defb0e31 Alexander Graf
    case 4:
1434 defb0e31 Alexander Graf
        /* round to nearest */
1435 defb0e31 Alexander Graf
        set_float_rounding_mode(float_round_nearest_even, &env->fpu_status);
1436 defb0e31 Alexander Graf
        break;
1437 defb0e31 Alexander Graf
    case 5:
1438 defb0e31 Alexander Graf
        /* round to zero */
1439 defb0e31 Alexander Graf
        set_float_rounding_mode(float_round_to_zero, &env->fpu_status);
1440 defb0e31 Alexander Graf
        break;
1441 defb0e31 Alexander Graf
    case 6:
1442 defb0e31 Alexander Graf
        /* round to +inf */
1443 defb0e31 Alexander Graf
        set_float_rounding_mode(float_round_up, &env->fpu_status);
1444 defb0e31 Alexander Graf
        break;
1445 defb0e31 Alexander Graf
    case 7:
1446 defb0e31 Alexander Graf
        /* round to -inf */
1447 defb0e31 Alexander Graf
        set_float_rounding_mode(float_round_down, &env->fpu_status);
1448 defb0e31 Alexander Graf
        break;
1449 defb0e31 Alexander Graf
    }
1450 defb0e31 Alexander Graf
}
1451 defb0e31 Alexander Graf
1452 defb0e31 Alexander Graf
/* convert 32-bit float to 64-bit int */
1453 defb0e31 Alexander Graf
uint32_t HELPER(cgebr)(uint32_t r1, uint32_t f2, uint32_t m3)
1454 defb0e31 Alexander Graf
{
1455 defb0e31 Alexander Graf
    float32 v2 = env->fregs[f2].l.upper;
1456 defb0e31 Alexander Graf
    set_round_mode(m3);
1457 defb0e31 Alexander Graf
    env->regs[r1] = float32_to_int64(v2, &env->fpu_status);
1458 defb0e31 Alexander Graf
    return set_cc_nz_f32(v2);
1459 defb0e31 Alexander Graf
}
1460 defb0e31 Alexander Graf
1461 defb0e31 Alexander Graf
/* convert 64-bit float to 64-bit int */
1462 defb0e31 Alexander Graf
uint32_t HELPER(cgdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
1463 defb0e31 Alexander Graf
{
1464 defb0e31 Alexander Graf
    float64 v2 = env->fregs[f2].d;
1465 defb0e31 Alexander Graf
    set_round_mode(m3);
1466 defb0e31 Alexander Graf
    env->regs[r1] = float64_to_int64(v2, &env->fpu_status);
1467 defb0e31 Alexander Graf
    return set_cc_nz_f64(v2);
1468 defb0e31 Alexander Graf
}
1469 defb0e31 Alexander Graf
1470 defb0e31 Alexander Graf
/* convert 128-bit float to 64-bit int */
1471 defb0e31 Alexander Graf
uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
1472 defb0e31 Alexander Graf
{
1473 defb0e31 Alexander Graf
    CPU_QuadU v2;
1474 defb0e31 Alexander Graf
    v2.ll.upper = env->fregs[f2].ll;
1475 defb0e31 Alexander Graf
    v2.ll.lower = env->fregs[f2 + 2].ll;
1476 defb0e31 Alexander Graf
    set_round_mode(m3);
1477 defb0e31 Alexander Graf
    env->regs[r1] = float128_to_int64(v2.q, &env->fpu_status);
1478 defb0e31 Alexander Graf
    if (float128_is_any_nan(v2.q)) {
1479 defb0e31 Alexander Graf
        return 3;
1480 defb0e31 Alexander Graf
    } else if (float128_is_zero(v2.q)) {
1481 defb0e31 Alexander Graf
        return 0;
1482 defb0e31 Alexander Graf
    } else if (float128_is_neg(v2.q)) {
1483 defb0e31 Alexander Graf
        return 1;
1484 defb0e31 Alexander Graf
    } else {
1485 defb0e31 Alexander Graf
        return 2;
1486 defb0e31 Alexander Graf
    }
1487 defb0e31 Alexander Graf
}
1488 defb0e31 Alexander Graf
1489 defb0e31 Alexander Graf
/* convert 32-bit float to 32-bit int */
1490 defb0e31 Alexander Graf
uint32_t HELPER(cfebr)(uint32_t r1, uint32_t f2, uint32_t m3)
1491 defb0e31 Alexander Graf
{
1492 defb0e31 Alexander Graf
    float32 v2 = env->fregs[f2].l.upper;
1493 defb0e31 Alexander Graf
    set_round_mode(m3);
1494 defb0e31 Alexander Graf
    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
1495 defb0e31 Alexander Graf
                     float32_to_int32(v2, &env->fpu_status);
1496 defb0e31 Alexander Graf
    return set_cc_nz_f32(v2);
1497 defb0e31 Alexander Graf
}
1498 defb0e31 Alexander Graf
1499 defb0e31 Alexander Graf
/* convert 64-bit float to 32-bit int */
1500 defb0e31 Alexander Graf
uint32_t HELPER(cfdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
1501 defb0e31 Alexander Graf
{
1502 defb0e31 Alexander Graf
    float64 v2 = env->fregs[f2].d;
1503 defb0e31 Alexander Graf
    set_round_mode(m3);
1504 defb0e31 Alexander Graf
    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
1505 defb0e31 Alexander Graf
                     float64_to_int32(v2, &env->fpu_status);
1506 defb0e31 Alexander Graf
    return set_cc_nz_f64(v2);
1507 defb0e31 Alexander Graf
}
1508 defb0e31 Alexander Graf
1509 defb0e31 Alexander Graf
/* convert 128-bit float to 32-bit int */
1510 defb0e31 Alexander Graf
uint32_t HELPER(cfxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
1511 defb0e31 Alexander Graf
{
1512 defb0e31 Alexander Graf
    CPU_QuadU v2;
1513 defb0e31 Alexander Graf
    v2.ll.upper = env->fregs[f2].ll;
1514 defb0e31 Alexander Graf
    v2.ll.lower = env->fregs[f2 + 2].ll;
1515 defb0e31 Alexander Graf
    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
1516 defb0e31 Alexander Graf
                     float128_to_int32(v2.q, &env->fpu_status);
1517 defb0e31 Alexander Graf
    return set_cc_nz_f128(v2.q);
1518 defb0e31 Alexander Graf
}
1519 defb0e31 Alexander Graf
1520 defb0e31 Alexander Graf
/* load 32-bit FP zero */
1521 defb0e31 Alexander Graf
void HELPER(lzer)(uint32_t f1)
1522 defb0e31 Alexander Graf
{
1523 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = float32_zero;
1524 defb0e31 Alexander Graf
}
1525 defb0e31 Alexander Graf
1526 defb0e31 Alexander Graf
/* load 64-bit FP zero */
1527 defb0e31 Alexander Graf
void HELPER(lzdr)(uint32_t f1)
1528 defb0e31 Alexander Graf
{
1529 defb0e31 Alexander Graf
    env->fregs[f1].d = float64_zero;
1530 defb0e31 Alexander Graf
}
1531 defb0e31 Alexander Graf
1532 defb0e31 Alexander Graf
/* load 128-bit FP zero */
1533 defb0e31 Alexander Graf
void HELPER(lzxr)(uint32_t f1)
1534 defb0e31 Alexander Graf
{
1535 defb0e31 Alexander Graf
    CPU_QuadU x;
1536 defb0e31 Alexander Graf
    x.q = float64_to_float128(float64_zero, &env->fpu_status);
1537 defb0e31 Alexander Graf
    env->fregs[f1].ll = x.ll.upper;
1538 defb0e31 Alexander Graf
    env->fregs[f1 + 1].ll = x.ll.lower;
1539 defb0e31 Alexander Graf
}
1540 defb0e31 Alexander Graf
1541 defb0e31 Alexander Graf
/* 128-bit FP subtraction RR */
1542 defb0e31 Alexander Graf
uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2)
1543 defb0e31 Alexander Graf
{
1544 defb0e31 Alexander Graf
    CPU_QuadU v1;
1545 defb0e31 Alexander Graf
    v1.ll.upper = env->fregs[f1].ll;
1546 defb0e31 Alexander Graf
    v1.ll.lower = env->fregs[f1 + 2].ll;
1547 defb0e31 Alexander Graf
    CPU_QuadU v2;
1548 defb0e31 Alexander Graf
    v2.ll.upper = env->fregs[f2].ll;
1549 defb0e31 Alexander Graf
    v2.ll.lower = env->fregs[f2 + 2].ll;
1550 defb0e31 Alexander Graf
    CPU_QuadU res;
1551 defb0e31 Alexander Graf
    res.q = float128_sub(v1.q, v2.q, &env->fpu_status);
1552 defb0e31 Alexander Graf
    env->fregs[f1].ll = res.ll.upper;
1553 defb0e31 Alexander Graf
    env->fregs[f1 + 2].ll = res.ll.lower;
1554 defb0e31 Alexander Graf
    return set_cc_nz_f128(res.q);
1555 defb0e31 Alexander Graf
}
1556 defb0e31 Alexander Graf
1557 defb0e31 Alexander Graf
/* 128-bit FP addition RR */
1558 defb0e31 Alexander Graf
uint32_t HELPER(axbr)(uint32_t f1, uint32_t f2)
1559 defb0e31 Alexander Graf
{
1560 defb0e31 Alexander Graf
    CPU_QuadU v1;
1561 defb0e31 Alexander Graf
    v1.ll.upper = env->fregs[f1].ll;
1562 defb0e31 Alexander Graf
    v1.ll.lower = env->fregs[f1 + 2].ll;
1563 defb0e31 Alexander Graf
    CPU_QuadU v2;
1564 defb0e31 Alexander Graf
    v2.ll.upper = env->fregs[f2].ll;
1565 defb0e31 Alexander Graf
    v2.ll.lower = env->fregs[f2 + 2].ll;
1566 defb0e31 Alexander Graf
    CPU_QuadU res;
1567 defb0e31 Alexander Graf
    res.q = float128_add(v1.q, v2.q, &env->fpu_status);
1568 defb0e31 Alexander Graf
    env->fregs[f1].ll = res.ll.upper;
1569 defb0e31 Alexander Graf
    env->fregs[f1 + 2].ll = res.ll.lower;
1570 defb0e31 Alexander Graf
    return set_cc_nz_f128(res.q);
1571 defb0e31 Alexander Graf
}
1572 defb0e31 Alexander Graf
1573 defb0e31 Alexander Graf
/* 32-bit FP multiplication RR */
1574 defb0e31 Alexander Graf
void HELPER(meebr)(uint32_t f1, uint32_t f2)
1575 defb0e31 Alexander Graf
{
1576 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = float32_mul(env->fregs[f1].l.upper,
1577 defb0e31 Alexander Graf
                                         env->fregs[f2].l.upper,
1578 defb0e31 Alexander Graf
                                         &env->fpu_status);
1579 defb0e31 Alexander Graf
}
1580 defb0e31 Alexander Graf
1581 defb0e31 Alexander Graf
/* 64-bit FP division RR */
1582 defb0e31 Alexander Graf
void HELPER(ddbr)(uint32_t f1, uint32_t f2)
1583 defb0e31 Alexander Graf
{
1584 defb0e31 Alexander Graf
    env->fregs[f1].d = float64_div(env->fregs[f1].d, env->fregs[f2].d,
1585 defb0e31 Alexander Graf
                                   &env->fpu_status);
1586 defb0e31 Alexander Graf
}
1587 defb0e31 Alexander Graf
1588 defb0e31 Alexander Graf
/* 64-bit FP multiply and add RM */
1589 defb0e31 Alexander Graf
void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3)
1590 defb0e31 Alexander Graf
{
1591 defb0e31 Alexander Graf
    HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __FUNCTION__, f1, a2, f3);
1592 defb0e31 Alexander Graf
    CPU_DoubleU v2;
1593 defb0e31 Alexander Graf
    v2.ll = ldq(a2);
1594 defb0e31 Alexander Graf
    env->fregs[f1].d = float64_add(env->fregs[f1].d,
1595 defb0e31 Alexander Graf
                                   float64_mul(v2.d, env->fregs[f3].d,
1596 defb0e31 Alexander Graf
                                               &env->fpu_status),
1597 defb0e31 Alexander Graf
                                   &env->fpu_status);
1598 defb0e31 Alexander Graf
}
1599 defb0e31 Alexander Graf
1600 defb0e31 Alexander Graf
/* 64-bit FP multiply and add RR */
1601 defb0e31 Alexander Graf
void HELPER(madbr)(uint32_t f1, uint32_t f3, uint32_t f2)
1602 defb0e31 Alexander Graf
{
1603 defb0e31 Alexander Graf
    HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __FUNCTION__, f1, f2, f3);
1604 defb0e31 Alexander Graf
    env->fregs[f1].d = float64_add(float64_mul(env->fregs[f2].d,
1605 defb0e31 Alexander Graf
                                               env->fregs[f3].d,
1606 defb0e31 Alexander Graf
                                               &env->fpu_status),
1607 defb0e31 Alexander Graf
                                   env->fregs[f1].d, &env->fpu_status);
1608 defb0e31 Alexander Graf
}
1609 defb0e31 Alexander Graf
1610 defb0e31 Alexander Graf
/* 64-bit FP multiply and subtract RR */
1611 defb0e31 Alexander Graf
void HELPER(msdbr)(uint32_t f1, uint32_t f3, uint32_t f2)
1612 defb0e31 Alexander Graf
{
1613 defb0e31 Alexander Graf
    HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __FUNCTION__, f1, f2, f3);
1614 defb0e31 Alexander Graf
    env->fregs[f1].d = float64_sub(float64_mul(env->fregs[f2].d,
1615 defb0e31 Alexander Graf
                                               env->fregs[f3].d,
1616 defb0e31 Alexander Graf
                                               &env->fpu_status),
1617 defb0e31 Alexander Graf
                                   env->fregs[f1].d, &env->fpu_status);
1618 defb0e31 Alexander Graf
}
1619 defb0e31 Alexander Graf
1620 defb0e31 Alexander Graf
/* 32-bit FP multiply and add RR */
1621 defb0e31 Alexander Graf
void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2)
1622 defb0e31 Alexander Graf
{
1623 defb0e31 Alexander Graf
    env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
1624 defb0e31 Alexander Graf
                                         float32_mul(env->fregs[f2].l.upper,
1625 defb0e31 Alexander Graf
                                                     env->fregs[f3].l.upper,
1626 defb0e31 Alexander Graf
                                                     &env->fpu_status),
1627 defb0e31 Alexander Graf
                                         &env->fpu_status);
1628 defb0e31 Alexander Graf
}
1629 defb0e31 Alexander Graf
1630 defb0e31 Alexander Graf
/* convert 64-bit float to 128-bit float */
1631 defb0e31 Alexander Graf
void HELPER(lxdb)(uint32_t f1, uint64_t a2)
1632 defb0e31 Alexander Graf
{
1633 defb0e31 Alexander Graf
    CPU_DoubleU v2;
1634 defb0e31 Alexander Graf
    v2.ll = ldq(a2);
1635 defb0e31 Alexander Graf
    CPU_QuadU v1;
1636 defb0e31 Alexander Graf
    v1.q = float64_to_float128(v2.d, &env->fpu_status);
1637 defb0e31 Alexander Graf
    env->fregs[f1].ll = v1.ll.upper;
1638 defb0e31 Alexander Graf
    env->fregs[f1 + 2].ll = v1.ll.lower;
1639 defb0e31 Alexander Graf
}
1640 defb0e31 Alexander Graf
1641 defb0e31 Alexander Graf
/* test data class 32-bit */
1642 defb0e31 Alexander Graf
uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2)
1643 defb0e31 Alexander Graf
{
1644 defb0e31 Alexander Graf
    float32 v1 = env->fregs[f1].l.upper;
1645 defb0e31 Alexander Graf
    int neg = float32_is_neg(v1);
1646 defb0e31 Alexander Graf
    uint32_t cc = 0;
1647 defb0e31 Alexander Graf
1648 defb0e31 Alexander Graf
    HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, (long)v1, m2, neg);
1649 defb0e31 Alexander Graf
    if ((float32_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
1650 defb0e31 Alexander Graf
        (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
1651 defb0e31 Alexander Graf
        (float32_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
1652 defb0e31 Alexander Graf
        (float32_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
1653 defb0e31 Alexander Graf
        cc = 1;
1654 defb0e31 Alexander Graf
    } else if (m2 & (1 << (9-neg))) {
1655 defb0e31 Alexander Graf
        /* assume normalized number */
1656 defb0e31 Alexander Graf
        cc = 1;
1657 defb0e31 Alexander Graf
    }
1658 defb0e31 Alexander Graf
1659 defb0e31 Alexander Graf
    /* FIXME: denormalized? */
1660 defb0e31 Alexander Graf
    return cc;
1661 defb0e31 Alexander Graf
}
1662 defb0e31 Alexander Graf
1663 defb0e31 Alexander Graf
/* test data class 64-bit */
1664 defb0e31 Alexander Graf
uint32_t HELPER(tcdb)(uint32_t f1, uint64_t m2)
1665 defb0e31 Alexander Graf
{
1666 defb0e31 Alexander Graf
    float64 v1 = env->fregs[f1].d;
1667 defb0e31 Alexander Graf
    int neg = float64_is_neg(v1);
1668 defb0e31 Alexander Graf
    uint32_t cc = 0;
1669 defb0e31 Alexander Graf
1670 defb0e31 Alexander Graf
    HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, v1, m2, neg);
1671 defb0e31 Alexander Graf
    if ((float64_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
1672 defb0e31 Alexander Graf
        (float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
1673 defb0e31 Alexander Graf
        (float64_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
1674 defb0e31 Alexander Graf
        (float64_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
1675 defb0e31 Alexander Graf
        cc = 1;
1676 defb0e31 Alexander Graf
    } else if (m2 & (1 << (9-neg))) {
1677 defb0e31 Alexander Graf
        /* assume normalized number */
1678 defb0e31 Alexander Graf
        cc = 1;
1679 defb0e31 Alexander Graf
    }
1680 defb0e31 Alexander Graf
    /* FIXME: denormalized? */
1681 defb0e31 Alexander Graf
    return cc;
1682 defb0e31 Alexander Graf
}
1683 defb0e31 Alexander Graf
1684 defb0e31 Alexander Graf
/* test data class 128-bit */
1685 defb0e31 Alexander Graf
uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2)
1686 defb0e31 Alexander Graf
{
1687 defb0e31 Alexander Graf
    CPU_QuadU v1;
1688 defb0e31 Alexander Graf
    uint32_t cc = 0;
1689 defb0e31 Alexander Graf
    v1.ll.upper = env->fregs[f1].ll;
1690 defb0e31 Alexander Graf
    v1.ll.lower = env->fregs[f1 + 2].ll;
1691 defb0e31 Alexander Graf
1692 defb0e31 Alexander Graf
    int neg = float128_is_neg(v1.q);
1693 defb0e31 Alexander Graf
    if ((float128_is_zero(v1.q) && (m2 & (1 << (11-neg)))) ||
1694 defb0e31 Alexander Graf
        (float128_is_infinity(v1.q) && (m2 & (1 << (5-neg)))) ||
1695 defb0e31 Alexander Graf
        (float128_is_any_nan(v1.q) && (m2 & (1 << (3-neg)))) ||
1696 defb0e31 Alexander Graf
        (float128_is_signaling_nan(v1.q) && (m2 & (1 << (1-neg))))) {
1697 defb0e31 Alexander Graf
        cc = 1;
1698 defb0e31 Alexander Graf
    } else if (m2 & (1 << (9-neg))) {
1699 defb0e31 Alexander Graf
        /* assume normalized number */
1700 defb0e31 Alexander Graf
        cc = 1;
1701 defb0e31 Alexander Graf
    }
1702 defb0e31 Alexander Graf
    /* FIXME: denormalized? */
1703 defb0e31 Alexander Graf
    return cc;
1704 defb0e31 Alexander Graf
}
1705 defb0e31 Alexander Graf
1706 defb0e31 Alexander Graf
/* find leftmost one */
1707 defb0e31 Alexander Graf
uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
1708 defb0e31 Alexander Graf
{
1709 defb0e31 Alexander Graf
    uint64_t res = 0;
1710 defb0e31 Alexander Graf
    uint64_t ov2 = v2;
1711 defb0e31 Alexander Graf
1712 defb0e31 Alexander Graf
    while (!(v2 & 0x8000000000000000ULL) && v2) {
1713 defb0e31 Alexander Graf
        v2 <<= 1;
1714 defb0e31 Alexander Graf
        res++;
1715 defb0e31 Alexander Graf
    }
1716 defb0e31 Alexander Graf
1717 defb0e31 Alexander Graf
    if (!v2) {
1718 defb0e31 Alexander Graf
        env->regs[r1] = 64;
1719 defb0e31 Alexander Graf
        env->regs[r1 + 1] = 0;
1720 defb0e31 Alexander Graf
        return 0;
1721 defb0e31 Alexander Graf
    } else {
1722 defb0e31 Alexander Graf
        env->regs[r1] = res;
1723 defb0e31 Alexander Graf
        env->regs[r1 + 1] = ov2 & ~(0x8000000000000000ULL >> res);
1724 defb0e31 Alexander Graf
        return 2;
1725 defb0e31 Alexander Graf
    }
1726 defb0e31 Alexander Graf
}
1727 defb0e31 Alexander Graf
1728 defb0e31 Alexander Graf
/* square root 64-bit RR */
1729 defb0e31 Alexander Graf
void HELPER(sqdbr)(uint32_t f1, uint32_t f2)
1730 defb0e31 Alexander Graf
{
1731 defb0e31 Alexander Graf
    env->fregs[f1].d = float64_sqrt(env->fregs[f2].d, &env->fpu_status);
1732 defb0e31 Alexander Graf
}
1733 defb0e31 Alexander Graf
1734 defb0e31 Alexander Graf
static inline uint64_t cksm_overflow(uint64_t cksm)
1735 defb0e31 Alexander Graf
{
1736 defb0e31 Alexander Graf
    if (cksm > 0xffffffffULL) {
1737 defb0e31 Alexander Graf
        cksm &= 0xffffffffULL;
1738 defb0e31 Alexander Graf
        cksm++;
1739 defb0e31 Alexander Graf
    }
1740 defb0e31 Alexander Graf
    return cksm;
1741 defb0e31 Alexander Graf
}
1742 defb0e31 Alexander Graf
1743 defb0e31 Alexander Graf
/* checksum */
1744 defb0e31 Alexander Graf
void HELPER(cksm)(uint32_t r1, uint32_t r2)
1745 defb0e31 Alexander Graf
{
1746 defb0e31 Alexander Graf
    uint64_t src = get_address_31fix(r2);
1747 defb0e31 Alexander Graf
    uint64_t src_len = env->regs[(r2 + 1) & 15];
1748 defb0e31 Alexander Graf
    uint64_t cksm = 0;
1749 defb0e31 Alexander Graf
1750 defb0e31 Alexander Graf
    while (src_len >= 4) {
1751 defb0e31 Alexander Graf
        cksm += ldl(src);
1752 defb0e31 Alexander Graf
        cksm = cksm_overflow(cksm);
1753 defb0e31 Alexander Graf
1754 defb0e31 Alexander Graf
        /* move to next word */
1755 defb0e31 Alexander Graf
        src_len -= 4;
1756 defb0e31 Alexander Graf
        src += 4;
1757 defb0e31 Alexander Graf
    }
1758 defb0e31 Alexander Graf
1759 defb0e31 Alexander Graf
    switch (src_len) {
1760 defb0e31 Alexander Graf
    case 0:
1761 defb0e31 Alexander Graf
        break;
1762 defb0e31 Alexander Graf
    case 1:
1763 defb0e31 Alexander Graf
        cksm += ldub(src);
1764 defb0e31 Alexander Graf
        cksm = cksm_overflow(cksm);
1765 defb0e31 Alexander Graf
        break;
1766 defb0e31 Alexander Graf
    case 2:
1767 defb0e31 Alexander Graf
        cksm += lduw(src);
1768 defb0e31 Alexander Graf
        cksm = cksm_overflow(cksm);
1769 defb0e31 Alexander Graf
        break;
1770 defb0e31 Alexander Graf
    case 3:
1771 defb0e31 Alexander Graf
        /* XXX check if this really is correct */
1772 defb0e31 Alexander Graf
        cksm += lduw(src) << 8;
1773 defb0e31 Alexander Graf
        cksm += ldub(src + 2);
1774 defb0e31 Alexander Graf
        cksm = cksm_overflow(cksm);
1775 defb0e31 Alexander Graf
        break;
1776 defb0e31 Alexander Graf
    }
1777 defb0e31 Alexander Graf
1778 defb0e31 Alexander Graf
    /* indicate we've processed everything */
1779 defb0e31 Alexander Graf
    env->regs[(r2 + 1) & 15] = 0;
1780 defb0e31 Alexander Graf
1781 defb0e31 Alexander Graf
    /* store result */
1782 defb0e31 Alexander Graf
    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | (uint32_t)cksm;
1783 defb0e31 Alexander Graf
}
1784 defb0e31 Alexander Graf
1785 defb0e31 Alexander Graf
static inline uint32_t cc_calc_ltgt_32(CPUState *env, int32_t src,
1786 defb0e31 Alexander Graf
                                       int32_t dst)
1787 defb0e31 Alexander Graf
{
1788 defb0e31 Alexander Graf
    if (src == dst) {
1789 defb0e31 Alexander Graf
        return 0;
1790 defb0e31 Alexander Graf
    } else if (src < dst) {
1791 defb0e31 Alexander Graf
        return 1;
1792 defb0e31 Alexander Graf
    } else {
1793 defb0e31 Alexander Graf
        return 2;
1794 defb0e31 Alexander Graf
    }
1795 defb0e31 Alexander Graf
}
1796 defb0e31 Alexander Graf
1797 defb0e31 Alexander Graf
static inline uint32_t cc_calc_ltgt0_32(CPUState *env, int32_t dst)
1798 defb0e31 Alexander Graf
{
1799 defb0e31 Alexander Graf
    return cc_calc_ltgt_32(env, dst, 0);
1800 defb0e31 Alexander Graf
}
1801 defb0e31 Alexander Graf
1802 defb0e31 Alexander Graf
static inline uint32_t cc_calc_ltgt_64(CPUState *env, int64_t src,
1803 defb0e31 Alexander Graf
                                       int64_t dst)
1804 defb0e31 Alexander Graf
{
1805 defb0e31 Alexander Graf
    if (src == dst) {
1806 defb0e31 Alexander Graf
        return 0;
1807 defb0e31 Alexander Graf
    } else if (src < dst) {
1808 defb0e31 Alexander Graf
        return 1;
1809 defb0e31 Alexander Graf
    } else {
1810 defb0e31 Alexander Graf
        return 2;
1811 defb0e31 Alexander Graf
    }
1812 defb0e31 Alexander Graf
}
1813 defb0e31 Alexander Graf
1814 defb0e31 Alexander Graf
static inline uint32_t cc_calc_ltgt0_64(CPUState *env, int64_t dst)
1815 defb0e31 Alexander Graf
{
1816 defb0e31 Alexander Graf
    return cc_calc_ltgt_64(env, dst, 0);
1817 defb0e31 Alexander Graf
}
1818 defb0e31 Alexander Graf
1819 defb0e31 Alexander Graf
static inline uint32_t cc_calc_ltugtu_32(CPUState *env, uint32_t src,
1820 defb0e31 Alexander Graf
                                         uint32_t dst)
1821 defb0e31 Alexander Graf
{
1822 defb0e31 Alexander Graf
    if (src == dst) {
1823 defb0e31 Alexander Graf
        return 0;
1824 defb0e31 Alexander Graf
    } else if (src < dst) {
1825 defb0e31 Alexander Graf
        return 1;
1826 defb0e31 Alexander Graf
    } else {
1827 defb0e31 Alexander Graf
        return 2;
1828 defb0e31 Alexander Graf
    }
1829 defb0e31 Alexander Graf
}
1830 defb0e31 Alexander Graf
1831 defb0e31 Alexander Graf
static inline uint32_t cc_calc_ltugtu_64(CPUState *env, uint64_t src,
1832 defb0e31 Alexander Graf
                                         uint64_t dst)
1833 defb0e31 Alexander Graf
{
1834 defb0e31 Alexander Graf
    if (src == dst) {
1835 defb0e31 Alexander Graf
        return 0;
1836 defb0e31 Alexander Graf
    } else if (src < dst) {
1837 defb0e31 Alexander Graf
        return 1;
1838 defb0e31 Alexander Graf
    } else {
1839 defb0e31 Alexander Graf
        return 2;
1840 defb0e31 Alexander Graf
    }
1841 defb0e31 Alexander Graf
}
1842 defb0e31 Alexander Graf
1843 defb0e31 Alexander Graf
static inline uint32_t cc_calc_tm_32(CPUState *env, uint32_t val, uint32_t mask)
1844 defb0e31 Alexander Graf
{
1845 defb0e31 Alexander Graf
    HELPER_LOG("%s: val 0x%x mask 0x%x\n", __FUNCTION__, val, mask);
1846 defb0e31 Alexander Graf
    uint16_t r = val & mask;
1847 defb0e31 Alexander Graf
    if (r == 0 || mask == 0) {
1848 defb0e31 Alexander Graf
        return 0;
1849 defb0e31 Alexander Graf
    } else if (r == mask) {
1850 defb0e31 Alexander Graf
        return 3;
1851 defb0e31 Alexander Graf
    } else {
1852 defb0e31 Alexander Graf
        return 1;
1853 defb0e31 Alexander Graf
    }
1854 defb0e31 Alexander Graf
}
1855 defb0e31 Alexander Graf
1856 defb0e31 Alexander Graf
/* set condition code for test under mask */
1857 defb0e31 Alexander Graf
static inline uint32_t cc_calc_tm_64(CPUState *env, uint64_t val, uint32_t mask)
1858 defb0e31 Alexander Graf
{
1859 defb0e31 Alexander Graf
    uint16_t r = val & mask;
1860 defb0e31 Alexander Graf
    HELPER_LOG("%s: val 0x%lx mask 0x%x r 0x%x\n", __FUNCTION__, val, mask, r);
1861 defb0e31 Alexander Graf
    if (r == 0 || mask == 0) {
1862 defb0e31 Alexander Graf
        return 0;
1863 defb0e31 Alexander Graf
    } else if (r == mask) {
1864 defb0e31 Alexander Graf
        return 3;
1865 defb0e31 Alexander Graf
    } else {
1866 defb0e31 Alexander Graf
        while (!(mask & 0x8000)) {
1867 defb0e31 Alexander Graf
            mask <<= 1;
1868 defb0e31 Alexander Graf
            val <<= 1;
1869 defb0e31 Alexander Graf
        }
1870 defb0e31 Alexander Graf
        if (val & 0x8000) {
1871 defb0e31 Alexander Graf
            return 2;
1872 defb0e31 Alexander Graf
        } else {
1873 defb0e31 Alexander Graf
            return 1;
1874 defb0e31 Alexander Graf
        }
1875 defb0e31 Alexander Graf
    }
1876 defb0e31 Alexander Graf
}
1877 defb0e31 Alexander Graf
1878 defb0e31 Alexander Graf
static inline uint32_t cc_calc_nz(CPUState *env, uint64_t dst)
1879 defb0e31 Alexander Graf
{
1880 defb0e31 Alexander Graf
    return !!dst;
1881 defb0e31 Alexander Graf
}
1882 defb0e31 Alexander Graf
1883 defb0e31 Alexander Graf
static inline uint32_t cc_calc_add_64(CPUState *env, int64_t a1, int64_t a2,
1884 defb0e31 Alexander Graf
                                      int64_t ar)
1885 defb0e31 Alexander Graf
{
1886 defb0e31 Alexander Graf
    if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
1887 defb0e31 Alexander Graf
        return 3; /* overflow */
1888 defb0e31 Alexander Graf
    } else {
1889 defb0e31 Alexander Graf
        if (ar < 0) {
1890 defb0e31 Alexander Graf
            return 1;
1891 defb0e31 Alexander Graf
        } else if (ar > 0) {
1892 defb0e31 Alexander Graf
            return 2;
1893 defb0e31 Alexander Graf
        } else {
1894 defb0e31 Alexander Graf
            return 0;
1895 defb0e31 Alexander Graf
        }
1896 defb0e31 Alexander Graf
    }
1897 defb0e31 Alexander Graf
}
1898 defb0e31 Alexander Graf
1899 defb0e31 Alexander Graf
static inline uint32_t cc_calc_addu_64(CPUState *env, uint64_t a1, uint64_t a2,
1900 defb0e31 Alexander Graf
                                       uint64_t ar)
1901 defb0e31 Alexander Graf
{
1902 defb0e31 Alexander Graf
    if (ar == 0) {
1903 defb0e31 Alexander Graf
        if (a1) {
1904 defb0e31 Alexander Graf
            return 2;
1905 defb0e31 Alexander Graf
        } else {
1906 defb0e31 Alexander Graf
            return 0;
1907 defb0e31 Alexander Graf
        }
1908 defb0e31 Alexander Graf
    } else {
1909 defb0e31 Alexander Graf
        if (ar < a1 || ar < a2) {
1910 defb0e31 Alexander Graf
          return 3;
1911 defb0e31 Alexander Graf
        } else {
1912 defb0e31 Alexander Graf
          return 1;
1913 defb0e31 Alexander Graf
        }
1914 defb0e31 Alexander Graf
    }
1915 defb0e31 Alexander Graf
}
1916 defb0e31 Alexander Graf
1917 defb0e31 Alexander Graf
static inline uint32_t cc_calc_sub_64(CPUState *env, int64_t a1, int64_t a2,
1918 defb0e31 Alexander Graf
                                      int64_t ar)
1919 defb0e31 Alexander Graf
{
1920 defb0e31 Alexander Graf
    if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
1921 defb0e31 Alexander Graf
        return 3; /* overflow */
1922 defb0e31 Alexander Graf
    } else {
1923 defb0e31 Alexander Graf
        if (ar < 0) {
1924 defb0e31 Alexander Graf
            return 1;
1925 defb0e31 Alexander Graf
        } else if (ar > 0) {
1926 defb0e31 Alexander Graf
            return 2;
1927 defb0e31 Alexander Graf
        } else {
1928 defb0e31 Alexander Graf
            return 0;
1929 defb0e31 Alexander Graf
        }
1930 defb0e31 Alexander Graf
    }
1931 defb0e31 Alexander Graf
}
1932 defb0e31 Alexander Graf
1933 defb0e31 Alexander Graf
static inline uint32_t cc_calc_subu_64(CPUState *env, uint64_t a1, uint64_t a2,
1934 defb0e31 Alexander Graf
                                       uint64_t ar)
1935 defb0e31 Alexander Graf
{
1936 defb0e31 Alexander Graf
    if (ar == 0) {
1937 defb0e31 Alexander Graf
        return 2;
1938 defb0e31 Alexander Graf
    } else {
1939 defb0e31 Alexander Graf
        if (a2 > a1) {
1940 defb0e31 Alexander Graf
            return 1;
1941 defb0e31 Alexander Graf
        } else {
1942 defb0e31 Alexander Graf
            return 3;
1943 defb0e31 Alexander Graf
        }
1944 defb0e31 Alexander Graf
    }
1945 defb0e31 Alexander Graf
}
1946 defb0e31 Alexander Graf
1947 defb0e31 Alexander Graf
static inline uint32_t cc_calc_abs_64(CPUState *env, int64_t dst)
1948 defb0e31 Alexander Graf
{
1949 defb0e31 Alexander Graf
    if ((uint64_t)dst == 0x8000000000000000ULL) {
1950 defb0e31 Alexander Graf
        return 3;
1951 defb0e31 Alexander Graf
    } else if (dst) {
1952 defb0e31 Alexander Graf
        return 1;
1953 defb0e31 Alexander Graf
    } else {
1954 defb0e31 Alexander Graf
        return 0;
1955 defb0e31 Alexander Graf
    }
1956 defb0e31 Alexander Graf
}
1957 defb0e31 Alexander Graf
1958 defb0e31 Alexander Graf
static inline uint32_t cc_calc_nabs_64(CPUState *env, int64_t dst)
1959 defb0e31 Alexander Graf
{
1960 defb0e31 Alexander Graf
    return !!dst;
1961 defb0e31 Alexander Graf
}
1962 defb0e31 Alexander Graf
1963 defb0e31 Alexander Graf
static inline uint32_t cc_calc_comp_64(CPUState *env, int64_t dst)
1964 defb0e31 Alexander Graf
{
1965 defb0e31 Alexander Graf
    if ((uint64_t)dst == 0x8000000000000000ULL) {
1966 defb0e31 Alexander Graf
        return 3;
1967 defb0e31 Alexander Graf
    } else if (dst < 0) {
1968 defb0e31 Alexander Graf
        return 1;
1969 defb0e31 Alexander Graf
    } else if (dst > 0) {
1970 defb0e31 Alexander Graf
        return 2;
1971 defb0e31 Alexander Graf
    } else {
1972 defb0e31 Alexander Graf
        return 0;
1973 defb0e31 Alexander Graf
    }
1974 defb0e31 Alexander Graf
}
1975 defb0e31 Alexander Graf
1976 defb0e31 Alexander Graf
1977 defb0e31 Alexander Graf
static inline uint32_t cc_calc_add_32(CPUState *env, int32_t a1, int32_t a2,
1978 defb0e31 Alexander Graf
                                      int32_t ar)
1979 defb0e31 Alexander Graf
{
1980 defb0e31 Alexander Graf
    if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
1981 defb0e31 Alexander Graf
        return 3; /* overflow */
1982 defb0e31 Alexander Graf
    } else {
1983 defb0e31 Alexander Graf
        if (ar < 0) {
1984 defb0e31 Alexander Graf
            return 1;
1985 defb0e31 Alexander Graf
        } else if (ar > 0) {
1986 defb0e31 Alexander Graf
            return 2;
1987 defb0e31 Alexander Graf
        } else {
1988 defb0e31 Alexander Graf
            return 0;
1989 defb0e31 Alexander Graf
        }
1990 defb0e31 Alexander Graf
    }
1991 defb0e31 Alexander Graf
}
1992 defb0e31 Alexander Graf
1993 defb0e31 Alexander Graf
static inline uint32_t cc_calc_addu_32(CPUState *env, uint32_t a1, uint32_t a2,
1994 defb0e31 Alexander Graf
                                       uint32_t ar)
1995 defb0e31 Alexander Graf
{
1996 defb0e31 Alexander Graf
    if (ar == 0) {
1997 defb0e31 Alexander Graf
        if (a1) {
1998 defb0e31 Alexander Graf
          return 2;
1999 defb0e31 Alexander Graf
        } else {
2000 defb0e31 Alexander Graf
          return 0;
2001 defb0e31 Alexander Graf
        }
2002 defb0e31 Alexander Graf
    } else {
2003 defb0e31 Alexander Graf
        if (ar < a1 || ar < a2) {
2004 defb0e31 Alexander Graf
          return 3;
2005 defb0e31 Alexander Graf
        } else {
2006 defb0e31 Alexander Graf
          return 1;
2007 defb0e31 Alexander Graf
        }
2008 defb0e31 Alexander Graf
    }
2009 defb0e31 Alexander Graf
}
2010 defb0e31 Alexander Graf
2011 defb0e31 Alexander Graf
static inline uint32_t cc_calc_sub_32(CPUState *env, int32_t a1, int32_t a2,
2012 defb0e31 Alexander Graf
                                      int32_t ar)
2013 defb0e31 Alexander Graf
{
2014 defb0e31 Alexander Graf
    if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
2015 defb0e31 Alexander Graf
        return 3; /* overflow */
2016 defb0e31 Alexander Graf
    } else {
2017 defb0e31 Alexander Graf
        if (ar < 0) {
2018 defb0e31 Alexander Graf
            return 1;
2019 defb0e31 Alexander Graf
        } else if (ar > 0) {
2020 defb0e31 Alexander Graf
            return 2;
2021 defb0e31 Alexander Graf
        } else {
2022 defb0e31 Alexander Graf
            return 0;
2023 defb0e31 Alexander Graf
        }
2024 defb0e31 Alexander Graf
    }
2025 defb0e31 Alexander Graf
}
2026 defb0e31 Alexander Graf
2027 defb0e31 Alexander Graf
static inline uint32_t cc_calc_subu_32(CPUState *env, uint32_t a1, uint32_t a2,
2028 defb0e31 Alexander Graf
                                       uint32_t ar)
2029 defb0e31 Alexander Graf
{
2030 defb0e31 Alexander Graf
    if (ar == 0) {
2031 defb0e31 Alexander Graf
        return 2;
2032 defb0e31 Alexander Graf
    } else {
2033 defb0e31 Alexander Graf
        if (a2 > a1) {
2034 defb0e31 Alexander Graf
            return 1;
2035 defb0e31 Alexander Graf
        } else {
2036 defb0e31 Alexander Graf
            return 3;
2037 defb0e31 Alexander Graf
        }
2038 defb0e31 Alexander Graf
    }
2039 defb0e31 Alexander Graf
}
2040 defb0e31 Alexander Graf
2041 defb0e31 Alexander Graf
static inline uint32_t cc_calc_abs_32(CPUState *env, int32_t dst)
2042 defb0e31 Alexander Graf
{
2043 defb0e31 Alexander Graf
    if ((uint32_t)dst == 0x80000000UL) {
2044 defb0e31 Alexander Graf
        return 3;
2045 defb0e31 Alexander Graf
    } else if (dst) {
2046 defb0e31 Alexander Graf
        return 1;
2047 defb0e31 Alexander Graf
    } else {
2048 defb0e31 Alexander Graf
        return 0;
2049 defb0e31 Alexander Graf
    }
2050 defb0e31 Alexander Graf
}
2051 defb0e31 Alexander Graf
2052 defb0e31 Alexander Graf
static inline uint32_t cc_calc_nabs_32(CPUState *env, int32_t dst)
2053 defb0e31 Alexander Graf
{
2054 defb0e31 Alexander Graf
    return !!dst;
2055 defb0e31 Alexander Graf
}
2056 defb0e31 Alexander Graf
2057 defb0e31 Alexander Graf
static inline uint32_t cc_calc_comp_32(CPUState *env, int32_t dst)
2058 defb0e31 Alexander Graf
{
2059 defb0e31 Alexander Graf
    if ((uint32_t)dst == 0x80000000UL) {
2060 defb0e31 Alexander Graf
        return 3;
2061 defb0e31 Alexander Graf
    } else if (dst < 0) {
2062 defb0e31 Alexander Graf
        return 1;
2063 defb0e31 Alexander Graf
    } else if (dst > 0) {
2064 defb0e31 Alexander Graf
        return 2;
2065 defb0e31 Alexander Graf
    } else {
2066 defb0e31 Alexander Graf
        return 0;
2067 defb0e31 Alexander Graf
    }
2068 defb0e31 Alexander Graf
}
2069 defb0e31 Alexander Graf
2070 defb0e31 Alexander Graf
/* calculate condition code for insert character under mask insn */
2071 defb0e31 Alexander Graf
static inline uint32_t cc_calc_icm_32(CPUState *env, uint32_t mask, uint32_t val)
2072 defb0e31 Alexander Graf
{
2073 defb0e31 Alexander Graf
    HELPER_LOG("%s: mask 0x%x val %d\n", __FUNCTION__, mask, val);
2074 defb0e31 Alexander Graf
    uint32_t cc;
2075 defb0e31 Alexander Graf
2076 defb0e31 Alexander Graf
    if (mask == 0xf) {
2077 defb0e31 Alexander Graf
        if (!val) {
2078 defb0e31 Alexander Graf
            return 0;
2079 defb0e31 Alexander Graf
        } else if (val & 0x80000000) {
2080 defb0e31 Alexander Graf
            return 1;
2081 defb0e31 Alexander Graf
        } else {
2082 defb0e31 Alexander Graf
            return 2;
2083 defb0e31 Alexander Graf
        }
2084 defb0e31 Alexander Graf
    }
2085 defb0e31 Alexander Graf
2086 defb0e31 Alexander Graf
    if (!val || !mask) {
2087 defb0e31 Alexander Graf
        cc = 0;
2088 defb0e31 Alexander Graf
    } else {
2089 defb0e31 Alexander Graf
        while (mask != 1) {
2090 defb0e31 Alexander Graf
            mask >>= 1;
2091 defb0e31 Alexander Graf
            val >>= 8;
2092 defb0e31 Alexander Graf
        }
2093 defb0e31 Alexander Graf
        if (val & 0x80) {
2094 defb0e31 Alexander Graf
            cc = 1;
2095 defb0e31 Alexander Graf
        } else {
2096 defb0e31 Alexander Graf
            cc = 2;
2097 defb0e31 Alexander Graf
        }
2098 defb0e31 Alexander Graf
    }
2099 defb0e31 Alexander Graf
    return cc;
2100 defb0e31 Alexander Graf
}
2101 defb0e31 Alexander Graf
2102 defb0e31 Alexander Graf
static inline uint32_t cc_calc_slag(CPUState *env, uint64_t src, uint64_t shift)
2103 defb0e31 Alexander Graf
{
2104 defb0e31 Alexander Graf
    uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift);
2105 defb0e31 Alexander Graf
    uint64_t match, r;
2106 defb0e31 Alexander Graf
2107 defb0e31 Alexander Graf
    /* check if the sign bit stays the same */
2108 defb0e31 Alexander Graf
    if (src & (1ULL << 63)) {
2109 defb0e31 Alexander Graf
        match = mask;
2110 defb0e31 Alexander Graf
    } else {
2111 defb0e31 Alexander Graf
        match = 0;
2112 defb0e31 Alexander Graf
    }
2113 defb0e31 Alexander Graf
2114 defb0e31 Alexander Graf
    if ((src & mask) != match) {
2115 defb0e31 Alexander Graf
        /* overflow */
2116 defb0e31 Alexander Graf
        return 3;
2117 defb0e31 Alexander Graf
    }
2118 defb0e31 Alexander Graf
2119 defb0e31 Alexander Graf
    r = ((src << shift) & ((1ULL << 63) - 1)) | (src & (1ULL << 63));
2120 defb0e31 Alexander Graf
2121 defb0e31 Alexander Graf
    if ((int64_t)r == 0) {
2122 defb0e31 Alexander Graf
        return 0;
2123 defb0e31 Alexander Graf
    } else if ((int64_t)r < 0) {
2124 defb0e31 Alexander Graf
        return 1;
2125 defb0e31 Alexander Graf
    }
2126 defb0e31 Alexander Graf
2127 defb0e31 Alexander Graf
    return 2;
2128 defb0e31 Alexander Graf
}
2129 defb0e31 Alexander Graf
2130 defb0e31 Alexander Graf
2131 defb0e31 Alexander Graf
static inline uint32_t do_calc_cc(CPUState *env, uint32_t cc_op, uint64_t src,
2132 defb0e31 Alexander Graf
                                  uint64_t dst, uint64_t vr)
2133 defb0e31 Alexander Graf
{
2134 defb0e31 Alexander Graf
    uint32_t r = 0;
2135 defb0e31 Alexander Graf
2136 defb0e31 Alexander Graf
    switch (cc_op) {
2137 defb0e31 Alexander Graf
    case CC_OP_CONST0:
2138 defb0e31 Alexander Graf
    case CC_OP_CONST1:
2139 defb0e31 Alexander Graf
    case CC_OP_CONST2:
2140 defb0e31 Alexander Graf
    case CC_OP_CONST3:
2141 defb0e31 Alexander Graf
        /* cc_op value _is_ cc */
2142 defb0e31 Alexander Graf
        r = cc_op;
2143 defb0e31 Alexander Graf
        break;
2144 defb0e31 Alexander Graf
    case CC_OP_LTGT0_32:
2145 defb0e31 Alexander Graf
        r = cc_calc_ltgt0_32(env, dst);
2146 defb0e31 Alexander Graf
        break;
2147 defb0e31 Alexander Graf
    case CC_OP_LTGT0_64:
2148 defb0e31 Alexander Graf
        r =  cc_calc_ltgt0_64(env, dst);
2149 defb0e31 Alexander Graf
        break;
2150 defb0e31 Alexander Graf
    case CC_OP_LTGT_32:
2151 defb0e31 Alexander Graf
        r =  cc_calc_ltgt_32(env, src, dst);
2152 defb0e31 Alexander Graf
        break;
2153 defb0e31 Alexander Graf
    case CC_OP_LTGT_64:
2154 defb0e31 Alexander Graf
        r =  cc_calc_ltgt_64(env, src, dst);
2155 defb0e31 Alexander Graf
        break;
2156 defb0e31 Alexander Graf
    case CC_OP_LTUGTU_32:
2157 defb0e31 Alexander Graf
        r =  cc_calc_ltugtu_32(env, src, dst);
2158 defb0e31 Alexander Graf
        break;
2159 defb0e31 Alexander Graf
    case CC_OP_LTUGTU_64:
2160 defb0e31 Alexander Graf
        r =  cc_calc_ltugtu_64(env, src, dst);
2161 defb0e31 Alexander Graf
        break;
2162 defb0e31 Alexander Graf
    case CC_OP_TM_32:
2163 defb0e31 Alexander Graf
        r =  cc_calc_tm_32(env, src, dst);
2164 defb0e31 Alexander Graf
        break;
2165 defb0e31 Alexander Graf
    case CC_OP_TM_64:
2166 defb0e31 Alexander Graf
        r =  cc_calc_tm_64(env, src, dst);
2167 defb0e31 Alexander Graf
        break;
2168 defb0e31 Alexander Graf
    case CC_OP_NZ:
2169 defb0e31 Alexander Graf
        r =  cc_calc_nz(env, dst);
2170 defb0e31 Alexander Graf
        break;
2171 defb0e31 Alexander Graf
    case CC_OP_ADD_64:
2172 defb0e31 Alexander Graf
        r =  cc_calc_add_64(env, src, dst, vr);
2173 defb0e31 Alexander Graf
        break;
2174 defb0e31 Alexander Graf
    case CC_OP_ADDU_64:
2175 defb0e31 Alexander Graf
        r =  cc_calc_addu_64(env, src, dst, vr);
2176 defb0e31 Alexander Graf
        break;
2177 defb0e31 Alexander Graf
    case CC_OP_SUB_64:
2178 defb0e31 Alexander Graf
        r =  cc_calc_sub_64(env, src, dst, vr);
2179 defb0e31 Alexander Graf
        break;
2180 defb0e31 Alexander Graf
    case CC_OP_SUBU_64:
2181 defb0e31 Alexander Graf
        r =  cc_calc_subu_64(env, src, dst, vr);
2182 defb0e31 Alexander Graf
        break;
2183 defb0e31 Alexander Graf
    case CC_OP_ABS_64:
2184 defb0e31 Alexander Graf
        r =  cc_calc_abs_64(env, dst);
2185 defb0e31 Alexander Graf
        break;
2186 defb0e31 Alexander Graf
    case CC_OP_NABS_64:
2187 defb0e31 Alexander Graf
        r =  cc_calc_nabs_64(env, dst);
2188 defb0e31 Alexander Graf
        break;
2189 defb0e31 Alexander Graf
    case CC_OP_COMP_64:
2190 defb0e31 Alexander Graf
        r =  cc_calc_comp_64(env, dst);
2191 defb0e31 Alexander Graf
        break;
2192 defb0e31 Alexander Graf
2193 defb0e31 Alexander Graf
    case CC_OP_ADD_32:
2194 defb0e31 Alexander Graf
        r =  cc_calc_add_32(env, src, dst, vr);
2195 defb0e31 Alexander Graf
        break;
2196 defb0e31 Alexander Graf
    case CC_OP_ADDU_32:
2197 defb0e31 Alexander Graf
        r =  cc_calc_addu_32(env, src, dst, vr);
2198 defb0e31 Alexander Graf
        break;
2199 defb0e31 Alexander Graf
    case CC_OP_SUB_32:
2200 defb0e31 Alexander Graf
        r =  cc_calc_sub_32(env, src, dst, vr);
2201 defb0e31 Alexander Graf
        break;
2202 defb0e31 Alexander Graf
    case CC_OP_SUBU_32:
2203 defb0e31 Alexander Graf
        r =  cc_calc_subu_32(env, src, dst, vr);
2204 defb0e31 Alexander Graf
        break;
2205 defb0e31 Alexander Graf
    case CC_OP_ABS_32:
2206 defb0e31 Alexander Graf
        r =  cc_calc_abs_64(env, dst);
2207 defb0e31 Alexander Graf
        break;
2208 defb0e31 Alexander Graf
    case CC_OP_NABS_32:
2209 defb0e31 Alexander Graf
        r =  cc_calc_nabs_64(env, dst);
2210 defb0e31 Alexander Graf
        break;
2211 defb0e31 Alexander Graf
    case CC_OP_COMP_32:
2212 defb0e31 Alexander Graf
        r =  cc_calc_comp_32(env, dst);
2213 defb0e31 Alexander Graf
        break;
2214 defb0e31 Alexander Graf
2215 defb0e31 Alexander Graf
    case CC_OP_ICM:
2216 defb0e31 Alexander Graf
        r =  cc_calc_icm_32(env, src, dst);
2217 defb0e31 Alexander Graf
        break;
2218 defb0e31 Alexander Graf
    case CC_OP_SLAG:
2219 defb0e31 Alexander Graf
        r =  cc_calc_slag(env, src, dst);
2220 defb0e31 Alexander Graf
        break;
2221 defb0e31 Alexander Graf
2222 defb0e31 Alexander Graf
    case CC_OP_LTGT_F32:
2223 defb0e31 Alexander Graf
        r = set_cc_f32(src, dst);
2224 defb0e31 Alexander Graf
        break;
2225 defb0e31 Alexander Graf
    case CC_OP_LTGT_F64:
2226 defb0e31 Alexander Graf
        r = set_cc_f64(src, dst);
2227 defb0e31 Alexander Graf
        break;
2228 defb0e31 Alexander Graf
    case CC_OP_NZ_F32:
2229 defb0e31 Alexander Graf
        r = set_cc_nz_f32(dst);
2230 defb0e31 Alexander Graf
        break;
2231 defb0e31 Alexander Graf
    case CC_OP_NZ_F64:
2232 defb0e31 Alexander Graf
        r = set_cc_nz_f64(dst);
2233 defb0e31 Alexander Graf
        break;
2234 defb0e31 Alexander Graf
2235 defb0e31 Alexander Graf
    default:
2236 defb0e31 Alexander Graf
        cpu_abort(env, "Unknown CC operation: %s\n", cc_name(cc_op));
2237 defb0e31 Alexander Graf
    }
2238 defb0e31 Alexander Graf
2239 defb0e31 Alexander Graf
    HELPER_LOG("%s: %15s 0x%016lx 0x%016lx 0x%016lx = %d\n", __FUNCTION__,
2240 defb0e31 Alexander Graf
               cc_name(cc_op), src, dst, vr, r);
2241 defb0e31 Alexander Graf
    return r;
2242 defb0e31 Alexander Graf
}
2243 defb0e31 Alexander Graf
2244 d5a43964 Alexander Graf
uint32_t calc_cc(CPUState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
2245 d5a43964 Alexander Graf
                 uint64_t vr)
2246 d5a43964 Alexander Graf
{
2247 defb0e31 Alexander Graf
    return do_calc_cc(env, cc_op, src, dst, vr);
2248 defb0e31 Alexander Graf
}
2249 defb0e31 Alexander Graf
2250 defb0e31 Alexander Graf
uint32_t HELPER(calc_cc)(uint32_t cc_op, uint64_t src, uint64_t dst,
2251 defb0e31 Alexander Graf
                         uint64_t vr)
2252 defb0e31 Alexander Graf
{
2253 defb0e31 Alexander Graf
    return do_calc_cc(env, cc_op, src, dst, vr);
2254 defb0e31 Alexander Graf
}
2255 defb0e31 Alexander Graf
2256 defb0e31 Alexander Graf
uint64_t HELPER(cvd)(int32_t bin)
2257 defb0e31 Alexander Graf
{
2258 defb0e31 Alexander Graf
    /* positive 0 */
2259 defb0e31 Alexander Graf
    uint64_t dec = 0x0c;
2260 defb0e31 Alexander Graf
    int shift = 4;
2261 defb0e31 Alexander Graf
2262 defb0e31 Alexander Graf
    if (bin < 0) {
2263 defb0e31 Alexander Graf
        bin = -bin;
2264 defb0e31 Alexander Graf
        dec = 0x0d;
2265 defb0e31 Alexander Graf
    }
2266 defb0e31 Alexander Graf
2267 defb0e31 Alexander Graf
    for (shift = 4; (shift < 64) && bin; shift += 4) {
2268 defb0e31 Alexander Graf
        int current_number = bin % 10;
2269 defb0e31 Alexander Graf
2270 defb0e31 Alexander Graf
        dec |= (current_number) << shift;
2271 defb0e31 Alexander Graf
        bin /= 10;
2272 defb0e31 Alexander Graf
    }
2273 defb0e31 Alexander Graf
2274 defb0e31 Alexander Graf
    return dec;
2275 defb0e31 Alexander Graf
}
2276 defb0e31 Alexander Graf
2277 defb0e31 Alexander Graf
void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
2278 defb0e31 Alexander Graf
{
2279 defb0e31 Alexander Graf
    int len_dest = len >> 4;
2280 defb0e31 Alexander Graf
    int len_src = len & 0xf;
2281 defb0e31 Alexander Graf
    uint8_t b;
2282 defb0e31 Alexander Graf
    int second_nibble = 0;
2283 defb0e31 Alexander Graf
2284 defb0e31 Alexander Graf
    dest += len_dest;
2285 defb0e31 Alexander Graf
    src += len_src;
2286 defb0e31 Alexander Graf
2287 defb0e31 Alexander Graf
    /* last byte is special, it only flips the nibbles */
2288 defb0e31 Alexander Graf
    b = ldub(src);
2289 defb0e31 Alexander Graf
    stb(dest, (b << 4) | (b >> 4));
2290 defb0e31 Alexander Graf
    src--;
2291 defb0e31 Alexander Graf
    len_src--;
2292 defb0e31 Alexander Graf
2293 defb0e31 Alexander Graf
    /* now pad every nibble with 0xf0 */
2294 defb0e31 Alexander Graf
2295 defb0e31 Alexander Graf
    while (len_dest > 0) {
2296 defb0e31 Alexander Graf
        uint8_t cur_byte = 0;
2297 defb0e31 Alexander Graf
2298 defb0e31 Alexander Graf
        if (len_src > 0) {
2299 defb0e31 Alexander Graf
            cur_byte = ldub(src);
2300 defb0e31 Alexander Graf
        }
2301 defb0e31 Alexander Graf
2302 defb0e31 Alexander Graf
        len_dest--;
2303 defb0e31 Alexander Graf
        dest--;
2304 defb0e31 Alexander Graf
2305 defb0e31 Alexander Graf
        /* only advance one nibble at a time */
2306 defb0e31 Alexander Graf
        if (second_nibble) {
2307 defb0e31 Alexander Graf
            cur_byte >>= 4;
2308 defb0e31 Alexander Graf
            len_src--;
2309 defb0e31 Alexander Graf
            src--;
2310 defb0e31 Alexander Graf
        }
2311 defb0e31 Alexander Graf
        second_nibble = !second_nibble;
2312 defb0e31 Alexander Graf
2313 defb0e31 Alexander Graf
        /* digit */
2314 defb0e31 Alexander Graf
        cur_byte = (cur_byte & 0xf);
2315 defb0e31 Alexander Graf
        /* zone bits */
2316 defb0e31 Alexander Graf
        cur_byte |= 0xf0;
2317 defb0e31 Alexander Graf
2318 defb0e31 Alexander Graf
        stb(dest, cur_byte);
2319 defb0e31 Alexander Graf
    }
2320 defb0e31 Alexander Graf
}
2321 defb0e31 Alexander Graf
2322 defb0e31 Alexander Graf
void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans)
2323 defb0e31 Alexander Graf
{
2324 defb0e31 Alexander Graf
    int i;
2325 defb0e31 Alexander Graf
2326 defb0e31 Alexander Graf
    for (i = 0; i <= len; i++) {
2327 defb0e31 Alexander Graf
        uint8_t byte = ldub(array + i);
2328 defb0e31 Alexander Graf
        uint8_t new_byte = ldub(trans + byte);
2329 defb0e31 Alexander Graf
        stb(array + i, new_byte);
2330 defb0e31 Alexander Graf
    }
2331 defb0e31 Alexander Graf
}
2332 defb0e31 Alexander Graf
2333 defb0e31 Alexander Graf
#ifndef CONFIG_USER_ONLY
2334 defb0e31 Alexander Graf
2335 defb0e31 Alexander Graf
void HELPER(load_psw)(uint64_t mask, uint64_t addr)
2336 defb0e31 Alexander Graf
{
2337 defb0e31 Alexander Graf
    load_psw(env, mask, addr);
2338 defb0e31 Alexander Graf
    cpu_loop_exit();
2339 defb0e31 Alexander Graf
}
2340 defb0e31 Alexander Graf
2341 defb0e31 Alexander Graf
static void program_interrupt(CPUState *env, uint32_t code, int ilc)
2342 defb0e31 Alexander Graf
{
2343 defb0e31 Alexander Graf
    qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr);
2344 defb0e31 Alexander Graf
2345 defb0e31 Alexander Graf
    if (kvm_enabled()) {
2346 defb0e31 Alexander Graf
        kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code);
2347 defb0e31 Alexander Graf
    } else {
2348 defb0e31 Alexander Graf
        env->int_pgm_code = code;
2349 defb0e31 Alexander Graf
        env->int_pgm_ilc = ilc;
2350 defb0e31 Alexander Graf
        env->exception_index = EXCP_PGM;
2351 defb0e31 Alexander Graf
        cpu_loop_exit();
2352 defb0e31 Alexander Graf
    }
2353 defb0e31 Alexander Graf
}
2354 defb0e31 Alexander Graf
2355 defb0e31 Alexander Graf
static void ext_interrupt(CPUState *env, int type, uint32_t param,
2356 defb0e31 Alexander Graf
                          uint64_t param64)
2357 defb0e31 Alexander Graf
{
2358 defb0e31 Alexander Graf
    cpu_inject_ext(env, type, param, param64);
2359 defb0e31 Alexander Graf
}
2360 defb0e31 Alexander Graf
2361 defb0e31 Alexander Graf
int sclp_service_call(CPUState *env, uint32_t sccb, uint64_t code)
2362 defb0e31 Alexander Graf
{
2363 defb0e31 Alexander Graf
    int r = 0;
2364 22486aa0 Christian Borntraeger
    int shift = 0;
2365 defb0e31 Alexander Graf
2366 defb0e31 Alexander Graf
#ifdef DEBUG_HELPER
2367 defb0e31 Alexander Graf
    printf("sclp(0x%x, 0x%" PRIx64 ")\n", sccb, code);
2368 defb0e31 Alexander Graf
#endif
2369 defb0e31 Alexander Graf
2370 defb0e31 Alexander Graf
    if (sccb & ~0x7ffffff8ul) {
2371 defb0e31 Alexander Graf
        fprintf(stderr, "KVM: invalid sccb address 0x%x\n", sccb);
2372 defb0e31 Alexander Graf
        r = -1;
2373 defb0e31 Alexander Graf
        goto out;
2374 defb0e31 Alexander Graf
    }
2375 defb0e31 Alexander Graf
2376 defb0e31 Alexander Graf
    switch(code) {
2377 defb0e31 Alexander Graf
        case SCLP_CMDW_READ_SCP_INFO:
2378 defb0e31 Alexander Graf
        case SCLP_CMDW_READ_SCP_INFO_FORCED:
2379 22486aa0 Christian Borntraeger
            while ((ram_size >> (20 + shift)) > 65535) {
2380 22486aa0 Christian Borntraeger
                shift++;
2381 22486aa0 Christian Borntraeger
            }
2382 22486aa0 Christian Borntraeger
            stw_phys(sccb + SCP_MEM_CODE, ram_size >> (20 + shift));
2383 22486aa0 Christian Borntraeger
            stb_phys(sccb + SCP_INCREMENT, 1 << shift);
2384 defb0e31 Alexander Graf
            stw_phys(sccb + SCP_RESPONSE_CODE, 0x10);
2385 defb0e31 Alexander Graf
2386 defb0e31 Alexander Graf
            if (kvm_enabled()) {
2387 defb0e31 Alexander Graf
#ifdef CONFIG_KVM
2388 defb0e31 Alexander Graf
                kvm_s390_interrupt_internal(env, KVM_S390_INT_SERVICE,
2389 defb0e31 Alexander Graf
                                            sccb & ~3, 0, 1);
2390 defb0e31 Alexander Graf
#endif
2391 defb0e31 Alexander Graf
            } else {
2392 defb0e31 Alexander Graf
                env->psw.addr += 4;
2393 defb0e31 Alexander Graf
                ext_interrupt(env, EXT_SERVICE, sccb & ~3, 0);
2394 defb0e31 Alexander Graf
            }
2395 defb0e31 Alexander Graf
            break;
2396 defb0e31 Alexander Graf
        default:
2397 defb0e31 Alexander Graf
#ifdef DEBUG_HELPER
2398 defb0e31 Alexander Graf
            printf("KVM: invalid sclp call 0x%x / 0x%" PRIx64 "x\n", sccb, code);
2399 defb0e31 Alexander Graf
#endif
2400 defb0e31 Alexander Graf
            r = -1;
2401 defb0e31 Alexander Graf
            break;
2402 defb0e31 Alexander Graf
    }
2403 defb0e31 Alexander Graf
2404 defb0e31 Alexander Graf
out:
2405 defb0e31 Alexander Graf
    return r;
2406 defb0e31 Alexander Graf
}
2407 defb0e31 Alexander Graf
2408 defb0e31 Alexander Graf
/* SCLP service call */
2409 defb0e31 Alexander Graf
uint32_t HELPER(servc)(uint32_t r1, uint64_t r2)
2410 defb0e31 Alexander Graf
{
2411 defb0e31 Alexander Graf
    if (sclp_service_call(env, r1, r2)) {
2412 defb0e31 Alexander Graf
        return 3;
2413 defb0e31 Alexander Graf
    }
2414 defb0e31 Alexander Graf
2415 defb0e31 Alexander Graf
    return 0;
2416 defb0e31 Alexander Graf
}
2417 defb0e31 Alexander Graf
2418 defb0e31 Alexander Graf
/* DIAG */
2419 defb0e31 Alexander Graf
uint64_t HELPER(diag)(uint32_t num, uint64_t mem, uint64_t code)
2420 defb0e31 Alexander Graf
{
2421 defb0e31 Alexander Graf
    uint64_t r;
2422 defb0e31 Alexander Graf
2423 defb0e31 Alexander Graf
    switch (num) {
2424 defb0e31 Alexander Graf
    case 0x500:
2425 defb0e31 Alexander Graf
        /* KVM hypercall */
2426 defb0e31 Alexander Graf
        r = s390_virtio_hypercall(env, mem, code);
2427 defb0e31 Alexander Graf
        break;
2428 defb0e31 Alexander Graf
    case 0x44:
2429 defb0e31 Alexander Graf
        /* yield */
2430 defb0e31 Alexander Graf
        r = 0;
2431 defb0e31 Alexander Graf
        break;
2432 defb0e31 Alexander Graf
    case 0x308:
2433 defb0e31 Alexander Graf
        /* ipl */
2434 defb0e31 Alexander Graf
        r = 0;
2435 defb0e31 Alexander Graf
        break;
2436 defb0e31 Alexander Graf
    default:
2437 defb0e31 Alexander Graf
        r = -1;
2438 defb0e31 Alexander Graf
        break;
2439 defb0e31 Alexander Graf
    }
2440 defb0e31 Alexander Graf
2441 defb0e31 Alexander Graf
    if (r) {
2442 defb0e31 Alexander Graf
        program_interrupt(env, PGM_OPERATION, ILC_LATER_INC);
2443 defb0e31 Alexander Graf
    }
2444 defb0e31 Alexander Graf
2445 defb0e31 Alexander Graf
    return r;
2446 defb0e31 Alexander Graf
}
2447 defb0e31 Alexander Graf
2448 defb0e31 Alexander Graf
/* Store CPU ID */
2449 defb0e31 Alexander Graf
void HELPER(stidp)(uint64_t a1)
2450 defb0e31 Alexander Graf
{
2451 defb0e31 Alexander Graf
    stq(a1, env->cpu_num);
2452 defb0e31 Alexander Graf
}
2453 defb0e31 Alexander Graf
2454 defb0e31 Alexander Graf
/* Set Prefix */
2455 defb0e31 Alexander Graf
void HELPER(spx)(uint64_t a1)
2456 defb0e31 Alexander Graf
{
2457 defb0e31 Alexander Graf
    uint32_t prefix;
2458 defb0e31 Alexander Graf
2459 defb0e31 Alexander Graf
    prefix = ldl(a1);
2460 defb0e31 Alexander Graf
    env->psa = prefix & 0xfffff000;
2461 defb0e31 Alexander Graf
    qemu_log("prefix: %#x\n", prefix);
2462 defb0e31 Alexander Graf
    tlb_flush_page(env, 0);
2463 defb0e31 Alexander Graf
    tlb_flush_page(env, TARGET_PAGE_SIZE);
2464 defb0e31 Alexander Graf
}
2465 defb0e31 Alexander Graf
2466 defb0e31 Alexander Graf
/* Set Clock */
2467 defb0e31 Alexander Graf
uint32_t HELPER(sck)(uint64_t a1)
2468 defb0e31 Alexander Graf
{
2469 defb0e31 Alexander Graf
    /* XXX not implemented - is it necessary? */
2470 defb0e31 Alexander Graf
2471 defb0e31 Alexander Graf
    return 0;
2472 defb0e31 Alexander Graf
}
2473 defb0e31 Alexander Graf
2474 defb0e31 Alexander Graf
static inline uint64_t clock_value(CPUState *env)
2475 defb0e31 Alexander Graf
{
2476 defb0e31 Alexander Graf
    uint64_t time;
2477 defb0e31 Alexander Graf
2478 defb0e31 Alexander Graf
    time = env->tod_offset +
2479 defb0e31 Alexander Graf
           time2tod(qemu_get_clock_ns(vm_clock) - env->tod_basetime);
2480 defb0e31 Alexander Graf
2481 defb0e31 Alexander Graf
    return time;
2482 defb0e31 Alexander Graf
}
2483 defb0e31 Alexander Graf
2484 defb0e31 Alexander Graf
/* Store Clock */
2485 defb0e31 Alexander Graf
uint32_t HELPER(stck)(uint64_t a1)
2486 defb0e31 Alexander Graf
{
2487 defb0e31 Alexander Graf
    stq(a1, clock_value(env));
2488 defb0e31 Alexander Graf
2489 defb0e31 Alexander Graf
    return 0;
2490 defb0e31 Alexander Graf
}
2491 defb0e31 Alexander Graf
2492 defb0e31 Alexander Graf
/* Store Clock Extended */
2493 defb0e31 Alexander Graf
uint32_t HELPER(stcke)(uint64_t a1)
2494 defb0e31 Alexander Graf
{
2495 defb0e31 Alexander Graf
    stb(a1, 0);
2496 defb0e31 Alexander Graf
    /* basically the same value as stck */
2497 defb0e31 Alexander Graf
    stq(a1 + 1, clock_value(env) | env->cpu_num);
2498 defb0e31 Alexander Graf
    /* more fine grained than stck */
2499 defb0e31 Alexander Graf
    stq(a1 + 9, 0);
2500 defb0e31 Alexander Graf
    /* XXX programmable fields */
2501 defb0e31 Alexander Graf
    stw(a1 + 17, 0);
2502 defb0e31 Alexander Graf
2503 defb0e31 Alexander Graf
2504 defb0e31 Alexander Graf
    return 0;
2505 defb0e31 Alexander Graf
}
2506 defb0e31 Alexander Graf
2507 defb0e31 Alexander Graf
/* Set Clock Comparator */
2508 defb0e31 Alexander Graf
void HELPER(sckc)(uint64_t a1)
2509 defb0e31 Alexander Graf
{
2510 defb0e31 Alexander Graf
    uint64_t time = ldq(a1);
2511 defb0e31 Alexander Graf
2512 defb0e31 Alexander Graf
    if (time == -1ULL) {
2513 defb0e31 Alexander Graf
        return;
2514 defb0e31 Alexander Graf
    }
2515 defb0e31 Alexander Graf
2516 defb0e31 Alexander Graf
    /* difference between now and then */
2517 defb0e31 Alexander Graf
    time -= clock_value(env);
2518 defb0e31 Alexander Graf
    /* nanoseconds */
2519 defb0e31 Alexander Graf
    time = (time * 125) >> 9;
2520 defb0e31 Alexander Graf
2521 defb0e31 Alexander Graf
    qemu_mod_timer(env->tod_timer, qemu_get_clock_ns(vm_clock) + time);
2522 defb0e31 Alexander Graf
}
2523 defb0e31 Alexander Graf
2524 defb0e31 Alexander Graf
/* Store Clock Comparator */
2525 defb0e31 Alexander Graf
void HELPER(stckc)(uint64_t a1)
2526 defb0e31 Alexander Graf
{
2527 defb0e31 Alexander Graf
    /* XXX implement */
2528 defb0e31 Alexander Graf
    stq(a1, 0);
2529 defb0e31 Alexander Graf
}
2530 defb0e31 Alexander Graf
2531 defb0e31 Alexander Graf
/* Set CPU Timer */
2532 defb0e31 Alexander Graf
void HELPER(spt)(uint64_t a1)
2533 defb0e31 Alexander Graf
{
2534 defb0e31 Alexander Graf
    uint64_t time = ldq(a1);
2535 defb0e31 Alexander Graf
2536 defb0e31 Alexander Graf
    if (time == -1ULL) {
2537 defb0e31 Alexander Graf
        return;
2538 defb0e31 Alexander Graf
    }
2539 defb0e31 Alexander Graf
2540 defb0e31 Alexander Graf
    /* nanoseconds */
2541 defb0e31 Alexander Graf
    time = (time * 125) >> 9;
2542 defb0e31 Alexander Graf
2543 defb0e31 Alexander Graf
    qemu_mod_timer(env->cpu_timer, qemu_get_clock_ns(vm_clock) + time);
2544 defb0e31 Alexander Graf
}
2545 defb0e31 Alexander Graf
2546 defb0e31 Alexander Graf
/* Store CPU Timer */
2547 defb0e31 Alexander Graf
void HELPER(stpt)(uint64_t a1)
2548 defb0e31 Alexander Graf
{
2549 defb0e31 Alexander Graf
    /* XXX implement */
2550 defb0e31 Alexander Graf
    stq(a1, 0);
2551 defb0e31 Alexander Graf
}
2552 defb0e31 Alexander Graf
2553 defb0e31 Alexander Graf
/* Store System Information */
2554 defb0e31 Alexander Graf
uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
2555 defb0e31 Alexander Graf
{
2556 defb0e31 Alexander Graf
    int cc = 0;
2557 defb0e31 Alexander Graf
    int sel1, sel2;
2558 defb0e31 Alexander Graf
2559 defb0e31 Alexander Graf
    if ((r0 & STSI_LEVEL_MASK) <= STSI_LEVEL_3 &&
2560 defb0e31 Alexander Graf
        ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK))) {
2561 defb0e31 Alexander Graf
        /* valid function code, invalid reserved bits */
2562 defb0e31 Alexander Graf
        program_interrupt(env, PGM_SPECIFICATION, 2);
2563 defb0e31 Alexander Graf
    }
2564 defb0e31 Alexander Graf
2565 defb0e31 Alexander Graf
    sel1 = r0 & STSI_R0_SEL1_MASK;
2566 defb0e31 Alexander Graf
    sel2 = r1 & STSI_R1_SEL2_MASK;
2567 defb0e31 Alexander Graf
2568 defb0e31 Alexander Graf
    /* XXX: spec exception if sysib is not 4k-aligned */
2569 defb0e31 Alexander Graf
2570 defb0e31 Alexander Graf
    switch (r0 & STSI_LEVEL_MASK) {
2571 defb0e31 Alexander Graf
    case STSI_LEVEL_1:
2572 defb0e31 Alexander Graf
        if ((sel1 == 1) && (sel2 == 1)) {
2573 defb0e31 Alexander Graf
            /* Basic Machine Configuration */
2574 defb0e31 Alexander Graf
            struct sysib_111 sysib;
2575 defb0e31 Alexander Graf
2576 defb0e31 Alexander Graf
            memset(&sysib, 0, sizeof(sysib));
2577 defb0e31 Alexander Graf
            ebcdic_put(sysib.manuf, "QEMU            ", 16);
2578 defb0e31 Alexander Graf
            /* same as machine type number in STORE CPU ID */
2579 defb0e31 Alexander Graf
            ebcdic_put(sysib.type, "QEMU", 4);
2580 defb0e31 Alexander Graf
            /* same as model number in STORE CPU ID */
2581 defb0e31 Alexander Graf
            ebcdic_put(sysib.model, "QEMU            ", 16);
2582 defb0e31 Alexander Graf
            ebcdic_put(sysib.sequence, "QEMU            ", 16);
2583 defb0e31 Alexander Graf
            ebcdic_put(sysib.plant, "QEMU", 4);
2584 defb0e31 Alexander Graf
            cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
2585 defb0e31 Alexander Graf
        } else if ((sel1 == 2) && (sel2 == 1)) {
2586 defb0e31 Alexander Graf
            /* Basic Machine CPU */
2587 defb0e31 Alexander Graf
            struct sysib_121 sysib;
2588 defb0e31 Alexander Graf
2589 defb0e31 Alexander Graf
            memset(&sysib, 0, sizeof(sysib));
2590 defb0e31 Alexander Graf
            /* XXX make different for different CPUs? */
2591 defb0e31 Alexander Graf
            ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
2592 defb0e31 Alexander Graf
            ebcdic_put(sysib.plant, "QEMU", 4);
2593 defb0e31 Alexander Graf
            stw_p(&sysib.cpu_addr, env->cpu_num);
2594 defb0e31 Alexander Graf
            cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
2595 defb0e31 Alexander Graf
        } else if ((sel1 == 2) && (sel2 == 2)) {
2596 defb0e31 Alexander Graf
            /* Basic Machine CPUs */
2597 defb0e31 Alexander Graf
            struct sysib_122 sysib;
2598 defb0e31 Alexander Graf
2599 defb0e31 Alexander Graf
            memset(&sysib, 0, sizeof(sysib));
2600 defb0e31 Alexander Graf
            stl_p(&sysib.capability, 0x443afc29);
2601 defb0e31 Alexander Graf
            /* XXX change when SMP comes */
2602 defb0e31 Alexander Graf
            stw_p(&sysib.total_cpus, 1);
2603 defb0e31 Alexander Graf
            stw_p(&sysib.active_cpus, 1);
2604 defb0e31 Alexander Graf
            stw_p(&sysib.standby_cpus, 0);
2605 defb0e31 Alexander Graf
            stw_p(&sysib.reserved_cpus, 0);
2606 defb0e31 Alexander Graf
            cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
2607 defb0e31 Alexander Graf
        } else {
2608 defb0e31 Alexander Graf
            cc = 3;
2609 defb0e31 Alexander Graf
        }
2610 defb0e31 Alexander Graf
        break;
2611 defb0e31 Alexander Graf
    case STSI_LEVEL_2:
2612 defb0e31 Alexander Graf
    {
2613 defb0e31 Alexander Graf
        if ((sel1 == 2) && (sel2 == 1)) {
2614 defb0e31 Alexander Graf
            /* LPAR CPU */
2615 defb0e31 Alexander Graf
            struct sysib_221 sysib;
2616 defb0e31 Alexander Graf
2617 defb0e31 Alexander Graf
            memset(&sysib, 0, sizeof(sysib));
2618 defb0e31 Alexander Graf
            /* XXX make different for different CPUs? */
2619 defb0e31 Alexander Graf
            ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
2620 defb0e31 Alexander Graf
            ebcdic_put(sysib.plant, "QEMU", 4);
2621 defb0e31 Alexander Graf
            stw_p(&sysib.cpu_addr, env->cpu_num);
2622 defb0e31 Alexander Graf
            stw_p(&sysib.cpu_id, 0);
2623 defb0e31 Alexander Graf
            cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
2624 defb0e31 Alexander Graf
        } else if ((sel1 == 2) && (sel2 == 2)) {
2625 defb0e31 Alexander Graf
            /* LPAR CPUs */
2626 defb0e31 Alexander Graf
            struct sysib_222 sysib;
2627 defb0e31 Alexander Graf
2628 defb0e31 Alexander Graf
            memset(&sysib, 0, sizeof(sysib));
2629 defb0e31 Alexander Graf
            stw_p(&sysib.lpar_num, 0);
2630 defb0e31 Alexander Graf
            sysib.lcpuc = 0;
2631 defb0e31 Alexander Graf
            /* XXX change when SMP comes */
2632 defb0e31 Alexander Graf
            stw_p(&sysib.total_cpus, 1);
2633 defb0e31 Alexander Graf
            stw_p(&sysib.conf_cpus, 1);
2634 defb0e31 Alexander Graf
            stw_p(&sysib.standby_cpus, 0);
2635 defb0e31 Alexander Graf
            stw_p(&sysib.reserved_cpus, 0);
2636 defb0e31 Alexander Graf
            ebcdic_put(sysib.name, "QEMU    ", 8);
2637 defb0e31 Alexander Graf
            stl_p(&sysib.caf, 1000);
2638 defb0e31 Alexander Graf
            stw_p(&sysib.dedicated_cpus, 0);
2639 defb0e31 Alexander Graf
            stw_p(&sysib.shared_cpus, 0);
2640 defb0e31 Alexander Graf
            cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
2641 defb0e31 Alexander Graf
        } else {
2642 defb0e31 Alexander Graf
            cc = 3;
2643 defb0e31 Alexander Graf
        }
2644 defb0e31 Alexander Graf
        break;
2645 defb0e31 Alexander Graf
    }
2646 defb0e31 Alexander Graf
    case STSI_LEVEL_3:
2647 defb0e31 Alexander Graf
    {
2648 defb0e31 Alexander Graf
        if ((sel1 == 2) && (sel2 == 2)) {
2649 defb0e31 Alexander Graf
            /* VM CPUs */
2650 defb0e31 Alexander Graf
            struct sysib_322 sysib;
2651 defb0e31 Alexander Graf
2652 defb0e31 Alexander Graf
            memset(&sysib, 0, sizeof(sysib));
2653 defb0e31 Alexander Graf
            sysib.count = 1;
2654 defb0e31 Alexander Graf
            /* XXX change when SMP comes */
2655 defb0e31 Alexander Graf
            stw_p(&sysib.vm[0].total_cpus, 1);
2656 defb0e31 Alexander Graf
            stw_p(&sysib.vm[0].conf_cpus, 1);
2657 defb0e31 Alexander Graf
            stw_p(&sysib.vm[0].standby_cpus, 0);
2658 defb0e31 Alexander Graf
            stw_p(&sysib.vm[0].reserved_cpus, 0);
2659 defb0e31 Alexander Graf
            ebcdic_put(sysib.vm[0].name, "KVMguest", 8);
2660 defb0e31 Alexander Graf
            stl_p(&sysib.vm[0].caf, 1000);
2661 defb0e31 Alexander Graf
            ebcdic_put(sysib.vm[0].cpi, "KVM/Linux       ", 16);
2662 defb0e31 Alexander Graf
            cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
2663 defb0e31 Alexander Graf
        } else {
2664 defb0e31 Alexander Graf
            cc = 3;
2665 defb0e31 Alexander Graf
        }
2666 defb0e31 Alexander Graf
        break;
2667 defb0e31 Alexander Graf
    }
2668 defb0e31 Alexander Graf
    case STSI_LEVEL_CURRENT:
2669 defb0e31 Alexander Graf
        env->regs[0] = STSI_LEVEL_3;
2670 defb0e31 Alexander Graf
        break;
2671 defb0e31 Alexander Graf
    default:
2672 defb0e31 Alexander Graf
        cc = 3;
2673 defb0e31 Alexander Graf
        break;
2674 defb0e31 Alexander Graf
    }
2675 defb0e31 Alexander Graf
2676 defb0e31 Alexander Graf
    return cc;
2677 defb0e31 Alexander Graf
}
2678 defb0e31 Alexander Graf
2679 defb0e31 Alexander Graf
void HELPER(lctlg)(uint32_t r1, uint64_t a2, uint32_t r3)
2680 defb0e31 Alexander Graf
{
2681 defb0e31 Alexander Graf
    int i;
2682 defb0e31 Alexander Graf
    uint64_t src = a2;
2683 defb0e31 Alexander Graf
2684 defb0e31 Alexander Graf
    for (i = r1;; i = (i + 1) % 16) {
2685 defb0e31 Alexander Graf
        env->cregs[i] = ldq(src);
2686 defb0e31 Alexander Graf
        HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%" PRIx64 "\n",
2687 defb0e31 Alexander Graf
                   i, src, env->cregs[i]);
2688 defb0e31 Alexander Graf
        src += sizeof(uint64_t);
2689 defb0e31 Alexander Graf
2690 defb0e31 Alexander Graf
        if (i == r3) {
2691 defb0e31 Alexander Graf
            break;
2692 defb0e31 Alexander Graf
        }
2693 defb0e31 Alexander Graf
    }
2694 defb0e31 Alexander Graf
2695 defb0e31 Alexander Graf
    tlb_flush(env, 1);
2696 defb0e31 Alexander Graf
}
2697 defb0e31 Alexander Graf
2698 defb0e31 Alexander Graf
void HELPER(lctl)(uint32_t r1, uint64_t a2, uint32_t r3)
2699 defb0e31 Alexander Graf
{
2700 defb0e31 Alexander Graf
    int i;
2701 defb0e31 Alexander Graf
    uint64_t src = a2;
2702 defb0e31 Alexander Graf
2703 defb0e31 Alexander Graf
    for (i = r1;; i = (i + 1) % 16) {
2704 defb0e31 Alexander Graf
        env->cregs[i] = (env->cregs[i] & 0xFFFFFFFF00000000ULL) | ldl(src);
2705 defb0e31 Alexander Graf
        src += sizeof(uint32_t);
2706 defb0e31 Alexander Graf
2707 defb0e31 Alexander Graf
        if (i == r3) {
2708 defb0e31 Alexander Graf
            break;
2709 defb0e31 Alexander Graf
        }
2710 defb0e31 Alexander Graf
    }
2711 defb0e31 Alexander Graf
2712 defb0e31 Alexander Graf
    tlb_flush(env, 1);
2713 defb0e31 Alexander Graf
}
2714 defb0e31 Alexander Graf
2715 defb0e31 Alexander Graf
void HELPER(stctg)(uint32_t r1, uint64_t a2, uint32_t r3)
2716 defb0e31 Alexander Graf
{
2717 defb0e31 Alexander Graf
    int i;
2718 defb0e31 Alexander Graf
    uint64_t dest = a2;
2719 defb0e31 Alexander Graf
2720 defb0e31 Alexander Graf
    for (i = r1;; i = (i + 1) % 16) {
2721 defb0e31 Alexander Graf
        stq(dest, env->cregs[i]);
2722 defb0e31 Alexander Graf
        dest += sizeof(uint64_t);
2723 defb0e31 Alexander Graf
2724 defb0e31 Alexander Graf
        if (i == r3) {
2725 defb0e31 Alexander Graf
            break;
2726 defb0e31 Alexander Graf
        }
2727 defb0e31 Alexander Graf
    }
2728 defb0e31 Alexander Graf
}
2729 defb0e31 Alexander Graf
2730 defb0e31 Alexander Graf
void HELPER(stctl)(uint32_t r1, uint64_t a2, uint32_t r3)
2731 defb0e31 Alexander Graf
{
2732 defb0e31 Alexander Graf
    int i;
2733 defb0e31 Alexander Graf
    uint64_t dest = a2;
2734 defb0e31 Alexander Graf
2735 defb0e31 Alexander Graf
    for (i = r1;; i = (i + 1) % 16) {
2736 defb0e31 Alexander Graf
        stl(dest, env->cregs[i]);
2737 defb0e31 Alexander Graf
        dest += sizeof(uint32_t);
2738 defb0e31 Alexander Graf
2739 defb0e31 Alexander Graf
        if (i == r3) {
2740 defb0e31 Alexander Graf
            break;
2741 defb0e31 Alexander Graf
        }
2742 defb0e31 Alexander Graf
    }
2743 defb0e31 Alexander Graf
}
2744 defb0e31 Alexander Graf
2745 defb0e31 Alexander Graf
uint32_t HELPER(tprot)(uint64_t a1, uint64_t a2)
2746 defb0e31 Alexander Graf
{
2747 defb0e31 Alexander Graf
    /* XXX implement */
2748 defb0e31 Alexander Graf
2749 defb0e31 Alexander Graf
    return 0;
2750 defb0e31 Alexander Graf
}
2751 defb0e31 Alexander Graf
2752 defb0e31 Alexander Graf
/* insert storage key extended */
2753 defb0e31 Alexander Graf
uint64_t HELPER(iske)(uint64_t r2)
2754 defb0e31 Alexander Graf
{
2755 defb0e31 Alexander Graf
    uint64_t addr = get_address(0, 0, r2);
2756 defb0e31 Alexander Graf
2757 defb0e31 Alexander Graf
    if (addr > ram_size) {
2758 defb0e31 Alexander Graf
        return 0;
2759 defb0e31 Alexander Graf
    }
2760 defb0e31 Alexander Graf
2761 defb0e31 Alexander Graf
    /* XXX maybe use qemu's internal keys? */
2762 defb0e31 Alexander Graf
    return env->storage_keys[addr / TARGET_PAGE_SIZE];
2763 defb0e31 Alexander Graf
}
2764 defb0e31 Alexander Graf
2765 defb0e31 Alexander Graf
/* set storage key extended */
2766 defb0e31 Alexander Graf
void HELPER(sske)(uint32_t r1, uint64_t r2)
2767 defb0e31 Alexander Graf
{
2768 defb0e31 Alexander Graf
    uint64_t addr = get_address(0, 0, r2);
2769 defb0e31 Alexander Graf
2770 defb0e31 Alexander Graf
    if (addr > ram_size) {
2771 defb0e31 Alexander Graf
        return;
2772 defb0e31 Alexander Graf
    }
2773 defb0e31 Alexander Graf
2774 defb0e31 Alexander Graf
    env->storage_keys[addr / TARGET_PAGE_SIZE] = r1;
2775 defb0e31 Alexander Graf
}
2776 defb0e31 Alexander Graf
2777 defb0e31 Alexander Graf
/* reset reference bit extended */
2778 defb0e31 Alexander Graf
uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2)
2779 defb0e31 Alexander Graf
{
2780 defb0e31 Alexander Graf
    if (r2 > ram_size) {
2781 defb0e31 Alexander Graf
        return 0;
2782 defb0e31 Alexander Graf
    }
2783 defb0e31 Alexander Graf
2784 defb0e31 Alexander Graf
    /* XXX implement */
2785 defb0e31 Alexander Graf
#if 0
2786 defb0e31 Alexander Graf
    env->storage_keys[r2 / TARGET_PAGE_SIZE] &= ~SK_REFERENCED;
2787 defb0e31 Alexander Graf
#endif
2788 defb0e31 Alexander Graf
2789 defb0e31 Alexander Graf
    /*
2790 defb0e31 Alexander Graf
     * cc
2791 defb0e31 Alexander Graf
     *
2792 defb0e31 Alexander Graf
     * 0  Reference bit zero; change bit zero
2793 defb0e31 Alexander Graf
     * 1  Reference bit zero; change bit one
2794 defb0e31 Alexander Graf
     * 2  Reference bit one; change bit zero
2795 defb0e31 Alexander Graf
     * 3  Reference bit one; change bit one
2796 defb0e31 Alexander Graf
     */
2797 d5a43964 Alexander Graf
    return 0;
2798 d5a43964 Alexander Graf
}
2799 defb0e31 Alexander Graf
2800 defb0e31 Alexander Graf
/* compare and swap and purge */
2801 defb0e31 Alexander Graf
uint32_t HELPER(csp)(uint32_t r1, uint32_t r2)
2802 defb0e31 Alexander Graf
{
2803 defb0e31 Alexander Graf
    uint32_t cc;
2804 defb0e31 Alexander Graf
    uint32_t o1 = env->regs[r1];
2805 defb0e31 Alexander Graf
    uint64_t a2 = get_address_31fix(r2) & ~3ULL;
2806 defb0e31 Alexander Graf
    uint32_t o2 = ldl(a2);
2807 defb0e31 Alexander Graf
2808 defb0e31 Alexander Graf
    if (o1 == o2) {
2809 defb0e31 Alexander Graf
        stl(a2, env->regs[(r1 + 1) & 15]);
2810 defb0e31 Alexander Graf
        if (env->regs[r2] & 0x3) {
2811 defb0e31 Alexander Graf
            /* flush TLB / ALB */
2812 defb0e31 Alexander Graf
            tlb_flush(env, 1);
2813 defb0e31 Alexander Graf
        }
2814 defb0e31 Alexander Graf
        cc = 0;
2815 defb0e31 Alexander Graf
    } else {
2816 defb0e31 Alexander Graf
        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | o2;
2817 defb0e31 Alexander Graf
        cc = 1;
2818 defb0e31 Alexander Graf
    }
2819 defb0e31 Alexander Graf
2820 defb0e31 Alexander Graf
    return cc;
2821 defb0e31 Alexander Graf
}
2822 defb0e31 Alexander Graf
2823 defb0e31 Alexander Graf
static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
2824 defb0e31 Alexander Graf
                        uint64_t mode2)
2825 defb0e31 Alexander Graf
{
2826 defb0e31 Alexander Graf
    target_ulong src, dest;
2827 defb0e31 Alexander Graf
    int flags, cc = 0, i;
2828 defb0e31 Alexander Graf
2829 defb0e31 Alexander Graf
    if (!l) {
2830 defb0e31 Alexander Graf
        return 0;
2831 defb0e31 Alexander Graf
    } else if (l > 256) {
2832 defb0e31 Alexander Graf
        /* max 256 */
2833 defb0e31 Alexander Graf
        l = 256;
2834 defb0e31 Alexander Graf
        cc = 3;
2835 defb0e31 Alexander Graf
    }
2836 defb0e31 Alexander Graf
2837 defb0e31 Alexander Graf
    if (mmu_translate(env, a1 & TARGET_PAGE_MASK, 1, mode1, &dest, &flags)) {
2838 defb0e31 Alexander Graf
        cpu_loop_exit();
2839 defb0e31 Alexander Graf
    }
2840 defb0e31 Alexander Graf
    dest |= a1 & ~TARGET_PAGE_MASK;
2841 defb0e31 Alexander Graf
2842 defb0e31 Alexander Graf
    if (mmu_translate(env, a2 & TARGET_PAGE_MASK, 0, mode2, &src, &flags)) {
2843 defb0e31 Alexander Graf
        cpu_loop_exit();
2844 defb0e31 Alexander Graf
    }
2845 defb0e31 Alexander Graf
    src |= a2 & ~TARGET_PAGE_MASK;
2846 defb0e31 Alexander Graf
2847 defb0e31 Alexander Graf
    /* XXX replace w/ memcpy */
2848 defb0e31 Alexander Graf
    for (i = 0; i < l; i++) {
2849 defb0e31 Alexander Graf
        /* XXX be more clever */
2850 defb0e31 Alexander Graf
        if ((((dest + i) & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) ||
2851 defb0e31 Alexander Graf
            (((src + i) & TARGET_PAGE_MASK) != (src & TARGET_PAGE_MASK))) {
2852 defb0e31 Alexander Graf
            mvc_asc(l - i, a1 + i, mode1, a2 + i, mode2);
2853 defb0e31 Alexander Graf
            break;
2854 defb0e31 Alexander Graf
        }
2855 defb0e31 Alexander Graf
        stb_phys(dest + i, ldub_phys(src + i));
2856 defb0e31 Alexander Graf
    }
2857 defb0e31 Alexander Graf
2858 defb0e31 Alexander Graf
    return cc;
2859 defb0e31 Alexander Graf
}
2860 defb0e31 Alexander Graf
2861 defb0e31 Alexander Graf
uint32_t HELPER(mvcs)(uint64_t l, uint64_t a1, uint64_t a2)
2862 defb0e31 Alexander Graf
{
2863 defb0e31 Alexander Graf
    HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
2864 defb0e31 Alexander Graf
               __FUNCTION__, l, a1, a2);
2865 defb0e31 Alexander Graf
2866 defb0e31 Alexander Graf
    return mvc_asc(l, a1, PSW_ASC_SECONDARY, a2, PSW_ASC_PRIMARY);
2867 defb0e31 Alexander Graf
}
2868 defb0e31 Alexander Graf
2869 defb0e31 Alexander Graf
uint32_t HELPER(mvcp)(uint64_t l, uint64_t a1, uint64_t a2)
2870 defb0e31 Alexander Graf
{
2871 defb0e31 Alexander Graf
    HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
2872 defb0e31 Alexander Graf
               __FUNCTION__, l, a1, a2);
2873 defb0e31 Alexander Graf
2874 defb0e31 Alexander Graf
    return mvc_asc(l, a1, PSW_ASC_PRIMARY, a2, PSW_ASC_SECONDARY);
2875 defb0e31 Alexander Graf
}
2876 defb0e31 Alexander Graf
2877 defb0e31 Alexander Graf
uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
2878 defb0e31 Alexander Graf
{
2879 defb0e31 Alexander Graf
    int cc = 0;
2880 defb0e31 Alexander Graf
2881 defb0e31 Alexander Graf
    HELPER_LOG("%s: %016" PRIx64 " %08x %016" PRIx64 "\n",
2882 defb0e31 Alexander Graf
               __FUNCTION__, order_code, r1, cpu_addr);
2883 defb0e31 Alexander Graf
2884 defb0e31 Alexander Graf
    /* Remember: Use "R1 or R1+1, whichever is the odd-numbered register"
2885 defb0e31 Alexander Graf
       as parameter (input). Status (output) is always R1. */
2886 defb0e31 Alexander Graf
2887 defb0e31 Alexander Graf
    switch (order_code) {
2888 defb0e31 Alexander Graf
    case SIGP_SET_ARCH:
2889 defb0e31 Alexander Graf
        /* switch arch */
2890 defb0e31 Alexander Graf
        break;
2891 defb0e31 Alexander Graf
    case SIGP_SENSE:
2892 defb0e31 Alexander Graf
        /* enumerate CPU status */
2893 defb0e31 Alexander Graf
        if (cpu_addr) {
2894 defb0e31 Alexander Graf
            /* XXX implement when SMP comes */
2895 defb0e31 Alexander Graf
            return 3;
2896 defb0e31 Alexander Graf
        }
2897 defb0e31 Alexander Graf
        env->regs[r1] &= 0xffffffff00000000ULL;
2898 defb0e31 Alexander Graf
        cc = 1;
2899 defb0e31 Alexander Graf
        break;
2900 defb0e31 Alexander Graf
    default:
2901 defb0e31 Alexander Graf
        /* unknown sigp */
2902 defb0e31 Alexander Graf
        fprintf(stderr, "XXX unknown sigp: 0x%" PRIx64 "\n", order_code);
2903 defb0e31 Alexander Graf
        cc = 3;
2904 defb0e31 Alexander Graf
    }
2905 defb0e31 Alexander Graf
2906 defb0e31 Alexander Graf
    return cc;
2907 defb0e31 Alexander Graf
}
2908 defb0e31 Alexander Graf
2909 defb0e31 Alexander Graf
void HELPER(sacf)(uint64_t a1)
2910 defb0e31 Alexander Graf
{
2911 defb0e31 Alexander Graf
    HELPER_LOG("%s: %16" PRIx64 "\n", __FUNCTION__, a1);
2912 defb0e31 Alexander Graf
2913 defb0e31 Alexander Graf
    switch (a1 & 0xf00) {
2914 defb0e31 Alexander Graf
    case 0x000:
2915 defb0e31 Alexander Graf
        env->psw.mask &= ~PSW_MASK_ASC;
2916 defb0e31 Alexander Graf
        env->psw.mask |= PSW_ASC_PRIMARY;
2917 defb0e31 Alexander Graf
        break;
2918 defb0e31 Alexander Graf
    case 0x100:
2919 defb0e31 Alexander Graf
        env->psw.mask &= ~PSW_MASK_ASC;
2920 defb0e31 Alexander Graf
        env->psw.mask |= PSW_ASC_SECONDARY;
2921 defb0e31 Alexander Graf
        break;
2922 defb0e31 Alexander Graf
    case 0x300:
2923 defb0e31 Alexander Graf
        env->psw.mask &= ~PSW_MASK_ASC;
2924 defb0e31 Alexander Graf
        env->psw.mask |= PSW_ASC_HOME;
2925 defb0e31 Alexander Graf
        break;
2926 defb0e31 Alexander Graf
    default:
2927 defb0e31 Alexander Graf
        qemu_log("unknown sacf mode: %" PRIx64 "\n", a1);
2928 defb0e31 Alexander Graf
        program_interrupt(env, PGM_SPECIFICATION, 2);
2929 defb0e31 Alexander Graf
        break;
2930 defb0e31 Alexander Graf
    }
2931 defb0e31 Alexander Graf
}
2932 defb0e31 Alexander Graf
2933 defb0e31 Alexander Graf
/* invalidate pte */
2934 defb0e31 Alexander Graf
void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
2935 defb0e31 Alexander Graf
{
2936 defb0e31 Alexander Graf
    uint64_t page = vaddr & TARGET_PAGE_MASK;
2937 defb0e31 Alexander Graf
    uint64_t pte = 0;
2938 defb0e31 Alexander Graf
2939 defb0e31 Alexander Graf
    /* XXX broadcast to other CPUs */
2940 defb0e31 Alexander Graf
2941 defb0e31 Alexander Graf
    /* XXX Linux is nice enough to give us the exact pte address.
2942 defb0e31 Alexander Graf
           According to spec we'd have to find it out ourselves */
2943 defb0e31 Alexander Graf
    /* XXX Linux is fine with overwriting the pte, the spec requires
2944 defb0e31 Alexander Graf
           us to only set the invalid bit */
2945 defb0e31 Alexander Graf
    stq_phys(pte_addr, pte | _PAGE_INVALID);
2946 defb0e31 Alexander Graf
2947 defb0e31 Alexander Graf
    /* XXX we exploit the fact that Linux passes the exact virtual
2948 defb0e31 Alexander Graf
           address here - it's not obliged to! */
2949 defb0e31 Alexander Graf
    tlb_flush_page(env, page);
2950 defb0e31 Alexander Graf
}
2951 defb0e31 Alexander Graf
2952 defb0e31 Alexander Graf
/* flush local tlb */
2953 defb0e31 Alexander Graf
void HELPER(ptlb)(void)
2954 defb0e31 Alexander Graf
{
2955 defb0e31 Alexander Graf
    tlb_flush(env, 1);
2956 defb0e31 Alexander Graf
}
2957 defb0e31 Alexander Graf
2958 defb0e31 Alexander Graf
/* store using real address */
2959 defb0e31 Alexander Graf
void HELPER(stura)(uint64_t addr, uint32_t v1)
2960 defb0e31 Alexander Graf
{
2961 defb0e31 Alexander Graf
    stw_phys(get_address(0, 0, addr), v1);
2962 defb0e31 Alexander Graf
}
2963 defb0e31 Alexander Graf
2964 defb0e31 Alexander Graf
/* load real address */
2965 defb0e31 Alexander Graf
uint32_t HELPER(lra)(uint64_t addr, uint32_t r1)
2966 defb0e31 Alexander Graf
{
2967 defb0e31 Alexander Graf
    uint32_t cc = 0;
2968 defb0e31 Alexander Graf
    int old_exc = env->exception_index;
2969 defb0e31 Alexander Graf
    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
2970 defb0e31 Alexander Graf
    uint64_t ret;
2971 defb0e31 Alexander Graf
    int flags;
2972 defb0e31 Alexander Graf
2973 defb0e31 Alexander Graf
    /* XXX incomplete - has more corner cases */
2974 defb0e31 Alexander Graf
    if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
2975 defb0e31 Alexander Graf
        program_interrupt(env, PGM_SPECIAL_OP, 2);
2976 defb0e31 Alexander Graf
    }
2977 defb0e31 Alexander Graf
2978 defb0e31 Alexander Graf
    env->exception_index = old_exc;
2979 defb0e31 Alexander Graf
    if (mmu_translate(env, addr, 0, asc, &ret, &flags)) {
2980 defb0e31 Alexander Graf
        cc = 3;
2981 defb0e31 Alexander Graf
    }
2982 defb0e31 Alexander Graf
    if (env->exception_index == EXCP_PGM) {
2983 defb0e31 Alexander Graf
        ret = env->int_pgm_code | 0x80000000;
2984 defb0e31 Alexander Graf
    } else {
2985 defb0e31 Alexander Graf
        ret |= addr & ~TARGET_PAGE_MASK;
2986 defb0e31 Alexander Graf
    }
2987 defb0e31 Alexander Graf
    env->exception_index = old_exc;
2988 defb0e31 Alexander Graf
2989 defb0e31 Alexander Graf
    if (!(env->psw.mask & PSW_MASK_64)) {
2990 defb0e31 Alexander Graf
        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | (ret & 0xffffffffULL);
2991 defb0e31 Alexander Graf
    } else {
2992 defb0e31 Alexander Graf
        env->regs[r1] = ret;
2993 defb0e31 Alexander Graf
    }
2994 defb0e31 Alexander Graf
2995 defb0e31 Alexander Graf
    return cc;
2996 defb0e31 Alexander Graf
}
2997 defb0e31 Alexander Graf
2998 defb0e31 Alexander Graf
#endif