Okna rejestrów

Nakładanie się okien rejestrów

SPARC prezentuje bardzo ciekawe podejście. Rejestry są podzielone na cztery grupy: globalne, wejściowe, lokalne i wyjściowe. Bardzo naturalne jest, że rejestry wyjściowe służą jako rejestry wejściowe dla następnego bloku instrukcji. Dlatego też, w tej architekturze możemy tworzyć tzw. okna rejestrów. Stworzenie takiego okna nie zmieni rejestrów globalnych, rejestry wejściowe pokryją się z poprzednimi wyjściowymi, a na pozostałe zostanie zaalokowanych 16 nowych rejestrów. Takie podejście jest nazywane "nakładaniem się okien rejestru" (ang. overlapping).

Rysunek 1. Nakładające się okna rejestrów

Operacje save i restore

Operacje te służą do tworzenia nowych i przywracania starych okien rejestrów. Oczywiste jest, że są pewne ograniczone zasoby do tworzenie nowych okien rejestrów. Dlatego też tworzą one swego rodzaju bufor cykliczny. Każde użycie instrukcji save lub restore powoduje przesunięcie rejestru CWP (current window pointer), w którym przechowywana jest informacja o aktualnym oknie rejestrów.

Wywołanie funkcji save ma następującą postać: save %sp, -framesize, %sp .

Wielkość framesize musi być na tyle duża, żeby zmieściły się w niej: wskaźnik struktury, argumenty wyjściowe (maxymalnie 6) i obszar roboczy (16 rejestrów), które mają być stworzone dla nowego okna. Liczba ta musi być podzielna przez 8, a jej mimimalną wartością jest 96.

Poniższy rysunek przedstawia ogólne działanie tego mechanizmu.

Rysunek 2. Cykliczne okna rejestrów

Przykład korzystający z okien rejestrów.

        .text
! pr_str - print a null terminated string
!
! Temporaries:  %i0 - pointer to string
!               %o0 - character to be printed
!
pr_str: save    %sp, -96, %sp   ! PROLOGUE - save the current window and
                                !   allocate the minimum stack frame
pr_lp:  ldub    [%i0], %o0      ! load character
        cmp     %o0, 0          ! check for null
        be      pr_dn
        nop
        call    pr_char         ! print character
        nop
        ba      pr_lp
        inc     %i0             ! increment the pointer (branch delay)
pr_dn:  ret                     ! EPILOGUE return from procedure and
        restore                 !   restore old window; no return value