Make string arrays used to convert numbers to strings when DEBUG_EEPRO100 is enabled...
[qemu] / target-i386 / helper_template.h
1 /*
2  *  i386 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 #define DATA_BITS (1 << (3 + SHIFT))
20 #define SHIFT_MASK (DATA_BITS - 1)
21 #define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1))
22 #if DATA_BITS <= 32
23 #define SHIFT1_MASK 0x1f
24 #else
25 #define SHIFT1_MASK 0x3f
26 #endif
27
28 #if DATA_BITS == 8
29 #define SUFFIX b
30 #define DATA_TYPE uint8_t
31 #define DATA_STYPE int8_t
32 #define DATA_MASK 0xff
33 #elif DATA_BITS == 16
34 #define SUFFIX w
35 #define DATA_TYPE uint16_t
36 #define DATA_STYPE int16_t
37 #define DATA_MASK 0xffff
38 #elif DATA_BITS == 32
39 #define SUFFIX l
40 #define DATA_TYPE uint32_t
41 #define DATA_STYPE int32_t
42 #define DATA_MASK 0xffffffff
43 #elif DATA_BITS == 64
44 #define SUFFIX q
45 #define DATA_TYPE uint64_t
46 #define DATA_STYPE int64_t
47 #define DATA_MASK 0xffffffffffffffffULL
48 #else
49 #error unhandled operand size
50 #endif
51
52 /* dynamic flags computation */
53
54 static int glue(compute_all_add, SUFFIX)(void)
55 {
56     int cf, pf, af, zf, sf, of;
57     target_long src1, src2;
58     src1 = CC_SRC;
59     src2 = CC_DST - CC_SRC;
60     cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
61     pf = parity_table[(uint8_t)CC_DST];
62     af = (CC_DST ^ src1 ^ src2) & 0x10;
63     zf = ((DATA_TYPE)CC_DST == 0) << 6;
64     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
65     of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
66     return cf | pf | af | zf | sf | of;
67 }
68
69 static int glue(compute_c_add, SUFFIX)(void)
70 {
71     int cf;
72     target_long src1;
73     src1 = CC_SRC;
74     cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
75     return cf;
76 }
77
78 static int glue(compute_all_adc, SUFFIX)(void)
79 {
80     int cf, pf, af, zf, sf, of;
81     target_long src1, src2;
82     src1 = CC_SRC;
83     src2 = CC_DST - CC_SRC - 1;
84     cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
85     pf = parity_table[(uint8_t)CC_DST];
86     af = (CC_DST ^ src1 ^ src2) & 0x10;
87     zf = ((DATA_TYPE)CC_DST == 0) << 6;
88     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
89     of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
90     return cf | pf | af | zf | sf | of;
91 }
92
93 static int glue(compute_c_adc, SUFFIX)(void)
94 {
95     int cf;
96     target_long src1;
97     src1 = CC_SRC;
98     cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
99     return cf;
100 }
101
102 static int glue(compute_all_sub, SUFFIX)(void)
103 {
104     int cf, pf, af, zf, sf, of;
105     target_long src1, src2;
106     src1 = CC_DST + CC_SRC;
107     src2 = CC_SRC;
108     cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
109     pf = parity_table[(uint8_t)CC_DST];
110     af = (CC_DST ^ src1 ^ src2) & 0x10;
111     zf = ((DATA_TYPE)CC_DST == 0) << 6;
112     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
113     of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
114     return cf | pf | af | zf | sf | of;
115 }
116
117 static int glue(compute_c_sub, SUFFIX)(void)
118 {
119     int cf;
120     target_long src1, src2;
121     src1 = CC_DST + CC_SRC;
122     src2 = CC_SRC;
123     cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
124     return cf;
125 }
126
127 static int glue(compute_all_sbb, SUFFIX)(void)
128 {
129     int cf, pf, af, zf, sf, of;
130     target_long src1, src2;
131     src1 = CC_DST + CC_SRC + 1;
132     src2 = CC_SRC;
133     cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
134     pf = parity_table[(uint8_t)CC_DST];
135     af = (CC_DST ^ src1 ^ src2) & 0x10;
136     zf = ((DATA_TYPE)CC_DST == 0) << 6;
137     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
138     of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
139     return cf | pf | af | zf | sf | of;
140 }
141
142 static int glue(compute_c_sbb, SUFFIX)(void)
143 {
144     int cf;
145     target_long src1, src2;
146     src1 = CC_DST + CC_SRC + 1;
147     src2 = CC_SRC;
148     cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
149     return cf;
150 }
151
152 static int glue(compute_all_logic, SUFFIX)(void)
153 {
154     int cf, pf, af, zf, sf, of;
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)(void)
170 {
171     int cf, pf, af, zf, sf, of;
172     target_long src1, src2;
173     src1 = CC_DST - 1;
174     src2 = 1;
175     cf = CC_SRC;
176     pf = parity_table[(uint8_t)CC_DST];
177     af = (CC_DST ^ src1 ^ src2) & 0x10;
178     zf = ((DATA_TYPE)CC_DST == 0) << 6;
179     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
180     of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
181     return cf | pf | af | zf | sf | of;
182 }
183
184 #if DATA_BITS == 32
185 static int glue(compute_c_inc, SUFFIX)(void)
186 {
187     return CC_SRC;
188 }
189 #endif
190
191 static int glue(compute_all_dec, SUFFIX)(void)
192 {
193     int cf, pf, af, zf, sf, of;
194     target_long src1, src2;
195     src1 = CC_DST + 1;
196     src2 = 1;
197     cf = CC_SRC;
198     pf = parity_table[(uint8_t)CC_DST];
199     af = (CC_DST ^ src1 ^ src2) & 0x10;
200     zf = ((DATA_TYPE)CC_DST == 0) << 6;
201     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
202     of = ((CC_DST & DATA_MASK) == ((target_ulong)SIGN_MASK - 1)) << 11;
203     return cf | pf | af | zf | sf | of;
204 }
205
206 static int glue(compute_all_shl, SUFFIX)(void)
207 {
208     int cf, pf, af, zf, sf, of;
209     cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C;
210     pf = parity_table[(uint8_t)CC_DST];
211     af = 0; /* undefined */
212     zf = ((DATA_TYPE)CC_DST == 0) << 6;
213     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
214     /* of is defined if shift count == 1 */
215     of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
216     return cf | pf | af | zf | sf | of;
217 }
218
219 static int glue(compute_c_shl, SUFFIX)(void)
220 {
221     return (CC_SRC >> (DATA_BITS - 1)) & CC_C;
222 }
223
224 #if DATA_BITS == 32
225 static int glue(compute_c_sar, SUFFIX)(void)
226 {
227     return CC_SRC & 1;
228 }
229 #endif
230
231 static int glue(compute_all_sar, SUFFIX)(void)
232 {
233     int cf, pf, af, zf, sf, of;
234     cf = CC_SRC & 1;
235     pf = parity_table[(uint8_t)CC_DST];
236     af = 0; /* undefined */
237     zf = ((DATA_TYPE)CC_DST == 0) << 6;
238     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
239     /* of is defined if shift count == 1 */
240     of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
241     return cf | pf | af | zf | sf | of;
242 }
243
244 #if DATA_BITS == 32
245 static int glue(compute_c_mul, SUFFIX)(void)
246 {
247     int cf;
248     cf = (CC_SRC != 0);
249     return cf;
250 }
251 #endif
252
253 /* NOTE: we compute the flags like the P4. On olders CPUs, only OF and
254    CF are modified and it is slower to do that. */
255 static int glue(compute_all_mul, SUFFIX)(void)
256 {
257     int cf, pf, af, zf, sf, of;
258     cf = (CC_SRC != 0);
259     pf = parity_table[(uint8_t)CC_DST];
260     af = 0; /* undefined */
261     zf = ((DATA_TYPE)CC_DST == 0) << 6;
262     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
263     of = cf << 11;
264     return cf | pf | af | zf | sf | of;
265 }
266
267 /* shifts */
268
269 target_ulong glue(helper_rcl, SUFFIX)(target_ulong t0, target_ulong t1)
270 {
271     int count, eflags;
272     target_ulong src;
273     target_long res;
274
275     count = t1 & SHIFT1_MASK;
276 #if DATA_BITS == 16
277     count = rclw_table[count];
278 #elif DATA_BITS == 8
279     count = rclb_table[count];
280 #endif
281     if (count) {
282         eflags = helper_cc_compute_all(CC_OP);
283         t0 &= DATA_MASK;
284         src = t0;
285         res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
286         if (count > 1)
287             res |= t0 >> (DATA_BITS + 1 - count);
288         t0 = res;
289         env->cc_tmp = (eflags & ~(CC_C | CC_O)) |
290             (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
291             ((src >> (DATA_BITS - count)) & CC_C);
292     } else {
293         env->cc_tmp = -1;
294     }
295     return t0;
296 }
297
298 target_ulong glue(helper_rcr, SUFFIX)(target_ulong t0, target_ulong t1)
299 {
300     int count, eflags;
301     target_ulong src;
302     target_long res;
303
304     count = t1 & SHIFT1_MASK;
305 #if DATA_BITS == 16
306     count = rclw_table[count];
307 #elif DATA_BITS == 8
308     count = rclb_table[count];
309 #endif
310     if (count) {
311         eflags = helper_cc_compute_all(CC_OP);
312         t0 &= DATA_MASK;
313         src = t0;
314         res = (t0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count));
315         if (count > 1)
316             res |= t0 << (DATA_BITS + 1 - count);
317         t0 = res;
318         env->cc_tmp = (eflags & ~(CC_C | CC_O)) |
319             (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
320             ((src >> (count - 1)) & CC_C);
321     } else {
322         env->cc_tmp = -1;
323     }
324     return t0;
325 }
326
327 #undef DATA_BITS
328 #undef SHIFT_MASK
329 #undef SHIFT1_MASK
330 #undef SIGN_MASK
331 #undef DATA_TYPE
332 #undef DATA_STYPE
333 #undef DATA_MASK
334 #undef SUFFIX