]> git.proxmox.com Git - qemu.git/blob - ops_template_mem.h
sparc support - hack to fix case where real_host_page_size < TARGET_PAGE_SIZE (typica...
[qemu.git] / 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 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
37 void 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
59 void 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
81 void 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
95 void 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
109 void 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
139 void 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
169 void 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
186 void 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
204 void 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 */
224 void 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
243 void 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
266 void 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
286 void 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
311 void 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
326 void 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
345 void 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
361 void 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
383 void 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
396 void 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
409 void 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