summaryrefslogtreecommitdiff
path: root/thesis/code-addresses.tex
diff options
context:
space:
mode:
Diffstat (limited to 'thesis/code-addresses.tex')
-rw-r--r--thesis/code-addresses.tex71
1 files changed, 71 insertions, 0 deletions
diff --git a/thesis/code-addresses.tex b/thesis/code-addresses.tex
new file mode 100644
index 0000000..2c3a043
--- /dev/null
+++ b/thesis/code-addresses.tex
@@ -0,0 +1,71 @@
+\section{Code addresses}
+\label{sec:code-addresses}
+
+\begin{multicols}{2}
+
+\subsection{Introduction}
+\label{sec:code-addresses:intro}
+The ARM ISA only has 32-bit instructions, meaning that the two least significant bits of a code address are always zero.
+When a branch is attempted to an address which has one or both of these bits set, the processor will automatically align the address by clearing these bits.
+
+Thumb mixes 32 and 16-bit instructions.
+Instructions are halfword-aligned, so bit 1 is part of the address.
+Additionally, bit 0 is used to facilitate ARM and Thumb interworking.
+When the PC is written to with a value where the LSB is cleared,
+ the processor jumps and switches to ARM mode.
+When the LSB is set, it switches to Thumb mode~\parencite[A2.3.2]{armv7ar}.
+
+\subsection{Usage in Clean}
+\label{sec:code-addresses:clean}
+The fact that in ARM mode the two lowest bits of a value written to the PC are cleared automatically has been exploited in the ARM code generator:
+ these two bits are used to store information.
+Bit 1 is used to mark a node as having reached head normal form%
+ \footnote{A node is in \emph{head} or \emph{root normal form} when it cannot be rewritten itself (though its children may)}.
+Bit 0 is used in Clean's default garbage collector, the copying collector, to record whether a node has been copied to the other semispace already:
+ when cleared (the normal state of an address as stored on the heap), it has not been copied yet.
+
+Porting to Thumb, we need to find a way to store this information without jumping to the middle of an instruction or accidentally switching to ARM mode.
+
+\subsection{Solution}
+\label{sec:code-addresses:solution}
+The solution for bit 1 is straightforward.
+By aligning all code addresses that we will ever want to jump to (the node entry addresses) on words rather than half-words, we ensure that bit 1 is always cleared.
+When a node has reached head normal form, setting bit 1 will give a corrupt address.
+Jumping to it would either jump after the first instruction (if it is 16-bit) or to the middle of the first instruction (if it is 32-bit).
+However, when a node is in HNF, there is no pointing in jumping to its entry address,
+ so the corrupted address is not a problem.
+
+The Thumb backend for Clean proposed in this thesis does not use interworking.
+However, we do need to make sure that whenever the PC is written to, the LSB is set.
+To that end, we store node entry addresses with the LSB on heap and stack.
+This only introduces problems in the copying collector,
+ which will then not copy any node (since having bit 0 set means having been copied already).
+Flipping the meaning of the LSB in the copying collector fixes this issue.
+
+\subsection{Comparison}
+\label{sec:code-addresses:comparison}
+Flipping the meaning of the LSB in the garbage collector amounts to swapping \ual{bne} and \ual{beq} and similar changes that do not effect the program's efficiency or size.
+
+By word-aligning all node entry addresses we lose one alignment byte per node entry address on average
+ (assuming that half of the node entry points are word-aligned already).
+This increases code size slightly, but since many instructions that were 32-bit in ARM are now 16-bit, the overall code size is still smaller.
+Aligning node entries has no effect on the program's efficiency, since the \ual{nop} instruction that is inserted above it will never be executed.
+
+\subsection{Other solutions}
+\label{sec:code-addresses:other-solutions}
+The solution described above exploits the fact that the LSB of a code address is only used inside the garbage collector,
+ and has a fixed value everywhere else.
+The solution for bit 1, however, is not specific to the Clean RTS.
+Therefore, a general solution to the problem that the two LSBs of a code address cannot be used to store information in Thumb mode would be to align all addresses that we need to store info of on double-words,
+ that is, ensuring the three LSBs are always zero.
+That way, the LSB can be used for ARM and Thumb interworking, and bit 1 and 2 can be used to store information.
+
+Of course, whether this is a viable solution depends on the density of code addresses that should be aligned.
+If every second instruction needs to be aligned, it would introduce so many \ual{nop} instructions
+ that code size will increase dramatically (even compared to ARM) and
+ that performance is degraded significantly.
+
+Then again, in many programs the issue we have explored in this section will not be a problem at all,
+ because the two LSBs of code addresses are not commonly used.
+
+\end{multicols}