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