September 2000 This article reviews the restrictions placed on the global registers by SPARC V8, V8PLUS, and V9 ABIs (application binary interface), and discusses some steps that developers can take to conform to the ABIs while making efficient use of available registers. It also highlights the global registers usage issues related to 64-bit porting of assembly code. IntroductionRegister usage is a critical resource allocation issue for compilers. The SPARC architecture defines a set of 32 general registers. The general register set is partitioned into windowed registers and non-windowed registers. The windowed registers are used primarily for passing parameters to, and receiving results from, subroutines and for keeping track of the memory stack. The windowed registers are automatically saved between function calls; the caller's registers are saved upon entering the callee and restored upon exit. As a result, there is not register values conflict among functions. In contrast, the non-window registers are not automatically saved and therefore do require special attention to ensure that the calling routine's live values are not overwritten. On the up side, this provides a mechanism to globally retain live values across several routines. Non-window registers are commonly known as global registers. Global RegistersThere are 8 global registers, designated as For V8 and prior versions of the SPARC architecture, the global registers are defined as 32-bit registers. For SPARC V9, their capacity was doubled to 64 bits. SPARC V8 ABI RestrictionsThe SPARC V8 ABI specifies that registers SPARC V8PLUS ABI RestrictionsThe SPARC V8PLUS ABI is an unofficial extension of the V8 ABI for V9 SPARC hardware.
Programs compiled with SPARC V8PLUS ABI will run on V9 hardware running a V8 aware Solaris operating environment.
For example, a 32-bit program compiled using a Forte compiler with the option Note: To determine the kernel release of a system, use The SPARC V8PLUS ABI switches register The rest of the register restrictions remain unchanged from SPARC V8 ABI. However, the global registers are 64-bit registers and may be used as such by user programs. SPARC V9 ABI RestrictionsThe SPARC V9 ABI better defines the use of registers Note: In a multi-threaded environment, registers Table 1 summarizes the global registers usage in various SPARC ABIs. Table 1: Global registers summary
One of the significant changes in the SPARC V9 ABI is that user and system functions that use registers In summary, ELF (Executable and Linking Format) register usage records were introduced. SPARC V9 ABI compliant programs are required to use these records to report global register usage. The Forte compilers automatically generate the ELF register records to implement this mechanism. During link time, either static or dynamic, the records are compared to ensure consistent use of global registers between differing linkage objects. If inconsistent usage is detected, an error message will result from the link operation. Linkers bundled with Solaris, beginning with Solaris 7 release, accept the ELF register records.
Linkers bundled with releases prior to Solaris 7 do not accept the new ELF register records and will issue an error message.
Since the SPARC assembler may also generate linkage objects, it should also be able to output the ELF register records.
Hence, the assembler needs to recognize how the user intends to use the global registers referenced within each input New V9 Pseudo InstructionThe new pseudo-instruction is accepted by the SPARC assembly for any architecture setting but only has effect for V9. This allows the user to write assembly code for V8 and V9 using the new natural assembly pseudo-ops:
.register %g {2 | 3 | 6 | 7}, {#scratch | symbol name | #ignore}
The SPARC assembler responds to the pseudo-instruction in any of the following circumstances:
The Scenario 1: 64-bit Porting of User Assembly Code and Global Register UsageThis section illustrates the use of the new ProblemIn order to port an application to 64-bit, the user assembly routine must be made SPARC V9 ABI compliant. A code fragment example is shown below.
The V8PLUS assembly code does not violate the global register usage, since the assembly code does not use the ABI reserved registers.
Rather the problem lies in the fact that the address computation for
!
! SUBROUTINE FOO(N, A, B, C, AT, NROW, START)
!
...
! line 21
.seg "text" ! line 22
...
sethi %hi(.L_NEG_ONE),%l3 ! line 87
ldd [%l3+%lo(.L_NEG_ONE)],%f0 ! line 88
...
.L_NEG_ONE:
...
If you compile the V8PLUS compliant routine, % cc -xarch=v9 foo.s main.c foo.s: main.c: ld: fatal: relocation error: R_SPARC_HI22: file foo.o: symbol : value 0x400404 does not fit SolutionAssuming that the register
...
sethi %hh(.L_NEG_ONE),%l3 ! line 87
sethi %lm(.L_NEG_ONE),%g1
or %l3,%hm(.L_NEG_ONE),%l3
sllx %l3,32,%l3
or %l3,%g1,%l3 ! line 91
ldd [%l3+%lo(.L_NEG_ONE)],%f0 ! line 92 <-- THIS WAS LINE 88
...
Clearly, one more register is needed for this code.
If register
...
.register %g2,#scratch ! line 21 <-- BLANK LINE IN ORIGINAL
.SEG "text"
...
SETHI %HH(.L_NEG_ONE),%L3 ! LINE 87
SETHI %LM(.L_NEG_ONE),%G2
OR %L3,%HM(.L_NEG_ONE),%L3
SLLX %L3,32,%L3
OR %L3,%G2,%L3 ! LINE 91
LDD [%L3+%LO(.L_NEG_ONE)],%F0 ! LINE 92
Failing to include the % cc -c -xarch=v9 foo.s -o foo.o /opt/SUNWspro/SC5.0/bin/fbe: "foo.s", line 87: error: detect global register use not covered .register pseudo-op /opt/SUNWspro/SC5.0/bin/fbe: "foo.s", line 91: error: detect global register use not covered .register pseudo-op However, with the The following examples demonstrate the use of two other pseudo-instructions, You can use
...
setxhi .L_NEG_ONE, %g2, %l3 ! line 87
ldd [%l3+%lo(.L_NEG_ONE)], %f0 ! line 88 <-- THIS WAS LINE 92
...
Or, you can use
...
setx .L_NEG_ONE, %g2, %l3 ! line 87
ldd [%l3], %f0 ! line 88 <-- THIS WAS LINE 92
...
Scenario 2: Global Register in Multi-threaded ApplicationsApplication developers should take care when using global registers in assembly code that is a part of multi-threaded applications. In order to be multi-thread safe, the assembly code needs to be compliant with all SPARC ABI specifications, including global register usage. ProblemIn this scenario, a multi-threaded SPARC V8PLUS compliant application encounters a SIGSEGV error during execution when linked with an object derived from your SPARC assembly code.
One possibility is that you used global registers SolutionThe error is corrected once the assembly code is rewritten to conform with the latest SPARC ABI specifications by not using the priviledged registers Note: Application developers should avoid using application-specific registers in building general purpose libraries,
such as system libraries, or those provided by software vendors as third-party libraries,
which might be linked with multiple applications. You can instruct the Forte compilers to not use application-specific
registers by using the ResourcesVisit Sun Studio Development Tools to learn more about compilers and developer tools. An extensive discussion on SPARC architecture can be found in The SPARC Architecture Manual, Version 9. Visit the Solaris ABI Program to ensure that your applications are ABI-conformant binary components. September 2000 | |||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||