OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 1:46 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: GCC generates FPU instructions for 64 bit integers
PostPosted: Sun Aug 15, 2021 4:24 pm 
Offline
Member
Member

Joined: Sun Apr 05, 2020 1:01 pm
Posts: 182
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:
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:
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?


Top
 Profile  
 
 Post subject: Re: GCC generates FPU instructions for 64 bit integers
PostPosted: Sun Aug 15, 2021 4:28 pm 
Offline
Member
Member

Joined: Tue Feb 18, 2020 3:29 pm
Posts: 1071
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


Top
 Profile  
 
 Post subject: Re: GCC generates FPU instructions for 64 bit integers
PostPosted: Sun Aug 15, 2021 4:33 pm 
Offline
Member
Member

Joined: Sun Apr 05, 2020 1:01 pm
Posts: 182
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. :)


Top
 Profile  
 
 Post subject: Re: GCC generates FPU instructions for 64 bit integers
PostPosted: Sun Aug 15, 2021 5:29 pm 
Offline
Member
Member

Joined: Tue Feb 18, 2020 3:29 pm
Posts: 1071
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


Top
 Profile  
 
 Post subject: Re: GCC generates FPU instructions for 64 bit integers
PostPosted: Sun Aug 15, 2021 10:01 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
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.)


Top
 Profile  
 
 Post subject: Re: GCC generates FPU instructions for 64 bit integers
PostPosted: Mon Aug 16, 2021 4:39 am 
Offline
Member
Member

Joined: Sun Apr 05, 2020 1:01 pm
Posts: 182
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.


Top
 Profile  
 
 Post subject: Re: GCC generates FPU instructions for 64 bit integers
PostPosted: Mon Aug 16, 2021 11:12 am 
Offline
Member
Member

Joined: Fri May 11, 2018 6:51 am
Posts: 274
If you wanna be sure that no compiler-emitted FPU instructions will be part of your kernel, you can compile it with:

Code:
-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


Top
 Profile  
 
 Post subject: Re: GCC generates FPU instructions for 64 bit integers
PostPosted: Tue Aug 17, 2021 12:48 am 
Offline
Member
Member
User avatar

Joined: Tue Sep 15, 2020 8:07 am
Posts: 264
Location: London, UK
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:
-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


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 77 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group