|Compiling to the Intel instruction set firstname.lastname@example.org (2004-06-06)|
|Re: Compiling to the Intel instruction set email@example.com (2004-06-09)|
|Re: Compiling to the Intel instruction set firstname.lastname@example.org (2004-06-09)|
|Re: Compiling to the Intel instruction set email@example.com (Scott Moore) (2004-06-25)|
|Re: Compiling to the Intel instruction set firstname.lastname@example.org (Andi Kleen) (2004-06-30)|
|From:||Scott Moore <email@example.com>|
|Date:||25 Jun 2004 01:53:06 -0400|
|Posted-Date:||25 Jun 2004 01:53:06 EDT|
Gary Walker wrote:
> I'm looking for resources on how to build an optimizing compiler (back
> end) for the Intel386 instruction set.
> I'm not new to compilers and I know several other assembly languages,
> but I'm new to the Intel assembly language, and I especially need help
> in dealing with the fact that the registers are not orthoginal.
> Gary Walker
> [Intel has a "IA-32 Intel Architecture Optimization Manual" available
> as a PDF on their web site. It says remarkably little about
> registers. The functions on the registers in ia32 are a lot more
> orthogonal than they were in the 286. Most places you can use one
> register, you can use any of them. There still aren't enough of them,
> but according to that manual, the chips have a whole lot of store buffers,
> and they do store forwarding of any reasonable store/load pair. -John]
The optimization guide (from Intel or or AMD), and the current
processor manual. I am somewhat partial to the old Pentium manual,
which included a really nifty chart on all the r/m and sib
I don't agree that 386 is all that non-orthognal. The main thing that
requires a register is the ecx as count register, and string moves,
compares, etc, that use esi/edi and ecx for the rep instruction.
Pretty much all such uses are deprecated now, and the software
optimization manuals state that sequences of standard instructions are
The biggest source of "non-orthogonal" register uses I encounter are
function calls. Virtually all register calling conventions require
that, say, argument 1 occupy a fixed register, etc. If your register
allocation method is going to consider that, these represent fixed
requirements for registers.
Now there is a lot of complaining about lack of register space on the
386. Things are getting better with the x86-64, but there is a lot you
can do in the meantime. A huge number of numeric references require no
more than byte registers (think char type in C). The standard method
in most 386 compilers is to carry all operands as full dwords, which
is not necessary. A lot of traffic can be kept in byte registers,
which effectively expands the register space to a maximum of 10 from
the usual 6 (al, ah, bl, bh, cl, ch, dl, dh, esi, edi). Also, in many
cases, you can forgo using the ebp in preference to direct stack
offsets, and thus free up the ebp register, making 3 dword registers
and 8 byte registers, and various combinations thereof.
The RISC trick of assigning fixed blocks of registers to the calling
convention is too expensive for the 386. Ie., in parameters, out
parameters, function return and scratch. The calling convention, in my
opinion, needs to adjust fully to the routine being encoded, without
artificial classifications. If the routine needs a lot of parameters,
give it to it, don't reserve registers for internal scratch. Reserving
a register for a function return makes no sense. That register can
contain an input parameter.
Lastly, the flags can contain parameters and function results. Holding
intermediate results in the flags only saves a register. Flags can
even be used to input parameters and return the function result.
Samiam is Scott A. Moore
Personal web site: http:/www.moorecad.com/scott
Return to the
Search the comp.compilers archives again.