[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [f-cpu] More Instruction Set Trouble



Michael Riepe wrote:
>The address of a variable is usually not known at compile/assemble time.
>The difference between the variable's address and the address of the
>instruction loading it will also be unknown in most cases (code and data
>usually belong to different sections that can be moved independently).
>That means that we have to use relocations: the compiler/assembler will
>create code for the general case, leaving the (absolute or relative)
>address open (usually set to 0), and let the link editor patch in the
>correct value.
>
>Unfortunately, the term `general case' means four(!) successive loadcons
>instructions (or similar).  There is no way to optimize one or two of
>them away because the compiler/assembler doesn't know which value is
>loaded.

The linker can handle whatever optimizations are necessary for efficient
relocations or else it is a very sad linker indeed. If this means
providing several alternatives patches of code to fill in depending
on the distances, then so be it. Too much focus has been put on
optimizing at compile time traditionally when it is quite beneficial
to do it at load time. The distances between code and data sections 
are very well known at this peculiar and oft ignored time.

>You might say: "use PC-relative addresses".  But that doesn't work
>either -- in fact it's even *worse* than using the absolute address
>because you need four loadcons instructions to put the relative address
>into a register, and then you still have to execute loadaddrd (that is,
>you need one instruction *more* for relative addressing).

I don't see why you couldn't just use loadraddrid here and fall back
to loadaddrd if the distance is too large.

>The same is true if you use a `base' register that points to the
>beginning of the data section and calculate the distance to that point.
>You still need 4x loadcons + 1x add to get the variable's address (and
>yet another instruction if you want the data to be prefetched, because
>`add' doesn't do that).

The distance of the variable from the current PC is easily calculated
at load time so a loadaddrid can be use great utility here, as has
been noted.

>A module-local base register is also possible, but you'll have to save,
>set and restore it in every function that is not module-local (e.g. has
>`extern' linkage in C) and uses global variables -- and you need the full
>`quadruple-loadcons' instruction sequence again each time you access a
>global variable that belongs to *another* module (just in case it isn't
>clear: `module' means `source file').

Not quite... a function need only have two entry points - one entry
point is module local and does nothing while the other is for the
non-local
case and sets the current module. Calls to non-local functions are
responsible for setting the current module after the non-local function
returns. This allows for efficient local calls that pay no penalty at
all.

Additionally, one should not neglect the effectiveness of redundancy
elimination when applied to constant loads.

When that fails... hasn't anyone told you that global variables are
evil anyway? :)

>Any other ideas how we can reduce/avoid the `address load penalty'?
An add coupled with a prefetch for data address loads off a
base/module register would be very nice. Possibly an immediate add
that some how supported longer immediate constants would be nice too,
but that could be done without.

Lee Salzman
The Long Lost F-CPU GCC Porter and "Maintainer"
*************************************************************
To unsubscribe, send an e-mail to majordomo@seul.org with
unsubscribe f-cpu       in the body. http://f-cpu.seul.org/