* Bitmanipulation in Ada @ 2004-08-18 20:37 Bernd Specht 2004-08-18 20:51 ` Ludovic Brenta ` (3 more replies) 0 siblings, 4 replies; 38+ messages in thread From: Bernd Specht @ 2004-08-18 20:37 UTC (permalink / raw) Hi, i have some questions regarding bitmanipulations: 1. I found bitwise "and", "or" and "xor" operations, but as far as I understand they are applicable only for modular types or packed boolean arrays. Is this correct? 2. I did not found shift and rotate operations. Did I miss something or are there really none? 3. When I want treat a value both as an integer and as a boolean array, how can i do this? In pascal I would use a tagless record like TYPE ov is record case boolean of true : i : integer; false : byte_array; end; end; Such overlay structures are not valid with Ada, so what do instead? thanks ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-18 20:37 Bitmanipulation in Ada Bernd Specht @ 2004-08-18 20:51 ` Ludovic Brenta 2004-08-18 21:10 ` Bernd Specht 2004-08-18 21:14 ` (see below) ` (2 subsequent siblings) 3 siblings, 1 reply; 38+ messages in thread From: Ludovic Brenta @ 2004-08-18 20:51 UTC (permalink / raw) (Bernd Specht) writes: > Hi, > > i have some questions regarding bitmanipulations: > > 1. I found bitwise "and", "or" and "xor" operations, but as far as I > understand they are applicable only for modular types or packed boolean > arrays. Is this correct? Yes. > 2. I did not found shift and rotate operations. Did I miss something or are > there really none? These operations are usually carried out in hardware for certain sizes of modular integers only. Consequently, these operations are defined in package Interfaces (see RM 3.5.4(31) and B.2). Package Interfaces defines the following subprograms: function Shift_Left (Value : Unsigned_n; Amount : Natural) return Unsigned_n; function Shift_Right (Value : Unsigned_n; Amount : Natural) return Unsigned_n; function Shift_Right_Arithmetic (Value : Unsigned_n; Amount : Natural) return Unsigned_n; function Rotate_Left (Value : Unsigned_n; Amount : Natural) return Unsigned_n; function Rotate_Right (Value : Unsigned_n; Amount : Natural) return Unsigned_n; Each compiler provides Unsigned_n types for various values of n corresponding to natural sizes of the target hardware. Doing bit rotations in the general case does not necessarily make sense, because the modulo of the type may not be a power of two. > 3. When I want treat a value both as an integer and as a boolean array, how > can i do this? In pascal I would use a tagless record like > > TYPE ov is record > case boolean of > true : i : integer; > false : byte_array; > end; > end; > > Such overlay structures are not valid with Ada, so what do instead? Have you considered a variant record? type Ov (T : Boolean) is record case T is when True => I : Integer; when False => B : Byte_Array; end T; end record; If what you really want is to convert an integer to a byte array, use Unchecked_Conversion: with Ada.Unchecked_Conversion; procedure P is type Byte_Array is array (1 .. Integer'Size) of Boolean; pragma Pack (Byte_Array); for Byte_Array'Size use Integer'Size; function To_Byte_Array is new Ada.Unchecked_Conversion (Source => Integer, Target => Byte_Array); I : Integer := 42; B : Byte_Array := To_Byte_Array (I); begin null; end P; -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-18 20:51 ` Ludovic Brenta @ 2004-08-18 21:10 ` Bernd Specht 2004-08-18 21:16 ` Ludovic Brenta ` (2 more replies) 0 siblings, 3 replies; 38+ messages in thread From: Bernd Specht @ 2004-08-18 21:10 UTC (permalink / raw) Ludovic Brenta <ludovic.brenta@insalien.org> wrote in news:87k6vwrwym.fsf@insalien.org: > (Bernd Specht) writes: >> Hi, Thanks. >> 2. I did not found shift and rotate operations. Did I miss something >> or are there really none? > > These operations are usually carried out in hardware for certain sizes > of modular integers only. Consequently, these operations are defined > in package Interfaces (see RM 3.5.4(31) and B.2). Package Interfaces > defines the following subprograms: > > function Shift_Left (Value : Unsigned_n; > Amount : Natural) return Unsigned_n; > function Shift_Right (Value : Unsigned_n; > Amount : Natural) return Unsigned_n; > function Shift_Right_Arithmetic (Value : Unsigned_n; > Amount : Natural) > return Unsigned_n; > function Rotate_Left (Value : Unsigned_n; > Amount : Natural) return Unsigned_n; > function Rotate_Right (Value : Unsigned_n; > Amount : Natural) return Unsigned_n; Ok. Is there a reason why it is not (directly) available in the language itself like the and/or/xor or the >> and << in C? >> 3. When I want treat a value both as an integer and as a boolean >> array, how can i do this? In pascal I would use a tagless record like >> Such overlay structures are not valid with Ada, so what do instead? > > Have you considered a variant record? > > type Ov (T : Boolean) is record > case T is > when True => I : Integer; > when False => B : Byte_Array; > end T; > end record; I found, that (at least GNAT) different storage locations are used for i and b. > If what you really want is to convert an integer to a byte array, use > Unchecked_Conversion: OK, but this would result in an assignment operation (a memory move on maschine code level). What I want is a real "overlay" (same storage location used for both), so reading the value would not need extra instructions. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-18 21:10 ` Bernd Specht @ 2004-08-18 21:16 ` Ludovic Brenta 2004-08-18 21:18 ` Ed Falis 2004-08-19 0:53 ` Jeffrey Carter 2 siblings, 0 replies; 38+ messages in thread From: Ludovic Brenta @ 2004-08-18 21:16 UTC (permalink / raw) (Bernd Specht) writes: > Ok. Is there a reason why it is not (directly) available in the language > itself like the and/or/xor or the >> and << in C? Yes. As I said, in Ada, modular types do not necessarily have a power of two as their modulo; nor do they necessarily have a "natural" size. You could have for example: type T is mod 17; for T'Size use 43; Since C only has modular types, and since all types in C have "natural" sizes, it makes sense to provide the shift and rotate operations in the language. >> If what you really want is to convert an integer to a byte array, use >> Unchecked_Conversion: > > OK, but this would result in an assignment operation (a memory move on > maschine code level). What I want is a real "overlay" (same storage location > used for both), so reading the value would not need extra instructions. Ah, OK. procedure P is type Byte_Array is array (1 .. Integer'Size) of Boolean; pragma Pack (Byte_Array); for Byte_Array'Size use Integer'Size; I : Integer := 42; B : Byte_Array; -- Specify that B and I are at the same address for B'Address use I'Address; begin for J in B'Range loop Ada.Text_IO.Put_Line (Boolean'Image (B (J))); end loop; end P; HTH -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-18 21:10 ` Bernd Specht 2004-08-18 21:16 ` Ludovic Brenta @ 2004-08-18 21:18 ` Ed Falis 2004-08-19 17:30 ` Bernd Specht 2004-08-19 0:53 ` Jeffrey Carter 2 siblings, 1 reply; 38+ messages in thread From: Ed Falis @ 2004-08-18 21:18 UTC (permalink / raw) On 18 Aug 2004 21:10:30 GMT, Bernd Specht <Bernd.Specht@gmx.com> wrote: > Ok. Is there a reason why it is not (directly) available in the language > itself like the and/or/xor or the >> and << in C? Doesn't really matter, since most implementations directly generate the code for these (they treat them as "instrinsic"). > > OK, but this would result in an assignment operation (a memory move on > maschine code level). What I want is a real "overlay" (same storage > location > used for both), so reading the value would not need extra instructions. In all implementations of which I'm aware (and I've been in the Ada compiler business for over 20 years) no code would be generated for an unchecked conversion where the source and target have the same size. You sound like you're looking for things to complain about, by the way. - Ed -- "When I was a kid, I wanted to grow up to be a wise man. Somehow, I just turned out to be a wise guy". ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-18 21:18 ` Ed Falis @ 2004-08-19 17:30 ` Bernd Specht 2004-08-19 17:44 ` Ed Falis 0 siblings, 1 reply; 38+ messages in thread From: Bernd Specht @ 2004-08-19 17:30 UTC (permalink / raw) "Ed Falis" <falis@verizon.net> wrote in news:opscx5geap5afhvo@localhost: > On 18 Aug 2004 21:10:30 GMT, Bernd Specht <Bernd.Specht@gmx.com> wrote: > >> OK, but this would result in an assignment operation (a memory move on >> maschine code level). What I want is a real "overlay" (same storage >> location used for both), so reading the value would not need extra >> instructions. > > In all implementations of which I'm aware (and I've been in the Ada > compiler business for over 20 years) no code would be generated for an > unchecked conversion where the source and target have the same size. Sorry, but that's absolutely *nonsense* Have a look at Ludovics code: with Ada.Unchecked_Conversion; procedure P is type Byte_Array is array (1 .. Integer'Size) of Boolean; pragma Pack (Byte_Array); for Byte_Array'Size use Integer'Size; function To_Byte_Array is new Ada.Unchecked_Conversion (Source => Integer, Target => Byte_Array); I : Integer := 42; B : Byte_Array := To_Byte_Array (I); begin null; end P; You agree that "I" and "B" are located at different adresses? Do you *really* think that you need *no* code to move data from one address to another??? That's wrong! You need at least *one* instruction, and this can be time consuming - especially if the data is missaligned and/or the code runs in a multiprocessor environment. > You sound like you're looking for things to complain about, by the way. Sorry - but you seem to be a blatherer. > (and I've been in the Ada compiler business for over 20 years) Wow! Be happy. > > - Ed *plonk* ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-19 17:30 ` Bernd Specht @ 2004-08-19 17:44 ` Ed Falis 0 siblings, 0 replies; 38+ messages in thread From: Ed Falis @ 2004-08-19 17:44 UTC (permalink / raw) On 19 Aug 2004 17:30:17 GMT, Bernd Specht <Bernd.Specht@gmx.com> wrote > EF wrote: >> In all implementations of which I'm aware (and I've been in the Ada >> compiler business for over 20 years) no code would be generated for an >> unchecked conversion where the source and target have the same size. > > Sorry, but that's absolutely *nonsense* > You agree that "I" and "B" are located at different adresses? Do you > *really* think that you need *no* code to move data from one address to > another??? That's wrong! You need at least *one* instruction, and this > can > be time consuming - especially if the data is missaligned and/or the code > runs in a multiprocessor environment. I believe your original complaint was about cost of conversion, not of assignment - and this is what I was responding to. The conversion costs nothing (in the implementations I'm aware of). If you assign, you of course have at least one instruction, regardless of the types. If the conversion appeared as part of an expression being evaluated, there would be no overhead related to it. Of course, if you insist on separately-named entities, then try: with Ada.Unchecked_Conversion; procedure P is type Byte_Array is array (1 .. Integer'Size) of Boolean; pragma Pack (Byte_Array); for Byte_Array'Size use Integer'Size; function To_Byte_Array is new Ada.Unchecked_Conversion (Source => Integer, Target => Byte_Array); I : Integer := 42; B : Byte_Array renames To_Byte_Array (I); begin null; end P; Compile some code and take a look at the generated assembly language. - Ed ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-18 21:10 ` Bernd Specht 2004-08-18 21:16 ` Ludovic Brenta 2004-08-18 21:18 ` Ed Falis @ 2004-08-19 0:53 ` Jeffrey Carter 2004-08-19 17:44 ` Bernd Specht 2 siblings, 1 reply; 38+ messages in thread From: Jeffrey Carter @ 2004-08-19 0:53 UTC (permalink / raw) Bernd Specht wrote: > Ok. Is there a reason why it is not (directly) available in the > language itself like the and/or/xor or the >> and << in C? Shift and rotate operations only make sense for types that are a "natural" size for the underlying hardware. Those are the only kind of integer types available in C. Since Ada also provides user-defined numeric types, which may not be a natural size for the hardware, these can only be provided for types which are a natural size. > OK, but this would result in an assignment operation (a memory move > on maschine code level). What I want is a real "overlay" (same > storage location used for both), so reading the value would not need > extra instructions. That may be what you want. What a software engineer wants is the clearest software that meets the requirements. Unchecked_Conversion will almost always provide this. In many cases, Unchecked_Conversion will generate no code, and need not involve an assignment. In well designed software, the part(s) of the software that deals with values as an integer and those that deal with them as bit arrays will be kept separate. So you do something like: with Ada.Unchecked_Conversion; procedure Deals_2_Ways is type Bit_Array is array (1 .. Integer'Size) of Boolean; pragma Pack (Bit_Array); for Bit_Array'Component_Size use 1; for Bit_Array'Size use Integer'Size; function Get return Integer is separate; Value : Integer := Get; procedure Deal_With_Integer (Value : in out Integer) is separate; procedure Deal_With_Bit_Array (Value : in out Bit_Array) is separate; function To_Bit is new Ada.Unchecked_Conversion (Source => Integer, Target => Bit_Array); begin -- Deals_2_Ways Deal_With_Integer (Value => Value); Deal_With_Bit_Array (Value => To_Bit (Value) ); end Deals_2_Ways; -- Jeff Carter "I'm particularly glad that these lovely children were here today to hear that speech. Not only was it authentic frontier gibberish, it expressed a courage little seen in this day and age." Blazing Saddles 88 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-19 0:53 ` Jeffrey Carter @ 2004-08-19 17:44 ` Bernd Specht 2004-08-19 18:09 ` Martin Dowie ` (3 more replies) 0 siblings, 4 replies; 38+ messages in thread From: Bernd Specht @ 2004-08-19 17:44 UTC (permalink / raw) Jeffrey Carter <spam@spam.com> wrote in news:wSSUc.27249$9Y6.977 @newsread1.news.pas.earthlink.net: > Bernd Specht wrote: > That may be what you want. What a software engineer wants is the > clearest software that meets the requirements. Unchecked_Conversion will > almost always provide this. Sure. > In many cases, Unchecked_Conversion will generate no code, and need not > involve an assignment. In well designed software, the part(s) of the > software that deals with values as an integer and those that deal with > them as bit arrays will be kept separate. So you do something like: Always? What do you think about bitscrambling software which has to treat data alternating as bitvector and as integer value in a loop like this (not exeactly this for securitity reasons): ... loop declare x : boolean; begin x := b(k); b(k) := b(32 - k); b (32 - k) := x; I := I * prime1 mod prime2; end; end loop; Can you find an equivalent algorithm where you can separate the bit-ops and the integer-ops? ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-19 17:44 ` Bernd Specht @ 2004-08-19 18:09 ` Martin Dowie 2004-08-19 18:28 ` Bernd Specht 2004-08-19 19:17 ` Jeffrey Carter ` (2 subsequent siblings) 3 siblings, 1 reply; 38+ messages in thread From: Martin Dowie @ 2004-08-19 18:09 UTC (permalink / raw) Bernd Specht wrote: > Always? What do you think about bitscrambling software which has to > treat data alternating as bitvector and as integer value in a loop > like this (not exeactly this for securitity reasons): > > ... > loop > declare > x : boolean; > begin > x := b(k); > b(k) := b(32 - k); > b (32 - k) := x; > I := I * prime1 mod prime2; > end; > end loop; > > > Can you find an equivalent algorithm where you can separate the > bit-ops and the integer-ops? Sorry, I'm missing something... Are "I" and "b" different views of the same address space? ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-19 18:09 ` Martin Dowie @ 2004-08-19 18:28 ` Bernd Specht 2004-08-19 19:31 ` Martin Dowie 2004-08-19 20:29 ` Martin Dowie 0 siblings, 2 replies; 38+ messages in thread From: Bernd Specht @ 2004-08-19 18:28 UTC (permalink / raw) "Martin Dowie" <martin.dowie@btopenworld.com> wrote in news:cg2qcj$de0$1@titan.btinternet.com: > Bernd Specht wrote: >> Always? What do you think about bitscrambling software which has to >> treat data alternating as bitvector and as integer value in a loop >> like this (not exeactly this for securitity reasons): >> >> ... >> loop >> declare >> x : boolean; >> begin >> x := b(k); >> b(k) := b(32 - k); >> b (32 - k) := x; >> I := I * prime1 mod prime2; >> end; >> end loop; >> >> >> Can you find an equivalent algorithm where you can separate the >> bit-ops and the integer-ops? > > Sorry, I'm missing something... Are "I" and "b" different views of the > same address space? > Sorry, I and b are as mentioned earlier: >> TYPE ov is record >> case boolean of >> true : i : integer; >> false : byte_array; >> end; >> end; ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-19 18:28 ` Bernd Specht @ 2004-08-19 19:31 ` Martin Dowie 2004-08-19 20:29 ` Martin Dowie 1 sibling, 0 replies; 38+ messages in thread From: Martin Dowie @ 2004-08-19 19:31 UTC (permalink / raw) Bernd Specht wrote: >> Sorry, I'm missing something... Are "I" and "b" different views of >> the same address space? >> > > > Sorry, I and b are as mentioned earlier: > >>> TYPE ov is record >>> case boolean of >>> true : i : integer; >>> false : byte_array; >>> end; >>> end; Ok so I is a 32-bit integer and b is a packed array of boolean (in your demo a 32-bit 'byte'). ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-19 18:28 ` Bernd Specht 2004-08-19 19:31 ` Martin Dowie @ 2004-08-19 20:29 ` Martin Dowie 2004-08-20 21:31 ` Bernd Specht 1 sibling, 1 reply; 38+ messages in thread From: Martin Dowie @ 2004-08-19 20:29 UTC (permalink / raw) Bernd Specht wrote: > Sorry, I and b are as mentioned earlier: > >>> TYPE ov is record >>> case boolean of >>> true : i : integer; >>> false : byte_array; >>> end; >>> end; Well, this isn't a complete solution (I've got a 4-year old to put to bed right now...) but it could send you on an alternative course (if the algorithm you posted is doing what I think it is! ;-) procedure Alternative (I : Unsigned_32) is K1, K2 : Unsigned_32; begin K1 := 16#8000_0000#; K2 := 16#0000_0001#; loop declare K1_Mask_Off : Unsigned_32 := 16#FFFF_FFFF# xor K1; K1_Mask_On : Unsigned_32 := 16#FFFF_FFFF# and K1; X1, X2 : Unsigned_32; begin Put ("K1"); IO.Put (K1, Base => 16); New_Line; Put ("K2"); IO.Put (K2, Base => 16); New_Line; Put ("K1_Mask_Off = "); IO.Put (K1_Mask_Off, Base => 16); New_Line; Put ("K1_Mask_On = "); IO.Put (K1_Mask_On, Base => 16); New_Line; X1 := I and K1; X2 := I and K2; K1 := Shift_Right (K1, 1); K2 := Shift_Left (K2, 1); exit when K2 = 0; end; end loop; end Alternative; The idea behind your loop (I think) is to swap bits from either end from MSBit to LSBit with a prime number 'twist' in each step? You can do this using the above as the basis for that solution - all in 'Unsigned_32'. Cheers -- Martin ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-19 20:29 ` Martin Dowie @ 2004-08-20 21:31 ` Bernd Specht 0 siblings, 0 replies; 38+ messages in thread From: Bernd Specht @ 2004-08-20 21:31 UTC (permalink / raw) "Martin Dowie" <martin.dowie@btopenworld.com> wrote in news:cg32ja$qru$1@titan.btinternet.com: > Bernd Specht wrote: > Well, this isn't a complete solution (I've got a 4-year old to put to > bed right now...) but it could send you on an alternative course (if > the algorithm you posted is doing what I think it is! ;-) I think you're right. > The idea behind your loop (I think) is to swap bits from either end > from MSBit to LSBit with a prime number 'twist' in each step? Yes, but thats not exactly my task. I do some kind of data scrambling for transmission over public network. > You can > do this using the above as the basis for that solution - all in > 'Unsigned_32'. Yes, I think so. Thanks. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-19 17:44 ` Bernd Specht 2004-08-19 18:09 ` Martin Dowie @ 2004-08-19 19:17 ` Jeffrey Carter 2004-08-19 19:57 ` Björn Persson 2004-08-19 21:24 ` Francois G. Dorais 2004-08-20 7:26 ` Jean-Pierre Rosen 3 siblings, 1 reply; 38+ messages in thread From: Jeffrey Carter @ 2004-08-19 19:17 UTC (permalink / raw) Bernd Specht wrote: > Jeffrey Carter <spam@spam.com> wrote in news:wSSUc.27249$9Y6.977 > @newsread1.news.pas.earthlink.net: >>In many cases, Unchecked_Conversion will generate no code, and need not >>involve an assignment. In well designed software, the part(s) of the >>software that deals with values as an integer and those that deal with >>them as bit arrays will be kept separate. So you do something like: > > Always? What do you think about bitscrambling software which has to treat > data alternating as bitvector and as integer value in a loop like this (not > exeactly this for securitity reasons): I don't see any claims for "always" in my statements. > ... > loop > declare > x : boolean; > begin > x := b(k); > b(k) := b(32 - k); > b (32 - k) := x; > I := I * prime1 mod prime2; > end; > end loop; > > Can you find an equivalent algorithm where you can separate the bit-ops and > the integer-ops? Assuming that I and B are Integer and Bit_Array versions of the same value, sure. Replace the assignment to I with Update_Integer (Value => To_Integer (B) ); where procedure Update_Integer (Value : in out Integer) is -- null; begin -- Update_Integer Value := Value * Prime1 mod Prime2; end Update_Integer; and To_Integer is an appropriate instantiation of Unchecked_Conversion. If measurement shows that the overhead of calling a procedure causes you to violate timing requirements, you can inline the procedure. -- Jeff Carter "Sons of a silly person." Monty Python & the Holy Grail 02 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-19 19:17 ` Jeffrey Carter @ 2004-08-19 19:57 ` Björn Persson 2004-08-20 0:52 ` Jeffrey Carter 0 siblings, 1 reply; 38+ messages in thread From: Björn Persson @ 2004-08-19 19:57 UTC (permalink / raw) Jeffrey Carter wrote: > Replace the assignment to I with > > Update_Integer (Value => To_Integer (B) ); You can't send a function result to an in out parameter, can you? Make Update_Integer a function instead: function Updated_Integer(I : Integer) return Integer is begin return I * prime1 mod prime2; end Updated_Integer; .... loop declare x : boolean; begin x := b(k); b(k) := b(32 - k); b (32 - k) := x; b := To_Bit_Array(Updated_Integer(To_Integer(b))); end; end loop; -- Björn Persson PGP key A88682FD omb jor ers @sv ge. r o.b n.p son eri nu ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-19 19:57 ` Björn Persson @ 2004-08-20 0:52 ` Jeffrey Carter 0 siblings, 0 replies; 38+ messages in thread From: Jeffrey Carter @ 2004-08-20 0:52 UTC (permalink / raw) Bj�rn Persson wrote: > You can't send a function result to an in out parameter, can you? Make > Update_Integer a function instead: You can pass a conversion as a parameter; that's been around since at least Ada 83. Unchecked_Conversion is technically a function, but it's special, since it generally doesn't generate any code, much less a function call. You're correct, though; this should be a function. -- Jeff Carter "Sons of a silly person." Monty Python & the Holy Grail 02 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-19 17:44 ` Bernd Specht 2004-08-19 18:09 ` Martin Dowie 2004-08-19 19:17 ` Jeffrey Carter @ 2004-08-19 21:24 ` Francois G. Dorais 2004-08-20 8:55 ` Pascal Obry 2004-08-20 7:26 ` Jean-Pierre Rosen 3 siblings, 1 reply; 38+ messages in thread From: Francois G. Dorais @ 2004-08-19 21:24 UTC (permalink / raw) Bernd Specht wrote: > Always? What do you think about bitscrambling software which has to treat > data alternating as bitvector and as integer value in a loop like this (not > exeactly this for securitity reasons): > > ... > loop > declare > x : boolean; > begin > x := b(k); > b(k) := b(32 - k); > b (32 - k) := x; > I := I * prime1 mod prime2; > end; > end loop; > > > Can you find an equivalent algorithm where you can separate the bit-ops and > the integer-ops? A generic solution for the above is to encapsulate the bit fiddling in an inlined procedure. For example, consider the following where I replaced your bit operation by one which doesn't implicitly need a copy (to store the K-th bit in your example.) with Ada.Unchecked_Conversion; [...] type Unsigned_32 is mod 2 ** 32; for Unsigned_32'Size use 32; subtype Bit_Index_32 is Integer range 0 .. 31; -- This avoids many range checks... procedure Bit_Fiddle (U : in out Unsigned_32; K : in Bit_Index_32) is type Bits_32 is array (Bit_Index_32) of Boolean; for Bits_32'Component_Size use 1; function To_Unsigned is new Ada.Unchecked_Conversion (Bits_32, Unsigned_32); function To_Bits is new Ada.Unchecked_Conversion (Unsigned_32, Bits_32); B : Bits_32 := To_Bits(U); begin B(K) := B(31 - K); U := To_Unsigned(B); end Bit_Fiddle; pragma Inline (Bit_Fiddle); [...] GNAT compiles the above without copy instructions if it doesn't need to. For example, try [...] for K in Bit_Index_32 loop Bit_Fiddle(X, K); X := X + 16#39A2_D071#; end loop; [...] I got the following x86 asm code from gnat 3.15p (with options "-S -O2 -gnaton") It uses register ebx for the loop counter K, it stores value 31 in edi throughout and X is initially in register esi. [...] xorl %ebx,%ebx addl $16,%esp movl $31,%edi .align 4 .L65: movl $1,%eax movl %ebx,%ecx sall %cl,%eax notl %eax movl %esi,%edx andl %eax,%edx movl %edi,%eax subl %ebx,%eax movl %eax,%ecx shrl %cl,%esi movl %esi,%eax andl $1,%eax movl %ebx,%ecx sall %cl,%eax movl %edx,%esi orl %eax,%esi addl $966971505,%esi incl %ebx cmpl $31,%ebx jle .L65 [...] This is not necessarily optimal code, but it's pretty decent. But since your example already needs a copy to save the k-th bit and probably more for the mul/mod, it's propbably more efficient to force the bit array B to be distinct from the integer I. The following should do what you want pretty efficiently. (I took the liberty to replace your mul/mod by an arithmetically correct one...) [...] type Unsigned_32 is mod 2 ** 32; for Unsigned_32'Size use 32; subtype Bit_Index_32 is Integer range 0 .. 31; type Bits_32 is array (Bit_Index_32) of Boolean; for Bits_32'Component_Size use 1; function To_Unsigned is new Ada.Unchecked_Conversion (Bits_32, Unsigned_32); function To_Bits is new Ada.Unchecked_Conversion (Unsigned_32, Bits_32); function Mul_Mod (Op_1, Op_2, Modulus : Unsigned_32) return Unsigned_32 is type Unsigned_64 is mod 2 ** 64; begin return Unsigned_32((Unsigned_64(Op_1) * Unsigned_64(Op_2)) mod Unsigned_64(Modulus)); end Mul_Mod; pragma Inline (Mul_Mod); [...] for K in Bit_Index_32 loop declare B : Bits_32 := To_Bits(I); begin B(K) := B(31 - K); B(31 - K) := To_Bits(I)(K); I := Mul_Mod(To_Unsigned(B), Prime_1, Prime_2); end; end loop; [...] Try it with GNAT and look at the generated code, you might be surprized. However, I know that bit arrays are usually not optimally handled by most compilers (for any language.) GNAT seems to do a pretty decent job in general, but when I have to do this kind of thing and time optimization is very important, I use the tools provided by package Interfaces and do the bit-fiddling code myself (as one would do in C) or else I use package System.Machine_Code to insert some hand optimized assembly code where needed. Alas, there is no such thing as a perfect compiler! ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-19 21:24 ` Francois G. Dorais @ 2004-08-20 8:55 ` Pascal Obry 0 siblings, 0 replies; 38+ messages in thread From: Pascal Obry @ 2004-08-20 8:55 UTC (permalink / raw) "Francois G. Dorais" <dorais@gauss.dartmouth.edu> writes: > This is not necessarily optimal code, but it's pretty decent. Do not forget that the GCC backend with 3.15p is GCC 2.8.1. The latest version of GNAT is based on GCC 3.4.x and there is lot more optimizations done by this new backend. Pascal. -- --|------------------------------------------------------ --| Pascal Obry Team-Ada Member --| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE --|------------------------------------------------------ --| http://www.obry.org --| "The best way to travel is by means of imagination" --| --| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595 ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-19 17:44 ` Bernd Specht ` (2 preceding siblings ...) 2004-08-19 21:24 ` Francois G. Dorais @ 2004-08-20 7:26 ` Jean-Pierre Rosen 2004-08-20 21:20 ` Bernd Specht 3 siblings, 1 reply; 38+ messages in thread From: Jean-Pierre Rosen @ 2004-08-20 7:26 UTC (permalink / raw) Bernd Specht a écrit : > Always? What do you think about bitscrambling software which has to treat > data alternating as bitvector and as integer value in a loop like this (not > exeactly this for securitity reasons): > > ... > loop > declare > x : boolean; > begin > x := b(k); > b(k) := b(32 - k); > b (32 - k) := x; > I := I * prime1 mod prime2; > end; > end loop; > Such software does not use signed integers, but modular integers. And you have all the bit operations you need on modular integers. -- --------------------------------------------------------- J-P. Rosen (rosen@adalog.fr) Visit Adalog's web site at http://www.adalog.fr ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-20 7:26 ` Jean-Pierre Rosen @ 2004-08-20 21:20 ` Bernd Specht 2004-08-20 21:39 ` Ed Falis 0 siblings, 1 reply; 38+ messages in thread From: Bernd Specht @ 2004-08-20 21:20 UTC (permalink / raw) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 817 bytes --] Jean-Pierre Rosen <rosen@adalog.fr> wrote in news:1394gc.kok.ln@skymaster: > Bernd Specht a �crit : > >> Always? What do you think about bitscrambling software which has to >> treat data alternating as bitvector and as integer value in a loop >> like this (not exeactly this for securitity reasons): >> >> ... >> loop >> declare >> x : boolean; >> begin >> x := b(k); >> b(k) := b(32 - k); >> b (32 - k) := x; >> I := I * prime1 mod prime2; >> end; >> end loop; >> > > Such software does not use signed integers, but modular integers. And > you have all the bit operations you need on modular integers. In fact, thats right :-o Can I declare full 32-bit modular types? Ada itself has no 32-bit unsigned (except in Interfaces.C). Natural is only a *subrange* from Integer. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-20 21:20 ` Bernd Specht @ 2004-08-20 21:39 ` Ed Falis 0 siblings, 0 replies; 38+ messages in thread From: Ed Falis @ 2004-08-20 21:39 UTC (permalink / raw) On 20 Aug 2004 21:20:49 GMT, Bernd Specht <Bernd.Specht@gmx.com> wrote: > Can I declare full 32-bit modular types? You can use the "sized" versions provided in package Interfaces (eg Unsigned_32), or declare your own: "type Word is mod 2 ** 32; - Ed -- "When I was a kid, I wanted to grow up to be a wise man. Somehow, I just turned out to be a wise guy". ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-18 20:37 Bitmanipulation in Ada Bernd Specht 2004-08-18 20:51 ` Ludovic Brenta @ 2004-08-18 21:14 ` (see below) 2004-08-18 21:56 ` Martin Dowie 2004-08-18 21:53 ` Martin Dowie 2004-08-20 20:57 ` Bitordering? was " Alfred Hilscher 3 siblings, 1 reply; 38+ messages in thread From: (see below) @ 2004-08-18 21:14 UTC (permalink / raw) On 18/8/04 9:37 pm, in article Xns9549E5E9CFFB1BerndSpechgmxcom@151.189.20.10, "Bernd Specht" <Bernd.Specht@gmx.com> wrote: > 3. When I want treat a value both as an integer and as a boolean array, how > can i do this? In pascal I would use a tagless record like > > TYPE ov is record > case boolean of > true : i : integer; > false : byte_array; > end; > end; > > Such overlay structures are not valid with Ada, so what do instead? Such usages are not valid in (ISO Standard) Pascal either, but you don't let that stop you. 8-) -- Bill Findlay <surname><forename> chez blueyonder.co.uk ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-18 21:14 ` (see below) @ 2004-08-18 21:56 ` Martin Dowie 2004-08-19 15:25 ` (see below) 0 siblings, 1 reply; 38+ messages in thread From: Martin Dowie @ 2004-08-18 21:56 UTC (permalink / raw) (see below) wrote: > On 18/8/04 9:37 pm, in article > Xns9549E5E9CFFB1BerndSpechgmxcom@151.189.20.10, "Bernd Specht" > <Bernd.Specht@gmx.com> wrote: > >> 3. When I want treat a value both as an integer and as a boolean >> array, how can i do this? In pascal I would use a tagless record like >> >> TYPE ov is record >> case boolean of >> true : i : integer; >> false : byte_array; >> end; >> end; >> >> Such overlay structures are not valid with Ada, so what do instead? > > Such usages are not valid in (ISO Standard) Pascal either, > but you don't let that stop you. 8-) Where does the standard deem this "not valid" in Ada? ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-18 21:56 ` Martin Dowie @ 2004-08-19 15:25 ` (see below) 2004-08-19 15:50 ` Martin Dowie 0 siblings, 1 reply; 38+ messages in thread From: (see below) @ 2004-08-19 15:25 UTC (permalink / raw) On 18/8/04 10:56 pm, in article cg0j9n$bkq$1@sparta.btinternet.com, "Martin Dowie" <martin.dowie@btopenworld.com> wrote: ... >>> TYPE ov is record >>> case boolean of >>> true : i : integer; >>> false : byte_array; >>> end; >>> end; >>> >>> Such overlay structures are not valid with Ada, so what do instead? >> >> Such usages are not valid in (ISO Standard) Pascal either, >> but you don't let that stop you. 8-) > > Where does the standard deem this "not valid" in Ada? I'm not sure who Martin is asking, nor what about; but: If "this" means Pascal-style tagless variant records, see the RM, section 3.8.1 "Variant Parts and Discrete Choices", where no such syntax appears. If "this" means assigning a value of type T1 to a field F1 of a variant V1 of a record structure R and retrieving a value of type T2 from a field F2 of a variant V2, "R.F1 := T1_Val; ...; T2_var := R.F2" then: (a) If the variant has not been changed from V1 to V2, then a discriminant check on access to F2 will raise a Constraint_Error. (b) If the variant has been changed to V2, then F2 has been given a new value and so does not retain the value placed in F1. (c) It cannot even be assumed that F1 and F2 coincide, unless a representation specification can be used to that effect. (I suspect Martin knows all this perfectly well, so I wonder why he asks.) -- Bill Findlay <surname><forename> chez blueyonder.co.uk ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-19 15:25 ` (see below) @ 2004-08-19 15:50 ` Martin Dowie 0 siblings, 0 replies; 38+ messages in thread From: Martin Dowie @ 2004-08-19 15:50 UTC (permalink / raw) "(see below)" <byaldnif@blueyonder.co.uk> wrote in message news:BD4A8509.96EBD% > (I suspect Martin knows all this perfectly well, so I wonder why he asks.) Bill, sorry I misread the original email (not even yours!) and had magic-ed in a discriminent in the Pascal version - that'll teach me to write to newsgroups at 11pm! Cheers -- Martin ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-18 20:37 Bitmanipulation in Ada Bernd Specht 2004-08-18 20:51 ` Ludovic Brenta 2004-08-18 21:14 ` (see below) @ 2004-08-18 21:53 ` Martin Dowie 2004-08-18 22:59 ` Björn Persson ` (2 more replies) 2004-08-20 20:57 ` Bitordering? was " Alfred Hilscher 3 siblings, 3 replies; 38+ messages in thread From: Martin Dowie @ 2004-08-18 21:53 UTC (permalink / raw) Bernd Specht wrote: > 2. I did not found shift and rotate operations. Did I miss something > or are there really none? Check out package "Interfaces" they are all there - as are some common predefined types. > 3. When I want treat a value both as an integer and as a boolean > array, how can i do this? In pascal I would use a tagless record like Assuming you had a _really_ good reason to need to think of the data in both terms, you have a number of options: 1) Unchecked_Conversion; procedure Foo (Y : Unsigned_8) is procedure To_Array_8 is new Ada.Unchecked_Conversion (Unsigned_8, Array_8); X : Array_8 := To_Array_8 (Y); begin ... 2) Address clause to 'overlay' 2 variables at the same address; procedure Foo (Y : Unsigned_8) is X : Array_8; for X'Address use Y'Address; begin ... 3) Variant record with a representation clause; type Variant (Is_Array : Boolean := False) is record case Is_Array is when False => U : Unsigned_8; when True => A : Array_8; end case; end record; for Variant use record U at 0 range 0 .. 7; A at 0 range 0 .. 7; end record; This will leave it to the compiler where to put "Is_Array" There are pros and cons to each - I'd rather use Ada.Unchecked_Conversion to make it explicit that I'm switching representations. Cheers -- Martin ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-18 21:53 ` Martin Dowie @ 2004-08-18 22:59 ` Björn Persson 2004-08-19 8:08 ` Egil H. H�vik 2004-08-19 17:46 ` Bernd Specht 2 siblings, 0 replies; 38+ messages in thread From: Björn Persson @ 2004-08-18 22:59 UTC (permalink / raw) Martin Dowie wrote: > 2) Address clause to 'overlay' 2 variables at the same address; > > procedure Foo (Y : Unsigned_8) is > X : Array_8; > for X'Address use Y'Address; > begin > .... Y should probably be declared "in out" here. > 3) Variant record with a representation clause; > > type Variant (Is_Array : Boolean := False) is > record > case Is_Array is > when False => > U : Unsigned_8; > when True => > A : Array_8; > end case; > end record; > for Variant use > record > U at 0 range 0 .. 7; > A at 0 range 0 .. 7; > end record; If you turn off the discriminant check. -- Björn Persson PGP key A88682FD omb jor ers @sv ge. r o.b n.p son eri nu ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-18 21:53 ` Martin Dowie 2004-08-18 22:59 ` Björn Persson @ 2004-08-19 8:08 ` Egil H. H�vik 2004-08-19 17:46 ` Bernd Specht 2 siblings, 0 replies; 38+ messages in thread From: Egil H. H�vik @ 2004-08-19 8:08 UTC (permalink / raw) "Martin Dowie" <martin.dowie@btopenworld.com> wrote in message news:cg0j57$bal$1@sparta.btinternet.com... > Bernd Specht wrote: <snip> > > 2) Address clause to 'overlay' 2 variables at the same address; > > procedure Foo (Y : Unsigned_8) is > X : Array_8; You would probably want a "pragma Import (Ada, X)" here, to suppress any default initializations... B.1(24) > for X'Address use Y'Address; > begin > ... ~egilhh ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitmanipulation in Ada 2004-08-18 21:53 ` Martin Dowie 2004-08-18 22:59 ` Björn Persson 2004-08-19 8:08 ` Egil H. H�vik @ 2004-08-19 17:46 ` Bernd Specht 2 siblings, 0 replies; 38+ messages in thread From: Bernd Specht @ 2004-08-19 17:46 UTC (permalink / raw) Many thanks, this will help me a lot. "Martin Dowie" <martin.dowie@btopenworld.com> wrote in news:cg0j57$bal$1@sparta.btinternet.com: > Bernd Specht wrote: >> 2. I did not found shift and rotate operations. Did I miss something >> or are there really none? > > Check out package "Interfaces" they are all there - as are some common > predefined types. > >> 3. When I want treat a value both as an integer and as a boolean >> array, how can i do this? In pascal I would use a tagless record like > > Assuming you had a _really_ good reason to need to think of the data in > both terms, you have a number of options: > > 1) Unchecked_Conversion; > > procedure Foo (Y : Unsigned_8) is > procedure To_Array_8 is > new Ada.Unchecked_Conversion (Unsigned_8, Array_8); > X : Array_8 := To_Array_8 (Y); > begin > ... > > 2) Address clause to 'overlay' 2 variables at the same address; > > procedure Foo (Y : Unsigned_8) is > X : Array_8; > for X'Address use Y'Address; > begin > ... > > 3) Variant record with a representation clause; > > type Variant (Is_Array : Boolean := False) is > record > case Is_Array is > when False => > U : Unsigned_8; > when True => > A : Array_8; > end case; > end record; > for Variant use > record > U at 0 range 0 .. 7; > A at 0 range 0 .. 7; > end record; > > This will leave it to the compiler where to put "Is_Array" > > There are pros and cons to each - I'd rather use > Ada.Unchecked_Conversion to make it explicit that I'm switching > representations. > > Cheers > > -- Martin > > ^ permalink raw reply [flat|nested] 38+ messages in thread
* Bitordering? was Re: Bitmanipulation in Ada 2004-08-18 20:37 Bitmanipulation in Ada Bernd Specht ` (2 preceding siblings ...) 2004-08-18 21:53 ` Martin Dowie @ 2004-08-20 20:57 ` Alfred Hilscher 2004-08-21 11:34 ` Nick Roberts 3 siblings, 1 reply; 38+ messages in thread From: Alfred Hilscher @ 2004-08-20 20:57 UTC (permalink / raw) Sorry that I interfere here, I have a question in this context, too. When I declare an boolean array with eight elements 1..8 (e.g. to address a hardware port with eight status bits), how are they ordered is X(1) the msb or the lsb of the byte? X(1) = 2**7 and X(8) = 2**0 or X(1) = 2**0 and X(8) = 2**7 Bernd Specht schrieb: > > Hi, > > i have some questions regarding bitmanipulations: [...] ----------------------------------------------------- To send me mail, please replace "Spam" by "Jedermann" ----------------------------------------------------- ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitordering? was Re: Bitmanipulation in Ada 2004-08-20 20:57 ` Bitordering? was " Alfred Hilscher @ 2004-08-21 11:34 ` Nick Roberts 2004-08-21 14:00 ` Jim Rogers ` (2 more replies) 0 siblings, 3 replies; 38+ messages in thread From: Nick Roberts @ 2004-08-21 11:34 UTC (permalink / raw) On Fri, 20 Aug 2004 22:57:40 +0200, Alfred Hilscher <SPAM@alfred-hilscher.de> wrote: > When I declare an boolean array with eight elements 1..8 (e.g. to > address a hardware port with eight status bits), how are they > ordered is X(1) the msb or the lsb of the byte? It is undefined. The typical way to deal with this kind of situation is to use a record type with a record representation clause. For example: type Frobnosticator_Status is record Ready, Complete, Motor_On, Fault, Power_Low: Boolean; end record; for Frobnosticator_Status'Bit_Order use System.Low_Order_First; for Frobnosticator_Status use record Ready at 0 range 0..0; Complete at 0 range 1..1; Motor_On at 0 range 3..3; Fault at 0 range 6..6; Power_Low at 0 range 7..7; end record; for Frobnosticator_Status'Size use 8; This lot specifies exactly where each bit is, and what it means. In this example, I've used representation clauses to tell the compiler to consider the LSB to be bit number 0 for this record, and to tell it that the record is 8 bits in size. I've associated a specific bit with each Boolean component (bits 2, 4, and 5 are unused). If I declare: Status: Frobnosticator_Status; for Status'Address use Frob_1_Status_Address; pragma Volatile(Status); to map the variable 'Status' to frobnosticator number 1's status port, I can read off its status bits by name: if Status.Fault then Put_Line( Current_Error, "Frob #1 went down" ); raise Hardware_Failure; end if; ... Does this help you? -- Nick Roberts ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitordering? was Re: Bitmanipulation in Ada 2004-08-21 11:34 ` Nick Roberts @ 2004-08-21 14:00 ` Jim Rogers 2004-08-21 16:54 ` Simon Wright 2004-08-21 16:55 ` Georg Bauhaus 2004-08-23 18:47 ` Alfred Hilscher 2 siblings, 1 reply; 38+ messages in thread From: Jim Rogers @ 2004-08-21 14:00 UTC (permalink / raw) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 1901 bytes --] "Nick Roberts" <nick.roberts@acm.org> wrote in news:opsc2yf8zvp4pfvb@bram-2: > On Fri, 20 Aug 2004 22:57:40 +0200, Alfred Hilscher > <SPAM@alfred-hilscher.de> wrote: > >> When I declare an boolean array with eight elements 1..8 (e.g. to >> address a hardware port with eight status bits), how are they >> ordered is X(1) the msb or the lsb of the byte? > > It is undefined. It is undefined in an array. It can be defined in a record. The Ada LRM, section 13.5.3 deals with bit ordering issues. To quoute: A bit ordering is a method of interpreting the meaning of the storage place attributes. High_Order_First (known in the vernacular as �big endian�) means that the first bit of a storage element (bit 0) is the most significant bit (interpreting the sequence of bits that represent a component as an unsigned integer value). Low_Order_First (known in the vernacular as �little endian�) means the opposite: the first bit is the least significant. For every specific record subtype S, the following attribute is defined: S�Bit_Order Denotes the bit ordering for the type of S. The value of this attribute is of type System.Bit_Order. Bit_Order may be specified for specific record types via an attribute_definition_clause; the expression of such a clause shall be static. If Word_Size = Storage_Unit, the default bit ordering is implementation defined. If Word_Size > Storage_Unit, the default bit ordering is the same as the ordering of storage elements in a word, when interpreted as an integer. The storage place attributes of a component of a type are interpreted according to the bit ordering of the type. Implementation Advice The recommended level of support for the nondefault bit ordering is: If Word_Size = Storage_Unit, then the implementation should support the nondefault bit ordering in addition to the default bit ordering. Jim Rogers ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitordering? was Re: Bitmanipulation in Ada 2004-08-21 14:00 ` Jim Rogers @ 2004-08-21 16:54 ` Simon Wright 0 siblings, 0 replies; 38+ messages in thread From: Simon Wright @ 2004-08-21 16:54 UTC (permalink / raw) Jim Rogers <jimmaureenrogers@worldnet.att.net> writes: > >> When I declare an boolean array with eight elements 1..8 (e.g. to > >> address a hardware port with eight status bits), how are they > >> ordered is X(1) the msb or the lsb of the byte? > > > > It is undefined. > > It is undefined in an array. It can be defined in a record. I think you have to use pragma Pack before the boolean elements are packed into bits? I don't have a big-endian machine here, but I'm pretty sure that GNAT orders a packed boolean array as you would expect from System.Default_Bit_Order (I used it as a demonstration to the unbelievers that bit ordering actually matters!) -- Simon Wright 100% Ada, no bugs. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitordering? was Re: Bitmanipulation in Ada 2004-08-21 11:34 ` Nick Roberts 2004-08-21 14:00 ` Jim Rogers @ 2004-08-21 16:55 ` Georg Bauhaus 2004-08-23 18:36 ` Alfred Hilscher 2004-08-23 18:47 ` Alfred Hilscher 2 siblings, 1 reply; 38+ messages in thread From: Georg Bauhaus @ 2004-08-21 16:55 UTC (permalink / raw) Nick Roberts <nick.roberts@acm.org> wrote: : On Fri, 20 Aug 2004 22:57:40 +0200, Alfred Hilscher : <SPAM@alfred-hilscher.de> wrote: : :> When I declare an boolean array with eight elements 1..8 (e.g. to :> address a hardware port with eight status bits), how are they :> ordered is X(1) the msb or the lsb of the byte? : : It is undefined. : : The typical way to deal with this kind of situation is to use a : record type with a record representation clause. For example: [...] You might also be interested in the Bit Order paper by Norman Cohen available in the grab bag at http://www.ada-auth.org -- Georg ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitordering? was Re: Bitmanipulation in Ada 2004-08-21 16:55 ` Georg Bauhaus @ 2004-08-23 18:36 ` Alfred Hilscher 0 siblings, 0 replies; 38+ messages in thread From: Alfred Hilscher @ 2004-08-23 18:36 UTC (permalink / raw) Georg Bauhaus schrieb: > > Nick Roberts <nick.roberts@acm.org> wrote: > : On Fri, 20 Aug 2004 22:57:40 +0200, Alfred Hilscher > : <SPAM@alfred-hilscher.de> wrote: > : > :> When I declare an boolean array with eight elements 1..8 (e.g. to > :> address a hardware port with eight status bits), how are they > :> ordered is X(1) the msb or the lsb of the byte? > : > : It is undefined. > : > : The typical way to deal with this kind of situation is to use a > : record type with a record representation clause. For example: > > [...] > > You might also be interested in the Bit Order paper by Norman Cohen > available in the grab bag at http://www.ada-auth.org > > -- Georg Very interessting. Thanks. I worked in the range of telecommunication (with CHILL) and our compiler had directives (pragmas) to tell him which variable should be treated as big-endian, bzw little endian. In the case of mixed expressions, the compiler generated code to change the representation. This siplyfied the code in some situations. ----------------------------------------------------- To send me mail, please replace "Spam" by "Jedermann" ----------------------------------------------------- ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitordering? was Re: Bitmanipulation in Ada 2004-08-21 11:34 ` Nick Roberts 2004-08-21 14:00 ` Jim Rogers 2004-08-21 16:55 ` Georg Bauhaus @ 2004-08-23 18:47 ` Alfred Hilscher 2004-08-23 22:39 ` Nick Roberts 2 siblings, 1 reply; 38+ messages in thread From: Alfred Hilscher @ 2004-08-23 18:47 UTC (permalink / raw) Nick Roberts schrieb: > > On Fri, 20 Aug 2004 22:57:40 +0200, Alfred Hilscher > <SPAM@alfred-hilscher.de> wrote: > > ... > > Does this help you? Yes it does. Although it is not what I expected. My first idea was something like this: type flags is (buffer_empty, overrun, parity_error, frame_error, timed_out, break_detected, receiving, idle); type port is array (flags) of boolean; pragma pack (port); status_port : port; for port use at 16#0004#; ... for s in overrun .. break_detected loop if status_port (s) then return flags'pos (s); end if; end loop; return 0; So instead I have to write: type port is record buffer_empty : boolean; ... end record; ... if status_port (overrun) then return 7; elsif status_port (parity_error) then return 6; ... else return 0; end if; Is this correct? Ok, it is a bit more to write, but this should not matter. Regards, Alfred ----------------------------------------------------- To send me mail, please replace "Spam" by "Jedermann" ----------------------------------------------------- ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: Bitordering? was Re: Bitmanipulation in Ada 2004-08-23 18:47 ` Alfred Hilscher @ 2004-08-23 22:39 ` Nick Roberts 0 siblings, 0 replies; 38+ messages in thread From: Nick Roberts @ 2004-08-23 22:39 UTC (permalink / raw) On Mon, 23 Aug 2004 20:47:10 +0200, Alfred Hilscher <SPAM@alfred-hilscher.de> wrote: >> Does this help you? > > Yes it does. Although it is not what I expected. > ... > Is this correct? In essence, yes. > Ok, it is a bit more to write, but this should not matter. Exactly. The Ada ethic is that the clarity of the code matters more than its conciseness. I'd suggest you declare the record type like this: with System; ... type Status_Flags is record Buffer_Empty, Overrun, Parity_Error, Frame_Error, Timed_Out, Break_Detected, Receiving, Idle: Boolean; end record; for Status_Flags'Size use 8; for Status_Flags'Bit_Order use System.Low_Order_First; for Status_Flags use record Buffer_Empty at 0 range 7..7; Overrun at 0 range 6..6; Parity_Error at 0 range 5..5; Frame_Error at 0 range 4..4; Timed_Out at 0 range 3..3; Break_Detected at 0 range 2..2; Receiving at 0 range 1..1; Idle at 0 range 0..0; end record; Note that I have numbered the bits here so that the LSB is 0 and the MSB is 7. If it would be more convenient for you to have it the other way round, change System.Low_Order_First to System.High_Order_First. Please check that the right flags are associated with the right bits! You could write a clarifying function such as: function Shows_Error (Flags: in Status_Flags) return Boolean is begin return Flags.Buffer_Empty or Flags.Overrun or Flags.Parity_Error or Flags.Frame_Error or Flags.Timed_Out or Flags.Break_Detected; end; You might declare a memory-mapped port like this: Status: Status_Flags; for Status'Address use 16#0004#; pragma Volatile(Status); You could handle status values using an 'if' structure such as: if Shows_Error(Status) then if Status.Buffer_Empty then ... elsif Status.Overrun then ... elsif Status.Parity_Error then ... elsif Status.Frame_Error then ... elsif Status.Timed_Out then ... elsif Status.Break_Detected then ... end if; else if Status.Receiving then ... elsif Status.Idle then ... else ... end if; end if; Note that these nested 'if' statements do not necessarily have the structure that meets the required logic of your program (you will have to work that out yourself). It is merely an illustration. HTH -- Nick Roberts ^ permalink raw reply [flat|nested] 38+ messages in thread
end of thread, other threads:[~2004-08-23 22:39 UTC | newest] Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2004-08-18 20:37 Bitmanipulation in Ada Bernd Specht 2004-08-18 20:51 ` Ludovic Brenta 2004-08-18 21:10 ` Bernd Specht 2004-08-18 21:16 ` Ludovic Brenta 2004-08-18 21:18 ` Ed Falis 2004-08-19 17:30 ` Bernd Specht 2004-08-19 17:44 ` Ed Falis 2004-08-19 0:53 ` Jeffrey Carter 2004-08-19 17:44 ` Bernd Specht 2004-08-19 18:09 ` Martin Dowie 2004-08-19 18:28 ` Bernd Specht 2004-08-19 19:31 ` Martin Dowie 2004-08-19 20:29 ` Martin Dowie 2004-08-20 21:31 ` Bernd Specht 2004-08-19 19:17 ` Jeffrey Carter 2004-08-19 19:57 ` Björn Persson 2004-08-20 0:52 ` Jeffrey Carter 2004-08-19 21:24 ` Francois G. Dorais 2004-08-20 8:55 ` Pascal Obry 2004-08-20 7:26 ` Jean-Pierre Rosen 2004-08-20 21:20 ` Bernd Specht 2004-08-20 21:39 ` Ed Falis 2004-08-18 21:14 ` (see below) 2004-08-18 21:56 ` Martin Dowie 2004-08-19 15:25 ` (see below) 2004-08-19 15:50 ` Martin Dowie 2004-08-18 21:53 ` Martin Dowie 2004-08-18 22:59 ` Björn Persson 2004-08-19 8:08 ` Egil H. H�vik 2004-08-19 17:46 ` Bernd Specht 2004-08-20 20:57 ` Bitordering? was " Alfred Hilscher 2004-08-21 11:34 ` Nick Roberts 2004-08-21 14:00 ` Jim Rogers 2004-08-21 16:54 ` Simon Wright 2004-08-21 16:55 ` Georg Bauhaus 2004-08-23 18:36 ` Alfred Hilscher 2004-08-23 18:47 ` Alfred Hilscher 2004-08-23 22:39 ` Nick Roberts
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox