summaryrefslogtreecommitdiff
path: root/thesis
diff options
context:
space:
mode:
Diffstat (limited to 'thesis')
-rw-r--r--thesis/storing-pc.tex43
1 files changed, 41 insertions, 2 deletions
diff --git a/thesis/storing-pc.tex b/thesis/storing-pc.tex
index 4bae7fb..d3fc474 100644
--- a/thesis/storing-pc.tex
+++ b/thesis/storing-pc.tex
@@ -173,14 +173,53 @@ A general comparison of running time under ARM and Thumb is made in \cref{sec:re
\subsection{Other solutions}
\label{sec:storing-pc:other-solutions}
-Another solution than the one we present makes use of the link register.
+Another solution than the one we have considered here makes use of the link register.
Some branch instructions, like \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 {...,lr}} and ends with \ual{pop {...,pc}}.
When generating code for a functional language, it is not straightforward to do this, due to tail recursion.
-It is an easier solution to have the caller responsible for storing the return address,
+An example of this can be found in the following basic function:
+
+\begin{minted}{clean}
+ length :: !Int ![a] -> Int
+ length n [] = n
+ length n [_:xs] = length (n+1) xs
+\end{minted}
+
+The current Thumb backend generates the following code:
+
+\begin{minted}{ual}
+slength_P2:
+ ldr r0,[r6] @ Load top of A-stack (the list)
+ ldr r14,=__Nil+2 @ Check if it is Nil
+ cmp r0,r14
+ bne case_P2
+case_P1: @ If the list is Nil
+ ldr pc,[sp],#4 @ Simply return
+ .ltorg
+case_P2: @ If the list is not Nil
+ ldr r6,[r6,#8] @ Load the Cons part of the list
+ ldr r0,[r6] @ Check if it has been evaluated already
+ tst r0,#2
+ bne e_0
+ str r4,[sp,#-4]! @ If the Cons part has not been evaluated
+ .align
+ add.w r14,pc,#7 @ Evaluate the cons part
+ str.w r14,[sp,#-4]!
+ blx r0
+ ldr r4,[sp],#4
+e_0: @ If / after the Cons part has been evaluated
+ add r4,r4,#1 @ Increase counter
+ b slength_P2 @ Tail recursively jump back to start of function
+ .ltorg
+\end{minted}
+
+In this setup, it is not easily possible to let the callee store the return address,
+ since we enter the function as many times as there are elements in the list,
+ while we only return from it once, in \texttt{case\_P1}.
+A more straightforward solution to have the caller responsible for storing the return address,
which is why this approach is taken in Clean's ARM code generator~\parencite{armcg}
and why we continue along these lines for the Thumb backend.