~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to target-i386/helper_template.h

  • Committer: ths
  • Date: 2007-06-17 15:32:30 UTC
  • Revision ID: git-v1:ffb04fcf089865952592f1f8855c2848d4514a89
Allow relative paths for the interpreter prefix in linux-user emulation.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2984 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
#define DATA_BITS (1 << (3 + SHIFT))
21
 
#define SHIFT_MASK (DATA_BITS - 1)
22
 
#define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1))
23
 
#if DATA_BITS <= 32
24
 
#define SHIFT1_MASK 0x1f
25
 
#else
26
 
#define SHIFT1_MASK 0x3f
27
 
#endif
28
 
 
29
 
#if DATA_BITS == 8
30
 
#define SUFFIX b
31
 
#define DATA_TYPE uint8_t
32
 
#define DATA_STYPE int8_t
33
 
#define DATA_MASK 0xff
34
 
#elif DATA_BITS == 16
35
 
#define SUFFIX w
36
 
#define DATA_TYPE uint16_t
37
 
#define DATA_STYPE int16_t
38
 
#define DATA_MASK 0xffff
39
 
#elif DATA_BITS == 32
40
 
#define SUFFIX l
41
 
#define DATA_TYPE uint32_t
42
 
#define DATA_STYPE int32_t
43
 
#define DATA_MASK 0xffffffff
44
 
#elif DATA_BITS == 64
45
 
#define SUFFIX q
46
 
#define DATA_TYPE uint64_t
47
 
#define DATA_STYPE int64_t
48
 
#define DATA_MASK 0xffffffffffffffffULL
49
 
#else
50
 
#error unhandled operand size
51
 
#endif
52
 
 
53
 
/* dynamic flags computation */
54
 
 
55
 
static int glue(compute_all_add, SUFFIX)(void)
56
 
{
57
 
    int cf, pf, af, zf, sf, of;
58
 
    target_long src1, src2;
59
 
    src1 = CC_SRC;
60
 
    src2 = CC_DST - CC_SRC;
61
 
    cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
62
 
    pf = parity_table[(uint8_t)CC_DST];
63
 
    af = (CC_DST ^ src1 ^ src2) & 0x10;
64
 
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
65
 
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
66
 
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
67
 
    return cf | pf | af | zf | sf | of;
68
 
}
69
 
 
70
 
static int glue(compute_c_add, SUFFIX)(void)
71
 
{
72
 
    int cf;
73
 
    target_long src1;
74
 
    src1 = CC_SRC;
75
 
    cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
76
 
    return cf;
77
 
}
78
 
 
79
 
static int glue(compute_all_adc, SUFFIX)(void)
80
 
{
81
 
    int cf, pf, af, zf, sf, of;
82
 
    target_long src1, src2;
83
 
    src1 = CC_SRC;
84
 
    src2 = CC_DST - CC_SRC - 1;
85
 
    cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
86
 
    pf = parity_table[(uint8_t)CC_DST];
87
 
    af = (CC_DST ^ src1 ^ src2) & 0x10;
88
 
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
89
 
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
90
 
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
91
 
    return cf | pf | af | zf | sf | of;
92
 
}
93
 
 
94
 
static int glue(compute_c_adc, SUFFIX)(void)
95
 
{
96
 
    int cf;
97
 
    target_long src1;
98
 
    src1 = CC_SRC;
99
 
    cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
100
 
    return cf;
101
 
}
102
 
 
103
 
static int glue(compute_all_sub, SUFFIX)(void)
104
 
{
105
 
    int cf, pf, af, zf, sf, of;
106
 
    target_long src1, src2;
107
 
    src1 = CC_DST + CC_SRC;
108
 
    src2 = CC_SRC;
109
 
    cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
110
 
    pf = parity_table[(uint8_t)CC_DST];
111
 
    af = (CC_DST ^ src1 ^ src2) & 0x10;
112
 
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
113
 
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
114
 
    of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
115
 
    return cf | pf | af | zf | sf | of;
116
 
}
117
 
 
118
 
static int glue(compute_c_sub, SUFFIX)(void)
119
 
{
120
 
    int cf;
121
 
    target_long src1, src2;
122
 
    src1 = CC_DST + CC_SRC;
123
 
    src2 = CC_SRC;
124
 
    cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
125
 
    return cf;
126
 
}
127
 
 
128
 
static int glue(compute_all_sbb, SUFFIX)(void)
129
 
{
130
 
    int cf, pf, af, zf, sf, of;
131
 
    target_long src1, src2;
132
 
    src1 = CC_DST + CC_SRC + 1;
133
 
    src2 = CC_SRC;
134
 
    cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
135
 
    pf = parity_table[(uint8_t)CC_DST];
136
 
    af = (CC_DST ^ src1 ^ src2) & 0x10;
137
 
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
138
 
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
139
 
    of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
140
 
    return cf | pf | af | zf | sf | of;
141
 
}
142
 
 
143
 
static int glue(compute_c_sbb, SUFFIX)(void)
144
 
{
145
 
    int cf;
146
 
    target_long src1, src2;
147
 
    src1 = CC_DST + CC_SRC + 1;
148
 
    src2 = CC_SRC;
149
 
    cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
150
 
    return cf;
151
 
}
152
 
 
153
 
static int glue(compute_all_logic, SUFFIX)(void)
154
 
{
155
 
    int cf, pf, af, zf, sf, of;
156
 
    cf = 0;
157
 
    pf = parity_table[(uint8_t)CC_DST];
158
 
    af = 0;
159
 
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
160
 
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
161
 
    of = 0;
162
 
    return cf | pf | af | zf | sf | of;
163
 
}
164
 
 
165
 
static int glue(compute_c_logic, SUFFIX)(void)
166
 
{
167
 
    return 0;
168
 
}
169
 
 
170
 
static int glue(compute_all_inc, SUFFIX)(void)
171
 
{
172
 
    int cf, pf, af, zf, sf, of;
173
 
    target_long src1, src2;
174
 
    src1 = CC_DST - 1;
175
 
    src2 = 1;
176
 
    cf = CC_SRC;
177
 
    pf = parity_table[(uint8_t)CC_DST];
178
 
    af = (CC_DST ^ src1 ^ src2) & 0x10;
179
 
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
180
 
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
181
 
    of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
182
 
    return cf | pf | af | zf | sf | of;
183
 
}
184
 
 
185
 
#if DATA_BITS == 32
186
 
static int glue(compute_c_inc, SUFFIX)(void)
187
 
{
188
 
    return CC_SRC;
189
 
}
190
 
#endif
191
 
 
192
 
static int glue(compute_all_dec, SUFFIX)(void)
193
 
{
194
 
    int cf, pf, af, zf, sf, of;
195
 
    target_long src1, src2;
196
 
    src1 = CC_DST + 1;
197
 
    src2 = 1;
198
 
    cf = CC_SRC;
199
 
    pf = parity_table[(uint8_t)CC_DST];
200
 
    af = (CC_DST ^ src1 ^ src2) & 0x10;
201
 
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
202
 
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
203
 
    of = ((CC_DST & DATA_MASK) == ((target_ulong)SIGN_MASK - 1)) << 11;
204
 
    return cf | pf | af | zf | sf | of;
205
 
}
206
 
 
207
 
static int glue(compute_all_shl, SUFFIX)(void)
208
 
{
209
 
    int cf, pf, af, zf, sf, of;
210
 
    cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C;
211
 
    pf = parity_table[(uint8_t)CC_DST];
212
 
    af = 0; /* undefined */
213
 
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
214
 
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
215
 
    /* of is defined if shift count == 1 */
216
 
    of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
217
 
    return cf | pf | af | zf | sf | of;
218
 
}
219
 
 
220
 
static int glue(compute_c_shl, SUFFIX)(void)
221
 
{
222
 
    return (CC_SRC >> (DATA_BITS - 1)) & CC_C;
223
 
}
224
 
 
225
 
#if DATA_BITS == 32
226
 
static int glue(compute_c_sar, SUFFIX)(void)
227
 
{
228
 
    return CC_SRC & 1;
229
 
}
230
 
#endif
231
 
 
232
 
static int glue(compute_all_sar, SUFFIX)(void)
233
 
{
234
 
    int cf, pf, af, zf, sf, of;
235
 
    cf = CC_SRC & 1;
236
 
    pf = parity_table[(uint8_t)CC_DST];
237
 
    af = 0; /* undefined */
238
 
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
239
 
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
240
 
    /* of is defined if shift count == 1 */
241
 
    of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
242
 
    return cf | pf | af | zf | sf | of;
243
 
}
244
 
 
245
 
#if DATA_BITS == 32
246
 
static int glue(compute_c_mul, SUFFIX)(void)
247
 
{
248
 
    int cf;
249
 
    cf = (CC_SRC != 0);
250
 
    return cf;
251
 
}
252
 
#endif
253
 
 
254
 
/* NOTE: we compute the flags like the P4. On olders CPUs, only OF and
255
 
   CF are modified and it is slower to do that. */
256
 
static int glue(compute_all_mul, SUFFIX)(void)
257
 
{
258
 
    int cf, pf, af, zf, sf, of;
259
 
    cf = (CC_SRC != 0);
260
 
    pf = parity_table[(uint8_t)CC_DST];
261
 
    af = 0; /* undefined */
262
 
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
263
 
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
264
 
    of = cf << 11;
265
 
    return cf | pf | af | zf | sf | of;
266
 
}
267
 
 
268
 
/* shifts */
269
 
 
270
 
target_ulong glue(helper_rcl, SUFFIX)(target_ulong t0, target_ulong t1)
271
 
{
272
 
    int count, eflags;
273
 
    target_ulong src;
274
 
    target_long res;
275
 
 
276
 
    count = t1 & SHIFT1_MASK;
277
 
#if DATA_BITS == 16
278
 
    count = rclw_table[count];
279
 
#elif DATA_BITS == 8
280
 
    count = rclb_table[count];
281
 
#endif
282
 
    if (count) {
283
 
        eflags = cc_table[CC_OP].compute_all();
284
 
        t0 &= DATA_MASK;
285
 
        src = t0;
286
 
        res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
287
 
        if (count > 1)
288
 
            res |= t0 >> (DATA_BITS + 1 - count);
289
 
        t0 = res;
290
 
        env->cc_tmp = (eflags & ~(CC_C | CC_O)) |
291
 
            (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
292
 
            ((src >> (DATA_BITS - count)) & CC_C);
293
 
    } else {
294
 
        env->cc_tmp = -1;
295
 
    }
296
 
    return t0;
297
 
}
298
 
 
299
 
target_ulong glue(helper_rcr, SUFFIX)(target_ulong t0, target_ulong t1)
300
 
{
301
 
    int count, eflags;
302
 
    target_ulong src;
303
 
    target_long res;
304
 
 
305
 
    count = t1 & SHIFT1_MASK;
306
 
#if DATA_BITS == 16
307
 
    count = rclw_table[count];
308
 
#elif DATA_BITS == 8
309
 
    count = rclb_table[count];
310
 
#endif
311
 
    if (count) {
312
 
        eflags = cc_table[CC_OP].compute_all();
313
 
        t0 &= DATA_MASK;
314
 
        src = t0;
315
 
        res = (t0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count));
316
 
        if (count > 1)
317
 
            res |= t0 << (DATA_BITS + 1 - count);
318
 
        t0 = res;
319
 
        env->cc_tmp = (eflags & ~(CC_C | CC_O)) |
320
 
            (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
321
 
            ((src >> (count - 1)) & CC_C);
322
 
    } else {
323
 
        env->cc_tmp = -1;
324
 
    }
325
 
    return t0;
326
 
}
327
 
 
328
 
#undef DATA_BITS
329
 
#undef SHIFT_MASK
330
 
#undef SHIFT1_MASK
331
 
#undef SIGN_MASK
332
 
#undef DATA_TYPE
333
 
#undef DATA_STYPE
334
 
#undef DATA_MASK
335
 
#undef SUFFIX