Jonas Maebe wrote:
On 8 sep 2006, at 16:57, Waldek Hebisch wrote:
What is the size of this packed array in gpc on 64 bit systems:
type ta = 0..$7fffffff; tb = packed array[0..799] of ta;
Is it 3100 or 3104 bytes?
It is 3100. The size is rounded up to the next multiple of half of the wordsize of the machine.
Is there a particular reason for this? This means that e.g. a byte and a "packed array[0..7] of boolean" have a different size (except on 16 bit systems).
This is just artifact of the implementation. Namely, all acceses must be properly aligned (otherwise we get wrong code or crashes on some platforms (ARM, Sparc)). gpc choose half of the wordsize as an access size and always fetches two consecutive halfwords. I guess that fixed size is used for simplicity of implementation and half of the wordsize to avoid double shifts.
This implementation has a number of problems. My plan was to change it. I would like to keep fixed access size -- IMHO pure byte access is the most natural one. Access to the last byte must be conditional.
There is always a compromise between space (forcing bigger alignment) and number of acceses needed to fetch given value -- I do not think that we must limit number of access to two.
On 64 bit machines wordsize is 8 bytes, so the size is rounded up to the multiple of 4-bytes. Since 3100 is a multiple of 4 the roundig up is a no-op here. BTW: when accesing the last element the current implementation will touch the 4-byte word beyond the end of the array (it is a bug ...).
Will this fixed by rounding up the size to a multiple of 8 bytes, or by turning all accesses into maximally half word accesses? I'd like to keep packed array sizes the same between fpc and gpc. Currently fpc rounds the size up to the access size, which is calculated as follows:
function packedbitsloadsize(bitlen: int64) : int64; begin case bitlen of 1,2,4,8: result := 1; { 10 bits can never be split over 3 bytes via 1-8-1,
because it } { always starts at a multiple of 10 bits. Same for the others. } 3,5,7,9,10,12,16: result := 2; {$ifdef cpu64bit} 11,13,14,15,17..26,28,32: result := 4; else result := 8; {$else cpu64bit} else result := 4; {$endif cpu64bit} end; end;
It basically chooses the smallest size possible which can encompass the entire value (although of course it sometimes still needs to be split into two accesses in case of access size boundary crossing). For my tests (on 32 bit systems) this corresponded with gpc sizes, but I didn't test exhaustively so was just coincidence I guess.
Yes, gpc uses the same access size for all bit lenths. There is always a compromise between space (forcing bigger alignment) and number of acceses needed to fetch given value.
On a related note, can someone explain me how to build gpc for Mac OS X/ppc64? powerpc64-apple-darwin8 doesn't seem to be a supported target, but maybe it's called differently?
You should already have 64 bit compiler proper (at least when using sufficiently new backend) -- try what `-print-multi-lib' gives you.
bigmac:~ jonas$ gpc -v Reading specs from /Developer/Pascal/gpc345u2/lib/gcc/powerpc-apple- darwin8/3.4.5/specs Configured with: ../gcc-3.4.5/configure --enable-languages=pascal,c -- enable-threads=posix --target=powerpc-apple-darwin8 --host=powerpc- apple-darwin8 --build=powerpc-apple-darwin8 --prefix=/Developer/ Pascal/gpc345u2 Thread model: posix gpc version 20051116, based on gcc-3.4.5 bigmac:~ jonas$ gpc -print-multi-lib .;
(this is Adriaan's Mac OS X distribution)
And at least "gpc -m64" doesn't work:
bigmac:~/fpc/test jonas$ gpc -m64 tt.pp gpc1: error: invalid option `64'
The problem is that ATM gpc runtime is build only in one version (32 bit one) -- one have to build 64 bit runtime by hand. Peter Keenan described what to do for 64 bit AIX:
http://www.gnu-pascal.de/crystal/gpc/en/mail11264.html
With obvious changes this should apply to OS/X.
I think I don't have a 64 bit gpc.
Yes, probably 3.4.x backend supports only 32 bit programs on OS/X. AFAICS 4.0.x and later backends have 64-bit support.