annotate doc/manual/callconvs/callconv_arm32.tex @ 0:3e629dc19168

initial from svn dyncall-1745
author Daniel Adler
date Thu, 19 Mar 2015 22:24:28 +0100
parents
children 645307d37731
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
1 %
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
2 % Copyright (c) 2007,2010 Daniel Adler <dadler@uni-goettingen.de>,
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
3 % Tassilo Philipp <tphilipp@potion-studios.com>
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
4 %
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
5 % Permission to use, copy, modify, and distribute this software for any
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
6 % purpose with or without fee is hereby granted, provided that the above
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
7 % copyright notice and this permission notice appear in all copies.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
8 %
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
9 % THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
10 % WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
11 % MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
12 % ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
13 % WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
14 % ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
15 % OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
16 %
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
17
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
18 % ==================================================
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
19 % ARM32
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
20 % ==================================================
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
21 \subsection{ARM32 Calling Convention}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
22
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
23 \paragraph{Overview}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
24
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
25 The ARM32 family of processors is based on
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
26 the Advanced RISC Machines (ARM) processor architecture (32 bit RISC).
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
27 The word size is 32 bits (and the programming model is LLP64).\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
28 Basically, this family of microprocessors can be run in 2 major modes:\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
29 \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
30 \begin{tabular}{2 B}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
31 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
32 Mode & Description\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
33 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
34 {\bf ARM} & 32bit instruction set\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
35 {\bf THUMB} & compressed instruction set using 16bit wide instruction encoding\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
36 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
37 \end{tabular}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
38 \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
39 \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
40 For more details, take a look at the ARM-THUMB Procedure Call Standard (ATPCS) \cite{ATPCS}, the Procedure Call Standard for the ARM Architecture (AAPCS) \cite{AAPCS}, as well as the Debian ARM EABI port wiki \cite{armeabi}.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
41
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
42
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
43 \paragraph{\product{dyncall} support}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
44
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
45 Currently, the \product{dyncall} library supports the ARM and THUMB mode of the ARM32 family (ATPCS \cite{ATPCS} and EABI \cite{armeabi}), excluding manually triggered ARM-THUMB interworking calls. Although it's quite possible that the current implementation runs on other ARM processor families as well, please note that only the ARMv4t family has been thoroughly tested at the time of writing. Please report if the code runs on other ARM families, too.\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
46 It is important to note, that dyncall supports the ARM architecture calling convention variant {\bf with floating point hardware disabled} (meaning that the FPA and the VFP (scalar mode) procedure call standards are not supported).
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
47 This processor family features some instruction sets accelerating DSP and multimedia application like the ARM Jazelle Technology (direct Java bytecode execution, providing acceleration for some bytecodes while calling software code for others), etc. that are not supported by the dyncall library.\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
48
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
49
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
50 \subsubsection{ATPCS ARM mode}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
51
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
52
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
53 \paragraph{Registers and register usage}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
54
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
55 In ARM mode, the ARM32 processor has sixteen 32 bit general purpose registers, namely r0-r15:\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
56 \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
57 \begin{table}[h]
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
58 \begin{tabular}{3 B}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
59 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
60 Name & Brief description\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
61 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
62 {\bf r0} & parameter 0, scratch, return value\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
63 {\bf r1} & parameter 1, scratch, return value\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
64 {\bf r2-r3} & parameters 2 and 3, scratch\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
65 {\bf r4-r10} & permanent\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
66 {\bf r11} & frame pointer, permanent\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
67 {\bf r12} & scratch\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
68 {\bf r13} & stack pointer, permanent\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
69 {\bf r14} & link register, permanent\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
70 {\bf r15} & program counter (note: due to pipeline, r15 points to 2 instructions ahead)\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
71 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
72 \end{tabular}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
73 \caption{Register usage on arm32}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
74 \end{table}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
75
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
76 \paragraph{Parameter passing}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
77
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
78 \begin{itemize}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
79 \item stack parameter order: right-to-left
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
80 \item caller cleans up the stack
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
81 \item first four words are passed using r0-r3
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
82 \item subsequent parameters are pushed onto the stack (in right to left order, such that the stack pointer points to the first of the remaining parameters)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
83 \item if the callee takes the address of one of the parameters and uses it to address other parameters (e.g. varargs) it has to copy - in its prolog - the first four words to a reserved stack area adjacent to the other parameters on the stack
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
84 \item parameters \textless=\ 32 bits are passed as 32 bit words
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
85 \item 64 bit parameters are passed as two 32 bit parts (even partly via the register and partly via the stack), although this doesn't seem to be specified in the ATPCS), with the loword coming first
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
86 \item structures and unions are passed by value, with the first four words of the parameters in r0-r3
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
87 \item if return value is a structure, a pointer pointing to the return value's space is passed in r0, the first parameter in r1, etc... (see {\bf return values})
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
88 \item keeping the stack eight-byte aligned can improve memory access performance and is required by LDRD and STRD on ARMv5TE processors which are part of the ARM32 family, so, in order to avoid problems one should always align the stack (tests have shown, that GCC does care about the alignment when using the ellipsis)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
89 \end{itemize}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
90
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
91 \paragraph{Return values}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
92 \begin{itemize}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
93 \item return values \textless=\ 32 bits use r0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
94 \item 64 bit return values use r0 and r1
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
95 \item if return value is a structure, the caller allocates space for the return value on the stack in its frame and passes a pointer to it in r0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
96 \end{itemize}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
97
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
98 \paragraph{Stack layout}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
99
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
100 Stack directly after function prolog:\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
101
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
102 \begin{figure}[h]
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
103 \begin{tabular}{5|3|1 1}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
104 \hhline{~-~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
105 & \vdots & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
106 \hhline{~=~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
107 register save area & & & \mrrbrace{5}{caller's frame} \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
108 \hhline{~-~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
109 local data & & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
110 \hhline{~-~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
111 \mrlbrace{7}{parameter area} & \ldots & \mrrbrace{3}{stack parameters} & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
112 & \ldots & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
113 & \ldots & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
114 \hhline{~=~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
115 & r3 & \mrrbrace{4}{spill area (if needed)} & \mrrbrace{7}{current frame} \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
116 & r2 & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
117 & r1 & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
118 & r0 & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
119 \hhline{~-~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
120 register save area (with return address) & & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
121 \hhline{~-~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
122 local data & & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
123 \hhline{~-~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
124 parameter area & \vdots & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
125 \hhline{~-~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
126 \end{tabular}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
127 \caption{Stack layout on arm32}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
128 \end{figure}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
129
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
130
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
131 \newpage
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
132
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
133 \subsubsection{ATPCS THUMB mode}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
134
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
135
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
136 \paragraph{Status}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
137
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
138 \begin{itemize}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
139 \item The ATPCS THUMB mode is untested.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
140 \item Ellipse calls may not work.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
141 \item C++ this calls do not work.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
142 \end{itemize}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
143
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
144 \paragraph{Registers and register usage}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
145
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
146 In THUMB mode, the ARM32 processor family supports eight 32 bit general purpose registers r0-r7 and access to high order registers r8-r15:\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
147 \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
148 \begin{table}[h]
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
149 \begin{tabular}{3 B}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
150 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
151 Name & Brief description\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
152 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
153 {\bf r0} & parameter 0, scratch, return value\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
154 {\bf r1} & parameter 1, scratch, return value\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
155 {\bf r2-r3} & parameters 2 and 3, scratch\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
156 {\bf r4-r6} & permanent\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
157 {\bf r7} & frame pointer, permanent\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
158 {\bf r8-r11} & permanent\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
159 {\bf r12} & scratch\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
160 {\bf r13} & stack pointer, permanent\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
161 {\bf r14} & link register, permanent\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
162 {\bf r15} & program counter (note: due to pipeline, r15 points to 2 instructions ahead)\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
163 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
164 \end{tabular}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
165 \caption{Register usage on arm32 thumb mode}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
166 \end{table}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
167
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
168 \paragraph{Parameter passing}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
169
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
170 \begin{itemize}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
171 \item stack parameter order: right-to-left
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
172 \item caller cleans up the stack
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
173 \item first four words are passed using r0-r3
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
174 \item subsequent parameters are pushed onto the stack (in right to left order, such that the stack pointer points to the first of the remaining parameters)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
175 \item if the callee takes the address of one of the parameters and uses it to address other parameters (e.g. varargs) it has to copy - in its prolog - the first four words to a reserved stack area adjacent to the other parameters on the stack
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
176 \item parameters \textless=\ 32 bits are passed as 32 bit words
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
177 \item 64 bit parameters are passed as two 32 bit parts (even partly via the register and partly via the stack), although this doesn't seem to be specified in the ATPCS), with the loword coming first
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
178 \item structures and unions are passed by value, with the first four words of the parameters in r0-r3
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
179 \item if return value is a structure, a pointer pointing to the return value's space is passed in r0, the first parameter in r1, etc. (see {\bf return values})
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
180 \item keeping the stack eight-byte aligned can improve memory access performance and is required by LDRD and STRD on ARMv5TE processors which are part of the ARM32 family, so, in order to avoid problems one should always align the stack (tests have shown, that GCC does care about the alignment when using the ellipsis)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
181 \end{itemize}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
182
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
183
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
184 \paragraph{Return values}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
185 \begin{itemize}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
186 \item return values \textless=\ 32 bits use r0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
187 \item 64 bit return values use r0 and r1
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
188 \item if return value is a structure, the caller allocates space for the return value on the stack in its frame and passes a pointer to it in r0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
189 \end{itemize}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
190
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
191 \paragraph{Stack layout}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
192
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
193 Stack directly after function prolog:\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
194
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
195 \begin{figure}[h]
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
196 \begin{tabular}{5|3|1 1}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
197 \hhline{~-~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
198 & \vdots & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
199 \hhline{~=~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
200 register save area & & & \mrrbrace{5}{caller's frame} \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
201 \hhline{~-~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
202 local data & & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
203 \hhline{~-~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
204 \mrlbrace{7}{parameter area} & \ldots & \mrrbrace{3}{stack parameters} & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
205 & \ldots & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
206 & \ldots & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
207 \hhline{~=~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
208 & r3 & \mrrbrace{4}{spill area (if needed)} & \mrrbrace{7}{current frame} \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
209 & r2 & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
210 & r1 & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
211 & r0 & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
212 \hhline{~-~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
213 register save area (with return address) & & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
214 \hhline{~-~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
215 local data & & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
216 \hhline{~-~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
217 parameter area & \vdots & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
218 \hhline{~-~~}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
219 \end{tabular}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
220 \caption{Stack layout on arm32 thumb mode}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
221 \end{figure}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
222
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
223
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
224
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
225 \newpage
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
226
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
227 \subsubsection{EABI (ARM and THUMB mode)}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
228
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
229
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
230 The ARM EABI is very similar to the ABI outlined in ARM-THUMB procedure call
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
231 standard (ATPCS) \cite{ATPCS} - however, the EABI requires the stack to be
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
232 8-byte aligned at function entries, as well as 64 bit parameters. The latter
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
233 are aligned on 8-byte boundaries on the stack and 2-registers for parameters
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
234 passed via register. In order to achieve such an alignment, a register might
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
235 have to be skipped for parameters passed via registers, or 4-bytes on the stack
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
236 for parameters passed via the stack. Refer to the Debian ARM EABI port wiki for more information \cite{armeabi}.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
237
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
238
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
239 \paragraph{Status}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
240
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
241 \begin{itemize}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
242 \item The EABI THUMB mode is tested and works fine (contrary to the ATPCS).
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
243 \item Ellipse calls do not work.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
244 \item C++ this calls do not work.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
245 \end{itemize}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
246
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
247 \newpage
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
248
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
249 \subsubsection{ARM on Apple's iOS (Darwin) Platform}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
250
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
251
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
252 The iOS runs on ARMv6 (iOS 2.0) and ARMv7 (iOS 3.0) architectures.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
253 Typically code is compiled in Thumb mode.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
254
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
255 \paragraph{Register usage}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
256
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
257 \begin{table}[h]
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
258 \begin{tabular}{3 B}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
259 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
260 Name & Brief description\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
261 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
262 {\bf R0} & parameter 0, scratch, return value\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
263 {\bf R1} & parameter 1, scratch, return value\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
264 {\bf R2-R3} & parameters 2 and 3, scratch\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
265 {\bf R4-R6} & permanent\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
266 {\bf R7} & frame pointer, permanent\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
267 {\bf R8} & permanent\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
268 {\bf R9} & permanent(iOS 2.0) and scratch (since iOS 3.0)\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
269 {\bf R10-R11}& permanent\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
270 {\bf R12} & scratch, intra-procedure scratch register (IP) used by dynamic linker\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
271 {\bf R13} & stack pointer, permanent\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
272 {\bf R14} & link register, permanent\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
273 {\bf R15} & program counter (note: due to pipeline, r15 points to 2 instructions ahead)\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
274 {\bf CPSR} & Program status register\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
275 {\bf D0-D7} & scratch. aliases S0-S15, on ARMv7 alsa as Q0-Q3. Not accessible from Thumb mode on ARMv6.\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
276 {\bf D8-D15} & permanent, aliases S16-S31, on ARMv7 alsa as Q4-A7. Not accesible from Thumb mode on ARMv6.\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
277 {\bf D16-D31}& Only available in ARMv7, aliases Q8-Q15.\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
278 {\bf FPSCR} & VFP status register.\\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
279 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
280 \end{tabular}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
281 \caption{Register usage on ARM Apple iOS}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
282 \end{table}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
283
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
284 The ABI is based on the AAPCS but with some important differences listed below:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
285
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
286 \begin{itemize}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
287 \item R7 instead of R11 is used as frame pointer
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
288 \item R9 is scratch since iOS 3.0, was preserved before.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
289 \end{itemize}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
290
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
291 \subsubsection{Architectures}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
292
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
293 The ARM architecture family contains several revisions with capabilities and
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
294 extensions (such as thumb-interworking and more vector registers)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
295 The following table summaries important properties of the various
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
296 architecture standards.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
297
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
298 % iPhone 3GS : ARM Cortex-A8
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
299 % Nintendo DS: ARM 7 and ARM 9
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
300 % ARM 7: ARMv4T
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
301 % ARM 9: ARMv4T, HTC Wizard
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
302
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
303 \begin{table}[h]
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
304 \begin{tabular}{lll}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
305 Arch & Platforms & Details \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
306 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
307 ARMv4 & & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
308 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
309 ARMv4T & ARM 7, ARM 9, Neo FreeRunner (OpenMoko) & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
310 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
311 ARMv5 & & BLX instruction available \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
312 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
313 ARMv6 & & No vector registers available in thumb \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
314 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
315 ARMv7 & iPod touch, iPhone 3GS/4 & \\
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
316 \hline
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
317 \end{tabular}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
318 \caption{Overview of ARM Architecture, Platforms and Details}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
319 \end{table}
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
320
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
321 \newpage
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
322