]> git.proxmox.com Git - qemu.git/blame - target-i386/ops_template_mem.h
first multi target test (lauches 'ls')
[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
23#if DATA_BITS == 8
24#define MEM_SUFFIX b_mem
25#elif DATA_BITS == 16
26#define MEM_SUFFIX w_mem
27#elif DATA_BITS == 32
28#define MEM_SUFFIX l_mem
29#endif
30
31#else
32
33#define MEM_SUFFIX SUFFIX
34
35#endif
36
37void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void)
38{
39 int count, src;
40 count = T1 & SHIFT_MASK;
41 if (count) {
42 src = T0;
43 T0 &= DATA_MASK;
44 T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
45#ifdef MEM_WRITE
46 glue(st, SUFFIX)((uint8_t *)A0, T0);
47#else
48 /* gcc 3.2 workaround. This is really a bug in gcc. */
49 asm volatile("" : : "r" (T0));
50#endif
51 CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
52 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
53 (T0 & CC_C);
54 CC_OP = CC_OP_EFLAGS;
55 }
56 FORCE_RET();
57}
58
59void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1_cc)(void)
60{
61 int count, src;
62 count = T1 & SHIFT_MASK;
63 if (count) {
64 src = T0;
65 T0 &= DATA_MASK;
66 T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
67#ifdef MEM_WRITE
68 glue(st, SUFFIX)((uint8_t *)A0, T0);
69#else
70 /* gcc 3.2 workaround. This is really a bug in gcc. */
71 asm volatile("" : : "r" (T0));
72#endif
73 CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
74 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
75 ((T0 >> (DATA_BITS - 1)) & CC_C);
76 CC_OP = CC_OP_EFLAGS;
77 }
78 FORCE_RET();
79}
80
81void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1)(void)
82{
83 int count;
84 count = T1 & SHIFT_MASK;
85 if (count) {
86 T0 &= DATA_MASK;
87 T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
88#ifdef MEM_WRITE
89 glue(st, SUFFIX)((uint8_t *)A0, T0);
90#endif
91 }
92 FORCE_RET();
93}
94
95void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1)(void)
96{
97 int count;
98 count = T1 & SHIFT_MASK;
99 if (count) {
100 T0 &= DATA_MASK;
101 T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
102#ifdef MEM_WRITE
103 glue(st, SUFFIX)((uint8_t *)A0, T0);
104#endif
105 }
106 FORCE_RET();
107}
108
109void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
110{
111 int count, res, eflags;
112 unsigned int src;
113
114 count = T1 & 0x1f;
115#if DATA_BITS == 16
116 count = rclw_table[count];
117#elif DATA_BITS == 8
118 count = rclb_table[count];
119#endif
120 if (count) {
121 eflags = cc_table[CC_OP].compute_all();
122 T0 &= DATA_MASK;
123 src = T0;
124 res = (T0 << count) | ((eflags & CC_C) << (count - 1));
125 if (count > 1)
126 res |= T0 >> (DATA_BITS + 1 - count);
127 T0 = res;
128#ifdef MEM_WRITE
129 glue(st, SUFFIX)((uint8_t *)A0, T0);
130#endif
131 CC_SRC = (eflags & ~(CC_C | CC_O)) |
132 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
133 ((src >> (DATA_BITS - count)) & CC_C);
134 CC_OP = CC_OP_EFLAGS;
135 }
136 FORCE_RET();
137}
138
139void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
140{
141 int count, res, eflags;
142 unsigned int src;
143
144 count = T1 & 0x1f;
145#if DATA_BITS == 16
146 count = rclw_table[count];
147#elif DATA_BITS == 8
148 count = rclb_table[count];
149#endif
150 if (count) {
151 eflags = cc_table[CC_OP].compute_all();
152 T0 &= DATA_MASK;
153 src = T0;
154 res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
155 if (count > 1)
156 res |= T0 << (DATA_BITS + 1 - count);
157 T0 = res;
158#ifdef MEM_WRITE
159 glue(st, SUFFIX)((uint8_t *)A0, T0);
160#endif
161 CC_SRC = (eflags & ~(CC_C | CC_O)) |
162 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
163 ((src >> (count - 1)) & CC_C);
164 CC_OP = CC_OP_EFLAGS;
165 }
166 FORCE_RET();
167}
168
169void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void)
170{
171 int count, src;
172 count = T1 & 0x1f;
173 if (count) {
174 src = (DATA_TYPE)T0 << (count - 1);
175 T0 = T0 << count;
176#ifdef MEM_WRITE
177 glue(st, SUFFIX)((uint8_t *)A0, T0);
178#endif
179 CC_SRC = src;
180 CC_DST = T0;
181 CC_OP = CC_OP_SHLB + SHIFT;
182 }
183 FORCE_RET();
184}
185
186void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void)
187{
188 int count, src;
189 count = T1 & 0x1f;
190 if (count) {
191 T0 &= DATA_MASK;
192 src = T0 >> (count - 1);
193 T0 = T0 >> count;
194#ifdef MEM_WRITE
195 glue(st, SUFFIX)((uint8_t *)A0, T0);
196#endif
197 CC_SRC = src;
198 CC_DST = T0;
199 CC_OP = CC_OP_SARB + SHIFT;
200 }
201 FORCE_RET();
202}
203
204void OPPROTO glue(glue(op_sar, MEM_SUFFIX), _T0_T1_cc)(void)
205{
206 int count, src;
207 count = T1 & 0x1f;
208 if (count) {
209 src = (DATA_STYPE)T0;
210 T0 = src >> count;
211 src = src >> (count - 1);
212#ifdef MEM_WRITE
213 glue(st, SUFFIX)((uint8_t *)A0, T0);
214#endif
215 CC_SRC = src;
216 CC_DST = T0;
217 CC_OP = CC_OP_SARB + SHIFT;
218 }
219 FORCE_RET();
220}
221
222#if DATA_BITS == 16
223/* XXX: overflow flag might be incorrect in some cases in shldw */
224void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
225{
226 int count;
227 unsigned int res, tmp;
228 count = PARAM1;
229 T1 &= 0xffff;
230 res = T1 | (T0 << 16);
231 tmp = res >> (32 - count);
232 res <<= count;
233 if (count > 16)
234 res |= T1 << (count - 16);
235 T0 = res >> 16;
236#ifdef MEM_WRITE
237 glue(st, SUFFIX)((uint8_t *)A0, T0);
238#endif
239 CC_SRC = tmp;
240 CC_DST = T0;
241}
242
243void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
244{
245 int count;
246 unsigned int res, tmp;
247 count = ECX & 0x1f;
248 if (count) {
249 T1 &= 0xffff;
250 res = T1 | (T0 << 16);
251 tmp = res >> (32 - count);
252 res <<= count;
253 if (count > 16)
254 res |= T1 << (count - 16);
255 T0 = res >> 16;
256#ifdef MEM_WRITE
257 glue(st, SUFFIX)((uint8_t *)A0, T0);
258#endif
259 CC_SRC = tmp;
260 CC_DST = T0;
261 CC_OP = CC_OP_SARB + SHIFT;
262 }
263 FORCE_RET();
264}
265
266void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
267{
268 int count;
269 unsigned int res, tmp;
270
271 count = PARAM1;
272 res = (T0 & 0xffff) | (T1 << 16);
273 tmp = res >> (count - 1);
274 res >>= count;
275 if (count > 16)
276 res |= T1 << (32 - count);
277 T0 = res;
278#ifdef MEM_WRITE
279 glue(st, SUFFIX)((uint8_t *)A0, T0);
280#endif
281 CC_SRC = tmp;
282 CC_DST = T0;
283}
284
285
286void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
287{
288 int count;
289 unsigned int res, tmp;
290
291 count = ECX & 0x1f;
292 if (count) {
293 res = (T0 & 0xffff) | (T1 << 16);
294 tmp = res >> (count - 1);
295 res >>= count;
296 if (count > 16)
297 res |= T1 << (32 - count);
298 T0 = res;
299#ifdef MEM_WRITE
300 glue(st, SUFFIX)((uint8_t *)A0, T0);
301#endif
302 CC_SRC = tmp;
303 CC_DST = T0;
304 CC_OP = CC_OP_SARB + SHIFT;
305 }
306 FORCE_RET();
307}
308#endif
309
310#if DATA_BITS == 32
311void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
312{
313 int count, tmp;
314 count = PARAM1;
315 T0 &= DATA_MASK;
316 T1 &= DATA_MASK;
317 tmp = T0 << (count - 1);
318 T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
319#ifdef MEM_WRITE
320 glue(st, SUFFIX)((uint8_t *)A0, T0);
321#endif
322 CC_SRC = tmp;
323 CC_DST = T0;
324}
325
326void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
327{
328 int count, tmp;
329 count = ECX & 0x1f;
330 if (count) {
331 T0 &= DATA_MASK;
332 T1 &= DATA_MASK;
333 tmp = T0 << (count - 1);
334 T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
335#ifdef MEM_WRITE
336 glue(st, SUFFIX)((uint8_t *)A0, T0);
337#endif
338 CC_SRC = tmp;
339 CC_DST = T0;
340 CC_OP = CC_OP_SHLB + SHIFT;
341 }
342 FORCE_RET();
343}
344
345void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
346{
347 int count, tmp;
348 count = PARAM1;
349 T0 &= DATA_MASK;
350 T1 &= DATA_MASK;
351 tmp = T0 >> (count - 1);
352 T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
353#ifdef MEM_WRITE
354 glue(st, SUFFIX)((uint8_t *)A0, T0);
355#endif
356 CC_SRC = tmp;
357 CC_DST = T0;
358}
359
360
361void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
362{
363 int count, tmp;
364 count = ECX & 0x1f;
365 if (count) {
366 T0 &= DATA_MASK;
367 T1 &= DATA_MASK;
368 tmp = T0 >> (count - 1);
369 T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
370#ifdef MEM_WRITE
371 glue(st, SUFFIX)((uint8_t *)A0, T0);
372#endif
373 CC_SRC = tmp;
374 CC_DST = T0;
375 CC_OP = CC_OP_SARB + SHIFT;
376 }
377 FORCE_RET();
378}
379#endif
380
381/* carry add/sub (we only need to set CC_OP differently) */
382
383void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void)
384{
385 int cf;
386 cf = cc_table[CC_OP].compute_c();
387 T0 = T0 + T1 + cf;
388#ifdef MEM_WRITE
389 glue(st, SUFFIX)((uint8_t *)A0, T0);
390#endif
391 CC_SRC = T1;
392 CC_DST = T0;
393 CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
394}
395
396void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void)
397{
398 int cf;
399 cf = cc_table[CC_OP].compute_c();
400 T0 = T0 - T1 - cf;
401#ifdef MEM_WRITE
402 glue(st, SUFFIX)((uint8_t *)A0, T0);
403#endif
404 CC_SRC = T1;
405 CC_DST = T0;
406 CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
407}
408
409void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void)
410{
411 unsigned int src, dst;
412
413 src = T0;
414 dst = EAX - T0;
415 if ((DATA_TYPE)dst == 0) {
416 T0 = T1;
417 } else {
418 EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
419 }
420#ifdef MEM_WRITE
421 glue(st, SUFFIX)((uint8_t *)A0, T0);
422#endif
423 CC_SRC = src;
424 CC_DST = dst;
425 FORCE_RET();
426}
427
428#undef MEM_SUFFIX
429#undef MEM_WRITE