Statistics
| Branch: | Revision:

root / target-s390x / op_helper.c @ 814589c4

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