Statistics
| Branch: | Revision:

root / target-i386 / op.c @ 07be379f

History | View | Annotate | Download (8.9 kB)

1
/*
2
 *  i386 micro operations
3
 *
4
 *  Copyright (c) 2003 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
#define ASM_SOFTMMU
22
#include "exec.h"
23

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

    
26
#define REG EAX
27
#define REGNAME _EAX
28
#include "opreg_template.h"
29
#undef REG
30
#undef REGNAME
31

    
32
#define REG ECX
33
#define REGNAME _ECX
34
#include "opreg_template.h"
35
#undef REG
36
#undef REGNAME
37

    
38
#define REG EDX
39
#define REGNAME _EDX
40
#include "opreg_template.h"
41
#undef REG
42
#undef REGNAME
43

    
44
#define REG EBX
45
#define REGNAME _EBX
46
#include "opreg_template.h"
47
#undef REG
48
#undef REGNAME
49

    
50
#define REG ESP
51
#define REGNAME _ESP
52
#include "opreg_template.h"
53
#undef REG
54
#undef REGNAME
55

    
56
#define REG EBP
57
#define REGNAME _EBP
58
#include "opreg_template.h"
59
#undef REG
60
#undef REGNAME
61

    
62
#define REG ESI
63
#define REGNAME _ESI
64
#include "opreg_template.h"
65
#undef REG
66
#undef REGNAME
67

    
68
#define REG EDI
69
#define REGNAME _EDI
70
#include "opreg_template.h"
71
#undef REG
72
#undef REGNAME
73

    
74
#ifdef TARGET_X86_64
75

    
76
#define REG (env->regs[8])
77
#define REGNAME _R8
78
#include "opreg_template.h"
79
#undef REG
80
#undef REGNAME
81

    
82
#define REG (env->regs[9])
83
#define REGNAME _R9
84
#include "opreg_template.h"
85
#undef REG
86
#undef REGNAME
87

    
88
#define REG (env->regs[10])
89
#define REGNAME _R10
90
#include "opreg_template.h"
91
#undef REG
92
#undef REGNAME
93

    
94
#define REG (env->regs[11])
95
#define REGNAME _R11
96
#include "opreg_template.h"
97
#undef REG
98
#undef REGNAME
99

    
100
#define REG (env->regs[12])
101
#define REGNAME _R12
102
#include "opreg_template.h"
103
#undef REG
104
#undef REGNAME
105

    
106
#define REG (env->regs[13])
107
#define REGNAME _R13
108
#include "opreg_template.h"
109
#undef REG
110
#undef REGNAME
111

    
112
#define REG (env->regs[14])
113
#define REGNAME _R14
114
#include "opreg_template.h"
115
#undef REG
116
#undef REGNAME
117

    
118
#define REG (env->regs[15])
119
#define REGNAME _R15
120
#include "opreg_template.h"
121
#undef REG
122
#undef REGNAME
123

    
124
#endif
125

    
126
/* multiple size ops */
127

    
128
#define ldul ldl
129

    
130
#define SHIFT 0
131
#include "ops_template.h"
132
#undef SHIFT
133

    
134
#define SHIFT 1
135
#include "ops_template.h"
136
#undef SHIFT
137

    
138
#define SHIFT 2
139
#include "ops_template.h"
140
#undef SHIFT
141

    
142
#ifdef TARGET_X86_64
143

    
144
#define SHIFT 3
145
#include "ops_template.h"
146
#undef SHIFT
147

    
148
#endif
149

    
150
/* segment handling */
151

    
152
/* faster VM86 version */
153
void OPPROTO op_movl_seg_T0_vm(void)
154
{
155
    int selector;
156
    SegmentCache *sc;
157

    
158
    selector = T0 & 0xffff;
159
    /* env->segs[] access */
160
    sc = (SegmentCache *)((char *)env + PARAM1);
161
    sc->selector = selector;
162
    sc->base = (selector << 4);
163
}
164

    
165
void OPPROTO op_movl_T0_seg(void)
166
{
167
    T0 = env->segs[PARAM1].selector;
168
}
169

    
170
void OPPROTO op_lsl(void)
171
{
172
    uint32_t val;
173
    val = helper_lsl(T0);
174
    if (CC_SRC & CC_Z)
175
        T1 = val;
176
    FORCE_RET();
177
}
178

    
179
void OPPROTO op_lar(void)
180
{
181
    uint32_t val;
182
    val = helper_lar(T0);
183
    if (CC_SRC & CC_Z)
184
        T1 = val;
185
    FORCE_RET();
186
}
187

    
188
void OPPROTO op_verr(void)
189
{
190
    helper_verr(T0);
191
}
192

    
193
void OPPROTO op_verw(void)
194
{
195
    helper_verw(T0);
196
}
197

    
198
void OPPROTO op_arpl(void)
199
{
200
    if ((T0 & 3) < (T1 & 3)) {
201
        /* XXX: emulate bug or 0xff3f0000 oring as in bochs ? */
202
        T0 = (T0 & ~3) | (T1 & 3);
203
        T1 = CC_Z;
204
   } else {
205
        T1 = 0;
206
    }
207
    FORCE_RET();
208
}
209

    
210
void OPPROTO op_arpl_update(void)
211
{
212
    int eflags;
213
    eflags = cc_table[CC_OP].compute_all();
214
    CC_SRC = (eflags & ~CC_Z) | T1;
215
}
216

    
217
void OPPROTO op_movl_T0_env(void)
218
{
219
    T0 = *(uint32_t *)((char *)env + PARAM1);
220
}
221

    
222
void OPPROTO op_movl_env_T0(void)
223
{
224
    *(uint32_t *)((char *)env + PARAM1) = T0;
225
}
226

    
227
void OPPROTO op_movl_env_T1(void)
228
{
229
    *(uint32_t *)((char *)env + PARAM1) = T1;
230
}
231

    
232
void OPPROTO op_movtl_T0_env(void)
233
{
234
    T0 = *(target_ulong *)((char *)env + PARAM1);
235
}
236

    
237
void OPPROTO op_movtl_env_T0(void)
238
{
239
    *(target_ulong *)((char *)env + PARAM1) = T0;
240
}
241

    
242
void OPPROTO op_movtl_T1_env(void)
243
{
244
    T1 = *(target_ulong *)((char *)env + PARAM1);
245
}
246

    
247
void OPPROTO op_movtl_env_T1(void)
248
{
249
    *(target_ulong *)((char *)env + PARAM1) = T1;
250
}
251

    
252
/* flags handling */
253

    
254
void OPPROTO op_jmp_label(void)
255
{
256
    GOTO_LABEL_PARAM(1);
257
}
258

    
259
void OPPROTO op_jnz_T0_label(void)
260
{
261
    if (T0)
262
        GOTO_LABEL_PARAM(1);
263
    FORCE_RET();
264
}
265

    
266
/* slow set cases (compute x86 flags) */
267
void OPPROTO op_seto_T0_cc(void)
268
{
269
    int eflags;
270
    eflags = cc_table[CC_OP].compute_all();
271
    T0 = (eflags >> 11) & 1;
272
}
273

    
274
void OPPROTO op_setb_T0_cc(void)
275
{
276
    T0 = cc_table[CC_OP].compute_c();
277
}
278

    
279
void OPPROTO op_setz_T0_cc(void)
280
{
281
    int eflags;
282
    eflags = cc_table[CC_OP].compute_all();
283
    T0 = (eflags >> 6) & 1;
284
}
285

    
286
void OPPROTO op_setbe_T0_cc(void)
287
{
288
    int eflags;
289
    eflags = cc_table[CC_OP].compute_all();
290
    T0 = (eflags & (CC_Z | CC_C)) != 0;
291
}
292

    
293
void OPPROTO op_sets_T0_cc(void)
294
{
295
    int eflags;
296
    eflags = cc_table[CC_OP].compute_all();
297
    T0 = (eflags >> 7) & 1;
298
}
299

    
300
void OPPROTO op_setp_T0_cc(void)
301
{
302
    int eflags;
303
    eflags = cc_table[CC_OP].compute_all();
304
    T0 = (eflags >> 2) & 1;
305
}
306

    
307
void OPPROTO op_setl_T0_cc(void)
308
{
309
    int eflags;
310
    eflags = cc_table[CC_OP].compute_all();
311
    T0 = ((eflags ^ (eflags >> 4)) >> 7) & 1;
312
}
313

    
314
void OPPROTO op_setle_T0_cc(void)
315
{
316
    int eflags;
317
    eflags = cc_table[CC_OP].compute_all();
318
    T0 = (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) != 0;
319
}
320

    
321
void OPPROTO op_xor_T0_1(void)
322
{
323
    T0 ^= 1;
324
}
325

    
326
/* XXX: clear VIF/VIP in all ops ? */
327

    
328
void OPPROTO op_movl_eflags_T0(void)
329
{
330
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK));
331
}
332

    
333
void OPPROTO op_movw_eflags_T0(void)
334
{
335
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff);
336
}
337

    
338
void OPPROTO op_movl_eflags_T0_io(void)
339
{
340
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK));
341
}
342

    
343
void OPPROTO op_movw_eflags_T0_io(void)
344
{
345
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff);
346
}
347

    
348
void OPPROTO op_movl_eflags_T0_cpl0(void)
349
{
350
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK));
351
}
352

    
353
void OPPROTO op_movw_eflags_T0_cpl0(void)
354
{
355
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff);
356
}
357

    
358
#if 0
359
/* vm86plus version */
360
void OPPROTO op_movw_eflags_T0_vm(void)
361
{
362
    int eflags;
363
    eflags = T0;
364
    CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
365
    DF = 1 - (2 * ((eflags >> 10) & 1));
366
    /* we also update some system flags as in user mode */
367
    env->eflags = (env->eflags & ~(FL_UPDATE_MASK16 | VIF_MASK)) |
368
        (eflags & FL_UPDATE_MASK16);
369
    if (eflags & IF_MASK) {
370
        env->eflags |= VIF_MASK;
371
        if (env->eflags & VIP_MASK) {
372
            EIP = PARAM1;
373
            raise_exception(EXCP0D_GPF);
374
        }
375
    }
376
    FORCE_RET();
377
}
378

379
void OPPROTO op_movl_eflags_T0_vm(void)
380
{
381
    int eflags;
382
    eflags = T0;
383
    CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
384
    DF = 1 - (2 * ((eflags >> 10) & 1));
385
    /* we also update some system flags as in user mode */
386
    env->eflags = (env->eflags & ~(FL_UPDATE_MASK32 | VIF_MASK)) |
387
        (eflags & FL_UPDATE_MASK32);
388
    if (eflags & IF_MASK) {
389
        env->eflags |= VIF_MASK;
390
        if (env->eflags & VIP_MASK) {
391
            EIP = PARAM1;
392
            raise_exception(EXCP0D_GPF);
393
        }
394
    }
395
    FORCE_RET();
396
}
397
#endif
398

    
399
/* XXX: compute only O flag */
400
void OPPROTO op_movb_eflags_T0(void)
401
{
402
    int of;
403
    of = cc_table[CC_OP].compute_all() & CC_O;
404
    CC_SRC = (T0 & (CC_S | CC_Z | CC_A | CC_P | CC_C)) | of;
405
}
406

    
407
void OPPROTO op_movl_T0_eflags(void)
408
{
409
    int eflags;
410
    eflags = cc_table[CC_OP].compute_all();
411
    eflags |= (DF & DF_MASK);
412
    eflags |= env->eflags & ~(VM_MASK | RF_MASK);
413
    T0 = eflags;
414
}
415

    
416
/* vm86plus version */
417
#if 0
418
void OPPROTO op_movl_T0_eflags_vm(void)
419
{
420
    int eflags;
421
    eflags = cc_table[CC_OP].compute_all();
422
    eflags |= (DF & DF_MASK);
423
    eflags |= env->eflags & ~(VM_MASK | RF_MASK | IF_MASK);
424
    if (env->eflags & VIF_MASK)
425
        eflags |= IF_MASK;
426
    T0 = eflags;
427
}
428
#endif
429

    
430
void OPPROTO op_clc(void)
431
{
432
    int eflags;
433
    eflags = cc_table[CC_OP].compute_all();
434
    eflags &= ~CC_C;
435
    CC_SRC = eflags;
436
}
437

    
438
void OPPROTO op_stc(void)
439
{
440
    int eflags;
441
    eflags = cc_table[CC_OP].compute_all();
442
    eflags |= CC_C;
443
    CC_SRC = eflags;
444
}
445

    
446
void OPPROTO op_cmc(void)
447
{
448
    int eflags;
449
    eflags = cc_table[CC_OP].compute_all();
450
    eflags ^= CC_C;
451
    CC_SRC = eflags;
452
}
453

    
454
void OPPROTO op_salc(void)
455
{
456
    int cf;
457
    cf = cc_table[CC_OP].compute_c();
458
    EAX = (EAX & ~0xff) | ((-cf) & 0xff);
459
}
460

    
461
void OPPROTO op_fcomi_dummy(void)
462
{
463
    T0 = 0;
464
}
465

    
466
/* SSE support */
467
void OPPROTO op_com_dummy(void)
468
{
469
    T0 = 0;
470
}