comp.lang.ada
 help / color / mirror / Atom feed
From: dewar@merv.cs.nyu.edu (Robert Dewar)
Subject: Re: Not intended for use in medical devices
Date: 1997/05/10
Date: 1997-05-10T00:00:00+00:00	[thread overview]
Message-ID: <dewar.863254614@merv> (raw)
In-Reply-To: mheaney-ya023680000805970900450001@news.ni.net


Matthew Heaney said

<<Is there some _other_ way of doing memory I/O - without using address
clauses?  Isn't memory-mapped I/O in fact the _reason_ for address clauses
in the language?>>

The safest way to do memory mapped I/O is to create appropriate
abstractions, and then program them up using machine insertions so
you get *exactly* the instructions you know you need. If you have
a friendly Ada compiler that implements machine intrinsics and
inlining in an effective manner (GNAT meets these requirements for
example), then you do not introduce an efficiency penalty by doing
this, and you KNOW exactly what you are getting.

There are cases where the use of address clauses for memory mapped I/O
make sense, a notable example is in mapping into the display buffer on
the original IBM/PC. On the other hand, if you did this, without
introducing an abstraction layer, you have a program that is unnecessarily
hard to port to other environments.

There are many reasons why address clauses were put in. Certainly MMIO was
one motivation, but there are others, in particular mapping into system
data structures at spsecific addresses (e.g. getting hold of the BIOS
data area on a PC).

The critical point here is that when you use address clauses for MMIO, youa
are doing something that is inherently risky, you are assuming you know,
and relying on your knowledge of, the exact way that the compiler will
generate instructions for loads and stores.

Let's give another example, suppose I have a byte that is memory mapped on
an x86

    x : character;
    for x'address use ...

    pragma Atomic (x);  -- don't forget atomic if possible, or else volatile!

now I am pretty safe in doing

    x := x + 1;

and assuming byte load/store

or am I????

A compiler aimed at the high end x86 might well decide that it is better
to keep everything in 32 bits unless specified otherwise or when space
is noticable as in arrays, so it might allocate 32 bits -- and we have
yet another surprising portability disaster.

OK, so put in the size clause, but let's change the example a bit:

   type xt is mod 2**8;
   x : xt;
   for x'address use ...
   pragma Atomic (x);
   for x'size use 8;

and after that mouthful, we write:

   if (x and 2#0100#) then ..

to test some status bit, and sure enough we get a nice byte load, which is
what the hardware requires:

but now we optimize and the program blows, why? because the optimizer now
changes this to be a test bit instruction -- and the MMIO does not expect
or react properly to this change because of some hardware peculiarity.

Bottom line, it is true that address clauses and MMIO often go nicely
together, but it is a good idea to wrap the access in inlined abstractions,
rather than let them spread around the program, if you must use this
combination.





  reply	other threads:[~1997-05-10  0:00 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-05-04  0:00 Not intended for use in medical devices Robert C. Leif, Ph.D.
1997-05-05  0:00 ` Kaz Kylheku
1997-05-06  0:00   ` Robert Dewar
1997-05-06  0:00     ` Kaz Kylheku
1997-05-12  0:00     ` Ken Garlington
1997-05-06  0:00 ` Michael F Brenner
1997-05-06  0:00   ` Kaz Kylheku
1997-05-07  0:00   ` Robert Dewar
1997-05-08  0:00     ` Matthew Heaney
1997-05-10  0:00       ` Robert Dewar [this message]
1997-05-14  0:00         ` Richard Kenner
  -- strict thread matches above, loose matches on Subject: below --
1997-05-03  0:00 Robert C. Leif, Ph.D.
1997-05-03  0:00 ` Robert Dewar
replies disabled

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