2 * x86 condition code helpers
4 * Copyright (c) 2008 Fabrice Bellard
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.
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.
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/>.
20 #define DATA_BITS (1 << (3 + SHIFT))
24 #define DATA_TYPE uint8_t
27 #define DATA_TYPE uint16_t
30 #define DATA_TYPE uint32_t
33 #define DATA_TYPE uint64_t
35 #error unhandled operand size
38 #define SIGN_MASK (((DATA_TYPE)1) << (DATA_BITS - 1))
40 /* dynamic flags computation */
42 static int glue(compute_all_add
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src1
)
44 int cf
, pf
, af
, zf
, sf
, of
;
45 DATA_TYPE src2
= 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
;
56 static int glue(compute_c_add
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src1
)
61 static int glue(compute_all_adc
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src1
,
64 int cf
, pf
, af
, zf
, sf
, of
;
65 DATA_TYPE src2
= dst
- src1
- src3
;
67 cf
= (src3
? dst
<= src1
: dst
< src1
);
68 pf
= parity_table
[(uint8_t)dst
];
69 af
= (dst
^ src1
^ src2
) & 0x10;
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
;
76 static int glue(compute_c_adc
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src1
,
79 return src3
? dst
<= src1
: dst
< src1
;
82 static int glue(compute_all_sub
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src2
)
84 int cf
, pf
, af
, zf
, sf
, of
;
85 DATA_TYPE src1
= dst
+ 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
;
96 static int glue(compute_c_sub
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src2
)
98 DATA_TYPE src1
= dst
+ src2
;
103 static int glue(compute_all_sbb
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src2
,
106 int cf
, pf
, af
, zf
, sf
, of
;
107 DATA_TYPE src1
= dst
+ src2
+ src3
;
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
;
118 static int glue(compute_c_sbb
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src2
,
121 DATA_TYPE src1
= dst
+ src2
+ src3
;
123 return (src3
? src1
<= src2
: src1
< src2
);
126 static int glue(compute_all_logic
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src1
)
128 int cf
, pf
, af
, zf
, sf
, of
;
131 pf
= parity_table
[(uint8_t)dst
];
133 zf
= (dst
== 0) * CC_Z
;
134 sf
= lshift(dst
, 8 - DATA_BITS
) & CC_S
;
136 return cf
| pf
| af
| zf
| sf
| of
;
139 static int glue(compute_all_inc
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src1
)
141 int cf
, pf
, af
, zf
, sf
, of
;
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
;
155 static int glue(compute_all_dec
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src1
)
157 int cf
, pf
, af
, zf
, sf
, of
;
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
;
171 static int glue(compute_all_shl
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src1
)
173 int cf
, pf
, af
, zf
, sf
, of
;
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
;
185 static int glue(compute_c_shl
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src1
)
187 return (src1
>> (DATA_BITS
- 1)) & CC_C
;
190 static int glue(compute_all_sar
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src1
)
192 int cf
, pf
, af
, zf
, sf
, of
;
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
;
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
)
209 int cf
, pf
, af
, zf
, sf
, of
;
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
;
217 return cf
| pf
| af
| zf
| sf
| of
;
220 static int glue(compute_all_bmilg
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src1
)
222 int cf
, pf
, af
, zf
, sf
, of
;
225 pf
= 0; /* undefined */
226 af
= 0; /* undefined */
227 zf
= (dst
== 0) * CC_Z
;
228 sf
= lshift(dst
, 8 - DATA_BITS
) & CC_S
;
230 return cf
| pf
| af
| zf
| sf
| of
;
233 static int glue(compute_c_bmilg
, SUFFIX
)(DATA_TYPE dst
, DATA_TYPE src1
)