Skip to content

FPU emulation for FILD qword is broken in MacOS Arm #5759

@asemarafa

Description

@asemarafa

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions