Fixed 16-bit and 32-bit FISTP(P) instruction, fixes OpenStep 4.2 font on interpreter and old recompiler, closes #1204.
This commit is contained in:
@@ -4363,7 +4363,7 @@ static inline int FP_LOAD_REG_INT_W(int reg)
|
|||||||
addbyte(0xc5);
|
addbyte(0xc5);
|
||||||
addbyte((uint8_t)cpu_state_offset(ST));
|
addbyte((uint8_t)cpu_state_offset(ST));
|
||||||
|
|
||||||
CALL_FUNC((uintptr_t)x87_fround);
|
CALL_FUNC((uintptr_t)x87_fround16_64);
|
||||||
|
|
||||||
addbyte(0x93); /*XCHG EBX, EAX*/
|
addbyte(0x93); /*XCHG EBX, EAX*/
|
||||||
|
|
||||||
@@ -4393,7 +4393,7 @@ static inline int FP_LOAD_REG_INT(int reg)
|
|||||||
addbyte(0xc5);
|
addbyte(0xc5);
|
||||||
addbyte((uint8_t)cpu_state_offset(ST));
|
addbyte((uint8_t)cpu_state_offset(ST));
|
||||||
|
|
||||||
CALL_FUNC((uintptr_t)x87_fround);
|
CALL_FUNC((uintptr_t)x87_fround32_64);
|
||||||
|
|
||||||
addbyte(0x93); /*XCHG EBX, EAX*/
|
addbyte(0x93); /*XCHG EBX, EAX*/
|
||||||
|
|
||||||
|
@@ -152,6 +152,68 @@ static __inline double x87_pop()
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __inline int16_t x87_fround16(double b)
|
||||||
|
{
|
||||||
|
int16_t a, c;
|
||||||
|
|
||||||
|
switch ((cpu_state.npxc >> 10) & 3)
|
||||||
|
{
|
||||||
|
case 0: /*Nearest*/
|
||||||
|
a = (int16_t)floor(b);
|
||||||
|
c = (int16_t)floor(b + 1.0);
|
||||||
|
if ((b - a) < (c - b))
|
||||||
|
return a;
|
||||||
|
else if ((b - a) > (c - b))
|
||||||
|
return c;
|
||||||
|
else
|
||||||
|
return (a & 1) ? c : a;
|
||||||
|
case 1: /*Down*/
|
||||||
|
return (int16_t)floor(b);
|
||||||
|
case 2: /*Up*/
|
||||||
|
return (int16_t)ceil(b);
|
||||||
|
case 3: /*Chop*/
|
||||||
|
return (int16_t)b;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline int64_t x87_fround16_64(double b)
|
||||||
|
{
|
||||||
|
return (int64_t) x87_fround16(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline int32_t x87_fround32(double b)
|
||||||
|
{
|
||||||
|
int32_t a, c;
|
||||||
|
|
||||||
|
switch ((cpu_state.npxc >> 10) & 3)
|
||||||
|
{
|
||||||
|
case 0: /*Nearest*/
|
||||||
|
a = (int32_t)floor(b);
|
||||||
|
c = (int32_t)floor(b + 1.0);
|
||||||
|
if ((b - a) < (c - b))
|
||||||
|
return a;
|
||||||
|
else if ((b - a) > (c - b))
|
||||||
|
return c;
|
||||||
|
else
|
||||||
|
return (a & 1) ? c : a;
|
||||||
|
case 1: /*Down*/
|
||||||
|
return (int32_t)floor(b);
|
||||||
|
case 2: /*Up*/
|
||||||
|
return (int32_t)ceil(b);
|
||||||
|
case 3: /*Chop*/
|
||||||
|
return (int32_t)b;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline int64_t x87_fround32_64(double b)
|
||||||
|
{
|
||||||
|
return (int64_t) x87_fround32(b);
|
||||||
|
}
|
||||||
|
|
||||||
static __inline int64_t x87_fround(double b)
|
static __inline int64_t x87_fround(double b)
|
||||||
{
|
{
|
||||||
int64_t a, c;
|
int64_t a, c;
|
||||||
|
@@ -42,24 +42,20 @@ static int opFILDiw_a32(uint32_t fetchdat)
|
|||||||
|
|
||||||
static int opFISTiw_a16(uint32_t fetchdat)
|
static int opFISTiw_a16(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
int64_t temp64;
|
|
||||||
FP_ENTER();
|
FP_ENTER();
|
||||||
fetch_ea_16(fetchdat);
|
fetch_ea_16(fetchdat);
|
||||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||||
temp64 = x87_fround(ST(0));
|
seteaw(x87_fround16(ST(0)));
|
||||||
seteaw((int16_t)temp64);
|
|
||||||
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
||||||
return cpu_state.abrt;
|
return cpu_state.abrt;
|
||||||
}
|
}
|
||||||
#ifndef FPU_8087
|
#ifndef FPU_8087
|
||||||
static int opFISTiw_a32(uint32_t fetchdat)
|
static int opFISTiw_a32(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
int64_t temp64;
|
|
||||||
FP_ENTER();
|
FP_ENTER();
|
||||||
fetch_ea_32(fetchdat);
|
fetch_ea_32(fetchdat);
|
||||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||||
temp64 = x87_fround(ST(0));
|
seteaw(x87_fround16(ST(0)));
|
||||||
seteaw((int16_t)temp64);
|
|
||||||
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
||||||
return cpu_state.abrt;
|
return cpu_state.abrt;
|
||||||
}
|
}
|
||||||
@@ -67,12 +63,10 @@ static int opFISTiw_a32(uint32_t fetchdat)
|
|||||||
|
|
||||||
static int opFISTPiw_a16(uint32_t fetchdat)
|
static int opFISTPiw_a16(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
int64_t temp64;
|
|
||||||
FP_ENTER();
|
FP_ENTER();
|
||||||
fetch_ea_16(fetchdat);
|
fetch_ea_16(fetchdat);
|
||||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||||
temp64 = x87_fround(ST(0));
|
seteaw(x87_fround16(ST(0))); if (cpu_state.abrt) return 1;
|
||||||
seteaw((int16_t)temp64); if (cpu_state.abrt) return 1;
|
|
||||||
x87_pop();
|
x87_pop();
|
||||||
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
||||||
return 0;
|
return 0;
|
||||||
@@ -80,12 +74,10 @@ static int opFISTPiw_a16(uint32_t fetchdat)
|
|||||||
#ifndef FPU_8087
|
#ifndef FPU_8087
|
||||||
static int opFISTPiw_a32(uint32_t fetchdat)
|
static int opFISTPiw_a32(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
int64_t temp64;
|
|
||||||
FP_ENTER();
|
FP_ENTER();
|
||||||
fetch_ea_32(fetchdat);
|
fetch_ea_32(fetchdat);
|
||||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||||
temp64 = x87_fround(ST(0));
|
seteaw(x87_fround16(ST(0))); if (cpu_state.abrt) return 1;
|
||||||
seteaw((int16_t)temp64); if (cpu_state.abrt) return 1;
|
|
||||||
x87_pop();
|
x87_pop();
|
||||||
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
||||||
return 0;
|
return 0;
|
||||||
@@ -240,24 +232,20 @@ static int opFILDil_a32(uint32_t fetchdat)
|
|||||||
|
|
||||||
static int opFISTil_a16(uint32_t fetchdat)
|
static int opFISTil_a16(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
int64_t temp64;
|
|
||||||
FP_ENTER();
|
FP_ENTER();
|
||||||
fetch_ea_16(fetchdat);
|
fetch_ea_16(fetchdat);
|
||||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||||
temp64 = x87_fround(ST(0));
|
seteal(x87_fround32(ST(0)));
|
||||||
seteal((int32_t)temp64);
|
|
||||||
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
||||||
return cpu_state.abrt;
|
return cpu_state.abrt;
|
||||||
}
|
}
|
||||||
#ifndef FPU_8087
|
#ifndef FPU_8087
|
||||||
static int opFISTil_a32(uint32_t fetchdat)
|
static int opFISTil_a32(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
int64_t temp64;
|
|
||||||
FP_ENTER();
|
FP_ENTER();
|
||||||
fetch_ea_32(fetchdat);
|
fetch_ea_32(fetchdat);
|
||||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||||
temp64 = x87_fround(ST(0));
|
seteal(x87_fround32(ST(0)));
|
||||||
seteal((int32_t)temp64);
|
|
||||||
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
||||||
return cpu_state.abrt;
|
return cpu_state.abrt;
|
||||||
}
|
}
|
||||||
@@ -265,12 +253,10 @@ static int opFISTil_a32(uint32_t fetchdat)
|
|||||||
|
|
||||||
static int opFISTPil_a16(uint32_t fetchdat)
|
static int opFISTPil_a16(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
int64_t temp64;
|
|
||||||
FP_ENTER();
|
FP_ENTER();
|
||||||
fetch_ea_16(fetchdat);
|
fetch_ea_16(fetchdat);
|
||||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||||
temp64 = x87_fround(ST(0));
|
seteal(x87_fround32(ST(0))); if (cpu_state.abrt) return 1;
|
||||||
seteal((int32_t)temp64); if (cpu_state.abrt) return 1;
|
|
||||||
x87_pop();
|
x87_pop();
|
||||||
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
||||||
return 0;
|
return 0;
|
||||||
@@ -278,12 +264,10 @@ static int opFISTPil_a16(uint32_t fetchdat)
|
|||||||
#ifndef FPU_8087
|
#ifndef FPU_8087
|
||||||
static int opFISTPil_a32(uint32_t fetchdat)
|
static int opFISTPil_a32(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
int64_t temp64;
|
|
||||||
FP_ENTER();
|
FP_ENTER();
|
||||||
fetch_ea_32(fetchdat);
|
fetch_ea_32(fetchdat);
|
||||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||||
temp64 = x87_fround(ST(0));
|
seteal(x87_fround32(ST(0))); if (cpu_state.abrt) return 1;
|
||||||
seteal((int32_t)temp64); if (cpu_state.abrt) return 1;
|
|
||||||
x87_pop();
|
x87_pop();
|
||||||
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user