blob: 1f94e11dcf0606923d2c670d4773fdf7db9aaa69 [file] [log] [blame]
bellardb6abf972008-05-17 12:44:31 +00001/*
Blue Swirl38de4c42012-05-12 20:39:26 +00002 * x86 condition code helpers
bellardb6abf972008-05-17 12:44:31 +00003 *
4 * Copyright (c) 2008 Fabrice Bellard
5 *
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.
10 *
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.
15 *
16 * You should have received a copy of the GNU Lesser General Public
Blue Swirl8167ee82009-07-16 20:47:01 +000017 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
bellardb6abf972008-05-17 12:44:31 +000018 */
Blue Swirla04759f2012-04-29 12:27:33 +000019
bellardb6abf972008-05-17 12:44:31 +000020#define DATA_BITS (1 << (3 + SHIFT))
bellardb6abf972008-05-17 12:44:31 +000021#define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1))
bellardb6abf972008-05-17 12:44:31 +000022
23#if DATA_BITS == 8
24#define SUFFIX b
25#define DATA_TYPE uint8_t
bellardb6abf972008-05-17 12:44:31 +000026#define DATA_MASK 0xff
27#elif DATA_BITS == 16
28#define SUFFIX w
29#define DATA_TYPE uint16_t
bellardb6abf972008-05-17 12:44:31 +000030#define DATA_MASK 0xffff
31#elif DATA_BITS == 32
32#define SUFFIX l
33#define DATA_TYPE uint32_t
bellardb6abf972008-05-17 12:44:31 +000034#define DATA_MASK 0xffffffff
35#elif DATA_BITS == 64
36#define SUFFIX q
37#define DATA_TYPE uint64_t
bellardb6abf972008-05-17 12:44:31 +000038#define DATA_MASK 0xffffffffffffffffULL
39#else
40#error unhandled operand size
41#endif
42
bellard07d2c592008-05-17 13:57:33 +000043/* dynamic flags computation */
44
Blue Swirlf0967a12012-04-29 12:45:34 +000045static int glue(compute_all_add, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +000046{
47 int cf, pf, af, zf, sf, of;
48 target_long src1, src2;
Blue Swirla04759f2012-04-29 12:27:33 +000049
bellard07d2c592008-05-17 13:57:33 +000050 src1 = CC_SRC;
51 src2 = CC_DST - CC_SRC;
52 cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
53 pf = parity_table[(uint8_t)CC_DST];
54 af = (CC_DST ^ src1 ^ src2) & 0x10;
55 zf = ((DATA_TYPE)CC_DST == 0) << 6;
56 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
57 of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
58 return cf | pf | af | zf | sf | of;
59}
60
Blue Swirlf0967a12012-04-29 12:45:34 +000061static int glue(compute_c_add, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +000062{
63 int cf;
64 target_long src1;
Blue Swirla04759f2012-04-29 12:27:33 +000065
bellard07d2c592008-05-17 13:57:33 +000066 src1 = CC_SRC;
67 cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
68 return cf;
69}
70
Blue Swirlf0967a12012-04-29 12:45:34 +000071static int glue(compute_all_adc, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +000072{
73 int cf, pf, af, zf, sf, of;
74 target_long src1, src2;
Blue Swirla04759f2012-04-29 12:27:33 +000075
bellard07d2c592008-05-17 13:57:33 +000076 src1 = CC_SRC;
77 src2 = CC_DST - CC_SRC - 1;
78 cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
79 pf = parity_table[(uint8_t)CC_DST];
80 af = (CC_DST ^ src1 ^ src2) & 0x10;
81 zf = ((DATA_TYPE)CC_DST == 0) << 6;
82 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
83 of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
84 return cf | pf | af | zf | sf | of;
85}
86
Blue Swirlf0967a12012-04-29 12:45:34 +000087static int glue(compute_c_adc, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +000088{
89 int cf;
90 target_long src1;
Blue Swirla04759f2012-04-29 12:27:33 +000091
bellard07d2c592008-05-17 13:57:33 +000092 src1 = CC_SRC;
93 cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
94 return cf;
95}
96
Blue Swirlf0967a12012-04-29 12:45:34 +000097static int glue(compute_all_sub, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +000098{
99 int cf, pf, af, zf, sf, of;
100 target_long src1, src2;
Blue Swirla04759f2012-04-29 12:27:33 +0000101
bellard07d2c592008-05-17 13:57:33 +0000102 src1 = CC_DST + CC_SRC;
103 src2 = CC_SRC;
104 cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
105 pf = parity_table[(uint8_t)CC_DST];
106 af = (CC_DST ^ src1 ^ src2) & 0x10;
107 zf = ((DATA_TYPE)CC_DST == 0) << 6;
108 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
109 of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
110 return cf | pf | af | zf | sf | of;
111}
112
Blue Swirlf0967a12012-04-29 12:45:34 +0000113static int glue(compute_c_sub, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +0000114{
115 int cf;
116 target_long src1, src2;
Blue Swirla04759f2012-04-29 12:27:33 +0000117
bellard07d2c592008-05-17 13:57:33 +0000118 src1 = CC_DST + CC_SRC;
119 src2 = CC_SRC;
120 cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
121 return cf;
122}
123
Blue Swirlf0967a12012-04-29 12:45:34 +0000124static int glue(compute_all_sbb, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +0000125{
126 int cf, pf, af, zf, sf, of;
127 target_long src1, src2;
Blue Swirla04759f2012-04-29 12:27:33 +0000128
bellard07d2c592008-05-17 13:57:33 +0000129 src1 = CC_DST + CC_SRC + 1;
130 src2 = CC_SRC;
131 cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
132 pf = parity_table[(uint8_t)CC_DST];
133 af = (CC_DST ^ src1 ^ src2) & 0x10;
134 zf = ((DATA_TYPE)CC_DST == 0) << 6;
135 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
136 of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
137 return cf | pf | af | zf | sf | of;
138}
139
Blue Swirlf0967a12012-04-29 12:45:34 +0000140static int glue(compute_c_sbb, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +0000141{
142 int cf;
143 target_long src1, src2;
Blue Swirla04759f2012-04-29 12:27:33 +0000144
bellard07d2c592008-05-17 13:57:33 +0000145 src1 = CC_DST + CC_SRC + 1;
146 src2 = CC_SRC;
147 cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
148 return cf;
149}
150
Blue Swirlf0967a12012-04-29 12:45:34 +0000151static int glue(compute_all_logic, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +0000152{
153 int cf, pf, af, zf, sf, of;
Blue Swirla04759f2012-04-29 12:27:33 +0000154
bellard07d2c592008-05-17 13:57:33 +0000155 cf = 0;
156 pf = parity_table[(uint8_t)CC_DST];
157 af = 0;
158 zf = ((DATA_TYPE)CC_DST == 0) << 6;
159 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
160 of = 0;
161 return cf | pf | af | zf | sf | of;
162}
163
164static int glue(compute_c_logic, SUFFIX)(void)
165{
166 return 0;
167}
168
Blue Swirlf0967a12012-04-29 12:45:34 +0000169static int glue(compute_all_inc, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +0000170{
171 int cf, pf, af, zf, sf, of;
172 target_long src1, src2;
Blue Swirla04759f2012-04-29 12:27:33 +0000173
bellard07d2c592008-05-17 13:57:33 +0000174 src1 = CC_DST - 1;
175 src2 = 1;
176 cf = CC_SRC;
177 pf = parity_table[(uint8_t)CC_DST];
178 af = (CC_DST ^ src1 ^ src2) & 0x10;
179 zf = ((DATA_TYPE)CC_DST == 0) << 6;
180 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
181 of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
182 return cf | pf | af | zf | sf | of;
183}
184
185#if DATA_BITS == 32
Blue Swirlf0967a12012-04-29 12:45:34 +0000186static int glue(compute_c_inc, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +0000187{
188 return CC_SRC;
189}
190#endif
191
Blue Swirlf0967a12012-04-29 12:45:34 +0000192static int glue(compute_all_dec, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +0000193{
194 int cf, pf, af, zf, sf, of;
195 target_long src1, src2;
Blue Swirla04759f2012-04-29 12:27:33 +0000196
bellard07d2c592008-05-17 13:57:33 +0000197 src1 = CC_DST + 1;
198 src2 = 1;
199 cf = CC_SRC;
200 pf = parity_table[(uint8_t)CC_DST];
201 af = (CC_DST ^ src1 ^ src2) & 0x10;
202 zf = ((DATA_TYPE)CC_DST == 0) << 6;
203 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
204 of = ((CC_DST & DATA_MASK) == ((target_ulong)SIGN_MASK - 1)) << 11;
205 return cf | pf | af | zf | sf | of;
206}
207
Blue Swirlf0967a12012-04-29 12:45:34 +0000208static int glue(compute_all_shl, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +0000209{
210 int cf, pf, af, zf, sf, of;
Blue Swirla04759f2012-04-29 12:27:33 +0000211
bellard07d2c592008-05-17 13:57:33 +0000212 cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C;
213 pf = parity_table[(uint8_t)CC_DST];
214 af = 0; /* undefined */
215 zf = ((DATA_TYPE)CC_DST == 0) << 6;
216 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
217 /* of is defined if shift count == 1 */
218 of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
219 return cf | pf | af | zf | sf | of;
220}
221
Blue Swirlf0967a12012-04-29 12:45:34 +0000222static int glue(compute_c_shl, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +0000223{
224 return (CC_SRC >> (DATA_BITS - 1)) & CC_C;
225}
226
227#if DATA_BITS == 32
Blue Swirlf0967a12012-04-29 12:45:34 +0000228static int glue(compute_c_sar, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +0000229{
230 return CC_SRC & 1;
231}
232#endif
233
Blue Swirlf0967a12012-04-29 12:45:34 +0000234static int glue(compute_all_sar, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +0000235{
236 int cf, pf, af, zf, sf, of;
Blue Swirla04759f2012-04-29 12:27:33 +0000237
bellard07d2c592008-05-17 13:57:33 +0000238 cf = CC_SRC & 1;
239 pf = parity_table[(uint8_t)CC_DST];
240 af = 0; /* undefined */
241 zf = ((DATA_TYPE)CC_DST == 0) << 6;
242 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
243 /* of is defined if shift count == 1 */
244 of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
245 return cf | pf | af | zf | sf | of;
246}
247
248#if DATA_BITS == 32
Blue Swirlf0967a12012-04-29 12:45:34 +0000249static int glue(compute_c_mul, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +0000250{
251 int cf;
Blue Swirla04759f2012-04-29 12:27:33 +0000252
bellard07d2c592008-05-17 13:57:33 +0000253 cf = (CC_SRC != 0);
254 return cf;
255}
256#endif
257
258/* NOTE: we compute the flags like the P4. On olders CPUs, only OF and
259 CF are modified and it is slower to do that. */
Blue Swirlf0967a12012-04-29 12:45:34 +0000260static int glue(compute_all_mul, SUFFIX)(CPUX86State *env)
bellard07d2c592008-05-17 13:57:33 +0000261{
262 int cf, pf, af, zf, sf, of;
Blue Swirla04759f2012-04-29 12:27:33 +0000263
bellard07d2c592008-05-17 13:57:33 +0000264 cf = (CC_SRC != 0);
265 pf = parity_table[(uint8_t)CC_DST];
266 af = 0; /* undefined */
267 zf = ((DATA_TYPE)CC_DST == 0) << 6;
268 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
269 of = cf << 11;
270 return cf | pf | af | zf | sf | of;
271}
272
bellardb6abf972008-05-17 12:44:31 +0000273#undef DATA_BITS
bellardb6abf972008-05-17 12:44:31 +0000274#undef SIGN_MASK
275#undef DATA_TYPE
bellardb6abf972008-05-17 12:44:31 +0000276#undef DATA_MASK
277#undef SUFFIX