Statistics
| Branch: | Revision:

root / target-i386 / ops_template_mem.h @ 2ee73ac3

History | View | Annotate | Download (10.4 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
#endif
32

    
33
#elif MEM_WRITE == 1
34

    
35
#if DATA_BITS == 8
36
#define MEM_SUFFIX b_kernel
37
#elif DATA_BITS == 16
38
#define MEM_SUFFIX w_kernel
39
#elif DATA_BITS == 32
40
#define MEM_SUFFIX l_kernel
41
#endif
42

    
43
#elif MEM_WRITE == 2
44

    
45
#if DATA_BITS == 8
46
#define MEM_SUFFIX b_user
47
#elif DATA_BITS == 16
48
#define MEM_SUFFIX w_user
49
#elif DATA_BITS == 32
50
#define MEM_SUFFIX l_user
51
#endif
52

    
53
#else
54

    
55
#error invalid MEM_WRITE
56

    
57
#endif
58

    
59
#else
60

    
61
#define MEM_SUFFIX SUFFIX
62

    
63
#endif
64

    
65
void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void)
66
{
67
    int count, src;
68
    count = T1 & SHIFT_MASK;
69
    if (count) {
70
        src = T0;
71
        T0 &= DATA_MASK;
72
        T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
73
#ifdef MEM_WRITE
74
        glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
75
#else
76
        /* gcc 3.2 workaround. This is really a bug in gcc. */
77
        asm volatile("" : : "r" (T0));
78
#endif
79
        CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) | 
80
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
81
            (T0 & CC_C);
82
        CC_OP = CC_OP_EFLAGS;
83
    }
84
    FORCE_RET();
85
}
86

    
87
void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1_cc)(void)
88
{
89
    int count, src;
90
    count = T1 & SHIFT_MASK;
91
    if (count) {
92
        src = T0;
93
        T0 &= DATA_MASK;
94
        T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
95
#ifdef MEM_WRITE
96
        glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
97
#else
98
        /* gcc 3.2 workaround. This is really a bug in gcc. */
99
        asm volatile("" : : "r" (T0));
100
#endif
101
        CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
102
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
103
            ((T0 >> (DATA_BITS - 1)) & CC_C);
104
        CC_OP = CC_OP_EFLAGS;
105
    }
106
    FORCE_RET();
107
}
108

    
109
void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1)(void)
110
{
111
    int count;
112
    count = T1 & SHIFT_MASK;
113
    if (count) {
114
        T0 &= DATA_MASK;
115
        T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
116
#ifdef MEM_WRITE
117
        glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
118
#endif
119
    }
120
    FORCE_RET();
121
}
122

    
123
void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1)(void)
124
{
125
    int count;
126
    count = T1 & SHIFT_MASK;
127
    if (count) {
128
        T0 &= DATA_MASK;
129
        T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
130
#ifdef MEM_WRITE
131
        glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
132
#endif
133
    }
134
    FORCE_RET();
135
}
136

    
137
void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
138
{
139
    int count, res, eflags;
140
    unsigned int src;
141

    
142
    count = T1 & 0x1f;
143
#if DATA_BITS == 16
144
    count = rclw_table[count];
145
#elif DATA_BITS == 8
146
    count = rclb_table[count];
147
#endif
148
    if (count) {
149
        eflags = cc_table[CC_OP].compute_all();
150
        T0 &= DATA_MASK;
151
        src = T0;
152
        res = (T0 << count) | ((eflags & CC_C) << (count - 1));
153
        if (count > 1)
154
            res |= T0 >> (DATA_BITS + 1 - count);
155
        T0 = res;
156
#ifdef MEM_WRITE
157
        glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
158
#endif
159
        CC_SRC = (eflags & ~(CC_C | CC_O)) |
160
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
161
            ((src >> (DATA_BITS - count)) & CC_C);
162
        CC_OP = CC_OP_EFLAGS;
163
    }
164
    FORCE_RET();
165
}
166

    
167
void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
168
{
169
    int count, res, eflags;
170
    unsigned int src;
171

    
172
    count = T1 & 0x1f;
173
#if DATA_BITS == 16
174
    count = rclw_table[count];
175
#elif DATA_BITS == 8
176
    count = rclb_table[count];
177
#endif
178
    if (count) {
179
        eflags = cc_table[CC_OP].compute_all();
180
        T0 &= DATA_MASK;
181
        src = T0;
182
        res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
183
        if (count > 1)
184
            res |= T0 << (DATA_BITS + 1 - count);
185
        T0 = res;
186
#ifdef MEM_WRITE
187
        glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
188
#endif
189
        CC_SRC = (eflags & ~(CC_C | CC_O)) |
190
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
191
            ((src >> (count - 1)) & CC_C);
192
        CC_OP = CC_OP_EFLAGS;
193
    }
194
    FORCE_RET();
195
}
196

    
197
void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void)
198
{
199
    int count, src;
200
    count = T1 & 0x1f;
201
    if (count) {
202
        src = (DATA_TYPE)T0 << (count - 1);
203
        T0 = T0 << count;
204
#ifdef MEM_WRITE
205
        glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
206
#endif
207
        CC_SRC = src;
208
        CC_DST = T0;
209
        CC_OP = CC_OP_SHLB + SHIFT;
210
    }
211
    FORCE_RET();
212
}
213

    
214
void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void)
215
{
216
    int count, src;
217
    count = T1 & 0x1f;
218
    if (count) {
219
        T0 &= DATA_MASK;
220
        src = T0 >> (count - 1);
221
        T0 = T0 >> count;
222
#ifdef MEM_WRITE
223
        glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
224
#endif
225
        CC_SRC = src;
226
        CC_DST = T0;
227
        CC_OP = CC_OP_SARB + SHIFT;
228
    }
229
    FORCE_RET();
230
}
231

    
232
void OPPROTO glue(glue(op_sar, MEM_SUFFIX), _T0_T1_cc)(void)
233
{
234
    int count, src;
235
    count = T1 & 0x1f;
236
    if (count) {
237
        src = (DATA_STYPE)T0;
238
        T0 = src >> count;
239
        src = src >> (count - 1);
240
#ifdef MEM_WRITE
241
        glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
242
#endif
243
        CC_SRC = src;
244
        CC_DST = T0;
245
        CC_OP = CC_OP_SARB + SHIFT;
246
    }
247
    FORCE_RET();
248
}
249

    
250
#if DATA_BITS == 16
251
/* XXX: overflow flag might be incorrect in some cases in shldw */
252
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
253
{
254
    int count;
255
    unsigned int res, tmp;
256
    count = PARAM1;
257
    T1 &= 0xffff;
258
    res = T1 | (T0 << 16);
259
    tmp = res >> (32 - count);
260
    res <<= count;
261
    if (count > 16)
262
        res |= T1 << (count - 16);
263
    T0 = res >> 16;
264
#ifdef MEM_WRITE
265
    glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
266
#endif
267
    CC_SRC = tmp;
268
    CC_DST = T0;
269
}
270

    
271
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
272
{
273
    int count;
274
    unsigned int res, tmp;
275
    count = ECX & 0x1f;
276
    if (count) {
277
        T1 &= 0xffff;
278
        res = T1 | (T0 << 16);
279
        tmp = res >> (32 - count);
280
        res <<= count;
281
        if (count > 16)
282
          res |= T1 << (count - 16);
283
        T0 = res >> 16;
284
#ifdef MEM_WRITE
285
        glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
286
#endif
287
        CC_SRC = tmp;
288
        CC_DST = T0;
289
        CC_OP = CC_OP_SARB + SHIFT;
290
    }
291
    FORCE_RET();
292
}
293

    
294
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
295
{
296
    int count;
297
    unsigned int res, tmp;
298

    
299
    count = PARAM1;
300
    res = (T0 & 0xffff) | (T1 << 16);
301
    tmp = res >> (count - 1);
302
    res >>= count;
303
    if (count > 16)
304
        res |= T1 << (32 - count);
305
    T0 = res;
306
#ifdef MEM_WRITE
307
    glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
308
#endif
309
    CC_SRC = tmp;
310
    CC_DST = T0;
311
}
312

    
313

    
314
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
315
{
316
    int count;
317
    unsigned int res, tmp;
318

    
319
    count = ECX & 0x1f;
320
    if (count) {
321
        res = (T0 & 0xffff) | (T1 << 16);
322
        tmp = res >> (count - 1);
323
        res >>= count;
324
        if (count > 16)
325
            res |= T1 << (32 - count);
326
        T0 = res;
327
#ifdef MEM_WRITE
328
        glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
329
#endif
330
        CC_SRC = tmp;
331
        CC_DST = T0;
332
        CC_OP = CC_OP_SARB + SHIFT;
333
    }
334
    FORCE_RET();
335
}
336
#endif
337

    
338
#if DATA_BITS == 32
339
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
340
{
341
    int count, tmp;
342
    count = PARAM1;
343
    T0 &= DATA_MASK;
344
    T1 &= DATA_MASK;
345
    tmp = T0 << (count - 1);
346
    T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
347
#ifdef MEM_WRITE
348
    glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
349
#endif
350
    CC_SRC = tmp;
351
    CC_DST = T0;
352
}
353

    
354
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
355
{
356
    int count, tmp;
357
    count = ECX & 0x1f;
358
    if (count) {
359
        T0 &= DATA_MASK;
360
        T1 &= DATA_MASK;
361
        tmp = T0 << (count - 1);
362
        T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
363
#ifdef MEM_WRITE
364
        glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
365
#endif
366
        CC_SRC = tmp;
367
        CC_DST = T0;
368
        CC_OP = CC_OP_SHLB + SHIFT;
369
    }
370
    FORCE_RET();
371
}
372

    
373
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
374
{
375
    int count, tmp;
376
    count = PARAM1;
377
    T0 &= DATA_MASK;
378
    T1 &= DATA_MASK;
379
    tmp = T0 >> (count - 1);
380
    T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
381
#ifdef MEM_WRITE
382
    glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
383
#endif
384
    CC_SRC = tmp;
385
    CC_DST = T0;
386
}
387

    
388

    
389
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
390
{
391
    int count, tmp;
392
    count = ECX & 0x1f;
393
    if (count) {
394
        T0 &= DATA_MASK;
395
        T1 &= DATA_MASK;
396
        tmp = T0 >> (count - 1);
397
        T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
398
#ifdef MEM_WRITE
399
        glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
400
#endif
401
        CC_SRC = tmp;
402
        CC_DST = T0;
403
        CC_OP = CC_OP_SARB + SHIFT;
404
    }
405
    FORCE_RET();
406
}
407
#endif
408

    
409
/* carry add/sub (we only need to set CC_OP differently) */
410

    
411
void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void)
412
{
413
    int cf;
414
    cf = cc_table[CC_OP].compute_c();
415
    T0 = T0 + T1 + cf;
416
#ifdef MEM_WRITE
417
    glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
418
#endif
419
    CC_SRC = T1;
420
    CC_DST = T0;
421
    CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
422
}
423

    
424
void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void)
425
{
426
    int cf;
427
    cf = cc_table[CC_OP].compute_c();
428
    T0 = T0 - T1 - cf;
429
#ifdef MEM_WRITE
430
    glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
431
#endif
432
    CC_SRC = T1;
433
    CC_DST = T0;
434
    CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
435
}
436

    
437
void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void)
438
{
439
    unsigned int src, dst;
440

    
441
    src = T0;
442
    dst = EAX - T0;
443
    if ((DATA_TYPE)dst == 0) {
444
        T0 = T1;
445
#ifdef MEM_WRITE
446
        glue(st, MEM_SUFFIX)((uint8_t *)A0, T0);
447
#endif
448
    } else {
449
        EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
450
    }
451
    CC_SRC = src;
452
    CC_DST = dst;
453
    FORCE_RET();
454
}
455

    
456
#undef MEM_SUFFIX
457
#undef MEM_WRITE