Statistics
| Branch: | Revision:

root / target-i386 / cc_helper_template.h @ 3523e4bd

History | View | Annotate | Download (6.6 kB)

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