From b35d88cd661978dcc8d118edbd184eecdbd3e714 Mon Sep 17 00:00:00 2001
From: Camil Staps
Date: Mon, 2 Jan 2017 21:52:25 +0100
Subject: Expand on note about tail recursion

---
 thesis/storing-pc.tex | 43 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 41 insertions(+), 2 deletions(-)

(limited to 'thesis/storing-pc.tex')

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.
 
-- 
cgit v1.2.3

