target-alpha: Add support for -cpu ?
[qemu/opensuse.git] / target-i386 / cc_helper_template.h
blob1f94e11dcf0606923d2c670d4773fdf7db9aaa69
1 /*
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))
21 #define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1))
23 #if DATA_BITS == 8
24 #define SUFFIX b
25 #define DATA_TYPE uint8_t
26 #define DATA_MASK 0xff
27 #elif DATA_BITS == 16
28 #define SUFFIX w
29 #define DATA_TYPE uint16_t
30 #define DATA_MASK 0xffff
31 #elif DATA_BITS == 32
32 #define SUFFIX l
33 #define DATA_TYPE uint32_t
34 #define DATA_MASK 0xffffffff
35 #elif DATA_BITS == 64
36 #define SUFFIX q
37 #define DATA_TYPE uint64_t
38 #define DATA_MASK 0xffffffffffffffffULL
39 #else
40 #error unhandled operand size
41 #endif
43 /* dynamic flags computation */
45 static int glue(compute_all_add, SUFFIX)(CPUX86State *env)
47 int cf, pf, af, zf, sf, of;
48 target_long src1, src2;
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;
61 static int glue(compute_c_add, SUFFIX)(CPUX86State *env)
63 int cf;
64 target_long src1;
66 src1 = CC_SRC;
67 cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
68 return cf;
71 static int glue(compute_all_adc, SUFFIX)(CPUX86State *env)
73 int cf, pf, af, zf, sf, of;
74 target_long src1, src2;
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;
87 static int glue(compute_c_adc, SUFFIX)(CPUX86State *env)
89 int cf;
90 target_long src1;
92 src1 = CC_SRC;
93 cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
94 return cf;
97 static int glue(compute_all_sub, SUFFIX)(CPUX86State *env)
99 int cf, pf, af, zf, sf, of;
100 target_long src1, src2;
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;
113 static int glue(compute_c_sub, SUFFIX)(CPUX86State *env)
115 int cf;
116 target_long src1, src2;
118 src1 = CC_DST + CC_SRC;
119 src2 = CC_SRC;
120 cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
121 return cf;
124 static int glue(compute_all_sbb, SUFFIX)(CPUX86State *env)
126 int cf, pf, af, zf, sf, of;
127 target_long src1, src2;
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;
140 static int glue(compute_c_sbb, SUFFIX)(CPUX86State *env)
142 int cf;
143 target_long src1, src2;
145 src1 = CC_DST + CC_SRC + 1;
146 src2 = CC_SRC;
147 cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
148 return cf;
151 static int glue(compute_all_logic, SUFFIX)(CPUX86State *env)
153 int cf, pf, af, zf, sf, of;
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;
164 static int glue(compute_c_logic, SUFFIX)(void)
166 return 0;
169 static int glue(compute_all_inc, SUFFIX)(CPUX86State *env)
171 int cf, pf, af, zf, sf, of;
172 target_long src1, src2;
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;
185 #if DATA_BITS == 32
186 static int glue(compute_c_inc, SUFFIX)(CPUX86State *env)
188 return CC_SRC;
190 #endif
192 static int glue(compute_all_dec, SUFFIX)(CPUX86State *env)
194 int cf, pf, af, zf, sf, of;
195 target_long src1, src2;
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;
208 static int glue(compute_all_shl, SUFFIX)(CPUX86State *env)
210 int cf, pf, af, zf, sf, of;
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;
222 static int glue(compute_c_shl, SUFFIX)(CPUX86State *env)
224 return (CC_SRC >> (DATA_BITS - 1)) & CC_C;
227 #if DATA_BITS == 32
228 static int glue(compute_c_sar, SUFFIX)(CPUX86State *env)
230 return CC_SRC & 1;
232 #endif
234 static int glue(compute_all_sar, SUFFIX)(CPUX86State *env)
236 int cf, pf, af, zf, sf, of;
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;
248 #if DATA_BITS == 32
249 static int glue(compute_c_mul, SUFFIX)(CPUX86State *env)
251 int cf;
253 cf = (CC_SRC != 0);
254 return cf;
256 #endif
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. */
260 static int glue(compute_all_mul, SUFFIX)(CPUX86State *env)
262 int cf, pf, af, zf, sf, of;
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;
273 #undef DATA_BITS
274 #undef SIGN_MASK
275 #undef DATA_TYPE
276 #undef DATA_MASK
277 #undef SUFFIX