summaryrefslogtreecommitdiffstats
path: root/doc/supplements/hppa1_1/callconv.texi
blob: 7f433ef39a3b81098a787e2c6c1074d6ee90d803 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
@c
@c  COPYRIGHT (c) 1988-1998.
@c  On-Line Applications Research Corporation (OAR).
@c  All rights reserved.
@c
@c  $Id$
@c

@ifinfo
@node Calling Conventions, Calling Conventions Introduction, CPU Model Dependent Features CPU Model Name, Top
@end ifinfo
@chapter Calling Conventions
@ifinfo
@menu
* Calling Conventions Introduction::
* Calling Conventions Processor Background::
* Calling Conventions Calling Mechanism::
* Calling Conventions Register Usage::
* Calling Conventions Parameter Passing::
* Calling Conventions User-Provided Routines::
@end menu
@end ifinfo

@ifinfo
@node Calling Conventions Introduction, Calling Conventions Processor Background, Calling Conventions, Calling Conventions
@end ifinfo
@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.

@ifinfo
@node Calling Conventions Processor Background, Calling Conventions Calling Mechanism, Calling Conventions Introduction, Calling Conventions
@end ifinfo
@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.

@ifinfo
@node Calling Conventions Calling Mechanism, Calling Conventions Register Usage, Calling Conventions Processor Background, Calling Conventions
@end ifinfo
@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.

@ifinfo
@node Calling Conventions Register Usage, Calling Conventions Parameter Passing, Calling Conventions Calling Mechanism, Calling Conventions
@end ifinfo
@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

@ifinfo
@node Calling Conventions Parameter Passing, Calling Conventions User-Provided Routines, Calling Conventions Register Usage, Calling Conventions
@end ifinfo
@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.

@ifinfo
@node Calling Conventions User-Provided Routines, Memory Model, Calling Conventions Parameter Passing, Calling Conventions
@end ifinfo
@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.