Hi Folks,
I need 64-bit code on Sun Solaris 2.9. The specification of the system (gpc -v):
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.9/3.2.1/specs Configured with: /users/cserzo/big/src/gcc-3.2.1/configure --enable-languages=pascal --disable-nls --with-gnu-as --with-gnu-ld --with-as=/usr/local/bin/as --with-ld=/usr/local/bin/ld Thread model: posix gpc version 20030507, based on gcc-3.2.1
Apparently, the 32-bit compiler should be able to generate 64-bit code. The problem is the missing 64-bit libgpc. The 64-bit version of the gcc library is there but its gpc counterpart not. How could I force the compilation of this library at build time?
I made another test. With the 32-bit version one should be able to address ~ 4.3 Gb of the memory. In practice, I can allocate about 2Gb (array[1..500000000] of integer) but not much more. If I compile a code containing array[1..600000000] of integer the following error generated:
/var/tmp//ccrvtgAm.s: Assembler messages: /var/tmp//ccrvtgAm.s:7: Error: .COMMon length (-1894967300.) <0! Ignored. /var/tmp//ccrvtgAm.s:7: Warning: rest of line ignored; first ignored character is `,'
What is the correct way to make use of the memory in this case?
Cheers,
miklos
Not quite true. A 32-bit virtual address space allows for about 4GB of TOTAL addressable memory; this includes both the PROCESS memory, and the KERNEL memory. Most OSes split the region in half, so that the most a process could allocate would be about 2GB. I know that MIPS, Windoze, etc. do this, and I would suspect that Solaris probably does the same.
--- Cserzo Miklos cserzo@abc.hu wrote:
I made another test. With the 32-bit version one should be able to address ~ 4.3 Gb of the memory. In practice, I can allocate about 2Gb
===== ======= Frank D. Engel, Jr.
Modify the equilibrium of the vertically-oriented particle decelerator to result in the reestablishment of its resistance to counterproductive atmospheric penetration.
__________________________________ Do you Yahoo!? Yahoo! Calendar - Free online calendar with sync to Outlook(TM). http://calendar.yahoo.com
Cserzo Miklos wrote:
I need 64-bit code on Sun Solaris 2.9. The specification of the system (gpc -v):
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.9/3.2.1/specs Configured with: /users/cserzo/big/src/gcc-3.2.1/configure --enable-languages=pascal --disable-nls --with-gnu-as --with-gnu-ld --with-as=/usr/local/bin/as --with-ld=/usr/local/bin/ld Thread model: posix gpc version 20030507, based on gcc-3.2.1
Apparently, the 32-bit compiler should be able to generate 64-bit code. The problem is the missing 64-bit libgpc. The 64-bit version of the gcc library is there but its gpc counterpart not. How could I force the compilation of this library at build time?
I don't have any experience myself with this situation, but provided there is an option to switch to 64 bit code, try adding it to PFLAGS on the make command line (you might need to call make from the gcc/ directory).
You can also configure and build the runtime library on its own, mostly like an ordinary library (in the p/rts directory). This not well tested and "undocumented", and you'll have to install the compiled library manually. Note that this requires the exactly matching GPC compiler already installed (or set in PC).
I made another test. With the 32-bit version one should be able to address ~ 4.3 Gb of the memory. In practice, I can allocate about 2Gb (array[1..500000000] of integer) but not much more. If I compile a code containing array[1..600000000] of integer the following error generated:
/var/tmp//ccrvtgAm.s: Assembler messages: /var/tmp//ccrvtgAm.s:7: Error: .COMMon length (-1894967300.) <0! Ignored. /var/tmp//ccrvtgAm.s:7: Warning: rest of line ignored; first ignored character is `,'
With some short example code and the resulting assembler file, I might be able to tell something. Does the same happen in C?
Frank
On Thu, 29 May 2003, Frank Heckenbach wrote:
I don't have any experience myself with this situation, but provided there is an option to switch to 64 bit code, try adding it to PFLAGS on the make command line (you might need to call make from the gcc/ directory).
You can also configure and build the runtime library on its own, mostly like an ordinary library (in the p/rts directory). This not well tested and "undocumented", and you'll have to install the compiled library manually. Note that this requires the exactly matching GPC compiler already installed (or set in PC).
I can generate a libgpc in this way but the gpc not seems to make use of it. The objects in the directory are 64-bit mostly but there are a few 32-bit too. (is it normal?) Then I copy the resulting libgpc.a to its place. (Maybe I am a bit naive: "manual installation" means copy or a more complicated operation?) Here comes the message generated when I want to use it:
/usr/local/bin/ld: skipping incompatible /usr/local/lib/gcc-lib/sparc-sun-solaris2.9/3.2.1/sparcv9/libgpc.a when searching for -lgpc /usr/local/bin/ld: skipping incompatible /usr/local/lib/gcc-lib/sparc-sun-solaris2.9/3.2.1/libgpc.a when searching for -lgpc /usr/local/bin/ld: cannot find -lgpc GNU ld version 2.13 Supported emulations: elf32_sparc elf64_sparc collect2: ld returned 1 exit status
So it is hooking for the library at its place, finds it but can not use it.
With some short example code and the resulting assembler file, I might be able to tell something. Does the same happen in C?
The sample goes in the attachment. Short and simple. I did not test it in C.
miklos
Cserzo Miklos wrote:
On Thu, 29 May 2003, Frank Heckenbach wrote:
I don't have any experience myself with this situation, but provided there is an option to switch to 64 bit code, try adding it to PFLAGS on the make command line (you might need to call make from the gcc/ directory).
You can also configure and build the runtime library on its own, mostly like an ordinary library (in the p/rts directory). This not well tested and "undocumented", and you'll have to install the compiled library manually. Note that this requires the exactly matching GPC compiler already installed (or set in PC).
I can generate a libgpc in this way but the gpc not seems to make use of it. The objects in the directory are 64-bit mostly but there are a few 32-bit too. (is it normal?)
Oh yeah, probably the C files (rts.o, rts-va.o, file.o). So I think you should set CFLAGS (which will then also apply to PFLAGS, no need to set both). If you set CFLAGS when building the whole compiler, it will also apply to the compiler itself which may or may not be what you want ...
Then I copy the resulting libgpc.a to its place. (Maybe I am a bit naive: "manual installation" means copy or a more complicated operation?)
Yes, just copy it.
Here comes the message generated when I want to use it:
/usr/local/bin/ld: skipping incompatible /usr/local/lib/gcc-lib/sparc-sun-solaris2.9/3.2.1/sparcv9/libgpc.a when searching for -lgpc /usr/local/bin/ld: skipping incompatible /usr/local/lib/gcc-lib/sparc-sun-solaris2.9/3.2.1/libgpc.a when searching for -lgpc /usr/local/bin/ld: cannot find -lgpc GNU ld version 2.13 Supported emulations: elf32_sparc elf64_sparc collect2: ld returned 1 exit status
Unless it's the CFLAGS issue, I don't know. Are the binutils (in particular ar, ld and ranlib) suitable for 64 bits? If different versions of them are needed, you can set them in AR and RANLIB.
On one system I found that ranlib didn't work in the configuration I had and disabling it (by setting RANLIB_TEST=false on the make command line) helped. But that's just a wild guess here.
With some short example code and the resulting assembler file, I might be able to tell something. Does the same happen in C?
The sample goes in the attachment.
What does the assembler file contain (WRT n)?
Frank
On Fri, 30 May 2003, Frank Heckenbach wrote:
Oh yeah, probably the C files (rts.o, rts-va.o, file.o). So I think you should set CFLAGS (which will then also apply to PFLAGS, no need to set both). If you set CFLAGS when building the whole compiler, it will also apply to the compiler itself which may or may not be what you want ...
That was the trick - let me summarize it if anyone wants to do it next time:
1) - Configure, build and install GPC in a separate directory on the top of the GCC 3.2.1 source. This will create the GCC runtimes in two versions (32-bit and 64-bit) and the 32-bit version of the GPC runtime. Do not need any unusual config option or make switch for that. The compiler itself is 32-bit but capable of 64-bit code generation.
2) - Go to the gcc/p/rts dir. of the source and run configure locally with the same options as you applied for the whole kit.
3) - Build the library in that dir. with the CFLAGS=-m64 option (for sun system).
4) - Copy the libgpc.a archive manually to its place where the gcc 64-bit runtimes are. (/usr/local/lib/gcc-lib/sparc-sun-solaris2.9/3.2.1/sparcv9 in my case.)
Done, the compiler generates valid 64-bit code with the -m64 switch.
The new problem starts here. The size of the array is still limited in the 64-bit version. The limit is the same as in 32-bit and it is much smaller than the memory limit of the system. So no use of the 64-bit architecture after all.
What does the assembler file contain (WRT n)?
How can I capture the assembler file of a source?
miklos
On Fri, 30 May 2003, Eike Lange wrote:
On Fri, May 30, 2003 at 02:38:08PM +0200, Cserzo Miklos wrote:
That was the trick - let me summarize it if anyone wants to do it next time:
Could you write a short chapter in the GPC's documentation about it?
Sure, but wouldn't it be better to fix the GPC makefile? The generation of the runtime libraries in two versions is transparent in GCC. I can send the log of the make process to whoever can trace back the problem. (It is a bit too large for the list.)
miklos
Cserzo Miklos wrote:
The compiler itself is 32-bit but capable of 64-bit code generation.
That's probably the reason for:
The new problem starts here. The size of the array is still limited in the 64-bit version. The limit is the same as in 32-bit and it is much smaller than the memory limit of the system. So no use of the 64-bit architecture after all.
What does the assembler file contain (WRT n)?
How can I capture the assembler file of a source?
gpc -S foo.pas
Frank
On Sat, 31 May 2003, Frank Heckenbach wrote:
How can I capture the assembler file of a source?
gpc -S foo.pas
OK, the source and the assembler goes in the attachment. I just realized that I could have two large arrays without problem but gpc refuse to allocate one larger array of the size of the two smaller. Very very funny...
miklos
Cserzo Miklos wrote:
OK, the source and the assembler goes in the attachment. I just realized that I could have two large arrays without problem but gpc refuse to allocate one larger array of the size of the two smaller. Very very funny...
/var/tmp//ccrvtgAm.s: Assembler messages: /var/tmp//ccrvtgAm.s:7: Error: .COMMon length (-1894967300.) <0! Ignored.
line 7: .common N,1999999996,4
This size is correct, so I suppose the problem is with the assembler. You might need to get a 64 bit one (if it's a Solaris assembler), or try to compile binutils for 64 bit target (if it's using the GNU assembler).
Frank
On Sat, 31 May 2003, Frank Heckenbach wrote:
/var/tmp//ccrvtgAm.s: Assembler messages: /var/tmp//ccrvtgAm.s:7: Error: .COMMon length (-1894967300.) <0! Ignored.
line 7: .common N,1999999996,4
This size is correct, so I suppose the problem is with the assembler. You might need to get a 64 bit one (if it's a Solaris assembler), or try to compile binutils for 64 bit target (if it's using the GNU assembler).
Sorry, did not understand you last time. The source and assembler I have sent is the version that compiles. Here goes the version that fails. The only difference is the size of the vector. The assembler is the "GNU as" and it is 64-capable. Other tools have been successfully compiled with it on the system.
miklos
Cserzo Miklos wrote:
On Sat, 31 May 2003, Frank Heckenbach wrote:
/var/tmp//ccrvtgAm.s: Assembler messages: /var/tmp//ccrvtgAm.s:7: Error: .COMMon length (-1894967300.) <0! Ignored.
line 7: .common N,1999999996,4
This size is correct, so I suppose the problem is with the assembler. You might need to get a 64 bit one (if it's a Solaris assembler), or try to compile binutils for 64 bit target (if it's using the GNU assembler).
Sorry, did not understand you last time. The source and assembler I have sent is the version that compiles. Here goes the version that fails. The only difference is the size of the vector. The assembler is the "GNU as" and it is 64-capable. Other tools have been successfully compiled with it on the system.
Also here, the assembler output looks correct:
prime-fail.p:
const max=600000000;
var n:array[2..max] of integer;
prime-fail.s:
.common N,2399999996,4
(Not incidentally, the negative size reported in the message is just 2399999996 - 2^32.)
So I still think the problem must be with the assembler. Either it's actually not 64-bit-capable, or it might need a special option for this. I'm afraid I have no experience in that area.
If you have no other recourse, you might want to try assembling prime-fail.s with as directly, and if this fails as expected, compile a similar C file, get its assembler file and assemble it directly. If this works, you should be able to see some significant difference in the Pascal and C assembler outputs. If it also fails for C, apparently those other tools have been built differently and you need to find out how.
BTW, do those other tools actually use such larrge data structures? There's a difference (from the assembler's point of view) between a program that just uses 64 bit instructions and one that contains such large data structures. In the latter case, the assembler itself must be able to work with 64 bit numbers, while in the former case it only needs the 64 bit instruction codes.
Frank
On Tue, 10 Jun 2003, Frank Heckenbach wrote:
Also here, the assembler output looks correct:
prime-fail.p:
const max=600000000;
var n:array[2..max] of integer;
prime-fail.s:
.common N,2399999996,4
(Not incidentally, the negative size reported in the message is just 2399999996 - 2^32.)
So I still think the problem must be with the assembler. Either it's actually not 64-bit-capable, or it might need a special option for this. I'm afraid I have no experience in that area.
OK, I contacted to the binutils guys. I will forward they solution. Also more tests in progress.
BTW, do those other tools actually use such larrge data structures? There's a difference (from the assembler's point of view) between a program that just uses 64 bit instructions and one that contains such large data structures. In the latter case, the assembler itself must be able to work with 64 bit numbers, while in the former case it only needs the 64 bit instruction codes.
We compiled 64 bit versions of gawk and perl. They were tested with large data sets (12 Gig). I know they allocates memory dynamically. That could make the difference I guess.
miklos
Cserzo Miklos wrote:
BTW, do those other tools actually use such larrge data structures? There's a difference (from the assembler's point of view) between a program that just uses 64 bit instructions and one that contains such large data structures. In the latter case, the assembler itself must be able to work with 64 bit numbers, while in the former case it only needs the 64 bit instruction codes.
We compiled 64 bit versions of gawk and perl. They were tested with large data sets (12 Gig). I know they allocates memory dynamically. That could make the difference I guess.
Indeed. The assembler probably doesn't need to do any 64 bit computations for these.
Frank
On Sat, 31 May 2003, Frank Heckenbach wrote:
Frank,
line 7: .common N,1999999996,4
am I right to think that the elements of N are stored on 4 bytes according to this notation? That would explain the size I can see on the "top" as the memory allocation. On the other hand it is a bad news. N supposed to be an integer, i.e. 2 bytes. The compiler allocates twice of the necessary size for the array. It is not a problem for "normal" size arrays but it could be a big problem for larger ones.
Cheers,
miklos
Cserzo Miklos wrote:
On Sat, 31 May 2003, Frank Heckenbach wrote:
Frank,
line 7: .common N,1999999996,4
am I right to think that the elements of N are stored on 4 bytes according to this notation? That would explain the size I can see on the "top" as the memory allocation. On the other hand it is a bad news. N supposed to be an integer, i.e. 2 bytes.
`Integer' is 4 or 8 bytes, depending on the platform, never 2 bytes. To get a 2 bytes integer use `Integer attribute (Size = 16)'.
Frank
On Tue, 3 Jun 2003, Cserzo Miklos wrote:
[ ... ]
N supposed to be an integer, i.e. 2 bytes.
Today's integer is usually 4 bytes. Back in the days of Apple IIe, IBM pc, TRS 80, etc, an integer was 2 bytes. That started changing when the 386 came out, about 20 years ago, with only backwards compatable code using 2 bytes.
I think it is safe to predict that in 20 years an integer will be 8 bytes.
Russ