1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "qemu/osdep.h"
22#include "cpu.h"
23#include "qemu/host-utils.h"
24#include "exec/helper-proto.h"
25
26
27#ifdef DEBUG_HELPER
28#define HELPER_LOG(x...) qemu_log(x)
29#else
30#define HELPER_LOG(x...)
31#endif
32
33
34int64_t HELPER(divs32)(CPUS390XState *env, int64_t a, int64_t b64)
35{
36 int32_t ret, b = b64;
37 int64_t q;
38
39 if (b == 0) {
40 runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
41 }
42
43 ret = q = a / b;
44 env->retxl = a % b;
45
46
47 if (ret != q) {
48 runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
49 }
50
51 return ret;
52}
53
54
55uint64_t HELPER(divu32)(CPUS390XState *env, uint64_t a, uint64_t b64)
56{
57 uint32_t ret, b = b64;
58 uint64_t q;
59
60 if (b == 0) {
61 runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
62 }
63
64 ret = q = a / b;
65 env->retxl = a % b;
66
67
68 if (ret != q) {
69 runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
70 }
71
72 return ret;
73}
74
75
76int64_t HELPER(divs64)(CPUS390XState *env, int64_t a, int64_t b)
77{
78
79 if (b == 0 || (b == -1 && a == (1ll << 63))) {
80 runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
81 }
82 env->retxl = a % b;
83 return a / b;
84}
85
86
87uint64_t HELPER(divu64)(CPUS390XState *env, uint64_t ah, uint64_t al,
88 uint64_t b)
89{
90 uint64_t ret;
91
92 if (b == 0) {
93 runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
94 }
95 if (ah == 0) {
96
97 env->retxl = al % b;
98 ret = al / b;
99 } else {
100
101#ifdef CONFIG_INT128
102 __uint128_t a = ((__uint128_t)ah << 64) | al;
103 __uint128_t q = a / b;
104 env->retxl = a % b;
105 ret = q;
106 if (ret != q) {
107 runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
108 }
109#else
110 S390CPU *cpu = s390_env_get_cpu(env);
111
112
113 cpu_abort(CPU(cpu), "128 -> 64/64 division not implemented\n");
114#endif
115 }
116 return ret;
117}
118
119
120uint64_t HELPER(clz)(uint64_t v)
121{
122 return clz64(v);
123}
124
125uint64_t HELPER(cvd)(int32_t reg)
126{
127
128 uint64_t dec = 0x0c;
129 int64_t bin = reg;
130 int shift;
131
132 if (bin < 0) {
133 bin = -bin;
134 dec = 0x0d;
135 }
136
137 for (shift = 4; (shift < 64) && bin; shift += 4) {
138 dec |= (bin % 10) << shift;
139 bin /= 10;
140 }
141
142 return dec;
143}
144
145uint64_t HELPER(popcnt)(uint64_t r2)
146{
147 uint64_t ret = 0;
148 int i;
149
150 for (i = 0; i < 64; i += 8) {
151 uint64_t t = ctpop32((r2 >> i) & 0xff);
152 ret |= t << i;
153 }
154 return ret;
155}
156