.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 you cannot 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