About 64-bit portability

  • Thread starter Thread starter Bonj
  • Start date Start date
B

Bonj

Happy new year to everybody...

Just a few questions about porting code to 64-bit environment.

1) Is there a different version of the SDK (i.e., C/C++ compiler) for the
64-bit platform, or does the regular one just automatically know it's
targeting 64-bit?

2) (sort of following on from (1) really, but...) when compiling for the
64-bit platform, does the compilier still treat 'long' as 32-bit?

3) (following on from (1 & 2)...) If I use __int64, LONGLONG, LARGE_INTEGER,
etc. do they automatically know to make use of 64-bit registers?

4) (not following on from any) I've got some asm code that uses MMX
registers, e.g. __asm { ... movq mm0, [esp+4] ... }
Since an AMD64's standard registers (e.g. rax, rbx being double eax,
ebx) are 64-bit, does this mmx code need to be changed/upgraded.....
..............a) in order to *work* on an AMD64?
..............b) in order to run *optimally* on an AMD64?

5) Is there a list of types that are different on 64-bit? e.g. I know an
LPVOID is 64-bit on a 64-bit platform, but 32-bit on a 32-bit platform,
whereas some ('long' ?) are 32 bit on both...


Thanks for any insight
 
Bonj said:
Happy new year to everybody...

Just a few questions about porting code to 64-bit environment.

1) Is there a different version of the SDK (i.e., C/C++ compiler) for the
64-bit platform, or does the regular one just automatically know it's
targeting 64-bit?

2) (sort of following on from (1) really, but...) when compiling for the
64-bit platform, does the compilier still treat 'long' as 32-bit?

3) (following on from (1 & 2)...) If I use __int64, LONGLONG,
LARGE_INTEGER, etc. do they automatically know to make use of 64-bit
registers?

4) (not following on from any) I've got some asm code that uses MMX
registers, e.g. __asm { ... movq mm0, [esp+4] ... }
Since an AMD64's standard registers (e.g. rax, rbx being double eax,
ebx) are 64-bit, does this mmx code need to be changed/upgraded.....
..............a) in order to *work* on an AMD64?
..............b) in order to run *optimally* on an AMD64?

5) Is there a list of types that are different on 64-bit? e.g. I know an
LPVOID is 64-bit on a 64-bit platform, but 32-bit on a 32-bit platform,
whereas some ('long' ?) are 32 bit on both...

Nothing you've mentioned above has anything to do with the C++ language
itself, which is what is discussed here.

You need to ask in a newsgroup devoted to the compiler and/or platform
you're referring to. (Such as on the news.microsoft.com news server?)

-Howard
 
Bonj said:
Happy new year to everybody...

Just a few questions about porting code to 64-bit environment.

Most of the questions you're asking depend on whether you're talking
about Linux or Windows platforms. I assume since you've crossposted to a
Windows newsgroup that you're talking Windows.
1) Is there a different version of the SDK (i.e., C/C++ compiler) for the
64-bit platform, or does the regular one just automatically know it's
targeting 64-bit?

I have no insight about this, again also depends on platform.
2) (sort of following on from (1) really, but...) when compiling for the
64-bit platform, does the compilier still treat 'long' as 32-bit?

From what I've heard, int is still treated as 32-bit, but long is now
64-bit.
4) (not following on from any) I've got some asm code that uses MMX
registers, e.g. __asm { ... movq mm0, [esp+4] ... }
Since an AMD64's standard registers (e.g. rax, rbx being double eax,
ebx) are 64-bit, does this mmx code need to be changed/upgraded.....
..............a) in order to *work* on an AMD64?
..............b) in order to run *optimally* on an AMD64?

The answer to this on the Microsoft platform is *no*. Microsoft has
specifically decided to exclude all x87-related functionality. That
means any instruction set generated off of the x87 unit is excluded,
including MMX, 3DNow, and of course x87 floating point itself. Only
SSE1-3 are supported from now on.

On Linux, I don't think there is any such restriction.

Yousuf Khan
 
Bonj said:
Happy new year to everybody...

Just a few questions about porting code to 64-bit environment.

Please don't cross-post to so many groups; your questions aren't relevant to
most.
1) Is there a different version of the SDK (i.e., C/C++ compiler) for the
64-bit platform, or does the regular one just automatically know it's
targeting 64-bit?

Yes, there is a different compiler for x86-64. It has not yet been released,
though last I heard it was going to ship with VS 2005. I believe you can
also get it from the DDK or something along those lines.
2) (sort of following on from (1) really, but...) when compiling for the
64-bit platform, does the compilier still treat 'long' as 32-bit?

Yes. MSDN explicitly says that int and long are 4 bytes, always. Microsoft
decided that it was better to do this so that fewer programs would break. As
a result, it is necessary to use the non-standard __int64 type (since MS
does not currently support long long) or the size_t type.
3) (following on from (1 & 2)...) If I use __int64, LONGLONG,
LARGE_INTEGER, etc. do they automatically know to make use of 64-bit
registers?

The first two definitely will. A LARGE_INTEGER will use 64-bit registers
with limitation. If you access QuadPart then yes, it will use a 64-bit
register. If you access LowPart or HighPart then the compiler will probably
use 32-bit registers. If you access QuadPart *and* you access LowPart or
HighPart, the compiler will probably store QuadPart to memory and then load
LowPart or HighPart from memory. At least, I would expect this from Visual
C++. I don't know how GCC or others fare. I don't have any x86-64 compiler,
so these are just guesses.
4) (not following on from any) I've got some asm code that uses MMX
registers, e.g. __asm { ... movq mm0, [esp+4] ... }
Since an AMD64's standard registers (e.g. rax, rbx being double eax,
ebx) are 64-bit, does this mmx code need to be changed/upgraded.....
..............a) in order to *work* on an AMD64?

No. As was pointed out, MMX code will not run on AMD64 because the kernel
will not save the state of the x87 registers for 64-bit apps. If any other
program on the system tries to use x87, MMX, or 3DNow!, then it will
overwrite the registers and your results will get trashed.
..............b) in order to run *optimally* on an AMD64?

Though this is sort've useless given the answer to (a), the answer to (b)
is: probably nothing. If your MMX code is optimal on K7, then it is optimal
on K8. At present, the same is largely true for the entire instruction set.

Code that uses MMX for fast 64-bit ALU ops will heavily favor conversion to
the integer instruction set. Code that uses MMX for packed ALU, swizzle, or
saturated arithmetic operations will be substantially slower if converted to
integer instructions.

You can port MMX code to SSE2 code fairly trivially in most cases. The SSE2
code may be slightly slower, though.
5) Is there a list of types that are different on 64-bit? e.g. I know an
LPVOID is 64-bit on a 64-bit platform, but 32-bit on a 32-bit platform,
whereas some ('long' ?) are 32 bit on both...

Pointers, size_t, and ptrdiff_t will be different. Microsoft has introduced
the various *_PTR types (INT_PTR, LONG_PTR, etc.) which also change. They
are basically the same as size_t. The SIZE_T type is also basically the same
as size_t. All others remain the same because Microsoft has defined them to
be constant sizes on all of their platforms.

-Matt
 
Matt" said:
Please don't cross-post to so many groups; your questions aren't relevant to
most.


Yes, there is a different compiler for x86-64. It has not yet been released,
though last I heard it was going to ship with VS 2005. I believe you can
also get it from the DDK or something along those lines.


Yes. MSDN explicitly says that int and long are 4 bytes, always. Microsoft
decided that it was better to do this so that fewer programs would break. As
a result, it is necessary to use the non-standard __int64 type (since MS
does not currently support long long) or the size_t type.

Does that mention of size_t mean that MS have ignored the warning given
in Clive Feather's 1999 cautionary
http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_201.htm
(Which while closed with no action the relevant point was reraised
a few months later and acted upon, IIRC.)

Phil
 
Bonj said:
Happy new year to everybody...

Just a few questions about porting code to 64-bit environment.

1) Is there a different version of the SDK (i.e., C/C++ compiler) for the
64-bit platform, or does the regular one just automatically know it's
targeting 64-bit?
If you stick to standard C, or sane C++, if you accept such a thing, you
should have eliminated such obstacles to portability. It looks like you
haven't bothered to read the advice offered freely by your favorite software
vendor.
2) (sort of following on from (1) really, but...) when compiling for the
64-bit platform, does the compilier still treat 'long' as 32-bit?
You didn't specify your idea of "the 64-bit platform," although you gave
hints further down. Not many here will agree with your implied prejudice.
long is not defined as 32-bit, except on certain instances of C. Definitely
not a standard C concept.
3) (following on from (1 & 2)...) If I use __int64, LONGLONG, LARGE_INTEGER,
etc. do they automatically know to make use of 64-bit registers?
Again, you should restrict your discussion to language standards. Yes, any
reasonable compiler will use 64-bit registers as available, but that's not a
language level concept. Your chances of automatic adaptation may be better
if you avoid platform specificity.
4) (not following on from any) I've got some asm code that uses MMX
registers, e.g. __asm { ... movq mm0, [esp+4] ... }
Since an AMD64's standard registers (e.g. rax, rbx being double eax,
ebx) are 64-bit, does this mmx code need to be changed/upgraded.....
..............a) in order to *work* on an AMD64?
..............b) in order to run *optimally* on an AMD64?
Normally, asm code would not upgrade itself to use full length 64-bit
registers. Now you know why you should have used standard source code. If
you seriously mean that you're trying to write code which runs well only on
an AMD64, you haven't chosen any suitable NG.
5) Is there a list of types that are different on 64-bit? e.g. I know an
LPVOID is 64-bit on a 64-bit platform, but 32-bit on a 32-bit platform,
whereas some ('long' ?) are 32 bit on both...
If you're interested only in Windows, your web browser could have helped you
more effectively than cross-posting to groups which have no interest in
Windows-only features.
 
Bonj said:
Happy new year to everybody...

Just a few questions about porting code to 64-bit environment.

1) Is there a different version of the SDK (i.e., C/C++ compiler) for the
64-bit platform, or does the regular one just automatically know it's
targeting 64-bit?

This is compiler dependant.

For example, using GCC, the amd64 version of gcc is able to build 32 bit
binaries as well (using the -m32 flag).

On Irix, using the SGI compiler, there are 3 ABI's "o32", "n32" and
"n64", perhaps by now only the n32 and n64 ABI's are supported.
2) (sort of following on from (1) really, but...) when compiling for the
64-bit platform, does the compilier still treat 'long' as 32-bit?

Again, this is compiler dependant. It's best to avoid the issue (it
it's important in your code) by adding compiler dependant defitinions
similar to:

typedef long int_64bit; ... etc
3) (following on from (1 & 2)...) If I use __int64, LONGLONG, LARGE_INTEGER,
etc. do they automatically know to make use of 64-bit registers?

Again, compiler dependant. However, al the compilers I've used end up
using 64 bit registers in a 64 bit capable system (if the OS supports it
as well).
4) (not following on from any) I've got some asm code that uses MMX
registers, e.g. __asm { ... movq mm0, [esp+4] ... }
Since an AMD64's standard registers (e.g. rax, rbx being double eax,
ebx) are 64-bit, does this mmx code need to be changed/upgraded.....
..............a) in order to *work* on an AMD64?
..............b) in order to run *optimally* on an AMD64?

Read up on the amd64 architechture docs from AMD.

"optimally" is somthing you need to figure out for your application,
figuring out wether you even need to be optimal is up to you.
5) Is there a list of types that are different on 64-bit? e.g. I know an
LPVOID is 64-bit on a 64-bit platform, but 32-bit on a 32-bit platform,
whereas some ('long' ?) are 32 bit on both...

LPVOID is windows specific, keep away from it. Write wrappers for your
code so that you code can be system independant, then you can write
portable code. Heck, if you're really clever, you can probably figure
out how to make a system independant set of wrappers that auto-configures.

e.g.

typedef FindInt<64>::type Int64;

- you can even make it fail gracefully at compile-time if compile-time
assumptions are incorrect.
 
OK, now you make it explicit that the answers depend on which of the many
NGs
Does that mention of size_t mean that MS have ignored the warning given
in Clive Feather's 1999 cautionary
http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_201.htm

Presumably, Microsoft studied the situation to a sufficient extent when
making their decision. There must be some applications which make
unwarranted assumptions about sizeof(long), without making similar
assumptions about the relationship between sizeof(long) and size_t.
I myself ran into a situation where a software vendor flat out refused to
support 64-bit Windows on account of size_t not fitting in long. That saved
me from having to sort out other inscrutable practices of theirs, such as
for(int i=0; i<last_outer; ++i){
for(int i=0; i<last_inner; ++i){
.....
if(some_condition)break;
}
some_flag = some_variable; // is this the inner or the outer i ?!
...
}

On the basis of admittedly insufficient data, my experience suggests that
people who insist on one non-standard practice will indulge in others.
 
Back
Top