]> git.proxmox.com Git - qemu.git/blob - target-i386/ops_template_mem.h
ppc bios
[qemu.git] / target-i386 / ops_template_mem.h
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 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
45 #if DATA_BITS == 8
46 #define MEM_SUFFIX b_user
47 #elif DATA_BITS == 16
48 #define MEM_SUFFIX w_user
49 #elif DATA_BITS == 32
50 #define MEM_SUFFIX l_user
51 #endif
52
53 #else
54
55 #error invalid MEM_WRITE
56
57 #endif
58
59 #else
60
61 #define MEM_SUFFIX SUFFIX
62
63 #endif
64
65 void 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
74 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
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
87 void 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
96 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
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
109 void 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
117 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
118 #endif
119 }
120 FORCE_RET();
121 }
122
123 void 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
131 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
132 #endif
133 }
134 FORCE_RET();
135 }
136
137 void 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
157 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
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
167 void 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
187 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
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
197 void 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
205 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
206 #endif
207 CC_SRC = src;
208 CC_DST = T0;
209 CC_OP = CC_OP_SHLB + SHIFT;
210 }
211 FORCE_RET();
212 }
213
214 void 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
223 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
224 #endif
225 CC_SRC = src;
226 CC_DST = T0;
227 CC_OP = CC_OP_SARB + SHIFT;
228 }
229 FORCE_RET();
230 }
231
232 void 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
241 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
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 */
252 void 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
265 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
266 #endif
267 CC_SRC = tmp;
268 CC_DST = T0;
269 }
270
271 void 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
285 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
286 #endif
287 CC_SRC = tmp;
288 CC_DST = T0;
289 CC_OP = CC_OP_SARB + SHIFT;
290 }
291 FORCE_RET();
292 }
293
294 void 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
307 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
308 #endif
309 CC_SRC = tmp;
310 CC_DST = T0;
311 }
312
313
314 void 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
328 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
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
339 void 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
348 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
349 #endif
350 CC_SRC = tmp;
351 CC_DST = T0;
352 }
353
354 void 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
364 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
365 #endif
366 CC_SRC = tmp;
367 CC_DST = T0;
368 CC_OP = CC_OP_SHLB + SHIFT;
369 }
370 FORCE_RET();
371 }
372
373 void 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
382 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
383 #endif
384 CC_SRC = tmp;
385 CC_DST = T0;
386 }
387
388
389 void 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
399 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
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
411 void 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
417 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
418 #endif
419 CC_SRC = T1;
420 CC_DST = T0;
421 CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
422 }
423
424 void 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
430 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
431 #endif
432 CC_SRC = T1;
433 CC_DST = T0;
434 CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
435 }
436
437 void 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;
445 #ifdef MEM_WRITE
446 glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
447 #endif
448 } else {
449 EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
450 }
451 CC_SRC = src;
452 CC_DST = dst;
453 FORCE_RET();
454 }
455
456 #undef MEM_SUFFIX
457 #undef MEM_WRITE