]> git.proxmox.com Git - qemu.git/blame - target-i386/ops_template_mem.h
ppc bios
[qemu.git] / target-i386 / ops_template_mem.h
CommitLineData
2c0262af
FB
1/*
2 * i386 micro operations (included several times to generate
3 * different operand sizes)
4 *
5 * Copyright (c) 2003 Fabrice Bellard
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#ifdef MEM_WRITE
22
943144d9
FB
23#if MEM_WRITE == 0
24
25#if DATA_BITS == 8
26#define MEM_SUFFIX b_raw
27#elif DATA_BITS == 16
28#define MEM_SUFFIX w_raw
29#elif DATA_BITS == 32
30#define MEM_SUFFIX l_raw
31#endif
32
33#elif MEM_WRITE == 1
34
35#if DATA_BITS == 8
36#define MEM_SUFFIX b_kernel
37#elif DATA_BITS == 16
38#define MEM_SUFFIX w_kernel
39#elif DATA_BITS == 32
40#define MEM_SUFFIX l_kernel
41#endif
42
43#elif MEM_WRITE == 2
44
2c0262af 45#if DATA_BITS == 8
943144d9 46#define MEM_SUFFIX b_user
2c0262af 47#elif DATA_BITS == 16
943144d9 48#define MEM_SUFFIX w_user
2c0262af 49#elif DATA_BITS == 32
943144d9
FB
50#define MEM_SUFFIX l_user
51#endif
52
53#else
54
55#error invalid MEM_WRITE
56
2c0262af
FB
57#endif
58
59#else
60
61#define MEM_SUFFIX SUFFIX
62
63#endif
64
65void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void)
66{
67 int count, src;
68 count = T1 & SHIFT_MASK;
69 if (count) {
70 src = T0;
71 T0 &= DATA_MASK;
72 T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
73#ifdef MEM_WRITE
943144d9 74 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
75#else
76 /* gcc 3.2 workaround. This is really a bug in gcc. */
77 asm volatile("" : : "r" (T0));
78#endif
79 CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
80 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
81 (T0 & CC_C);
82 CC_OP = CC_OP_EFLAGS;
83 }
84 FORCE_RET();
85}
86
87void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1_cc)(void)
88{
89 int count, src;
90 count = T1 & SHIFT_MASK;
91 if (count) {
92 src = T0;
93 T0 &= DATA_MASK;
94 T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
95#ifdef MEM_WRITE
943144d9 96 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
97#else
98 /* gcc 3.2 workaround. This is really a bug in gcc. */
99 asm volatile("" : : "r" (T0));
100#endif
101 CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
102 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
103 ((T0 >> (DATA_BITS - 1)) & CC_C);
104 CC_OP = CC_OP_EFLAGS;
105 }
106 FORCE_RET();
107}
108
109void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1)(void)
110{
111 int count;
112 count = T1 & SHIFT_MASK;
113 if (count) {
114 T0 &= DATA_MASK;
115 T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
116#ifdef MEM_WRITE
943144d9 117 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
118#endif
119 }
120 FORCE_RET();
121}
122
123void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1)(void)
124{
125 int count;
126 count = T1 & SHIFT_MASK;
127 if (count) {
128 T0 &= DATA_MASK;
129 T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
130#ifdef MEM_WRITE
943144d9 131 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
132#endif
133 }
134 FORCE_RET();
135}
136
137void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
138{
139 int count, res, eflags;
140 unsigned int src;
141
142 count = T1 & 0x1f;
143#if DATA_BITS == 16
144 count = rclw_table[count];
145#elif DATA_BITS == 8
146 count = rclb_table[count];
147#endif
148 if (count) {
149 eflags = cc_table[CC_OP].compute_all();
150 T0 &= DATA_MASK;
151 src = T0;
152 res = (T0 << count) | ((eflags & CC_C) << (count - 1));
153 if (count > 1)
154 res |= T0 >> (DATA_BITS + 1 - count);
155 T0 = res;
156#ifdef MEM_WRITE
943144d9 157 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
158#endif
159 CC_SRC = (eflags & ~(CC_C | CC_O)) |
160 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
161 ((src >> (DATA_BITS - count)) & CC_C);
162 CC_OP = CC_OP_EFLAGS;
163 }
164 FORCE_RET();
165}
166
167void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
168{
169 int count, res, eflags;
170 unsigned int src;
171
172 count = T1 & 0x1f;
173#if DATA_BITS == 16
174 count = rclw_table[count];
175#elif DATA_BITS == 8
176 count = rclb_table[count];
177#endif
178 if (count) {
179 eflags = cc_table[CC_OP].compute_all();
180 T0 &= DATA_MASK;
181 src = T0;
182 res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
183 if (count > 1)
184 res |= T0 << (DATA_BITS + 1 - count);
185 T0 = res;
186#ifdef MEM_WRITE
943144d9 187 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
188#endif
189 CC_SRC = (eflags & ~(CC_C | CC_O)) |
190 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
191 ((src >> (count - 1)) & CC_C);
192 CC_OP = CC_OP_EFLAGS;
193 }
194 FORCE_RET();
195}
196
197void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void)
198{
199 int count, src;
200 count = T1 & 0x1f;
201 if (count) {
202 src = (DATA_TYPE)T0 << (count - 1);
203 T0 = T0 << count;
204#ifdef MEM_WRITE
943144d9 205 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
206#endif
207 CC_SRC = src;
208 CC_DST = T0;
209 CC_OP = CC_OP_SHLB + SHIFT;
210 }
211 FORCE_RET();
212}
213
214void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void)
215{
216 int count, src;
217 count = T1 & 0x1f;
218 if (count) {
219 T0 &= DATA_MASK;
220 src = T0 >> (count - 1);
221 T0 = T0 >> count;
222#ifdef MEM_WRITE
943144d9 223 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
224#endif
225 CC_SRC = src;
226 CC_DST = T0;
227 CC_OP = CC_OP_SARB + SHIFT;
228 }
229 FORCE_RET();
230}
231
232void OPPROTO glue(glue(op_sar, MEM_SUFFIX), _T0_T1_cc)(void)
233{
234 int count, src;
235 count = T1 & 0x1f;
236 if (count) {
237 src = (DATA_STYPE)T0;
238 T0 = src >> count;
239 src = src >> (count - 1);
240#ifdef MEM_WRITE
943144d9 241 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
242#endif
243 CC_SRC = src;
244 CC_DST = T0;
245 CC_OP = CC_OP_SARB + SHIFT;
246 }
247 FORCE_RET();
248}
249
250#if DATA_BITS == 16
251/* XXX: overflow flag might be incorrect in some cases in shldw */
252void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
253{
254 int count;
255 unsigned int res, tmp;
256 count = PARAM1;
257 T1 &= 0xffff;
258 res = T1 | (T0 << 16);
259 tmp = res >> (32 - count);
260 res <<= count;
261 if (count > 16)
262 res |= T1 << (count - 16);
263 T0 = res >> 16;
264#ifdef MEM_WRITE
943144d9 265 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
266#endif
267 CC_SRC = tmp;
268 CC_DST = T0;
269}
270
271void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
272{
273 int count;
274 unsigned int res, tmp;
275 count = ECX & 0x1f;
276 if (count) {
277 T1 &= 0xffff;
278 res = T1 | (T0 << 16);
279 tmp = res >> (32 - count);
280 res <<= count;
281 if (count > 16)
282 res |= T1 << (count - 16);
283 T0 = res >> 16;
284#ifdef MEM_WRITE
943144d9 285 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
286#endif
287 CC_SRC = tmp;
288 CC_DST = T0;
289 CC_OP = CC_OP_SARB + SHIFT;
290 }
291 FORCE_RET();
292}
293
294void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
295{
296 int count;
297 unsigned int res, tmp;
298
299 count = PARAM1;
300 res = (T0 & 0xffff) | (T1 << 16);
301 tmp = res >> (count - 1);
302 res >>= count;
303 if (count > 16)
304 res |= T1 << (32 - count);
305 T0 = res;
306#ifdef MEM_WRITE
943144d9 307 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
308#endif
309 CC_SRC = tmp;
310 CC_DST = T0;
311}
312
313
314void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
315{
316 int count;
317 unsigned int res, tmp;
318
319 count = ECX & 0x1f;
320 if (count) {
321 res = (T0 & 0xffff) | (T1 << 16);
322 tmp = res >> (count - 1);
323 res >>= count;
324 if (count > 16)
325 res |= T1 << (32 - count);
326 T0 = res;
327#ifdef MEM_WRITE
943144d9 328 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
329#endif
330 CC_SRC = tmp;
331 CC_DST = T0;
332 CC_OP = CC_OP_SARB + SHIFT;
333 }
334 FORCE_RET();
335}
336#endif
337
338#if DATA_BITS == 32
339void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
340{
341 int count, tmp;
342 count = PARAM1;
343 T0 &= DATA_MASK;
344 T1 &= DATA_MASK;
345 tmp = T0 << (count - 1);
346 T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
347#ifdef MEM_WRITE
943144d9 348 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
349#endif
350 CC_SRC = tmp;
351 CC_DST = T0;
352}
353
354void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
355{
356 int count, tmp;
357 count = ECX & 0x1f;
358 if (count) {
359 T0 &= DATA_MASK;
360 T1 &= DATA_MASK;
361 tmp = T0 << (count - 1);
362 T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
363#ifdef MEM_WRITE
943144d9 364 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
365#endif
366 CC_SRC = tmp;
367 CC_DST = T0;
368 CC_OP = CC_OP_SHLB + SHIFT;
369 }
370 FORCE_RET();
371}
372
373void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
374{
375 int count, tmp;
376 count = PARAM1;
377 T0 &= DATA_MASK;
378 T1 &= DATA_MASK;
379 tmp = T0 >> (count - 1);
380 T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
381#ifdef MEM_WRITE
943144d9 382 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
383#endif
384 CC_SRC = tmp;
385 CC_DST = T0;
386}
387
388
389void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
390{
391 int count, tmp;
392 count = ECX & 0x1f;
393 if (count) {
394 T0 &= DATA_MASK;
395 T1 &= DATA_MASK;
396 tmp = T0 >> (count - 1);
397 T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
398#ifdef MEM_WRITE
943144d9 399 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
400#endif
401 CC_SRC = tmp;
402 CC_DST = T0;
403 CC_OP = CC_OP_SARB + SHIFT;
404 }
405 FORCE_RET();
406}
407#endif
408
409/* carry add/sub (we only need to set CC_OP differently) */
410
411void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void)
412{
413 int cf;
414 cf = cc_table[CC_OP].compute_c();
415 T0 = T0 + T1 + cf;
416#ifdef MEM_WRITE
943144d9 417 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
418#endif
419 CC_SRC = T1;
420 CC_DST = T0;
421 CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
422}
423
424void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void)
425{
426 int cf;
427 cf = cc_table[CC_OP].compute_c();
428 T0 = T0 - T1 - cf;
429#ifdef MEM_WRITE
943144d9 430 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
2c0262af
FB
431#endif
432 CC_SRC = T1;
433 CC_DST = T0;
434 CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
435}
436
437void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void)
438{
439 unsigned int src, dst;
440
441 src = T0;
442 dst = EAX - T0;
443 if ((DATA_TYPE)dst == 0) {
444 T0 = T1;
1e4fe7ce
FB
445#ifdef MEM_WRITE
446 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
447#endif
2c0262af
FB
448 } else {
449 EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
450 }
2c0262af
FB
451 CC_SRC = src;
452 CC_DST = dst;
453 FORCE_RET();
454}
455
456#undef MEM_SUFFIX
457#undef MEM_WRITE