-
Notifications
You must be signed in to change notification settings - Fork 450
Open
Labels
Description
Describe the bug
Noticed a bug with FPU emulation on macOS M1. The FILD instruction with a 64-bit integer (qword) gives incorrect result.
Steps to reproduce the behaviour
Compile and run this C code with Borland C++ inside DOSBox-X:
#include <stdio.h>
#include <dos.h>
struct {
unsigned long low;
unsigned long high;
} my_qword = {123L, 0L};
long my_dword = 123L;
long double result_val;
void main(void)
{
printf("This program directly tests the FILD instruction.\n");
printf("It will load the integer 123 and store it back.\n\n");
printf("Press Enter to begin...\n");
getchar();
printf("--- Testing 64-bit FILD (qword) -> 80-bit ST(0) -> 80-bit FSTP (tbyte) ---\n");
asm {
finit
fild qword ptr [my_qword]
fstp tbyte ptr [result_val]
}
printf(" Expected result: 123.000000\n");
printf(" Actual result: %Lf\n\n", result_val);
printf("--- Testing 32-bit FILD (dword) for comparison ---\n");
asm {
finit
fild dword ptr [my_dword]
fstp tbyte ptr [result_val]
}
printf(" Expected result: 123.000000\n");
printf(" Actual result: %Lf\n", result_val);
}Observed Output:
--- Testing 64-bit FILD (qword) -> 80-bit ST(0) -> 80-bit FSTP (tbyte) ---
Expected result: 123.000000
Actual result: 9223372036854776320.000000
--- Testing 32-bit FILD (dword) for comparison ---
Expected result: 123.000000
Actual result: 123.000000
The issue also reproducable by simply using functions like atof() and scanf() while dealing with doubles.
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
void main(void)
{
double d_val;
char* str_to_convert = "123";
asm { int 3 }
d_val = atof(str_to_convert);
asm { int 3 };
printf("Result of atof(\"%s\"): %lf\n", str_to_convert, d_val);
}This will also print 9223372036854776320.000000
I created inturrputs so I can get CPU Logs, that I attached.
Notable is
...
; Borland's internal code converts the string "123" to the integer 0x7B (123)
; and stores it on the stack at [bp-18].
...
0824:00000A01 fildq [bp-18] ss:[FF9C]=007B
; This is the key instruction. It loads the correct 64-bit integer value 0x7B (123)
; from the stack. The FPU emulation should convert this to 123.0, but instead
; creates a garbage value in the ST(0) register due to the bug.
...
0824:00000BED fstpq [bp-14] ss:[FFCA]=FFDE
; The incorrect value from ST(0) is then stored back to memory,
; leading to the wrong result from the atof function.
...I am readying a pull request for a fix.
LOGLCPU.TXT
Expected behavior
No response
What operating system(s) this bug have occurred on?
MacOS 15.5
What version(s) of DOSBox-X have this bug?
2025.05.03 SDL2 commit:3077039cdf7b4dab4e33a4765d06dcdec55d4501
Used configuration
Output log
Additional information
No response
Have you checked that no similar bug report(s) exist?
- I have searched and didn't find any similar bug report.
Code of Conduct & Contributing Guidelines
- I agree to follow the code of conduct and the contributing guidelines.