Add qemu 2.4.0
[kvmfornfv.git] / qemu / 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
22 #if DATA_BITS == 8
23 #define SUFFIX b
24 #define DATA_TYPE uint8_t
25 #elif DATA_BITS == 16
26 #define SUFFIX w
27 #define DATA_TYPE uint16_t
28 #elif DATA_BITS == 32
29 #define SUFFIX l
30 #define DATA_TYPE uint32_t
31 #elif DATA_BITS == 64
32 #define SUFFIX q
33 #define DATA_TYPE uint64_t
34 #else
35 #error unhandled operand size
36 #endif
37
38 #define SIGN_MASK (((DATA_TYPE)1) << (DATA_BITS - 1))
39
40 /* dynamic flags computation */
41
42 static int glue(compute_all_add, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
43 {
44     int cf, pf, af, zf, sf, of;
45     DATA_TYPE src2 = dst - src1;
46
47     cf = 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;
54 }
55
56 static int glue(compute_c_add, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
57 {
58     return dst < src1;
59 }
60
61 static int glue(compute_all_adc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1,
62                                          DATA_TYPE src3)
63 {
64     int cf, pf, af, zf, sf, of;
65     DATA_TYPE src2 = dst - src1 - src3;
66
67     cf = (src3 ? dst <= src1 : dst < src1);
68     pf = parity_table[(uint8_t)dst];
69     af = (dst ^ src1 ^ src2) & 0x10;
70     zf = (dst == 0) << 6;
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;
74 }
75
76 static int glue(compute_c_adc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1,
77                                        DATA_TYPE src3)
78 {
79     return src3 ? dst <= src1 : dst < src1;
80 }
81
82 static int glue(compute_all_sub, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2)
83 {
84     int cf, pf, af, zf, sf, of;
85     DATA_TYPE src1 = dst + src2;
86
87     cf = src1 < 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;
94 }
95
96 static int glue(compute_c_sub, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2)
97 {
98     DATA_TYPE src1 = dst + src2;
99
100     return src1 < src2;
101 }
102
103 static int glue(compute_all_sbb, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2,
104                                          DATA_TYPE src3)
105 {
106     int cf, pf, af, zf, sf, of;
107     DATA_TYPE src1 = dst + src2 + src3;
108
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;
116 }
117
118 static int glue(compute_c_sbb, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2,
119                                        DATA_TYPE src3)
120 {
121     DATA_TYPE src1 = dst + src2 + src3;
122
123     return (src3 ? src1 <= src2 : src1 < src2);
124 }
125
126 static int glue(compute_all_logic, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
127 {
128     int cf, pf, af, zf, sf, of;
129
130     cf = 0;
131     pf = parity_table[(uint8_t)dst];
132     af = 0;
133     zf = (dst == 0) * CC_Z;
134     sf = lshift(dst, 8 - DATA_BITS) & CC_S;
135     of = 0;
136     return cf | pf | af | zf | sf | of;
137 }
138
139 static int glue(compute_all_inc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
140 {
141     int cf, pf, af, zf, sf, of;
142     DATA_TYPE src2;
143
144     cf = src1;
145     src1 = dst - 1;
146     src2 = 1;
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;
153 }
154
155 static int glue(compute_all_dec, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
156 {
157     int cf, pf, af, zf, sf, of;
158     DATA_TYPE src2;
159
160     cf = src1;
161     src1 = dst + 1;
162     src2 = 1;
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;
169 }
170
171 static int glue(compute_all_shl, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
172 {
173     int cf, pf, af, zf, sf, of;
174
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;
183 }
184
185 static int glue(compute_c_shl, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
186 {
187     return (src1 >> (DATA_BITS - 1)) & CC_C;
188 }
189
190 static int glue(compute_all_sar, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
191 {
192     int cf, pf, af, zf, sf, of;
193
194     cf = src1 & 1;
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;
202 }
203
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)
208 {
209     int cf, pf, af, zf, sf, of;
210
211     cf = (src1 != 0);
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;
216     of = cf * CC_O;
217     return cf | pf | af | zf | sf | of;
218 }
219
220 static int glue(compute_all_bmilg, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
221 {
222     int cf, pf, af, zf, sf, of;
223
224     cf = (src1 == 0);
225     pf = 0; /* undefined */
226     af = 0; /* undefined */
227     zf = (dst == 0) * CC_Z;
228     sf = lshift(dst, 8 - DATA_BITS) & CC_S;
229     of = 0;
230     return cf | pf | af | zf | sf | of;
231 }
232
233 static int glue(compute_c_bmilg, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
234 {
235     return src1 == 0;
236 }
237
238 #undef DATA_BITS
239 #undef SIGN_MASK
240 #undef DATA_TYPE
241 #undef DATA_MASK
242 #undef SUFFIX