summaryrefslogblamecommitdiffstats
path: root/doc/supplements/hppa1_1/callconv.t
blob: e3dc146f6f973f9ec4d70f8e8c1926e8b535bb90 (plain) (tree)
1
2
3
4
5
6
7
8
9
  
                            


                                                    

        
 
                            
 

























                                                                


















                                                                






                                                                 













































                                                                  

























                                                                








                                                             
@c
@c  COPYRIGHT (c) 1988-2002.
@c  On-Line Applications Research Corporation (OAR).
@c  All rights reserved.
@c
@c  $Id$
@c

@chapter Calling Conventions

@section Introduction

Each high-level language compiler generates
subroutine entry and exit code based upon a set of rules known
as the compiler's calling convention.   These rules address the
following issues:

@itemize @bullet
@item register preservation and usage

@item parameter passing

@item call and return mechanism
@end itemize

A compiler's calling convention is of importance when
interfacing to subroutines written in another language either
assembly or high-level.  Even when the high-level language and
target processor are the same, different compilers may use
different calling conventions.  As a result, calling conventions
are both processor and compiler dependent.

This chapter describes the calling conventions used
by the GNU C and standard HP-UX compilers for the PA-RISC
architecture.

@section Processor Background

The PA-RISC architecture supports a simple yet
effective call and return mechanism for subroutine calls where
the caller and callee are both in the same address space.  The
compiler will not automatically generate subroutine calls which
cross address spaces.  A subroutine is invoked via the branch
and link (bl) or the branch and link register (blr).  These
instructions save the return address in a caller specified
register.  By convention, the return address is saved in r2.
The callee is responsible for maintaining the return address so
it can return to the correct address.  The branch vectored (bv)
instruction is used to branch to the return address and thus
return from the subroutine to the caller.  It is is important to
note that the PA-RISC subroutine call and return mechanism does
not automatically save or restore any registers.  It is the
responsibility of the high-level language compiler to define the
register preservation and usage convention.

@section Calling Mechanism

All RTEMS directives are invoked as standard
subroutines via a bl or a blr instruction with the return address
assumed to be in r2 and return to the user application via the
bv instruction.

@section Register Usage

As discussed above, the bl and blr instructions do
not automatically save any registers.  RTEMS uses the registers
r1, r19 - r26, and r31 as scratch registers.  The PA-RISC
calling convention specifies that the first four (4) arguments
to subroutines are passed in registers r23 - r26.  After the
arguments have been used, the contents of these registers may be
altered.  Register r31 is the millicode scratch register.
Millicode is the set of routines which support high-level
languages on the PA-RISC by providing routines which are either
too complex or too long for the compiler to generate inline code
when these operations are needed.  For example, indirect calls
utilize a millicode routine.  The scratch registers are not
preserved by RTEMS directives therefore, the contents of these
registers should not be assumed upon return from any RTEMS
directive.

Surprisingly, when using the GNU C compiler at least
integer multiplies are performed using the floating point
registers.  This is an important optimization because the
PA-RISC does not have otherwise have hardware for multiplies.
This has important ramifications in regards to the PA-RISC port
of RTEMS.  On most processors, the floating point unit is
ignored if the code only performs integer operations.  This
makes it easy for the application developer to predict whether
or not any particular task will require floating point
operations.  This property is taken advantage of by RTEMS on
other architectures to minimize the number of times the floating
point context is saved and restored.  However, on the PA-RISC
architecture, every task is implicitly a floating point task.
Additionally the state of the floating point unit must be saved
and restored as part of the interrupt processing because for all
practical purposes it is impossible to avoid the use of the
floating point registers.  It is unknown if the HP-UX C compiler
shares this property.

@itemize @code{ }
@item @b{NOTE}: Later versions of the GNU C has a PA-RISC specific
option to disable use of the floating point registers.  RTEMS
currently assumes that this option is not turned on.  If the use
of this option sets a built-in define, then it should be
possible to modify the PA-RISC specific code such that all tasks
are considered floating point only when this option is not used.
@end itemize

@section Parameter Passing

RTEMS assumes that the first four (4) arguments are
placed in the appropriate registers (r26, r25, r24, and r23)
and, if needed, additional are placed on the current stack
before the directive is invoked via the bl or blr instruction.
The first argument is placed in r26, the second is placed in
r25, and so forth.  The following pseudo-code illustrates the
typical sequence used to call a RTEMS directive with three (3)
arguments:


@example
set r24 to the third argument
set r25 to the second argument
set r26 to the first argument
invoke directive
@end example

The stack on the PA-RISC grows upward -- i.e.
"pushing" onto the stack results in the address in the stack
pointer becoming numerically larger.  By convention, r27 is used
as the stack pointer.  The standard stack frame consists of a
minimum of sixty-four (64) bytes and is the responsibility of
the callee to maintain.

@section User-Provided Routines

All user-provided routines invoked by RTEMS, such as
user extensions, device drivers, and MPCI routines, must also
adhere to these calling conventions.