Revision b6abf97d

b/target-i386/cpu.h
476 476
    /* temporaries if we cannot store them in host registers */
477 477
    target_ulong t0, t1, t2;
478 478
#endif
479
    target_ulong t3;
479 480

  
480 481
    /* standard registers */
481 482
    target_ulong regs[CPU_NB_REGS];
......
727 728
    return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
728 729
}
729 730

  
731
typedef struct CCTable {
732
    int (*compute_all)(void); /* return all the flags */
733
    int (*compute_c)(void);  /* return the C flag */
734
} CCTable;
735

  
736
extern CCTable cc_table[];
737

  
730 738
#include "cpu-all.h"
731 739

  
732 740
#include "svm.h"
b/target-i386/exec.h
98 98
#include "cpu.h"
99 99
#include "exec-all.h"
100 100

  
101
typedef struct CCTable {
102
    int (*compute_all)(void); /* return all the flags */
103
    int (*compute_c)(void);  /* return the C flag */
104
} CCTable;
105

  
106
extern CCTable cc_table[];
107

  
108 101
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
109 102
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
110 103
void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
......
129 122
void OPPROTO op_movl_eflags_T0(void);
130 123
void OPPROTO op_movl_T0_eflags(void);
131 124

  
125
/* n must be a constant to be efficient */
126
static inline target_long lshift(target_long x, int n)
127
{
128
    if (n >= 0)
129
        return x << n;
130
    else
131
        return x >> (-n);
132
}
133

  
132 134
#include "helper.h"
133 135

  
134 136
static inline void svm_check_intercept(uint32_t type)
b/target-i386/helper.c
5220 5220
#define SHIFT 1
5221 5221
#include "ops_sse.h"
5222 5222

  
5223
#define SHIFT 0
5224
#include "helper_template.h"
5225
#undef SHIFT
5226

  
5227
#define SHIFT 1
5228
#include "helper_template.h"
5229
#undef SHIFT
5230

  
5231
#define SHIFT 2
5232
#include "helper_template.h"
5233
#undef SHIFT
5234

  
5235
#ifdef TARGET_X86_64
5236

  
5237
#define SHIFT 3
5238
#include "helper_template.h"
5239
#undef SHIFT
5240

  
5241
#endif
b/target-i386/helper.h
199 199
#define SHIFT 1
200 200
#include "ops_sse_header.h"
201 201

  
202
target_ulong helper_rclb(target_ulong t0, target_ulong t1);
203
target_ulong helper_rclw(target_ulong t0, target_ulong t1);
204
target_ulong helper_rcll(target_ulong t0, target_ulong t1);
205
target_ulong helper_rcrb(target_ulong t0, target_ulong t1);
206
target_ulong helper_rcrw(target_ulong t0, target_ulong t1);
207
target_ulong helper_rcrl(target_ulong t0, target_ulong t1);
208
#ifdef TARGET_X86_64
209
target_ulong helper_rclq(target_ulong t0, target_ulong t1);
210
target_ulong helper_rcrq(target_ulong t0, target_ulong t1);
211
#endif
212

  
b/target-i386/helper_template.h
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
target_ulong glue(helper_rcl, SUFFIX)(target_ulong t0, target_ulong t1)
54
{
55
    int count, eflags;
56
    target_ulong src;
57
    target_long res;
58

  
59
    count = t1 & SHIFT1_MASK;
60
#if DATA_BITS == 16
61
    count = rclw_table[count];
62
#elif DATA_BITS == 8
63
    count = rclb_table[count];
64
#endif
65
    if (count) {
66
        eflags = cc_table[CC_OP].compute_all();
67
        t0 &= DATA_MASK;
68
        src = t0;
69
        res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
70
        if (count > 1)
71
            res |= t0 >> (DATA_BITS + 1 - count);
72
        t0 = res;
73
        env->t3 = (eflags & ~(CC_C | CC_O)) |
74
            (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
75
            ((src >> (DATA_BITS - count)) & CC_C);
76
    } else {
77
        env->t3 = -1;
78
    }
79
    return t0;
80
}
81

  
82
target_ulong glue(helper_rcr, SUFFIX)(target_ulong t0, target_ulong t1)
83
{
84
    int count, eflags;
85
    target_ulong src;
86
    target_long res;
87

  
88
    count = t1 & SHIFT1_MASK;
89
#if DATA_BITS == 16
90
    count = rclw_table[count];
91
#elif DATA_BITS == 8
92
    count = rclb_table[count];
93
#endif
94
    if (count) {
95
        eflags = cc_table[CC_OP].compute_all();
96
        t0 &= DATA_MASK;
97
        src = t0;
98
        res = (t0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count));
99
        if (count > 1)
100
            res |= t0 << (DATA_BITS + 1 - count);
101
        t0 = res;
102
        env->t3 = (eflags & ~(CC_C | CC_O)) |
103
            (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
104
            ((src >> (count - 1)) & CC_C);
105
    } else {
106
        env->t3 = -1;
107
    }
108
    return t0;
109
}
110

  
111
#undef DATA_BITS
112
#undef SHIFT_MASK
113
#undef SHIFT1_MASK
114
#undef SIGN_MASK
115
#undef DATA_TYPE
116
#undef DATA_STYPE
117
#undef DATA_MASK
118
#undef SUFFIX
b/target-i386/op.c
21 21
#define ASM_SOFTMMU
22 22
#include "exec.h"
23 23

  
24
/* n must be a constant to be efficient */
25
static inline target_long lshift(target_long x, int n)
26
{
27
    if (n >= 0)
28
        return x << n;
29
    else
30
        return x >> (-n);
31
}
32

  
33 24
/* we define the various pieces of code used by the JIT */
34 25

  
35 26
#define REG EAX
......
132 123

  
133 124
#endif
134 125

  
135
/* operations with flags */
136

  
137
/* update flags with T0 and T1 (add/sub case) */
138
void OPPROTO op_update2_cc(void)
139
{
140
    CC_SRC = T1;
141
    CC_DST = T0;
142
}
143

  
144
/* update flags with T0 (logic operation case) */
145
void OPPROTO op_update1_cc(void)
146
{
147
    CC_DST = T0;
148
}
149

  
150
void OPPROTO op_update_neg_cc(void)
151
{
152
    CC_SRC = -T0;
153
    CC_DST = T0;
154
}
155

  
156
void OPPROTO op_cmpl_T0_T1_cc(void)
157
{
158
    CC_SRC = T1;
159
    CC_DST = T0 - T1;
160
}
161

  
162
void OPPROTO op_update_inc_cc(void)
163
{
164
    CC_SRC = cc_table[CC_OP].compute_c();
165
    CC_DST = T0;
166
}
167

  
168
void OPPROTO op_testl_T0_T1_cc(void)
169
{
170
    CC_DST = T0 & T1;
171
}
172

  
173
/* operations without flags */
174

  
175
void OPPROTO op_negl_T0(void)
176
{
177
    T0 = -T0;
178
}
179

  
180
void OPPROTO op_incl_T0(void)
181
{
182
    T0++;
183
}
184

  
185
void OPPROTO op_decl_T0(void)
186
{
187
    T0--;
188
}
189

  
190
void OPPROTO op_notl_T0(void)
191
{
192
    T0 = ~T0;
193
}
194

  
195 126
/* multiply/divide */
196 127

  
197 128
/* XXX: add eflags optimizations */
......
308 239
    A0 = (uint32_t)(A0 + (EAX & 0xff));
309 240
}
310 241

  
311
#ifdef WORDS_BIGENDIAN
312
typedef union UREG64 {
313
    struct { uint16_t v3, v2, v1, v0; } w;
314
    struct { uint32_t v1, v0; } l;
315
    uint64_t q;
316
} UREG64;
317
#else
318
typedef union UREG64 {
319
    struct { uint16_t v0, v1, v2, v3; } w;
320
    struct { uint32_t v0, v1; } l;
321
    uint64_t q;
322
} UREG64;
323
#endif
324

  
325
#define PARAMQ1 \
326
({\
327
    UREG64 __p;\
328
    __p.l.v1 = PARAM1;\
329
    __p.l.v0 = PARAM2;\
330
    __p.q;\
331
})
332

  
333 242
#ifdef TARGET_X86_64
334 243

  
335 244
void OPPROTO op_addq_A0_AL(void)
b/target-i386/ops_template.h
415 415
    T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
416 416
}
417 417

  
418
/* shifts */
419

  
420
void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
421
{
422
    int count;
423
    count = T1 & SHIFT1_MASK;
424
    T0 = T0 << count;
425
    FORCE_RET();
426
}
427

  
428
void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
429
{
430
    int count;
431
    count = T1 & SHIFT1_MASK;
432
    T0 &= DATA_MASK;
433
    T0 = T0 >> count;
434
    FORCE_RET();
435
}
436

  
437
void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
438
{
439
    int count;
440
    target_long src;
441

  
442
    count = T1 & SHIFT1_MASK;
443
    src = (DATA_STYPE)T0;
444
    T0 = src >> count;
445
    FORCE_RET();
446
}
447

  
448 418
#undef MEM_WRITE
449 419
#include "ops_template_mem.h"
450 420

  
b/target-i386/ops_template_mem.h
68 68

  
69 69
#endif
70 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 71
/* carry add/sub (we only need to set CC_OP differently) */
436 72

  
437 73
void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void)
b/target-i386/translate.c
58 58
//#define MACRO_TEST   1
59 59

  
60 60
/* global register indexes */
61
static TCGv cpu_env, cpu_T[2], cpu_A0;
61
static TCGv cpu_env, cpu_T[2], cpu_A0, cpu_cc_op, cpu_cc_src, cpu_cc_dst;
62
static TCGv cpu_T3;
62 63
/* local register indexes (only used inside old micro ops) */
63
static TCGv cpu_tmp0, cpu_tmp1, cpu_tmp2, cpu_tmp3, cpu_ptr0, cpu_ptr1;
64
static TCGv cpu_tmp0, cpu_tmp1_i64, cpu_tmp2_i32, cpu_tmp3_i32, cpu_tmp4, cpu_ptr0, cpu_ptr1;
65
static TCGv cpu_tmp5, cpu_tmp6;
64 66

  
65 67
#ifdef TARGET_X86_64
66 68
static int x86_64_hregs;
......
428 430

  
429 431
static inline void gen_op_set_cc_op(int32_t val)
430 432
{
431
    tcg_gen_movi_tl(cpu_tmp0, val);
432
    tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, cc_op));
433
    tcg_gen_movi_i32(cpu_cc_op, val);
433 434
}
434 435

  
435 436
static inline void gen_op_addl_A0_reg_sN(int shift, int reg)
......
556 557
#endif
557 558
};
558 559

  
559
#define DEF_SHIFT(SUFFIX)\
560
    {\
561
        gen_op_rolb ## SUFFIX ## _T0_T1_cc,\
562
        gen_op_rorb ## SUFFIX ## _T0_T1_cc,\
563
        gen_op_rclb ## SUFFIX ## _T0_T1_cc,\
564
        gen_op_rcrb ## SUFFIX ## _T0_T1_cc,\
565
        gen_op_shlb ## SUFFIX ## _T0_T1_cc,\
566
        gen_op_shrb ## SUFFIX ## _T0_T1_cc,\
567
        gen_op_shlb ## SUFFIX ## _T0_T1_cc,\
568
        gen_op_sarb ## SUFFIX ## _T0_T1_cc,\
569
    },\
570
    {\
571
        gen_op_rolw ## SUFFIX ## _T0_T1_cc,\
572
        gen_op_rorw ## SUFFIX ## _T0_T1_cc,\
573
        gen_op_rclw ## SUFFIX ## _T0_T1_cc,\
574
        gen_op_rcrw ## SUFFIX ## _T0_T1_cc,\
575
        gen_op_shlw ## SUFFIX ## _T0_T1_cc,\
576
        gen_op_shrw ## SUFFIX ## _T0_T1_cc,\
577
        gen_op_shlw ## SUFFIX ## _T0_T1_cc,\
578
        gen_op_sarw ## SUFFIX ## _T0_T1_cc,\
579
    },\
580
    {\
581
        gen_op_roll ## SUFFIX ## _T0_T1_cc,\
582
        gen_op_rorl ## SUFFIX ## _T0_T1_cc,\
583
        gen_op_rcll ## SUFFIX ## _T0_T1_cc,\
584
        gen_op_rcrl ## SUFFIX ## _T0_T1_cc,\
585
        gen_op_shll ## SUFFIX ## _T0_T1_cc,\
586
        gen_op_shrl ## SUFFIX ## _T0_T1_cc,\
587
        gen_op_shll ## SUFFIX ## _T0_T1_cc,\
588
        gen_op_sarl ## SUFFIX ## _T0_T1_cc,\
589
    },\
590
    {\
591
        X86_64_ONLY(gen_op_rolq ## SUFFIX ## _T0_T1_cc),\
592
        X86_64_ONLY(gen_op_rorq ## SUFFIX ## _T0_T1_cc),\
593
        X86_64_ONLY(gen_op_rclq ## SUFFIX ## _T0_T1_cc),\
594
        X86_64_ONLY(gen_op_rcrq ## SUFFIX ## _T0_T1_cc),\
595
        X86_64_ONLY(gen_op_shlq ## SUFFIX ## _T0_T1_cc),\
596
        X86_64_ONLY(gen_op_shrq ## SUFFIX ## _T0_T1_cc),\
597
        X86_64_ONLY(gen_op_shlq ## SUFFIX ## _T0_T1_cc),\
598
        X86_64_ONLY(gen_op_sarq ## SUFFIX ## _T0_T1_cc),\
599
    },
600

  
601
static GenOpFunc *gen_op_shift_T0_T1_cc[4][8] = {
602
    DEF_SHIFT( )
603
};
604

  
605
static GenOpFunc *gen_op_shift_mem_T0_T1_cc[3 * 4][8] = {
606
    DEF_SHIFT(_raw)
607
#ifndef CONFIG_USER_ONLY
608
    DEF_SHIFT(_kernel)
609
    DEF_SHIFT(_user)
610
#endif
611
};
612

  
613
#define DEF_SHIFTD(SUFFIX, op)\
614
    {\
615
        NULL,\
616
        NULL,\
617
    },\
618
    {\
619
        gen_op_shldw ## SUFFIX ## _T0_T1_ ## op ## _cc,\
620
        gen_op_shrdw ## SUFFIX ## _T0_T1_ ## op ## _cc,\
621
     },\
622
    {\
623
        gen_op_shldl ## SUFFIX ## _T0_T1_ ## op ## _cc,\
624
        gen_op_shrdl ## SUFFIX ## _T0_T1_ ## op ## _cc,\
625
    },\
626
    {\
627
X86_64_DEF(gen_op_shldq ## SUFFIX ## _T0_T1_ ## op ## _cc,\
628
           gen_op_shrdq ## SUFFIX ## _T0_T1_ ## op ## _cc,)\
629
    },
630

  
631
static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[4][2] = {
632
    DEF_SHIFTD(, im)
633
};
634

  
635
static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[4][2] = {
636
    DEF_SHIFTD(, ECX)
637
};
638

  
639
static GenOpFunc1 *gen_op_shiftd_mem_T0_T1_im_cc[3 * 4][2] = {
640
    DEF_SHIFTD(_raw, im)
641
#ifndef CONFIG_USER_ONLY
642
    DEF_SHIFTD(_kernel, im)
643
    DEF_SHIFTD(_user, im)
644
#endif
645
};
646

  
647
static GenOpFunc *gen_op_shiftd_mem_T0_T1_ECX_cc[3 * 4][2] = {
648
    DEF_SHIFTD(_raw, ECX)
649
#ifndef CONFIG_USER_ONLY
650
    DEF_SHIFTD(_kernel, ECX)
651
    DEF_SHIFTD(_user, ECX)
652
#endif
653
};
654

  
655 560
static GenOpFunc *gen_op_btx_T0_T1_cc[3][4] = {
656 561
    [0] = {
657 562
        gen_op_btw_T0_T1_cc,
......
933 838
            gen_op_set_cc_op(s->cc_op);
934 839
        gen_jmp_im(cur_eip);
935 840
        state_saved = 1;
936
        tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
841
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
937 842
        tcg_gen_helper_0_1(gen_check_io_func[ot],
938
                           cpu_tmp2);
843
                           cpu_tmp2_i32);
939 844
    }
940 845
    if(s->flags & (1ULL << INTERCEPT_IOIO_PROT)) {
941 846
        if (!state_saved) {
......
946 851
        }
947 852
        svm_flags |= (1 << (4 + ot));
948 853
        next_eip = s->pc - s->cs_base;
949
        tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
854
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
950 855
        tcg_gen_helper_0_3(helper_svm_check_io,
951
                           cpu_tmp2,
856
                           cpu_tmp2_i32,
952 857
                           tcg_const_i32(svm_flags),
953 858
                           tcg_const_i32(next_eip - cur_eip));
954 859
    }
......
984 889
    }
985 890
}
986 891

  
892
static void gen_op_update1_cc(void)
893
{
894
    tcg_gen_discard_tl(cpu_cc_src);
895
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
896
}
897

  
898
static void gen_op_update2_cc(void)
899
{
900
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
901
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
902
}
903

  
904
static inline void gen_op_cmpl_T0_T1_cc(void)
905
{
906
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
907
    tcg_gen_sub_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
908
}
909

  
910
static inline void gen_op_testl_T0_T1_cc(void)
911
{
912
    tcg_gen_discard_tl(cpu_cc_src);
913
    tcg_gen_and_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
914
}
915

  
916
static void gen_op_update_neg_cc(void)
917
{
918
    tcg_gen_neg_tl(cpu_cc_src, cpu_T[0]);
919
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
920
}
921

  
987 922
/* XXX: does not work with gdbstub "ice" single step - not a
988 923
   serious problem */
989 924
static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
......
1083 1018
    gen_op_movl_T0_0();
1084 1019
    gen_op_st_T0_A0(ot + s->mem_index);
1085 1020
    gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1086
    tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[1]);
1087
    tcg_gen_andi_i32(cpu_tmp2, cpu_tmp2, 0xffff);
1088
    tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[0], cpu_tmp2);
1021
    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1022
    tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1023
    tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[0], cpu_tmp2_i32);
1089 1024
    gen_op_st_T0_A0(ot + s->mem_index);
1090 1025
    gen_op_movl_T0_Dshift[ot]();
1091 1026
#ifdef TARGET_X86_64
......
1106 1041
    gen_op_ld_T0_A0(ot + s->mem_index);
1107 1042

  
1108 1043
    gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
1109
    tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[1]);
1110
    tcg_gen_andi_i32(cpu_tmp2, cpu_tmp2, 0xffff);
1111
    tcg_gen_trunc_tl_i32(cpu_tmp3, cpu_T[0]);
1112
    tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2, cpu_tmp3);
1044
    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
1045
    tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
1046
    tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);
1047
    tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2_i32, cpu_tmp3_i32);
1113 1048

  
1114 1049
    gen_op_movl_T0_Dshift[ot]();
1115 1050
#ifdef TARGET_X86_64
......
1390 1325
 the_end: ;
1391 1326
}
1392 1327

  
1328
/* compute eflags.C to reg */
1329
static void gen_compute_eflags_c(TCGv reg)
1330
{
1331
#if TCG_TARGET_REG_BITS == 32
1332
    tcg_gen_shli_i32(cpu_tmp2_i32, cpu_cc_op, 3);
1333
    tcg_gen_addi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 
1334
                     (long)cc_table + offsetof(CCTable, compute_c));
1335
    tcg_gen_ld_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0);
1336
    tcg_gen_call(&tcg_ctx, cpu_tmp2_i32, TCG_CALL_PURE, 
1337
                 1, &reg, 0, NULL);
1338
#else
1339
    tcg_gen_extu_i32_tl(cpu_tmp1_i64, cpu_cc_op);
1340
    tcg_gen_shli_i64(cpu_tmp1_i64, cpu_tmp1_i64, 4);
1341
    tcg_gen_addi_i64(cpu_tmp1_i64, cpu_tmp1_i64, 
1342
                     (long)cc_table + offsetof(CCTable, compute_c));
1343
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_tmp1_i64, 0);
1344
    tcg_gen_call(&tcg_ctx, cpu_tmp1_i64, TCG_CALL_PURE, 
1345
                 1, &cpu_tmp2_i32, 0, NULL);
1346
    tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
1347
#endif
1348
}
1349

  
1350
/* compute all eflags to cc_src */
1351
static void gen_compute_eflags(TCGv reg)
1352
{
1353
#if TCG_TARGET_REG_BITS == 32
1354
    tcg_gen_shli_i32(cpu_tmp2_i32, cpu_cc_op, 3);
1355
    tcg_gen_addi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 
1356
                     (long)cc_table + offsetof(CCTable, compute_all));
1357
    tcg_gen_ld_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0);
1358
    tcg_gen_call(&tcg_ctx, cpu_tmp2_i32, TCG_CALL_PURE, 
1359
                 1, &reg, 0, NULL);
1360
#else
1361
    tcg_gen_extu_i32_tl(cpu_tmp1_i64, cpu_cc_op);
1362
    tcg_gen_shli_i64(cpu_tmp1_i64, cpu_tmp1_i64, 4);
1363
    tcg_gen_addi_i64(cpu_tmp1_i64, cpu_tmp1_i64, 
1364
                     (long)cc_table + offsetof(CCTable, compute_all));
1365
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_tmp1_i64, 0);
1366
    tcg_gen_call(&tcg_ctx, cpu_tmp1_i64, TCG_CALL_PURE, 
1367
                 1, &cpu_tmp2_i32, 0, NULL);
1368
    tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
1369
#endif
1370
}
1371

  
1393 1372
/* if d == OR_TMP0, it means memory operand (address in A0) */
1394 1373
static void gen_inc(DisasContext *s1, int ot, int d, int c)
1395 1374
{
......
1400 1379
    if (s1->cc_op != CC_OP_DYNAMIC)
1401 1380
        gen_op_set_cc_op(s1->cc_op);
1402 1381
    if (c > 0) {
1403
        gen_op_incl_T0();
1382
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 1);
1404 1383
        s1->cc_op = CC_OP_INCB + ot;
1405 1384
    } else {
1406
        gen_op_decl_T0();
1385
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], -1);
1407 1386
        s1->cc_op = CC_OP_DECB + ot;
1408 1387
    }
1409 1388
    if (d != OR_TMP0)
1410 1389
        gen_op_mov_reg_T0(ot, d);
1411 1390
    else
1412 1391
        gen_op_st_T0_A0(ot + s1->mem_index);
1413
    gen_op_update_inc_cc();
1392
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1393
    gen_compute_eflags_c(cpu_cc_src);
1414 1394
}
1415 1395

  
1416
static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
1396
/* XXX: add faster immediate case */
1397
static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, 
1398
                            int is_right, int is_arith)
1417 1399
{
1418
    if (d != OR_TMP0)
1419
        gen_op_mov_TN_reg(ot, 0, d);
1400
    target_ulong mask;
1401
    int shift_label;
1402
    
1403
    if (ot == OT_QUAD)
1404
        mask = 0x3f;
1420 1405
    else
1421
        gen_op_ld_T0_A0(ot + s1->mem_index);
1422
    if (s != OR_TMP1)
1423
        gen_op_mov_TN_reg(ot, 1, s);
1424
    /* for zero counts, flags are not updated, so must do it dynamically */
1425
    if (s1->cc_op != CC_OP_DYNAMIC)
1426
        gen_op_set_cc_op(s1->cc_op);
1406
        mask = 0x1f;
1427 1407

  
1428
    if (d != OR_TMP0)
1429
        gen_op_shift_T0_T1_cc[ot][op]();
1408
    /* load */
1409
    if (op1 == OR_TMP0)
1410
        gen_op_ld_T0_A0(ot + s->mem_index);
1430 1411
    else
1431
        gen_op_shift_mem_T0_T1_cc[ot + s1->mem_index][op]();
1432
    if (d != OR_TMP0)
1433
        gen_op_mov_reg_T0(ot, d);
1434
    s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1412
        gen_op_mov_TN_reg(ot, 0, op1);
1413

  
1414
    tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask);
1415

  
1416
    tcg_gen_addi_tl(cpu_tmp5, cpu_T[1], -1);
1417

  
1418
    if (is_right) {
1419
        if (is_arith) {
1420
            switch(ot) {
1421
            case OT_BYTE:
1422
                tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
1423
                break;
1424
            case OT_WORD:
1425
                tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
1426
                break;
1427
            case OT_LONG:
1428
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1429
                break;
1430
            default:
1431
                break;
1432
            }
1433
            tcg_gen_sar_tl(cpu_T3, cpu_T[0], cpu_tmp5);
1434
            tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1435
        } else {
1436
            switch(ot) {
1437
            case OT_BYTE:
1438
                tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
1439
                break;
1440
            case OT_WORD:
1441
                tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
1442
                break;
1443
            case OT_LONG:
1444
                tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1445
                break;
1446
            default:
1447
                break;
1448
            }
1449
            tcg_gen_shr_tl(cpu_T3, cpu_T[0], cpu_tmp5);
1450
            tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1451
        }
1452
    } else {
1453
        tcg_gen_shl_tl(cpu_T3, cpu_T[0], cpu_tmp5);
1454
        tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1455
    }
1456

  
1457
    /* store */
1458
    if (op1 == OR_TMP0)
1459
        gen_op_st_T0_A0(ot + s->mem_index);
1460
    else
1461
        gen_op_mov_reg_T0(ot, op1);
1462
        
1463
    /* update eflags if non zero shift */
1464
    if (s->cc_op != CC_OP_DYNAMIC)
1465
        gen_op_set_cc_op(s->cc_op);
1466

  
1467
    shift_label = gen_new_label();
1468
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), shift_label);
1469

  
1470
    tcg_gen_mov_tl(cpu_cc_src, cpu_T3);
1471
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1472
    if (is_right)
1473
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
1474
    else
1475
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
1476
        
1477
    gen_set_label(shift_label);
1478
    s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1479
}
1480

  
1481
static inline void tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2)
1482
{
1483
    if (arg2 >= 0)
1484
        tcg_gen_shli_tl(ret, arg1, arg2);
1485
    else
1486
        tcg_gen_shri_tl(ret, arg1, -arg2);
1487
}
1488

  
1489
/* XXX: add faster immediate case */
1490
static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, 
1491
                          int is_right)
1492
{
1493
    target_ulong mask;
1494
    int label1, label2, data_bits;
1495
    
1496
    if (ot == OT_QUAD)
1497
        mask = 0x3f;
1498
    else
1499
        mask = 0x1f;
1500

  
1501
    /* load */
1502
    if (op1 == OR_TMP0)
1503
        gen_op_ld_T0_A0(ot + s->mem_index);
1504
    else
1505
        gen_op_mov_TN_reg(ot, 0, op1);
1506

  
1507
    tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask);
1508

  
1509
    /* Must test zero case to avoid using undefined behaviour in TCG
1510
       shifts. */
1511
    label1 = gen_new_label();
1512
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), label1);
1513
    
1514
    if (ot <= OT_WORD)
1515
        tcg_gen_andi_tl(cpu_tmp0, cpu_T[1], (1 << (3 + ot)) - 1);
1516
    else
1517
        tcg_gen_mov_tl(cpu_tmp0, cpu_T[1]);
1518
    
1519
    switch(ot) {
1520
    case OT_BYTE:
1521
        tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
1522
        break;
1523
    case OT_WORD:
1524
        tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
1525
        break;
1526
    case OT_LONG:
1527
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1528
        break;
1529
    default:
1530
        break;
1531
    }
1532
    tcg_gen_mov_tl(cpu_T3, cpu_T[0]);
1533

  
1534
    data_bits = 8 << ot;
1535
    /* XXX: rely on behaviour of shifts when operand 2 overflows (XXX:
1536
       fix TCG definition) */
1537
    if (is_right) {
1538
        tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_tmp0);
1539
        tcg_gen_sub_tl(cpu_tmp0, tcg_const_tl(data_bits), cpu_tmp0);
1540
        tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
1541
    } else {
1542
        tcg_gen_shl_tl(cpu_tmp4, cpu_T[0], cpu_tmp0);
1543
        tcg_gen_sub_tl(cpu_tmp0, tcg_const_tl(data_bits), cpu_tmp0);
1544
        tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
1545
    }
1546
    tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
1547

  
1548
    gen_set_label(label1);
1549
    /* store */
1550
    if (op1 == OR_TMP0)
1551
        gen_op_st_T0_A0(ot + s->mem_index);
1552
    else
1553
        gen_op_mov_reg_T0(ot, op1);
1554
    
1555
    /* update eflags */
1556
    if (s->cc_op != CC_OP_DYNAMIC)
1557
        gen_op_set_cc_op(s->cc_op);
1558

  
1559
    label2 = gen_new_label();
1560
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[1], tcg_const_tl(0), label2);
1561

  
1562
    gen_compute_eflags(cpu_cc_src);
1563
    tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
1564
    tcg_gen_xor_tl(cpu_tmp0, cpu_T3, cpu_T[0]);
1565
    tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
1566
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
1567
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
1568
    if (is_right) {
1569
        tcg_gen_shri_tl(cpu_T[0], cpu_T[0], data_bits - 1);
1570
    }
1571
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_C);
1572
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]);
1573
    
1574
    tcg_gen_discard_tl(cpu_cc_dst);
1575
    tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
1576
        
1577
    gen_set_label(label2);
1578
    s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1579
}
1580

  
1581
static void *helper_rotc[8] = {
1582
    helper_rclb,
1583
    helper_rclw,
1584
    helper_rcll,
1585
    X86_64_ONLY(helper_rclq),
1586
    helper_rcrb,
1587
    helper_rcrw,
1588
    helper_rcrl,
1589
    X86_64_ONLY(helper_rcrq),
1590
};
1591

  
1592
/* XXX: add faster immediate = 1 case */
1593
static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, 
1594
                           int is_right)
1595
{
1596
    int label1;
1597

  
1598
    if (s->cc_op != CC_OP_DYNAMIC)
1599
        gen_op_set_cc_op(s->cc_op);
1600

  
1601
    /* load */
1602
    if (op1 == OR_TMP0)
1603
        gen_op_ld_T0_A0(ot + s->mem_index);
1604
    else
1605
        gen_op_mov_TN_reg(ot, 0, op1);
1606
    
1607
    tcg_gen_helper_1_2(helper_rotc[ot + (is_right * 4)],
1608
                       cpu_T[0], cpu_T[0], cpu_T[1]);
1609
    /* store */
1610
    if (op1 == OR_TMP0)
1611
        gen_op_st_T0_A0(ot + s->mem_index);
1612
    else
1613
        gen_op_mov_reg_T0(ot, op1);
1614

  
1615
    /* update eflags */
1616
    label1 = gen_new_label();
1617
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T3, tcg_const_tl(-1), label1);
1618

  
1619
    tcg_gen_mov_tl(cpu_cc_src, cpu_T3);
1620
    tcg_gen_discard_tl(cpu_cc_dst);
1621
    tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
1622
        
1623
    gen_set_label(label1);
1624
    s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1625
}
1626

  
1627
/* XXX: add faster immediate case */
1628
static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1, 
1629
                                int is_right)
1630
{
1631
    int label1, label2, data_bits;
1632
    target_ulong mask;
1633

  
1634
    if (ot == OT_QUAD)
1635
        mask = 0x3f;
1636
    else
1637
        mask = 0x1f;
1638

  
1639
    /* load */
1640
    if (op1 == OR_TMP0)
1641
        gen_op_ld_T0_A0(ot + s->mem_index);
1642
    else
1643
        gen_op_mov_TN_reg(ot, 0, op1);
1644

  
1645
    tcg_gen_andi_tl(cpu_T3, cpu_T3, mask);
1646
    /* Must test zero case to avoid using undefined behaviour in TCG
1647
       shifts. */
1648
    label1 = gen_new_label();
1649
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T3, tcg_const_tl(0), label1);
1650
    
1651
    tcg_gen_addi_tl(cpu_tmp5, cpu_T3, -1);
1652
    if (ot == OT_WORD) {
1653
        /* Note: we implement the Intel behaviour for shift count > 16 */
1654
        if (is_right) {
1655
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
1656
            tcg_gen_shli_tl(cpu_tmp0, cpu_T[1], 16);
1657
            tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
1658
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1659

  
1660
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_tmp5);
1661
            
1662
            /* only needed if count > 16, but a test would complicate */
1663
            tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(32), cpu_T3);
1664
            tcg_gen_shl_tl(cpu_tmp0, cpu_T[0], cpu_tmp5);
1665

  
1666
            tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T3);
1667

  
1668
            tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
1669
        } else {
1670
            /* XXX: not optimal */
1671
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
1672
            tcg_gen_shli_tl(cpu_T[1], cpu_T[1], 16);
1673
            tcg_gen_or_tl(cpu_T[1], cpu_T[1], cpu_T[0]);
1674
            tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1675
            
1676
            tcg_gen_shl_tl(cpu_tmp4, cpu_T[0], cpu_tmp5);
1677
            tcg_gen_sub_tl(cpu_tmp0, tcg_const_tl(32), cpu_tmp5);
1678
            tcg_gen_shr_tl(cpu_tmp6, cpu_T[1], cpu_tmp0);
1679
            tcg_gen_or_tl(cpu_tmp4, cpu_tmp4, cpu_tmp6);
1680

  
1681
            tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T3);
1682
            tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(32), cpu_T3);
1683
            tcg_gen_shr_tl(cpu_T[1], cpu_T[1], cpu_tmp5);
1684
            tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1685
        }
1686
    } else {
1687
        data_bits = 8 << ot;
1688
        if (is_right) {
1689
            if (ot == OT_LONG)
1690
                tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1691

  
1692
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_tmp5);
1693

  
1694
            tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T3);
1695
            tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(data_bits), cpu_T3);
1696
            tcg_gen_shl_tl(cpu_T[1], cpu_T[1], cpu_tmp5);
1697
            tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1698
            
1699
        } else {
1700
            if (ot == OT_LONG)
1701
                tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1702

  
1703
            tcg_gen_shl_tl(cpu_tmp4, cpu_T[0], cpu_tmp5);
1704
            
1705
            tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T3);
1706
            tcg_gen_sub_tl(cpu_tmp5, tcg_const_tl(data_bits), cpu_T3);
1707
            tcg_gen_shr_tl(cpu_T[1], cpu_T[1], cpu_tmp5);
1708
            tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1709
        }
1710
    }
1711
    tcg_gen_mov_tl(cpu_T[1], cpu_tmp4);
1712

  
1713
    gen_set_label(label1);
1714
    /* store */
1715
    if (op1 == OR_TMP0)
1716
        gen_op_st_T0_A0(ot + s->mem_index);
1717
    else
1718
        gen_op_mov_reg_T0(ot, op1);
1719
    
1720
    /* update eflags */
1721
    if (s->cc_op != CC_OP_DYNAMIC)
1722
        gen_op_set_cc_op(s->cc_op);
1723

  
1724
    label2 = gen_new_label();
1725
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T3, tcg_const_tl(0), label2);
1726

  
1727
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
1728
    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
1729
    if (is_right) {
1730
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
1731
    } else {
1732
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
1733
    }
1734
    gen_set_label(label2);
1735
    s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1736
}
1737

  
1738
static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
1739
{
1740
    if (s != OR_TMP1)
1741
        gen_op_mov_TN_reg(ot, 1, s);
1742
    switch(op) {
1743
    case OP_ROL:
1744
        gen_rot_rm_T1(s1, ot, d, 0);
1745
        break;
1746
    case OP_ROR:
1747
        gen_rot_rm_T1(s1, ot, d, 1);
1748
        break;
1749
    case OP_SHL:
1750
    case OP_SHL1:
1751
        gen_shift_rm_T1(s1, ot, d, 0, 0);
1752
        break;
1753
    case OP_SHR:
1754
        gen_shift_rm_T1(s1, ot, d, 1, 0);
1755
        break;
1756
    case OP_SAR:
1757
        gen_shift_rm_T1(s1, ot, d, 1, 1);
1758
        break;
1759
    case OP_RCL:
1760
        gen_rotc_rm_T1(s1, ot, d, 0);
1761
        break;
1762
    case OP_RCR:
1763
        gen_rotc_rm_T1(s1, ot, d, 1);
1764
        break;
1765
    }
1435 1766
}
1436 1767

  
1437 1768
static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
......
1987 2318
        if (s->cc_op != CC_OP_DYNAMIC)
1988 2319
            gen_op_set_cc_op(s->cc_op);
1989 2320
        gen_jmp_im(cur_eip);
1990
        tcg_gen_trunc_tl_i32(cpu_tmp2, cpu_T[0]);
1991
        tcg_gen_helper_0_2(helper_load_seg, tcg_const_i32(seg_reg), cpu_tmp2);
2321
        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
2322
        tcg_gen_helper_0_2(helper_load_seg, tcg_const_i32(seg_reg), cpu_tmp2_i32);
1992 2323
        /* abort translation because the addseg value may change or
1993 2324
           because ss32 may change. For R_SS, translation must always
1994 2325
           stop as a special handling must be done to disable hardware
......
2373 2704
static inline void gen_ldq_env_A0(int idx, int offset)
2374 2705
{
2375 2706
    int mem_index = (idx >> 2) - 1;
2376
    tcg_gen_qemu_ld64(cpu_tmp1, cpu_A0, mem_index);
2377
    tcg_gen_st_i64(cpu_tmp1, cpu_env, offset);
2707
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2708
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
2378 2709
}
2379 2710

  
2380 2711
static inline void gen_stq_env_A0(int idx, int offset)
2381 2712
{
2382 2713
    int mem_index = (idx >> 2) - 1;
2383
    tcg_gen_ld_i64(cpu_tmp1, cpu_env, offset);
2384
    tcg_gen_qemu_st64(cpu_tmp1, cpu_A0, mem_index);
2714
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
2715
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
2385 2716
}
2386 2717

  
2387 2718
static inline void gen_ldo_env_A0(int idx, int offset)
2388 2719
{
2389 2720
    int mem_index = (idx >> 2) - 1;
2390
    tcg_gen_qemu_ld64(cpu_tmp1, cpu_A0, mem_index);
2391
    tcg_gen_st_i64(cpu_tmp1, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2721
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
2722
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2392 2723
    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
2393
    tcg_gen_qemu_ld64(cpu_tmp1, cpu_tmp0, mem_index);
2394
    tcg_gen_st_i64(cpu_tmp1, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2724
    tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_tmp0, mem_index);
2725
    tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2395 2726
}
2396 2727

  
2397 2728
static inline void gen_sto_env_A0(int idx, int offset)
2398 2729
{
2399 2730
    int mem_index = (idx >> 2) - 1;
2400
    tcg_gen_ld_i64(cpu_tmp1, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2401
    tcg_gen_qemu_st64(cpu_tmp1, cpu_A0, mem_index);
2731
    tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2732
    tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff