Please see below ...
Joe.
-----Original Message----- From: Sven Jauring [SMTP:sven.jauring@hiq.se] Sent: Thursday, August 23, 2001 6:52 PM To: gpc@gnu.de Subject: Re: Need a complete set implementation in GPC (data alignment)
Hi Frank
Thank you for your help. I modifed the compiler according to your instructions so that it uses Byte instead of MedCard for sets. It worked wonders for the two 8 bit sets. (BSLB and BSHB in my example code below). Unfortunately I ran into trouble with the 16 bit sets.
I need BIT0 to represent the least and BIT15 the most significant bit, but since the 16 bit set is split into two bytes, BIT8 represents the least and BIT7 the most significant bit:
+-----+---+----+-----+---+----+
USRINT |bit15|...|bit8|bit7 |...|bit0| +-----+---+----+-----+---+----+ BT |BIT7 |...|BIT0|BIT15|...|BIT8| +-----+---+----+-----+---+----+
This seems like some sort of LittleEndianness?
[Joe da Silva]
It sure does!
Since this code seems to still be supported by it's creators, perhaps you can request them to put some sort of conditional compilation in the code, to take care of big/little-endianness?
Is it possible to have the byte order shifted, so that USRINT and BT aligns?
I can't just change the order of declaration for BITS, e.g BITS=(BIT8,...,BIT15,...,BIT0,...,BIT7), since that would "undermine" the use of ord() and subsets (e.g [BIT6..BIT8]).
The Pascal code that I need to compile is not actually ours, so any changes to the code has to be done everytime a new version is released. (It is also rather large...) The code would not have had this kind of contructions had it been ours. ;-)
Best Regards Sven Jauring
Frank Heckenbach wrote:
Sven Jauring wrote:
Recently I posted some questions concerning problems with 16 bit
sets.
I got good suggestions from some of you, but further analysis of
the
code revealed this kind of construct:
TYPE INT16 = INTEGER(16); INT8 = packed 0.. INT0_65535 = packed 0..65535; B_TYPE = (B1, B2, B3, B4, B5, B6, B7, B8); BITS =
(BIT0,BIT1,BIT2,BIT3,BIT4,BIT5,BIT6,BIT7,BIT8,BIT9,
BIT10,BIT11,BIT12,BIT13,BIT14,BIT15); B_TYPE_SET = set of B_TYPE; BIT_SET = set of BITS;
VAR OUT_REC = record case INT16 of 0 : (BSLB: B_TYPE_SET; BSHB: B_TYPE_SET); 1 : (USRINT : INT0_65535); 2 : (BT: BIT_SET); END;
I haven't followed the thread too intensely since I was out of town last week. If I understand it correctly, what you need is that a set
of a type of, say 8, elements is only 1 byte large. (However, in the
code above, there will also be endianness problems, i.e. on a little-endian system BSLB would align with the least significant bits of USRINT and on a big-endian system with the most significant bits; this problem could be overcome with a conditional compilation,
see, e.g., the declaration of TWindowXY in GPC's CRT unit).
GPC internally stores sets as arrays of a certain type, currently MedCard. It is fairly easy to change that type to Byte (requires a small change in p/rts/sets.pas (TSelElement) and two in p/util.c (set_word_size and set_alignment)).
However note:
This will slightly decrease the performance of set routines since they will use byte rather than word operations internally.
Sets with and without this change will be incompatible. Don't try to mix object files created by a patched and an unpatched compiler.
This works only down to bytes. Trying even smaller types (like Cardinal (4)) there will not work.
Another approach would be to keep the array of words for sets at least as big as a word, and use a single smaller type for smaller sets. Then they would take only as many bits as required within a packed record. However, this would require quite some effort. Basically, every set operation would have to check if their arguemnts are of the second type and convert them, and likewise convert back the result.
Personally, I'd suggest to change your Pascal code to not rely on the variant alignment and such ...
Frank
-- Frank Heckenbach, frank@g-n-u.de, http://fjf.gnu.de/ GPC To-Do list, latest features, fixed bugs: http://agnes.dida.physik.uni-essen.de/~gnu-pascal/todo.html << File: Card for Sven Jauring >>