better registers representation in C?

Programming, for all ages and all languages.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: better registers representation in C?

Post by Solar »

Love4Boobies wrote:
XenOS wrote:I'm really not too worried about portability across different compilers. I decided to use GCC for my project just because it fits my needs and it targets a lot of different architectures.
And what if you someday wish to port it to some architecture that GCC doesn't support but other compilers do? There are plenty of useful things that GCC can't output, such as EFI Byte Code (not that you'd want to port your OS to EFI, I'm just pointing out that GCC's not perfect).
Or what if GCC changes its internals? Doesn't happen too often, but it has happened before. Writing "unsigned int" carries no information that you had any specific size in mind. Relying on it having a specific size is relying on unspecified behaviour. It doesn't crash your app as certainly as de-referencing an uninitialized pointer, but it is perfectly allowed to. 8) And the poor sod who comes after you in maintaining your code has to deduce what you meant by "unsigned int" from the rest of the code...
Every good solution is obvious once you've found it.
Fanael
Member
Member
Posts: 38
Joined: Fri Oct 16, 2009 9:20 am

Re: better registers representation in C?

Post by Fanael »

Solar wrote:Relying on it having a specific size is relying on unspecified behaviour. It doesn't crash your app as certainly as de-referencing an uninitialized pointer, but it is perfectly allowed to. 8)
No, it's not, because it's unspecified (C99, 3.4.4/1 says "[...] behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance"), not undefined (anything can happen).
Last edited by Fanael on Mon Aug 01, 2011 12:25 pm, edited 1 time in total.
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: better registers representation in C?

Post by Love4Boobies »

Fix your tags, I didn't say that :) Also, you basically agree with what Solar was trying to say (i.e., that it's a bug but still legal), except you misinterpreted him.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
User avatar
xenos
Member
Member
Posts: 1118
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: better registers representation in C?

Post by xenos »

Love4Boobies wrote:Freestanding C++03 (with or without TR1) implementations must provide fewer headers: <cstddef>, <limits>, <cstdlib> (see Combuster's comments), <new>, <typeinfo>, <exception>, and <cstdarg>. Perhaps passing -std=c++0x fixes things; I don't know how complete GCC's C++0x support is.
I already tried -std=c++0x before, but unfortunately it didn't change anything. It seems that I need to install (a freestanding version of) libstdc++-v3 along with my cross compiler. At least the libstdc++-v3 docs suggest that I should configure my cross compiler with "--disable-hosted-libstdcxx" and run "make all-target-libstdc++-v3 install-target-libstdc++-v3". However, even though this make command intends to install only the freestanding headers, it nevertheless tries to build the complete hosted library, which of course fails. I could not find a suitable workaround yet.
And what if you someday wish to port it to some architecture that GCC doesn't support but other compilers do? There are plenty of useful things that GCC can't output, such as EFI Byte Code (not that you'd want to port your OS to EFI, I'm just pointing out that GCC's not perfect).
In that case I'd have to port all the architecture dependent code to the new architecture in a way that the new compiler understands. Well, since it's a completely different and new architecture, "porting" here really means that I need to write completely new code anyway - I cannot "port" x86 CPU startup code to ARM. So it really doesn't matter to me what the existing architecture dependent code looks like - I won't reuse it for the new architecture.

But of course the architecture independent code (such as scheduler / memory manager algorithms, process and thread management...) must be ported, and this part of my kernel is indeed written completely in C++ without any architecture or compiler dependent stuff, inline assembly or whatever.
Learning calling conventions wasn't my point. My point was that changing the ABI at some point (e.g., by passing some argument to your compiler) can cause subtle bugs regardless of how you wish to write your assembly, in case inline assembly created some false sense of security. But I take it that wasn't it...
Good point.
Solar wrote:Or what if GCC changes its internals? Doesn't happen too often, but it has happened before. Writing "unsigned int" carries no information that you had any specific size in mind. Relying on it having a specific size is relying on unspecified behaviour. It doesn't crash your app as certainly as de-referencing an uninitialized pointer, but it is perfectly allowed to. 8) And the poor sod who comes after you in maintaining your code has to deduce what you meant by "unsigned int" from the rest of the code...
I totally agree with you. That's why I intend to change all those nasty "unsigned int"s to "uint32_t"s as soon as I managed to properly integrate the freestanding C++0x headers into my cross compiler toolchain :)
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: better registers representation in C?

Post by Love4Boobies »

XenOS wrote:
Love4Boobies wrote:Freestanding C++03 (with or without TR1) implementations must provide fewer headers: <cstddef>, <limits>, <cstdlib> (see Combuster's comments), <new>, <typeinfo>, <exception>, and <cstdarg>. Perhaps passing -std=c++0x fixes things; I don't know how complete GCC's C++0x support is.
I already tried -std=c++0x before, but unfortunately it didn't change anything. It seems that I need to install (a freestanding version of) libstdc++-v3 along with my cross compiler. At least the libstdc++-v3 docs suggest that I should configure my cross compiler with "--disable-hosted-libstdcxx" and run "make all-target-libstdc++-v3 install-target-libstdc++-v3". However, even though this make command intends to install only the freestanding headers, it nevertheless tries to build the complete hosted library, which of course fails. I could not find a suitable workaround yet.
Maybe that will work, maybe it won't. Or maybe the code just isn't there yet. Perhaps someone with more knowledge of GCC can help you here.
XenOS wrote:
And what if you someday wish to port it to some architecture that GCC doesn't support but other compilers do? There are plenty of useful things that GCC can't output, such as EFI Byte Code (not that you'd want to port your OS to EFI, I'm just pointing out that GCC's not perfect).
In that case I'd have to port all the architecture dependent code to the new architecture in a way that the new compiler understands. Well, since it's a completely different and new architecture, "porting" here really means that I need to write completely new code anyway - I cannot "port" x86 CPU startup code to ARM. So it really doesn't matter to me what the existing architecture dependent code looks like - I won't reuse it for the new architecture.
That's the thing---with proper coding standards and design, a lot of the seemingly unportable code can actually become portable. The secret is to come up with good abstractions and use those in the code shared between architectures. Since you've mentioned bootstrap code, check out GRUB's source code; a lot of the code is common to all supported architectures. In the scenario we were talking about, having all sorts of compiler-specific things in the code will make it much harder to port the code.

Anyway, while I agree that this little rant doesn't apply to (inline) assembly, new architectures isn't the only reason for switching compilers---that was merely an example. Other examples: compiler X is better at optimizing, the compiler's vendor stopped developing your compiler, etc.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: better registers representation in C?

Post by Owen »

Love4Boobies wrote:
XenOS wrote:
Using inline assembly is dangerous because it ties your code to a single compiler---you don't really want that.
Of course this is true. However, I'm really not too worried about portability across different compilers. I decided to use GCC for my project just because it fits my needs and it targets a lot of different architectures.
And what if you someday wish to port it to some architecture that GCC doesn't support but other compilers do? There are plenty of useful things that GCC can't output, such as EFI Byte Code (not that you'd want to port your OS to EFI, I'm just pointing out that GCC's not perfect).
You're changing architecture. Your inline assembly is useless anyway!
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: better registers representation in C?

Post by Love4Boobies »

Owen wrote:You're changing architecture. Your inline assembly is useless anyway!
I guess you didn't read everything? Happens to me too :lol:
Love4Boobies wrote:Anyway, while I agree that this little rant doesn't apply to (inline) assembly, new architectures isn't the only reason for switching compilers---that was merely an example. Other examples: compiler X is better at optimizing, the compiler's vendor stopped developing your compiler, etc.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
Fanael
Member
Member
Posts: 38
Joined: Fri Oct 16, 2009 9:20 am

Re: better registers representation in C?

Post by Fanael »

Love4Boobies wrote:Fix your tags, I didn't say that :)
Oh well. Sorry for that.
Love4Boobies wrote:Also, you basically agree with what Solar was trying to say (i.e., that it's a bug but still legal), except you misinterpreted him.
Darn it. English (or German, or French, or any other natural language) is so ambiguous :P
User avatar
miker00lz
Member
Member
Posts: 144
Joined: Wed Dec 08, 2010 3:16 am
Location: St. Louis, MO USA

Re: better registers representation in C?

Post by miker00lz »

this reminds me of the old Borland Turbo C++ 3.0 compiler. it had an excellent way to work with registers, treating them as 16 or 8 bit variables.

for example _AX, _AH, _AL, _DI, _ES, _FLAGS, etc... i wish Borland were still around, they made the best compilers overall back in the day. imo, anyway.
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: better registers representation in C?

Post by Owen »

GCC/Clang:

Code: Select all

    register uint64_t myVariable asm("rax");
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: better registers representation in C?

Post by Love4Boobies »

Note that the register keyword isn't required to actually store variables in registers---in fact, good compilers will ignore this optimization hint and use more optimal register allocation. The real usefulness of this keyword comes from the fact that it stops people from dereferencing things that shouldn't be dereferenced.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: better registers representation in C?

Post by Owen »

In the case of the GCC extension I just mentioned, it is required to disambiguate:

Code: Select all

// At global scope
int myVar asm("..."); // A
register int myVar asm("..."); // B
A specifies a global variable allocated in memory with the specified name, which will be identical to that if the symbol was defined as an assembler label. The second says "myVar is an alias for the specified register." The second must be used with care, and exists to enable better optimization of interpreters.

[This disambiguation is of course not necessary for local variables, but maintains consistent syntax. Also note that this extension could be useful as an optimized implementation of something like <iohw.h>]
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: better registers representation in C?

Post by Love4Boobies »

Owen wrote:The second must be used with care, and exists to enable better optimization of interpreters.
Which interpreters? GCC doesn't have any C interpreter...
Owen wrote:Also note that this extension could be useful as an optimized implementation of something like <iohw.h>]
Could you elaborate?
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: better registers representation in C?

Post by Owen »

Love4Boobies wrote:
Owen wrote:The second must be used with care, and exists to enable better optimization of interpreters.
Which interpreters? GCC doesn't have any C interpreter...
Who said GCC had an interpreter? I said it was to enable better optimization of interpreters in general.
Owen wrote:Also note that this extension could be useful as an optimized implementation of something like <iohw.h>]
Could you elaborate?
It does occur to me that it wouldn't be useful for my original thought. That said, it is useful on some embedded systems, and for fast system call implementations (particularly on architectures like ARM and AMD64 where not all the registers are cleanly exposed to the inline assembly syntax).
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: better registers representation in C?

Post by Love4Boobies »

Owen wrote:
Love4Boobies wrote:
Owen wrote:The second must be used with care, and exists to enable better optimization of interpreters.
Which interpreters? GCC doesn't have any C interpreter...
Who said GCC had an interpreter? I said it was to enable better optimization of interpreters in general.
Not sure how valid a reason to adding a compiler extension that is. I maintain my original position that the only reason for which C programmers would have direct access to registers is a poor register allocator in the compiler.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
Post Reply