GCC generates FPU instructions for 64 bit integers

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
8infy
Member
Member
Posts: 185
Joined: Sun Apr 05, 2020 1:01 pm

GCC generates FPU instructions for 64 bit integers

Post by 8infy »

Hello, I have an issue with GCC where it for some reason generates FPU instructions for 64 bit math when building for i686.

Example:

Code: Select all

c0171197:	df 2d 70 21 1a c0    	fild   QWORD PTR ds:0xc01a2170
c017119d:	df 7d e0             	fistp  QWORD PTR [ebp-0x20]
This is the piece of code generated when calling my sleep function.

Code: Select all

inline void for_seconds(u64 time)
{
    until(Timer::nanoseconds_since_boot() + (time * Time::nanoseconds_in_second));
}
When i tried adding -mgeneral-regs-only the linker generated a bunch of undefined references to __atomic_load_8.
Why does this happen?

....

I think I got it. Unfortunately i was trying to use a 64 bit atomic counter in my kernel and i think on 32 bit GCC implements
it via FPU QWORD load and store =D> ... Is that true? Can anyone link any resources that talk about this?
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: GCC generates FPU instructions for 64 bit integers

Post by nexos »

8infy wrote:When i tried adding -mgeneral-regs-only the linker generated a bunch of undefined references to __atomic_load_8.
The GCC docs refer to those as builtins. Are you linking with libgcc?
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
8infy
Member
Member
Posts: 185
Joined: Sun Apr 05, 2020 1:01 pm

Re: GCC generates FPU instructions for 64 bit integers

Post by 8infy »

nexos wrote:
8infy wrote:When i tried adding -mgeneral-regs-only the linker generated a bunch of undefined references to __atomic_load_8.
The GCC docs refer to those as builtins. Are you linking with libgcc?
I do. I don't get those errors if i don't pass the general-regs-only flag. I think the reason is because GCC doesn't have an implementation
for those functions that doesn't include FPU instructions. :)
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: GCC generates FPU instructions for 64 bit integers

Post by nexos »

8infy wrote:I think the reason is because GCC doesn't have an implementation for those functions that doesn't include FPU instructions.
Sounds reasonable, that probably is why. Sounds kind of like a bug maybe.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: GCC generates FPU instructions for 64 bit integers

Post by Octocontrabass »

8infy wrote:Can anyone link any resources that talk about this?
The Intel SDM (volume 3A section 8.1.1) says aligned 64-bit loads and stores are atomic on Pentium and later processors. When you don't need the compare or exchange parts of CMPXCHG8B, it's pretty reasonable to choose some other instruction, and the only other options for i686 are floating-point.

Incidentally, Clang is able to use CMPXCHG8B when floating-point instructions are not available. (But if you try this with your own copy of Clang you'll notice that support for -mgeneral-regs-only was added very recently.)
8infy
Member
Member
Posts: 185
Joined: Sun Apr 05, 2020 1:01 pm

Re: GCC generates FPU instructions for 64 bit integers

Post by 8infy »

Octocontrabass wrote:
8infy wrote:Can anyone link any resources that talk about this?
The Intel SDM (volume 3A section 8.1.1) says aligned 64-bit loads and stores are atomic on Pentium and later processors. When you don't need the compare or exchange parts of CMPXCHG8B, it's pretty reasonable to choose some other instruction, and the only other options for i686 are floating-point.

Incidentally, Clang is able to use CMPXCHG8B when floating-point instructions are not available. (But if you try this with your own copy of Clang you'll notice that support for -mgeneral-regs-only was added very recently.)
Thanks, that was a big TIL moment for me.
vvaltchev
Member
Member
Posts: 274
Joined: Fri May 11, 2018 6:51 am

Re: GCC generates FPU instructions for 64 bit integers

Post by vvaltchev »

If you wanna be sure that no compiler-emitted FPU instructions will be part of your kernel, you can compile it with:

Code: Select all

-mno-80387 -mno-mmx -mno-sse -mno-avx
Using FPU instructions, with some exceptions, is dangerous in the kernel because it will corrupt the state of the FPU registers used by the current user process, unless you always save and restore all the FPU regs even when you do just a mode switch (jump kernel and back). However, saving and restoring the FPU regs is a very expensive operation, so you don't have much of a choice if you care about performance. Modern compilers emit FPU instructions all the time at higher level of optimizations even with -ffreestanding, unless you explicitly tell them not to.
Tilck, a Tiny Linux-Compatible Kernel: https://github.com/vvaltchev/tilck
User avatar
bloodline
Member
Member
Posts: 264
Joined: Tue Sep 15, 2020 8:07 am
Location: London, UK

Re: GCC generates FPU instructions for 64 bit integers

Post by bloodline »

vvaltchev wrote:If you wanna be sure that no compiler-emitted FPU instructions will be part of your kernel, you can compile it with:

Code: Select all

-mno-80387 -mno-mmx -mno-sse -mno-avx
Using FPU instructions, with some exceptions, is dangerous in the kernel because it will corrupt the state of the FPU registers used by the current user process, unless you always save and restore all the FPU regs even when you do just a mode switch (jump kernel and back). However, saving and restoring the FPU regs is a very expensive operation, so you don't have much of a choice if you care about performance. Modern compilers emit FPU instructions all the time at higher level of optimizations even with -ffreestanding, unless you explicitly tell them not to.
#-o This is good advice, I’ve not really thought about the FPU… I’m definitely not saving the FPU state during a context switch! I’ve not had any unexplained crashes yet, probably down to luck more than anything :(
CuriOS: A single address space GUI based operating system built upon a fairly pure Microkernel/Nanokernel. Download latest bootable x86 Disk Image: https://github.com/h5n1xp/CuriOS/blob/main/disk.img.zip
Discord:https://discord.gg/zn2vV2Su
Post Reply