.In
.nr H1 2
.NH
PROBLEMS
.NH 2
Maintain SPARC speed
.PP
If we want to generate SPARC code, we should try to generate efficient code
as fast as possible. It would be quite embarrassing to find out that the
same program would run faster on a Motorola 68020 than on a SPARC processor,
when both operate at the same clock frequency.
Looking at some code generated by Sun's C-compiler and optimizing assembler,
we can spot a few remarkable characteristics of the generated SPARC code:
.IP -
There are almost no memory references
.IP -
Parameters to functions are passed through registers.
.IP -
Almost all delay slots\(dg
.FS
\(dg For details about delay slots see the SPARC Architecture Manual, chapter 4, pp. 42-48
.FE
are filled in by the assembler
.LP
If we want to generate efficient code, we should at least try to
reduce the number of memory references and use registers wherever we can.
Since EM is stack-oriented it references its stack for every operation so
this will not be an easy task; a suitable solution will however be given in
the next chapter.
.NH 2
Increase compilation speed
.PP
Because we will implement a code expander (fast backend) we should keep
a close eye on efficiency; if we cannot beat regular compilers on producing
efficient code we will try to beat them on fast code generation.
The usual trick to achieve fast compilation is to pack the frontend,
optimizer, code-generator and
assembler all into a single large binary to reduce the overhead of
reading and writing temporary files. Unfortunately, due to the
SPARC instruction set, its relocation information is slightly bizarre
and cannot be represented with the present primitives.
This means that it will not be possible to generate the required output
format directly from our backend.
.PP
There are three solutions here: generate assembler code, and let an
existing assembler generate the required object (\fI.o\fR) files,
create our own primitives than can handle the SPARC relocation format, or
do not use any of the addressing modes that require the bizarre relocation.
Because we have enough on our hands already we will
let the existing assembler deal with generating object files.
.NH 2
Convert stack to register operations
.PP
As we wrote in the previous chapter, for RISC machines a code expander can
produce almost as efficient code as a code generator. The fact that this is
true for stack-oriented RISC processors is rather obvious. The problem we
face, however, is that the SPARC processor is register, instead of 
stack oriented. In the next chapter we will give a suitable solution to
convert most stack accesses to register accesses.
.NH 2
Miscellaneous
.PP
Besides performance and \fI.o\fR-compatibility there are some other
peculiarities of the SPARC processor and Sun's C-compiler (henceforth
simply called \fIcc\fR).
.PP
For some reason, the SPARC stack pointer requires alignment
on 8 bytes, so it is impossible to push a 4-byte integer on the stack
and then \*(Sisub 4, %sp\*(So\(dd.
.FS
\(dd For more information about SPARC assembler see the Sun-4 Assembly
Language Reference Manual
.FE
This too will be discussed in the next chapter, where we will take a
more in-depth look into this problem and also discuss a couple of
possible solutions.
.PP
Another thing is that \fIcc\fR usually passes the first six parameters of a
function-call through registers. To be \fI.o\fR-compatible we would have to
pass the first six parameters of each function call through registers as well.
Exactly why this is not feasible will also be discussed in the next chapter.
.bp
