VirtualBox

source: vbox/trunk/src/recompiler/target-i386/helper_template.h@ 33889

Last change on this file since 33889 was 33656, checked in by vboxsync, 14 years ago

*: rebrand Sun (L)GPL disclaimers

  • Property svn:eol-style set to native
File size: 9.2 KB
Line 
1/*
2 * i386 helpers
3 *
4 * Copyright (c) 2008 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
23 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
24 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
25 * a choice of LGPL license versions is made available with the language indicating
26 * that LGPLv2 or any later version may be used, or where a choice of which version
27 * of the LGPL is applied is otherwise unspecified.
28 */
29
30#define DATA_BITS (1 << (3 + SHIFT))
31#define SHIFT_MASK (DATA_BITS - 1)
32#define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1))
33#if DATA_BITS <= 32
34#define SHIFT1_MASK 0x1f
35#else
36#define SHIFT1_MASK 0x3f
37#endif
38
39#if DATA_BITS == 8
40#define SUFFIX b
41#define DATA_TYPE uint8_t
42#define DATA_STYPE int8_t
43#define DATA_MASK 0xff
44#elif DATA_BITS == 16
45#define SUFFIX w
46#define DATA_TYPE uint16_t
47#define DATA_STYPE int16_t
48#define DATA_MASK 0xffff
49#elif DATA_BITS == 32
50#define SUFFIX l
51#define DATA_TYPE uint32_t
52#define DATA_STYPE int32_t
53#define DATA_MASK 0xffffffff
54#elif DATA_BITS == 64
55#define SUFFIX q
56#define DATA_TYPE uint64_t
57#define DATA_STYPE int64_t
58#define DATA_MASK 0xffffffffffffffffULL
59#else
60#error unhandled operand size
61#endif
62
63/* dynamic flags computation */
64
65static int glue(compute_all_add, SUFFIX)(void)
66{
67 int cf, pf, af, zf, sf, of;
68 target_long src1, src2;
69 src1 = CC_SRC;
70 src2 = CC_DST - CC_SRC;
71 cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
72 pf = parity_table[(uint8_t)CC_DST];
73 af = (CC_DST ^ src1 ^ src2) & 0x10;
74 zf = ((DATA_TYPE)CC_DST == 0) << 6;
75 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
76 of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
77 return cf | pf | af | zf | sf | of;
78}
79
80static int glue(compute_c_add, SUFFIX)(void)
81{
82 int cf;
83 target_long src1;
84 src1 = CC_SRC;
85 cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
86 return cf;
87}
88
89static int glue(compute_all_adc, SUFFIX)(void)
90{
91 int cf, pf, af, zf, sf, of;
92 target_long src1, src2;
93 src1 = CC_SRC;
94 src2 = CC_DST - CC_SRC - 1;
95 cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
96 pf = parity_table[(uint8_t)CC_DST];
97 af = (CC_DST ^ src1 ^ src2) & 0x10;
98 zf = ((DATA_TYPE)CC_DST == 0) << 6;
99 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
100 of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
101 return cf | pf | af | zf | sf | of;
102}
103
104static int glue(compute_c_adc, SUFFIX)(void)
105{
106 int cf;
107 target_long src1;
108 src1 = CC_SRC;
109 cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
110 return cf;
111}
112
113static int glue(compute_all_sub, SUFFIX)(void)
114{
115 int cf, pf, af, zf, sf, of;
116 target_long src1, src2;
117 src1 = CC_DST + CC_SRC;
118 src2 = CC_SRC;
119 cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
120 pf = parity_table[(uint8_t)CC_DST];
121 af = (CC_DST ^ src1 ^ src2) & 0x10;
122 zf = ((DATA_TYPE)CC_DST == 0) << 6;
123 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
124 of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
125 return cf | pf | af | zf | sf | of;
126}
127
128static int glue(compute_c_sub, SUFFIX)(void)
129{
130 int cf;
131 target_long src1, src2;
132 src1 = CC_DST + CC_SRC;
133 src2 = CC_SRC;
134 cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
135 return cf;
136}
137
138static int glue(compute_all_sbb, SUFFIX)(void)
139{
140 int cf, pf, af, zf, sf, of;
141 target_long src1, src2;
142 src1 = CC_DST + CC_SRC + 1;
143 src2 = CC_SRC;
144 cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
145 pf = parity_table[(uint8_t)CC_DST];
146 af = (CC_DST ^ src1 ^ src2) & 0x10;
147 zf = ((DATA_TYPE)CC_DST == 0) << 6;
148 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
149 of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
150 return cf | pf | af | zf | sf | of;
151}
152
153static int glue(compute_c_sbb, SUFFIX)(void)
154{
155 int cf;
156 target_long src1, src2;
157 src1 = CC_DST + CC_SRC + 1;
158 src2 = CC_SRC;
159 cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
160 return cf;
161}
162
163static int glue(compute_all_logic, SUFFIX)(void)
164{
165 int cf, pf, af, zf, sf, of;
166 cf = 0;
167 pf = parity_table[(uint8_t)CC_DST];
168 af = 0;
169 zf = ((DATA_TYPE)CC_DST == 0) << 6;
170 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
171 of = 0;
172 return cf | pf | af | zf | sf | of;
173}
174
175static int glue(compute_c_logic, SUFFIX)(void)
176{
177 return 0;
178}
179
180static int glue(compute_all_inc, SUFFIX)(void)
181{
182 int cf, pf, af, zf, sf, of;
183 target_long src1, src2;
184 src1 = CC_DST - 1;
185 src2 = 1;
186 cf = CC_SRC;
187 pf = parity_table[(uint8_t)CC_DST];
188 af = (CC_DST ^ src1 ^ src2) & 0x10;
189 zf = ((DATA_TYPE)CC_DST == 0) << 6;
190 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
191 of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
192 return cf | pf | af | zf | sf | of;
193}
194
195#if DATA_BITS == 32
196static int glue(compute_c_inc, SUFFIX)(void)
197{
198 return CC_SRC;
199}
200#endif
201
202static int glue(compute_all_dec, SUFFIX)(void)
203{
204 int cf, pf, af, zf, sf, of;
205 target_long src1, src2;
206 src1 = CC_DST + 1;
207 src2 = 1;
208 cf = CC_SRC;
209 pf = parity_table[(uint8_t)CC_DST];
210 af = (CC_DST ^ src1 ^ src2) & 0x10;
211 zf = ((DATA_TYPE)CC_DST == 0) << 6;
212 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
213 of = ((CC_DST & DATA_MASK) == ((target_ulong)SIGN_MASK - 1)) << 11;
214 return cf | pf | af | zf | sf | of;
215}
216
217static int glue(compute_all_shl, SUFFIX)(void)
218{
219 int cf, pf, af, zf, sf, of;
220 cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C;
221 pf = parity_table[(uint8_t)CC_DST];
222 af = 0; /* undefined */
223 zf = ((DATA_TYPE)CC_DST == 0) << 6;
224 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
225 /* of is defined if shift count == 1 */
226 of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
227 return cf | pf | af | zf | sf | of;
228}
229
230static int glue(compute_c_shl, SUFFIX)(void)
231{
232 return (CC_SRC >> (DATA_BITS - 1)) & CC_C;
233}
234
235#if DATA_BITS == 32
236static int glue(compute_c_sar, SUFFIX)(void)
237{
238 return CC_SRC & 1;
239}
240#endif
241
242static int glue(compute_all_sar, SUFFIX)(void)
243{
244 int cf, pf, af, zf, sf, of;
245 cf = CC_SRC & 1;
246 pf = parity_table[(uint8_t)CC_DST];
247 af = 0; /* undefined */
248 zf = ((DATA_TYPE)CC_DST == 0) << 6;
249 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
250 /* of is defined if shift count == 1 */
251 of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
252 return cf | pf | af | zf | sf | of;
253}
254
255#if DATA_BITS == 32
256static int glue(compute_c_mul, SUFFIX)(void)
257{
258 int cf;
259 cf = (CC_SRC != 0);
260 return cf;
261}
262#endif
263
264/* NOTE: we compute the flags like the P4. On olders CPUs, only OF and
265 CF are modified and it is slower to do that. */
266static int glue(compute_all_mul, SUFFIX)(void)
267{
268 int cf, pf, af, zf, sf, of;
269 cf = (CC_SRC != 0);
270 pf = parity_table[(uint8_t)CC_DST];
271 af = 0; /* undefined */
272 zf = ((DATA_TYPE)CC_DST == 0) << 6;
273 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
274 of = cf << 11;
275 return cf | pf | af | zf | sf | of;
276}
277
278/* shifts */
279
280target_ulong glue(helper_rcl, SUFFIX)(target_ulong t0, target_ulong t1)
281{
282 int count, eflags;
283 target_ulong src;
284 target_long res;
285
286 count = t1 & SHIFT1_MASK;
287#if DATA_BITS == 16
288 count = rclw_table[count];
289#elif DATA_BITS == 8
290 count = rclb_table[count];
291#endif
292 if (count) {
293 eflags = cc_table[CC_OP].compute_all();
294 t0 &= DATA_MASK;
295 src = t0;
296 res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
297 if (count > 1)
298 res |= t0 >> (DATA_BITS + 1 - count);
299 t0 = res;
300 env->cc_tmp = (eflags & ~(CC_C | CC_O)) |
301 (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
302 ((src >> (DATA_BITS - count)) & CC_C);
303 } else {
304 env->cc_tmp = -1;
305 }
306 return t0;
307}
308
309target_ulong glue(helper_rcr, SUFFIX)(target_ulong t0, target_ulong t1)
310{
311 int count, eflags;
312 target_ulong src;
313 target_long res;
314
315 count = t1 & SHIFT1_MASK;
316#if DATA_BITS == 16
317 count = rclw_table[count];
318#elif DATA_BITS == 8
319 count = rclb_table[count];
320#endif
321 if (count) {
322 eflags = cc_table[CC_OP].compute_all();
323 t0 &= DATA_MASK;
324 src = t0;
325 res = (t0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count));
326 if (count > 1)
327 res |= t0 << (DATA_BITS + 1 - count);
328 t0 = res;
329 env->cc_tmp = (eflags & ~(CC_C | CC_O)) |
330 (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
331 ((src >> (count - 1)) & CC_C);
332 } else {
333 env->cc_tmp = -1;
334 }
335 return t0;
336}
337
338#undef DATA_BITS
339#undef SHIFT_MASK
340#undef SHIFT1_MASK
341#undef SIGN_MASK
342#undef DATA_TYPE
343#undef DATA_STYPE
344#undef DATA_MASK
345#undef SUFFIX
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette