sync with latest
[sdk/emulator/qemu.git] / target-i386 / cc_helper_template.h
1 /*
2  *  x86 condition code helpers
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
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #define DATA_BITS (1 << (3 + SHIFT))
21 #define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1))
22
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
42
43 /* dynamic flags computation */
44
45 static int glue(compute_all_add, SUFFIX)(CPUX86State *env)
46 {
47     int cf, pf, af, zf, sf, of;
48     target_long src1, src2;
49
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
61 static int glue(compute_c_add, SUFFIX)(CPUX86State *env)
62 {
63     int cf;
64     target_long src1;
65
66     src1 = CC_SRC;
67     cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
68     return cf;
69 }
70
71 static int glue(compute_all_adc, SUFFIX)(CPUX86State *env)
72 {
73     int cf, pf, af, zf, sf, of;
74     target_long src1, src2;
75
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
87 static int glue(compute_c_adc, SUFFIX)(CPUX86State *env)
88 {
89     int cf;
90     target_long src1;
91
92     src1 = CC_SRC;
93     cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
94     return cf;
95 }
96
97 static int glue(compute_all_sub, SUFFIX)(CPUX86State *env)
98 {
99     int cf, pf, af, zf, sf, of;
100     target_long src1, src2;
101
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
113 static int glue(compute_c_sub, SUFFIX)(CPUX86State *env)
114 {
115     int cf;
116     target_long src1, src2;
117
118     src1 = CC_DST + CC_SRC;
119     src2 = CC_SRC;
120     cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
121     return cf;
122 }
123
124 static int glue(compute_all_sbb, SUFFIX)(CPUX86State *env)
125 {
126     int cf, pf, af, zf, sf, of;
127     target_long src1, src2;
128
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
140 static int glue(compute_c_sbb, SUFFIX)(CPUX86State *env)
141 {
142     int cf;
143     target_long src1, src2;
144
145     src1 = CC_DST + CC_SRC + 1;
146     src2 = CC_SRC;
147     cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
148     return cf;
149 }
150
151 static int glue(compute_all_logic, SUFFIX)(CPUX86State *env)
152 {
153     int cf, pf, af, zf, sf, of;
154
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
164 static int glue(compute_c_logic, SUFFIX)(void)
165 {
166     return 0;
167 }
168
169 static int glue(compute_all_inc, SUFFIX)(CPUX86State *env)
170 {
171     int cf, pf, af, zf, sf, of;
172     target_long src1, src2;
173
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
186 static int glue(compute_c_inc, SUFFIX)(CPUX86State *env)
187 {
188     return CC_SRC;
189 }
190 #endif
191
192 static int glue(compute_all_dec, SUFFIX)(CPUX86State *env)
193 {
194     int cf, pf, af, zf, sf, of;
195     target_long src1, src2;
196
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
208 static int glue(compute_all_shl, SUFFIX)(CPUX86State *env)
209 {
210     int cf, pf, af, zf, sf, of;
211
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
222 static int glue(compute_c_shl, SUFFIX)(CPUX86State *env)
223 {
224     return (CC_SRC >> (DATA_BITS - 1)) & CC_C;
225 }
226
227 #if DATA_BITS == 32
228 static int glue(compute_c_sar, SUFFIX)(CPUX86State *env)
229 {
230     return CC_SRC & 1;
231 }
232 #endif
233
234 static int glue(compute_all_sar, SUFFIX)(CPUX86State *env)
235 {
236     int cf, pf, af, zf, sf, of;
237
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
249 static int glue(compute_c_mul, SUFFIX)(CPUX86State *env)
250 {
251     int cf;
252
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. */
260 static int glue(compute_all_mul, SUFFIX)(CPUX86State *env)
261 {
262     int cf, pf, af, zf, sf, of;
263
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
273 #undef DATA_BITS
274 #undef SIGN_MASK
275 #undef DATA_TYPE
276 #undef DATA_MASK
277 #undef SUFFIX