comp.lang.ada
 help / color / mirror / Atom feed
From: "Robert I. Eachus" <rieachus@comcast.net>
Subject: Re: Is there a better (Ada) way?
Date: Thu, 23 Oct 2003 21:42:34 GMT
Date: 2003-10-23T21:42:34+00:00	[thread overview]
Message-ID: <3F984AF5.6030703@comcast.net> (raw)
In-Reply-To: 20619edc.0310230857.5da5446f@posting.google.com

Mike Silva wrote:
> "Robert I. Eachus" <rieachus@comcast.net> wrote in message news:<3F96ED50.2040009@comcast.net>...
> 
>>>   R16 := R16 + Reg16_t( Integer( PB.offset5 ) mod Reg16_t'Modulus );
>>>-- the above line works, but is it good Ada, or C-in-Ada?
>>
>>    R16 := R16 + Reg16_t(PB.offset5);
>>
>>Should do exactly the same thing--but it doesn't.
> 
> 
> Do you mean that the language should have been defined so that the
> conversion in the 2nd line acts like the 1st, with negative numbers? 
> Or ???
> 
> Mike

Yes.  I believe that this will be "fixed" in the next version of the 
standard, but for now you will find compilers that raise 
Constraint_Error when converting a negative value to a modular type. 
Suppressing Constraint_Error for this one line makes it all come out 
right, if there is nothing that should be a Constraint_Error.

It is one of those nasty complex glitches that make language definition 
so hard.  There may not be a valid representation for a negative value 
of an unsigned type, so it looks like the "right" rule.  But in reality, 
there must be a valid representation of the current value--the current 
one--and arithmetic works correctly after a possible sign extension for 
modular types with binary modulii.

Incidently I thought of what may be a better way to do it, but to do it 
efficiently is tricky.  Define a sign extention intrinsic operation, 
then do a normal addition.  This works great on most hardware.  Do a 
left shift that puts the bits in the high order position, then a sign 
extending right shift.  Not great on a Pentium 4, but most other 
processors have a barrel-shifter that can do the two instructions quickly.

And you can always write:

if PB.offset5 >= 0
then R16 := R16 + Reg16_t(PB.offset5);
else R16 := R16 - Reg16_t(-PB.offset5);
end if;

On some compilers you will get better performance than the version with 
the explicit mod operation, since even 16-bit division tends to be slow. 
   But as I said the best code is probably to use pragma 
Suppress(Range_Check, Reg16_t);  I can't imagine any case other than 
this where you might want the check to be made for a binary modular type 
like Reg16_t, so you can probably put the pragma with the type declaration.

Hmmm, thinking more about it, the compiler is not required to do the 
sign extension in that case, but the following should always work right:

function To_Reg16(Value: in Offset5_t) return Reg16_t is
   type Integer16 is range -2**15..2**15-1;
   for Integer16'Size use 16;
   function UC is new Ada.Unchecked_Conversion(Integer16, Reg16_t);
begin return UC(Integer16(Value)); end To_Reg16;
pragma Inline(To_Reg16);

A lot of work to eliminate one mod operation, but now you can write:

   R16 := To_Reg16(PB.offset5);

And be sure it is portable.  If you have a lot of these operations, it 
may be worth it.  Of course, it will take an awful lot of instances to 
justify all this analysis, but I think this is all covered under the 
learning experience heading.

The lesson that should be coming through is that Ada programmers care a 
lot about making the code look pretty and easy to read and understand. 
That doesn't mean that we don't care about efficiency.  We just go out 
of our way to hide the messy parts of the code in some function hidden 
in some package body.  Oh, and that Ada programmers tend to have trouble 
sleeping if they write code that is compiler dependent when it doesn't 
have to be. ;-)

-- 
                                           Robert I. Eachus

"Quality is the Buddha. Quality is scientific reality. Quality is the 
goal of Art. It remains to work these concepts into a practical, 
down-to-earth context, and for this there is nothing more practical or 
down-to-earth than what I have been talking about all along...the repair 
of an old motorcycle."  -- from Zen and the Art of Motorcycle 
Maintenance by Robert Pirsig




  reply	other threads:[~2003-10-23 21:42 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 [this message]
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
replies disabled

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