Revision 3b46e624 target-i386/helper.c
b/target-i386/helper.c | ||
---|---|---|
91 | 91 |
1.44269504088896340739L, /*l2e*/ |
92 | 92 |
3.32192809488736234781L, /*l2t*/ |
93 | 93 |
}; |
94 |
|
|
94 |
|
|
95 | 95 |
/* thread support */ |
96 | 96 |
|
97 | 97 |
spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED; |
... | ... | |
126 | 126 |
*e2_ptr = ldl_kernel(ptr + 4); |
127 | 127 |
return 0; |
128 | 128 |
} |
129 |
|
|
129 |
|
|
130 | 130 |
static inline unsigned int get_seg_limit(uint32_t e1, uint32_t e2) |
131 | 131 |
{ |
132 | 132 |
unsigned int limit; |
... | ... | |
160 | 160 |
uint32_t *esp_ptr, int dpl) |
161 | 161 |
{ |
162 | 162 |
int type, index, shift; |
163 |
|
|
163 |
|
|
164 | 164 |
#if 0 |
165 | 165 |
{ |
166 | 166 |
int i; |
... | ... | |
325 | 325 |
new_segs[R_GS] = 0; |
326 | 326 |
new_trap = 0; |
327 | 327 |
} |
328 |
|
|
328 |
|
|
329 | 329 |
/* NOTE: we must avoid memory exceptions during the task switch, |
330 | 330 |
so we make dummy accesses before */ |
331 | 331 |
/* XXX: it can still fail in some cases, so a bigger hack is |
... | ... | |
335 | 335 |
v2 = ldub_kernel(env->tr.base + old_tss_limit_max); |
336 | 336 |
stb_kernel(env->tr.base, v1); |
337 | 337 |
stb_kernel(env->tr.base + old_tss_limit_max, v2); |
338 |
|
|
338 |
|
|
339 | 339 |
/* clear busy bit (it is restartable) */ |
340 | 340 |
if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_IRET) { |
341 | 341 |
target_ulong ptr; |
... | ... | |
348 | 348 |
old_eflags = compute_eflags(); |
349 | 349 |
if (source == SWITCH_TSS_IRET) |
350 | 350 |
old_eflags &= ~NT_MASK; |
351 |
|
|
351 |
|
|
352 | 352 |
/* save the current state in the old TSS */ |
353 | 353 |
if (type & 8) { |
354 | 354 |
/* 32 bit */ |
... | ... | |
379 | 379 |
for(i = 0; i < 4; i++) |
380 | 380 |
stw_kernel(env->tr.base + (0x22 + i * 4), env->segs[i].selector); |
381 | 381 |
} |
382 |
|
|
382 |
|
|
383 | 383 |
/* now if an exception occurs, it will occurs in the next task |
384 | 384 |
context */ |
385 | 385 |
|
... | ... | |
406 | 406 |
env->tr.base = tss_base; |
407 | 407 |
env->tr.limit = tss_limit; |
408 | 408 |
env->tr.flags = e2 & ~DESC_TSS_BUSY_MASK; |
409 |
|
|
409 |
|
|
410 | 410 |
if ((type & 8) && (env->cr[0] & CR0_PG_MASK)) { |
411 | 411 |
cpu_x86_update_cr3(env, new_cr3); |
412 | 412 |
} |
413 |
|
|
413 |
|
|
414 | 414 |
/* load all registers without an exception, then reload them with |
415 | 415 |
possible exception */ |
416 | 416 |
env->eip = new_eip; |
... | ... | |
440 | 440 |
for(i = 0; i < 6; i++) |
441 | 441 |
cpu_x86_load_seg_cache(env, i, new_segs[i], 0, 0, 0); |
442 | 442 |
} |
443 |
|
|
443 |
|
|
444 | 444 |
env->ldt.selector = new_ldt & ~4; |
445 | 445 |
env->ldt.base = 0; |
446 | 446 |
env->ldt.limit = 0; |
... | ... | |
464 | 464 |
raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc); |
465 | 465 |
load_seg_cache_raw_dt(&env->ldt, e1, e2); |
466 | 466 |
} |
467 |
|
|
467 |
|
|
468 | 468 |
/* load the segments */ |
469 | 469 |
if (!(new_eflags & VM_MASK)) { |
470 | 470 |
tss_load_seg(R_CS, new_segs[R_CS]); |
... | ... | |
474 | 474 |
tss_load_seg(R_FS, new_segs[R_FS]); |
475 | 475 |
tss_load_seg(R_GS, new_segs[R_GS]); |
476 | 476 |
} |
477 |
|
|
477 |
|
|
478 | 478 |
/* check that EIP is in the CS segment limits */ |
479 | 479 |
if (new_eip > env->segs[R_CS].limit) { |
480 | 480 |
/* XXX: different exception if CALL ? */ |
... | ... | |
486 | 486 |
static inline void check_io(int addr, int size) |
487 | 487 |
{ |
488 | 488 |
int io_offset, val, mask; |
489 |
|
|
489 |
|
|
490 | 490 |
/* TSS must be a valid 32 bit one */ |
491 | 491 |
if (!(env->tr.flags & DESC_P_MASK) || |
492 | 492 |
((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 || |
... | ... | |
760 | 760 |
PUSHW(ssp, esp, sp_mask, error_code); |
761 | 761 |
} |
762 | 762 |
} |
763 |
|
|
763 |
|
|
764 | 764 |
if (new_stack) { |
765 | 765 |
if (env->eflags & VM_MASK) { |
766 | 766 |
cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0, 0); |
... | ... | |
806 | 806 |
static inline target_ulong get_rsp_from_tss(int level) |
807 | 807 |
{ |
808 | 808 |
int index; |
809 |
|
|
809 |
|
|
810 | 810 |
#if 0 |
811 | 811 |
printf("TR: base=" TARGET_FMT_lx " limit=%x\n", |
812 | 812 |
env->tr.base, env->tr.limit); |
... | ... | |
926 | 926 |
if (has_error_code) { |
927 | 927 |
PUSHQ(esp, error_code); |
928 | 928 |
} |
929 |
|
|
929 |
|
|
930 | 930 |
if (new_stack) { |
931 | 931 |
ss = 0 | dpl; |
932 | 932 |
cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0); |
... | ... | |
963 | 963 |
|
964 | 964 |
ECX = env->eip + next_eip_addend; |
965 | 965 |
env->regs[11] = compute_eflags(); |
966 |
|
|
966 |
|
|
967 | 967 |
code64 = env->hflags & HF_CS64_MASK; |
968 | 968 |
|
969 | 969 |
cpu_x86_set_cpl(env, 0); |
... | ... | |
986 | 986 |
#endif |
987 | 987 |
{ |
988 | 988 |
ECX = (uint32_t)(env->eip + next_eip_addend); |
989 |
|
|
989 |
|
|
990 | 990 |
cpu_x86_set_cpl(env, 0); |
991 | 991 |
cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc, |
992 | 992 |
0, 0xffffffff, |
... | ... | |
1096 | 1096 |
PUSHW(ssp, esp, 0xffff, compute_eflags()); |
1097 | 1097 |
PUSHW(ssp, esp, 0xffff, old_cs); |
1098 | 1098 |
PUSHW(ssp, esp, 0xffff, old_eip); |
1099 |
|
|
1099 |
|
|
1100 | 1100 |
/* update processor state */ |
1101 | 1101 |
ESP = (ESP & ~0xffff) | (esp & 0xffff); |
1102 | 1102 |
env->eip = offset; |
... | ... | |
1117 | 1117 |
dt = &env->idt; |
1118 | 1118 |
ptr = dt->base + (intno * 8); |
1119 | 1119 |
e2 = ldl_kernel(ptr + 4); |
1120 |
|
|
1120 |
|
|
1121 | 1121 |
dpl = (e2 >> DESC_DPL_SHIFT) & 3; |
1122 | 1122 |
cpl = env->hflags & HF_CPL_MASK; |
1123 | 1123 |
/* check privledge if software int */ |
... | ... | |
1134 | 1134 |
/* |
1135 | 1135 |
* Begin execution of an interruption. is_int is TRUE if coming from |
1136 | 1136 |
* the int instruction. next_eip is the EIP value AFTER the interrupt |
1137 |
* instruction. It is only relevant if is_int is TRUE.
|
|
1137 |
* instruction. It is only relevant if is_int is TRUE. |
|
1138 | 1138 |
*/ |
1139 | 1139 |
void do_interrupt(int intno, int is_int, int error_code, |
1140 | 1140 |
target_ulong next_eip, int is_hw) |
... | ... | |
1222 | 1222 |
* Signal an interruption. It is executed in the main CPU loop. |
1223 | 1223 |
* is_int is TRUE if coming from the int instruction. next_eip is the |
1224 | 1224 |
* EIP value AFTER the interrupt instruction. It is only relevant if |
1225 |
* is_int is TRUE.
|
|
1225 |
* is_int is TRUE. |
|
1226 | 1226 |
*/ |
1227 | 1227 |
void raise_interrupt(int intno, int is_int, int error_code, |
1228 | 1228 |
int next_eip_addend) |
... | ... | |
1296 | 1296 |
cpu_smm_update(env); |
1297 | 1297 |
|
1298 | 1298 |
sm_state = env->smbase + 0x8000; |
1299 |
|
|
1299 |
|
|
1300 | 1300 |
#ifdef TARGET_X86_64 |
1301 | 1301 |
for(i = 0; i < 6; i++) { |
1302 | 1302 |
dt = &env->segs[i]; |
... | ... | |
1314 | 1314 |
stq_phys(sm_state + 0x7e78, env->ldt.base); |
1315 | 1315 |
stl_phys(sm_state + 0x7e74, env->ldt.limit); |
1316 | 1316 |
stw_phys(sm_state + 0x7e72, (env->ldt.flags >> 8) & 0xf0ff); |
1317 |
|
|
1317 |
|
|
1318 | 1318 |
stq_phys(sm_state + 0x7e88, env->idt.base); |
1319 | 1319 |
stl_phys(sm_state + 0x7e84, env->idt.limit); |
1320 | 1320 |
|
... | ... | |
1322 | 1322 |
stq_phys(sm_state + 0x7e98, env->tr.base); |
1323 | 1323 |
stl_phys(sm_state + 0x7e94, env->tr.limit); |
1324 | 1324 |
stw_phys(sm_state + 0x7e92, (env->tr.flags >> 8) & 0xf0ff); |
1325 |
|
|
1325 |
|
|
1326 | 1326 |
stq_phys(sm_state + 0x7ed0, env->efer); |
1327 | 1327 |
|
1328 | 1328 |
stq_phys(sm_state + 0x7ff8, EAX); |
... | ... | |
1361 | 1361 |
stl_phys(sm_state + 0x7fd0, EAX); |
1362 | 1362 |
stl_phys(sm_state + 0x7fcc, env->dr[6]); |
1363 | 1363 |
stl_phys(sm_state + 0x7fc8, env->dr[7]); |
1364 |
|
|
1364 |
|
|
1365 | 1365 |
stl_phys(sm_state + 0x7fc4, env->tr.selector); |
1366 | 1366 |
stl_phys(sm_state + 0x7f64, env->tr.base); |
1367 | 1367 |
stl_phys(sm_state + 0x7f60, env->tr.limit); |
1368 | 1368 |
stl_phys(sm_state + 0x7f5c, (env->tr.flags >> 8) & 0xf0ff); |
1369 |
|
|
1369 |
|
|
1370 | 1370 |
stl_phys(sm_state + 0x7fc0, env->ldt.selector); |
1371 | 1371 |
stl_phys(sm_state + 0x7f80, env->ldt.base); |
1372 | 1372 |
stl_phys(sm_state + 0x7f7c, env->ldt.limit); |
1373 | 1373 |
stl_phys(sm_state + 0x7f78, (env->ldt.flags >> 8) & 0xf0ff); |
1374 |
|
|
1374 |
|
|
1375 | 1375 |
stl_phys(sm_state + 0x7f74, env->gdt.base); |
1376 | 1376 |
stl_phys(sm_state + 0x7f70, env->gdt.limit); |
1377 | 1377 |
|
... | ... | |
1409 | 1409 |
cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff, 0); |
1410 | 1410 |
cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff, 0); |
1411 | 1411 |
cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff, 0); |
1412 |
|
|
1412 |
|
|
1413 | 1413 |
cpu_x86_update_cr0(env, |
1414 | 1414 |
env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK | CR0_PG_MASK)); |
1415 | 1415 |
cpu_x86_update_cr4(env, 0); |
... | ... | |
1447 | 1447 |
env->ldt.base = ldq_phys(sm_state + 0x7e78); |
1448 | 1448 |
env->ldt.limit = ldl_phys(sm_state + 0x7e74); |
1449 | 1449 |
env->ldt.flags = (lduw_phys(sm_state + 0x7e72) & 0xf0ff) << 8; |
1450 |
|
|
1450 |
|
|
1451 | 1451 |
env->idt.base = ldq_phys(sm_state + 0x7e88); |
1452 | 1452 |
env->idt.limit = ldl_phys(sm_state + 0x7e84); |
1453 | 1453 |
|
... | ... | |
1455 | 1455 |
env->tr.base = ldq_phys(sm_state + 0x7e98); |
1456 | 1456 |
env->tr.limit = ldl_phys(sm_state + 0x7e94); |
1457 | 1457 |
env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8; |
1458 |
|
|
1458 |
|
|
1459 | 1459 |
EAX = ldq_phys(sm_state + 0x7ff8); |
1460 | 1460 |
ECX = ldq_phys(sm_state + 0x7ff0); |
1461 | 1461 |
EDX = ldq_phys(sm_state + 0x7fe8); |
... | ... | |
1496 | 1496 |
EAX = ldl_phys(sm_state + 0x7fd0); |
1497 | 1497 |
env->dr[6] = ldl_phys(sm_state + 0x7fcc); |
1498 | 1498 |
env->dr[7] = ldl_phys(sm_state + 0x7fc8); |
1499 |
|
|
1499 |
|
|
1500 | 1500 |
env->tr.selector = ldl_phys(sm_state + 0x7fc4) & 0xffff; |
1501 | 1501 |
env->tr.base = ldl_phys(sm_state + 0x7f64); |
1502 | 1502 |
env->tr.limit = ldl_phys(sm_state + 0x7f60); |
1503 | 1503 |
env->tr.flags = (ldl_phys(sm_state + 0x7f5c) & 0xf0ff) << 8; |
1504 |
|
|
1504 |
|
|
1505 | 1505 |
env->ldt.selector = ldl_phys(sm_state + 0x7fc0) & 0xffff; |
1506 | 1506 |
env->ldt.base = ldl_phys(sm_state + 0x7f80); |
1507 | 1507 |
env->ldt.limit = ldl_phys(sm_state + 0x7f7c); |
1508 | 1508 |
env->ldt.flags = (ldl_phys(sm_state + 0x7f78) & 0xf0ff) << 8; |
1509 |
|
|
1509 |
|
|
1510 | 1510 |
env->gdt.base = ldl_phys(sm_state + 0x7f74); |
1511 | 1511 |
env->gdt.limit = ldl_phys(sm_state + 0x7f70); |
1512 | 1512 |
|
... | ... | |
1564 | 1564 |
{ |
1565 | 1565 |
unsigned int den, r; |
1566 | 1566 |
uint64_t num, q; |
1567 |
|
|
1567 |
|
|
1568 | 1568 |
num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32); |
1569 | 1569 |
den = T0; |
1570 | 1570 |
if (den == 0) { |
... | ... | |
1586 | 1586 |
{ |
1587 | 1587 |
int den, r; |
1588 | 1588 |
int64_t num, q; |
1589 |
|
|
1589 |
|
|
1590 | 1590 |
num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32); |
1591 | 1591 |
den = T0; |
1592 | 1592 |
if (den == 0) { |
... | ... | |
1632 | 1632 |
{ |
1633 | 1633 |
uint32_t index; |
1634 | 1634 |
index = (uint32_t)EAX; |
1635 |
|
|
1635 |
|
|
1636 | 1636 |
/* test if maximum index reached */ |
1637 | 1637 |
if (index & 0x80000000) { |
1638 | 1638 |
if (index > env->cpuid_xlevel) |
... | ... | |
1641 | 1641 |
if (index > env->cpuid_level) |
1642 | 1642 |
index = env->cpuid_level; |
1643 | 1643 |
} |
1644 |
|
|
1644 |
|
|
1645 | 1645 |
switch(index) { |
1646 | 1646 |
case 0: |
1647 | 1647 |
EAX = env->cpuid_level; |
... | ... | |
1783 | 1783 |
uint32_t e1, e2; |
1784 | 1784 |
int index, entry_limit; |
1785 | 1785 |
target_ulong ptr; |
1786 |
|
|
1786 |
|
|
1787 | 1787 |
selector = T0 & 0xffff; |
1788 | 1788 |
if ((selector & 0xfffc) == 0) { |
1789 | 1789 |
/* XXX: NULL selector case: invalid LDT */ |
... | ... | |
1798 | 1798 |
if (env->hflags & HF_LMA_MASK) |
1799 | 1799 |
entry_limit = 15; |
1800 | 1800 |
else |
1801 |
#endif
|
|
1801 |
#endif |
|
1802 | 1802 |
entry_limit = 7; |
1803 | 1803 |
if ((index + entry_limit) > dt->limit) |
1804 | 1804 |
raise_exception_err(EXCP0D_GPF, selector & 0xfffc); |
... | ... | |
1831 | 1831 |
uint32_t e1, e2; |
1832 | 1832 |
int index, type, entry_limit; |
1833 | 1833 |
target_ulong ptr; |
1834 |
|
|
1834 |
|
|
1835 | 1835 |
selector = T0 & 0xffff; |
1836 | 1836 |
if ((selector & 0xfffc) == 0) { |
1837 | 1837 |
/* NULL selector case: invalid TR */ |
... | ... | |
1847 | 1847 |
if (env->hflags & HF_LMA_MASK) |
1848 | 1848 |
entry_limit = 15; |
1849 | 1849 |
else |
1850 |
#endif
|
|
1850 |
#endif |
|
1851 | 1851 |
entry_limit = 7; |
1852 | 1852 |
if ((index + entry_limit) > dt->limit) |
1853 | 1853 |
raise_exception_err(EXCP0D_GPF, selector & 0xfffc); |
... | ... | |
1901 | 1901 |
raise_exception_err(EXCP0D_GPF, 0); |
1902 | 1902 |
cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0); |
1903 | 1903 |
} else { |
1904 |
|
|
1904 |
|
|
1905 | 1905 |
if (selector & 0x4) |
1906 | 1906 |
dt = &env->ldt; |
1907 | 1907 |
else |
... | ... | |
1912 | 1912 |
ptr = dt->base + index; |
1913 | 1913 |
e1 = ldl_kernel(ptr); |
1914 | 1914 |
e2 = ldl_kernel(ptr + 4); |
1915 |
|
|
1915 |
|
|
1916 | 1916 |
if (!(e2 & DESC_S_MASK)) |
1917 | 1917 |
raise_exception_err(EXCP0D_GPF, selector & 0xfffc); |
1918 | 1918 |
rpl = selector & 3; |
... | ... | |
1927 | 1927 |
/* must be readable segment */ |
1928 | 1928 |
if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) |
1929 | 1929 |
raise_exception_err(EXCP0D_GPF, selector & 0xfffc); |
1930 |
|
|
1930 |
|
|
1931 | 1931 |
if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) { |
1932 | 1932 |
/* if not conforming code, test rights */ |
1933 | 1933 |
if (dpl < cpl || dpl < rpl) |
... | ... | |
1965 | 1965 |
int new_cs, gate_cs, type; |
1966 | 1966 |
uint32_t e1, e2, cpl, dpl, rpl, limit; |
1967 | 1967 |
target_ulong new_eip, next_eip; |
1968 |
|
|
1968 |
|
|
1969 | 1969 |
new_cs = T0; |
1970 | 1970 |
new_eip = T1; |
1971 | 1971 |
if ((new_cs & 0xfffc) == 0) |
... | ... | |
2084 | 2084 |
uint32_t ss, ss_e1, ss_e2, sp, type, ss_dpl, sp_mask; |
2085 | 2085 |
uint32_t val, limit, old_sp_mask; |
2086 | 2086 |
target_ulong ssp, old_ssp, next_eip, new_eip; |
2087 |
|
|
2087 |
|
|
2088 | 2088 |
new_cs = T0; |
2089 | 2089 |
new_eip = T1; |
2090 | 2090 |
next_eip = env->eip + next_eip_addend; |
... | ... | |
2151 | 2151 |
PUSHW(ssp, sp, sp_mask, env->segs[R_CS].selector); |
2152 | 2152 |
PUSHW(ssp, sp, sp_mask, next_eip); |
2153 | 2153 |
} |
2154 |
|
|
2154 |
|
|
2155 | 2155 |
limit = get_seg_limit(e1, e2); |
2156 | 2156 |
if (new_eip > limit) |
2157 | 2157 |
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); |
... | ... | |
2228 | 2228 |
raise_exception_err(EXCP0A_TSS, ss & 0xfffc); |
2229 | 2229 |
if (!(ss_e2 & DESC_P_MASK)) |
2230 | 2230 |
raise_exception_err(EXCP0A_TSS, ss & 0xfffc); |
2231 |
|
|
2231 |
|
|
2232 | 2232 |
// push_size = ((param_count * 2) + 8) << shift; |
2233 | 2233 |
|
2234 | 2234 |
old_sp_mask = get_sp_mask(env->segs[R_SS].flags); |
2235 | 2235 |
old_ssp = env->segs[R_SS].base; |
2236 |
|
|
2236 |
|
|
2237 | 2237 |
sp_mask = get_sp_mask(ss_e2); |
2238 | 2238 |
ssp = get_seg_base(ss_e1, ss_e2); |
2239 | 2239 |
if (shift) { |
... | ... | |
2360 | 2360 |
uint32_t e1, e2, ss_e1, ss_e2; |
2361 | 2361 |
int cpl, dpl, rpl, eflags_mask, iopl; |
2362 | 2362 |
target_ulong ssp, sp, new_eip, new_esp, sp_mask; |
2363 |
|
|
2363 |
|
|
2364 | 2364 |
#ifdef TARGET_X86_64 |
2365 | 2365 |
if (shift == 2) |
2366 | 2366 |
sp_mask = -1; |
... | ... | |
2425 | 2425 |
} |
2426 | 2426 |
if (!(e2 & DESC_P_MASK)) |
2427 | 2427 |
raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc); |
2428 |
|
|
2428 |
|
|
2429 | 2429 |
sp += addend; |
2430 | 2430 |
if (rpl == cpl && (!(env->hflags & HF_CS64_MASK) || |
2431 | 2431 |
((env->hflags & HF_CS64_MASK) && !is_iret))) { |
... | ... | |
2539 | 2539 |
POPL(ssp, sp, sp_mask, new_ds); |
2540 | 2540 |
POPL(ssp, sp, sp_mask, new_fs); |
2541 | 2541 |
POPL(ssp, sp, sp_mask, new_gs); |
2542 |
|
|
2542 |
|
|
2543 | 2543 |
/* modify processor state */ |
2544 | 2544 |
load_eflags(new_eflags, TF_MASK | AC_MASK | ID_MASK | |
2545 | 2545 |
IF_MASK | IOPL_MASK | VM_MASK | NT_MASK | VIF_MASK | VIP_MASK); |
... | ... | |
2559 | 2559 |
{ |
2560 | 2560 |
int tss_selector, type; |
2561 | 2561 |
uint32_t e1, e2; |
2562 |
|
|
2562 |
|
|
2563 | 2563 |
/* specific case for TSS */ |
2564 | 2564 |
if (env->eflags & NT_MASK) { |
2565 | 2565 |
#ifdef TARGET_X86_64 |
... | ... | |
3080 | 3080 |
void helper_fyl2x(void) |
3081 | 3081 |
{ |
3082 | 3082 |
CPU86_LDouble fptemp; |
3083 |
|
|
3083 |
|
|
3084 | 3084 |
fptemp = ST0; |
3085 | 3085 |
if (fptemp>0.0){ |
3086 | 3086 |
fptemp = log(fptemp)/log(2.0); /* log2(ST) */ |
... | ... | |
3490 | 3490 |
helper_fstt(tmp, addr); |
3491 | 3491 |
addr += 16; |
3492 | 3492 |
} |
3493 |
|
|
3493 |
|
|
3494 | 3494 |
if (env->cr[4] & CR4_OSFXSR_MASK) { |
3495 | 3495 |
/* XXX: finish it */ |
3496 | 3496 |
stl(ptr + 0x18, env->mxcsr); /* mxcsr */ |
Also available in: Unified diff