]>
git.proxmox.com Git - qemu.git/blob - target-i386/ops_template_mem.h
2 * i386 micro operations (included several times to generate
3 * different operand sizes)
5 * Copyright (c) 2003 Fabrice Bellard
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.
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.
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
26 #define MEM_SUFFIX b_raw
28 #define MEM_SUFFIX w_raw
30 #define MEM_SUFFIX l_raw
36 #define MEM_SUFFIX b_kernel
38 #define MEM_SUFFIX w_kernel
40 #define MEM_SUFFIX l_kernel
46 #define MEM_SUFFIX b_user
48 #define MEM_SUFFIX w_user
50 #define MEM_SUFFIX l_user
55 #error invalid MEM_WRITE
61 #define MEM_SUFFIX SUFFIX
65 void OPPROTO
glue(glue(op_rol
, MEM_SUFFIX
), _T0_T1_cc
)(void)
68 count
= T1
& SHIFT_MASK
;
72 T0
= (T0
<< count
) | (T0
>> (DATA_BITS
- count
));
74 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
76 /* gcc 3.2 workaround. This is really a bug in gcc. */
77 asm volatile("" : : "r" (T0
));
79 CC_SRC
= (cc_table
[CC_OP
].compute_all() & ~(CC_O
| CC_C
)) |
80 (lshift(src
^ T0
, 11 - (DATA_BITS
- 1)) & CC_O
) |
87 void OPPROTO
glue(glue(op_ror
, MEM_SUFFIX
), _T0_T1_cc
)(void)
90 count
= T1
& SHIFT_MASK
;
94 T0
= (T0
>> count
) | (T0
<< (DATA_BITS
- count
));
96 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
98 /* gcc 3.2 workaround. This is really a bug in gcc. */
99 asm volatile("" : : "r" (T0
));
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
;
109 void OPPROTO
glue(glue(op_rol
, MEM_SUFFIX
), _T0_T1
)(void)
112 count
= T1
& SHIFT_MASK
;
115 T0
= (T0
<< count
) | (T0
>> (DATA_BITS
- count
));
117 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
123 void OPPROTO
glue(glue(op_ror
, MEM_SUFFIX
), _T0_T1
)(void)
126 count
= T1
& SHIFT_MASK
;
129 T0
= (T0
>> count
) | (T0
<< (DATA_BITS
- count
));
131 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
137 void OPPROTO
glue(glue(op_rcl
, MEM_SUFFIX
), _T0_T1_cc
)(void)
139 int count
, res
, eflags
;
144 count
= rclw_table
[count
];
146 count
= rclb_table
[count
];
149 eflags
= cc_table
[CC_OP
].compute_all();
152 res
= (T0
<< count
) | ((eflags
& CC_C
) << (count
- 1));
154 res
|= T0
>> (DATA_BITS
+ 1 - count
);
157 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
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
;
167 void OPPROTO
glue(glue(op_rcr
, MEM_SUFFIX
), _T0_T1_cc
)(void)
169 int count
, res
, eflags
;
174 count
= rclw_table
[count
];
176 count
= rclb_table
[count
];
179 eflags
= cc_table
[CC_OP
].compute_all();
182 res
= (T0
>> count
) | ((eflags
& CC_C
) << (DATA_BITS
- count
));
184 res
|= T0
<< (DATA_BITS
+ 1 - count
);
187 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
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
;
197 void OPPROTO
glue(glue(op_shl
, MEM_SUFFIX
), _T0_T1_cc
)(void)
202 src
= (DATA_TYPE
)T0
<< (count
- 1);
205 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
209 CC_OP
= CC_OP_SHLB
+ SHIFT
;
214 void OPPROTO
glue(glue(op_shr
, MEM_SUFFIX
), _T0_T1_cc
)(void)
220 src
= T0
>> (count
- 1);
223 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
227 CC_OP
= CC_OP_SARB
+ SHIFT
;
232 void OPPROTO
glue(glue(op_sar
, MEM_SUFFIX
), _T0_T1_cc
)(void)
237 src
= (DATA_STYPE
)T0
;
239 src
= src
>> (count
- 1);
241 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
245 CC_OP
= CC_OP_SARB
+ SHIFT
;
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)
255 unsigned int res
, tmp
;
258 res
= T1
| (T0
<< 16);
259 tmp
= res
>> (32 - count
);
262 res
|= T1
<< (count
- 16);
265 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
271 void OPPROTO
glue(glue(op_shld
, MEM_SUFFIX
), _T0_T1_ECX_cc
)(void)
274 unsigned int res
, tmp
;
278 res
= T1
| (T0
<< 16);
279 tmp
= res
>> (32 - count
);
282 res
|= T1
<< (count
- 16);
285 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
289 CC_OP
= CC_OP_SARB
+ SHIFT
;
294 void OPPROTO
glue(glue(op_shrd
, MEM_SUFFIX
), _T0_T1_im_cc
)(void)
297 unsigned int res
, tmp
;
300 res
= (T0
& 0xffff) | (T1
<< 16);
301 tmp
= res
>> (count
- 1);
304 res
|= T1
<< (32 - count
);
307 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
314 void OPPROTO
glue(glue(op_shrd
, MEM_SUFFIX
), _T0_T1_ECX_cc
)(void)
317 unsigned int res
, tmp
;
321 res
= (T0
& 0xffff) | (T1
<< 16);
322 tmp
= res
>> (count
- 1);
325 res
|= T1
<< (32 - count
);
328 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
332 CC_OP
= CC_OP_SARB
+ SHIFT
;
339 void OPPROTO
glue(glue(op_shld
, MEM_SUFFIX
), _T0_T1_im_cc
)(void)
345 tmp
= T0
<< (count
- 1);
346 T0
= (T0
<< count
) | (T1
>> (DATA_BITS
- count
));
348 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
354 void OPPROTO
glue(glue(op_shld
, MEM_SUFFIX
), _T0_T1_ECX_cc
)(void)
361 tmp
= T0
<< (count
- 1);
362 T0
= (T0
<< count
) | (T1
>> (DATA_BITS
- count
));
364 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
368 CC_OP
= CC_OP_SHLB
+ SHIFT
;
373 void OPPROTO
glue(glue(op_shrd
, MEM_SUFFIX
), _T0_T1_im_cc
)(void)
379 tmp
= T0
>> (count
- 1);
380 T0
= (T0
>> count
) | (T1
<< (DATA_BITS
- count
));
382 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
389 void OPPROTO
glue(glue(op_shrd
, MEM_SUFFIX
), _T0_T1_ECX_cc
)(void)
396 tmp
= T0
>> (count
- 1);
397 T0
= (T0
>> count
) | (T1
<< (DATA_BITS
- count
));
399 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
403 CC_OP
= CC_OP_SARB
+ SHIFT
;
409 /* carry add/sub (we only need to set CC_OP differently) */
411 void OPPROTO
glue(glue(op_adc
, MEM_SUFFIX
), _T0_T1_cc
)(void)
414 cf
= cc_table
[CC_OP
].compute_c();
417 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
421 CC_OP
= CC_OP_ADDB
+ SHIFT
+ cf
* 3;
424 void OPPROTO
glue(glue(op_sbb
, MEM_SUFFIX
), _T0_T1_cc
)(void)
427 cf
= cc_table
[CC_OP
].compute_c();
430 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
434 CC_OP
= CC_OP_SUBB
+ SHIFT
+ cf
* 3;
437 void OPPROTO
glue(glue(op_cmpxchg
, MEM_SUFFIX
), _T0_T1_EAX_cc
)(void)
439 unsigned int src
, dst
;
443 if ((DATA_TYPE
)dst
== 0) {
446 glue(st
, MEM_SUFFIX
)((uint8_t *)A0
, T0
);
449 EAX
= (EAX
& ~DATA_MASK
) | (T0
& DATA_MASK
);