\subsection{Storing the program counter} \label{sec:fix-storing-pc} The first issue I ran into is that of storing the program counter. Storing the program counter on the stack is something done commonly in many languages during a function call. \subsubsection{ARM code example} Usually, an offset to the actual program counter at the moment of the store instruction is stored, to allow for a branch after that instruction, and have the callee return to the address after that branch. The ARM architecture accommodates for this: an instruction that reads the program counter, actually reads \enquote{the address of the current instruction plus 8}~\cite[A2.3]{armv7ar}. The following ARM assembly example illustrates this (\texttt{armstartup.s:540-2},~\cite{armrts}): \begin{minted}{ual} str pc,[sp,#-4]! @ 0x20 Store PC on the stack bl init_clean @ 0x24 Branch to init_clean tst r4,r4 @ 0x28 \end{minted} \begin{lrbox}{\ualbox} \ual{[sp,#-4]!} \end{lrbox} Dummy addresses have been indicated in comments. When execution arrives at \ual{0x20}, the program counter is set to \ual{0x20}. Per the above documentation, \ual{str} stores \ual{0x20+8} on the stack% \footnote{\usebox{\ualbox} indicates that the stack pointer should be decreased by four before storing the program counter on the stack. It has nothing to do with the 8 offset that is added to the program counter itself.}. The processor branches to \ual{init_clean}, which loads the value from the stack back into the program counter to return to the caller. The program counter is then \ual{0x28}. For the next instruction cycle, the \ual{tst} command is executed. \subsubsection{Adapting for Thumb-2} There are two reasons why the above cannot be used in Thumb-2 code. First, \ual{pc} is not allowed as the first operand to a \ual{str} instruction. Hence, we need to first move \ual{pc} to an auxiliary register, and then push that on the stack. We then get: \begin{minted}{ual} add lr,pc,#9 @ 0x20 Save PC+4+9 to LR str lr,[sp,#-4]! @ 0x24 Store LR on the stack bl init_clean @ 0x28 Branch to init_clean tst r4,r4 @ 0x2c \end{minted} We store the value \ual{0x2d}. This address points to the \ual{tst} instruction as before, with the LSB set to 1 to indicate Thumb mode. The second problem we meet is that the instruction to store the program counter may be halfword-aligned rather than word-aligned. We saw above that a read of the program counter in ARM mode reads as PC+8. In Thumb mode this is more complicated. In this case, we \enquote{[r]ead the word-aligned PC value, that is, the address of the current instruction + 4, with bits [1:0] forced to zero}~\cite[A5.1.2]{armv7m}. This means that when the \ual{add} instruction above is at \ual{0x22}, we will still store \ual{0x2d} on the stack, since the word-aligned program counter is \ual{0x20} as before. However, in this case \ual{bl} is located at \ual{0x2a}, and since this is a 32 bits instruction we point to the middle of that instruction. In hand-written code, we can solve this by adding labels for the addresses we want to store on the stack. In generated code, we need to keep track of the current alignment and add either \ual{9} or \ual{11} to the read program counter. \subsubsection{Other solutions} Another solution than the one we present here is the use of the link register. Branch instructions as \ual{bl} store the address of the next instruction in the link register. We could therefore imagine a setup where the callee gets the return address from that register rather than from the stack. This is the approach taken by GCC. The code of a typical C subroutine starts with \ual{push {r7,lr}} and ends with \ual{pop {r7,pc}}. When generating code for a functional language, this is not easily done due to tail recursion. It is an easier solution to have the caller responsible for storing the return address, which is why this approach is taken in Clean's ARM code generator\cite{armcg} and why I continue along those lines. \subsubsection{Complexity analysis} To be done. %TODO For every occurrence: +1 word code size; for every function call: +1 instruction.