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
24 #define MEM_SUFFIX b_mem
26 #define MEM_SUFFIX w_mem
28 #define MEM_SUFFIX l_mem
33 #define MEM_SUFFIX SUFFIX
37 void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void)
40 count = T1 & SHIFT_MASK;
44 T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
46 glue(st, SUFFIX)((uint8_t *)A0, T0);
48 CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
49 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
56 void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1_cc)(void)
59 count = T1 & SHIFT_MASK;
63 T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
65 glue(st, SUFFIX)((uint8_t *)A0, T0);
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);
75 void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1)(void)
78 count = T1 & SHIFT_MASK;
81 T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
83 glue(st, SUFFIX)((uint8_t *)A0, T0);
89 void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1)(void)
92 count = T1 & SHIFT_MASK;
95 T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
97 glue(st, SUFFIX)((uint8_t *)A0, T0);
103 void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
105 int count, res, eflags;
110 count = rclw_table[count];
112 count = rclb_table[count];
115 eflags = cc_table[CC_OP].compute_all();
118 res = (T0 << count) | ((eflags & CC_C) << (count - 1));
120 res |= T0 >> (DATA_BITS + 1 - count);
123 glue(st, SUFFIX)((uint8_t *)A0, T0);
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;
133 void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
135 int count, res, eflags;
140 count = rclw_table[count];
142 count = rclb_table[count];
145 eflags = cc_table[CC_OP].compute_all();
148 res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
150 res |= T0 << (DATA_BITS + 1 - count);
153 glue(st, SUFFIX)((uint8_t *)A0, T0);
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;
163 void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void)
168 src = (DATA_TYPE)T0 << (count - 1);
171 glue(st, SUFFIX)((uint8_t *)A0, T0);
175 CC_OP = CC_OP_SHLB + SHIFT;
180 void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void)
186 src = T0 >> (count - 1);
189 glue(st, SUFFIX)((uint8_t *)A0, T0);
193 CC_OP = CC_OP_SARB + SHIFT;
198 void OPPROTO glue(glue(op_sar, MEM_SUFFIX), _T0_T1_cc)(void)
203 src = (DATA_STYPE)T0;
205 src = src >> (count - 1);
207 glue(st, SUFFIX)((uint8_t *)A0, T0);
211 CC_OP = CC_OP_SARB + SHIFT;
217 /* XXX: overflow flag might be incorrect in some cases in shldw */
218 void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
221 unsigned int res, tmp;
224 res = T1 | (T0 << 16);
225 tmp = res >> (32 - count);
228 res |= T1 << (count - 16);
231 glue(st, SUFFIX)((uint8_t *)A0, T0);
237 void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
240 unsigned int res, tmp;
244 res = T1 | (T0 << 16);
245 tmp = res >> (32 - count);
248 res |= T1 << (count - 16);
251 glue(st, SUFFIX)((uint8_t *)A0, T0);
255 CC_OP = CC_OP_SARB + SHIFT;
260 void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
263 unsigned int res, tmp;
266 res = (T0 & 0xffff) | (T1 << 16);
267 tmp = res >> (count - 1);
270 res |= T1 << (32 - count);
273 glue(st, SUFFIX)((uint8_t *)A0, T0);
280 void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
283 unsigned int res, tmp;
287 res = (T0 & 0xffff) | (T1 << 16);
288 tmp = res >> (count - 1);
291 res |= T1 << (32 - count);
294 glue(st, SUFFIX)((uint8_t *)A0, T0);
298 CC_OP = CC_OP_SARB + SHIFT;
305 void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
311 tmp = T0 << (count - 1);
312 T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
314 glue(st, SUFFIX)((uint8_t *)A0, T0);
320 void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
327 tmp = T0 << (count - 1);
328 T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
330 glue(st, SUFFIX)((uint8_t *)A0, T0);
334 CC_OP = CC_OP_SHLB + SHIFT;
339 void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
345 tmp = T0 >> (count - 1);
346 T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
348 glue(st, SUFFIX)((uint8_t *)A0, T0);
355 void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
362 tmp = T0 >> (count - 1);
363 T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
365 glue(st, SUFFIX)((uint8_t *)A0, T0);
369 CC_OP = CC_OP_SARB + SHIFT;
375 /* carry add/sub (we only need to set CC_OP differently) */
377 void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void)
380 cf = cc_table[CC_OP].compute_c();
383 glue(st, SUFFIX)((uint8_t *)A0, T0);
387 CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
390 void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void)
393 cf = cc_table[CC_OP].compute_c();
396 glue(st, SUFFIX)((uint8_t *)A0, T0);
400 CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
403 void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void)
405 unsigned int src, dst;
409 if ((DATA_TYPE)dst == 0) {
412 EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
415 glue(st, SUFFIX)((uint8_t *)A0, T0);