~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to target-i386/op.c

  • Committer: Bazaar Package Importer
  • Author(s): Aurelien Jarno, Aurelien Jarno
  • Date: 2009-03-22 10:13:17 UTC
  • mfrom: (1.2.1 upstream) (6.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20090322101317-iigjtnu5qil35dtb
Tags: 0.10.1-1
[ Aurelien Jarno ]
* New upstream stable release:
  - patches/80_stable-branch.patch: remove.
* debian/control: 
  - Remove depends on proll.
  - Move depends on device-tree-compiler to build-depends.
  - Bump Standards-Version to 3.8.1 (no changes).
* patches/82_qemu-img_decimal.patch: new patch from upstream to make
  qemu-img accept sizes with decimal values (closes: bug#501400).

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
/* 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
 
/* we define the various pieces of code used by the JIT */
34
 
 
35
 
#define REG EAX
36
 
#define REGNAME _EAX
37
 
#include "opreg_template.h"
38
 
#undef REG
39
 
#undef REGNAME
40
 
 
41
 
#define REG ECX
42
 
#define REGNAME _ECX
43
 
#include "opreg_template.h"
44
 
#undef REG
45
 
#undef REGNAME
46
 
 
47
 
#define REG EDX
48
 
#define REGNAME _EDX
49
 
#include "opreg_template.h"
50
 
#undef REG
51
 
#undef REGNAME
52
 
 
53
 
#define REG EBX
54
 
#define REGNAME _EBX
55
 
#include "opreg_template.h"
56
 
#undef REG
57
 
#undef REGNAME
58
 
 
59
 
#define REG ESP
60
 
#define REGNAME _ESP
61
 
#include "opreg_template.h"
62
 
#undef REG
63
 
#undef REGNAME
64
 
 
65
 
#define REG EBP
66
 
#define REGNAME _EBP
67
 
#include "opreg_template.h"
68
 
#undef REG
69
 
#undef REGNAME
70
 
 
71
 
#define REG ESI
72
 
#define REGNAME _ESI
73
 
#include "opreg_template.h"
74
 
#undef REG
75
 
#undef REGNAME
76
 
 
77
 
#define REG EDI
78
 
#define REGNAME _EDI
79
 
#include "opreg_template.h"
80
 
#undef REG
81
 
#undef REGNAME
82
 
 
83
 
#ifdef TARGET_X86_64
84
 
 
85
 
#define REG (env->regs[8])
86
 
#define REGNAME _R8
87
 
#include "opreg_template.h"
88
 
#undef REG
89
 
#undef REGNAME
90
 
 
91
 
#define REG (env->regs[9])
92
 
#define REGNAME _R9
93
 
#include "opreg_template.h"
94
 
#undef REG
95
 
#undef REGNAME
96
 
 
97
 
#define REG (env->regs[10])
98
 
#define REGNAME _R10
99
 
#include "opreg_template.h"
100
 
#undef REG
101
 
#undef REGNAME
102
 
 
103
 
#define REG (env->regs[11])
104
 
#define REGNAME _R11
105
 
#include "opreg_template.h"
106
 
#undef REG
107
 
#undef REGNAME
108
 
 
109
 
#define REG (env->regs[12])
110
 
#define REGNAME _R12
111
 
#include "opreg_template.h"
112
 
#undef REG
113
 
#undef REGNAME
114
 
 
115
 
#define REG (env->regs[13])
116
 
#define REGNAME _R13
117
 
#include "opreg_template.h"
118
 
#undef REG
119
 
#undef REGNAME
120
 
 
121
 
#define REG (env->regs[14])
122
 
#define REGNAME _R14
123
 
#include "opreg_template.h"
124
 
#undef REG
125
 
#undef REGNAME
126
 
 
127
 
#define REG (env->regs[15])
128
 
#define REGNAME _R15
129
 
#include "opreg_template.h"
130
 
#undef REG
131
 
#undef REGNAME
132
 
 
133
 
#endif
134
 
 
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_addl_T0_T1(void)
176
 
{
177
 
    T0 += T1;
178
 
}
179
 
 
180
 
void OPPROTO op_orl_T0_T1(void)
181
 
{
182
 
    T0 |= T1;
183
 
}
184
 
 
185
 
void OPPROTO op_andl_T0_T1(void)
186
 
{
187
 
    T0 &= T1;
188
 
}
189
 
 
190
 
void OPPROTO op_subl_T0_T1(void)
191
 
{
192
 
    T0 -= T1;
193
 
}
194
 
 
195
 
void OPPROTO op_xorl_T0_T1(void)
196
 
{
197
 
    T0 ^= T1;
198
 
}
199
 
 
200
 
void OPPROTO op_negl_T0(void)
201
 
{
202
 
    T0 = -T0;
203
 
}
204
 
 
205
 
void OPPROTO op_incl_T0(void)
206
 
{
207
 
    T0++;
208
 
}
209
 
 
210
 
void OPPROTO op_decl_T0(void)
211
 
{
212
 
    T0--;
213
 
}
214
 
 
215
 
void OPPROTO op_notl_T0(void)
216
 
{
217
 
    T0 = ~T0;
218
 
}
219
 
 
220
 
void OPPROTO op_bswapl_T0(void)
221
 
{
222
 
    T0 = bswap32(T0);
223
 
}
224
 
 
225
 
#ifdef TARGET_X86_64
226
 
void OPPROTO op_bswapq_T0(void)
227
 
{
228
 
    helper_bswapq_T0();
229
 
}
230
 
#endif
231
 
 
232
 
/* multiply/divide */
233
 
 
234
 
/* XXX: add eflags optimizations */
235
 
/* XXX: add non P4 style flags */
236
 
 
237
 
void OPPROTO op_mulb_AL_T0(void)
238
 
{
239
 
    unsigned int res;
240
 
    res = (uint8_t)EAX * (uint8_t)T0;
241
 
    EAX = (EAX & ~0xffff) | res;
242
 
    CC_DST = res;
243
 
    CC_SRC = (res & 0xff00);
244
 
}
245
 
 
246
 
void OPPROTO op_imulb_AL_T0(void)
247
 
{
248
 
    int res;
249
 
    res = (int8_t)EAX * (int8_t)T0;
250
 
    EAX = (EAX & ~0xffff) | (res & 0xffff);
251
 
    CC_DST = res;
252
 
    CC_SRC = (res != (int8_t)res);
253
 
}
254
 
 
255
 
void OPPROTO op_mulw_AX_T0(void)
256
 
{
257
 
    unsigned int res;
258
 
    res = (uint16_t)EAX * (uint16_t)T0;
259
 
    EAX = (EAX & ~0xffff) | (res & 0xffff);
260
 
    EDX = (EDX & ~0xffff) | ((res >> 16) & 0xffff);
261
 
    CC_DST = res;
262
 
    CC_SRC = res >> 16;
263
 
}
264
 
 
265
 
void OPPROTO op_imulw_AX_T0(void)
266
 
{
267
 
    int res;
268
 
    res = (int16_t)EAX * (int16_t)T0;
269
 
    EAX = (EAX & ~0xffff) | (res & 0xffff);
270
 
    EDX = (EDX & ~0xffff) | ((res >> 16) & 0xffff);
271
 
    CC_DST = res;
272
 
    CC_SRC = (res != (int16_t)res);
273
 
}
274
 
 
275
 
void OPPROTO op_mull_EAX_T0(void)
276
 
{
277
 
    uint64_t res;
278
 
    res = (uint64_t)((uint32_t)EAX) * (uint64_t)((uint32_t)T0);
279
 
    EAX = (uint32_t)res;
280
 
    EDX = (uint32_t)(res >> 32);
281
 
    CC_DST = (uint32_t)res;
282
 
    CC_SRC = (uint32_t)(res >> 32);
283
 
}
284
 
 
285
 
void OPPROTO op_imull_EAX_T0(void)
286
 
{
287
 
    int64_t res;
288
 
    res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T0);
289
 
    EAX = (uint32_t)(res);
290
 
    EDX = (uint32_t)(res >> 32);
291
 
    CC_DST = res;
292
 
    CC_SRC = (res != (int32_t)res);
293
 
}
294
 
 
295
 
void OPPROTO op_imulw_T0_T1(void)
296
 
{
297
 
    int res;
298
 
    res = (int16_t)T0 * (int16_t)T1;
299
 
    T0 = res;
300
 
    CC_DST = res;
301
 
    CC_SRC = (res != (int16_t)res);
302
 
}
303
 
 
304
 
void OPPROTO op_imull_T0_T1(void)
305
 
{
306
 
    int64_t res;
307
 
    res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
308
 
    T0 = res;
309
 
    CC_DST = res;
310
 
    CC_SRC = (res != (int32_t)res);
311
 
}
312
 
 
313
 
#ifdef TARGET_X86_64
314
 
void OPPROTO op_mulq_EAX_T0(void)
315
 
{
316
 
    helper_mulq_EAX_T0();
317
 
}
318
 
 
319
 
void OPPROTO op_imulq_EAX_T0(void)
320
 
{
321
 
    helper_imulq_EAX_T0();
322
 
}
323
 
 
324
 
void OPPROTO op_imulq_T0_T1(void)
325
 
{
326
 
    helper_imulq_T0_T1();
327
 
}
328
 
#endif
329
 
 
330
 
/* division, flags are undefined */
331
 
 
332
 
void OPPROTO op_divb_AL_T0(void)
333
 
{
334
 
    unsigned int num, den, q, r;
335
 
 
336
 
    num = (EAX & 0xffff);
337
 
    den = (T0 & 0xff);
338
 
    if (den == 0) {
339
 
        raise_exception(EXCP00_DIVZ);
340
 
    }
341
 
    q = (num / den);
342
 
    if (q > 0xff)
343
 
        raise_exception(EXCP00_DIVZ);
344
 
    q &= 0xff;
345
 
    r = (num % den) & 0xff;
346
 
    EAX = (EAX & ~0xffff) | (r << 8) | q;
347
 
}
348
 
 
349
 
void OPPROTO op_idivb_AL_T0(void)
350
 
{
351
 
    int num, den, q, r;
352
 
 
353
 
    num = (int16_t)EAX;
354
 
    den = (int8_t)T0;
355
 
    if (den == 0) {
356
 
        raise_exception(EXCP00_DIVZ);
357
 
    }
358
 
    q = (num / den);
359
 
    if (q != (int8_t)q)
360
 
        raise_exception(EXCP00_DIVZ);
361
 
    q &= 0xff;
362
 
    r = (num % den) & 0xff;
363
 
    EAX = (EAX & ~0xffff) | (r << 8) | q;
364
 
}
365
 
 
366
 
void OPPROTO op_divw_AX_T0(void)
367
 
{
368
 
    unsigned int num, den, q, r;
369
 
 
370
 
    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
371
 
    den = (T0 & 0xffff);
372
 
    if (den == 0) {
373
 
        raise_exception(EXCP00_DIVZ);
374
 
    }
375
 
    q = (num / den);
376
 
    if (q > 0xffff)
377
 
        raise_exception(EXCP00_DIVZ);
378
 
    q &= 0xffff;
379
 
    r = (num % den) & 0xffff;
380
 
    EAX = (EAX & ~0xffff) | q;
381
 
    EDX = (EDX & ~0xffff) | r;
382
 
}
383
 
 
384
 
void OPPROTO op_idivw_AX_T0(void)
385
 
{
386
 
    int num, den, q, r;
387
 
 
388
 
    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
389
 
    den = (int16_t)T0;
390
 
    if (den == 0) {
391
 
        raise_exception(EXCP00_DIVZ);
392
 
    }
393
 
    q = (num / den);
394
 
    if (q != (int16_t)q)
395
 
        raise_exception(EXCP00_DIVZ);
396
 
    q &= 0xffff;
397
 
    r = (num % den) & 0xffff;
398
 
    EAX = (EAX & ~0xffff) | q;
399
 
    EDX = (EDX & ~0xffff) | r;
400
 
}
401
 
 
402
 
void OPPROTO op_divl_EAX_T0(void)
403
 
{
404
 
    helper_divl_EAX_T0();
405
 
}
406
 
 
407
 
void OPPROTO op_idivl_EAX_T0(void)
408
 
{
409
 
    helper_idivl_EAX_T0();
410
 
}
411
 
 
412
 
#ifdef TARGET_X86_64
413
 
void OPPROTO op_divq_EAX_T0(void)
414
 
{
415
 
    helper_divq_EAX_T0();
416
 
}
417
 
 
418
 
void OPPROTO op_idivq_EAX_T0(void)
419
 
{
420
 
    helper_idivq_EAX_T0();
421
 
}
422
 
#endif
423
 
 
424
 
/* constant load & misc op */
425
 
 
426
 
/* XXX: consistent names */
427
 
void OPPROTO op_movl_T0_imu(void)
428
 
{
429
 
    T0 = (uint32_t)PARAM1;
430
 
}
431
 
 
432
 
void OPPROTO op_movl_T0_im(void)
433
 
{
434
 
    T0 = (int32_t)PARAM1;
435
 
}
436
 
 
437
 
void OPPROTO op_addl_T0_im(void)
438
 
{
439
 
    T0 += PARAM1;
440
 
}
441
 
 
442
 
void OPPROTO op_andl_T0_ffff(void)
443
 
{
444
 
    T0 = T0 & 0xffff;
445
 
}
446
 
 
447
 
void OPPROTO op_andl_T0_im(void)
448
 
{
449
 
    T0 = T0 & PARAM1;
450
 
}
451
 
 
452
 
void OPPROTO op_movl_T0_T1(void)
453
 
{
454
 
    T0 = T1;
455
 
}
456
 
 
457
 
void OPPROTO op_movl_T1_imu(void)
458
 
{
459
 
    T1 = (uint32_t)PARAM1;
460
 
}
461
 
 
462
 
void OPPROTO op_movl_T1_im(void)
463
 
{
464
 
    T1 = (int32_t)PARAM1;
465
 
}
466
 
 
467
 
void OPPROTO op_addl_T1_im(void)
468
 
{
469
 
    T1 += PARAM1;
470
 
}
471
 
 
472
 
void OPPROTO op_movl_T1_A0(void)
473
 
{
474
 
    T1 = A0;
475
 
}
476
 
 
477
 
void OPPROTO op_movl_A0_im(void)
478
 
{
479
 
    A0 = (uint32_t)PARAM1;
480
 
}
481
 
 
482
 
void OPPROTO op_addl_A0_im(void)
483
 
{
484
 
    A0 = (uint32_t)(A0 + PARAM1);
485
 
}
486
 
 
487
 
void OPPROTO op_movl_A0_seg(void)
488
 
{
489
 
    A0 = (uint32_t)*(target_ulong *)((char *)env + PARAM1);
490
 
}
491
 
 
492
 
void OPPROTO op_addl_A0_seg(void)
493
 
{
494
 
    A0 = (uint32_t)(A0 + *(target_ulong *)((char *)env + PARAM1));
495
 
}
496
 
 
497
 
void OPPROTO op_addl_A0_AL(void)
498
 
{
499
 
    A0 = (uint32_t)(A0 + (EAX & 0xff));
500
 
}
501
 
 
502
 
#ifdef WORDS_BIGENDIAN
503
 
typedef union UREG64 {
504
 
    struct { uint16_t v3, v2, v1, v0; } w;
505
 
    struct { uint32_t v1, v0; } l;
506
 
    uint64_t q;
507
 
} UREG64;
508
 
#else
509
 
typedef union UREG64 {
510
 
    struct { uint16_t v0, v1, v2, v3; } w;
511
 
    struct { uint32_t v0, v1; } l;
512
 
    uint64_t q;
513
 
} UREG64;
514
 
#endif
515
 
 
516
 
#define PARAMQ1 \
517
 
({\
518
 
    UREG64 __p;\
519
 
    __p.l.v1 = PARAM1;\
520
 
    __p.l.v0 = PARAM2;\
521
 
    __p.q;\
522
 
})
523
 
 
524
 
#ifdef TARGET_X86_64
525
 
 
526
 
void OPPROTO op_movq_T0_im64(void)
527
 
{
528
 
    T0 = PARAMQ1;
529
 
}
530
 
 
531
 
void OPPROTO op_movq_T1_im64(void)
532
 
{
533
 
    T1 = PARAMQ1;
534
 
}
535
 
 
536
 
void OPPROTO op_movq_A0_im(void)
537
 
{
538
 
    A0 = (int32_t)PARAM1;
539
 
}
540
 
 
541
 
void OPPROTO op_movq_A0_im64(void)
542
 
{
543
 
    A0 = PARAMQ1;
544
 
}
545
 
 
546
 
void OPPROTO op_addq_A0_im(void)
547
 
{
548
 
    A0 = (A0 + (int32_t)PARAM1);
549
 
}
550
 
 
551
 
void OPPROTO op_addq_A0_im64(void)
552
 
{
553
 
    A0 = (A0 + PARAMQ1);
554
 
}
555
 
 
556
 
void OPPROTO op_movq_A0_seg(void)
557
 
{
558
 
    A0 = *(target_ulong *)((char *)env + PARAM1);
559
 
}
560
 
 
561
 
void OPPROTO op_addq_A0_seg(void)
562
 
{
563
 
    A0 += *(target_ulong *)((char *)env + PARAM1);
564
 
}
565
 
 
566
 
void OPPROTO op_addq_A0_AL(void)
567
 
{
568
 
    A0 = (A0 + (EAX & 0xff));
569
 
}
570
 
 
571
 
#endif
572
 
 
573
 
void OPPROTO op_andl_A0_ffff(void)
574
 
{
575
 
    A0 = A0 & 0xffff;
576
 
}
577
 
 
578
 
/* memory access */
579
 
 
580
 
#define MEMSUFFIX _raw
581
 
#include "ops_mem.h"
582
 
 
583
 
#if !defined(CONFIG_USER_ONLY)
584
 
#define MEMSUFFIX _kernel
585
 
#include "ops_mem.h"
586
 
 
587
 
#define MEMSUFFIX _user
588
 
#include "ops_mem.h"
589
 
#endif
590
 
 
591
 
/* indirect jump */
592
 
 
593
 
void OPPROTO op_jmp_T0(void)
594
 
{
595
 
    EIP = T0;
596
 
}
597
 
 
598
 
void OPPROTO op_movl_eip_im(void)
599
 
{
600
 
    EIP = (uint32_t)PARAM1;
601
 
}
602
 
 
603
 
#ifdef TARGET_X86_64
604
 
void OPPROTO op_movq_eip_im(void)
605
 
{
606
 
    EIP = (int32_t)PARAM1;
607
 
}
608
 
 
609
 
void OPPROTO op_movq_eip_im64(void)
610
 
{
611
 
    EIP = PARAMQ1;
612
 
}
613
 
#endif
614
 
 
615
 
void OPPROTO op_hlt(void)
616
 
{
617
 
    helper_hlt();
618
 
}
619
 
 
620
 
void OPPROTO op_monitor(void)
621
 
{
622
 
    helper_monitor();
623
 
}
624
 
 
625
 
void OPPROTO op_mwait(void)
626
 
{
627
 
    helper_mwait();
628
 
}
629
 
 
630
 
void OPPROTO op_debug(void)
631
 
{
632
 
    env->exception_index = EXCP_DEBUG;
633
 
    cpu_loop_exit();
634
 
}
635
 
 
636
 
void OPPROTO op_raise_interrupt(void)
637
 
{
638
 
    int intno, next_eip_addend;
639
 
    intno = PARAM1;
640
 
    next_eip_addend = PARAM2;
641
 
    raise_interrupt(intno, 1, 0, next_eip_addend);
642
 
}
643
 
 
644
 
void OPPROTO op_raise_exception(void)
645
 
{
646
 
    int exception_index;
647
 
    exception_index = PARAM1;
648
 
    raise_exception(exception_index);
649
 
}
650
 
 
651
 
void OPPROTO op_into(void)
652
 
{
653
 
    int eflags;
654
 
    eflags = cc_table[CC_OP].compute_all();
655
 
    if (eflags & CC_O) {
656
 
        raise_interrupt(EXCP04_INTO, 1, 0, PARAM1);
657
 
    }
658
 
    FORCE_RET();
659
 
}
660
 
 
661
 
void OPPROTO op_cli(void)
662
 
{
663
 
    env->eflags &= ~IF_MASK;
664
 
}
665
 
 
666
 
void OPPROTO op_sti(void)
667
 
{
668
 
    env->eflags |= IF_MASK;
669
 
}
670
 
 
671
 
void OPPROTO op_set_inhibit_irq(void)
672
 
{
673
 
    env->hflags |= HF_INHIBIT_IRQ_MASK;
674
 
}
675
 
 
676
 
void OPPROTO op_reset_inhibit_irq(void)
677
 
{
678
 
    env->hflags &= ~HF_INHIBIT_IRQ_MASK;
679
 
}
680
 
 
681
 
void OPPROTO op_rsm(void)
682
 
{
683
 
    helper_rsm();
684
 
}
685
 
 
686
 
#if 0
687
 
/* vm86plus instructions */
688
 
void OPPROTO op_cli_vm(void)
689
 
{
690
 
    env->eflags &= ~VIF_MASK;
691
 
}
692
 
 
693
 
void OPPROTO op_sti_vm(void)
694
 
{
695
 
    env->eflags |= VIF_MASK;
696
 
    if (env->eflags & VIP_MASK) {
697
 
        EIP = PARAM1;
698
 
        raise_exception(EXCP0D_GPF);
699
 
    }
700
 
    FORCE_RET();
701
 
}
702
 
#endif
703
 
 
704
 
void OPPROTO op_boundw(void)
705
 
{
706
 
    int low, high, v;
707
 
    low = ldsw(A0);
708
 
    high = ldsw(A0 + 2);
709
 
    v = (int16_t)T0;
710
 
    if (v < low || v > high) {
711
 
        raise_exception(EXCP05_BOUND);
712
 
    }
713
 
    FORCE_RET();
714
 
}
715
 
 
716
 
void OPPROTO op_boundl(void)
717
 
{
718
 
    int low, high, v;
719
 
    low = ldl(A0);
720
 
    high = ldl(A0 + 4);
721
 
    v = T0;
722
 
    if (v < low || v > high) {
723
 
        raise_exception(EXCP05_BOUND);
724
 
    }
725
 
    FORCE_RET();
726
 
}
727
 
 
728
 
void OPPROTO op_cmpxchg8b(void)
729
 
{
730
 
    helper_cmpxchg8b();
731
 
}
732
 
 
733
 
void OPPROTO op_single_step(void)
734
 
{
735
 
    helper_single_step();
736
 
}
737
 
 
738
 
void OPPROTO op_movl_T0_0(void)
739
 
{
740
 
    T0 = 0;
741
 
}
742
 
 
743
 
void OPPROTO op_exit_tb(void)
744
 
{
745
 
    EXIT_TB();
746
 
}
747
 
 
748
 
/* multiple size ops */
749
 
 
750
 
#define ldul ldl
751
 
 
752
 
#define SHIFT 0
753
 
#include "ops_template.h"
754
 
#undef SHIFT
755
 
 
756
 
#define SHIFT 1
757
 
#include "ops_template.h"
758
 
#undef SHIFT
759
 
 
760
 
#define SHIFT 2
761
 
#include "ops_template.h"
762
 
#undef SHIFT
763
 
 
764
 
#ifdef TARGET_X86_64
765
 
 
766
 
#define SHIFT 3
767
 
#include "ops_template.h"
768
 
#undef SHIFT
769
 
 
770
 
#endif
771
 
 
772
 
/* sign extend */
773
 
 
774
 
void OPPROTO op_movsbl_T0_T0(void)
775
 
{
776
 
    T0 = (int8_t)T0;
777
 
}
778
 
 
779
 
void OPPROTO op_movzbl_T0_T0(void)
780
 
{
781
 
    T0 = (uint8_t)T0;
782
 
}
783
 
 
784
 
void OPPROTO op_movswl_T0_T0(void)
785
 
{
786
 
    T0 = (int16_t)T0;
787
 
}
788
 
 
789
 
void OPPROTO op_movzwl_T0_T0(void)
790
 
{
791
 
    T0 = (uint16_t)T0;
792
 
}
793
 
 
794
 
void OPPROTO op_movswl_EAX_AX(void)
795
 
{
796
 
    EAX = (uint32_t)((int16_t)EAX);
797
 
}
798
 
 
799
 
#ifdef TARGET_X86_64
800
 
void OPPROTO op_movslq_T0_T0(void)
801
 
{
802
 
    T0 = (int32_t)T0;
803
 
}
804
 
 
805
 
void OPPROTO op_movslq_RAX_EAX(void)
806
 
{
807
 
    EAX = (int32_t)EAX;
808
 
}
809
 
#endif
810
 
 
811
 
void OPPROTO op_movsbw_AX_AL(void)
812
 
{
813
 
    EAX = (EAX & ~0xffff) | ((int8_t)EAX & 0xffff);
814
 
}
815
 
 
816
 
void OPPROTO op_movslq_EDX_EAX(void)
817
 
{
818
 
    EDX = (uint32_t)((int32_t)EAX >> 31);
819
 
}
820
 
 
821
 
void OPPROTO op_movswl_DX_AX(void)
822
 
{
823
 
    EDX = (EDX & ~0xffff) | (((int16_t)EAX >> 15) & 0xffff);
824
 
}
825
 
 
826
 
#ifdef TARGET_X86_64
827
 
void OPPROTO op_movsqo_RDX_RAX(void)
828
 
{
829
 
    EDX = (int64_t)EAX >> 63;
830
 
}
831
 
#endif
832
 
 
833
 
/* string ops helpers */
834
 
 
835
 
void OPPROTO op_addl_ESI_T0(void)
836
 
{
837
 
    ESI = (uint32_t)(ESI + T0);
838
 
}
839
 
 
840
 
void OPPROTO op_addw_ESI_T0(void)
841
 
{
842
 
    ESI = (ESI & ~0xffff) | ((ESI + T0) & 0xffff);
843
 
}
844
 
 
845
 
void OPPROTO op_addl_EDI_T0(void)
846
 
{
847
 
    EDI = (uint32_t)(EDI + T0);
848
 
}
849
 
 
850
 
void OPPROTO op_addw_EDI_T0(void)
851
 
{
852
 
    EDI = (EDI & ~0xffff) | ((EDI + T0) & 0xffff);
853
 
}
854
 
 
855
 
void OPPROTO op_decl_ECX(void)
856
 
{
857
 
    ECX = (uint32_t)(ECX - 1);
858
 
}
859
 
 
860
 
void OPPROTO op_decw_ECX(void)
861
 
{
862
 
    ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff);
863
 
}
864
 
 
865
 
#ifdef TARGET_X86_64
866
 
void OPPROTO op_addq_ESI_T0(void)
867
 
{
868
 
    ESI = (ESI + T0);
869
 
}
870
 
 
871
 
void OPPROTO op_addq_EDI_T0(void)
872
 
{
873
 
    EDI = (EDI + T0);
874
 
}
875
 
 
876
 
void OPPROTO op_decq_ECX(void)
877
 
{
878
 
    ECX--;
879
 
}
880
 
#endif
881
 
 
882
 
/* push/pop utils */
883
 
 
884
 
void op_addl_A0_SS(void)
885
 
{
886
 
    A0 = (uint32_t)(A0 + env->segs[R_SS].base);
887
 
}
888
 
 
889
 
void op_subl_A0_2(void)
890
 
{
891
 
    A0 = (uint32_t)(A0 - 2);
892
 
}
893
 
 
894
 
void op_subl_A0_4(void)
895
 
{
896
 
    A0 = (uint32_t)(A0 - 4);
897
 
}
898
 
 
899
 
void op_addl_ESP_4(void)
900
 
{
901
 
    ESP = (uint32_t)(ESP + 4);
902
 
}
903
 
 
904
 
void op_addl_ESP_2(void)
905
 
{
906
 
    ESP = (uint32_t)(ESP + 2);
907
 
}
908
 
 
909
 
void op_addw_ESP_4(void)
910
 
{
911
 
    ESP = (ESP & ~0xffff) | ((ESP + 4) & 0xffff);
912
 
}
913
 
 
914
 
void op_addw_ESP_2(void)
915
 
{
916
 
    ESP = (ESP & ~0xffff) | ((ESP + 2) & 0xffff);
917
 
}
918
 
 
919
 
void op_addl_ESP_im(void)
920
 
{
921
 
    ESP = (uint32_t)(ESP + PARAM1);
922
 
}
923
 
 
924
 
void op_addw_ESP_im(void)
925
 
{
926
 
    ESP = (ESP & ~0xffff) | ((ESP + PARAM1) & 0xffff);
927
 
}
928
 
 
929
 
#ifdef TARGET_X86_64
930
 
void op_subq_A0_2(void)
931
 
{
932
 
    A0 -= 2;
933
 
}
934
 
 
935
 
void op_subq_A0_8(void)
936
 
{
937
 
    A0 -= 8;
938
 
}
939
 
 
940
 
void op_addq_ESP_8(void)
941
 
{
942
 
    ESP += 8;
943
 
}
944
 
 
945
 
void op_addq_ESP_im(void)
946
 
{
947
 
    ESP += PARAM1;
948
 
}
949
 
#endif
950
 
 
951
 
void OPPROTO op_rdtsc(void)
952
 
{
953
 
    helper_rdtsc();
954
 
}
955
 
 
956
 
void OPPROTO op_rdpmc(void)
957
 
{
958
 
    helper_rdpmc();
959
 
}
960
 
 
961
 
void OPPROTO op_cpuid(void)
962
 
{
963
 
    helper_cpuid();
964
 
}
965
 
 
966
 
void OPPROTO op_enter_level(void)
967
 
{
968
 
    helper_enter_level(PARAM1, PARAM2);
969
 
}
970
 
 
971
 
#ifdef TARGET_X86_64
972
 
void OPPROTO op_enter64_level(void)
973
 
{
974
 
    helper_enter64_level(PARAM1, PARAM2);
975
 
}
976
 
#endif
977
 
 
978
 
void OPPROTO op_sysenter(void)
979
 
{
980
 
    helper_sysenter();
981
 
}
982
 
 
983
 
void OPPROTO op_sysexit(void)
984
 
{
985
 
    helper_sysexit();
986
 
}
987
 
 
988
 
#ifdef TARGET_X86_64
989
 
void OPPROTO op_syscall(void)
990
 
{
991
 
    helper_syscall(PARAM1);
992
 
}
993
 
 
994
 
void OPPROTO op_sysret(void)
995
 
{
996
 
    helper_sysret(PARAM1);
997
 
}
998
 
#endif
999
 
 
1000
 
void OPPROTO op_rdmsr(void)
1001
 
{
1002
 
    helper_rdmsr();
1003
 
}
1004
 
 
1005
 
void OPPROTO op_wrmsr(void)
1006
 
{
1007
 
    helper_wrmsr();
1008
 
}
1009
 
 
1010
 
/* bcd */
1011
 
 
1012
 
/* XXX: exception */
1013
 
void OPPROTO op_aam(void)
1014
 
{
1015
 
    int base = PARAM1;
1016
 
    int al, ah;
1017
 
    al = EAX & 0xff;
1018
 
    ah = al / base;
1019
 
    al = al % base;
1020
 
    EAX = (EAX & ~0xffff) | al | (ah << 8);
1021
 
    CC_DST = al;
1022
 
}
1023
 
 
1024
 
void OPPROTO op_aad(void)
1025
 
{
1026
 
    int base = PARAM1;
1027
 
    int al, ah;
1028
 
    al = EAX & 0xff;
1029
 
    ah = (EAX >> 8) & 0xff;
1030
 
    al = ((ah * base) + al) & 0xff;
1031
 
    EAX = (EAX & ~0xffff) | al;
1032
 
    CC_DST = al;
1033
 
}
1034
 
 
1035
 
void OPPROTO op_aaa(void)
1036
 
{
1037
 
    int icarry;
1038
 
    int al, ah, af;
1039
 
    int eflags;
1040
 
 
1041
 
    eflags = cc_table[CC_OP].compute_all();
1042
 
    af = eflags & CC_A;
1043
 
    al = EAX & 0xff;
1044
 
    ah = (EAX >> 8) & 0xff;
1045
 
 
1046
 
    icarry = (al > 0xf9);
1047
 
    if (((al & 0x0f) > 9 ) || af) {
1048
 
        al = (al + 6) & 0x0f;
1049
 
        ah = (ah + 1 + icarry) & 0xff;
1050
 
        eflags |= CC_C | CC_A;
1051
 
    } else {
1052
 
        eflags &= ~(CC_C | CC_A);
1053
 
        al &= 0x0f;
1054
 
    }
1055
 
    EAX = (EAX & ~0xffff) | al | (ah << 8);
1056
 
    CC_SRC = eflags;
1057
 
    FORCE_RET();
1058
 
}
1059
 
 
1060
 
void OPPROTO op_aas(void)
1061
 
{
1062
 
    int icarry;
1063
 
    int al, ah, af;
1064
 
    int eflags;
1065
 
 
1066
 
    eflags = cc_table[CC_OP].compute_all();
1067
 
    af = eflags & CC_A;
1068
 
    al = EAX & 0xff;
1069
 
    ah = (EAX >> 8) & 0xff;
1070
 
 
1071
 
    icarry = (al < 6);
1072
 
    if (((al & 0x0f) > 9 ) || af) {
1073
 
        al = (al - 6) & 0x0f;
1074
 
        ah = (ah - 1 - icarry) & 0xff;
1075
 
        eflags |= CC_C | CC_A;
1076
 
    } else {
1077
 
        eflags &= ~(CC_C | CC_A);
1078
 
        al &= 0x0f;
1079
 
    }
1080
 
    EAX = (EAX & ~0xffff) | al | (ah << 8);
1081
 
    CC_SRC = eflags;
1082
 
    FORCE_RET();
1083
 
}
1084
 
 
1085
 
void OPPROTO op_daa(void)
1086
 
{
1087
 
    int al, af, cf;
1088
 
    int eflags;
1089
 
 
1090
 
    eflags = cc_table[CC_OP].compute_all();
1091
 
    cf = eflags & CC_C;
1092
 
    af = eflags & CC_A;
1093
 
    al = EAX & 0xff;
1094
 
 
1095
 
    eflags = 0;
1096
 
    if (((al & 0x0f) > 9 ) || af) {
1097
 
        al = (al + 6) & 0xff;
1098
 
        eflags |= CC_A;
1099
 
    }
1100
 
    if ((al > 0x9f) || cf) {
1101
 
        al = (al + 0x60) & 0xff;
1102
 
        eflags |= CC_C;
1103
 
    }
1104
 
    EAX = (EAX & ~0xff) | al;
1105
 
    /* well, speed is not an issue here, so we compute the flags by hand */
1106
 
    eflags |= (al == 0) << 6; /* zf */
1107
 
    eflags |= parity_table[al]; /* pf */
1108
 
    eflags |= (al & 0x80); /* sf */
1109
 
    CC_SRC = eflags;
1110
 
    FORCE_RET();
1111
 
}
1112
 
 
1113
 
void OPPROTO op_das(void)
1114
 
{
1115
 
    int al, al1, af, cf;
1116
 
    int eflags;
1117
 
 
1118
 
    eflags = cc_table[CC_OP].compute_all();
1119
 
    cf = eflags & CC_C;
1120
 
    af = eflags & CC_A;
1121
 
    al = EAX & 0xff;
1122
 
 
1123
 
    eflags = 0;
1124
 
    al1 = al;
1125
 
    if (((al & 0x0f) > 9 ) || af) {
1126
 
        eflags |= CC_A;
1127
 
        if (al < 6 || cf)
1128
 
            eflags |= CC_C;
1129
 
        al = (al - 6) & 0xff;
1130
 
    }
1131
 
    if ((al1 > 0x99) || cf) {
1132
 
        al = (al - 0x60) & 0xff;
1133
 
        eflags |= CC_C;
1134
 
    }
1135
 
    EAX = (EAX & ~0xff) | al;
1136
 
    /* well, speed is not an issue here, so we compute the flags by hand */
1137
 
    eflags |= (al == 0) << 6; /* zf */
1138
 
    eflags |= parity_table[al]; /* pf */
1139
 
    eflags |= (al & 0x80); /* sf */
1140
 
    CC_SRC = eflags;
1141
 
    FORCE_RET();
1142
 
}
1143
 
 
1144
 
/* segment handling */
1145
 
 
1146
 
/* never use it with R_CS */
1147
 
void OPPROTO op_movl_seg_T0(void)
1148
 
{
1149
 
    load_seg(PARAM1, T0);
1150
 
}
1151
 
 
1152
 
/* faster VM86 version */
1153
 
void OPPROTO op_movl_seg_T0_vm(void)
1154
 
{
1155
 
    int selector;
1156
 
    SegmentCache *sc;
1157
 
 
1158
 
    selector = T0 & 0xffff;
1159
 
    /* env->segs[] access */
1160
 
    sc = (SegmentCache *)((char *)env + PARAM1);
1161
 
    sc->selector = selector;
1162
 
    sc->base = (selector << 4);
1163
 
}
1164
 
 
1165
 
void OPPROTO op_movl_T0_seg(void)
1166
 
{
1167
 
    T0 = env->segs[PARAM1].selector;
1168
 
}
1169
 
 
1170
 
void OPPROTO op_lsl(void)
1171
 
{
1172
 
    helper_lsl();
1173
 
}
1174
 
 
1175
 
void OPPROTO op_lar(void)
1176
 
{
1177
 
    helper_lar();
1178
 
}
1179
 
 
1180
 
void OPPROTO op_verr(void)
1181
 
{
1182
 
    helper_verr();
1183
 
}
1184
 
 
1185
 
void OPPROTO op_verw(void)
1186
 
{
1187
 
    helper_verw();
1188
 
}
1189
 
 
1190
 
void OPPROTO op_arpl(void)
1191
 
{
1192
 
    if ((T0 & 3) < (T1 & 3)) {
1193
 
        /* XXX: emulate bug or 0xff3f0000 oring as in bochs ? */
1194
 
        T0 = (T0 & ~3) | (T1 & 3);
1195
 
        T1 = CC_Z;
1196
 
   } else {
1197
 
        T1 = 0;
1198
 
    }
1199
 
    FORCE_RET();
1200
 
}
1201
 
 
1202
 
void OPPROTO op_arpl_update(void)
1203
 
{
1204
 
    int eflags;
1205
 
    eflags = cc_table[CC_OP].compute_all();
1206
 
    CC_SRC = (eflags & ~CC_Z) | T1;
1207
 
}
1208
 
 
1209
 
/* T0: segment, T1:eip */
1210
 
void OPPROTO op_ljmp_protected_T0_T1(void)
1211
 
{
1212
 
    helper_ljmp_protected_T0_T1(PARAM1);
1213
 
}
1214
 
 
1215
 
void OPPROTO op_lcall_real_T0_T1(void)
1216
 
{
1217
 
    helper_lcall_real_T0_T1(PARAM1, PARAM2);
1218
 
}
1219
 
 
1220
 
void OPPROTO op_lcall_protected_T0_T1(void)
1221
 
{
1222
 
    helper_lcall_protected_T0_T1(PARAM1, PARAM2);
1223
 
}
1224
 
 
1225
 
void OPPROTO op_iret_real(void)
1226
 
{
1227
 
    helper_iret_real(PARAM1);
1228
 
}
1229
 
 
1230
 
void OPPROTO op_iret_protected(void)
1231
 
{
1232
 
    helper_iret_protected(PARAM1, PARAM2);
1233
 
}
1234
 
 
1235
 
void OPPROTO op_lret_protected(void)
1236
 
{
1237
 
    helper_lret_protected(PARAM1, PARAM2);
1238
 
}
1239
 
 
1240
 
void OPPROTO op_lldt_T0(void)
1241
 
{
1242
 
    helper_lldt_T0();
1243
 
}
1244
 
 
1245
 
void OPPROTO op_ltr_T0(void)
1246
 
{
1247
 
    helper_ltr_T0();
1248
 
}
1249
 
 
1250
 
/* CR registers access. */
1251
 
void OPPROTO op_movl_crN_T0(void)
1252
 
{
1253
 
    helper_movl_crN_T0(PARAM1);
1254
 
}
1255
 
 
1256
 
/* These pseudo-opcodes check for SVM intercepts. */
1257
 
void OPPROTO op_svm_check_intercept(void)
1258
 
{
1259
 
    A0 = PARAM1 & PARAM2;
1260
 
    svm_check_intercept(PARAMQ1);
1261
 
}
1262
 
 
1263
 
void OPPROTO op_svm_check_intercept_param(void)
1264
 
{
1265
 
    A0 = PARAM1 & PARAM2;
1266
 
    svm_check_intercept_param(PARAMQ1, T1);
1267
 
}
1268
 
 
1269
 
void OPPROTO op_svm_vmexit(void)
1270
 
{
1271
 
    A0 = PARAM1 & PARAM2;
1272
 
    vmexit(PARAMQ1, T1);
1273
 
}
1274
 
 
1275
 
void OPPROTO op_geneflags(void)
1276
 
{
1277
 
    CC_SRC = cc_table[CC_OP].compute_all();
1278
 
}
1279
 
 
1280
 
/* This pseudo-opcode checks for IO intercepts. */
1281
 
#if !defined(CONFIG_USER_ONLY)
1282
 
void OPPROTO op_svm_check_intercept_io(void)
1283
 
{
1284
 
    A0 = PARAM1 & PARAM2;
1285
 
    /* PARAMQ1 = TYPE (0 = OUT, 1 = IN; 4 = STRING; 8 = REP)
1286
 
       T0      = PORT
1287
 
       T1      = next eip */
1288
 
    stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), T1);
1289
 
    /* ASIZE does not appear on real hw */
1290
 
    svm_check_intercept_param(SVM_EXIT_IOIO,
1291
 
                              (PARAMQ1 & ~SVM_IOIO_ASIZE_MASK) |
1292
 
                              ((T0 & 0xffff) << 16));
1293
 
}
1294
 
#endif
1295
 
 
1296
 
#if !defined(CONFIG_USER_ONLY)
1297
 
void OPPROTO op_movtl_T0_cr8(void)
1298
 
{
1299
 
    T0 = cpu_get_apic_tpr(env);
1300
 
}
1301
 
#endif
1302
 
 
1303
 
/* DR registers access */
1304
 
void OPPROTO op_movl_drN_T0(void)
1305
 
{
1306
 
    helper_movl_drN_T0(PARAM1);
1307
 
}
1308
 
 
1309
 
void OPPROTO op_lmsw_T0(void)
1310
 
{
1311
 
    /* only 4 lower bits of CR0 are modified. PE cannot be set to zero
1312
 
       if already set to one. */
1313
 
    T0 = (env->cr[0] & ~0xe) | (T0 & 0xf);
1314
 
    helper_movl_crN_T0(0);
1315
 
}
1316
 
 
1317
 
void OPPROTO op_invlpg_A0(void)
1318
 
{
1319
 
    helper_invlpg(A0);
1320
 
}
1321
 
 
1322
 
void OPPROTO op_movl_T0_env(void)
1323
 
{
1324
 
    T0 = *(uint32_t *)((char *)env + PARAM1);
1325
 
}
1326
 
 
1327
 
void OPPROTO op_movl_env_T0(void)
1328
 
{
1329
 
    *(uint32_t *)((char *)env + PARAM1) = T0;
1330
 
}
1331
 
 
1332
 
void OPPROTO op_movl_env_T1(void)
1333
 
{
1334
 
    *(uint32_t *)((char *)env + PARAM1) = T1;
1335
 
}
1336
 
 
1337
 
void OPPROTO op_movtl_T0_env(void)
1338
 
{
1339
 
    T0 = *(target_ulong *)((char *)env + PARAM1);
1340
 
}
1341
 
 
1342
 
void OPPROTO op_movtl_env_T0(void)
1343
 
{
1344
 
    *(target_ulong *)((char *)env + PARAM1) = T0;
1345
 
}
1346
 
 
1347
 
void OPPROTO op_movtl_T1_env(void)
1348
 
{
1349
 
    T1 = *(target_ulong *)((char *)env + PARAM1);
1350
 
}
1351
 
 
1352
 
void OPPROTO op_movtl_env_T1(void)
1353
 
{
1354
 
    *(target_ulong *)((char *)env + PARAM1) = T1;
1355
 
}
1356
 
 
1357
 
void OPPROTO op_clts(void)
1358
 
{
1359
 
    env->cr[0] &= ~CR0_TS_MASK;
1360
 
    env->hflags &= ~HF_TS_MASK;
1361
 
}
1362
 
 
1363
 
/* flags handling */
1364
 
 
1365
 
void OPPROTO op_goto_tb0(void)
1366
 
{
1367
 
    GOTO_TB(op_goto_tb0, PARAM1, 0);
1368
 
}
1369
 
 
1370
 
void OPPROTO op_goto_tb1(void)
1371
 
{
1372
 
    GOTO_TB(op_goto_tb1, PARAM1, 1);
1373
 
}
1374
 
 
1375
 
void OPPROTO op_jmp_label(void)
1376
 
{
1377
 
    GOTO_LABEL_PARAM(1);
1378
 
}
1379
 
 
1380
 
void OPPROTO op_jnz_T0_label(void)
1381
 
{
1382
 
    if (T0)
1383
 
        GOTO_LABEL_PARAM(1);
1384
 
    FORCE_RET();
1385
 
}
1386
 
 
1387
 
void OPPROTO op_jz_T0_label(void)
1388
 
{
1389
 
    if (!T0)
1390
 
        GOTO_LABEL_PARAM(1);
1391
 
    FORCE_RET();
1392
 
}
1393
 
 
1394
 
/* slow set cases (compute x86 flags) */
1395
 
void OPPROTO op_seto_T0_cc(void)
1396
 
{
1397
 
    int eflags;
1398
 
    eflags = cc_table[CC_OP].compute_all();
1399
 
    T0 = (eflags >> 11) & 1;
1400
 
}
1401
 
 
1402
 
void OPPROTO op_setb_T0_cc(void)
1403
 
{
1404
 
    T0 = cc_table[CC_OP].compute_c();
1405
 
}
1406
 
 
1407
 
void OPPROTO op_setz_T0_cc(void)
1408
 
{
1409
 
    int eflags;
1410
 
    eflags = cc_table[CC_OP].compute_all();
1411
 
    T0 = (eflags >> 6) & 1;
1412
 
}
1413
 
 
1414
 
void OPPROTO op_setbe_T0_cc(void)
1415
 
{
1416
 
    int eflags;
1417
 
    eflags = cc_table[CC_OP].compute_all();
1418
 
    T0 = (eflags & (CC_Z | CC_C)) != 0;
1419
 
}
1420
 
 
1421
 
void OPPROTO op_sets_T0_cc(void)
1422
 
{
1423
 
    int eflags;
1424
 
    eflags = cc_table[CC_OP].compute_all();
1425
 
    T0 = (eflags >> 7) & 1;
1426
 
}
1427
 
 
1428
 
void OPPROTO op_setp_T0_cc(void)
1429
 
{
1430
 
    int eflags;
1431
 
    eflags = cc_table[CC_OP].compute_all();
1432
 
    T0 = (eflags >> 2) & 1;
1433
 
}
1434
 
 
1435
 
void OPPROTO op_setl_T0_cc(void)
1436
 
{
1437
 
    int eflags;
1438
 
    eflags = cc_table[CC_OP].compute_all();
1439
 
    T0 = ((eflags ^ (eflags >> 4)) >> 7) & 1;
1440
 
}
1441
 
 
1442
 
void OPPROTO op_setle_T0_cc(void)
1443
 
{
1444
 
    int eflags;
1445
 
    eflags = cc_table[CC_OP].compute_all();
1446
 
    T0 = (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) != 0;
1447
 
}
1448
 
 
1449
 
void OPPROTO op_xor_T0_1(void)
1450
 
{
1451
 
    T0 ^= 1;
1452
 
}
1453
 
 
1454
 
void OPPROTO op_set_cc_op(void)
1455
 
{
1456
 
    CC_OP = PARAM1;
1457
 
}
1458
 
 
1459
 
void OPPROTO op_mov_T0_cc(void)
1460
 
{
1461
 
    T0 = cc_table[CC_OP].compute_all();
1462
 
}
1463
 
 
1464
 
/* XXX: clear VIF/VIP in all ops ? */
1465
 
 
1466
 
void OPPROTO op_movl_eflags_T0(void)
1467
 
{
1468
 
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK));
1469
 
}
1470
 
 
1471
 
void OPPROTO op_movw_eflags_T0(void)
1472
 
{
1473
 
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff);
1474
 
}
1475
 
 
1476
 
void OPPROTO op_movl_eflags_T0_io(void)
1477
 
{
1478
 
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK));
1479
 
}
1480
 
 
1481
 
void OPPROTO op_movw_eflags_T0_io(void)
1482
 
{
1483
 
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff);
1484
 
}
1485
 
 
1486
 
void OPPROTO op_movl_eflags_T0_cpl0(void)
1487
 
{
1488
 
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK));
1489
 
}
1490
 
 
1491
 
void OPPROTO op_movw_eflags_T0_cpl0(void)
1492
 
{
1493
 
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff);
1494
 
}
1495
 
 
1496
 
#if 0
1497
 
/* vm86plus version */
1498
 
void OPPROTO op_movw_eflags_T0_vm(void)
1499
 
{
1500
 
    int eflags;
1501
 
    eflags = T0;
1502
 
    CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1503
 
    DF = 1 - (2 * ((eflags >> 10) & 1));
1504
 
    /* we also update some system flags as in user mode */
1505
 
    env->eflags = (env->eflags & ~(FL_UPDATE_MASK16 | VIF_MASK)) |
1506
 
        (eflags & FL_UPDATE_MASK16);
1507
 
    if (eflags & IF_MASK) {
1508
 
        env->eflags |= VIF_MASK;
1509
 
        if (env->eflags & VIP_MASK) {
1510
 
            EIP = PARAM1;
1511
 
            raise_exception(EXCP0D_GPF);
1512
 
        }
1513
 
    }
1514
 
    FORCE_RET();
1515
 
}
1516
 
 
1517
 
void OPPROTO op_movl_eflags_T0_vm(void)
1518
 
{
1519
 
    int eflags;
1520
 
    eflags = T0;
1521
 
    CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1522
 
    DF = 1 - (2 * ((eflags >> 10) & 1));
1523
 
    /* we also update some system flags as in user mode */
1524
 
    env->eflags = (env->eflags & ~(FL_UPDATE_MASK32 | VIF_MASK)) |
1525
 
        (eflags & FL_UPDATE_MASK32);
1526
 
    if (eflags & IF_MASK) {
1527
 
        env->eflags |= VIF_MASK;
1528
 
        if (env->eflags & VIP_MASK) {
1529
 
            EIP = PARAM1;
1530
 
            raise_exception(EXCP0D_GPF);
1531
 
        }
1532
 
    }
1533
 
    FORCE_RET();
1534
 
}
1535
 
#endif
1536
 
 
1537
 
/* XXX: compute only O flag */
1538
 
void OPPROTO op_movb_eflags_T0(void)
1539
 
{
1540
 
    int of;
1541
 
    of = cc_table[CC_OP].compute_all() & CC_O;
1542
 
    CC_SRC = (T0 & (CC_S | CC_Z | CC_A | CC_P | CC_C)) | of;
1543
 
}
1544
 
 
1545
 
void OPPROTO op_movl_T0_eflags(void)
1546
 
{
1547
 
    int eflags;
1548
 
    eflags = cc_table[CC_OP].compute_all();
1549
 
    eflags |= (DF & DF_MASK);
1550
 
    eflags |= env->eflags & ~(VM_MASK | RF_MASK);
1551
 
    T0 = eflags;
1552
 
}
1553
 
 
1554
 
/* vm86plus version */
1555
 
#if 0
1556
 
void OPPROTO op_movl_T0_eflags_vm(void)
1557
 
{
1558
 
    int eflags;
1559
 
    eflags = cc_table[CC_OP].compute_all();
1560
 
    eflags |= (DF & DF_MASK);
1561
 
    eflags |= env->eflags & ~(VM_MASK | RF_MASK | IF_MASK);
1562
 
    if (env->eflags & VIF_MASK)
1563
 
        eflags |= IF_MASK;
1564
 
    T0 = eflags;
1565
 
}
1566
 
#endif
1567
 
 
1568
 
void OPPROTO op_cld(void)
1569
 
{
1570
 
    DF = 1;
1571
 
}
1572
 
 
1573
 
void OPPROTO op_std(void)
1574
 
{
1575
 
    DF = -1;
1576
 
}
1577
 
 
1578
 
void OPPROTO op_clc(void)
1579
 
{
1580
 
    int eflags;
1581
 
    eflags = cc_table[CC_OP].compute_all();
1582
 
    eflags &= ~CC_C;
1583
 
    CC_SRC = eflags;
1584
 
}
1585
 
 
1586
 
void OPPROTO op_stc(void)
1587
 
{
1588
 
    int eflags;
1589
 
    eflags = cc_table[CC_OP].compute_all();
1590
 
    eflags |= CC_C;
1591
 
    CC_SRC = eflags;
1592
 
}
1593
 
 
1594
 
void OPPROTO op_cmc(void)
1595
 
{
1596
 
    int eflags;
1597
 
    eflags = cc_table[CC_OP].compute_all();
1598
 
    eflags ^= CC_C;
1599
 
    CC_SRC = eflags;
1600
 
}
1601
 
 
1602
 
void OPPROTO op_salc(void)
1603
 
{
1604
 
    int cf;
1605
 
    cf = cc_table[CC_OP].compute_c();
1606
 
    EAX = (EAX & ~0xff) | ((-cf) & 0xff);
1607
 
}
1608
 
 
1609
 
static int compute_all_eflags(void)
1610
 
{
1611
 
    return CC_SRC;
1612
 
}
1613
 
 
1614
 
static int compute_c_eflags(void)
1615
 
{
1616
 
    return CC_SRC & CC_C;
1617
 
}
1618
 
 
1619
 
CCTable cc_table[CC_OP_NB] = {
1620
 
    [CC_OP_DYNAMIC] = { /* should never happen */ },
1621
 
 
1622
 
    [CC_OP_EFLAGS] = { compute_all_eflags, compute_c_eflags },
1623
 
 
1624
 
    [CC_OP_MULB] = { compute_all_mulb, compute_c_mull },
1625
 
    [CC_OP_MULW] = { compute_all_mulw, compute_c_mull },
1626
 
    [CC_OP_MULL] = { compute_all_mull, compute_c_mull },
1627
 
 
1628
 
    [CC_OP_ADDB] = { compute_all_addb, compute_c_addb },
1629
 
    [CC_OP_ADDW] = { compute_all_addw, compute_c_addw  },
1630
 
    [CC_OP_ADDL] = { compute_all_addl, compute_c_addl  },
1631
 
 
1632
 
    [CC_OP_ADCB] = { compute_all_adcb, compute_c_adcb },
1633
 
    [CC_OP_ADCW] = { compute_all_adcw, compute_c_adcw  },
1634
 
    [CC_OP_ADCL] = { compute_all_adcl, compute_c_adcl  },
1635
 
 
1636
 
    [CC_OP_SUBB] = { compute_all_subb, compute_c_subb  },
1637
 
    [CC_OP_SUBW] = { compute_all_subw, compute_c_subw  },
1638
 
    [CC_OP_SUBL] = { compute_all_subl, compute_c_subl  },
1639
 
 
1640
 
    [CC_OP_SBBB] = { compute_all_sbbb, compute_c_sbbb  },
1641
 
    [CC_OP_SBBW] = { compute_all_sbbw, compute_c_sbbw  },
1642
 
    [CC_OP_SBBL] = { compute_all_sbbl, compute_c_sbbl  },
1643
 
 
1644
 
    [CC_OP_LOGICB] = { compute_all_logicb, compute_c_logicb },
1645
 
    [CC_OP_LOGICW] = { compute_all_logicw, compute_c_logicw },
1646
 
    [CC_OP_LOGICL] = { compute_all_logicl, compute_c_logicl },
1647
 
 
1648
 
    [CC_OP_INCB] = { compute_all_incb, compute_c_incl },
1649
 
    [CC_OP_INCW] = { compute_all_incw, compute_c_incl },
1650
 
    [CC_OP_INCL] = { compute_all_incl, compute_c_incl },
1651
 
 
1652
 
    [CC_OP_DECB] = { compute_all_decb, compute_c_incl },
1653
 
    [CC_OP_DECW] = { compute_all_decw, compute_c_incl },
1654
 
    [CC_OP_DECL] = { compute_all_decl, compute_c_incl },
1655
 
 
1656
 
    [CC_OP_SHLB] = { compute_all_shlb, compute_c_shlb },
1657
 
    [CC_OP_SHLW] = { compute_all_shlw, compute_c_shlw },
1658
 
    [CC_OP_SHLL] = { compute_all_shll, compute_c_shll },
1659
 
 
1660
 
    [CC_OP_SARB] = { compute_all_sarb, compute_c_sarl },
1661
 
    [CC_OP_SARW] = { compute_all_sarw, compute_c_sarl },
1662
 
    [CC_OP_SARL] = { compute_all_sarl, compute_c_sarl },
1663
 
 
1664
 
#ifdef TARGET_X86_64
1665
 
    [CC_OP_MULQ] = { compute_all_mulq, compute_c_mull },
1666
 
 
1667
 
    [CC_OP_ADDQ] = { compute_all_addq, compute_c_addq  },
1668
 
 
1669
 
    [CC_OP_ADCQ] = { compute_all_adcq, compute_c_adcq  },
1670
 
 
1671
 
    [CC_OP_SUBQ] = { compute_all_subq, compute_c_subq  },
1672
 
 
1673
 
    [CC_OP_SBBQ] = { compute_all_sbbq, compute_c_sbbq  },
1674
 
 
1675
 
    [CC_OP_LOGICQ] = { compute_all_logicq, compute_c_logicq },
1676
 
 
1677
 
    [CC_OP_INCQ] = { compute_all_incq, compute_c_incl },
1678
 
 
1679
 
    [CC_OP_DECQ] = { compute_all_decq, compute_c_incl },
1680
 
 
1681
 
    [CC_OP_SHLQ] = { compute_all_shlq, compute_c_shlq },
1682
 
 
1683
 
    [CC_OP_SARQ] = { compute_all_sarq, compute_c_sarl },
1684
 
#endif
1685
 
};
1686
 
 
1687
 
/* floating point support. Some of the code for complicated x87
1688
 
   functions comes from the LGPL'ed x86 emulator found in the Willows
1689
 
   TWIN windows emulator. */
1690
 
 
1691
 
/* fp load FT0 */
1692
 
 
1693
 
void OPPROTO op_flds_FT0_A0(void)
1694
 
{
1695
 
#ifdef USE_FP_CONVERT
1696
 
    FP_CONVERT.i32 = ldl(A0);
1697
 
    FT0 = FP_CONVERT.f;
1698
 
#else
1699
 
    FT0 = ldfl(A0);
1700
 
#endif
1701
 
}
1702
 
 
1703
 
void OPPROTO op_fldl_FT0_A0(void)
1704
 
{
1705
 
#ifdef USE_FP_CONVERT
1706
 
    FP_CONVERT.i64 = ldq(A0);
1707
 
    FT0 = FP_CONVERT.d;
1708
 
#else
1709
 
    FT0 = ldfq(A0);
1710
 
#endif
1711
 
}
1712
 
 
1713
 
/* helpers are needed to avoid static constant reference. XXX: find a better way */
1714
 
#ifdef USE_INT_TO_FLOAT_HELPERS
1715
 
 
1716
 
void helper_fild_FT0_A0(void)
1717
 
{
1718
 
    FT0 = (CPU86_LDouble)ldsw(A0);
1719
 
}
1720
 
 
1721
 
void helper_fildl_FT0_A0(void)
1722
 
{
1723
 
    FT0 = (CPU86_LDouble)((int32_t)ldl(A0));
1724
 
}
1725
 
 
1726
 
void helper_fildll_FT0_A0(void)
1727
 
{
1728
 
    FT0 = (CPU86_LDouble)((int64_t)ldq(A0));
1729
 
}
1730
 
 
1731
 
void OPPROTO op_fild_FT0_A0(void)
1732
 
{
1733
 
    helper_fild_FT0_A0();
1734
 
}
1735
 
 
1736
 
void OPPROTO op_fildl_FT0_A0(void)
1737
 
{
1738
 
    helper_fildl_FT0_A0();
1739
 
}
1740
 
 
1741
 
void OPPROTO op_fildll_FT0_A0(void)
1742
 
{
1743
 
    helper_fildll_FT0_A0();
1744
 
}
1745
 
 
1746
 
#else
1747
 
 
1748
 
void OPPROTO op_fild_FT0_A0(void)
1749
 
{
1750
 
#ifdef USE_FP_CONVERT
1751
 
    FP_CONVERT.i32 = ldsw(A0);
1752
 
    FT0 = (CPU86_LDouble)FP_CONVERT.i32;
1753
 
#else
1754
 
    FT0 = (CPU86_LDouble)ldsw(A0);
1755
 
#endif
1756
 
}
1757
 
 
1758
 
void OPPROTO op_fildl_FT0_A0(void)
1759
 
{
1760
 
#ifdef USE_FP_CONVERT
1761
 
    FP_CONVERT.i32 = (int32_t) ldl(A0);
1762
 
    FT0 = (CPU86_LDouble)FP_CONVERT.i32;
1763
 
#else
1764
 
    FT0 = (CPU86_LDouble)((int32_t)ldl(A0));
1765
 
#endif
1766
 
}
1767
 
 
1768
 
void OPPROTO op_fildll_FT0_A0(void)
1769
 
{
1770
 
#ifdef USE_FP_CONVERT
1771
 
    FP_CONVERT.i64 = (int64_t) ldq(A0);
1772
 
    FT0 = (CPU86_LDouble)FP_CONVERT.i64;
1773
 
#else
1774
 
    FT0 = (CPU86_LDouble)((int64_t)ldq(A0));
1775
 
#endif
1776
 
}
1777
 
#endif
1778
 
 
1779
 
/* fp load ST0 */
1780
 
 
1781
 
void OPPROTO op_flds_ST0_A0(void)
1782
 
{
1783
 
    int new_fpstt;
1784
 
    new_fpstt = (env->fpstt - 1) & 7;
1785
 
#ifdef USE_FP_CONVERT
1786
 
    FP_CONVERT.i32 = ldl(A0);
1787
 
    env->fpregs[new_fpstt].d = FP_CONVERT.f;
1788
 
#else
1789
 
    env->fpregs[new_fpstt].d = ldfl(A0);
1790
 
#endif
1791
 
    env->fpstt = new_fpstt;
1792
 
    env->fptags[new_fpstt] = 0; /* validate stack entry */
1793
 
}
1794
 
 
1795
 
void OPPROTO op_fldl_ST0_A0(void)
1796
 
{
1797
 
    int new_fpstt;
1798
 
    new_fpstt = (env->fpstt - 1) & 7;
1799
 
#ifdef USE_FP_CONVERT
1800
 
    FP_CONVERT.i64 = ldq(A0);
1801
 
    env->fpregs[new_fpstt].d = FP_CONVERT.d;
1802
 
#else
1803
 
    env->fpregs[new_fpstt].d = ldfq(A0);
1804
 
#endif
1805
 
    env->fpstt = new_fpstt;
1806
 
    env->fptags[new_fpstt] = 0; /* validate stack entry */
1807
 
}
1808
 
 
1809
 
void OPPROTO op_fldt_ST0_A0(void)
1810
 
{
1811
 
    helper_fldt_ST0_A0();
1812
 
}
1813
 
 
1814
 
/* helpers are needed to avoid static constant reference. XXX: find a better way */
1815
 
#ifdef USE_INT_TO_FLOAT_HELPERS
1816
 
 
1817
 
void helper_fild_ST0_A0(void)
1818
 
{
1819
 
    int new_fpstt;
1820
 
    new_fpstt = (env->fpstt - 1) & 7;
1821
 
    env->fpregs[new_fpstt].d = (CPU86_LDouble)ldsw(A0);
1822
 
    env->fpstt = new_fpstt;
1823
 
    env->fptags[new_fpstt] = 0; /* validate stack entry */
1824
 
}
1825
 
 
1826
 
void helper_fildl_ST0_A0(void)
1827
 
{
1828
 
    int new_fpstt;
1829
 
    new_fpstt = (env->fpstt - 1) & 7;
1830
 
    env->fpregs[new_fpstt].d = (CPU86_LDouble)((int32_t)ldl(A0));
1831
 
    env->fpstt = new_fpstt;
1832
 
    env->fptags[new_fpstt] = 0; /* validate stack entry */
1833
 
}
1834
 
 
1835
 
void helper_fildll_ST0_A0(void)
1836
 
{
1837
 
    int new_fpstt;
1838
 
    new_fpstt = (env->fpstt - 1) & 7;
1839
 
    env->fpregs[new_fpstt].d = (CPU86_LDouble)((int64_t)ldq(A0));
1840
 
    env->fpstt = new_fpstt;
1841
 
    env->fptags[new_fpstt] = 0; /* validate stack entry */
1842
 
}
1843
 
 
1844
 
void OPPROTO op_fild_ST0_A0(void)
1845
 
{
1846
 
    helper_fild_ST0_A0();
1847
 
}
1848
 
 
1849
 
void OPPROTO op_fildl_ST0_A0(void)
1850
 
{
1851
 
    helper_fildl_ST0_A0();
1852
 
}
1853
 
 
1854
 
void OPPROTO op_fildll_ST0_A0(void)
1855
 
{
1856
 
    helper_fildll_ST0_A0();
1857
 
}
1858
 
 
1859
 
#else
1860
 
 
1861
 
void OPPROTO op_fild_ST0_A0(void)
1862
 
{
1863
 
    int new_fpstt;
1864
 
    new_fpstt = (env->fpstt - 1) & 7;
1865
 
#ifdef USE_FP_CONVERT
1866
 
    FP_CONVERT.i32 = ldsw(A0);
1867
 
    env->fpregs[new_fpstt].d = (CPU86_LDouble)FP_CONVERT.i32;
1868
 
#else
1869
 
    env->fpregs[new_fpstt].d = (CPU86_LDouble)ldsw(A0);
1870
 
#endif
1871
 
    env->fpstt = new_fpstt;
1872
 
    env->fptags[new_fpstt] = 0; /* validate stack entry */
1873
 
}
1874
 
 
1875
 
void OPPROTO op_fildl_ST0_A0(void)
1876
 
{
1877
 
    int new_fpstt;
1878
 
    new_fpstt = (env->fpstt - 1) & 7;
1879
 
#ifdef USE_FP_CONVERT
1880
 
    FP_CONVERT.i32 = (int32_t) ldl(A0);
1881
 
    env->fpregs[new_fpstt].d = (CPU86_LDouble)FP_CONVERT.i32;
1882
 
#else
1883
 
    env->fpregs[new_fpstt].d = (CPU86_LDouble)((int32_t)ldl(A0));
1884
 
#endif
1885
 
    env->fpstt = new_fpstt;
1886
 
    env->fptags[new_fpstt] = 0; /* validate stack entry */
1887
 
}
1888
 
 
1889
 
void OPPROTO op_fildll_ST0_A0(void)
1890
 
{
1891
 
    int new_fpstt;
1892
 
    new_fpstt = (env->fpstt - 1) & 7;
1893
 
#ifdef USE_FP_CONVERT
1894
 
    FP_CONVERT.i64 = (int64_t) ldq(A0);
1895
 
    env->fpregs[new_fpstt].d = (CPU86_LDouble)FP_CONVERT.i64;
1896
 
#else
1897
 
    env->fpregs[new_fpstt].d = (CPU86_LDouble)((int64_t)ldq(A0));
1898
 
#endif
1899
 
    env->fpstt = new_fpstt;
1900
 
    env->fptags[new_fpstt] = 0; /* validate stack entry */
1901
 
}
1902
 
 
1903
 
#endif
1904
 
 
1905
 
/* fp store */
1906
 
 
1907
 
void OPPROTO op_fsts_ST0_A0(void)
1908
 
{
1909
 
#ifdef USE_FP_CONVERT
1910
 
    FP_CONVERT.f = (float)ST0;
1911
 
    stfl(A0, FP_CONVERT.f);
1912
 
#else
1913
 
    stfl(A0, (float)ST0);
1914
 
#endif
1915
 
    FORCE_RET();
1916
 
}
1917
 
 
1918
 
void OPPROTO op_fstl_ST0_A0(void)
1919
 
{
1920
 
    stfq(A0, (double)ST0);
1921
 
    FORCE_RET();
1922
 
}
1923
 
 
1924
 
void OPPROTO op_fstt_ST0_A0(void)
1925
 
{
1926
 
    helper_fstt_ST0_A0();
1927
 
}
1928
 
 
1929
 
void OPPROTO op_fist_ST0_A0(void)
1930
 
{
1931
 
#if defined(__sparc__) && !defined(__sparc_v9__)
1932
 
    register CPU86_LDouble d asm("o0");
1933
 
#else
1934
 
    CPU86_LDouble d;
1935
 
#endif
1936
 
    int val;
1937
 
 
1938
 
    d = ST0;
1939
 
    val = floatx_to_int32(d, &env->fp_status);
1940
 
    if (val != (int16_t)val)
1941
 
        val = -32768;
1942
 
    stw(A0, val);
1943
 
    FORCE_RET();
1944
 
}
1945
 
 
1946
 
void OPPROTO op_fistl_ST0_A0(void)
1947
 
{
1948
 
#if defined(__sparc__) && !defined(__sparc_v9__)
1949
 
    register CPU86_LDouble d asm("o0");
1950
 
#else
1951
 
    CPU86_LDouble d;
1952
 
#endif
1953
 
    int val;
1954
 
 
1955
 
    d = ST0;
1956
 
    val = floatx_to_int32(d, &env->fp_status);
1957
 
    stl(A0, val);
1958
 
    FORCE_RET();
1959
 
}
1960
 
 
1961
 
void OPPROTO op_fistll_ST0_A0(void)
1962
 
{
1963
 
#if defined(__sparc__) && !defined(__sparc_v9__)
1964
 
    register CPU86_LDouble d asm("o0");
1965
 
#else
1966
 
    CPU86_LDouble d;
1967
 
#endif
1968
 
    int64_t val;
1969
 
 
1970
 
    d = ST0;
1971
 
    val = floatx_to_int64(d, &env->fp_status);
1972
 
    stq(A0, val);
1973
 
    FORCE_RET();
1974
 
}
1975
 
 
1976
 
void OPPROTO op_fistt_ST0_A0(void)
1977
 
{
1978
 
#if defined(__sparc__) && !defined(__sparc_v9__)
1979
 
    register CPU86_LDouble d asm("o0");
1980
 
#else
1981
 
    CPU86_LDouble d;
1982
 
#endif
1983
 
    int val;
1984
 
 
1985
 
    d = ST0;
1986
 
    val = floatx_to_int32_round_to_zero(d, &env->fp_status);
1987
 
    if (val != (int16_t)val)
1988
 
        val = -32768;
1989
 
    stw(A0, val);
1990
 
    FORCE_RET();
1991
 
}
1992
 
 
1993
 
void OPPROTO op_fisttl_ST0_A0(void)
1994
 
{
1995
 
#if defined(__sparc__) && !defined(__sparc_v9__)
1996
 
    register CPU86_LDouble d asm("o0");
1997
 
#else
1998
 
    CPU86_LDouble d;
1999
 
#endif
2000
 
    int val;
2001
 
 
2002
 
    d = ST0;
2003
 
    val = floatx_to_int32_round_to_zero(d, &env->fp_status);
2004
 
    stl(A0, val);
2005
 
    FORCE_RET();
2006
 
}
2007
 
 
2008
 
void OPPROTO op_fisttll_ST0_A0(void)
2009
 
{
2010
 
#if defined(__sparc__) && !defined(__sparc_v9__)
2011
 
    register CPU86_LDouble d asm("o0");
2012
 
#else
2013
 
    CPU86_LDouble d;
2014
 
#endif
2015
 
    int64_t val;
2016
 
 
2017
 
    d = ST0;
2018
 
    val = floatx_to_int64_round_to_zero(d, &env->fp_status);
2019
 
    stq(A0, val);
2020
 
    FORCE_RET();
2021
 
}
2022
 
 
2023
 
void OPPROTO op_fbld_ST0_A0(void)
2024
 
{
2025
 
    helper_fbld_ST0_A0();
2026
 
}
2027
 
 
2028
 
void OPPROTO op_fbst_ST0_A0(void)
2029
 
{
2030
 
    helper_fbst_ST0_A0();
2031
 
}
2032
 
 
2033
 
/* FPU move */
2034
 
 
2035
 
void OPPROTO op_fpush(void)
2036
 
{
2037
 
    fpush();
2038
 
}
2039
 
 
2040
 
void OPPROTO op_fpop(void)
2041
 
{
2042
 
    fpop();
2043
 
}
2044
 
 
2045
 
void OPPROTO op_fdecstp(void)
2046
 
{
2047
 
    env->fpstt = (env->fpstt - 1) & 7;
2048
 
    env->fpus &= (~0x4700);
2049
 
}
2050
 
 
2051
 
void OPPROTO op_fincstp(void)
2052
 
{
2053
 
    env->fpstt = (env->fpstt + 1) & 7;
2054
 
    env->fpus &= (~0x4700);
2055
 
}
2056
 
 
2057
 
void OPPROTO op_ffree_STN(void)
2058
 
{
2059
 
    env->fptags[(env->fpstt + PARAM1) & 7] = 1;
2060
 
}
2061
 
 
2062
 
void OPPROTO op_fmov_ST0_FT0(void)
2063
 
{
2064
 
    ST0 = FT0;
2065
 
}
2066
 
 
2067
 
void OPPROTO op_fmov_FT0_STN(void)
2068
 
{
2069
 
    FT0 = ST(PARAM1);
2070
 
}
2071
 
 
2072
 
void OPPROTO op_fmov_ST0_STN(void)
2073
 
{
2074
 
    ST0 = ST(PARAM1);
2075
 
}
2076
 
 
2077
 
void OPPROTO op_fmov_STN_ST0(void)
2078
 
{
2079
 
    ST(PARAM1) = ST0;
2080
 
}
2081
 
 
2082
 
void OPPROTO op_fxchg_ST0_STN(void)
2083
 
{
2084
 
    CPU86_LDouble tmp;
2085
 
    tmp = ST(PARAM1);
2086
 
    ST(PARAM1) = ST0;
2087
 
    ST0 = tmp;
2088
 
}
2089
 
 
2090
 
/* FPU operations */
2091
 
 
2092
 
const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500};
2093
 
 
2094
 
void OPPROTO op_fcom_ST0_FT0(void)
2095
 
{
2096
 
    int ret;
2097
 
 
2098
 
    ret = floatx_compare(ST0, FT0, &env->fp_status);
2099
 
    env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1];
2100
 
    FORCE_RET();
2101
 
}
2102
 
 
2103
 
void OPPROTO op_fucom_ST0_FT0(void)
2104
 
{
2105
 
    int ret;
2106
 
 
2107
 
    ret = floatx_compare_quiet(ST0, FT0, &env->fp_status);
2108
 
    env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret+ 1];
2109
 
    FORCE_RET();
2110
 
}
2111
 
 
2112
 
const int fcomi_ccval[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C};
2113
 
 
2114
 
void OPPROTO op_fcomi_ST0_FT0(void)
2115
 
{
2116
 
    int eflags;
2117
 
    int ret;
2118
 
 
2119
 
    ret = floatx_compare(ST0, FT0, &env->fp_status);
2120
 
    eflags = cc_table[CC_OP].compute_all();
2121
 
    eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
2122
 
    CC_SRC = eflags;
2123
 
    FORCE_RET();
2124
 
}
2125
 
 
2126
 
void OPPROTO op_fucomi_ST0_FT0(void)
2127
 
{
2128
 
    int eflags;
2129
 
    int ret;
2130
 
 
2131
 
    ret = floatx_compare_quiet(ST0, FT0, &env->fp_status);
2132
 
    eflags = cc_table[CC_OP].compute_all();
2133
 
    eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
2134
 
    CC_SRC = eflags;
2135
 
    FORCE_RET();
2136
 
}
2137
 
 
2138
 
void OPPROTO op_fcmov_ST0_STN_T0(void)
2139
 
{
2140
 
    if (T0) {
2141
 
        ST0 = ST(PARAM1);
2142
 
    }
2143
 
    FORCE_RET();
2144
 
}
2145
 
 
2146
 
void OPPROTO op_fadd_ST0_FT0(void)
2147
 
{
2148
 
    ST0 += FT0;
2149
 
}
2150
 
 
2151
 
void OPPROTO op_fmul_ST0_FT0(void)
2152
 
{
2153
 
    ST0 *= FT0;
2154
 
}
2155
 
 
2156
 
void OPPROTO op_fsub_ST0_FT0(void)
2157
 
{
2158
 
    ST0 -= FT0;
2159
 
}
2160
 
 
2161
 
void OPPROTO op_fsubr_ST0_FT0(void)
2162
 
{
2163
 
    ST0 = FT0 - ST0;
2164
 
}
2165
 
 
2166
 
void OPPROTO op_fdiv_ST0_FT0(void)
2167
 
{
2168
 
    ST0 = helper_fdiv(ST0, FT0);
2169
 
}
2170
 
 
2171
 
void OPPROTO op_fdivr_ST0_FT0(void)
2172
 
{
2173
 
    ST0 = helper_fdiv(FT0, ST0);
2174
 
}
2175
 
 
2176
 
/* fp operations between STN and ST0 */
2177
 
 
2178
 
void OPPROTO op_fadd_STN_ST0(void)
2179
 
{
2180
 
    ST(PARAM1) += ST0;
2181
 
}
2182
 
 
2183
 
void OPPROTO op_fmul_STN_ST0(void)
2184
 
{
2185
 
    ST(PARAM1) *= ST0;
2186
 
}
2187
 
 
2188
 
void OPPROTO op_fsub_STN_ST0(void)
2189
 
{
2190
 
    ST(PARAM1) -= ST0;
2191
 
}
2192
 
 
2193
 
void OPPROTO op_fsubr_STN_ST0(void)
2194
 
{
2195
 
    CPU86_LDouble *p;
2196
 
    p = &ST(PARAM1);
2197
 
    *p = ST0 - *p;
2198
 
}
2199
 
 
2200
 
void OPPROTO op_fdiv_STN_ST0(void)
2201
 
{
2202
 
    CPU86_LDouble *p;
2203
 
    p = &ST(PARAM1);
2204
 
    *p = helper_fdiv(*p, ST0);
2205
 
}
2206
 
 
2207
 
void OPPROTO op_fdivr_STN_ST0(void)
2208
 
{
2209
 
    CPU86_LDouble *p;
2210
 
    p = &ST(PARAM1);
2211
 
    *p = helper_fdiv(ST0, *p);
2212
 
}
2213
 
 
2214
 
/* misc FPU operations */
2215
 
void OPPROTO op_fchs_ST0(void)
2216
 
{
2217
 
    ST0 = floatx_chs(ST0);
2218
 
}
2219
 
 
2220
 
void OPPROTO op_fabs_ST0(void)
2221
 
{
2222
 
    ST0 = floatx_abs(ST0);
2223
 
}
2224
 
 
2225
 
void OPPROTO op_fxam_ST0(void)
2226
 
{
2227
 
    helper_fxam_ST0();
2228
 
}
2229
 
 
2230
 
void OPPROTO op_fld1_ST0(void)
2231
 
{
2232
 
    ST0 = f15rk[1];
2233
 
}
2234
 
 
2235
 
void OPPROTO op_fldl2t_ST0(void)
2236
 
{
2237
 
    ST0 = f15rk[6];
2238
 
}
2239
 
 
2240
 
void OPPROTO op_fldl2e_ST0(void)
2241
 
{
2242
 
    ST0 = f15rk[5];
2243
 
}
2244
 
 
2245
 
void OPPROTO op_fldpi_ST0(void)
2246
 
{
2247
 
    ST0 = f15rk[2];
2248
 
}
2249
 
 
2250
 
void OPPROTO op_fldlg2_ST0(void)
2251
 
{
2252
 
    ST0 = f15rk[3];
2253
 
}
2254
 
 
2255
 
void OPPROTO op_fldln2_ST0(void)
2256
 
{
2257
 
    ST0 = f15rk[4];
2258
 
}
2259
 
 
2260
 
void OPPROTO op_fldz_ST0(void)
2261
 
{
2262
 
    ST0 = f15rk[0];
2263
 
}
2264
 
 
2265
 
void OPPROTO op_fldz_FT0(void)
2266
 
{
2267
 
    FT0 = f15rk[0];
2268
 
}
2269
 
 
2270
 
/* associated heplers to reduce generated code length and to simplify
2271
 
   relocation (FP constants are usually stored in .rodata section) */
2272
 
 
2273
 
void OPPROTO op_f2xm1(void)
2274
 
{
2275
 
    helper_f2xm1();
2276
 
}
2277
 
 
2278
 
void OPPROTO op_fyl2x(void)
2279
 
{
2280
 
    helper_fyl2x();
2281
 
}
2282
 
 
2283
 
void OPPROTO op_fptan(void)
2284
 
{
2285
 
    helper_fptan();
2286
 
}
2287
 
 
2288
 
void OPPROTO op_fpatan(void)
2289
 
{
2290
 
    helper_fpatan();
2291
 
}
2292
 
 
2293
 
void OPPROTO op_fxtract(void)
2294
 
{
2295
 
    helper_fxtract();
2296
 
}
2297
 
 
2298
 
void OPPROTO op_fprem1(void)
2299
 
{
2300
 
    helper_fprem1();
2301
 
}
2302
 
 
2303
 
 
2304
 
void OPPROTO op_fprem(void)
2305
 
{
2306
 
    helper_fprem();
2307
 
}
2308
 
 
2309
 
void OPPROTO op_fyl2xp1(void)
2310
 
{
2311
 
    helper_fyl2xp1();
2312
 
}
2313
 
 
2314
 
void OPPROTO op_fsqrt(void)
2315
 
{
2316
 
    helper_fsqrt();
2317
 
}
2318
 
 
2319
 
void OPPROTO op_fsincos(void)
2320
 
{
2321
 
    helper_fsincos();
2322
 
}
2323
 
 
2324
 
void OPPROTO op_frndint(void)
2325
 
{
2326
 
    helper_frndint();
2327
 
}
2328
 
 
2329
 
void OPPROTO op_fscale(void)
2330
 
{
2331
 
    helper_fscale();
2332
 
}
2333
 
 
2334
 
void OPPROTO op_fsin(void)
2335
 
{
2336
 
    helper_fsin();
2337
 
}
2338
 
 
2339
 
void OPPROTO op_fcos(void)
2340
 
{
2341
 
    helper_fcos();
2342
 
}
2343
 
 
2344
 
void OPPROTO op_fnstsw_A0(void)
2345
 
{
2346
 
    int fpus;
2347
 
    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
2348
 
    stw(A0, fpus);
2349
 
    FORCE_RET();
2350
 
}
2351
 
 
2352
 
void OPPROTO op_fnstsw_EAX(void)
2353
 
{
2354
 
    int fpus;
2355
 
    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
2356
 
    EAX = (EAX & ~0xffff) | fpus;
2357
 
}
2358
 
 
2359
 
void OPPROTO op_fnstcw_A0(void)
2360
 
{
2361
 
    stw(A0, env->fpuc);
2362
 
    FORCE_RET();
2363
 
}
2364
 
 
2365
 
void OPPROTO op_fldcw_A0(void)
2366
 
{
2367
 
    env->fpuc = lduw(A0);
2368
 
    update_fp_status();
2369
 
}
2370
 
 
2371
 
void OPPROTO op_fclex(void)
2372
 
{
2373
 
    env->fpus &= 0x7f00;
2374
 
}
2375
 
 
2376
 
void OPPROTO op_fwait(void)
2377
 
{
2378
 
    if (env->fpus & FPUS_SE)
2379
 
        fpu_raise_exception();
2380
 
    FORCE_RET();
2381
 
}
2382
 
 
2383
 
void OPPROTO op_fninit(void)
2384
 
{
2385
 
    env->fpus = 0;
2386
 
    env->fpstt = 0;
2387
 
    env->fpuc = 0x37f;
2388
 
    env->fptags[0] = 1;
2389
 
    env->fptags[1] = 1;
2390
 
    env->fptags[2] = 1;
2391
 
    env->fptags[3] = 1;
2392
 
    env->fptags[4] = 1;
2393
 
    env->fptags[5] = 1;
2394
 
    env->fptags[6] = 1;
2395
 
    env->fptags[7] = 1;
2396
 
}
2397
 
 
2398
 
void OPPROTO op_fnstenv_A0(void)
2399
 
{
2400
 
    helper_fstenv(A0, PARAM1);
2401
 
}
2402
 
 
2403
 
void OPPROTO op_fldenv_A0(void)
2404
 
{
2405
 
    helper_fldenv(A0, PARAM1);
2406
 
}
2407
 
 
2408
 
void OPPROTO op_fnsave_A0(void)
2409
 
{
2410
 
    helper_fsave(A0, PARAM1);
2411
 
}
2412
 
 
2413
 
void OPPROTO op_frstor_A0(void)
2414
 
{
2415
 
    helper_frstor(A0, PARAM1);
2416
 
}
2417
 
 
2418
 
/* threading support */
2419
 
void OPPROTO op_lock(void)
2420
 
{
2421
 
    cpu_lock();
2422
 
}
2423
 
 
2424
 
void OPPROTO op_unlock(void)
2425
 
{
2426
 
    cpu_unlock();
2427
 
}
2428
 
 
2429
 
/* SSE support */
2430
 
static inline void memcpy16(void *d, void *s)
2431
 
{
2432
 
    ((uint32_t *)d)[0] = ((uint32_t *)s)[0];
2433
 
    ((uint32_t *)d)[1] = ((uint32_t *)s)[1];
2434
 
    ((uint32_t *)d)[2] = ((uint32_t *)s)[2];
2435
 
    ((uint32_t *)d)[3] = ((uint32_t *)s)[3];
2436
 
}
2437
 
 
2438
 
void OPPROTO op_movo(void)
2439
 
{
2440
 
    /* XXX: badly generated code */
2441
 
    XMMReg *d, *s;
2442
 
    d = (XMMReg *)((char *)env + PARAM1);
2443
 
    s = (XMMReg *)((char *)env + PARAM2);
2444
 
    memcpy16(d, s);
2445
 
}
2446
 
 
2447
 
void OPPROTO op_movq(void)
2448
 
{
2449
 
    uint64_t *d, *s;
2450
 
    d = (uint64_t *)((char *)env + PARAM1);
2451
 
    s = (uint64_t *)((char *)env + PARAM2);
2452
 
    *d = *s;
2453
 
}
2454
 
 
2455
 
void OPPROTO op_movl(void)
2456
 
{
2457
 
    uint32_t *d, *s;
2458
 
    d = (uint32_t *)((char *)env + PARAM1);
2459
 
    s = (uint32_t *)((char *)env + PARAM2);
2460
 
    *d = *s;
2461
 
}
2462
 
 
2463
 
void OPPROTO op_movq_env_0(void)
2464
 
{
2465
 
    uint64_t *d;
2466
 
    d = (uint64_t *)((char *)env + PARAM1);
2467
 
    *d = 0;
2468
 
}
2469
 
 
2470
 
void OPPROTO op_fxsave_A0(void)
2471
 
{
2472
 
    helper_fxsave(A0, PARAM1);
2473
 
}
2474
 
 
2475
 
void OPPROTO op_fxrstor_A0(void)
2476
 
{
2477
 
    helper_fxrstor(A0, PARAM1);
2478
 
}
2479
 
 
2480
 
/* XXX: optimize by storing fptt and fptags in the static cpu state */
2481
 
void OPPROTO op_enter_mmx(void)
2482
 
{
2483
 
    env->fpstt = 0;
2484
 
    *(uint32_t *)(env->fptags) = 0;
2485
 
    *(uint32_t *)(env->fptags + 4) = 0;
2486
 
}
2487
 
 
2488
 
void OPPROTO op_emms(void)
2489
 
{
2490
 
    /* set to empty state */
2491
 
    *(uint32_t *)(env->fptags) = 0x01010101;
2492
 
    *(uint32_t *)(env->fptags + 4) = 0x01010101;
2493
 
}
2494
 
 
2495
 
#define SHIFT 0
2496
 
#include "ops_sse.h"
2497
 
 
2498
 
#define SHIFT 1
2499
 
#include "ops_sse.h"
2500
 
 
2501
 
/* Secure Virtual Machine ops */
2502
 
 
2503
 
void OPPROTO op_vmrun(void)
2504
 
{
2505
 
    helper_vmrun(EAX);
2506
 
}
2507
 
 
2508
 
void OPPROTO op_vmmcall(void)
2509
 
{
2510
 
    helper_vmmcall();
2511
 
}
2512
 
 
2513
 
void OPPROTO op_vmload(void)
2514
 
{
2515
 
    helper_vmload(EAX);
2516
 
}
2517
 
 
2518
 
void OPPROTO op_vmsave(void)
2519
 
{
2520
 
    helper_vmsave(EAX);
2521
 
}
2522
 
 
2523
 
void OPPROTO op_stgi(void)
2524
 
{
2525
 
    helper_stgi();
2526
 
}
2527
 
 
2528
 
void OPPROTO op_clgi(void)
2529
 
{
2530
 
    helper_clgi();
2531
 
}
2532
 
 
2533
 
void OPPROTO op_skinit(void)
2534
 
{
2535
 
    helper_skinit();
2536
 
}
2537
 
 
2538
 
void OPPROTO op_invlpga(void)
2539
 
{
2540
 
    helper_invlpga();
2541
 
}