2
* x86 condition code helpers
4
* Copyright (c) 2008 Fabrice Bellard
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2 of the License, or (at your option) any later version.
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
20
#define DATA_BITS (1 << (3 + SHIFT))
24
#define DATA_TYPE uint8_t
27
#define DATA_TYPE uint16_t
30
#define DATA_TYPE uint32_t
33
#define DATA_TYPE uint64_t
35
#error unhandled operand size
38
#define SIGN_MASK (((DATA_TYPE)1) << (DATA_BITS - 1))
40
/* dynamic flags computation */
42
static int glue(compute_all_add, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
44
int cf, pf, af, zf, sf, of;
45
DATA_TYPE src2 = dst - src1;
48
pf = parity_table[(uint8_t)dst];
49
af = (dst ^ src1 ^ src2) & CC_A;
50
zf = (dst == 0) * CC_Z;
51
sf = lshift(dst, 8 - DATA_BITS) & CC_S;
52
of = lshift((src1 ^ src2 ^ -1) & (src1 ^ dst), 12 - DATA_BITS) & CC_O;
53
return cf | pf | af | zf | sf | of;
56
static int glue(compute_c_add, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
61
static int glue(compute_all_adc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1,
64
int cf, pf, af, zf, sf, of;
65
DATA_TYPE src2 = dst - src1 - src3;
67
cf = (src3 ? dst <= src1 : dst < src1);
68
pf = parity_table[(uint8_t)dst];
69
af = (dst ^ src1 ^ src2) & 0x10;
71
sf = lshift(dst, 8 - DATA_BITS) & 0x80;
72
of = lshift((src1 ^ src2 ^ -1) & (src1 ^ dst), 12 - DATA_BITS) & CC_O;
73
return cf | pf | af | zf | sf | of;
76
static int glue(compute_c_adc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1,
79
return src3 ? dst <= src1 : dst < src1;
82
static int glue(compute_all_sub, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2)
84
int cf, pf, af, zf, sf, of;
85
DATA_TYPE src1 = dst + src2;
88
pf = parity_table[(uint8_t)dst];
89
af = (dst ^ src1 ^ src2) & CC_A;
90
zf = (dst == 0) * CC_Z;
91
sf = lshift(dst, 8 - DATA_BITS) & CC_S;
92
of = lshift((src1 ^ src2) & (src1 ^ dst), 12 - DATA_BITS) & CC_O;
93
return cf | pf | af | zf | sf | of;
96
static int glue(compute_c_sub, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2)
98
DATA_TYPE src1 = dst + src2;
103
static int glue(compute_all_sbb, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2,
106
int cf, pf, af, zf, sf, of;
107
DATA_TYPE src1 = dst + src2 + src3;
109
cf = (src3 ? src1 <= src2 : src1 < src2);
110
pf = parity_table[(uint8_t)dst];
111
af = (dst ^ src1 ^ src2) & 0x10;
112
zf = (dst == 0) << 6;
113
sf = lshift(dst, 8 - DATA_BITS) & 0x80;
114
of = lshift((src1 ^ src2) & (src1 ^ dst), 12 - DATA_BITS) & CC_O;
115
return cf | pf | af | zf | sf | of;
118
static int glue(compute_c_sbb, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2,
121
DATA_TYPE src1 = dst + src2 + src3;
123
return (src3 ? src1 <= src2 : src1 < src2);
126
static int glue(compute_all_logic, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
128
int cf, pf, af, zf, sf, of;
131
pf = parity_table[(uint8_t)dst];
133
zf = (dst == 0) * CC_Z;
134
sf = lshift(dst, 8 - DATA_BITS) & CC_S;
136
return cf | pf | af | zf | sf | of;
139
static int glue(compute_all_inc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
141
int cf, pf, af, zf, sf, of;
147
pf = parity_table[(uint8_t)dst];
148
af = (dst ^ src1 ^ src2) & CC_A;
149
zf = (dst == 0) * CC_Z;
150
sf = lshift(dst, 8 - DATA_BITS) & CC_S;
151
of = (dst == SIGN_MASK) * CC_O;
152
return cf | pf | af | zf | sf | of;
155
static int glue(compute_all_dec, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
157
int cf, pf, af, zf, sf, of;
163
pf = parity_table[(uint8_t)dst];
164
af = (dst ^ src1 ^ src2) & CC_A;
165
zf = (dst == 0) * CC_Z;
166
sf = lshift(dst, 8 - DATA_BITS) & CC_S;
167
of = (dst == SIGN_MASK - 1) * CC_O;
168
return cf | pf | af | zf | sf | of;
171
static int glue(compute_all_shl, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
173
int cf, pf, af, zf, sf, of;
175
cf = (src1 >> (DATA_BITS - 1)) & CC_C;
176
pf = parity_table[(uint8_t)dst];
177
af = 0; /* undefined */
178
zf = (dst == 0) * CC_Z;
179
sf = lshift(dst, 8 - DATA_BITS) & CC_S;
180
/* of is defined iff shift count == 1 */
181
of = lshift(src1 ^ dst, 12 - DATA_BITS) & CC_O;
182
return cf | pf | af | zf | sf | of;
185
static int glue(compute_c_shl, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
187
return (src1 >> (DATA_BITS - 1)) & CC_C;
190
static int glue(compute_all_sar, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
192
int cf, pf, af, zf, sf, of;
195
pf = parity_table[(uint8_t)dst];
196
af = 0; /* undefined */
197
zf = (dst == 0) * CC_Z;
198
sf = lshift(dst, 8 - DATA_BITS) & CC_S;
199
/* of is defined iff shift count == 1 */
200
of = lshift(src1 ^ dst, 12 - DATA_BITS) & CC_O;
201
return cf | pf | af | zf | sf | of;
204
/* NOTE: we compute the flags like the P4. On olders CPUs, only OF and
205
CF are modified and it is slower to do that. Note as well that we
206
don't truncate SRC1 for computing carry to DATA_TYPE. */
207
static int glue(compute_all_mul, SUFFIX)(DATA_TYPE dst, target_long src1)
209
int cf, pf, af, zf, sf, of;
212
pf = parity_table[(uint8_t)dst];
213
af = 0; /* undefined */
214
zf = (dst == 0) * CC_Z;
215
sf = lshift(dst, 8 - DATA_BITS) & CC_S;
217
return cf | pf | af | zf | sf | of;
220
static int glue(compute_all_bmilg, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
222
int cf, pf, af, zf, sf, of;
225
pf = 0; /* undefined */
226
af = 0; /* undefined */
227
zf = (dst == 0) * CC_Z;
228
sf = lshift(dst, 8 - DATA_BITS) & CC_S;
230
return cf | pf | af | zf | sf | of;
233
static int glue(compute_c_bmilg, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)