Code models come in two sizes, 32-bit and 64-bit, which results in three code models for 32-bit code, and five code models for 64-bit code.
For 32-bit code, the following address modes exist:
32-bit absolute
13-bit PIC
32-bit PIC
For 64-bit code, the following address modes exist:
32-bit absolute
44-bit absolute
64-bit absolute
13-bit PIC
32-bit PIC
The following is an example of 32-bit absolute assembly code for the function add() function from Basics of Compiling C Programs:
add:
         sethi   %hi(sum),%o4
         ld      [%o4+%lo(sum)],%o5
         add     %o5,%o0,%o3
         retl
         st      %o3,[%o4+%lo(sum)]
It takes two instructions to form the address of sum. The %hi() operator tells the assembler to create a R_SPARC_HI22 relocation symbol sum, and the %lo(sum) operator creates a R_SPARC_LO10 relocation on the symbol sum.
The 64-bit absolute code model for add() from Basics of Compiling C Programs might look like this:
add:
         sethi   %hh(sum),%o5
         sethi   %lm(sum),%o2
         or      %o5,%hm(sum),%o4
         sllx    %o4,32,%o3
         or      %o3,%o2,%o1
         ld      [%o1+%lo(sum)],%g5
         add     %g5,%o0,%g3
         retl 
         st      %g3,[%o1+%lo(sum)]
Here it takes 6 instruction to form address of sum. The operators act as follows:
The 44-bit absolute code model for add() from Basics of Compiling C Programs might look like the following:
add:
         sethi   %h44(sum),%o5
         or      %o5,%m44(sum),%o4
         sllx    %o4,12,%o2
         ld      [%o2+%l44(sum)],%o3
         add     %o3,%o0,%o1
         retl 
         st      %o1,[%o2+%l44(sum)]
It takes 4 instructions to form the 44 bits of address for sum. The operators act as follows:
The 64-bit with 13-bit PIC code for add() from Basics of Compiling C Programs might look like the following:
add:
.L900000106:
         rd      %pc,%o3
         sethi   %pc22(_GLOBAL_OFFSET_TABLE_-(.L900000106-.)),%g1
         add     %g1,%pc10(_GLOBAL_OFFSET_TABLE_-(.L900000106-.)),%g1
         add     %g1,%o3,%o3
         ldx     [%o3+%got13(sum)],%o1
         ld      [%o1],%o2
         add     %o2,%o0,%g5
         retl    ! Result =
         st      %g5,[%o1]
The address of sum is formed in two parts. The first four instructions form the address of the global offset table (GOT). Then a 13-bit offset into the GOT is used to load the address of sum. The dynamic linker puts the correct address for sum into the GOT at run-time.
The operators act as follows:
The 32-bit with 13-bit PIC code for add() is similar to the preceding 64-bit with 13-bit PIC, but the ldx used for 64-bit code is changed to ld for 32-bit code.
The 64-bit with 32-bit PIC code for add() from Basics of Compiling C Programs might look as follows:
add:
         .L900000106:
         rd      %pc,%o1
         sethi   %pc22(_GLOBAL_OFFSET_TABLE_-(.L900000106-.)),%g1
         sethi   %got22(sum),%o3
         add     %g1,%pc10(_GLOBAL_OFFSET_TABLE_-(.L900000106-.)),%g1
         xor     %o3,%got10(sum),%o2
         add     %g1,%o1,%o1
         ldx     [%o1+%o2],%g4,%gdop(sum)
         ld      [%g4],%g5
         add     %g5,%o0,%g3
         retl    ! Result =
         st      %g3,[%g4]
Again, the address of sum is formed in two parts. The first part forms the address of the global offset table (GOT). Then a 32-bit offset into the GOT is used to load the address of sum.
The operators act as follows:
Similarly, the 32-bit code with 32-bit PIC would use just ld instead of ldx to load the address of sum from the GOT.