From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,4ac8a7e7d3e637dc X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-10-24 15:20:22 PST Path: archiver1.google.com!news2.google.com!fu-berlin.de!uni-berlin.de!82-43-33-75.cable.ubr01.croy.blueyonder.co.UK!not-for-mail From: Nick Roberts Newsgroups: comp.lang.ada Subject: Re: Is there a better (Ada) way? Date: Fri, 24 Oct 2003 23:20:15 +0100 Message-ID: References: <20619edc.0310221056.4c92d10c@posting.google.com> NNTP-Posting-Host: 82-43-33-75.cable.ubr01.croy.blueyonder.co.uk (82.43.33.75) Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-Trace: news.uni-berlin.de 1067034021 33780929 82.43.33.75 (16 [25716]) User-Agent: Mozilla/5.0 (Windows; U; Win95; en-US; rv:1.5) Gecko/20031013 Thunderbird/0.3 X-Accept-Language: en-us, en In-Reply-To: <20619edc.0310221056.4c92d10c@posting.google.com> Xref: archiver1.google.com comp.lang.ada:1631 Date: 2003-10-24T23:20:15+01:00 List-Id: Mike Silva wrote: > I've started writing a little CPU simulator, just for fun and to be > doing *something* in Ada, and I want to make sure I'm not writing "C > in Ada" when it comes to all the bit, bitfield and register > manipulations. > > Below is a typical question. I need to add a 5-bit signed offset to a > 16-bit register. The way I came up with is shown on the last line of > the example code, but I want to find out if there's a more Ada-ish way > to do what I'm doing. Any comments about any part of the example code > are welcome. > > Mike > > -------- example code -------- > > procedure test is > type Reg16_t is mod 2**16; -- 16 bit register > for Reg16_t'Size use 16; > > type Offset5_t is range -2**4..2**4-1; -- 5 bit signed offset > for Offset5_t'Size use 5; > > type Dummy_t is mod 2**3; -- just take up extra 3 bits > in byte, for this example > for Dummy_t'Size use 3; > > type Postbyte_t is -- typical opcode postbyte > record > dummy : Dummy_t; > offset5 : Offset5_t; > end record; > > for Postbyte_t use > record > dummy at 0 range 5..7; > offset5 at 0 range 0..4; > end record; > > for Postbyte_t'Size use 8; > > R16 : Reg16_t; > PB : Postbyte_t; > begin > .... > R16 := R16 + Reg16_t( Integer( PB.offset5 ) mod Reg16_t'Modulus ); > -- the above line works, but is it good Ada, or C-in-Ada? I would be inclined to create an explicit signed integer type of the appropriate size: procedure test is type Unsigned_16 is mod 2**16; for Unsigned_16'Size use 16; type Offset_5 is range -2**4..2**4-1; for Offset_5'Size use 5; type Signed_16 is range -2**15..2**15-1; for Signed_16'Size use 16; type Jump_Postbyte is record Offset: Offset_5; end record; for Jump_Postbyte use record Offset at 0 range 0..4; end record; for Jump_Postbyte'Size use 8; R16 : Unsigned_16; PB : Jump_Postbyte; begin .... R16 := R16 + Unsigned_16( Signed_16(PB.Offset)+2**4 ) - 2**4; This formulation gives wrap-around semantics, which is the likely choice for a hard implementation. Ada 95 doesn't provide signed-to-modular integer addition. Perhaps the next revision should. (There's a thought ;-) -- Nick Roberts