Subject: port-sparc/4029: Register usage doesn't comply with SPARC ABI
To: None <gnats-bugs@gnats.netbsd.org>
From: Krister Walfridsson <cato@ulysses.df.lth.se>
List: netbsd-bugs
Date: 08/23/1997 22:38:03
>Number:         4029
>Category:       port-sparc
>Synopsis:       Register usage doesn't comply with SPARC ABI
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Aug 23 13:50:01 1997
>Last-Modified:
>Originator:     Krister Walfridsson
>Organization:
	
>Release:        NetBSD-current Aug 15 1997
>Environment:
	
System: NetBSD ulysses 1.2G NetBSD 1.2G (KWA) #0: Fri Aug 15 20:36:02 CEST 1997 cato@ulysses:/usr/src/sys/arch/sparc/compile/KWA sparc


>Description:
Modern languages usually have runtime systems which stores some pointers
in global registers, and compilers I have encountered usually likes to store
those in %g3 and %g4. Unfortunally does NetBSD destroy them (at least %g3)
in linbrary calls.

The SPARC Architecture Manual (Version 8) says

   The convention used by the SPARC Application Binary Interface (ABI)
   is that %g1 is assumed to be volatile across procedure calls,
   %g2 ... %g4 are reserved for use by the application program (for
   example, as global register variables), and %g5 ... %g7 are assumed
   to be nonvolatile and reserved for (as-yet-undefined) use by the
   execution environment.

...so we shouldn't use %g2-%g4 in library code. %g2 are used in function
calls, and I don't know if we can change it without breaking anything,
but %g3 and %g4 aren't used (more than temporary registers for gcc) so
it is easy to keep the value in them across library calls.

>How-To-Repeat:
Try to run the following program

.text
        .align 8
LC0:
        .ascii "%d\12\0"
        .align 4
        .global _main
_main:
        save %sp,-104,%sp

        mov 23,%g3

        sethi %hi(LC0),%o0
        or %o0,%lo(LC0),%o0
        call _printf,0
        mov %g3,%o1

        sethi %hi(LC0),%o0
        or %o0,%lo(LC0),%o0
        call _printf,0
        mov %g3,%o1

        ret
        restore

When I run this, I get something like

   bash$ ./a.out
   23
   50331648

i.e. printf destroys %g3

>Fix:
Use the flag '-mno-app-regs' when compiling libraries

>Audit-Trail:
>Unformatted: