1 From e9f67c1f326a995ff0000a08a223435386867d8f Mon Sep 17 00:00:00 2001
2 From: Blue Swirl <blauwirbel@gmail.com>
3 Date: Sun, 2 Sep 2012 07:33:33 +0000
4 Subject: [PATCH] target-s390x: split integer helpers
6 Move integer helpers to int_helper.c.
8 Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
9 Signed-off-by: Alexander Graf <agraf@suse.de>
10 Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
12 target-s390x/Makefile.objs | 3 +-
13 target-s390x/int_helper.c | 201 +++++++++++++++++++++++++++++++++++++++++++++
14 target-s390x/op_helper.c | 170 --------------------------------------
15 3 files changed, 203 insertions(+), 171 deletions(-)
16 create mode 100644 target-s390x/int_helper.c
18 diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
19 index f9437d6..e8f66e9 100644
20 --- a/target-s390x/Makefile.objs
21 +++ b/target-s390x/Makefile.objs
23 obj-y += translate.o op_helper.o helper.o cpu.o interrupt.o
24 -obj-y += fpu_helper.o cc_helper.o
25 +obj-y += int_helper.o fpu_helper.o cc_helper.o
26 obj-$(CONFIG_SOFTMMU) += machine.o
27 obj-$(CONFIG_KVM) += kvm.o
29 $(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
30 +$(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
31 $(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
32 $(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
33 diff --git a/target-s390x/int_helper.c b/target-s390x/int_helper.c
35 index 0000000..e2eeb07
37 +++ b/target-s390x/int_helper.c
40 + * S/390 integer helper routines
42 + * Copyright (c) 2009 Ulrich Hecht
43 + * Copyright (c) 2009 Alexander Graf
45 + * This library is free software; you can redistribute it and/or
46 + * modify it under the terms of the GNU Lesser General Public
47 + * License as published by the Free Software Foundation; either
48 + * version 2 of the License, or (at your option) any later version.
50 + * This library is distributed in the hope that it will be useful,
51 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
52 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
53 + * Lesser General Public License for more details.
55 + * You should have received a copy of the GNU Lesser General Public
56 + * License along with this library; if not, see <http://www.gnu.org/licenses/>.
60 +#include "dyngen-exec.h"
61 +#include "host-utils.h"
64 +/* #define DEBUG_HELPER */
66 +#define HELPER_LOG(x...) qemu_log(x)
68 +#define HELPER_LOG(x...)
71 +/* 64/64 -> 128 unsigned multiplication */
72 +void HELPER(mlg)(uint32_t r1, uint64_t v2)
74 +#if HOST_LONG_BITS == 64 && defined(__GNUC__)
75 + /* assuming 64-bit hosts have __uint128_t */
76 + __uint128_t res = (__uint128_t)env->regs[r1 + 1];
78 + res *= (__uint128_t)v2;
79 + env->regs[r1] = (uint64_t)(res >> 64);
80 + env->regs[r1 + 1] = (uint64_t)res;
82 + mulu64(&env->regs[r1 + 1], &env->regs[r1], env->regs[r1 + 1], v2);
86 +/* 128 -> 64/64 unsigned division */
87 +void HELPER(dlg)(uint32_t r1, uint64_t v2)
89 + uint64_t divisor = v2;
91 + if (!env->regs[r1]) {
92 + /* 64 -> 64/64 case */
93 + env->regs[r1] = env->regs[r1 + 1] % divisor;
94 + env->regs[r1 + 1] = env->regs[r1 + 1] / divisor;
97 +#if HOST_LONG_BITS == 64 && defined(__GNUC__)
98 + /* assuming 64-bit hosts have __uint128_t */
99 + __uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) |
100 + (env->regs[r1 + 1]);
101 + __uint128_t quotient = dividend / divisor;
102 + __uint128_t remainder = dividend % divisor;
104 + env->regs[r1 + 1] = quotient;
105 + env->regs[r1] = remainder;
107 + /* 32-bit hosts would need special wrapper functionality - just abort if
108 + we encounter such a case; it's very unlikely anyways. */
109 + cpu_abort(env, "128 -> 64/64 division not implemented\n");
114 +/* absolute value 32-bit */
115 +uint32_t HELPER(abs_i32)(int32_t val)
124 +/* negative absolute value 32-bit */
125 +int32_t HELPER(nabs_i32)(int32_t val)
134 +/* absolute value 64-bit */
135 +uint64_t HELPER(abs_i64)(int64_t val)
137 + HELPER_LOG("%s: val 0x%" PRIx64 "\n", __func__, val);
146 +/* negative absolute value 64-bit */
147 +int64_t HELPER(nabs_i64)(int64_t val)
156 +/* add with carry 32-bit unsigned */
157 +uint32_t HELPER(addc_u32)(uint32_t cc, uint32_t v1, uint32_t v2)
169 +/* subtract unsigned v2 from v1 with borrow */
170 +uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2)
172 + uint32_t v1 = env->regs[r1];
173 + uint32_t res = v1 + (~v2) + (cc >> 1);
175 + env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | res;
184 +/* subtract unsigned v2 from v1 with borrow */
185 +uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
187 + uint64_t res = v1 + (~v2) + (cc >> 1);
189 + env->regs[r1] = res;
198 +/* find leftmost one */
199 +uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
204 + while (!(v2 & 0x8000000000000000ULL) && v2) {
210 + env->regs[r1] = 64;
211 + env->regs[r1 + 1] = 0;
214 + env->regs[r1] = res;
215 + env->regs[r1 + 1] = ov2 & ~(0x8000000000000000ULL >> res);
220 +uint64_t HELPER(cvd)(int32_t bin)
223 + uint64_t dec = 0x0c;
231 + for (shift = 4; (shift < 64) && bin; shift += 4) {
232 + int current_number = bin % 10;
234 + dec |= (current_number) << shift;
240 diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
241 index eced890..3b8b997 100644
242 --- a/target-s390x/op_helper.c
243 +++ b/target-s390x/op_helper.c
244 @@ -352,49 +352,6 @@ void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
248 -/* 64/64 -> 128 unsigned multiplication */
249 -void HELPER(mlg)(uint32_t r1, uint64_t v2)
251 -#if HOST_LONG_BITS == 64 && defined(__GNUC__)
252 - /* assuming 64-bit hosts have __uint128_t */
253 - __uint128_t res = (__uint128_t)env->regs[r1 + 1];
255 - res *= (__uint128_t)v2;
256 - env->regs[r1] = (uint64_t)(res >> 64);
257 - env->regs[r1 + 1] = (uint64_t)res;
259 - mulu64(&env->regs[r1 + 1], &env->regs[r1], env->regs[r1 + 1], v2);
263 -/* 128 -> 64/64 unsigned division */
264 -void HELPER(dlg)(uint32_t r1, uint64_t v2)
266 - uint64_t divisor = v2;
268 - if (!env->regs[r1]) {
269 - /* 64 -> 64/64 case */
270 - env->regs[r1] = env->regs[r1 + 1] % divisor;
271 - env->regs[r1 + 1] = env->regs[r1 + 1] / divisor;
274 -#if HOST_LONG_BITS == 64 && defined(__GNUC__)
275 - /* assuming 64-bit hosts have __uint128_t */
276 - __uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) |
277 - (env->regs[r1 + 1]);
278 - __uint128_t quotient = dividend / divisor;
279 - __uint128_t remainder = dividend % divisor;
281 - env->regs[r1 + 1] = quotient;
282 - env->regs[r1] = remainder;
284 - /* 32-bit hosts would need special wrapper functionality - just abort if
285 - we encounter such a case; it's very unlikely anyways. */
286 - cpu_abort(env, "128 -> 64/64 division not implemented\n");
291 static inline uint64_t get_address(int x2, int b2, int d2)
294 @@ -677,61 +634,6 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
298 -/* absolute value 32-bit */
299 -uint32_t HELPER(abs_i32)(int32_t val)
308 -/* negative absolute value 32-bit */
309 -int32_t HELPER(nabs_i32)(int32_t val)
318 -/* absolute value 64-bit */
319 -uint64_t HELPER(abs_i64)(int64_t val)
321 - HELPER_LOG("%s: val 0x%" PRIx64 "\n", __func__, val);
330 -/* negative absolute value 64-bit */
331 -int64_t HELPER(nabs_i64)(int64_t val)
340 -/* add with carry 32-bit unsigned */
341 -uint32_t HELPER(addc_u32)(uint32_t cc, uint32_t v1, uint32_t v2)
353 /* store character under mask high operates on the upper half of r1 */
354 void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask)
356 @@ -936,57 +838,6 @@ uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
360 -/* subtract unsigned v2 from v1 with borrow */
361 -uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2)
363 - uint32_t v1 = env->regs[r1];
364 - uint32_t res = v1 + (~v2) + (cc >> 1);
366 - env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | res;
375 -/* subtract unsigned v2 from v1 with borrow */
376 -uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
378 - uint64_t res = v1 + (~v2) + (cc >> 1);
380 - env->regs[r1] = res;
389 -/* find leftmost one */
390 -uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
395 - while (!(v2 & 0x8000000000000000ULL) && v2) {
401 - env->regs[r1] = 64;
402 - env->regs[r1 + 1] = 0;
405 - env->regs[r1] = res;
406 - env->regs[r1 + 1] = ov2 & ~(0x8000000000000000ULL >> res);
412 void HELPER(cksm)(uint32_t r1, uint32_t r2)
414 @@ -1026,27 +877,6 @@ void HELPER(cksm)(uint32_t r1, uint32_t r2)
415 ((uint32_t)cksm + (cksm >> 32));
418 -uint64_t HELPER(cvd)(int32_t bin)
421 - uint64_t dec = 0x0c;
429 - for (shift = 4; (shift < 64) && bin; shift += 4) {
430 - int current_number = bin % 10;
432 - dec |= (current_number) << shift;
439 void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
441 int len_dest = len >> 4;