Statistics
| Branch: | Revision:

root / target-i386 / op.c @ 3bd7da9e

History | View | Annotate | Download (7.7 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
void OPPROTO op_movl_T0_env(void)
151
{
152
    T0 = *(uint32_t *)((char *)env + PARAM1);
153
}
154

    
155
void OPPROTO op_movl_env_T0(void)
156
{
157
    *(uint32_t *)((char *)env + PARAM1) = T0;
158
}
159

    
160
void OPPROTO op_movl_env_T1(void)
161
{
162
    *(uint32_t *)((char *)env + PARAM1) = T1;
163
}
164

    
165
void OPPROTO op_movtl_T0_env(void)
166
{
167
    T0 = *(target_ulong *)((char *)env + PARAM1);
168
}
169

    
170
void OPPROTO op_movtl_env_T0(void)
171
{
172
    *(target_ulong *)((char *)env + PARAM1) = T0;
173
}
174

    
175
void OPPROTO op_movtl_T1_env(void)
176
{
177
    T1 = *(target_ulong *)((char *)env + PARAM1);
178
}
179

    
180
void OPPROTO op_movtl_env_T1(void)
181
{
182
    *(target_ulong *)((char *)env + PARAM1) = T1;
183
}
184

    
185
/* flags handling */
186

    
187
void OPPROTO op_jmp_label(void)
188
{
189
    GOTO_LABEL_PARAM(1);
190
}
191

    
192
void OPPROTO op_jnz_T0_label(void)
193
{
194
    if (T0)
195
        GOTO_LABEL_PARAM(1);
196
    FORCE_RET();
197
}
198

    
199
/* slow set cases (compute x86 flags) */
200
void OPPROTO op_seto_T0_cc(void)
201
{
202
    int eflags;
203
    eflags = cc_table[CC_OP].compute_all();
204
    T0 = (eflags >> 11) & 1;
205
}
206

    
207
void OPPROTO op_setb_T0_cc(void)
208
{
209
    T0 = cc_table[CC_OP].compute_c();
210
}
211

    
212
void OPPROTO op_setz_T0_cc(void)
213
{
214
    int eflags;
215
    eflags = cc_table[CC_OP].compute_all();
216
    T0 = (eflags >> 6) & 1;
217
}
218

    
219
void OPPROTO op_setbe_T0_cc(void)
220
{
221
    int eflags;
222
    eflags = cc_table[CC_OP].compute_all();
223
    T0 = (eflags & (CC_Z | CC_C)) != 0;
224
}
225

    
226
void OPPROTO op_sets_T0_cc(void)
227
{
228
    int eflags;
229
    eflags = cc_table[CC_OP].compute_all();
230
    T0 = (eflags >> 7) & 1;
231
}
232

    
233
void OPPROTO op_setp_T0_cc(void)
234
{
235
    int eflags;
236
    eflags = cc_table[CC_OP].compute_all();
237
    T0 = (eflags >> 2) & 1;
238
}
239

    
240
void OPPROTO op_setl_T0_cc(void)
241
{
242
    int eflags;
243
    eflags = cc_table[CC_OP].compute_all();
244
    T0 = ((eflags ^ (eflags >> 4)) >> 7) & 1;
245
}
246

    
247
void OPPROTO op_setle_T0_cc(void)
248
{
249
    int eflags;
250
    eflags = cc_table[CC_OP].compute_all();
251
    T0 = (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) != 0;
252
}
253

    
254
void OPPROTO op_xor_T0_1(void)
255
{
256
    T0 ^= 1;
257
}
258

    
259
/* XXX: clear VIF/VIP in all ops ? */
260

    
261
void OPPROTO op_movl_eflags_T0(void)
262
{
263
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK));
264
}
265

    
266
void OPPROTO op_movw_eflags_T0(void)
267
{
268
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff);
269
}
270

    
271
void OPPROTO op_movl_eflags_T0_io(void)
272
{
273
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK));
274
}
275

    
276
void OPPROTO op_movw_eflags_T0_io(void)
277
{
278
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff);
279
}
280

    
281
void OPPROTO op_movl_eflags_T0_cpl0(void)
282
{
283
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK));
284
}
285

    
286
void OPPROTO op_movw_eflags_T0_cpl0(void)
287
{
288
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff);
289
}
290

    
291
#if 0
292
/* vm86plus version */
293
void OPPROTO op_movw_eflags_T0_vm(void)
294
{
295
    int eflags;
296
    eflags = T0;
297
    CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
298
    DF = 1 - (2 * ((eflags >> 10) & 1));
299
    /* we also update some system flags as in user mode */
300
    env->eflags = (env->eflags & ~(FL_UPDATE_MASK16 | VIF_MASK)) |
301
        (eflags & FL_UPDATE_MASK16);
302
    if (eflags & IF_MASK) {
303
        env->eflags |= VIF_MASK;
304
        if (env->eflags & VIP_MASK) {
305
            EIP = PARAM1;
306
            raise_exception(EXCP0D_GPF);
307
        }
308
    }
309
    FORCE_RET();
310
}
311

312
void OPPROTO op_movl_eflags_T0_vm(void)
313
{
314
    int eflags;
315
    eflags = T0;
316
    CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
317
    DF = 1 - (2 * ((eflags >> 10) & 1));
318
    /* we also update some system flags as in user mode */
319
    env->eflags = (env->eflags & ~(FL_UPDATE_MASK32 | VIF_MASK)) |
320
        (eflags & FL_UPDATE_MASK32);
321
    if (eflags & IF_MASK) {
322
        env->eflags |= VIF_MASK;
323
        if (env->eflags & VIP_MASK) {
324
            EIP = PARAM1;
325
            raise_exception(EXCP0D_GPF);
326
        }
327
    }
328
    FORCE_RET();
329
}
330
#endif
331

    
332
/* XXX: compute only O flag */
333
void OPPROTO op_movb_eflags_T0(void)
334
{
335
    int of;
336
    of = cc_table[CC_OP].compute_all() & CC_O;
337
    CC_SRC = (T0 & (CC_S | CC_Z | CC_A | CC_P | CC_C)) | of;
338
}
339

    
340
void OPPROTO op_movl_T0_eflags(void)
341
{
342
    int eflags;
343
    eflags = cc_table[CC_OP].compute_all();
344
    eflags |= (DF & DF_MASK);
345
    eflags |= env->eflags & ~(VM_MASK | RF_MASK);
346
    T0 = eflags;
347
}
348

    
349
/* vm86plus version */
350
#if 0
351
void OPPROTO op_movl_T0_eflags_vm(void)
352
{
353
    int eflags;
354
    eflags = cc_table[CC_OP].compute_all();
355
    eflags |= (DF & DF_MASK);
356
    eflags |= env->eflags & ~(VM_MASK | RF_MASK | IF_MASK);
357
    if (env->eflags & VIF_MASK)
358
        eflags |= IF_MASK;
359
    T0 = eflags;
360
}
361
#endif
362

    
363
void OPPROTO op_clc(void)
364
{
365
    int eflags;
366
    eflags = cc_table[CC_OP].compute_all();
367
    eflags &= ~CC_C;
368
    CC_SRC = eflags;
369
}
370

    
371
void OPPROTO op_stc(void)
372
{
373
    int eflags;
374
    eflags = cc_table[CC_OP].compute_all();
375
    eflags |= CC_C;
376
    CC_SRC = eflags;
377
}
378

    
379
void OPPROTO op_cmc(void)
380
{
381
    int eflags;
382
    eflags = cc_table[CC_OP].compute_all();
383
    eflags ^= CC_C;
384
    CC_SRC = eflags;
385
}
386

    
387
void OPPROTO op_salc(void)
388
{
389
    int cf;
390
    cf = cc_table[CC_OP].compute_c();
391
    EAX = (EAX & ~0xff) | ((-cf) & 0xff);
392
}