]> git.proxmox.com Git - qemu.git/blame - target-i386/cc_helper_template.h
migration: make qemu_ftell() public and support writable files
[qemu.git] / target-i386 / cc_helper_template.h
CommitLineData
b6abf97d 1/*
38de4c46 2 * x86 condition code helpers
b6abf97d
FB
3 *
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
8167ee88 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
b6abf97d 18 */
a04759f6 19
b6abf97d 20#define DATA_BITS (1 << (3 + SHIFT))
b6abf97d 21#define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1))
b6abf97d
FB
22
23#if DATA_BITS == 8
24#define SUFFIX b
25#define DATA_TYPE uint8_t
b6abf97d
FB
26#define DATA_MASK 0xff
27#elif DATA_BITS == 16
28#define SUFFIX w
29#define DATA_TYPE uint16_t
b6abf97d
FB
30#define DATA_MASK 0xffff
31#elif DATA_BITS == 32
32#define SUFFIX l
33#define DATA_TYPE uint32_t
b6abf97d
FB
34#define DATA_MASK 0xffffffff
35#elif DATA_BITS == 64
36#define SUFFIX q
37#define DATA_TYPE uint64_t
b6abf97d
FB
38#define DATA_MASK 0xffffffffffffffffULL
39#else
40#error unhandled operand size
41#endif
42
07d2c595
FB
43/* dynamic flags computation */
44
f0967a1a 45static int glue(compute_all_add, SUFFIX)(CPUX86State *env)
07d2c595
FB
46{
47 int cf, pf, af, zf, sf, of;
48 target_long src1, src2;
a04759f6 49
07d2c595
FB
50 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
f0967a1a 61static int glue(compute_c_add, SUFFIX)(CPUX86State *env)
07d2c595
FB
62{
63 int cf;
64 target_long src1;
a04759f6 65
07d2c595
FB
66 src1 = CC_SRC;
67 cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
68 return cf;
69}
70
f0967a1a 71static int glue(compute_all_adc, SUFFIX)(CPUX86State *env)
07d2c595
FB
72{
73 int cf, pf, af, zf, sf, of;
74 target_long src1, src2;
a04759f6 75
07d2c595
FB
76 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
f0967a1a 87static int glue(compute_c_adc, SUFFIX)(CPUX86State *env)
07d2c595
FB
88{
89 int cf;
90 target_long src1;
a04759f6 91
07d2c595
FB
92 src1 = CC_SRC;
93 cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
94 return cf;
95}
96
f0967a1a 97static int glue(compute_all_sub, SUFFIX)(CPUX86State *env)
07d2c595
FB
98{
99 int cf, pf, af, zf, sf, of;
100 target_long src1, src2;
a04759f6 101
07d2c595
FB
102 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
f0967a1a 113static int glue(compute_c_sub, SUFFIX)(CPUX86State *env)
07d2c595
FB
114{
115 int cf;
116 target_long src1, src2;
a04759f6 117
07d2c595
FB
118 src1 = CC_DST + CC_SRC;
119 src2 = CC_SRC;
120 cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
121 return cf;
122}
123
f0967a1a 124static int glue(compute_all_sbb, SUFFIX)(CPUX86State *env)
07d2c595
FB
125{
126 int cf, pf, af, zf, sf, of;
127 target_long src1, src2;
a04759f6 128
07d2c595
FB
129 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
f0967a1a 140static int glue(compute_c_sbb, SUFFIX)(CPUX86State *env)
07d2c595
FB
141{
142 int cf;
143 target_long src1, src2;
a04759f6 144
07d2c595
FB
145 src1 = CC_DST + CC_SRC + 1;
146 src2 = CC_SRC;
147 cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
148 return cf;
149}
150
f0967a1a 151static int glue(compute_all_logic, SUFFIX)(CPUX86State *env)
07d2c595
FB
152{
153 int cf, pf, af, zf, sf, of;
a04759f6 154
07d2c595
FB
155 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
f0967a1a 169static int glue(compute_all_inc, SUFFIX)(CPUX86State *env)
07d2c595
FB
170{
171 int cf, pf, af, zf, sf, of;
172 target_long src1, src2;
a04759f6 173
07d2c595
FB
174 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
f0967a1a 186static int glue(compute_c_inc, SUFFIX)(CPUX86State *env)
07d2c595
FB
187{
188 return CC_SRC;
189}
190#endif
191
f0967a1a 192static int glue(compute_all_dec, SUFFIX)(CPUX86State *env)
07d2c595
FB
193{
194 int cf, pf, af, zf, sf, of;
195 target_long src1, src2;
a04759f6 196
07d2c595
FB
197 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
f0967a1a 208static int glue(compute_all_shl, SUFFIX)(CPUX86State *env)
07d2c595
FB
209{
210 int cf, pf, af, zf, sf, of;
a04759f6 211
07d2c595
FB
212 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
f0967a1a 222static int glue(compute_c_shl, SUFFIX)(CPUX86State *env)
07d2c595
FB
223{
224 return (CC_SRC >> (DATA_BITS - 1)) & CC_C;
225}
226
227#if DATA_BITS == 32
f0967a1a 228static int glue(compute_c_sar, SUFFIX)(CPUX86State *env)
07d2c595
FB
229{
230 return CC_SRC & 1;
231}
232#endif
233
f0967a1a 234static int glue(compute_all_sar, SUFFIX)(CPUX86State *env)
07d2c595
FB
235{
236 int cf, pf, af, zf, sf, of;
a04759f6 237
07d2c595
FB
238 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
f0967a1a 249static int glue(compute_c_mul, SUFFIX)(CPUX86State *env)
07d2c595
FB
250{
251 int cf;
a04759f6 252
07d2c595
FB
253 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. */
f0967a1a 260static int glue(compute_all_mul, SUFFIX)(CPUX86State *env)
07d2c595
FB
261{
262 int cf, pf, af, zf, sf, of;
a04759f6 263
07d2c595
FB
264 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
b6abf97d 273#undef DATA_BITS
b6abf97d
FB
274#undef SIGN_MASK
275#undef DATA_TYPE
b6abf97d
FB
276#undef DATA_MASK
277#undef SUFFIX