Statistics
| Branch: | Revision:

root / target-i386 / int_helper.c @ 4d5b97da

History | View | Annotate | Download (10.4 kB)

1 d7582078 Blue Swirl
/*
2 d7582078 Blue Swirl
 *  x86 integer helpers
3 d7582078 Blue Swirl
 *
4 d7582078 Blue Swirl
 *  Copyright (c) 2003 Fabrice Bellard
5 d7582078 Blue Swirl
 *
6 d7582078 Blue Swirl
 * This library is free software; you can redistribute it and/or
7 d7582078 Blue Swirl
 * modify it under the terms of the GNU Lesser General Public
8 d7582078 Blue Swirl
 * License as published by the Free Software Foundation; either
9 d7582078 Blue Swirl
 * version 2 of the License, or (at your option) any later version.
10 d7582078 Blue Swirl
 *
11 d7582078 Blue Swirl
 * This library is distributed in the hope that it will be useful,
12 d7582078 Blue Swirl
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 d7582078 Blue Swirl
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 d7582078 Blue Swirl
 * Lesser General Public License for more details.
15 d7582078 Blue Swirl
 *
16 d7582078 Blue Swirl
 * You should have received a copy of the GNU Lesser General Public
17 d7582078 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 d7582078 Blue Swirl
 */
19 d7582078 Blue Swirl
20 d7582078 Blue Swirl
#include "cpu.h"
21 d7582078 Blue Swirl
#include "host-utils.h"
22 d7582078 Blue Swirl
#include "helper.h"
23 d7582078 Blue Swirl
24 d7582078 Blue Swirl
//#define DEBUG_MULDIV
25 d7582078 Blue Swirl
26 d7582078 Blue Swirl
/* modulo 9 table */
27 d7582078 Blue Swirl
static const uint8_t rclb_table[32] = {
28 d7582078 Blue Swirl
    0, 1, 2, 3, 4, 5, 6, 7,
29 d7582078 Blue Swirl
    8, 0, 1, 2, 3, 4, 5, 6,
30 d7582078 Blue Swirl
    7, 8, 0, 1, 2, 3, 4, 5,
31 d7582078 Blue Swirl
    6, 7, 8, 0, 1, 2, 3, 4,
32 d7582078 Blue Swirl
};
33 d7582078 Blue Swirl
34 d7582078 Blue Swirl
/* modulo 17 table */
35 d7582078 Blue Swirl
static const uint8_t rclw_table[32] = {
36 d7582078 Blue Swirl
    0, 1, 2, 3, 4, 5, 6, 7,
37 d7582078 Blue Swirl
    8, 9, 10, 11, 12, 13, 14, 15,
38 d7582078 Blue Swirl
    16, 0, 1, 2, 3, 4, 5, 6,
39 d7582078 Blue Swirl
    7, 8, 9, 10, 11, 12, 13, 14,
40 d7582078 Blue Swirl
};
41 d7582078 Blue Swirl
42 d7582078 Blue Swirl
/* division, flags are undefined */
43 d7582078 Blue Swirl
44 7923057b Blue Swirl
void helper_divb_AL(CPUX86State *env, target_ulong t0)
45 d7582078 Blue Swirl
{
46 d7582078 Blue Swirl
    unsigned int num, den, q, r;
47 d7582078 Blue Swirl
48 d7582078 Blue Swirl
    num = (EAX & 0xffff);
49 d7582078 Blue Swirl
    den = (t0 & 0xff);
50 d7582078 Blue Swirl
    if (den == 0) {
51 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
52 d7582078 Blue Swirl
    }
53 d7582078 Blue Swirl
    q = (num / den);
54 d7582078 Blue Swirl
    if (q > 0xff) {
55 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
56 d7582078 Blue Swirl
    }
57 d7582078 Blue Swirl
    q &= 0xff;
58 d7582078 Blue Swirl
    r = (num % den) & 0xff;
59 d7582078 Blue Swirl
    EAX = (EAX & ~0xffff) | (r << 8) | q;
60 d7582078 Blue Swirl
}
61 d7582078 Blue Swirl
62 7923057b Blue Swirl
void helper_idivb_AL(CPUX86State *env, target_ulong t0)
63 d7582078 Blue Swirl
{
64 d7582078 Blue Swirl
    int num, den, q, r;
65 d7582078 Blue Swirl
66 d7582078 Blue Swirl
    num = (int16_t)EAX;
67 d7582078 Blue Swirl
    den = (int8_t)t0;
68 d7582078 Blue Swirl
    if (den == 0) {
69 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
70 d7582078 Blue Swirl
    }
71 d7582078 Blue Swirl
    q = (num / den);
72 d7582078 Blue Swirl
    if (q != (int8_t)q) {
73 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
74 d7582078 Blue Swirl
    }
75 d7582078 Blue Swirl
    q &= 0xff;
76 d7582078 Blue Swirl
    r = (num % den) & 0xff;
77 d7582078 Blue Swirl
    EAX = (EAX & ~0xffff) | (r << 8) | q;
78 d7582078 Blue Swirl
}
79 d7582078 Blue Swirl
80 7923057b Blue Swirl
void helper_divw_AX(CPUX86State *env, target_ulong t0)
81 d7582078 Blue Swirl
{
82 d7582078 Blue Swirl
    unsigned int num, den, q, r;
83 d7582078 Blue Swirl
84 d7582078 Blue Swirl
    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
85 d7582078 Blue Swirl
    den = (t0 & 0xffff);
86 d7582078 Blue Swirl
    if (den == 0) {
87 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
88 d7582078 Blue Swirl
    }
89 d7582078 Blue Swirl
    q = (num / den);
90 d7582078 Blue Swirl
    if (q > 0xffff) {
91 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
92 d7582078 Blue Swirl
    }
93 d7582078 Blue Swirl
    q &= 0xffff;
94 d7582078 Blue Swirl
    r = (num % den) & 0xffff;
95 d7582078 Blue Swirl
    EAX = (EAX & ~0xffff) | q;
96 d7582078 Blue Swirl
    EDX = (EDX & ~0xffff) | r;
97 d7582078 Blue Swirl
}
98 d7582078 Blue Swirl
99 7923057b Blue Swirl
void helper_idivw_AX(CPUX86State *env, target_ulong t0)
100 d7582078 Blue Swirl
{
101 d7582078 Blue Swirl
    int num, den, q, r;
102 d7582078 Blue Swirl
103 d7582078 Blue Swirl
    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
104 d7582078 Blue Swirl
    den = (int16_t)t0;
105 d7582078 Blue Swirl
    if (den == 0) {
106 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
107 d7582078 Blue Swirl
    }
108 d7582078 Blue Swirl
    q = (num / den);
109 d7582078 Blue Swirl
    if (q != (int16_t)q) {
110 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
111 d7582078 Blue Swirl
    }
112 d7582078 Blue Swirl
    q &= 0xffff;
113 d7582078 Blue Swirl
    r = (num % den) & 0xffff;
114 d7582078 Blue Swirl
    EAX = (EAX & ~0xffff) | q;
115 d7582078 Blue Swirl
    EDX = (EDX & ~0xffff) | r;
116 d7582078 Blue Swirl
}
117 d7582078 Blue Swirl
118 7923057b Blue Swirl
void helper_divl_EAX(CPUX86State *env, target_ulong t0)
119 d7582078 Blue Swirl
{
120 d7582078 Blue Swirl
    unsigned int den, r;
121 d7582078 Blue Swirl
    uint64_t num, q;
122 d7582078 Blue Swirl
123 d7582078 Blue Swirl
    num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
124 d7582078 Blue Swirl
    den = t0;
125 d7582078 Blue Swirl
    if (den == 0) {
126 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
127 d7582078 Blue Swirl
    }
128 d7582078 Blue Swirl
    q = (num / den);
129 d7582078 Blue Swirl
    r = (num % den);
130 d7582078 Blue Swirl
    if (q > 0xffffffff) {
131 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
132 d7582078 Blue Swirl
    }
133 d7582078 Blue Swirl
    EAX = (uint32_t)q;
134 d7582078 Blue Swirl
    EDX = (uint32_t)r;
135 d7582078 Blue Swirl
}
136 d7582078 Blue Swirl
137 7923057b Blue Swirl
void helper_idivl_EAX(CPUX86State *env, target_ulong t0)
138 d7582078 Blue Swirl
{
139 d7582078 Blue Swirl
    int den, r;
140 d7582078 Blue Swirl
    int64_t num, q;
141 d7582078 Blue Swirl
142 d7582078 Blue Swirl
    num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
143 d7582078 Blue Swirl
    den = t0;
144 d7582078 Blue Swirl
    if (den == 0) {
145 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
146 d7582078 Blue Swirl
    }
147 d7582078 Blue Swirl
    q = (num / den);
148 d7582078 Blue Swirl
    r = (num % den);
149 d7582078 Blue Swirl
    if (q != (int32_t)q) {
150 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
151 d7582078 Blue Swirl
    }
152 d7582078 Blue Swirl
    EAX = (uint32_t)q;
153 d7582078 Blue Swirl
    EDX = (uint32_t)r;
154 d7582078 Blue Swirl
}
155 d7582078 Blue Swirl
156 d7582078 Blue Swirl
/* bcd */
157 d7582078 Blue Swirl
158 d7582078 Blue Swirl
/* XXX: exception */
159 7923057b Blue Swirl
void helper_aam(CPUX86State *env, int base)
160 d7582078 Blue Swirl
{
161 d7582078 Blue Swirl
    int al, ah;
162 d7582078 Blue Swirl
163 d7582078 Blue Swirl
    al = EAX & 0xff;
164 d7582078 Blue Swirl
    ah = al / base;
165 d7582078 Blue Swirl
    al = al % base;
166 d7582078 Blue Swirl
    EAX = (EAX & ~0xffff) | al | (ah << 8);
167 d7582078 Blue Swirl
    CC_DST = al;
168 d7582078 Blue Swirl
}
169 d7582078 Blue Swirl
170 7923057b Blue Swirl
void helper_aad(CPUX86State *env, int base)
171 d7582078 Blue Swirl
{
172 d7582078 Blue Swirl
    int al, ah;
173 d7582078 Blue Swirl
174 d7582078 Blue Swirl
    al = EAX & 0xff;
175 d7582078 Blue Swirl
    ah = (EAX >> 8) & 0xff;
176 d7582078 Blue Swirl
    al = ((ah * base) + al) & 0xff;
177 d7582078 Blue Swirl
    EAX = (EAX & ~0xffff) | al;
178 d7582078 Blue Swirl
    CC_DST = al;
179 d7582078 Blue Swirl
}
180 d7582078 Blue Swirl
181 7923057b Blue Swirl
void helper_aaa(CPUX86State *env)
182 d7582078 Blue Swirl
{
183 d7582078 Blue Swirl
    int icarry;
184 d7582078 Blue Swirl
    int al, ah, af;
185 d7582078 Blue Swirl
    int eflags;
186 d7582078 Blue Swirl
187 f0967a1a Blue Swirl
    eflags = cpu_cc_compute_all(env, CC_OP);
188 d7582078 Blue Swirl
    af = eflags & CC_A;
189 d7582078 Blue Swirl
    al = EAX & 0xff;
190 d7582078 Blue Swirl
    ah = (EAX >> 8) & 0xff;
191 d7582078 Blue Swirl
192 d7582078 Blue Swirl
    icarry = (al > 0xf9);
193 d7582078 Blue Swirl
    if (((al & 0x0f) > 9) || af) {
194 d7582078 Blue Swirl
        al = (al + 6) & 0x0f;
195 d7582078 Blue Swirl
        ah = (ah + 1 + icarry) & 0xff;
196 d7582078 Blue Swirl
        eflags |= CC_C | CC_A;
197 d7582078 Blue Swirl
    } else {
198 d7582078 Blue Swirl
        eflags &= ~(CC_C | CC_A);
199 d7582078 Blue Swirl
        al &= 0x0f;
200 d7582078 Blue Swirl
    }
201 d7582078 Blue Swirl
    EAX = (EAX & ~0xffff) | al | (ah << 8);
202 d7582078 Blue Swirl
    CC_SRC = eflags;
203 d7582078 Blue Swirl
}
204 d7582078 Blue Swirl
205 7923057b Blue Swirl
void helper_aas(CPUX86State *env)
206 d7582078 Blue Swirl
{
207 d7582078 Blue Swirl
    int icarry;
208 d7582078 Blue Swirl
    int al, ah, af;
209 d7582078 Blue Swirl
    int eflags;
210 d7582078 Blue Swirl
211 f0967a1a Blue Swirl
    eflags = cpu_cc_compute_all(env, CC_OP);
212 d7582078 Blue Swirl
    af = eflags & CC_A;
213 d7582078 Blue Swirl
    al = EAX & 0xff;
214 d7582078 Blue Swirl
    ah = (EAX >> 8) & 0xff;
215 d7582078 Blue Swirl
216 d7582078 Blue Swirl
    icarry = (al < 6);
217 d7582078 Blue Swirl
    if (((al & 0x0f) > 9) || af) {
218 d7582078 Blue Swirl
        al = (al - 6) & 0x0f;
219 d7582078 Blue Swirl
        ah = (ah - 1 - icarry) & 0xff;
220 d7582078 Blue Swirl
        eflags |= CC_C | CC_A;
221 d7582078 Blue Swirl
    } else {
222 d7582078 Blue Swirl
        eflags &= ~(CC_C | CC_A);
223 d7582078 Blue Swirl
        al &= 0x0f;
224 d7582078 Blue Swirl
    }
225 d7582078 Blue Swirl
    EAX = (EAX & ~0xffff) | al | (ah << 8);
226 d7582078 Blue Swirl
    CC_SRC = eflags;
227 d7582078 Blue Swirl
}
228 d7582078 Blue Swirl
229 7923057b Blue Swirl
void helper_daa(CPUX86State *env)
230 d7582078 Blue Swirl
{
231 d7582078 Blue Swirl
    int old_al, al, af, cf;
232 d7582078 Blue Swirl
    int eflags;
233 d7582078 Blue Swirl
234 f0967a1a Blue Swirl
    eflags = cpu_cc_compute_all(env, CC_OP);
235 d7582078 Blue Swirl
    cf = eflags & CC_C;
236 d7582078 Blue Swirl
    af = eflags & CC_A;
237 d7582078 Blue Swirl
    old_al = al = EAX & 0xff;
238 d7582078 Blue Swirl
239 d7582078 Blue Swirl
    eflags = 0;
240 d7582078 Blue Swirl
    if (((al & 0x0f) > 9) || af) {
241 d7582078 Blue Swirl
        al = (al + 6) & 0xff;
242 d7582078 Blue Swirl
        eflags |= CC_A;
243 d7582078 Blue Swirl
    }
244 d7582078 Blue Swirl
    if ((old_al > 0x99) || cf) {
245 d7582078 Blue Swirl
        al = (al + 0x60) & 0xff;
246 d7582078 Blue Swirl
        eflags |= CC_C;
247 d7582078 Blue Swirl
    }
248 d7582078 Blue Swirl
    EAX = (EAX & ~0xff) | al;
249 d7582078 Blue Swirl
    /* well, speed is not an issue here, so we compute the flags by hand */
250 d7582078 Blue Swirl
    eflags |= (al == 0) << 6; /* zf */
251 d7582078 Blue Swirl
    eflags |= parity_table[al]; /* pf */
252 d7582078 Blue Swirl
    eflags |= (al & 0x80); /* sf */
253 d7582078 Blue Swirl
    CC_SRC = eflags;
254 d7582078 Blue Swirl
}
255 d7582078 Blue Swirl
256 7923057b Blue Swirl
void helper_das(CPUX86State *env)
257 d7582078 Blue Swirl
{
258 d7582078 Blue Swirl
    int al, al1, af, cf;
259 d7582078 Blue Swirl
    int eflags;
260 d7582078 Blue Swirl
261 f0967a1a Blue Swirl
    eflags = cpu_cc_compute_all(env, CC_OP);
262 d7582078 Blue Swirl
    cf = eflags & CC_C;
263 d7582078 Blue Swirl
    af = eflags & CC_A;
264 d7582078 Blue Swirl
    al = EAX & 0xff;
265 d7582078 Blue Swirl
266 d7582078 Blue Swirl
    eflags = 0;
267 d7582078 Blue Swirl
    al1 = al;
268 d7582078 Blue Swirl
    if (((al & 0x0f) > 9) || af) {
269 d7582078 Blue Swirl
        eflags |= CC_A;
270 d7582078 Blue Swirl
        if (al < 6 || cf) {
271 d7582078 Blue Swirl
            eflags |= CC_C;
272 d7582078 Blue Swirl
        }
273 d7582078 Blue Swirl
        al = (al - 6) & 0xff;
274 d7582078 Blue Swirl
    }
275 d7582078 Blue Swirl
    if ((al1 > 0x99) || cf) {
276 d7582078 Blue Swirl
        al = (al - 0x60) & 0xff;
277 d7582078 Blue Swirl
        eflags |= CC_C;
278 d7582078 Blue Swirl
    }
279 d7582078 Blue Swirl
    EAX = (EAX & ~0xff) | al;
280 d7582078 Blue Swirl
    /* well, speed is not an issue here, so we compute the flags by hand */
281 d7582078 Blue Swirl
    eflags |= (al == 0) << 6; /* zf */
282 d7582078 Blue Swirl
    eflags |= parity_table[al]; /* pf */
283 d7582078 Blue Swirl
    eflags |= (al & 0x80); /* sf */
284 d7582078 Blue Swirl
    CC_SRC = eflags;
285 d7582078 Blue Swirl
}
286 d7582078 Blue Swirl
287 d7582078 Blue Swirl
#ifdef TARGET_X86_64
288 d7582078 Blue Swirl
static void add128(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
289 d7582078 Blue Swirl
{
290 d7582078 Blue Swirl
    *plow += a;
291 d7582078 Blue Swirl
    /* carry test */
292 d7582078 Blue Swirl
    if (*plow < a) {
293 d7582078 Blue Swirl
        (*phigh)++;
294 d7582078 Blue Swirl
    }
295 d7582078 Blue Swirl
    *phigh += b;
296 d7582078 Blue Swirl
}
297 d7582078 Blue Swirl
298 d7582078 Blue Swirl
static void neg128(uint64_t *plow, uint64_t *phigh)
299 d7582078 Blue Swirl
{
300 d7582078 Blue Swirl
    *plow = ~*plow;
301 d7582078 Blue Swirl
    *phigh = ~*phigh;
302 d7582078 Blue Swirl
    add128(plow, phigh, 1, 0);
303 d7582078 Blue Swirl
}
304 d7582078 Blue Swirl
305 d7582078 Blue Swirl
/* return TRUE if overflow */
306 d7582078 Blue Swirl
static int div64(uint64_t *plow, uint64_t *phigh, uint64_t b)
307 d7582078 Blue Swirl
{
308 d7582078 Blue Swirl
    uint64_t q, r, a1, a0;
309 d7582078 Blue Swirl
    int i, qb, ab;
310 d7582078 Blue Swirl
311 d7582078 Blue Swirl
    a0 = *plow;
312 d7582078 Blue Swirl
    a1 = *phigh;
313 d7582078 Blue Swirl
    if (a1 == 0) {
314 d7582078 Blue Swirl
        q = a0 / b;
315 d7582078 Blue Swirl
        r = a0 % b;
316 d7582078 Blue Swirl
        *plow = q;
317 d7582078 Blue Swirl
        *phigh = r;
318 d7582078 Blue Swirl
    } else {
319 d7582078 Blue Swirl
        if (a1 >= b) {
320 d7582078 Blue Swirl
            return 1;
321 d7582078 Blue Swirl
        }
322 d7582078 Blue Swirl
        /* XXX: use a better algorithm */
323 d7582078 Blue Swirl
        for (i = 0; i < 64; i++) {
324 d7582078 Blue Swirl
            ab = a1 >> 63;
325 d7582078 Blue Swirl
            a1 = (a1 << 1) | (a0 >> 63);
326 d7582078 Blue Swirl
            if (ab || a1 >= b) {
327 d7582078 Blue Swirl
                a1 -= b;
328 d7582078 Blue Swirl
                qb = 1;
329 d7582078 Blue Swirl
            } else {
330 d7582078 Blue Swirl
                qb = 0;
331 d7582078 Blue Swirl
            }
332 d7582078 Blue Swirl
            a0 = (a0 << 1) | qb;
333 d7582078 Blue Swirl
        }
334 d7582078 Blue Swirl
#if defined(DEBUG_MULDIV)
335 d7582078 Blue Swirl
        printf("div: 0x%016" PRIx64 "%016" PRIx64 " / 0x%016" PRIx64
336 d7582078 Blue Swirl
               ": q=0x%016" PRIx64 " r=0x%016" PRIx64 "\n",
337 d7582078 Blue Swirl
               *phigh, *plow, b, a0, a1);
338 d7582078 Blue Swirl
#endif
339 d7582078 Blue Swirl
        *plow = a0;
340 d7582078 Blue Swirl
        *phigh = a1;
341 d7582078 Blue Swirl
    }
342 d7582078 Blue Swirl
    return 0;
343 d7582078 Blue Swirl
}
344 d7582078 Blue Swirl
345 d7582078 Blue Swirl
/* return TRUE if overflow */
346 d7582078 Blue Swirl
static int idiv64(uint64_t *plow, uint64_t *phigh, int64_t b)
347 d7582078 Blue Swirl
{
348 d7582078 Blue Swirl
    int sa, sb;
349 d7582078 Blue Swirl
350 d7582078 Blue Swirl
    sa = ((int64_t)*phigh < 0);
351 d7582078 Blue Swirl
    if (sa) {
352 d7582078 Blue Swirl
        neg128(plow, phigh);
353 d7582078 Blue Swirl
    }
354 d7582078 Blue Swirl
    sb = (b < 0);
355 d7582078 Blue Swirl
    if (sb) {
356 d7582078 Blue Swirl
        b = -b;
357 d7582078 Blue Swirl
    }
358 d7582078 Blue Swirl
    if (div64(plow, phigh, b) != 0) {
359 d7582078 Blue Swirl
        return 1;
360 d7582078 Blue Swirl
    }
361 d7582078 Blue Swirl
    if (sa ^ sb) {
362 d7582078 Blue Swirl
        if (*plow > (1ULL << 63)) {
363 d7582078 Blue Swirl
            return 1;
364 d7582078 Blue Swirl
        }
365 d7582078 Blue Swirl
        *plow = -*plow;
366 d7582078 Blue Swirl
    } else {
367 d7582078 Blue Swirl
        if (*plow >= (1ULL << 63)) {
368 d7582078 Blue Swirl
            return 1;
369 d7582078 Blue Swirl
        }
370 d7582078 Blue Swirl
    }
371 d7582078 Blue Swirl
    if (sa) {
372 d7582078 Blue Swirl
        *phigh = -*phigh;
373 d7582078 Blue Swirl
    }
374 d7582078 Blue Swirl
    return 0;
375 d7582078 Blue Swirl
}
376 d7582078 Blue Swirl
377 7923057b Blue Swirl
void helper_mulq_EAX_T0(CPUX86State *env, target_ulong t0)
378 d7582078 Blue Swirl
{
379 d7582078 Blue Swirl
    uint64_t r0, r1;
380 d7582078 Blue Swirl
381 d7582078 Blue Swirl
    mulu64(&r0, &r1, EAX, t0);
382 d7582078 Blue Swirl
    EAX = r0;
383 d7582078 Blue Swirl
    EDX = r1;
384 d7582078 Blue Swirl
    CC_DST = r0;
385 d7582078 Blue Swirl
    CC_SRC = r1;
386 d7582078 Blue Swirl
}
387 d7582078 Blue Swirl
388 7923057b Blue Swirl
void helper_imulq_EAX_T0(CPUX86State *env, target_ulong t0)
389 d7582078 Blue Swirl
{
390 d7582078 Blue Swirl
    uint64_t r0, r1;
391 d7582078 Blue Swirl
392 d7582078 Blue Swirl
    muls64(&r0, &r1, EAX, t0);
393 d7582078 Blue Swirl
    EAX = r0;
394 d7582078 Blue Swirl
    EDX = r1;
395 d7582078 Blue Swirl
    CC_DST = r0;
396 d7582078 Blue Swirl
    CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
397 d7582078 Blue Swirl
}
398 d7582078 Blue Swirl
399 7923057b Blue Swirl
target_ulong helper_imulq_T0_T1(CPUX86State *env, target_ulong t0,
400 7923057b Blue Swirl
                                target_ulong t1)
401 d7582078 Blue Swirl
{
402 d7582078 Blue Swirl
    uint64_t r0, r1;
403 d7582078 Blue Swirl
404 d7582078 Blue Swirl
    muls64(&r0, &r1, t0, t1);
405 d7582078 Blue Swirl
    CC_DST = r0;
406 d7582078 Blue Swirl
    CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
407 d7582078 Blue Swirl
    return r0;
408 d7582078 Blue Swirl
}
409 d7582078 Blue Swirl
410 7923057b Blue Swirl
void helper_divq_EAX(CPUX86State *env, target_ulong t0)
411 d7582078 Blue Swirl
{
412 d7582078 Blue Swirl
    uint64_t r0, r1;
413 d7582078 Blue Swirl
414 d7582078 Blue Swirl
    if (t0 == 0) {
415 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
416 d7582078 Blue Swirl
    }
417 d7582078 Blue Swirl
    r0 = EAX;
418 d7582078 Blue Swirl
    r1 = EDX;
419 d7582078 Blue Swirl
    if (div64(&r0, &r1, t0)) {
420 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
421 d7582078 Blue Swirl
    }
422 d7582078 Blue Swirl
    EAX = r0;
423 d7582078 Blue Swirl
    EDX = r1;
424 d7582078 Blue Swirl
}
425 d7582078 Blue Swirl
426 7923057b Blue Swirl
void helper_idivq_EAX(CPUX86State *env, target_ulong t0)
427 d7582078 Blue Swirl
{
428 d7582078 Blue Swirl
    uint64_t r0, r1;
429 d7582078 Blue Swirl
430 d7582078 Blue Swirl
    if (t0 == 0) {
431 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
432 d7582078 Blue Swirl
    }
433 d7582078 Blue Swirl
    r0 = EAX;
434 d7582078 Blue Swirl
    r1 = EDX;
435 d7582078 Blue Swirl
    if (idiv64(&r0, &r1, t0)) {
436 d7582078 Blue Swirl
        raise_exception(env, EXCP00_DIVZ);
437 d7582078 Blue Swirl
    }
438 d7582078 Blue Swirl
    EAX = r0;
439 d7582078 Blue Swirl
    EDX = r1;
440 d7582078 Blue Swirl
}
441 d7582078 Blue Swirl
#endif
442 d7582078 Blue Swirl
443 d7582078 Blue Swirl
/* bit operations */
444 d7582078 Blue Swirl
target_ulong helper_bsf(target_ulong t0)
445 d7582078 Blue Swirl
{
446 d7582078 Blue Swirl
    int count;
447 d7582078 Blue Swirl
    target_ulong res;
448 d7582078 Blue Swirl
449 d7582078 Blue Swirl
    res = t0;
450 d7582078 Blue Swirl
    count = 0;
451 d7582078 Blue Swirl
    while ((res & 1) == 0) {
452 d7582078 Blue Swirl
        count++;
453 d7582078 Blue Swirl
        res >>= 1;
454 d7582078 Blue Swirl
    }
455 d7582078 Blue Swirl
    return count;
456 d7582078 Blue Swirl
}
457 d7582078 Blue Swirl
458 d7582078 Blue Swirl
target_ulong helper_lzcnt(target_ulong t0, int wordsize)
459 d7582078 Blue Swirl
{
460 d7582078 Blue Swirl
    int count;
461 d7582078 Blue Swirl
    target_ulong res, mask;
462 d7582078 Blue Swirl
463 d7582078 Blue Swirl
    if (wordsize > 0 && t0 == 0) {
464 d7582078 Blue Swirl
        return wordsize;
465 d7582078 Blue Swirl
    }
466 d7582078 Blue Swirl
    res = t0;
467 d7582078 Blue Swirl
    count = TARGET_LONG_BITS - 1;
468 d7582078 Blue Swirl
    mask = (target_ulong)1 << (TARGET_LONG_BITS - 1);
469 d7582078 Blue Swirl
    while ((res & mask) == 0) {
470 d7582078 Blue Swirl
        count--;
471 d7582078 Blue Swirl
        res <<= 1;
472 d7582078 Blue Swirl
    }
473 d7582078 Blue Swirl
    if (wordsize > 0) {
474 d7582078 Blue Swirl
        return wordsize - 1 - count;
475 d7582078 Blue Swirl
    }
476 d7582078 Blue Swirl
    return count;
477 d7582078 Blue Swirl
}
478 d7582078 Blue Swirl
479 d7582078 Blue Swirl
target_ulong helper_bsr(target_ulong t0)
480 d7582078 Blue Swirl
{
481 d7582078 Blue Swirl
    return helper_lzcnt(t0, 0);
482 d7582078 Blue Swirl
}
483 d7582078 Blue Swirl
484 d7582078 Blue Swirl
#define SHIFT 0
485 d7582078 Blue Swirl
#include "shift_helper_template.h"
486 d7582078 Blue Swirl
#undef SHIFT
487 d7582078 Blue Swirl
488 d7582078 Blue Swirl
#define SHIFT 1
489 d7582078 Blue Swirl
#include "shift_helper_template.h"
490 d7582078 Blue Swirl
#undef SHIFT
491 d7582078 Blue Swirl
492 d7582078 Blue Swirl
#define SHIFT 2
493 d7582078 Blue Swirl
#include "shift_helper_template.h"
494 d7582078 Blue Swirl
#undef SHIFT
495 d7582078 Blue Swirl
496 d7582078 Blue Swirl
#ifdef TARGET_X86_64
497 d7582078 Blue Swirl
#define SHIFT 3
498 d7582078 Blue Swirl
#include "shift_helper_template.h"
499 d7582078 Blue Swirl
#undef SHIFT
500 d7582078 Blue Swirl
#endif