root / ops_template_mem.h @ d05e66d2
History | View | Annotate | Download (10 kB)
1 | e477b8b8 | bellard | /*
|
---|---|---|---|
2 | e477b8b8 | bellard | * i386 micro operations (included several times to generate
|
3 | e477b8b8 | bellard | * different operand sizes)
|
4 | e477b8b8 | bellard | *
|
5 | e477b8b8 | bellard | * Copyright (c) 2003 Fabrice Bellard
|
6 | e477b8b8 | bellard | *
|
7 | e477b8b8 | bellard | * This library is free software; you can redistribute it and/or
|
8 | e477b8b8 | bellard | * modify it under the terms of the GNU Lesser General Public
|
9 | e477b8b8 | bellard | * License as published by the Free Software Foundation; either
|
10 | e477b8b8 | bellard | * version 2 of the License, or (at your option) any later version.
|
11 | e477b8b8 | bellard | *
|
12 | e477b8b8 | bellard | * This library is distributed in the hope that it will be useful,
|
13 | e477b8b8 | bellard | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 | e477b8b8 | bellard | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15 | e477b8b8 | bellard | * Lesser General Public License for more details.
|
16 | e477b8b8 | bellard | *
|
17 | e477b8b8 | bellard | * You should have received a copy of the GNU Lesser General Public
|
18 | e477b8b8 | bellard | * License along with this library; if not, write to the Free Software
|
19 | e477b8b8 | bellard | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20 | e477b8b8 | bellard | */
|
21 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
22 | e477b8b8 | bellard | |
23 | e477b8b8 | bellard | #if DATA_BITS == 8 |
24 | e477b8b8 | bellard | #define MEM_SUFFIX b_mem
|
25 | e477b8b8 | bellard | #elif DATA_BITS == 16 |
26 | e477b8b8 | bellard | #define MEM_SUFFIX w_mem
|
27 | e477b8b8 | bellard | #elif DATA_BITS == 32 |
28 | e477b8b8 | bellard | #define MEM_SUFFIX l_mem
|
29 | e477b8b8 | bellard | #endif
|
30 | e477b8b8 | bellard | |
31 | e477b8b8 | bellard | #else
|
32 | e477b8b8 | bellard | |
33 | e477b8b8 | bellard | #define MEM_SUFFIX SUFFIX
|
34 | e477b8b8 | bellard | |
35 | e477b8b8 | bellard | #endif
|
36 | e477b8b8 | bellard | |
37 | e477b8b8 | bellard | void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void) |
38 | e477b8b8 | bellard | { |
39 | e477b8b8 | bellard | int count, src;
|
40 | e477b8b8 | bellard | count = T1 & SHIFT_MASK; |
41 | e477b8b8 | bellard | if (count) {
|
42 | e477b8b8 | bellard | src = T0; |
43 | e477b8b8 | bellard | T0 &= DATA_MASK; |
44 | e477b8b8 | bellard | T0 = (T0 << count) | (T0 >> (DATA_BITS - count)); |
45 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
46 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
47 | 91cf4d88 | bellard | #else
|
48 | 91cf4d88 | bellard | /* gcc 3.2 workaround. This is really a bug in gcc. */
|
49 | 91cf4d88 | bellard | asm volatile("" : : "r" (T0)); |
50 | e477b8b8 | bellard | #endif
|
51 | e477b8b8 | bellard | CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) | |
52 | e477b8b8 | bellard | (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | |
53 | e477b8b8 | bellard | (T0 & CC_C); |
54 | e477b8b8 | bellard | CC_OP = CC_OP_EFLAGS; |
55 | e477b8b8 | bellard | } |
56 | e477b8b8 | bellard | FORCE_RET(); |
57 | e477b8b8 | bellard | } |
58 | e477b8b8 | bellard | |
59 | e477b8b8 | bellard | void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1_cc)(void) |
60 | e477b8b8 | bellard | { |
61 | e477b8b8 | bellard | int count, src;
|
62 | e477b8b8 | bellard | count = T1 & SHIFT_MASK; |
63 | e477b8b8 | bellard | if (count) {
|
64 | e477b8b8 | bellard | src = T0; |
65 | e477b8b8 | bellard | T0 &= DATA_MASK; |
66 | e477b8b8 | bellard | T0 = (T0 >> count) | (T0 << (DATA_BITS - count)); |
67 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
68 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
69 | 91cf4d88 | bellard | #else
|
70 | 91cf4d88 | bellard | /* gcc 3.2 workaround. This is really a bug in gcc. */
|
71 | 91cf4d88 | bellard | asm volatile("" : : "r" (T0)); |
72 | e477b8b8 | bellard | #endif
|
73 | e477b8b8 | bellard | CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) | |
74 | e477b8b8 | bellard | (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | |
75 | e477b8b8 | bellard | ((T0 >> (DATA_BITS - 1)) & CC_C);
|
76 | e477b8b8 | bellard | CC_OP = CC_OP_EFLAGS; |
77 | e477b8b8 | bellard | } |
78 | e477b8b8 | bellard | FORCE_RET(); |
79 | e477b8b8 | bellard | } |
80 | e477b8b8 | bellard | |
81 | e477b8b8 | bellard | void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1)(void) |
82 | e477b8b8 | bellard | { |
83 | e477b8b8 | bellard | int count;
|
84 | e477b8b8 | bellard | count = T1 & SHIFT_MASK; |
85 | e477b8b8 | bellard | if (count) {
|
86 | e477b8b8 | bellard | T0 &= DATA_MASK; |
87 | e477b8b8 | bellard | T0 = (T0 << count) | (T0 >> (DATA_BITS - count)); |
88 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
89 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
90 | e477b8b8 | bellard | #endif
|
91 | e477b8b8 | bellard | } |
92 | e477b8b8 | bellard | FORCE_RET(); |
93 | e477b8b8 | bellard | } |
94 | e477b8b8 | bellard | |
95 | e477b8b8 | bellard | void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1)(void) |
96 | e477b8b8 | bellard | { |
97 | e477b8b8 | bellard | int count;
|
98 | e477b8b8 | bellard | count = T1 & SHIFT_MASK; |
99 | e477b8b8 | bellard | if (count) {
|
100 | e477b8b8 | bellard | T0 &= DATA_MASK; |
101 | e477b8b8 | bellard | T0 = (T0 >> count) | (T0 << (DATA_BITS - count)); |
102 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
103 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
104 | e477b8b8 | bellard | #endif
|
105 | e477b8b8 | bellard | } |
106 | e477b8b8 | bellard | FORCE_RET(); |
107 | e477b8b8 | bellard | } |
108 | e477b8b8 | bellard | |
109 | e477b8b8 | bellard | void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void) |
110 | e477b8b8 | bellard | { |
111 | e477b8b8 | bellard | int count, res, eflags;
|
112 | e477b8b8 | bellard | unsigned int src; |
113 | e477b8b8 | bellard | |
114 | e477b8b8 | bellard | count = T1 & 0x1f;
|
115 | e477b8b8 | bellard | #if DATA_BITS == 16 |
116 | e477b8b8 | bellard | count = rclw_table[count]; |
117 | e477b8b8 | bellard | #elif DATA_BITS == 8 |
118 | e477b8b8 | bellard | count = rclb_table[count]; |
119 | e477b8b8 | bellard | #endif
|
120 | e477b8b8 | bellard | if (count) {
|
121 | e477b8b8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
122 | e477b8b8 | bellard | T0 &= DATA_MASK; |
123 | e477b8b8 | bellard | src = T0; |
124 | e477b8b8 | bellard | res = (T0 << count) | ((eflags & CC_C) << (count - 1));
|
125 | e477b8b8 | bellard | if (count > 1) |
126 | e477b8b8 | bellard | res |= T0 >> (DATA_BITS + 1 - count);
|
127 | e477b8b8 | bellard | T0 = res; |
128 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
129 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
130 | e477b8b8 | bellard | #endif
|
131 | e477b8b8 | bellard | CC_SRC = (eflags & ~(CC_C | CC_O)) | |
132 | e477b8b8 | bellard | (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | |
133 | e477b8b8 | bellard | ((src >> (DATA_BITS - count)) & CC_C); |
134 | e477b8b8 | bellard | CC_OP = CC_OP_EFLAGS; |
135 | e477b8b8 | bellard | } |
136 | e477b8b8 | bellard | FORCE_RET(); |
137 | e477b8b8 | bellard | } |
138 | e477b8b8 | bellard | |
139 | e477b8b8 | bellard | void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void) |
140 | e477b8b8 | bellard | { |
141 | e477b8b8 | bellard | int count, res, eflags;
|
142 | e477b8b8 | bellard | unsigned int src; |
143 | e477b8b8 | bellard | |
144 | e477b8b8 | bellard | count = T1 & 0x1f;
|
145 | e477b8b8 | bellard | #if DATA_BITS == 16 |
146 | e477b8b8 | bellard | count = rclw_table[count]; |
147 | e477b8b8 | bellard | #elif DATA_BITS == 8 |
148 | e477b8b8 | bellard | count = rclb_table[count]; |
149 | e477b8b8 | bellard | #endif
|
150 | e477b8b8 | bellard | if (count) {
|
151 | e477b8b8 | bellard | eflags = cc_table[CC_OP].compute_all(); |
152 | e477b8b8 | bellard | T0 &= DATA_MASK; |
153 | e477b8b8 | bellard | src = T0; |
154 | e477b8b8 | bellard | res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count)); |
155 | e477b8b8 | bellard | if (count > 1) |
156 | e477b8b8 | bellard | res |= T0 << (DATA_BITS + 1 - count);
|
157 | e477b8b8 | bellard | T0 = res; |
158 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
159 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
160 | e477b8b8 | bellard | #endif
|
161 | e477b8b8 | bellard | CC_SRC = (eflags & ~(CC_C | CC_O)) | |
162 | e477b8b8 | bellard | (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | |
163 | e477b8b8 | bellard | ((src >> (count - 1)) & CC_C);
|
164 | e477b8b8 | bellard | CC_OP = CC_OP_EFLAGS; |
165 | e477b8b8 | bellard | } |
166 | e477b8b8 | bellard | FORCE_RET(); |
167 | e477b8b8 | bellard | } |
168 | e477b8b8 | bellard | |
169 | e477b8b8 | bellard | void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void) |
170 | e477b8b8 | bellard | { |
171 | e477b8b8 | bellard | int count, src;
|
172 | e477b8b8 | bellard | count = T1 & 0x1f;
|
173 | e477b8b8 | bellard | if (count) {
|
174 | e477b8b8 | bellard | src = (DATA_TYPE)T0 << (count - 1);
|
175 | e477b8b8 | bellard | T0 = T0 << count; |
176 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
177 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
178 | e477b8b8 | bellard | #endif
|
179 | e477b8b8 | bellard | CC_SRC = src; |
180 | e477b8b8 | bellard | CC_DST = T0; |
181 | e477b8b8 | bellard | CC_OP = CC_OP_SHLB + SHIFT; |
182 | e477b8b8 | bellard | } |
183 | e477b8b8 | bellard | FORCE_RET(); |
184 | e477b8b8 | bellard | } |
185 | e477b8b8 | bellard | |
186 | e477b8b8 | bellard | void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void) |
187 | e477b8b8 | bellard | { |
188 | e477b8b8 | bellard | int count, src;
|
189 | e477b8b8 | bellard | count = T1 & 0x1f;
|
190 | e477b8b8 | bellard | if (count) {
|
191 | e477b8b8 | bellard | T0 &= DATA_MASK; |
192 | e477b8b8 | bellard | src = T0 >> (count - 1);
|
193 | e477b8b8 | bellard | T0 = T0 >> count; |
194 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
195 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
196 | e477b8b8 | bellard | #endif
|
197 | e477b8b8 | bellard | CC_SRC = src; |
198 | e477b8b8 | bellard | CC_DST = T0; |
199 | e477b8b8 | bellard | CC_OP = CC_OP_SARB + SHIFT; |
200 | e477b8b8 | bellard | } |
201 | e477b8b8 | bellard | FORCE_RET(); |
202 | e477b8b8 | bellard | } |
203 | e477b8b8 | bellard | |
204 | e477b8b8 | bellard | void OPPROTO glue(glue(op_sar, MEM_SUFFIX), _T0_T1_cc)(void) |
205 | e477b8b8 | bellard | { |
206 | e477b8b8 | bellard | int count, src;
|
207 | e477b8b8 | bellard | count = T1 & 0x1f;
|
208 | e477b8b8 | bellard | if (count) {
|
209 | e477b8b8 | bellard | src = (DATA_STYPE)T0; |
210 | e477b8b8 | bellard | T0 = src >> count; |
211 | e477b8b8 | bellard | src = src >> (count - 1);
|
212 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
213 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
214 | e477b8b8 | bellard | #endif
|
215 | e477b8b8 | bellard | CC_SRC = src; |
216 | e477b8b8 | bellard | CC_DST = T0; |
217 | e477b8b8 | bellard | CC_OP = CC_OP_SARB + SHIFT; |
218 | e477b8b8 | bellard | } |
219 | e477b8b8 | bellard | FORCE_RET(); |
220 | e477b8b8 | bellard | } |
221 | e477b8b8 | bellard | |
222 | e477b8b8 | bellard | #if DATA_BITS == 16 |
223 | e477b8b8 | bellard | /* XXX: overflow flag might be incorrect in some cases in shldw */
|
224 | e477b8b8 | bellard | void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void) |
225 | e477b8b8 | bellard | { |
226 | e477b8b8 | bellard | int count;
|
227 | e477b8b8 | bellard | unsigned int res, tmp; |
228 | e477b8b8 | bellard | count = PARAM1; |
229 | e477b8b8 | bellard | T1 &= 0xffff;
|
230 | e477b8b8 | bellard | res = T1 | (T0 << 16);
|
231 | e477b8b8 | bellard | tmp = res >> (32 - count);
|
232 | e477b8b8 | bellard | res <<= count; |
233 | e477b8b8 | bellard | if (count > 16) |
234 | e477b8b8 | bellard | res |= T1 << (count - 16);
|
235 | e477b8b8 | bellard | T0 = res >> 16;
|
236 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
237 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
238 | e477b8b8 | bellard | #endif
|
239 | e477b8b8 | bellard | CC_SRC = tmp; |
240 | e477b8b8 | bellard | CC_DST = T0; |
241 | e477b8b8 | bellard | } |
242 | e477b8b8 | bellard | |
243 | e477b8b8 | bellard | void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void) |
244 | e477b8b8 | bellard | { |
245 | e477b8b8 | bellard | int count;
|
246 | e477b8b8 | bellard | unsigned int res, tmp; |
247 | e477b8b8 | bellard | count = ECX & 0x1f;
|
248 | e477b8b8 | bellard | if (count) {
|
249 | e477b8b8 | bellard | T1 &= 0xffff;
|
250 | e477b8b8 | bellard | res = T1 | (T0 << 16);
|
251 | e477b8b8 | bellard | tmp = res >> (32 - count);
|
252 | e477b8b8 | bellard | res <<= count; |
253 | e477b8b8 | bellard | if (count > 16) |
254 | e477b8b8 | bellard | res |= T1 << (count - 16);
|
255 | e477b8b8 | bellard | T0 = res >> 16;
|
256 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
257 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
258 | e477b8b8 | bellard | #endif
|
259 | e477b8b8 | bellard | CC_SRC = tmp; |
260 | e477b8b8 | bellard | CC_DST = T0; |
261 | e477b8b8 | bellard | CC_OP = CC_OP_SARB + SHIFT; |
262 | e477b8b8 | bellard | } |
263 | e477b8b8 | bellard | FORCE_RET(); |
264 | e477b8b8 | bellard | } |
265 | e477b8b8 | bellard | |
266 | e477b8b8 | bellard | void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void) |
267 | e477b8b8 | bellard | { |
268 | e477b8b8 | bellard | int count;
|
269 | e477b8b8 | bellard | unsigned int res, tmp; |
270 | e477b8b8 | bellard | |
271 | e477b8b8 | bellard | count = PARAM1; |
272 | e477b8b8 | bellard | res = (T0 & 0xffff) | (T1 << 16); |
273 | e477b8b8 | bellard | tmp = res >> (count - 1);
|
274 | e477b8b8 | bellard | res >>= count; |
275 | e477b8b8 | bellard | if (count > 16) |
276 | e477b8b8 | bellard | res |= T1 << (32 - count);
|
277 | e477b8b8 | bellard | T0 = res; |
278 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
279 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
280 | e477b8b8 | bellard | #endif
|
281 | e477b8b8 | bellard | CC_SRC = tmp; |
282 | e477b8b8 | bellard | CC_DST = T0; |
283 | e477b8b8 | bellard | } |
284 | e477b8b8 | bellard | |
285 | e477b8b8 | bellard | |
286 | e477b8b8 | bellard | void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void) |
287 | e477b8b8 | bellard | { |
288 | e477b8b8 | bellard | int count;
|
289 | e477b8b8 | bellard | unsigned int res, tmp; |
290 | e477b8b8 | bellard | |
291 | e477b8b8 | bellard | count = ECX & 0x1f;
|
292 | e477b8b8 | bellard | if (count) {
|
293 | e477b8b8 | bellard | res = (T0 & 0xffff) | (T1 << 16); |
294 | e477b8b8 | bellard | tmp = res >> (count - 1);
|
295 | e477b8b8 | bellard | res >>= count; |
296 | e477b8b8 | bellard | if (count > 16) |
297 | e477b8b8 | bellard | res |= T1 << (32 - count);
|
298 | e477b8b8 | bellard | T0 = res; |
299 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
300 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
301 | e477b8b8 | bellard | #endif
|
302 | e477b8b8 | bellard | CC_SRC = tmp; |
303 | e477b8b8 | bellard | CC_DST = T0; |
304 | e477b8b8 | bellard | CC_OP = CC_OP_SARB + SHIFT; |
305 | e477b8b8 | bellard | } |
306 | e477b8b8 | bellard | FORCE_RET(); |
307 | e477b8b8 | bellard | } |
308 | e477b8b8 | bellard | #endif
|
309 | e477b8b8 | bellard | |
310 | e477b8b8 | bellard | #if DATA_BITS == 32 |
311 | e477b8b8 | bellard | void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void) |
312 | e477b8b8 | bellard | { |
313 | e477b8b8 | bellard | int count, tmp;
|
314 | e477b8b8 | bellard | count = PARAM1; |
315 | e477b8b8 | bellard | T0 &= DATA_MASK; |
316 | e477b8b8 | bellard | T1 &= DATA_MASK; |
317 | e477b8b8 | bellard | tmp = T0 << (count - 1);
|
318 | e477b8b8 | bellard | T0 = (T0 << count) | (T1 >> (DATA_BITS - count)); |
319 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
320 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
321 | e477b8b8 | bellard | #endif
|
322 | e477b8b8 | bellard | CC_SRC = tmp; |
323 | e477b8b8 | bellard | CC_DST = T0; |
324 | e477b8b8 | bellard | } |
325 | e477b8b8 | bellard | |
326 | e477b8b8 | bellard | void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void) |
327 | e477b8b8 | bellard | { |
328 | e477b8b8 | bellard | int count, tmp;
|
329 | e477b8b8 | bellard | count = ECX & 0x1f;
|
330 | e477b8b8 | bellard | if (count) {
|
331 | e477b8b8 | bellard | T0 &= DATA_MASK; |
332 | e477b8b8 | bellard | T1 &= DATA_MASK; |
333 | e477b8b8 | bellard | tmp = T0 << (count - 1);
|
334 | e477b8b8 | bellard | T0 = (T0 << count) | (T1 >> (DATA_BITS - count)); |
335 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
336 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
337 | e477b8b8 | bellard | #endif
|
338 | e477b8b8 | bellard | CC_SRC = tmp; |
339 | e477b8b8 | bellard | CC_DST = T0; |
340 | e477b8b8 | bellard | CC_OP = CC_OP_SHLB + SHIFT; |
341 | e477b8b8 | bellard | } |
342 | e477b8b8 | bellard | FORCE_RET(); |
343 | e477b8b8 | bellard | } |
344 | e477b8b8 | bellard | |
345 | e477b8b8 | bellard | void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void) |
346 | e477b8b8 | bellard | { |
347 | e477b8b8 | bellard | int count, tmp;
|
348 | e477b8b8 | bellard | count = PARAM1; |
349 | e477b8b8 | bellard | T0 &= DATA_MASK; |
350 | e477b8b8 | bellard | T1 &= DATA_MASK; |
351 | e477b8b8 | bellard | tmp = T0 >> (count - 1);
|
352 | e477b8b8 | bellard | T0 = (T0 >> count) | (T1 << (DATA_BITS - count)); |
353 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
354 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
355 | e477b8b8 | bellard | #endif
|
356 | e477b8b8 | bellard | CC_SRC = tmp; |
357 | e477b8b8 | bellard | CC_DST = T0; |
358 | e477b8b8 | bellard | } |
359 | e477b8b8 | bellard | |
360 | e477b8b8 | bellard | |
361 | e477b8b8 | bellard | void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void) |
362 | e477b8b8 | bellard | { |
363 | e477b8b8 | bellard | int count, tmp;
|
364 | e477b8b8 | bellard | count = ECX & 0x1f;
|
365 | e477b8b8 | bellard | if (count) {
|
366 | e477b8b8 | bellard | T0 &= DATA_MASK; |
367 | e477b8b8 | bellard | T1 &= DATA_MASK; |
368 | e477b8b8 | bellard | tmp = T0 >> (count - 1);
|
369 | e477b8b8 | bellard | T0 = (T0 >> count) | (T1 << (DATA_BITS - count)); |
370 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
371 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
372 | e477b8b8 | bellard | #endif
|
373 | e477b8b8 | bellard | CC_SRC = tmp; |
374 | e477b8b8 | bellard | CC_DST = T0; |
375 | e477b8b8 | bellard | CC_OP = CC_OP_SARB + SHIFT; |
376 | e477b8b8 | bellard | } |
377 | e477b8b8 | bellard | FORCE_RET(); |
378 | e477b8b8 | bellard | } |
379 | e477b8b8 | bellard | #endif
|
380 | e477b8b8 | bellard | |
381 | e477b8b8 | bellard | /* carry add/sub (we only need to set CC_OP differently) */
|
382 | e477b8b8 | bellard | |
383 | e477b8b8 | bellard | void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void) |
384 | e477b8b8 | bellard | { |
385 | e477b8b8 | bellard | int cf;
|
386 | e477b8b8 | bellard | cf = cc_table[CC_OP].compute_c(); |
387 | e477b8b8 | bellard | T0 = T0 + T1 + cf; |
388 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
389 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
390 | e477b8b8 | bellard | #endif
|
391 | e477b8b8 | bellard | CC_SRC = T1; |
392 | e477b8b8 | bellard | CC_DST = T0; |
393 | e477b8b8 | bellard | CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
|
394 | e477b8b8 | bellard | } |
395 | e477b8b8 | bellard | |
396 | e477b8b8 | bellard | void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void) |
397 | e477b8b8 | bellard | { |
398 | e477b8b8 | bellard | int cf;
|
399 | e477b8b8 | bellard | cf = cc_table[CC_OP].compute_c(); |
400 | e477b8b8 | bellard | T0 = T0 - T1 - cf; |
401 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
402 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
403 | e477b8b8 | bellard | #endif
|
404 | e477b8b8 | bellard | CC_SRC = T1; |
405 | e477b8b8 | bellard | CC_DST = T0; |
406 | e477b8b8 | bellard | CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
|
407 | e477b8b8 | bellard | } |
408 | e477b8b8 | bellard | |
409 | e477b8b8 | bellard | void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void) |
410 | e477b8b8 | bellard | { |
411 | e477b8b8 | bellard | unsigned int src, dst; |
412 | e477b8b8 | bellard | |
413 | e477b8b8 | bellard | src = T0; |
414 | e477b8b8 | bellard | dst = EAX - T0; |
415 | e477b8b8 | bellard | if ((DATA_TYPE)dst == 0) { |
416 | e477b8b8 | bellard | T0 = T1; |
417 | e477b8b8 | bellard | } else {
|
418 | e477b8b8 | bellard | EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK); |
419 | e477b8b8 | bellard | } |
420 | e477b8b8 | bellard | #ifdef MEM_WRITE
|
421 | e477b8b8 | bellard | glue(st, SUFFIX)((uint8_t *)A0, T0); |
422 | e477b8b8 | bellard | #endif
|
423 | e477b8b8 | bellard | CC_SRC = src; |
424 | e477b8b8 | bellard | CC_DST = dst; |
425 | e477b8b8 | bellard | FORCE_RET(); |
426 | e477b8b8 | bellard | } |
427 | e477b8b8 | bellard | |
428 | e477b8b8 | bellard | #undef MEM_SUFFIX
|
429 | e477b8b8 | bellard | #undef MEM_WRITE |