From: | George Neuner <gneuner2@comcast.net> |
Newsgroups: | comp.compilers |
Date: | Thu, 06 Jan 2011 15:45:23 -0500 |
Organization: | A noiseless patient Spider |
References: | 10-12-040 10-12-043 11-01-006 |
Keywords: | design, types |
Posted-Date: | 06 Jan 2011 15:51:18 EST |
On Fri, 31 Dec 2010 21:06:32 +0100, Florian Weimer <fw@deneb.enyo.de>
wrote:
>* George Neuner:
>
>> C++ forbids a union of classes ... so you won't ever see one.
>
>C++0X adds a restricted form.
I hadn't noticed that, thanks!
>Unions of classes are fairly common in C++ libraries and are currently
>emulated with placement news and some hopeful magic to deal with
>alignment concerns.
Nothing forbids doing this, AFAICS, but the results would be
implementation dependent. I have to think about it for awhile to
convince myself it would be safe, but just offhand I would be worried
about issues with classes having multiple inheritance.
>> With respect to POD variant record types, I guess they depends on how
>> you see your language being used. Packed POD records (including
>> variant types) are very useful for hardware interfacing in a "systems"
>> language, but in an "application" language the only real attraction of
>> POD types is that they are (usually) lighter weight and faster than an
>> equivalent class (though dynamic dispatch can be made O(1) if you are
>> serious about speed ... unfortunately very few class implementations
>> are that serious).
>
>It is very difficult to use memory-mapped I/O without machine code
>insertions with modern compilers. It's also likely that the device's
>idea of memory layout differs from that of the host system. This
>means that useful language support in this area is going to be very
>difficult to provide.
Not really. I've done a quite a bit of device programming and I can
say from experience that it isn't that hard.
PIO registers are fairly simple to deal with, typically needing only
additional barrier instructions to guarantee back-to-back ordered
accesses. Marking the PIO range non-cacheable makes reads more
efficient, but you trade that against slightly slower writes if the
out-going data is static or slow changing.
It is not uncommon for a device's memory to be bit reversed vs the
host's memory ... I might have this backwards (it's been a while since
I did any hardware debugging) but, IIRC, DRAM address decoders are
little-endian, so you need to reverse the bus connections to a
big-endian CPU. That means data is stored backwards relative to the
CPU, but it doesn't matter because it is reversed again on the read
back. Every device I've seen that shared memory with the host had the
external bus connected so that the data appeared in the correct
bit-order for the host.
So really there are only three issues of consequence: the device
having byte endianness opposite the host, the device having memory of
a different width, and address translation between device and host.
Byte endianness is simple to deal with ... just agree on a transfer
format and decide which side will reverse multi-byte data.
Differing memory width can be a minor problem. Many DSPs, for
example, are VLIW (e.g., 48 bit instructions) and thus have oddly
sized memories which can be accessed at different widths (typically in
multiples of 16-bits). Downloading code, then, is a matter of
formatting it correctly (endianness) and then when copying it to
access the device memory using a width that allows the whole odd size
word to be filled.
Data transfers usually aren't a problem because data will be in
standard 8/16/32/64 bit widths.
[Many DSPs have a DMA channel that can repack data on the fly - for
example, 3 32-bit words into 2 48-bit words (or the reverse). Usually
repacking DMA also will take care of byte endianness so DMA often is
preferable to having shared memory.]
Address translation shouldn't be an issue unless the device is a DMA
bus master. With shared memory, the device and the host can access
the block using their own private addresses and, hopefully, the data
will not contain relative addresses (offsets are fine, though). For
DMA, the target side has to provide the address and a transfer size
has to be agreed on as well as data repacking (if relevant). If the
host will handle the DMA, it can easily translate a device relative
address by adding/subtracting the device's base address. For a
bus-mastering device however, the device needs a complete host target
addresses because the device typically does not know where it lives in
the host's memory map.
>Variant types are somewhat challenging to support if their values can
>be (partically) unbounded. For instance, an object of such a type
>cannot be placed directly into a record. Adding an indirection when
>necessary certainly helps here. If you don't want to do this, you're
>really facing an uphill battle because without additional measures, a
>simple module system will hide the variable-sized nature of a type.
Yes. Although you can use a facility similar to Ada's discriminated
records in which the variably sized members become fixed at
allocation.
The problem is that you must either fix the alternation at allocation
(making the variant case immutable) or somehow allocate for the
largest alternation. I can't say I ever tried it, but AFAIK, Ada
doesn't have any way to describe multiple discriminated cases when
allocating a variant record so that the compiler can allocate
sufficient space to handle any of them. I think in such a case the
programmer has to figure out which alternation case will be the
largest, allocate that case (which will be fixed) and then cast the
result back into a mutable record.
George
Return to the
comp.compilers page.
Search the
comp.compilers archives again.