82 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
.so init
 | 
						|
.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
 |