]> git.proxmox.com Git - qemu.git/blame - target-i386/cc_helper_template.h
usb-host: add usb_host_full_speed_compat
[qemu.git] / target-i386 / cc_helper_template.h
CommitLineData
b6abf97d 1/*
38de4c46 2 * x86 condition code helpers
b6abf97d
FB
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
8167ee88 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
b6abf97d 18 */
a04759f6 19
b6abf97d 20#define DATA_BITS (1 << (3 + SHIFT))
b6abf97d
FB
21
22#if DATA_BITS == 8
23#define SUFFIX b
24#define DATA_TYPE uint8_t
b6abf97d
FB
25#elif DATA_BITS == 16
26#define SUFFIX w
27#define DATA_TYPE uint16_t
b6abf97d
FB
28#elif DATA_BITS == 32
29#define SUFFIX l
30#define DATA_TYPE uint32_t
b6abf97d
FB
31#elif DATA_BITS == 64
32#define SUFFIX q
33#define DATA_TYPE uint64_t
b6abf97d
FB
34#else
35#error unhandled operand size
36#endif
37
8601c0b6
RH
38#define SIGN_MASK (((DATA_TYPE)1) << (DATA_BITS - 1))
39
07d2c595
FB
40/* dynamic flags computation */
41
8601c0b6 42static int glue(compute_all_add, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
07d2c595
FB
43{
44 int cf, pf, af, zf, sf, of;
8601c0b6
RH
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;
07d2c595
FB
53 return cf | pf | af | zf | sf | of;
54}
55
8601c0b6 56static int glue(compute_c_add, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
07d2c595 57{
8601c0b6 58 return dst < src1;
07d2c595
FB
59}
60
988c3eb0
RH
61static int glue(compute_all_adc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1,
62 DATA_TYPE src3)
07d2c595
FB
63{
64 int cf, pf, af, zf, sf, of;
988c3eb0 65 DATA_TYPE src2 = dst - src1 - src3;
8601c0b6 66
988c3eb0 67 cf = (src3 ? dst <= src1 : dst < src1);
8601c0b6
RH
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;
07d2c595
FB
73 return cf | pf | af | zf | sf | of;
74}
75
988c3eb0
RH
76static int glue(compute_c_adc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1,
77 DATA_TYPE src3)
07d2c595 78{
988c3eb0 79 return src3 ? dst <= src1 : dst < src1;
07d2c595
FB
80}
81
8601c0b6 82static int glue(compute_all_sub, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2)
07d2c595
FB
83{
84 int cf, pf, af, zf, sf, of;
8601c0b6
RH
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;
07d2c595
FB
93 return cf | pf | af | zf | sf | of;
94}
95
8601c0b6 96static int glue(compute_c_sub, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2)
07d2c595 97{
8601c0b6 98 DATA_TYPE src1 = dst + src2;
a04759f6 99
8601c0b6 100 return src1 < src2;
07d2c595
FB
101}
102
988c3eb0
RH
103static int glue(compute_all_sbb, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2,
104 DATA_TYPE src3)
07d2c595
FB
105{
106 int cf, pf, af, zf, sf, of;
988c3eb0 107 DATA_TYPE src1 = dst + src2 + src3;
8601c0b6 108
988c3eb0 109 cf = (src3 ? src1 <= src2 : src1 < src2);
8601c0b6
RH
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;
07d2c595
FB
115 return cf | pf | af | zf | sf | of;
116}
117
988c3eb0
RH
118static int glue(compute_c_sbb, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2,
119 DATA_TYPE src3)
07d2c595 120{
988c3eb0 121 DATA_TYPE src1 = dst + src2 + src3;
a04759f6 122
988c3eb0 123 return (src3 ? src1 <= src2 : src1 < src2);
07d2c595
FB
124}
125
8601c0b6 126static int glue(compute_all_logic, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
07d2c595
FB
127{
128 int cf, pf, af, zf, sf, of;
a04759f6 129
07d2c595 130 cf = 0;
8601c0b6 131 pf = parity_table[(uint8_t)dst];
07d2c595 132 af = 0;
8601c0b6
RH
133 zf = (dst == 0) * CC_Z;
134 sf = lshift(dst, 8 - DATA_BITS) & CC_S;
07d2c595
FB
135 of = 0;
136 return cf | pf | af | zf | sf | of;
137}
138
8601c0b6 139static int glue(compute_all_inc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
07d2c595
FB
140{
141 int cf, pf, af, zf, sf, of;
8601c0b6 142 DATA_TYPE src2;
a04759f6 143
8601c0b6
RH
144 cf = src1;
145 src1 = dst - 1;
07d2c595 146 src2 = 1;
8601c0b6
RH
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;
07d2c595
FB
152 return cf | pf | af | zf | sf | of;
153}
154
8601c0b6 155static int glue(compute_all_dec, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
07d2c595
FB
156{
157 int cf, pf, af, zf, sf, of;
8601c0b6 158 DATA_TYPE src2;
a04759f6 159
8601c0b6
RH
160 cf = src1;
161 src1 = dst + 1;
07d2c595 162 src2 = 1;
8601c0b6
RH
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;
07d2c595
FB
168 return cf | pf | af | zf | sf | of;
169}
170
8601c0b6 171static int glue(compute_all_shl, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
07d2c595
FB
172{
173 int cf, pf, af, zf, sf, of;
a04759f6 174
8601c0b6
RH
175 cf = (src1 >> (DATA_BITS - 1)) & CC_C;
176 pf = parity_table[(uint8_t)dst];
07d2c595 177 af = 0; /* undefined */
8601c0b6
RH
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;
07d2c595
FB
182 return cf | pf | af | zf | sf | of;
183}
184
8601c0b6 185static int glue(compute_c_shl, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
07d2c595 186{
8601c0b6 187 return (src1 >> (DATA_BITS - 1)) & CC_C;
07d2c595
FB
188}
189
8601c0b6 190static int glue(compute_all_sar, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
07d2c595
FB
191{
192 int cf, pf, af, zf, sf, of;
a04759f6 193
8601c0b6
RH
194 cf = src1 & 1;
195 pf = parity_table[(uint8_t)dst];
07d2c595 196 af = 0; /* undefined */
8601c0b6
RH
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;
07d2c595
FB
201 return cf | pf | af | zf | sf | of;
202}
203
07d2c595 204/* NOTE: we compute the flags like the P4. On olders CPUs, only OF and
8601c0b6
RH
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. */
207static int glue(compute_all_mul, SUFFIX)(DATA_TYPE dst, target_long src1)
07d2c595
FB
208{
209 int cf, pf, af, zf, sf, of;
a04759f6 210
8601c0b6
RH
211 cf = (src1 != 0);
212 pf = parity_table[(uint8_t)dst];
07d2c595 213 af = 0; /* undefined */
8601c0b6
RH
214 zf = (dst == 0) * CC_Z;
215 sf = lshift(dst, 8 - DATA_BITS) & CC_S;
216 of = cf * CC_O;
07d2c595
FB
217 return cf | pf | af | zf | sf | of;
218}
219
bc4b43dc
RH
220static 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
233static int glue(compute_c_bmilg, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
234{
235 return src1 == 0;
236}
237
b6abf97d 238#undef DATA_BITS
b6abf97d
FB
239#undef SIGN_MASK
240#undef DATA_TYPE
b6abf97d
FB
241#undef DATA_MASK
242#undef SUFFIX