]> git.proxmox.com Git - qemu.git/blob - target-i386/cc_helper_template.h
Merge branch 's390-for-upstream' of git://repo.or.cz/qemu/agraf
[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