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
|
\section{Reduced offset space for memory load instructions}
\label{sec:load-offsets}
\begin{multicols}{2}
\subsection{Introduction}
\label{sec:load-offsets:intro}
The \ual{LDR} (immediate) instruction loads a word from memory into a register.
The address is specified by a base register and an offset
(which can possibly be added to the base register before or after the load).
On ARM, this offset is encoded in twelve bits, and one bit is used for its sign.
That allows for any offset between $-4095$ and $4095$ bytes.
For details, see \cite[A8.8.63]{armv7ar}.
The Thumb instruction set defines four different variants of the immediate \ual{LDR} instruction~\parencite[6.7.42]{armv7m}:
\begin{itemize}[itemsep=0pt]
\item
16-bits, any base register, a 5-bit positive offset.
\item
16-bits, SP as base, a 8-bit positive offset.
\item
32-bits, any base register, a 12-bit positive offset.
\item
32-bits, any base register, a 8-bit negative offset.
\end{itemize}
While in some cases a narrow \ual{LDR} instructions can be used in Thumb,
some uses in ARM cannot be used directly in Thumb:
the offset can now only be between $-255$ and $4095$ bytes.
\subsection{Usage in Clean}
\label{sec:load-offsets:clean}
For most Clean programs, the generated code will not attempt to load memory with large negative offsets.
However, it can occur when a function has to look far down the A-stack.
In practice, this happens when a function has a high arity or many complex expressions in its right hand side.
\todo{rest}
\end{multicols}
|