This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: An unusual Performance approach using Synthetic registers, and a request for guidance.


On Friday 27 December 2002 02:27 am, Andy Walker wrote:
>
> There is an additional price for Synthetic registers.  I could not figure
> out a simple way to use the frame pointer, so I dragooned the "C" register,
> register number 2, to be used as the base register for the modrm
> instructions.  Time will tell if this is Dumb, or Dumber.  I am absolutely
> convinced there is a better way.  I just do not know yet what it is.
>
Within the x86 instruction set, the "C" (%ECX) register may not be your best 
choice.  
Not because of compiler usage of the register, but because of uses 
of the register outside of the compiler (Hand coded __asm__ ).
That is; hand coded __asm__, is hand coded to use ISA features that the 
compiler doesn't otherwise use.  Of those unused features, the %ECX register
related special portions of the ISA are frequently used.

A similar, but much weaker, argument could be made against using the 
%ESI and %EDI registers.

The %EAX and %EDX registers are out of the question (the ISA single and
double length result registers).

If you wanted to enforce the -fomit-frame-pointer option, the %EBP register
has possibilities (if you also restrict yourself to stack/heap/data in the
same address space).  But this path would probably be too restrictive for a
general implementation.

Hmm... we seem to be running out of registers...

Indeed, some (non-gnu) compilers reserve the %EBX register for internal uses.

So, I think (personal opinion here), using the %EBX register as the base 
(frame pointer) of the synthetic register frames should be your first choice.

Think of it as generating code for a load/store ISA machine with the primary
registers addressed %EBX relative.  This gives you two, double length,
secondary registers (The %EAX/%EDX pair and the %ESI/%EDI pair) with
a single length scratch register (%EAX).
That is, you would be generating code for a 64bit (split) register size with 
coding for a 32bit register size the exceptional case.
That allows you to combine your two register pairs to handle 128bit data
as another exceptional case to the 64bit (split) register size coding;
and a single 32bit scratch register (%ECX) that can be tested for zero with
a single byte instruction.

The argument I presented above is not 100% academic...

I have actually done (in a non-compiler context) such x86 programming,
with the added decoration of making the primary registers 10 bytes long
so that they could hold any FPU/ALU data type.
That decision was driven by a desire to use the data-type conversion
features of the FPU portion of the ISA as an intregal part of the synthetic
machine.

I should note that the above was done before the FPU learned to do
vector instructions.  Which now might require a re-think of the old
plan.

Going beyond the register mapping I used departs too much from what
you are planning to be of much use; 
But my register mapping from the synthetic machine to the real hardware 
was:

Primary registers (frame): %EBX relative (a "zero address", stack machine, 
with the addition of directly addressable registers)
First secondary register: %EAX/%EDX or FPU TOS(relative) as appropriate.
Second secondary register: %ESI/%EDI or FPU TOS(relative) as appropriate.
Scratch/Counter/Test for Zero register: %ECX
I retained the ISA usage of the %EBP/%ESP register pair.
I captured the FPU stack over-run, under-run exceptions to extend its
hardware register stack into the synthetic (primary) registers (in my case,
a stack rather than a fixed number of synthetic registers.
Considering the FPU/ALU instruction set as a whole, I subset it to those
instructions that worked directly on the actual hardware mappings.

Mike


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]