1*f1cc7c28SPhilippe Mathieu-Daudé/* 2*f1cc7c28SPhilippe Mathieu-Daudé * x86 condition code helpers 3*f1cc7c28SPhilippe Mathieu-Daudé * 4*f1cc7c28SPhilippe Mathieu-Daudé * Copyright (c) 2008 Fabrice Bellard 5*f1cc7c28SPhilippe Mathieu-Daudé * 6*f1cc7c28SPhilippe Mathieu-Daudé * This library is free software; you can redistribute it and/or 7*f1cc7c28SPhilippe Mathieu-Daudé * modify it under the terms of the GNU Lesser General Public 8*f1cc7c28SPhilippe Mathieu-Daudé * License as published by the Free Software Foundation; either 9*f1cc7c28SPhilippe Mathieu-Daudé * version 2.1 of the License, or (at your option) any later version. 10*f1cc7c28SPhilippe Mathieu-Daudé * 11*f1cc7c28SPhilippe Mathieu-Daudé * This library is distributed in the hope that it will be useful, 12*f1cc7c28SPhilippe Mathieu-Daudé * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*f1cc7c28SPhilippe Mathieu-Daudé * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14*f1cc7c28SPhilippe Mathieu-Daudé * Lesser General Public License for more details. 15*f1cc7c28SPhilippe Mathieu-Daudé * 16*f1cc7c28SPhilippe Mathieu-Daudé * You should have received a copy of the GNU Lesser General Public 17*f1cc7c28SPhilippe Mathieu-Daudé * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18*f1cc7c28SPhilippe Mathieu-Daudé */ 19*f1cc7c28SPhilippe Mathieu-Daudé 20*f1cc7c28SPhilippe Mathieu-Daudé#define DATA_BITS (1 << (3 + SHIFT)) 21*f1cc7c28SPhilippe Mathieu-Daudé 22*f1cc7c28SPhilippe Mathieu-Daudé#if DATA_BITS == 8 23*f1cc7c28SPhilippe Mathieu-Daudé#define SUFFIX b 24*f1cc7c28SPhilippe Mathieu-Daudé#define DATA_TYPE uint8_t 25*f1cc7c28SPhilippe Mathieu-Daudé#elif DATA_BITS == 16 26*f1cc7c28SPhilippe Mathieu-Daudé#define SUFFIX w 27*f1cc7c28SPhilippe Mathieu-Daudé#define DATA_TYPE uint16_t 28*f1cc7c28SPhilippe Mathieu-Daudé#elif DATA_BITS == 32 29*f1cc7c28SPhilippe Mathieu-Daudé#define SUFFIX l 30*f1cc7c28SPhilippe Mathieu-Daudé#define DATA_TYPE uint32_t 31*f1cc7c28SPhilippe Mathieu-Daudé#elif DATA_BITS == 64 32*f1cc7c28SPhilippe Mathieu-Daudé#define SUFFIX q 33*f1cc7c28SPhilippe Mathieu-Daudé#define DATA_TYPE uint64_t 34*f1cc7c28SPhilippe Mathieu-Daudé#else 35*f1cc7c28SPhilippe Mathieu-Daudé#error unhandled operand size 36*f1cc7c28SPhilippe Mathieu-Daudé#endif 37*f1cc7c28SPhilippe Mathieu-Daudé 38*f1cc7c28SPhilippe Mathieu-Daudé#define SIGN_MASK (((DATA_TYPE)1) << (DATA_BITS - 1)) 39*f1cc7c28SPhilippe Mathieu-Daudé 40*f1cc7c28SPhilippe Mathieu-Daudé/* dynamic flags computation */ 41*f1cc7c28SPhilippe Mathieu-Daudé 42*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_all_add, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) 43*f1cc7c28SPhilippe Mathieu-Daudé{ 44*f1cc7c28SPhilippe Mathieu-Daudé int cf, pf, af, zf, sf, of; 45*f1cc7c28SPhilippe Mathieu-Daudé DATA_TYPE src2 = dst - src1; 46*f1cc7c28SPhilippe Mathieu-Daudé 47*f1cc7c28SPhilippe Mathieu-Daudé cf = dst < src1; 48*f1cc7c28SPhilippe Mathieu-Daudé pf = parity_table[(uint8_t)dst]; 49*f1cc7c28SPhilippe Mathieu-Daudé af = (dst ^ src1 ^ src2) & CC_A; 50*f1cc7c28SPhilippe Mathieu-Daudé zf = (dst == 0) * CC_Z; 51*f1cc7c28SPhilippe Mathieu-Daudé sf = lshift(dst, 8 - DATA_BITS) & CC_S; 52*f1cc7c28SPhilippe Mathieu-Daudé of = lshift((src1 ^ src2 ^ -1) & (src1 ^ dst), 12 - DATA_BITS) & CC_O; 53*f1cc7c28SPhilippe Mathieu-Daudé return cf | pf | af | zf | sf | of; 54*f1cc7c28SPhilippe Mathieu-Daudé} 55*f1cc7c28SPhilippe Mathieu-Daudé 56*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_c_add, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) 57*f1cc7c28SPhilippe Mathieu-Daudé{ 58*f1cc7c28SPhilippe Mathieu-Daudé return dst < src1; 59*f1cc7c28SPhilippe Mathieu-Daudé} 60*f1cc7c28SPhilippe Mathieu-Daudé 61*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_all_adc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1, 62*f1cc7c28SPhilippe Mathieu-Daudé DATA_TYPE src3) 63*f1cc7c28SPhilippe Mathieu-Daudé{ 64*f1cc7c28SPhilippe Mathieu-Daudé int cf, pf, af, zf, sf, of; 65*f1cc7c28SPhilippe Mathieu-Daudé DATA_TYPE src2 = dst - src1 - src3; 66*f1cc7c28SPhilippe Mathieu-Daudé 67*f1cc7c28SPhilippe Mathieu-Daudé cf = (src3 ? dst <= src1 : dst < src1); 68*f1cc7c28SPhilippe Mathieu-Daudé pf = parity_table[(uint8_t)dst]; 69*f1cc7c28SPhilippe Mathieu-Daudé af = (dst ^ src1 ^ src2) & 0x10; 70*f1cc7c28SPhilippe Mathieu-Daudé zf = (dst == 0) << 6; 71*f1cc7c28SPhilippe Mathieu-Daudé sf = lshift(dst, 8 - DATA_BITS) & 0x80; 72*f1cc7c28SPhilippe Mathieu-Daudé of = lshift((src1 ^ src2 ^ -1) & (src1 ^ dst), 12 - DATA_BITS) & CC_O; 73*f1cc7c28SPhilippe Mathieu-Daudé return cf | pf | af | zf | sf | of; 74*f1cc7c28SPhilippe Mathieu-Daudé} 75*f1cc7c28SPhilippe Mathieu-Daudé 76*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_c_adc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1, 77*f1cc7c28SPhilippe Mathieu-Daudé DATA_TYPE src3) 78*f1cc7c28SPhilippe Mathieu-Daudé{ 79*f1cc7c28SPhilippe Mathieu-Daudé return src3 ? dst <= src1 : dst < src1; 80*f1cc7c28SPhilippe Mathieu-Daudé} 81*f1cc7c28SPhilippe Mathieu-Daudé 82*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_all_sub, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2) 83*f1cc7c28SPhilippe Mathieu-Daudé{ 84*f1cc7c28SPhilippe Mathieu-Daudé int cf, pf, af, zf, sf, of; 85*f1cc7c28SPhilippe Mathieu-Daudé DATA_TYPE src1 = dst + src2; 86*f1cc7c28SPhilippe Mathieu-Daudé 87*f1cc7c28SPhilippe Mathieu-Daudé cf = src1 < src2; 88*f1cc7c28SPhilippe Mathieu-Daudé pf = parity_table[(uint8_t)dst]; 89*f1cc7c28SPhilippe Mathieu-Daudé af = (dst ^ src1 ^ src2) & CC_A; 90*f1cc7c28SPhilippe Mathieu-Daudé zf = (dst == 0) * CC_Z; 91*f1cc7c28SPhilippe Mathieu-Daudé sf = lshift(dst, 8 - DATA_BITS) & CC_S; 92*f1cc7c28SPhilippe Mathieu-Daudé of = lshift((src1 ^ src2) & (src1 ^ dst), 12 - DATA_BITS) & CC_O; 93*f1cc7c28SPhilippe Mathieu-Daudé return cf | pf | af | zf | sf | of; 94*f1cc7c28SPhilippe Mathieu-Daudé} 95*f1cc7c28SPhilippe Mathieu-Daudé 96*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_c_sub, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2) 97*f1cc7c28SPhilippe Mathieu-Daudé{ 98*f1cc7c28SPhilippe Mathieu-Daudé DATA_TYPE src1 = dst + src2; 99*f1cc7c28SPhilippe Mathieu-Daudé 100*f1cc7c28SPhilippe Mathieu-Daudé return src1 < src2; 101*f1cc7c28SPhilippe Mathieu-Daudé} 102*f1cc7c28SPhilippe Mathieu-Daudé 103*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_all_sbb, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2, 104*f1cc7c28SPhilippe Mathieu-Daudé DATA_TYPE src3) 105*f1cc7c28SPhilippe Mathieu-Daudé{ 106*f1cc7c28SPhilippe Mathieu-Daudé int cf, pf, af, zf, sf, of; 107*f1cc7c28SPhilippe Mathieu-Daudé DATA_TYPE src1 = dst + src2 + src3; 108*f1cc7c28SPhilippe Mathieu-Daudé 109*f1cc7c28SPhilippe Mathieu-Daudé cf = (src3 ? src1 <= src2 : src1 < src2); 110*f1cc7c28SPhilippe Mathieu-Daudé pf = parity_table[(uint8_t)dst]; 111*f1cc7c28SPhilippe Mathieu-Daudé af = (dst ^ src1 ^ src2) & 0x10; 112*f1cc7c28SPhilippe Mathieu-Daudé zf = (dst == 0) << 6; 113*f1cc7c28SPhilippe Mathieu-Daudé sf = lshift(dst, 8 - DATA_BITS) & 0x80; 114*f1cc7c28SPhilippe Mathieu-Daudé of = lshift((src1 ^ src2) & (src1 ^ dst), 12 - DATA_BITS) & CC_O; 115*f1cc7c28SPhilippe Mathieu-Daudé return cf | pf | af | zf | sf | of; 116*f1cc7c28SPhilippe Mathieu-Daudé} 117*f1cc7c28SPhilippe Mathieu-Daudé 118*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_c_sbb, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2, 119*f1cc7c28SPhilippe Mathieu-Daudé DATA_TYPE src3) 120*f1cc7c28SPhilippe Mathieu-Daudé{ 121*f1cc7c28SPhilippe Mathieu-Daudé DATA_TYPE src1 = dst + src2 + src3; 122*f1cc7c28SPhilippe Mathieu-Daudé 123*f1cc7c28SPhilippe Mathieu-Daudé return (src3 ? src1 <= src2 : src1 < src2); 124*f1cc7c28SPhilippe Mathieu-Daudé} 125*f1cc7c28SPhilippe Mathieu-Daudé 126*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_all_logic, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) 127*f1cc7c28SPhilippe Mathieu-Daudé{ 128*f1cc7c28SPhilippe Mathieu-Daudé int cf, pf, af, zf, sf, of; 129*f1cc7c28SPhilippe Mathieu-Daudé 130*f1cc7c28SPhilippe Mathieu-Daudé cf = 0; 131*f1cc7c28SPhilippe Mathieu-Daudé pf = parity_table[(uint8_t)dst]; 132*f1cc7c28SPhilippe Mathieu-Daudé af = 0; 133*f1cc7c28SPhilippe Mathieu-Daudé zf = (dst == 0) * CC_Z; 134*f1cc7c28SPhilippe Mathieu-Daudé sf = lshift(dst, 8 - DATA_BITS) & CC_S; 135*f1cc7c28SPhilippe Mathieu-Daudé of = 0; 136*f1cc7c28SPhilippe Mathieu-Daudé return cf | pf | af | zf | sf | of; 137*f1cc7c28SPhilippe Mathieu-Daudé} 138*f1cc7c28SPhilippe Mathieu-Daudé 139*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_all_inc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) 140*f1cc7c28SPhilippe Mathieu-Daudé{ 141*f1cc7c28SPhilippe Mathieu-Daudé int cf, pf, af, zf, sf, of; 142*f1cc7c28SPhilippe Mathieu-Daudé DATA_TYPE src2; 143*f1cc7c28SPhilippe Mathieu-Daudé 144*f1cc7c28SPhilippe Mathieu-Daudé cf = src1; 145*f1cc7c28SPhilippe Mathieu-Daudé src1 = dst - 1; 146*f1cc7c28SPhilippe Mathieu-Daudé src2 = 1; 147*f1cc7c28SPhilippe Mathieu-Daudé pf = parity_table[(uint8_t)dst]; 148*f1cc7c28SPhilippe Mathieu-Daudé af = (dst ^ src1 ^ src2) & CC_A; 149*f1cc7c28SPhilippe Mathieu-Daudé zf = (dst == 0) * CC_Z; 150*f1cc7c28SPhilippe Mathieu-Daudé sf = lshift(dst, 8 - DATA_BITS) & CC_S; 151*f1cc7c28SPhilippe Mathieu-Daudé of = (dst == SIGN_MASK) * CC_O; 152*f1cc7c28SPhilippe Mathieu-Daudé return cf | pf | af | zf | sf | of; 153*f1cc7c28SPhilippe Mathieu-Daudé} 154*f1cc7c28SPhilippe Mathieu-Daudé 155*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_all_dec, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) 156*f1cc7c28SPhilippe Mathieu-Daudé{ 157*f1cc7c28SPhilippe Mathieu-Daudé int cf, pf, af, zf, sf, of; 158*f1cc7c28SPhilippe Mathieu-Daudé DATA_TYPE src2; 159*f1cc7c28SPhilippe Mathieu-Daudé 160*f1cc7c28SPhilippe Mathieu-Daudé cf = src1; 161*f1cc7c28SPhilippe Mathieu-Daudé src1 = dst + 1; 162*f1cc7c28SPhilippe Mathieu-Daudé src2 = 1; 163*f1cc7c28SPhilippe Mathieu-Daudé pf = parity_table[(uint8_t)dst]; 164*f1cc7c28SPhilippe Mathieu-Daudé af = (dst ^ src1 ^ src2) & CC_A; 165*f1cc7c28SPhilippe Mathieu-Daudé zf = (dst == 0) * CC_Z; 166*f1cc7c28SPhilippe Mathieu-Daudé sf = lshift(dst, 8 - DATA_BITS) & CC_S; 167*f1cc7c28SPhilippe Mathieu-Daudé of = (dst == SIGN_MASK - 1) * CC_O; 168*f1cc7c28SPhilippe Mathieu-Daudé return cf | pf | af | zf | sf | of; 169*f1cc7c28SPhilippe Mathieu-Daudé} 170*f1cc7c28SPhilippe Mathieu-Daudé 171*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_all_shl, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) 172*f1cc7c28SPhilippe Mathieu-Daudé{ 173*f1cc7c28SPhilippe Mathieu-Daudé int cf, pf, af, zf, sf, of; 174*f1cc7c28SPhilippe Mathieu-Daudé 175*f1cc7c28SPhilippe Mathieu-Daudé cf = (src1 >> (DATA_BITS - 1)) & CC_C; 176*f1cc7c28SPhilippe Mathieu-Daudé pf = parity_table[(uint8_t)dst]; 177*f1cc7c28SPhilippe Mathieu-Daudé af = 0; /* undefined */ 178*f1cc7c28SPhilippe Mathieu-Daudé zf = (dst == 0) * CC_Z; 179*f1cc7c28SPhilippe Mathieu-Daudé sf = lshift(dst, 8 - DATA_BITS) & CC_S; 180*f1cc7c28SPhilippe Mathieu-Daudé /* of is defined iff shift count == 1 */ 181*f1cc7c28SPhilippe Mathieu-Daudé of = lshift(src1 ^ dst, 12 - DATA_BITS) & CC_O; 182*f1cc7c28SPhilippe Mathieu-Daudé return cf | pf | af | zf | sf | of; 183*f1cc7c28SPhilippe Mathieu-Daudé} 184*f1cc7c28SPhilippe Mathieu-Daudé 185*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_c_shl, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) 186*f1cc7c28SPhilippe Mathieu-Daudé{ 187*f1cc7c28SPhilippe Mathieu-Daudé return (src1 >> (DATA_BITS - 1)) & CC_C; 188*f1cc7c28SPhilippe Mathieu-Daudé} 189*f1cc7c28SPhilippe Mathieu-Daudé 190*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_all_sar, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) 191*f1cc7c28SPhilippe Mathieu-Daudé{ 192*f1cc7c28SPhilippe Mathieu-Daudé int cf, pf, af, zf, sf, of; 193*f1cc7c28SPhilippe Mathieu-Daudé 194*f1cc7c28SPhilippe Mathieu-Daudé cf = src1 & 1; 195*f1cc7c28SPhilippe Mathieu-Daudé pf = parity_table[(uint8_t)dst]; 196*f1cc7c28SPhilippe Mathieu-Daudé af = 0; /* undefined */ 197*f1cc7c28SPhilippe Mathieu-Daudé zf = (dst == 0) * CC_Z; 198*f1cc7c28SPhilippe Mathieu-Daudé sf = lshift(dst, 8 - DATA_BITS) & CC_S; 199*f1cc7c28SPhilippe Mathieu-Daudé /* of is defined iff shift count == 1 */ 200*f1cc7c28SPhilippe Mathieu-Daudé of = lshift(src1 ^ dst, 12 - DATA_BITS) & CC_O; 201*f1cc7c28SPhilippe Mathieu-Daudé return cf | pf | af | zf | sf | of; 202*f1cc7c28SPhilippe Mathieu-Daudé} 203*f1cc7c28SPhilippe Mathieu-Daudé 204*f1cc7c28SPhilippe Mathieu-Daudé/* NOTE: we compute the flags like the P4. On olders CPUs, only OF and 205*f1cc7c28SPhilippe Mathieu-Daudé CF are modified and it is slower to do that. Note as well that we 206*f1cc7c28SPhilippe Mathieu-Daudé don't truncate SRC1 for computing carry to DATA_TYPE. */ 207*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_all_mul, SUFFIX)(DATA_TYPE dst, target_long src1) 208*f1cc7c28SPhilippe Mathieu-Daudé{ 209*f1cc7c28SPhilippe Mathieu-Daudé int cf, pf, af, zf, sf, of; 210*f1cc7c28SPhilippe Mathieu-Daudé 211*f1cc7c28SPhilippe Mathieu-Daudé cf = (src1 != 0); 212*f1cc7c28SPhilippe Mathieu-Daudé pf = parity_table[(uint8_t)dst]; 213*f1cc7c28SPhilippe Mathieu-Daudé af = 0; /* undefined */ 214*f1cc7c28SPhilippe Mathieu-Daudé zf = (dst == 0) * CC_Z; 215*f1cc7c28SPhilippe Mathieu-Daudé sf = lshift(dst, 8 - DATA_BITS) & CC_S; 216*f1cc7c28SPhilippe Mathieu-Daudé of = cf * CC_O; 217*f1cc7c28SPhilippe Mathieu-Daudé return cf | pf | af | zf | sf | of; 218*f1cc7c28SPhilippe Mathieu-Daudé} 219*f1cc7c28SPhilippe Mathieu-Daudé 220*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_all_bmilg, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) 221*f1cc7c28SPhilippe Mathieu-Daudé{ 222*f1cc7c28SPhilippe Mathieu-Daudé int cf, pf, af, zf, sf, of; 223*f1cc7c28SPhilippe Mathieu-Daudé 224*f1cc7c28SPhilippe Mathieu-Daudé cf = (src1 == 0); 225*f1cc7c28SPhilippe Mathieu-Daudé pf = 0; /* undefined */ 226*f1cc7c28SPhilippe Mathieu-Daudé af = 0; /* undefined */ 227*f1cc7c28SPhilippe Mathieu-Daudé zf = (dst == 0) * CC_Z; 228*f1cc7c28SPhilippe Mathieu-Daudé sf = lshift(dst, 8 - DATA_BITS) & CC_S; 229*f1cc7c28SPhilippe Mathieu-Daudé of = 0; 230*f1cc7c28SPhilippe Mathieu-Daudé return cf | pf | af | zf | sf | of; 231*f1cc7c28SPhilippe Mathieu-Daudé} 232*f1cc7c28SPhilippe Mathieu-Daudé 233*f1cc7c28SPhilippe Mathieu-Daudéstatic int glue(compute_c_bmilg, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) 234*f1cc7c28SPhilippe Mathieu-Daudé{ 235*f1cc7c28SPhilippe Mathieu-Daudé return src1 == 0; 236*f1cc7c28SPhilippe Mathieu-Daudé} 237*f1cc7c28SPhilippe Mathieu-Daudé 238*f1cc7c28SPhilippe Mathieu-Daudé#undef DATA_BITS 239*f1cc7c28SPhilippe Mathieu-Daudé#undef SIGN_MASK 240*f1cc7c28SPhilippe Mathieu-Daudé#undef DATA_TYPE 241*f1cc7c28SPhilippe Mathieu-Daudé#undef DATA_MASK 242*f1cc7c28SPhilippe Mathieu-Daudé#undef SUFFIX 243