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