Changeset 9bfda06 in rtems-docs


Ignore:
Timestamp:
Aug 20, 2018, 4:16:24 PM (2 years ago)
Author:
Joel Sherrill <joel@…>
Branches:
5, am, master
Children:
5ce8e43
Parents:
587d14f
Message:

cpu-supplement/sparc.rst: Revert work in progress accidentally committed

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpu-supplement/sparc.rst

    r587d14f r9bfda06  
    770770- Must initialize the SPARC's initial trap table with at least trap handlers
    771771  for register window overflow and register window underflow.
    772 
    773 ....................................
    774 ....
    775 
    776 Understanding stacks and registers in the SPARC architecture(s)
    777 ===============================================================
    778 
    779 The content in this section originally appeared at
    780 https://www.sics.se/~psm/sparcstack.html. It appears here with the
    781 gracious permission of the author Peter Magnusson.
    782 
    783 
    784 The SPARC architecture from Sun Microsystems has some "interesting"
    785 characteristics. After having to deal with both compiler, interpreter, OS
    786 emulator, and OS porting issues for the SPARC, I decided to gather notes
    787 and documentation in one place. If there are any issues you don't find
    788 addressed by this page, or if you know of any similar Net resources, let
    789 me know. This document is limited to the V8 version of the architecture.
    790 
    791 General Structure
    792 -----------------
    793 
    794 SPARC has 32 general purpose integer registers visible to the program
    795 at any given time. Of these, 8 registers are global registers and 24
    796 registers are in a register window. A window consists of three groups
    797 of 8 registers, the out, local, and in registers. See table 1. A SPARC
    798 implementation can have from 2 to 32 windows, thus varying the number
    799 of registers from 40 to 520. Most implentations have 7 or 8 windows. The
    800 variable number of registers is the principal reason for the SPARC being
    801 "scalable".
    802 
    803 At any given time, only one window is visible, as determined by the
    804 current window pointer (CWP) which is part of the processor status
    805 register (PSR). This is a five bit value that can be decremented or
    806 incremented by the SAVE and RESTORE instructions, respectively. These
    807 instructions are generally executed on procedure call and return
    808 (respectively). The idea is that the in registers contain incoming
    809 parameters, the local register constitute scratch registers, the out
    810 registers contain outgoing parameters, and the global registers contain
    811 values that vary little between executions. The register windows overlap
    812 partially, thus the out registers become renamed by SAVE to become the in
    813 registers of the called procedure. Thus, the memory traffic is reduced
    814 when going up and down the procedure call. Since this is a frequent
    815 operation, performance is improved.
    816 
    817 (That was the idea, anyway. The drawback is that upon interactions
    818 with the system the registers need to be flushed to the stack,
    819 necessitating a long sequence of writes to memory of data that is
    820 often mostly garbage. Register windows was a bad idea that was caused
    821 by simulation studies that considered only programs in isolation, as
    822 opposed to multitasking workloads, and by considering compilers with
    823 poor optimization. It also caused considerable problems in implementing
    824 high-end SPARC processors such as the SuperSPARC, although more recent
    825 implementations have dealt effectively with the obstacles. Register
    826 windows is now part of the compatibility legacy and not easily removed
    827 from the architecture.)
    828 
    829 ================ ======== ================
    830 Register  Group  Mnemonic Register Address
    831 ================ ======== ================
    832 global           %g0-%g7  r[0]-r[7]
    833 out              %o0-%o7  r[8]-r[15]
    834 local            %l0-%l7  r[16]-r[23]
    835 in               %i0-%i7  r[24]-r[31]
    836 ================ ======== ================
    837 
    838 .. Table 1 - Visible Registers
    839 
    840 The overlap of the registers is illustrated in figure 1. The figure
    841 shows an implementation with 8 windows, numbered 0 to 7 (labeled w0 to
    842 w7 in the figure).. Each window corresponds to 24 registers, 16 of which
    843 are shared with "neighboring" windows. The windows are arranged in a
    844 wrap-around manner, thus window number 0 borders window number 7. The
    845 common cause of changing the current window, as pointed to by CWP, is
    846 the RESTORE and SAVE instuctions, shown in the middle. Less common is
    847 the supervisor RETT instruction (return from trap) and the trap event
    848 (interrupt, exception, or TRAP instruction).
    849 
    850 
    851 .. image:: sparcwin.gif
    852 
    853 Figure 1 - Windowed Registers
    854 
    855 The "WIM" register is also indicated in the top left of figure 1. The
    856 window invalid mask is a bit map of valid windows. It is generally used
    857 as a pointer, i.e. exactly one bit is set in the WIM register indicating
    858 which window is invalid (in the figure it's window 7). Register windows
    859 are generally used to support procedure calls, so they can be viewed
    860 as a cache of the stack contents. The WIM "pointer" indicates how
    861 many procedure calls in a row can be taken without writing out data to
    862 memory. In the figure, the capacity of the register windows is fully
    863 utilized. An additional call will thus exceed capacity, triggering a
    864 window overflow trap. At the other end, a window underflow trap occurs
    865 when the register window "cache" if empty and more data needs to be
    866 fetched from memory.
    867 
    868 Register Semantics
    869 ------------------
    870 
    871 phe SPARC Architecture includes recommended software semantics. These are
    872 described in the architecture manual, the SPARC ABI (application binary
    873 interface) standard, and, unfortunately, in various other locations as
    874 well (including header files and compiler documentation).
    875 
    876 Figure 2 shows a summary of register contents at any given time.
    877 
    878 .. code-block:: asm
    879 
    880                  %g0  (r00)       always zero
    881                  %g1  (r01)  [1]  temporary value
    882                  %g2  (r02)  [2]  global 2
    883      global      %g3  (r03)  [2]  global 3
    884                  %g4  (r04)  [2]  global 4
    885                  %g5  (r05)       reserved for SPARC ABI
    886                  %g6  (r06)       reserved for SPARC ABI
    887                  %g7  (r07)       reserved for SPARC ABI
    888 
    889                  %o0  (r08)  [3]  outgoing parameter 0 / return value from callee   
    890                  %o1  (r09)  [1]  outgoing parameter 1
    891                  %o2  (r10)  [1]  outgoing parameter 2
    892      out         %o3  (r11)  [1]  outgoing parameter 3
    893                  %o4  (r12)  [1]  outgoing parameter 4
    894                  %o5  (r13)  [1]  outgoing parameter 5
    895             %sp, %o6  (r14)  [1]  stack pointer
    896                  %o7  (r15)  [1]  temporary value / address of CALL instruction
    897 
    898                  %l0  (r16)  [3]  local 0
    899                  %l1  (r17)  [3]  local 1
    900                  %l2  (r18)  [3]  local 2
    901      local       %l3  (r19)  [3]  local 3
    902                  %l4  (r20)  [3]  local 4
    903                  %l5  (r21)  [3]  local 5
    904                  %l6  (r22)  [3]  local 6
    905                  %l7  (r23)  [3]  local 7
    906 
    907                  %i0  (r24)  [3]  incoming parameter 0 / return value to caller
    908                  %i1  (r25)  [3]  incoming parameter 1
    909                  %i2  (r26)  [3]  incoming parameter 2
    910      in          %i3  (r27)  [3]  incoming parameter 3
    911                  %i4  (r28)  [3]  incoming parameter 4
    912                  %i5  (r29)  [3]  incoming parameter 5
    913             %fp, %i6  (r30)  [3]  frame pointer
    914                  %i7  (r31)  [3]  return address - 8
    915 
    916 Notes:
    917 
    918 # assumed by caller to be destroyed (volatile) across a procedure call
    919 
    920 # should not be used by SPARC ABI library code
    921 
    922 # assumed by caller to be preserved across a procedure call
    923 
    924 .. Above was Figure 2 - SPARC register semantics
    925 
    926 Particular compilers are likely to vary slightly.
    927 
    928 Note that globals %g2-%g4 are reserved for the "application", which
    929 includes libraries and compiler. Thus, for example, libraries may
    930 overwrite these registers unless they've been compiled with suitable
    931 flags. Also, the "reserved" registers are presumed to be allocated
    932 (in the future) bottom-up, i.e. %g7 is currently the "safest" to use.
    933 
    934 Optimizing linkers and interpreters are exmples that use global registers.
    935 
    936 Register Windows and the Stack
    937 ------------------------------
    938 
    939 The SPARC register windows are, naturally, intimately related to the
    940 stack. In particular, the stack pointer (%sp or %o6) must always point
    941 to a free block of 64 bytes. This area is used by the operating system
    942 (Solaris, SunOS, and Linux at least) to save the current local and in
    943 registers upon a system interupt, exception, or trap instruction. (Note
    944 that this can occur at any time.)
    945 
    946 Other aspects of register relations with memory are programming
    947 convention. The typical, and recommended, layout of the stack is shown
    948 in figure 3. The figure shows a stack frame.
    949 
    950 .. code-block:: asm
    951                     low addresses
    952                +-------------------------+         
    953      %sp  -->  | 16 words for storing    |
    954                | LOCAL and IN registers  |
    955                +-------------------------+
    956                |  one-word pointer to    |
    957                | aggregate return value  |
    958                +-------------------------+
    959                |   6 words for callee    |
    960                |   to store register     |
    961                |       arguments         |
    962                +-------------------------+
    963                |  outgoing parameters    |
    964                |  past the 6th, if any   |
    965                +-------------------------+
    966                |  space, if needed, for  |
    967                |  compiler temporaries   |
    968                |   and saved floating-   |
    969                |    point registers      |
    970                +-------------------------+
    971                     .................
    972                +-------------------------+
    973                |    space dynamically    |
    974                |    allocated via the    |
    975                |  alloca() library call  |
    976                +-------------------------+
    977                |  space, if needed, for  |
    978                |    automatic arrays,    |
    979                |    aggregates, and      |
    980                |   addressable scalar    |
    981                |       automatics        |
    982                +-------------------------+
    983     %fp  -->
    984                      high addresses
    985 
    986 .. Figure 3 - Stack frame contents
    987 
    988 Note that the top boxes of figure 3 are addressed via the stack pointer
    989 (%sp), as positive offsets (including zero), and the bottom boxes are
    990 accessed over the frame pointer using negative offsets (excluding zero),
    991 and that the frame pointer is the old stack pointer. This scheme allows
    992 the separation of information known at compile time (number and size
    993 of local parameters, etc) from run-time information (size of blocks
    994 allocated by alloca()).
    995 
    996 "addressable scalar automatics" is a fancy name for local variables.
    997 
    998 The clever nature of the stack and frame pointers are that they are always
    999 16 registers apart in the register windows. Thus, a SAVE instruction will
    1000 make the current stack pointer into the frame pointer and, since the SAVE
    1001 instruction also doubles as an ADD, create a new stack pointer. Figure 4
    1002 illustrates what the top of a stack might look like during execution. (The
    1003 listing is from the "pwin" command in the SimICS simulator.)
    1004 
    1005 .. code-block:: asm
    1006 
    1007                   REGISTER WINDOWS
    1008                  +--+---+----------+
    1009                  |g0|r00|0x00000000| global
    1010                  |g1|r01|0x00000006| registers
    1011                  |g2|r02|0x00091278|
    1012       g0-g7      |g3|r03|0x0008ebd0|
    1013                  |g4|r04|0x00000000|        (note: 'save' and 'trap' decrements CWP,
    1014                  |g5|r05|0x00000000|        i.e. moves it up on this diagram. 'restore'
    1015                  |g6|r06|0x00000000|        and 'rett' increments CWP, i.e. down)
    1016                  |g7|r07|0x00000000|
    1017                  +--+---+----------+
    1018  CWP (2)         |o0|r08|0x00000002|
    1019                  |o1|r09|0x00000000|                            MEMORY
    1020                  |o2|r10|0x00000001|
    1021       o0-o7      |o3|r11|0x00000001|             stack growth
    1022                  |o4|r12|0x000943d0|
    1023                  |o5|r13|0x0008b400|                  ^
    1024                  |sp|r14|0xdffff9a0| ----\           /|\
    1025                  |o7|r15|0x00062abc|     |            |                     addresses
    1026                  +--+---+----------+     |     +--+----------+         virtual     physical
    1027                  |l0|r16|0x00087c00|     \---> |l0|0x00000000|        0xdffff9a0  0x000039a0  top of frame 0   
    1028                  |l1|r17|0x00027fd4|           |l1|0x00000000|        0xdffff9a4  0x000039a4
    1029                  |l2|r18|0x00000000|           |l2|0x0009df80|        0xdffff9a8  0x000039a8
    1030       l0-l7      |l3|r19|0x00000000|           |l3|0x00097660|        0xdffff9ac  0x000039ac
    1031                  |l4|r20|0x00000000|           |l4|0x00000014|        0xdffff9b0  0x000039b0
    1032                  |l5|r21|0x00097678|           |l5|0x00000001|        0xdffff9b4  0x000039b4
    1033                  |l6|r22|0x0008b400|           |l6|0x00000004|        0xdffff9b8  0x000039b8
    1034                  |l7|r23|0x0008b800|           |l7|0x0008dd60|        0xdffff9bc  0x000039bc
    1035               +--+--+---+----------+           +--+----------+
    1036  CWP+1 (3)    |o0|i0|r24|0x00000002|           |i0|0x00091048|        0xdffff9c0  0x000039c0
    1037               |o1|i1|r25|0x00000000|           |i1|0x00000011|        0xdffff9c4  0x000039c4
    1038               |o2|i2|r26|0x0008b7c0|           |i2|0x00091158|        0xdffff9c8  0x000039c8
    1039       i0-i7   |o3|i3|r27|0x00000019|           |i3|0x0008d370|        0xdffff9cc  0x000039cc
    1040               |o4|i4|r28|0x0000006c|           |i4|0x0008eac4|        0xdffff9d0  0x000039d0
    1041               |o5|i5|r29|0x00000000|           |i5|0x00000000|        0xdffff9d4  0x000039d4
    1042               |o6|fp|r30|0xdffffa00| ----\     |fp|0x00097660|        0xdffff9d8  0x000039d8
    1043               |o7|i7|r31|0x00040468|     |     |i7|0x00000000|        0xdffff9dc  0x000039dc
    1044               +--+--+---+----------+     |     +--+----------+
    1045                                          |        |0x00000001|        0xdffff9e0  0x000039e0  parameters
    1046                                          |        |0x00000002|        0xdffff9e4  0x000039e4
    1047                                          |        |0x00000040|        0xdffff9e8  0x000039e8
    1048                                          |        |0x00097671|        0xdffff9ec  0x000039ec
    1049                                          |        |0xdffffa68|        0xdffff9f0  0x000039f0
    1050                                          |        |0x00024078|        0xdffff9f4  0x000039f4
    1051                                          |        |0x00000004|        0xdffff9f8  0x000039f8
    1052                                          |        |0x0008dd60|        0xdffff9fc  0x000039fc
    1053               +--+------+----------+     |     +--+----------+
    1054               |l0|      |0x00087c00|     \---> |l0|0x00091048|        0xdffffa00  0x00003a00  top of frame 1
    1055               |l1|      |0x000c8d48|           |l1|0x0000000b|        0xdffffa04  0x00003a04
    1056               |l2|      |0x000007ff|           |l2|0x00091158|        0xdffffa08  0x00003a08
    1057               |l3|      |0x00000400|           |l3|0x000c6f10|        0xdffffa0c  0x00003a0c
    1058               |l4|      |0x00000000|           |l4|0x0008eac4|        0xdffffa10  0x00003a10
    1059               |l5|      |0x00088000|           |l5|0x00000000|        0xdffffa14  0x00003a14
    1060               |l6|      |0x0008d5e0|           |l6|0x000c6f10|        0xdffffa18  0x00003a18
    1061               |l7|      |0x00088000|           |l7|0x0008cd00|        0xdffffa1c  0x00003a1c
    1062               +--+--+---+----------+           +--+----------+
    1063  CWP+2 (4)    |i0|o0|   |0x00000002|           |i0|0x0008cb00|        0xdffffa20  0x00003a20
    1064               |i1|o1|   |0x00000011|           |i1|0x00000003|        0xdffffa24  0x00003a24
    1065               |i2|o2|   |0xffffffff|           |i2|0x00000040|        0xdffffa28  0x00003a28
    1066               |i3|o3|   |0x00000000|           |i3|0x0009766b|        0xdffffa2c  0x00003a2c
    1067               |i4|o4|   |0x00000000|           |i4|0xdffffa68|        0xdffffa30  0x00003a30
    1068               |i5|o5|   |0x00064c00|           |i5|0x000253d8|        0xdffffa34  0x00003a34
    1069               |i6|o6|   |0xdffffa70| ----\     |i6|0xffffffff|        0xdffffa38  0x00003a38
    1070               |i7|o7|   |0x000340e8|     |     |i7|0x00000000|        0xdffffa3c  0x00003a3c
    1071               +--+--+---+----------+     |     +--+----------+
    1072                                          |        |0x00000001|        0xdffffa40  0x00003a40  parameters
    1073                                          |        |0x00000000|        0xdffffa44  0x00003a44
    1074                                          |        |0x00000000|        0xdffffa48  0x00003a48
    1075                                          |        |0x00000000|        0xdffffa4c  0x00003a4c
    1076                                          |        |0x00000000|        0xdffffa50  0x00003a50
    1077                                          |        |0x00000000|        0xdffffa54  0x00003a54
    1078                                          |        |0x00000002|        0xdffffa58  0x00003a58
    1079                                          |        |0x00000002|        0xdffffa5c  0x00003a5c
    1080                                          |        |    .     |
    1081                                          |        |    .     |        .. etc (another 16 bytes)
    1082                                          |        |    .     |
    1083 
    1084 .. Figure 4 - Sample stack contents
    1085 
    1086 Note how the stack contents are not necessarily synchronized with the
    1087 registers. Various events can cause the register windows to be "flushed"
    1088 to memory, including most system calls. A programmer can force this
    1089 update by using ST_FLUSH_WINDOWS trap, which also reduces the number of
    1090 valid windows to the minimum of 1.
    1091 
    1092 Writing a library for multithreaded execution is an example that requires
    1093 explicit flushing, as is longjmp().
    1094 
    1095 Procedure epilogue and prologue
    1096 -------------------------------
    1097 
    1098 The stack frame described in the previous section leads to the standard
    1099 entry/exit mechanisms listed in figure 5.
    1100 
    1101 .. code-block:: asm
    1102 
    1103   function:
    1104     save  %sp, -C, %sp
    1105 
    1106                ; perform function, leave return value,   
    1107                ; if any, in register %i0 upon exit
    1108 
    1109     ret        ; jmpl %i7+8, %g0
    1110     restore    ; restore %g0,%g0,%g0
    1111 
    1112 .. Figure 5 - Epilogue/prologue in procedures
    1113 The SAVE instruction decrements the CWP, as discussed earlier, and also
    1114 performs an addition. The constant "C" that is used in the figure to
    1115 indicate the amount of space to make on the stack, and thus corresponds
    1116 to the frame contents in Figure 3. The minimum is therefore the 16 words
    1117 for the LOCAL and IN registers, i.e. (hex) 0x40 bytes.
    1118 
    1119 A confusing element of the SAVE instruction is that the source operands
    1120 (the first two parameters) are read from the old register window, and
    1121 the destination operand (the rightmost parameter) is written to the new
    1122 window. Thus, allthough "%sp" is indicated as both source and destination,
    1123 the result is actually written into the stack pointer of the new window
    1124 (the source stack pointer becomes renamed and is now the frame pointer).
    1125 
    1126 The return instructions are also a bit particular. ret is a synthetic
    1127 instruction, corresponding to jmpl (jump linked). This instruction
    1128 jumps to the address resulting from adding 8 to the %i7 register. The
    1129 source instruction address (the address of the ret instruction itself)
    1130 is written to the %g0 register, i.e. it is discarded.
    1131 
    1132 The restore instruction is similarly a synthetic instruction, and is
    1133 just a short form for a restore that choses not to perform an addition.
    1134 
    1135 The calling instruction, in turn, typically looks as follows:
    1136 
    1137 .. code-block:: asm
    1138 
    1139     call <function>    ; jmpl <address>, %o7
    1140     mov 0, %o0
    1141 
    1142 Again, the call instruction is synthetic, and is actually the same
    1143 instruction that performs the return. This time, however, it is interested
    1144 in saving the return address, into register %o7. Note that the delay
    1145 slot is often filled with an instruction related to the parameters,
    1146 in this example it sets the first parameter to zero.
    1147 Note also that the return value is also generally passed in %o0.
    1148 
    1149 Leaf procedures are different. A leaf procedure is an optimization that
    1150 reduces unnecessary work by taking advantage of the knowledge that no
    1151 call instructions exist in many procedures. Thus, the save/restore couple
    1152 can be eliminated. The downside is that such a procedure may only use
    1153 the out registers (since the in and local registers actually belong to
    1154 the caller). See Figure 6.
    1155 
    1156 .. code-block:: asm
    1157 
    1158   function:
    1159                ; no save instruction needed upon entry
    1160 
    1161                ; perform function, leave return value,   
    1162                ; if any, in register %o0 upon exit
    1163 
    1164     retl       ; jmpl %o7+8, %g0
    1165     nop        ; the delay slot can be used for something else   
    1166 
    1167 .. Figure 6 - Epilogue/prologue in leaf procedures
    1168 
    1169 Note in the figure that there is only one instruction overhead, namely the
    1170 retl instruction. retl is also synthetic (return from leaf subroutine), is
    1171 again a variant of the jmpl instruction, this time with %o7+8 as target.
    1172 
    1173 Yet another variation of epilogue is caused by tail call elimination,
    1174 an optimization supported by some compilers (including Sun's C compiler
    1175 but not GCC). If the compiler detects that a called function will return
    1176 to the calling function, it can replace its place on the stack with the
    1177 called function. Figure 7 contains an example.
    1178 
    1179 .. code-block:: asm
    1180 
    1181        int
    1182         foo(int n)
    1183       {
    1184         if (n == 0)
    1185           return 0;
    1186         else
    1187           return bar(n);
    1188       }
    1189          cmp     %o0,0
    1190         bne     .L1
    1191         or      %g0,%o7,%g1
    1192         retl
    1193         or      %g0,0,%o0
    1194   .L1:  call    bar
    1195         or      %g0,%g1,%o7
    1196 
    1197 .. Figure 7 - Example of tail call elimination
    1198 
    1199 Note that the call instruction overwrites register %o7 with the program
    1200 counter. Therefore the above code saves the old value of %o7, and restores
    1201 it in the delay slot of the call instruction. If the function call is
    1202 register indirect, this twiddling with %o7 can be avoided, but of course
    1203 that form of call is slower on modern processors.
    1204 
    1205 The benefit of tail call elimination is to remove an indirection upon
    1206 return. It is also needed to reduce register window usage, since otherwise
    1207 the foo() function in Figure 7 would need to allocate a stack frame to
    1208 save the program counter.
    1209 
    1210 A special form of tail call elimination is tail recursion elimination,
    1211 which detects functions calling themselves, and replaces it with a simple
    1212 branch. Figure 8 contains an example.
    1213 
    1214 .. code-block:: asm
    1215 
    1216          int
    1217           foo(int n)
    1218         {
    1219           if (n == 0)
    1220             return 1;
    1221           else
    1222             return (foo(n - 1));
    1223         }
    1224          cmp     %o0,0
    1225         be      .L1
    1226         or      %g0,%o0,%g1
    1227         subcc   %g1,1,%g1
    1228   .L2:  bne     .L2
    1229         subcc   %g1,1,%g1
    1230   .L1:  retl
    1231         or      %g0,1,%o0
    1232 
    1233 .. comment Figure 8 - Example of tail recursion elimination
    1234 
    1235 Needless to say, these optimizations produce code that is difficult to debug.
    1236 
    1237 Procedures, stacks, and debuggers
    1238 ----------------------------------
    1239 
    1240 When debugging an application, your debugger will be parsing the binary
    1241 and consulting the symbol table to determine procedure entry points. It
    1242 will also travel the stack frames "upward" to determine the current
    1243 call chain.
    1244 
    1245 When compiling for debugging, compilers will generate additional code
    1246 as well as avoid some optimizations in order to allow reconstructing
    1247 situations during execution. For example, GCC/GDB makes sure original
    1248 parameter values are kept intact somewhere for future parsing of
    1249 the procedure call stack. The live in registers other than %i0 are
    1250 not touched. %i0 itself is copied into a free local register, and its
    1251 location is noted in the symbol file. (You can find out where variables
    1252 reside by using the "info address" command in GDB.)
    1253 
    1254 Given that much of the semantics relating to stack handling and procedure
    1255 call entry/exit code is only recommended, debuggers will sometimes
    1256 be fooled. For example, the decision as to wether or not the current
    1257 procedure is a leaf one or not can be incorrect. In this case a spurious
    1258 procedure will be inserted between the current procedure and it's "real"
    1259 parent. Another example is when the application maintains its own implicit
    1260 call hierarchy, such as jumping to function pointers. In this case the
    1261 debugger can easily become totally confused.
    1262 
    1263 The window overflow and underflow traps
    1264 ---------------------------------------
    1265 
    1266 When the SAVE instruction decrements the current window pointer (CWP)
    1267 so that it coincides with the invalid window in the window invalid mask
    1268 (WIM), a window overflow trap occurs. Conversely, when the RESTORE or
    1269 RETT instructions increment the CWP to coincide with the invalid window,
    1270 a window underflow trap occurs.
    1271 
    1272 Either trap is handled by the operating system. Generally, data is
    1273 written out to memory and/or read from memory, and the WIM register
    1274 suitably altered.
    1275 
    1276 The code in Figure 9 and Figure 10 below are bare-bones handlers for
    1277 the two traps. The text is directly from the source code, and sort of
    1278 works. (As far as I know, these are minimalistic handlers for SPARC
    1279 V8). Note that there is no way to directly access window registers
    1280 other than the current one, hence the code does additional save/restore
    1281 instructions. It's pretty tricky to understand the code, but figure 1
    1282 should be of help.
    1283 
    1284 .. code-block:: asm
    1285 
    1286         /* a SAVE instruction caused a trap */
    1287 window_overflow:
    1288         /* rotate WIM on bit right, we have 8 windows */
    1289         mov %wim,%l3
    1290         sll %l3,7,%l4
    1291         srl %l3,1,%l3
    1292         or  %l3,%l4,%l3
    1293         and %l3,0xff,%l3
    1294 
    1295         /* disable WIM traps */
    1296         mov %g0,%wim
    1297         nop; nop; nop
    1298 
    1299         /* point to correct window */
    1300         save
    1301 
    1302         /* dump registers to stack */
    1303         std %l0, [%sp +  0]
    1304         std %l2, [%sp +  8]
    1305         std %l4, [%sp + 16]
    1306         std %l6, [%sp + 24]
    1307         std %i0, [%sp + 32]
    1308         std %i2, [%sp + 40]
    1309         std %i4, [%sp + 48]
    1310         std %i6, [%sp + 56]
    1311 
    1312         /* back to where we should be */
    1313         restore
    1314 
    1315         /* set new value of window */
    1316         mov %l3,%wim
    1317         nop; nop; nop
    1318 
    1319         /* go home */
    1320         jmp %l1
    1321         rett %l2
    1322 Figure 9 - window_underflow trap handler
    1323         /* a RESTORE instruction caused a trap */
    1324 window_underflow:
    1325        
    1326         /* rotate WIM on bit LEFT, we have 8 windows */
    1327         mov %wim,%l3
    1328         srl %l3,7,%l4
    1329         sll %l3,1,%l3
    1330         or  %l3,%l4,%l3
    1331         and %l3,0xff,%l3
    1332 
    1333         /* disable WIM traps */
    1334         mov %g0,%wim
    1335         nop; nop; nop
    1336 
    1337         /* point to correct window */
    1338         restore
    1339         restore
    1340 
    1341         /* dump registers to stack */
    1342         ldd [%sp +  0], %l0
    1343         ldd [%sp +  8], %l2
    1344         ldd [%sp + 16], %l4
    1345         ldd [%sp + 24], %l6
    1346         ldd [%sp + 32], %i0
    1347         ldd [%sp + 40], %i2
    1348         ldd [%sp + 48], %i4
    1349         ldd [%sp + 56], %i6
    1350 
    1351         /* back to where we should be */
    1352         save
    1353         save
    1354 
    1355         /* set new value of window */
    1356         mov %l3,%wim
    1357         nop; nop; nop
    1358 
    1359         /* go home */
    1360         jmp %l1
    1361         rett %l2
    1362 
    1363 .. comment Figure 10 - window_underflow trap handler
    1364 
Note: See TracChangeset for help on using the changeset viewer.