root / target-i386 / cc_helper_template.h @ 26ca8c06
History | View | Annotate | Download (7 kB)
1 | b6abf97d | bellard | /*
|
---|---|---|---|
2 | 38de4c46 | Blue Swirl | * x86 condition code helpers
|
3 | b6abf97d | bellard | *
|
4 | b6abf97d | bellard | * Copyright (c) 2008 Fabrice Bellard
|
5 | b6abf97d | bellard | *
|
6 | b6abf97d | bellard | * This library is free software; you can redistribute it and/or
|
7 | b6abf97d | bellard | * modify it under the terms of the GNU Lesser General Public
|
8 | b6abf97d | bellard | * License as published by the Free Software Foundation; either
|
9 | b6abf97d | bellard | * version 2 of the License, or (at your option) any later version.
|
10 | b6abf97d | bellard | *
|
11 | b6abf97d | bellard | * This library is distributed in the hope that it will be useful,
|
12 | b6abf97d | bellard | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | b6abf97d | bellard | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | b6abf97d | bellard | * Lesser General Public License for more details.
|
15 | b6abf97d | bellard | *
|
16 | b6abf97d | bellard | * You should have received a copy of the GNU Lesser General Public
|
17 | 8167ee88 | Blue Swirl | * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
18 | b6abf97d | bellard | */
|
19 | a04759f6 | Blue Swirl | |
20 | b6abf97d | bellard | #define DATA_BITS (1 << (3 + SHIFT)) |
21 | b6abf97d | bellard | #define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1)) |
22 | b6abf97d | bellard | |
23 | b6abf97d | bellard | #if DATA_BITS == 8 |
24 | b6abf97d | bellard | #define SUFFIX b
|
25 | b6abf97d | bellard | #define DATA_TYPE uint8_t
|
26 | b6abf97d | bellard | #define DATA_MASK 0xff |
27 | b6abf97d | bellard | #elif DATA_BITS == 16 |
28 | b6abf97d | bellard | #define SUFFIX w
|
29 | b6abf97d | bellard | #define DATA_TYPE uint16_t
|
30 | b6abf97d | bellard | #define DATA_MASK 0xffff |
31 | b6abf97d | bellard | #elif DATA_BITS == 32 |
32 | b6abf97d | bellard | #define SUFFIX l
|
33 | b6abf97d | bellard | #define DATA_TYPE uint32_t
|
34 | b6abf97d | bellard | #define DATA_MASK 0xffffffff |
35 | b6abf97d | bellard | #elif DATA_BITS == 64 |
36 | b6abf97d | bellard | #define SUFFIX q
|
37 | b6abf97d | bellard | #define DATA_TYPE uint64_t
|
38 | b6abf97d | bellard | #define DATA_MASK 0xffffffffffffffffULL |
39 | b6abf97d | bellard | #else
|
40 | b6abf97d | bellard | #error unhandled operand size
|
41 | b6abf97d | bellard | #endif
|
42 | b6abf97d | bellard | |
43 | 07d2c595 | bellard | /* dynamic flags computation */
|
44 | 07d2c595 | bellard | |
45 | f0967a1a | Blue Swirl | static int glue(compute_all_add, SUFFIX)(CPUX86State *env) |
46 | 07d2c595 | bellard | { |
47 | 07d2c595 | bellard | int cf, pf, af, zf, sf, of;
|
48 | 07d2c595 | bellard | target_long src1, src2; |
49 | a04759f6 | Blue Swirl | |
50 | 07d2c595 | bellard | src1 = CC_SRC; |
51 | 07d2c595 | bellard | src2 = CC_DST - CC_SRC; |
52 | 07d2c595 | bellard | cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1; |
53 | 07d2c595 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
54 | 07d2c595 | bellard | af = (CC_DST ^ src1 ^ src2) & 0x10;
|
55 | 07d2c595 | bellard | zf = ((DATA_TYPE)CC_DST == 0) << 6; |
56 | 07d2c595 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
57 | 07d2c595 | bellard | of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O; |
58 | 07d2c595 | bellard | return cf | pf | af | zf | sf | of;
|
59 | 07d2c595 | bellard | } |
60 | 07d2c595 | bellard | |
61 | f0967a1a | Blue Swirl | static int glue(compute_c_add, SUFFIX)(CPUX86State *env) |
62 | 07d2c595 | bellard | { |
63 | 07d2c595 | bellard | int cf;
|
64 | 07d2c595 | bellard | target_long src1; |
65 | a04759f6 | Blue Swirl | |
66 | 07d2c595 | bellard | src1 = CC_SRC; |
67 | 07d2c595 | bellard | cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1; |
68 | 07d2c595 | bellard | return cf;
|
69 | 07d2c595 | bellard | } |
70 | 07d2c595 | bellard | |
71 | f0967a1a | Blue Swirl | static int glue(compute_all_adc, SUFFIX)(CPUX86State *env) |
72 | 07d2c595 | bellard | { |
73 | 07d2c595 | bellard | int cf, pf, af, zf, sf, of;
|
74 | 07d2c595 | bellard | target_long src1, src2; |
75 | a04759f6 | Blue Swirl | |
76 | 07d2c595 | bellard | src1 = CC_SRC; |
77 | 07d2c595 | bellard | src2 = CC_DST - CC_SRC - 1;
|
78 | 07d2c595 | bellard | cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1; |
79 | 07d2c595 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
80 | 07d2c595 | bellard | af = (CC_DST ^ src1 ^ src2) & 0x10;
|
81 | 07d2c595 | bellard | zf = ((DATA_TYPE)CC_DST == 0) << 6; |
82 | 07d2c595 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
83 | 07d2c595 | bellard | of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O; |
84 | 07d2c595 | bellard | return cf | pf | af | zf | sf | of;
|
85 | 07d2c595 | bellard | } |
86 | 07d2c595 | bellard | |
87 | f0967a1a | Blue Swirl | static int glue(compute_c_adc, SUFFIX)(CPUX86State *env) |
88 | 07d2c595 | bellard | { |
89 | 07d2c595 | bellard | int cf;
|
90 | 07d2c595 | bellard | target_long src1; |
91 | a04759f6 | Blue Swirl | |
92 | 07d2c595 | bellard | src1 = CC_SRC; |
93 | 07d2c595 | bellard | cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1; |
94 | 07d2c595 | bellard | return cf;
|
95 | 07d2c595 | bellard | } |
96 | 07d2c595 | bellard | |
97 | f0967a1a | Blue Swirl | static int glue(compute_all_sub, SUFFIX)(CPUX86State *env) |
98 | 07d2c595 | bellard | { |
99 | 07d2c595 | bellard | int cf, pf, af, zf, sf, of;
|
100 | 07d2c595 | bellard | target_long src1, src2; |
101 | a04759f6 | Blue Swirl | |
102 | 07d2c595 | bellard | src1 = CC_DST + CC_SRC; |
103 | 07d2c595 | bellard | src2 = CC_SRC; |
104 | 07d2c595 | bellard | cf = (DATA_TYPE)src1 < (DATA_TYPE)src2; |
105 | 07d2c595 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
106 | 07d2c595 | bellard | af = (CC_DST ^ src1 ^ src2) & 0x10;
|
107 | 07d2c595 | bellard | zf = ((DATA_TYPE)CC_DST == 0) << 6; |
108 | 07d2c595 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
109 | 07d2c595 | bellard | of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
|
110 | 07d2c595 | bellard | return cf | pf | af | zf | sf | of;
|
111 | 07d2c595 | bellard | } |
112 | 07d2c595 | bellard | |
113 | f0967a1a | Blue Swirl | static int glue(compute_c_sub, SUFFIX)(CPUX86State *env) |
114 | 07d2c595 | bellard | { |
115 | 07d2c595 | bellard | int cf;
|
116 | 07d2c595 | bellard | target_long src1, src2; |
117 | a04759f6 | Blue Swirl | |
118 | 07d2c595 | bellard | src1 = CC_DST + CC_SRC; |
119 | 07d2c595 | bellard | src2 = CC_SRC; |
120 | 07d2c595 | bellard | cf = (DATA_TYPE)src1 < (DATA_TYPE)src2; |
121 | 07d2c595 | bellard | return cf;
|
122 | 07d2c595 | bellard | } |
123 | 07d2c595 | bellard | |
124 | f0967a1a | Blue Swirl | static int glue(compute_all_sbb, SUFFIX)(CPUX86State *env) |
125 | 07d2c595 | bellard | { |
126 | 07d2c595 | bellard | int cf, pf, af, zf, sf, of;
|
127 | 07d2c595 | bellard | target_long src1, src2; |
128 | a04759f6 | Blue Swirl | |
129 | 07d2c595 | bellard | src1 = CC_DST + CC_SRC + 1;
|
130 | 07d2c595 | bellard | src2 = CC_SRC; |
131 | 07d2c595 | bellard | cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2; |
132 | 07d2c595 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
133 | 07d2c595 | bellard | af = (CC_DST ^ src1 ^ src2) & 0x10;
|
134 | 07d2c595 | bellard | zf = ((DATA_TYPE)CC_DST == 0) << 6; |
135 | 07d2c595 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
136 | 07d2c595 | bellard | of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
|
137 | 07d2c595 | bellard | return cf | pf | af | zf | sf | of;
|
138 | 07d2c595 | bellard | } |
139 | 07d2c595 | bellard | |
140 | f0967a1a | Blue Swirl | static int glue(compute_c_sbb, SUFFIX)(CPUX86State *env) |
141 | 07d2c595 | bellard | { |
142 | 07d2c595 | bellard | int cf;
|
143 | 07d2c595 | bellard | target_long src1, src2; |
144 | a04759f6 | Blue Swirl | |
145 | 07d2c595 | bellard | src1 = CC_DST + CC_SRC + 1;
|
146 | 07d2c595 | bellard | src2 = CC_SRC; |
147 | 07d2c595 | bellard | cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2; |
148 | 07d2c595 | bellard | return cf;
|
149 | 07d2c595 | bellard | } |
150 | 07d2c595 | bellard | |
151 | f0967a1a | Blue Swirl | static int glue(compute_all_logic, SUFFIX)(CPUX86State *env) |
152 | 07d2c595 | bellard | { |
153 | 07d2c595 | bellard | int cf, pf, af, zf, sf, of;
|
154 | a04759f6 | Blue Swirl | |
155 | 07d2c595 | bellard | cf = 0;
|
156 | 07d2c595 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
157 | 07d2c595 | bellard | af = 0;
|
158 | 07d2c595 | bellard | zf = ((DATA_TYPE)CC_DST == 0) << 6; |
159 | 07d2c595 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
160 | 07d2c595 | bellard | of = 0;
|
161 | 07d2c595 | bellard | return cf | pf | af | zf | sf | of;
|
162 | 07d2c595 | bellard | } |
163 | 07d2c595 | bellard | |
164 | 07d2c595 | bellard | static int glue(compute_c_logic, SUFFIX)(void) |
165 | 07d2c595 | bellard | { |
166 | 07d2c595 | bellard | return 0; |
167 | 07d2c595 | bellard | } |
168 | 07d2c595 | bellard | |
169 | f0967a1a | Blue Swirl | static int glue(compute_all_inc, SUFFIX)(CPUX86State *env) |
170 | 07d2c595 | bellard | { |
171 | 07d2c595 | bellard | int cf, pf, af, zf, sf, of;
|
172 | 07d2c595 | bellard | target_long src1, src2; |
173 | a04759f6 | Blue Swirl | |
174 | 07d2c595 | bellard | src1 = CC_DST - 1;
|
175 | 07d2c595 | bellard | src2 = 1;
|
176 | 07d2c595 | bellard | cf = CC_SRC; |
177 | 07d2c595 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
178 | 07d2c595 | bellard | af = (CC_DST ^ src1 ^ src2) & 0x10;
|
179 | 07d2c595 | bellard | zf = ((DATA_TYPE)CC_DST == 0) << 6; |
180 | 07d2c595 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
181 | 07d2c595 | bellard | of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
|
182 | 07d2c595 | bellard | return cf | pf | af | zf | sf | of;
|
183 | 07d2c595 | bellard | } |
184 | 07d2c595 | bellard | |
185 | 07d2c595 | bellard | #if DATA_BITS == 32 |
186 | f0967a1a | Blue Swirl | static int glue(compute_c_inc, SUFFIX)(CPUX86State *env) |
187 | 07d2c595 | bellard | { |
188 | 07d2c595 | bellard | return CC_SRC;
|
189 | 07d2c595 | bellard | } |
190 | 07d2c595 | bellard | #endif
|
191 | 07d2c595 | bellard | |
192 | f0967a1a | Blue Swirl | static int glue(compute_all_dec, SUFFIX)(CPUX86State *env) |
193 | 07d2c595 | bellard | { |
194 | 07d2c595 | bellard | int cf, pf, af, zf, sf, of;
|
195 | 07d2c595 | bellard | target_long src1, src2; |
196 | a04759f6 | Blue Swirl | |
197 | 07d2c595 | bellard | src1 = CC_DST + 1;
|
198 | 07d2c595 | bellard | src2 = 1;
|
199 | 07d2c595 | bellard | cf = CC_SRC; |
200 | 07d2c595 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
201 | 07d2c595 | bellard | af = (CC_DST ^ src1 ^ src2) & 0x10;
|
202 | 07d2c595 | bellard | zf = ((DATA_TYPE)CC_DST == 0) << 6; |
203 | 07d2c595 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
204 | 07d2c595 | bellard | of = ((CC_DST & DATA_MASK) == ((target_ulong)SIGN_MASK - 1)) << 11; |
205 | 07d2c595 | bellard | return cf | pf | af | zf | sf | of;
|
206 | 07d2c595 | bellard | } |
207 | 07d2c595 | bellard | |
208 | f0967a1a | Blue Swirl | static int glue(compute_all_shl, SUFFIX)(CPUX86State *env) |
209 | 07d2c595 | bellard | { |
210 | 07d2c595 | bellard | int cf, pf, af, zf, sf, of;
|
211 | a04759f6 | Blue Swirl | |
212 | 07d2c595 | bellard | cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C;
|
213 | 07d2c595 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
214 | 07d2c595 | bellard | af = 0; /* undefined */ |
215 | 07d2c595 | bellard | zf = ((DATA_TYPE)CC_DST == 0) << 6; |
216 | 07d2c595 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
217 | 07d2c595 | bellard | /* of is defined if shift count == 1 */
|
218 | 07d2c595 | bellard | of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
|
219 | 07d2c595 | bellard | return cf | pf | af | zf | sf | of;
|
220 | 07d2c595 | bellard | } |
221 | 07d2c595 | bellard | |
222 | f0967a1a | Blue Swirl | static int glue(compute_c_shl, SUFFIX)(CPUX86State *env) |
223 | 07d2c595 | bellard | { |
224 | 07d2c595 | bellard | return (CC_SRC >> (DATA_BITS - 1)) & CC_C; |
225 | 07d2c595 | bellard | } |
226 | 07d2c595 | bellard | |
227 | 07d2c595 | bellard | #if DATA_BITS == 32 |
228 | f0967a1a | Blue Swirl | static int glue(compute_c_sar, SUFFIX)(CPUX86State *env) |
229 | 07d2c595 | bellard | { |
230 | 07d2c595 | bellard | return CC_SRC & 1; |
231 | 07d2c595 | bellard | } |
232 | 07d2c595 | bellard | #endif
|
233 | 07d2c595 | bellard | |
234 | f0967a1a | Blue Swirl | static int glue(compute_all_sar, SUFFIX)(CPUX86State *env) |
235 | 07d2c595 | bellard | { |
236 | 07d2c595 | bellard | int cf, pf, af, zf, sf, of;
|
237 | a04759f6 | Blue Swirl | |
238 | 07d2c595 | bellard | cf = CC_SRC & 1;
|
239 | 07d2c595 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
240 | 07d2c595 | bellard | af = 0; /* undefined */ |
241 | 07d2c595 | bellard | zf = ((DATA_TYPE)CC_DST == 0) << 6; |
242 | 07d2c595 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
243 | 07d2c595 | bellard | /* of is defined if shift count == 1 */
|
244 | 07d2c595 | bellard | of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
|
245 | 07d2c595 | bellard | return cf | pf | af | zf | sf | of;
|
246 | 07d2c595 | bellard | } |
247 | 07d2c595 | bellard | |
248 | 07d2c595 | bellard | #if DATA_BITS == 32 |
249 | f0967a1a | Blue Swirl | static int glue(compute_c_mul, SUFFIX)(CPUX86State *env) |
250 | 07d2c595 | bellard | { |
251 | 07d2c595 | bellard | int cf;
|
252 | a04759f6 | Blue Swirl | |
253 | 07d2c595 | bellard | cf = (CC_SRC != 0);
|
254 | 07d2c595 | bellard | return cf;
|
255 | 07d2c595 | bellard | } |
256 | 07d2c595 | bellard | #endif
|
257 | 07d2c595 | bellard | |
258 | 07d2c595 | bellard | /* NOTE: we compute the flags like the P4. On olders CPUs, only OF and
|
259 | 07d2c595 | bellard | CF are modified and it is slower to do that. */
|
260 | f0967a1a | Blue Swirl | static int glue(compute_all_mul, SUFFIX)(CPUX86State *env) |
261 | 07d2c595 | bellard | { |
262 | 07d2c595 | bellard | int cf, pf, af, zf, sf, of;
|
263 | a04759f6 | Blue Swirl | |
264 | 07d2c595 | bellard | cf = (CC_SRC != 0);
|
265 | 07d2c595 | bellard | pf = parity_table[(uint8_t)CC_DST]; |
266 | 07d2c595 | bellard | af = 0; /* undefined */ |
267 | 07d2c595 | bellard | zf = ((DATA_TYPE)CC_DST == 0) << 6; |
268 | 07d2c595 | bellard | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
269 | 07d2c595 | bellard | of = cf << 11;
|
270 | 07d2c595 | bellard | return cf | pf | af | zf | sf | of;
|
271 | 07d2c595 | bellard | } |
272 | 07d2c595 | bellard | |
273 | b6abf97d | bellard | #undef DATA_BITS
|
274 | b6abf97d | bellard | #undef SIGN_MASK
|
275 | b6abf97d | bellard | #undef DATA_TYPE
|
276 | b6abf97d | bellard | #undef DATA_MASK
|
277 | b6abf97d | bellard | #undef SUFFIX |