comp.lang.ada
 help / color / mirror / Atom feed
From: Nick Roberts <nick.roberts@acm.org>
Subject: Re: Is there a better (Ada) way?
Date: Fri, 24 Oct 2003 23:20:15 +0100
Date: 2003-10-24T23:20:15+01:00	[thread overview]
Message-ID: <bnc8j5$106t61$1@ID-25716.news.uni-berlin.de> (raw)
In-Reply-To: <20619edc.0310221056.4c92d10c@posting.google.com>

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




      parent reply	other threads:[~2003-10-24 22:20 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-10-22 18:56 Is there a better (Ada) way? Mike Silva
2003-10-22 19:33 ` sk
2003-10-23 18:33   ` Mike Silva
2003-10-22 20:50 ` Robert I. Eachus
2003-10-23 16:57   ` Mike Silva
2003-10-23 21:42     ` Robert I. Eachus
2003-10-24  1:42       ` Mike Silva
2003-10-23  3:12 ` Steve
2003-10-23 18:30   ` Mike Silva
2003-10-24 22:20 ` Nick Roberts [this message]
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox