Statistics
| Branch: | Revision:

root / target-i386 / ops_template_mem.h @ 5fafdf24

History | View | Annotate | Download (10.6 kB)

1
/*
2
 *  i386 micro operations (included several times to generate
3
 *  different operand sizes)
4
 *
5
 *  Copyright (c) 2003 Fabrice Bellard
6
 *
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.
11
 *
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.
16
 *
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
20
 */
21
#ifdef MEM_WRITE
22

    
23
#if MEM_WRITE == 0
24

    
25
#if DATA_BITS == 8
26
#define MEM_SUFFIX b_raw
27
#elif DATA_BITS == 16
28
#define MEM_SUFFIX w_raw
29
#elif DATA_BITS == 32
30
#define MEM_SUFFIX l_raw
31
#elif DATA_BITS == 64
32
#define MEM_SUFFIX q_raw
33
#endif
34

    
35
#elif MEM_WRITE == 1
36

    
37
#if DATA_BITS == 8
38
#define MEM_SUFFIX b_kernel
39
#elif DATA_BITS == 16
40
#define MEM_SUFFIX w_kernel
41
#elif DATA_BITS == 32
42
#define MEM_SUFFIX l_kernel
43
#elif DATA_BITS == 64
44
#define MEM_SUFFIX q_kernel
45
#endif
46

    
47
#elif MEM_WRITE == 2
48

    
49
#if DATA_BITS == 8
50
#define MEM_SUFFIX b_user
51
#elif DATA_BITS == 16
52
#define MEM_SUFFIX w_user
53
#elif DATA_BITS == 32
54
#define MEM_SUFFIX l_user
55
#elif DATA_BITS == 64
56
#define MEM_SUFFIX q_user
57
#endif
58

    
59
#else
60

    
61
#error invalid MEM_WRITE
62

    
63
#endif
64

    
65
#else
66

    
67
#define MEM_SUFFIX SUFFIX
68

    
69
#endif
70

    
71
void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void)
72
{
73
    int count;
74
    target_long src;
75

    
76
    if (T1 & SHIFT1_MASK) {
77
        count = T1 & SHIFT_MASK;
78
        src = T0;
79
        T0 &= DATA_MASK;
80
        T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
81
#ifdef MEM_WRITE
82
        glue(st, MEM_SUFFIX)(A0, T0);
83
#else
84
        /* gcc 3.2 workaround. This is really a bug in gcc. */
85
        asm volatile("" : : "r" (T0));
86
#endif
87
        CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
88
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
89
            (T0 & CC_C);
90
        CC_OP = CC_OP_EFLAGS;
91
    }
92
    FORCE_RET();
93
}
94

    
95
void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1_cc)(void)
96
{
97
    int count;
98
    target_long src;
99

    
100
    if (T1 & SHIFT1_MASK) {
101
        count = T1 & SHIFT_MASK;
102
        src = T0;
103
        T0 &= DATA_MASK;
104
        T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
105
#ifdef MEM_WRITE
106
        glue(st, MEM_SUFFIX)(A0, T0);
107
#else
108
        /* gcc 3.2 workaround. This is really a bug in gcc. */
109
        asm volatile("" : : "r" (T0));
110
#endif
111
        CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
112
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
113
            ((T0 >> (DATA_BITS - 1)) & CC_C);
114
        CC_OP = CC_OP_EFLAGS;
115
    }
116
    FORCE_RET();
117
}
118

    
119
void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1)(void)
120
{
121
    int count;
122
    count = T1 & SHIFT_MASK;
123
    if (count) {
124
        T0 &= DATA_MASK;
125
        T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
126
#ifdef MEM_WRITE
127
        glue(st, MEM_SUFFIX)(A0, T0);
128
#endif
129
    }
130
    FORCE_RET();
131
}
132

    
133
void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1)(void)
134
{
135
    int count;
136
    count = T1 & SHIFT_MASK;
137
    if (count) {
138
        T0 &= DATA_MASK;
139
        T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
140
#ifdef MEM_WRITE
141
        glue(st, MEM_SUFFIX)(A0, T0);
142
#endif
143
    }
144
    FORCE_RET();
145
}
146

    
147
void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
148
{
149
    int count, eflags;
150
    target_ulong src;
151
    target_long res;
152

    
153
    count = T1 & SHIFT1_MASK;
154
#if DATA_BITS == 16
155
    count = rclw_table[count];
156
#elif DATA_BITS == 8
157
    count = rclb_table[count];
158
#endif
159
    if (count) {
160
        eflags = cc_table[CC_OP].compute_all();
161
        T0 &= DATA_MASK;
162
        src = T0;
163
        res = (T0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
164
        if (count > 1)
165
            res |= T0 >> (DATA_BITS + 1 - count);
166
        T0 = res;
167
#ifdef MEM_WRITE
168
        glue(st, MEM_SUFFIX)(A0, T0);
169
#endif
170
        CC_SRC = (eflags & ~(CC_C | CC_O)) |
171
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
172
            ((src >> (DATA_BITS - count)) & CC_C);
173
        CC_OP = CC_OP_EFLAGS;
174
    }
175
    FORCE_RET();
176
}
177

    
178
void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
179
{
180
    int count, eflags;
181
    target_ulong src;
182
    target_long res;
183

    
184
    count = T1 & SHIFT1_MASK;
185
#if DATA_BITS == 16
186
    count = rclw_table[count];
187
#elif DATA_BITS == 8
188
    count = rclb_table[count];
189
#endif
190
    if (count) {
191
        eflags = cc_table[CC_OP].compute_all();
192
        T0 &= DATA_MASK;
193
        src = T0;
194
        res = (T0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count));
195
        if (count > 1)
196
            res |= T0 << (DATA_BITS + 1 - count);
197
        T0 = res;
198
#ifdef MEM_WRITE
199
        glue(st, MEM_SUFFIX)(A0, T0);
200
#endif
201
        CC_SRC = (eflags & ~(CC_C | CC_O)) |
202
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
203
            ((src >> (count - 1)) & CC_C);
204
        CC_OP = CC_OP_EFLAGS;
205
    }
206
    FORCE_RET();
207
}
208

    
209
void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void)
210
{
211
    int count;
212
    target_long src;
213

    
214
    count = T1 & SHIFT1_MASK;
215
    if (count) {
216
        src = (DATA_TYPE)T0 << (count - 1);
217
        T0 = T0 << count;
218
#ifdef MEM_WRITE
219
        glue(st, MEM_SUFFIX)(A0, T0);
220
#endif
221
        CC_SRC = src;
222
        CC_DST = T0;
223
        CC_OP = CC_OP_SHLB + SHIFT;
224
    }
225
    FORCE_RET();
226
}
227

    
228
void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void)
229
{
230
    int count;
231
    target_long src;
232

    
233
    count = T1 & SHIFT1_MASK;
234
    if (count) {
235
        T0 &= DATA_MASK;
236
        src = T0 >> (count - 1);
237
        T0 = T0 >> count;
238
#ifdef MEM_WRITE
239
        glue(st, MEM_SUFFIX)(A0, T0);
240
#endif
241
        CC_SRC = src;
242
        CC_DST = T0;
243
        CC_OP = CC_OP_SARB + SHIFT;
244
    }
245
    FORCE_RET();
246
}
247

    
248
void OPPROTO glue(glue(op_sar, MEM_SUFFIX), _T0_T1_cc)(void)
249
{
250
    int count;
251
    target_long src;
252

    
253
    count = T1 & SHIFT1_MASK;
254
    if (count) {
255
        src = (DATA_STYPE)T0;
256
        T0 = src >> count;
257
        src = src >> (count - 1);
258
#ifdef MEM_WRITE
259
        glue(st, MEM_SUFFIX)(A0, T0);
260
#endif
261
        CC_SRC = src;
262
        CC_DST = T0;
263
        CC_OP = CC_OP_SARB + SHIFT;
264
    }
265
    FORCE_RET();
266
}
267

    
268
#if DATA_BITS == 16
269
/* XXX: overflow flag might be incorrect in some cases in shldw */
270
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
271
{
272
    int count;
273
    unsigned int res, tmp;
274
    count = PARAM1;
275
    T1 &= 0xffff;
276
    res = T1 | (T0 << 16);
277
    tmp = res >> (32 - count);
278
    res <<= count;
279
    if (count > 16)
280
        res |= T1 << (count - 16);
281
    T0 = res >> 16;
282
#ifdef MEM_WRITE
283
    glue(st, MEM_SUFFIX)(A0, T0);
284
#endif
285
    CC_SRC = tmp;
286
    CC_DST = T0;
287
}
288

    
289
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
290
{
291
    int count;
292
    unsigned int res, tmp;
293
    count = ECX & 0x1f;
294
    if (count) {
295
        T1 &= 0xffff;
296
        res = T1 | (T0 << 16);
297
        tmp = res >> (32 - count);
298
        res <<= count;
299
        if (count > 16)
300
          res |= T1 << (count - 16);
301
        T0 = res >> 16;
302
#ifdef MEM_WRITE
303
        glue(st, MEM_SUFFIX)(A0, T0);
304
#endif
305
        CC_SRC = tmp;
306
        CC_DST = T0;
307
        CC_OP = CC_OP_SARB + SHIFT;
308
    }
309
    FORCE_RET();
310
}
311

    
312
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
313
{
314
    int count;
315
    unsigned int res, tmp;
316

    
317
    count = PARAM1;
318
    res = (T0 & 0xffff) | (T1 << 16);
319
    tmp = res >> (count - 1);
320
    res >>= count;
321
    if (count > 16)
322
        res |= T1 << (32 - count);
323
    T0 = res;
324
#ifdef MEM_WRITE
325
    glue(st, MEM_SUFFIX)(A0, T0);
326
#endif
327
    CC_SRC = tmp;
328
    CC_DST = T0;
329
}
330

    
331

    
332
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
333
{
334
    int count;
335
    unsigned int res, tmp;
336

    
337
    count = ECX & 0x1f;
338
    if (count) {
339
        res = (T0 & 0xffff) | (T1 << 16);
340
        tmp = res >> (count - 1);
341
        res >>= count;
342
        if (count > 16)
343
            res |= T1 << (32 - count);
344
        T0 = res;
345
#ifdef MEM_WRITE
346
        glue(st, MEM_SUFFIX)(A0, T0);
347
#endif
348
        CC_SRC = tmp;
349
        CC_DST = T0;
350
        CC_OP = CC_OP_SARB + SHIFT;
351
    }
352
    FORCE_RET();
353
}
354
#endif
355

    
356
#if DATA_BITS >= 32
357
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
358
{
359
    int count;
360
    target_long tmp;
361

    
362
    count = PARAM1;
363
    T0 &= DATA_MASK;
364
    T1 &= DATA_MASK;
365
    tmp = T0 << (count - 1);
366
    T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
367
#ifdef MEM_WRITE
368
    glue(st, MEM_SUFFIX)(A0, T0);
369
#endif
370
    CC_SRC = tmp;
371
    CC_DST = T0;
372
}
373

    
374
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
375
{
376
    int count;
377
    target_long tmp;
378

    
379
    count = ECX & SHIFT1_MASK;
380
    if (count) {
381
        T0 &= DATA_MASK;
382
        T1 &= DATA_MASK;
383
        tmp = T0 << (count - 1);
384
        T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
385
#ifdef MEM_WRITE
386
        glue(st, MEM_SUFFIX)(A0, T0);
387
#endif
388
        CC_SRC = tmp;
389
        CC_DST = T0;
390
        CC_OP = CC_OP_SHLB + SHIFT;
391
    }
392
    FORCE_RET();
393
}
394

    
395
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
396
{
397
    int count;
398
    target_long tmp;
399

    
400
    count = PARAM1;
401
    T0 &= DATA_MASK;
402
    T1 &= DATA_MASK;
403
    tmp = T0 >> (count - 1);
404
    T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
405
#ifdef MEM_WRITE
406
    glue(st, MEM_SUFFIX)(A0, T0);
407
#endif
408
    CC_SRC = tmp;
409
    CC_DST = T0;
410
}
411

    
412

    
413
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
414
{
415
    int count;
416
    target_long tmp;
417

    
418
    count = ECX & SHIFT1_MASK;
419
    if (count) {
420
        T0 &= DATA_MASK;
421
        T1 &= DATA_MASK;
422
        tmp = T0 >> (count - 1);
423
        T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
424
#ifdef MEM_WRITE
425
        glue(st, MEM_SUFFIX)(A0, T0);
426
#endif
427
        CC_SRC = tmp;
428
        CC_DST = T0;
429
        CC_OP = CC_OP_SARB + SHIFT;
430
    }
431
    FORCE_RET();
432
}
433
#endif
434

    
435
/* carry add/sub (we only need to set CC_OP differently) */
436

    
437
void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void)
438
{
439
    int cf;
440
    cf = cc_table[CC_OP].compute_c();
441
    T0 = T0 + T1 + cf;
442
#ifdef MEM_WRITE
443
    glue(st, MEM_SUFFIX)(A0, T0);
444
#endif
445
    CC_SRC = T1;
446
    CC_DST = T0;
447
    CC_OP = CC_OP_ADDB + SHIFT + cf * 4;
448
}
449

    
450
void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void)
451
{
452
    int cf;
453
    cf = cc_table[CC_OP].compute_c();
454
    T0 = T0 - T1 - cf;
455
#ifdef MEM_WRITE
456
    glue(st, MEM_SUFFIX)(A0, T0);
457
#endif
458
    CC_SRC = T1;
459
    CC_DST = T0;
460
    CC_OP = CC_OP_SUBB + SHIFT + cf * 4;
461
}
462

    
463
void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void)
464
{
465
    target_ulong src, dst;
466

    
467
    src = T0;
468
    dst = EAX - T0;
469
    if ((DATA_TYPE)dst == 0) {
470
        T0 = T1;
471
#ifdef MEM_WRITE
472
        glue(st, MEM_SUFFIX)(A0, T0);
473
#endif
474
    } else {
475
        EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
476
    }
477
    CC_SRC = src;
478
    CC_DST = dst;
479
    FORCE_RET();
480
}
481

    
482
#undef MEM_SUFFIX
483
#undef MEM_WRITE