147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner/*
247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner *  x86 integer helpers
347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner *
447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner *  Copyright (c) 2003 Fabrice Bellard
547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner *
647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner * This library is free software; you can redistribute it and/or
747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner * modify it under the terms of the GNU Lesser General Public
847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner * License as published by the Free Software Foundation; either
947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner * version 2 of the License, or (at your option) any later version.
1047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner *
1147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner * This library is distributed in the hope that it will be useful,
1247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner * but WITHOUT ANY WARRANTY; without even the implied warranty of
1347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner * Lesser General Public License for more details.
1547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner *
1647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner * You should have received a copy of the GNU Lesser General Public
1747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner */
1947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
2047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#include "cpu.h"
2147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#include "qemu/host-utils.h"
2247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#include "helper.h"
2347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
2447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner//#define DEBUG_MULDIV
2547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
2647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner/* modulo 17 table */
2747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnerstatic const uint8_t rclw_table[32] = {
2847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    0, 1, 2, 3, 4, 5, 6, 7,
2947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    8, 9,10,11,12,13,14,15,
3047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner   16, 0, 1, 2, 3, 4, 5, 6,
3147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    7, 8, 9,10,11,12,13,14,
3247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner};
3347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
3447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner/* modulo 9 table */
3547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnerstatic const uint8_t rclb_table[32] = {
3647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    0, 1, 2, 3, 4, 5, 6, 7,
3747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    8, 0, 1, 2, 3, 4, 5, 6,
3847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    7, 8, 0, 1, 2, 3, 4, 5,
3947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    6, 7, 8, 0, 1, 2, 3, 4,
4047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner};
4147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
4247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner/* division, flags are undefined */
4347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
4447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_divb_AL(CPUX86State *env, target_ulong t0)
4547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
4647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    unsigned int num, den, q, r;
4747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
4847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    num = (EAX & 0xffff);
4947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    den = (t0 & 0xff);
5047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (den == 0) {
5147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
5247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
5347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    q = (num / den);
5447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (q > 0xff)
5547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
5647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    q &= 0xff;
5747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    r = (num % den) & 0xff;
5847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = (EAX & ~0xffff) | (r << 8) | q;
5947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
6047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
6147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_idivb_AL(CPUX86State *env, target_ulong t0)
6247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
6347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int num, den, q, r;
6447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
6547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    num = (int16_t)EAX;
6647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    den = (int8_t)t0;
6747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (den == 0) {
6847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
6947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
7047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    q = (num / den);
7147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (q != (int8_t)q)
7247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
7347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    q &= 0xff;
7447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    r = (num % den) & 0xff;
7547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = (EAX & ~0xffff) | (r << 8) | q;
7647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
7747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
7847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_divw_AX(CPUX86State *env, target_ulong t0)
7947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
8047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    unsigned int num, den, q, r;
8147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
8247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
8347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    den = (t0 & 0xffff);
8447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (den == 0) {
8547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
8647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
8747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    q = (num / den);
8847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (q > 0xffff)
8947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
9047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    q &= 0xffff;
9147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    r = (num % den) & 0xffff;
9247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = (EAX & ~0xffff) | q;
9347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EDX = (EDX & ~0xffff) | r;
9447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
9547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
9647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_idivw_AX(CPUX86State *env, target_ulong t0)
9747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
9847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int num, den, q, r;
9947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
10047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
10147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    den = (int16_t)t0;
10247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (den == 0) {
10347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
10447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
10547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    q = (num / den);
10647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (q != (int16_t)q)
10747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
10847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    q &= 0xffff;
10947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    r = (num % den) & 0xffff;
11047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = (EAX & ~0xffff) | q;
11147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EDX = (EDX & ~0xffff) | r;
11247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
11347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
11447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_divl_EAX(CPUX86State *env, target_ulong t0)
11547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
11647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    unsigned int den, r;
11747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    uint64_t num, q;
11847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
11947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
12047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    den = t0;
12147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (den == 0) {
12247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
12347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
12447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    q = (num / den);
12547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    r = (num % den);
12647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (q > 0xffffffff)
12747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
12847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = (uint32_t)q;
12947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EDX = (uint32_t)r;
13047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
13147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
13247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_idivl_EAX(CPUX86State *env, target_ulong t0)
13347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
13447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int den, r;
13547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int64_t num, q;
13647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
13747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
13847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    den = t0;
13947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (den == 0) {
14047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
14147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
14247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    q = (num / den);
14347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    r = (num % den);
14447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (q != (int32_t)q)
14547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
14647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = (uint32_t)q;
14747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EDX = (uint32_t)r;
14847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
14947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
15047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner/* bcd */
15147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
15247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner/* XXX: exception */
15347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_aam(CPUX86State *env, int base)
15447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
15547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int al, ah;
15647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    al = EAX & 0xff;
15747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    ah = al / base;
15847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    al = al % base;
15947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = (EAX & ~0xffff) | al | (ah << 8);
16047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    CC_DST = al;
16147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
16247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
16347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_aad(CPUX86State *env, int base)
16447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
16547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int al, ah;
16647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    al = EAX & 0xff;
16747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    ah = (EAX >> 8) & 0xff;
16847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    al = ((ah * base) + al) & 0xff;
16947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = (EAX & ~0xffff) | al;
17047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    CC_DST = al;
17147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
17247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
17347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_aaa(CPUX86State *env)
17447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
17547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int icarry;
17647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int al, ah, af;
17747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int eflags;
17847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
17947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    eflags = helper_cc_compute_all(env, CC_OP);
18047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    af = eflags & CC_A;
18147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    al = EAX & 0xff;
18247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    ah = (EAX >> 8) & 0xff;
18347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
18447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    icarry = (al > 0xf9);
18547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (((al & 0x0f) > 9 ) || af) {
18647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        al = (al + 6) & 0x0f;
18747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        ah = (ah + 1 + icarry) & 0xff;
18847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        eflags |= CC_C | CC_A;
18947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    } else {
19047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        eflags &= ~(CC_C | CC_A);
19147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        al &= 0x0f;
19247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
19347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = (EAX & ~0xffff) | al | (ah << 8);
19447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    CC_SRC = eflags;
19547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
19647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
19747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_aas(CPUX86State *env)
19847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
19947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int icarry;
20047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int al, ah, af;
20147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int eflags;
20247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
20347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    eflags = helper_cc_compute_all(env, CC_OP);
20447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    af = eflags & CC_A;
20547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    al = EAX & 0xff;
20647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    ah = (EAX >> 8) & 0xff;
20747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
20847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    icarry = (al < 6);
20947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (((al & 0x0f) > 9 ) || af) {
21047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        al = (al - 6) & 0x0f;
21147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        ah = (ah - 1 - icarry) & 0xff;
21247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        eflags |= CC_C | CC_A;
21347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    } else {
21447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        eflags &= ~(CC_C | CC_A);
21547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        al &= 0x0f;
21647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
21747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = (EAX & ~0xffff) | al | (ah << 8);
21847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    CC_SRC = eflags;
21947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
22047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
22147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_daa(CPUX86State *env)
22247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
22347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int al, af, cf;
22447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int eflags;
22547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
22647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    eflags = helper_cc_compute_all(env, CC_OP);
22747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    cf = eflags & CC_C;
22847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    af = eflags & CC_A;
22947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    al = EAX & 0xff;
23047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
23147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    eflags = 0;
23247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (((al & 0x0f) > 9 ) || af) {
23347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        al = (al + 6) & 0xff;
23447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        eflags |= CC_A;
23547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
23647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if ((al > 0x9f) || cf) {
23747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        al = (al + 0x60) & 0xff;
23847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        eflags |= CC_C;
23947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
24047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = (EAX & ~0xff) | al;
24147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    /* well, speed is not an issue here, so we compute the flags by hand */
24247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    eflags |= (al == 0) << 6; /* zf */
24347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    eflags |= parity_table[al]; /* pf */
24447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    eflags |= (al & 0x80); /* sf */
24547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    CC_SRC = eflags;
24647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
24747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
24847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_das(CPUX86State *env)
24947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
25047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int al, al1, af, cf;
25147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int eflags;
25247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
25347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    eflags = helper_cc_compute_all(env, CC_OP);
25447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    cf = eflags & CC_C;
25547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    af = eflags & CC_A;
25647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    al = EAX & 0xff;
25747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
25847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    eflags = 0;
25947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    al1 = al;
26047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (((al & 0x0f) > 9 ) || af) {
26147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        eflags |= CC_A;
26247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        if (al < 6 || cf)
26347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner            eflags |= CC_C;
26447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        al = (al - 6) & 0xff;
26547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
26647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if ((al1 > 0x99) || cf) {
26747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        al = (al - 0x60) & 0xff;
26847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        eflags |= CC_C;
26947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
27047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = (EAX & ~0xff) | al;
27147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    /* well, speed is not an issue here, so we compute the flags by hand */
27247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    eflags |= (al == 0) << 6; /* zf */
27347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    eflags |= parity_table[al]; /* pf */
27447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    eflags |= (al & 0x80); /* sf */
27547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    CC_SRC = eflags;
27647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
27747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
27847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#ifdef TARGET_X86_64
27947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
28047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnerstatic void add128(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
28147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
28247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    *plow += a;
28347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    /* carry test */
28447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (*plow < a)
28547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        (*phigh)++;
28647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    *phigh += b;
28747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
28847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
28947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnerstatic void neg128(uint64_t *plow, uint64_t *phigh)
29047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
29147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    *plow = ~ *plow;
29247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    *phigh = ~ *phigh;
29347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    add128(plow, phigh, 1, 0);
29447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
29547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
29647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner/* return TRUE if overflow */
29747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnerstatic int div64(uint64_t *plow, uint64_t *phigh, uint64_t b)
29847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
29947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    uint64_t q, r, a1, a0;
30047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int i, qb, ab;
30147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
30247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    a0 = *plow;
30347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    a1 = *phigh;
30447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (a1 == 0) {
30547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        q = a0 / b;
30647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        r = a0 % b;
30747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        *plow = q;
30847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        *phigh = r;
30947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    } else {
31047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        if (a1 >= b)
31147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner            return 1;
31247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        /* XXX: use a better algorithm */
31347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        for(i = 0; i < 64; i++) {
31447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner            ab = a1 >> 63;
31547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner            a1 = (a1 << 1) | (a0 >> 63);
31647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner            if (ab || a1 >= b) {
31747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner                a1 -= b;
31847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner                qb = 1;
31947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner            } else {
32047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner                qb = 0;
32147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner            }
32247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner            a0 = (a0 << 1) | qb;
32347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        }
32447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#if defined(DEBUG_MULDIV)
32547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        printf("div: 0x%016" PRIx64 "%016" PRIx64 " / 0x%016" PRIx64 ": q=0x%016" PRIx64 " r=0x%016" PRIx64 "\n",
32647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner               *phigh, *plow, b, a0, a1);
32747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#endif
32847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        *plow = a0;
32947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        *phigh = a1;
33047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
33147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    return 0;
33247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
33347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
33447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner/* return TRUE if overflow */
33547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnerstatic int idiv64(uint64_t *plow, uint64_t *phigh, int64_t b)
33647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
33747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int sa, sb;
33847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    sa = ((int64_t)*phigh < 0);
33947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (sa)
34047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        neg128(plow, phigh);
34147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    sb = (b < 0);
34247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (sb)
34347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        b = -b;
34447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (div64(plow, phigh, b) != 0)
34547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        return 1;
34647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (sa ^ sb) {
34747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        if (*plow > (1ULL << 63))
34847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner            return 1;
34947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        *plow = - *plow;
35047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    } else {
35147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        if (*plow >= (1ULL << 63))
35247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner            return 1;
35347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
35447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (sa)
35547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        *phigh = - *phigh;
35647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    return 0;
35747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
35847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
35947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_mulq_EAX_T0(CPUX86State *env, target_ulong t0)
36047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
36147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    uint64_t r0, r1;
36247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
36347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    mulu64(&r0, &r1, EAX, t0);
36447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = r0;
36547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EDX = r1;
36647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    CC_DST = r0;
36747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    CC_SRC = r1;
36847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
36947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
37047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_imulq_EAX_T0(CPUX86State *env, target_ulong t0)
37147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
37247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    uint64_t r0, r1;
37347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
37447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    muls64(&r0, &r1, EAX, t0);
37547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = r0;
37647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EDX = r1;
37747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    CC_DST = r0;
37847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
37947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
38047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
38147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnertarget_ulong helper_imulq_T0_T1(CPUX86State *env, target_ulong t0, target_ulong t1)
38247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
38347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    uint64_t r0, r1;
38447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
38547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    muls64(&r0, &r1, t0, t1);
38647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    CC_DST = r0;
38747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
38847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    return r0;
38947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
39047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
39147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_divq_EAX(CPUX86State *env, target_ulong t0)
39247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
39347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    uint64_t r0, r1;
39447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (t0 == 0) {
39547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
39647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
39747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    r0 = EAX;
39847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    r1 = EDX;
39947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (div64(&r0, &r1, t0))
40047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
40147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = r0;
40247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EDX = r1;
40347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
40447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
40547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnervoid helper_idivq_EAX(CPUX86State *env, target_ulong t0)
40647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
40747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    uint64_t r0, r1;
40847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (t0 == 0) {
40947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
41047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
41147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    r0 = EAX;
41247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    r1 = EDX;
41347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    if (idiv64(&r0, &r1, t0))
41447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        raise_exception(env, EXCP00_DIVZ);
41547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EAX = r0;
41647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    EDX = r1;
41747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
41847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
41947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#endif
42047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
42147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#define SHIFT 0
42247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#include "shift_helper_template.h"
42347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#undef SHIFT
42447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
42547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#define SHIFT 1
42647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#include "shift_helper_template.h"
42747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#undef SHIFT
42847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
42947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#define SHIFT 2
43047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#include "shift_helper_template.h"
43147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#undef SHIFT
43247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
43347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#ifdef TARGET_X86_64
43447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#define SHIFT 3
43547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#include "shift_helper_template.h"
43647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#undef SHIFT
43747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner#endif
43847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
43947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner/* bit operations */
44047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnertarget_ulong helper_bsf(target_ulong t0)
44147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
44247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int count;
44347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    target_ulong res;
44447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
44547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    res = t0;
44647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    count = 0;
44747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    while ((res & 1) == 0) {
44847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        count++;
44947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        res >>= 1;
45047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
45147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    return count;
45247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
45347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
45447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turnertarget_ulong helper_bsr(target_ulong t0)
45547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner{
45647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    int count;
45747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    target_ulong res, mask;
45847fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner
45947fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    res = t0;
46047fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    count = TARGET_LONG_BITS - 1;
46147fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    mask = (target_ulong)1 << (TARGET_LONG_BITS - 1);
46247fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    while ((res & mask) == 0) {
46347fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        count--;
46447fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner        res <<= 1;
46547fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    }
46647fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner    return count;
46747fcd074d8bd4f7cb732db6009f620fd0dc64f4cDavid 'Digit' Turner}
468