Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FPU software emulation #9

Open
mezantrop opened this issue Dec 9, 2022 · 15 comments
Open

FPU software emulation #9

mezantrop opened this issue Dec 9, 2022 · 15 comments

Comments

@mezantrop
Copy link

A question, not an issue, if you please. I see: "i386 processor (with floating-point processor)" in the minimum requirements. Are you planning to implement FPU software emulation, perhaps, at some point? I'd be interesting in reviving my 386sx machine with some modern, yet lightweight OS.

@mikaku
Copy link
Owner

mikaku commented Dec 9, 2022

I'm in the same situation. I've a PC/104 with a 386SX with 4MB of RAM but without floating-point processor. I like to power on this machine from time to time and I saw that it 's somehow able to run FiwixOS 3.2, but some binaries crash because they try to run some FPU instructions.

I was investigating if there is a way to tell GCC to not use any FPU instruction (or use an emulation on its own instead), but I didn't see any option for this.

Sincerely, give FPU support to the Fiwix kernel is out of scope of my possibilities and is not in my priority list right now. Maybe in the future someone finds interesting to include a minimal FPU support.

Sorry for the inconveniences.

@mezantrop
Copy link
Author

@mikaku thank you very much for the answer. I'll follow you and keep eye on the FiwixOS . Good luck with the amazing project.

@mikaku
Copy link
Owner

mikaku commented Dec 9, 2022

Thank you!

@glegris
Copy link

glegris commented Oct 9, 2024

Hello @mikaku, I think "-msoft-float" should work

@mikaku
Copy link
Owner

mikaku commented Oct 9, 2024

@glegris, I've just added -msoft-float to CFLAGS in the Makefile and rebuilt the kernel but I still get the No Math Coprocessor exception:

Screenshot from 2024-10-09 13-04-17

GCC's manual says:

-msoft-float
    Generate output containing library calls for floating point. Warning: the requisite libraries are not part of GCC. Normally the facilities of the machine's usual C compiler are used, but this can't be done directly in cross-compilation. You must make your own arrangements to provide suitable library functions for cross-compilation.

    On machines where a function returns floating point results in the 80387 register stack, some floating point opcodes may be emitted even if -msoft-float is used. 

Perhaps GCC requires a special configuration parameter during the build to accomplish this?

@glegris
Copy link

glegris commented Oct 9, 2024

In my opinion, since FiwixOS's newlib is not compiled in soft float mode, the binaries of the code (df in your case) linked against newlib contains FP instructions. Newlib's printf uses FP for example.

@mikaku
Copy link
Owner

mikaku commented Oct 9, 2024

Oh yes, you're right. I understood it in the other way around.
I should compile df (or any other program that uses FP instructions) to see the difference.

@mikaku
Copy link
Owner

mikaku commented Oct 11, 2024

I've made a test with a simple program that generates Floating Point instructions:

#include <stdio.h>

static double test(double d)
{
	printf("d = %.5G\n", (double)d);
	return (d * 100);
}

int main(int argc, char** argv)
{
	int res;

	res = test(19.67);
	printf("res = %d\n", res);
	return 0;
}

It works well on an processor with a FPU:

(root):~# gcc -o fpu fpu.c 
(root):~# ./fpu 
d = 19.67
res = 1967

As you can see, It uses FP instructions:

[...]
08048229 <main>:
 8048229:       55                      push   %ebp
 804822a:       89 e5                   mov    %esp,%ebp
 804822c:       83 e4 f0                and    $0xfffffff0,%esp
 804822f:       83 ec 30                sub    $0x30,%esp
 8048232:       b8 ec 51 b8 1e          mov    $0x1eb851ec,%eax
 8048237:       ba 85 ab 33 40          mov    $0x4033ab85,%edx
 804823c:       89 04 24                mov    %eax,(%esp)
 804823f:       89 54 24 04             mov    %edx,0x4(%esp)
 8048243:       e8 a8 ff ff ff          call   80481f0 <test>
 8048248:       d9 7c 24 1e             fnstcw 0x1e(%esp)
 804824c:       66 8b 44 24 1e          mov    0x1e(%esp),%ax
 8048251:       b4 0c                   mov    $0xc,%ah
 8048253:       66 89 44 24 1c          mov    %ax,0x1c(%esp)
 8048258:       d9 6c 24 1c             fldcw  0x1c(%esp)
 804825c:       db 5c 24 2c             fistpl 0x2c(%esp)
 8048260:       d9 6c 24 1e             fldcw  0x1e(%esp)
 8048264:       8b 44 24 2c             mov    0x2c(%esp),%eax
 8048268:       89 44 24 04             mov    %eax,0x4(%esp)
[...]

When I compile it with the parameter -msoft-float I get undefined references (even with -lgcc parameter):

(root):~# gcc -msoft-float -o fpu fpu.c 
/tmp/cc000039.o: In function `test':
fpu.c:(.text+0x4c): undefined reference to `__muldf3'
/tmp/cc000039.o: In function `main':
fpu.c:(.text+0x79): undefined reference to `__fixdfsi'
collect2: error: ld returned 1 exit status

I'm not sure but I think that GCC Toolchain must be built with a special configuration parameter that is not currently passed during the compilation on FiwixOS.

I need to investigate more on this.

After reading this I'm a bit skeptic (at least for i386).

@glegris
Copy link

glegris commented Oct 11, 2024

I see that soft-fp is not integrated in the FiwixOS's gcc package. You can build the soft-fp library yourself and compile your code against it:
gcc -msoft-float test.c -lsoft-fp

@glegris
Copy link

glegris commented Oct 11, 2024

I can't compile soft-fp for gcc-4.7.4, it seems broken. I found a temporary solution based on a third party library in the meantime. The source code to compile your example is attached (I wrote a small README at the root).
softfloat.zip

@mikaku
Copy link
Owner

mikaku commented Oct 12, 2024

Nice, it seems to work on an i386 without FPU.

I think the best way to compile the ieeelib under FiwixOS is integrate it into GCC Toolchain build, so it can use the libgcc directory directly. Then, I'll try rebuild the packages of FiwixOS using the softfloat library and see how it works.

@mikaku
Copy link
Owner

mikaku commented Oct 14, 2024

Some progress ...

I've included the ieeelib project into the build process of the GNU Toolchain. So now, the script make-toolchain.sh also generates the file ieeelib_2c52005_i386.ipk which will install the library /usr/i386-pc-fiwix/lib/libsoft-fp.a into the system.

Then I've modified the file makeall.sh, which is the script that builds all the packages that conform the FiwixOS, to introduce the ability to build some packages with -msoft-float and with the link-time parameter -lsoft-fp. Since the command free is one of those that generate the No Math Coprocessor exception, I've modified the script to also create the package procps_3.2.8_i386-softfp.ipk and it worked nicely.

The next command was grep, which also worked perfectly and now there is the new package grep_3.11_i386-softfp.ipk.

The problem was with the command awk. During its build I got the following error messages:

[...]
gcc  -msoft-float  -s -o gawk array.o awkgram.o builtin.o dfa.o ext.o field.o floatcomp.o gawkmisc.o getopt.o getopt1.o io.o main.o msg.o node.o random.o re.o regex.o replace.o version.o eval.o profile.o    -lm -lm -lsoft-fp
builtin.o: In function `format_tree':
builtin.c:(.text+0x253a): undefined reference to `__unorddf2'
builtin.c:(.text+0x258e): undefined reference to `__unorddf2'
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:491: gawk] Error 1
make[2]: Leaving directory '/mnt/disk/gawk-3.1.8'
make[1]: *** [Makefile:550: all-recursive] Error 1
make[1]: Leaving directory '/mnt/disk/gawk-3.1.8'
make: *** [Makefile:397: all] Error 2

 *** An error occurred. Build has been stopped ***

It looks like the original code of ieeelib did not include any reference to the function __unorddf2.

I've been investigating and I discovered an email in the GCC Project Mailing List where a user called Joseph S. Myers submitted a patch which hopefully will fix this. The same email also references another one that fixes a different bug.

I plan to introduce both patches into the build process of the ieeelib, so eventually I'll be able to compile awk and hopefully the rest of programs.

@mikaku
Copy link
Owner

mikaku commented Oct 16, 2024

Well, I have bad news. This was a false positive: the free and the grep commands worked because I had an old configuration in the 86Box. The i386 motherboard was setup with FPU. D'oh! 😞

I think that these commands still have the FPU instructions that come with the Newlib static libraries. So, in the next days I'll try to rebuild the Newlib C library using the msoft-float, and link it with -lsoft-fp.

In fact, the fpu in the softfloat.zip doesn't work either.

@glegris
Copy link

glegris commented Oct 17, 2024

In fact, the fpu in the softfloat.zip doesn't work either.

Could you give me your 86Box configuration? So I can try to fix things too.

@mikaku
Copy link
Owner

mikaku commented Oct 18, 2024

[General]
vid_renderer = qt_software
host_cpu = Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
emu_build_num = 6000
uuid = 56db3ab3-69ea-5a67-a191-d9f03826b693

[Machine]
machine = asus386
cpu_family = i386dx
cpu_speed = 40000000
cpu_multi = 1
cpu_use_dynarec = 0
time_sync = local
fpu_softfloat = 0
cpu = 4
mem_size = 65536

[Video]
gfxcard = vga

[Input devices]
mouse_type = none

[Storage controllers]
hdc = ide_isa_2ch
cassette_mode = load

[Hard disks]
hdd_01_parameters = 63, 16, 2080, 0, ide
hdd_01_fn = /mnt/storage/kvm/fiwix-ext2-1GB.img
hdd_01_speed = 1997_5400rpm
hdd_01_ide_channel = 0:0

[Floppy and CD-ROM drives]
fdd_01_fn = /mnt/storage/kvm/fiwix-floppy.img
fdd_01_type = 35_2hd
fdd_02_type = none
cdrom_01_parameters = 1, atapi
cdrom_01_ide_channel = 1:0
cdrom_01_image_path = /mnt/storage/kvm/FiwixOS-3.3-i386.iso
cdrom_01_type = 86BOX_CD-ROM_1.00

[Sound]
fm_driver = nuked

[Serial Passthrough Device #1]
mode = 0
data_bits = 8
stop_bits = 1
baudrate = 115200

[Ports (COM & LPT)]
serial1_passthrough_enabled = 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants