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
next prev parent 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