Jeremy Siek 9 年之前
父节点
当前提交
0e896b3a82
共有 1 个文件被更改,包括 93 次插入86 次删除
  1. 93 86
      book.tex

+ 93 - 86
book.tex

@@ -899,7 +899,8 @@ that the assembly program exhibits the same behavior on an x86
 computer as the $S_0$ program running in a Racket implementation.
 computer as the $S_0$ program running in a Racket implementation.
 \[
 \[
 \xymatrix{
 \xymatrix{
-P_1 \in S_0  \ar[rr]^{\text{compile}} \ar[drr]_{\text{run in Racket}\quad}   &&  P_2 \in \text{x86-64} \ar[d]^{\quad\text{run on an x86 machine}}\\
+P_1 \in S_0  \ar[rr]^{\text{compile}} \ar[drr]_{\text{run in Racket}\quad} 
+  &&  P_2 \in \text{x86-64} \ar[d]^{\quad\text{run on an x86 machine}}\\
 & & n \in \mathbb{Z}   
 & & n \in \mathbb{Z}   
 }
 }
 \]
 \]
@@ -1097,13 +1098,13 @@ abstract syntax tree into the text representation for x86
 \begin{array}{lcl}
 \begin{array}{lcl}
 \Arg &::=&  \INT{\Int} \mid \REG{\itm{register}}
 \Arg &::=&  \INT{\Int} \mid \REG{\itm{register}}
     \mid \STACKLOC{\Int} \\ 
     \mid \STACKLOC{\Int} \\ 
-\Instr &::=& (\key{add} \; \Arg\; \Arg) \mid 
-      (\key{sub} \; \Arg\; \Arg) \mid 
-      (\key{imul} \; \Arg\;\Arg) \mid 
-      (\key{neg} \; \Arg) \mid \\
-  && (\key{mov} \; \Arg\; \Arg) \mid 
+\Instr &::=& (\key{addq} \; \Arg\; \Arg) \mid 
+      (\key{subq} \; \Arg\; \Arg) \mid 
+      (\key{imulq} \; \Arg\;\Arg) \mid 
+      (\key{negq} \; \Arg) \mid \\
+  && (\key{movq} \; \Arg\; \Arg) \mid 
       (\key{call} \; \mathit{label}) \mid
       (\key{call} \; \mathit{label}) \mid
-      (\key{push}\;\Arg) \mid (\key{pop}\;\Arg) \mid (\key{ret}) \\
+      (\key{pushq}\;\Arg) \mid (\key{popq}\;\Arg) \mid (\key{retq}) \\
 \Prog &::= & (\key{program} \;\itm{info} \; \Instr^{+})
 \Prog &::= & (\key{program} \;\itm{info} \; \Instr^{+})
 \end{array}
 \end{array}
 \]
 \]
@@ -1390,17 +1391,18 @@ test your passes on the example programs.
 In the \key{select\_instructions} pass we begin the work of
 In the \key{select\_instructions} pass we begin the work of
 translating from $C_0$ to x86. The target language of this pass is a
 translating from $C_0$ to x86. The target language of this pass is a
 pseudo-x86 language that still uses variables, so we add an AST node
 pseudo-x86 language that still uses variables, so we add an AST node
-of the form $\VAR{\itm{var}}$.  The \key{select\_instructions} pass
-deals with the differing format of arithmetic operations. For example,
-in $C_0$ an addition operation could take the following form:
+of the form $\VAR{\itm{var}}$ to the x86 abstract syntax.  The
+\key{select\_instructions} pass deals with the differing format of
+arithmetic operations. For example, in $C_0$ an addition operation
+could take the following form:
 \[
 \[
 \ASSIGN{x}{ \BINOP{+}{10}{32} }
 \ASSIGN{x}{ \BINOP{+}{10}{32} }
 \]
 \]
 To translate to x86, we need to express this addition using the
 To translate to x86, we need to express this addition using the
-\key{add} instruction that does an inplace update. So we first move
-$10$ to $x$ then perform the \key{add}.
+\key{addq} instruction that does an inplace update. So we first move
+$10$ to $x$ then perform the \key{addq}.
 \[
 \[
-(\key{mov}\,\INT{10}\, \VAR{x})\; (\key{add} \;\INT{32}\; \VAR{x})
+(\key{mov}\,\INT{10}\, \VAR{x})\; (\key{addq} \;\INT{32}\; \VAR{x})
 \]
 \]
 
 
 There are some cases that require special care to avoid generating
 There are some cases that require special care to avoid generating
@@ -1410,7 +1412,7 @@ extra move instruction.  For example, the following
 \[
 \[
 \ASSIGN{x}{ \BINOP{+}{10}{x} }
 \ASSIGN{x}{ \BINOP{+}{10}{x} }
 \quad\text{should translate to}\quad
 \quad\text{should translate to}\quad
-(\key{add} \; \INT{10}\; \VAR{x})
+(\key{addq} \; \INT{10}\; \VAR{x})
 \]
 \]
 
 
 Regarding the \RETURN{e} statement of $C_0$, we recommend treating it
 Regarding the \RETURN{e} statement of $C_0$, we recommend treating it
@@ -1427,10 +1429,10 @@ Consider again the example $S_0$ program $\BINOP{+}{52}{ \UNIOP{-}{10} }$,
 which after \key{select\_instructions} looks like the following.
 which after \key{select\_instructions} looks like the following.
 \[
 \[
 \begin{array}{l}
 \begin{array}{l}
-(\key{mov}\;\INT{10}\; \VAR{x})\\
-(\key{neg}\; \VAR{x})\\
-(\key{mov}\; \INT{52}\; \REG{\itm{rax}})\\
-(\key{add}\; \VAR{x} \REG{\itm{rax}})
+(\key{movq}\;\INT{10}\; \VAR{x})\\
+(\key{negq}\; \VAR{x})\\
+(\key{movq}\; \INT{52}\; \REG{\itm{rax}})\\
+(\key{addq}\; \VAR{x} \REG{\itm{rax}})
 \end{array}
 \end{array}
 \]
 \]
 The one and only variable $x$ is assigned to stack location
 The one and only variable $x$ is assigned to stack location
@@ -1438,10 +1440,10 @@ The one and only variable $x$ is assigned to stack location
 above to
 above to
 \[
 \[
 \begin{array}{l}
 \begin{array}{l}
-(\key{mov}\;\INT{10}\; \STACKLOC{{-}8})\\
-(\key{neg}\; \STACKLOC{{-}8})\\
-(\key{mov}\; \INT{52}\; \REG{\itm{rax}})\\
-(\key{add}\; \STACKLOC{{-}8}\; \REG{\itm{rax}})
+(\key{movq}\;\INT{10}\; \STACKLOC{{-}8})\\
+(\key{negq}\; \STACKLOC{{-}8})\\
+(\key{movq}\; \INT{52}\; \REG{\itm{rax}})\\
+(\key{addq}\; \STACKLOC{{-}8}\; \REG{\itm{rax}})
 \end{array}
 \end{array}
 \]
 \]
 
 
@@ -1464,44 +1466,49 @@ Consider again the following example.
 After \key{assign\_homes} pass, the above has been translated to
 After \key{assign\_homes} pass, the above has been translated to
 \[
 \[
 \begin{array}{l}
 \begin{array}{l}
-(\key{mov} \;\INT{42}\; \STACKLOC{{-}8})\\
-(\key{mov}\;\STACKLOC{{-}8}\; \STACKLOC{{-}16})\\
-(\key{mov}\;\STACKLOC{{-}16}\; \REG{\itm{rax}})
+(\key{movq} \;\INT{42}\; \STACKLOC{{-}8})\\
+(\key{movq}\;\STACKLOC{{-}8}\; \STACKLOC{{-}16})\\
+(\key{movq}\;\STACKLOC{{-}16}\; \REG{\itm{rax}})
 \end{array}
 \end{array}
 \]
 \]
-The second \key{mov} instruction is problematic because both arguments
+The second \key{movq} instruction is problematic because both arguments
 are stack locations. We suggest fixing this problem by moving from the
 are stack locations. We suggest fixing this problem by moving from the
 source to \key{rax} and then from \key{rax} to the destination, as
 source to \key{rax} and then from \key{rax} to the destination, as
 follows.
 follows.
 \[
 \[
 \begin{array}{l}
 \begin{array}{l}
-(\key{mov} \;\INT{42}\; \STACKLOC{{-}8})\\
-(\key{mov}\;\STACKLOC{{-}8}\; \REG{\itm{rax}})\\
-(\key{mov}\;\REG{\itm{rax}}\; \STACKLOC{{-}16})\\
-(\key{mov}\;\STACKLOC{{-}16}\; \REG{\itm{rax}})
+(\key{movq} \;\INT{42}\; \STACKLOC{{-}8})\\
+(\key{movq}\;\STACKLOC{{-}8}\; \REG{\itm{rax}})\\
+(\key{movq}\;\REG{\itm{rax}}\; \STACKLOC{{-}16})\\
+(\key{movq}\;\STACKLOC{{-}16}\; \REG{\itm{rax}})
 \end{array}
 \end{array}
 \]
 \]
 
 
-The \key{imul} instruction is a special case because the destination
+The \key{imulq} instruction is a special case because the destination
 argument must be a register.
 argument must be a register.
 
 
-\section{Testing with Interpreters}
+\section{Print x86}
+\label{sec:print-x86}
 
 
-The typical way to test a compiler is to run the generated assembly
-code on a diverse set of programs and check whether they behave as
-expected. However, when a compiler is structured as our is, with many
-passes, when there is an error in the generated assembly code it can
-be hard to determine which pass contains the source of the error.  A
-good way to isolate the error is to not only test the generated
-assembly code but to also test the output of every pass. This requires
-having interpreters for all the intermediate languages.  Indeed, the
-file \key{interp.rkt} in the supplemental code provides interpreters
-for all the intermediate languages described in this book, starting
-with interpreters for $S_0$, $C_0$, and x86 (in abstract syntax).
+[To do: talk about printing the AST to x86.]
 
 
-The file \key{run-tests.rkt} automates the process of running the
-interpreters on the output programs of each pass and checking their
-result.
+%% \section{Testing with Interpreters}
+
+%% The typical way to test a compiler is to run the generated assembly
+%% code on a diverse set of programs and check whether they behave as
+%% expected. However, when a compiler is structured as our is, with many
+%% passes, when there is an error in the generated assembly code it can
+%% be hard to determine which pass contains the source of the error.  A
+%% good way to isolate the error is to not only test the generated
+%% assembly code but to also test the output of every pass. This requires
+%% having interpreters for all the intermediate languages.  Indeed, the
+%% file \key{interp.rkt} in the supplemental code provides interpreters
+%% for all the intermediate languages described in this book, starting
+%% with interpreters for $S_0$, $C_0$, and x86 (in abstract syntax).
+
+%% The file \key{run-tests.rkt} automates the process of running the
+%% interpreters on the output programs of each pass and checking their
+%% result.
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Register Allocation}
 \chapter{Register Allocation}
@@ -1535,16 +1542,16 @@ Source program:
 After instruction selection:
 After instruction selection:
 \begin{lstlisting}
 \begin{lstlisting}
   (program (v w x y z)
   (program (v w x y z)
-    (mov (int 1) (var v))
-    (mov (int 46) (var w))
-    (mov (var v) (var x))
-    (add (int 7) (var x))
-    (mov (var x) (var y))
-    (add (int 4) (var y))
-    (mov (var x) (var z))
-    (add (var w) (var z))
-    (mov (var z) (reg rax))
-    (sub (var y) (reg rax)))
+    (movq (int 1) (var v))
+    (movq (int 46) (var w))
+    (movq (var v) (var x))
+    (addq (int 7) (var x))
+    (movq (var x) (var y))
+    (addq (int 4) (var y))
+    (movq (var x) (var z))
+    (addq (var w) (var z))
+    (movq (var z) (reg rax))
+    (subq (var y) (reg rax)))
 \end{lstlisting}
 \end{lstlisting}
 \end{minipage}
 \end{minipage}
 \caption{Running example for this chapter.}
 \caption{Running example for this chapter.}
@@ -1574,11 +1581,11 @@ To understand the latter condition, consider the following code
 fragment in which there are two writes to $b$. Are $a$ and
 fragment in which there are two writes to $b$. Are $a$ and
 $b$ both live at the same time? 
 $b$ both live at the same time? 
 \begin{lstlisting}[numbers=left,numberstyle=\tiny]
 \begin{lstlisting}[numbers=left,numberstyle=\tiny]
-(mov (int 5) (var a))    ; @$a \gets 5$@
-(mov (int 30) (var b))   ; @$b \gets 30$@
-(mov (var a) (var c))    ; @$c \gets x$@
-(mov (int 10) (var b))   ; @$b \gets 10$@
-(add (var b) (var c))    ; @$c \gets c + b$@
+(movq (int 5) (var a))    ; @$a \gets 5$@
+(movq (int 30) (var b))   ; @$b \gets 30$@
+(movq (var a) (var c))    ; @$c \gets x$@
+(movq (int 10) (var b))   ; @$b \gets 10$@
+(addq (var b) (var c))    ; @$c \gets c + b$@
 \end{lstlisting}
 \end{lstlisting}
 The answer is no because the value $30$ written to $b$ on line 2 is
 The answer is no because the value $30$ written to $b$ on line 2 is
 never used. The variable $b$ is read on line 5 and there is an
 never used. The variable $b$ is read on line 5 and there is an
@@ -1615,16 +1622,16 @@ $L_{\mathtt{after}}$ set.
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{lstlisting}
 \begin{lstlisting}
   (program (v w x y z)
   (program (v w x y z)
-    (mov (int 1) (var v))      @$\{ v \}$@
-    (mov (int 46) (var w))     @$\{ v, w \}$@
-    (mov (var v) (var x))      @$\{ w, x \}$@
-    (add (int 7) (var x))      @$\{ w, x \}$@
-    (mov (var x) (var y))      @$\{ w, x, y\}$@
-    (add (int 4) (var y))      @$\{ w, x, y \}$@
-    (mov (var x) (var z))      @$\{ w, y, z \}$@
-    (add (var w) (var z))      @$\{ y, z \}$@
-    (mov (var z) (reg rax))    @$\{ y \}$@
-    (sub (var y) (reg rax)))   @$\{\}$@
+    (movq (int 1) (var v))      @$\{ v \}$@
+    (movq (int 46) (var w))     @$\{ v, w \}$@
+    (movq (var v) (var x))      @$\{ w, x \}$@
+    (addq (int 7) (var x))      @$\{ w, x \}$@
+    (movq (var x) (var y))      @$\{ w, x, y\}$@
+    (addq (int 4) (var y))      @$\{ w, x, y \}$@
+    (movq (var x) (var z))      @$\{ w, y, z \}$@
+    (addq (var w) (var z))      @$\{ y, z \}$@
+    (movq (var z) (reg rax))    @$\{ y \}$@
+    (subq (var y) (reg rax)))   @$\{\}$@
 \end{lstlisting}
 \end{lstlisting}
 \caption{Running example program annotated with live-after sets.}
 \caption{Running example program annotated with live-after sets.}
 \label{fig:live-eg}
 \label{fig:live-eg}
@@ -1657,12 +1664,12 @@ A better way to compute the edges of the intereference graph is given
 by the following rules.
 by the following rules.
 
 
 \begin{itemize}
 \begin{itemize}
-\item If instruction $I_k$ is a move: (\key{mov} $s$\, $d$), then add
+\item If instruction $I_k$ is a move: (\key{movq} $s$\, $d$), then add
   the edge $(d,v)$ for every $v \in L_{\mathsf{after}}(k)$ unless $v =
   the edge $(d,v)$ for every $v \in L_{\mathsf{after}}(k)$ unless $v =
   d$ or $v = s$.
   d$ or $v = s$.
 
 
 \item If instruction $I_k$ is not a move but some other arithmetic
 \item If instruction $I_k$ is not a move but some other arithmetic
-  instruction such as (\key{add} $s$\, $d$), then add the edge $(d,v)$
+  instruction such as (\key{addq} $s$\, $d$), then add the edge $(d,v)$
   for every $v \in L_{\mathsf{after}}(k)$ unless $v = d$.
   for every $v \in L_{\mathsf{after}}(k)$ unless $v = d$.
   
   
 \item If instruction $I_k$ is of the form (\key{call}
 \item If instruction $I_k$ is of the form (\key{call}
@@ -1868,16 +1875,16 @@ Applying this assignment to our running example
 % why frame size of 32? -JGS
 % why frame size of 32? -JGS
 \begin{lstlisting}
 \begin{lstlisting}
 (program 32
 (program 32
-  (mov (int 1) (reg rbx))
-  (mov (int 46) (stack-loc -8))
-  (mov (reg rbx) (stack-loc -16))
-  (add (int 7) (stack-loc -16))
-  (mov (stack-loc 16) (reg rbx))
-  (add (int 4) (reg rbx))
-  (mov (stack-loc -16) (stack-loc -16))
-  (add (stack-loc -8) (stack-loc -16))
-  (mov (stack-loc -16) (reg rax))
-  (sub (reg rbx) (reg rax)))
+  (movq (int 1) (reg rbx))
+  (movq (int 46) (stack-loc -8))
+  (movq (reg rbx) (stack-loc -16))
+  (addq (int 7) (stack-loc -16))
+  (movq (stack-loc 16) (reg rbx))
+  (addq (int 4) (reg rbx))
+  (movq (stack-loc -16) (stack-loc -16))
+  (addq (stack-loc -8) (stack-loc -16))
+  (movq (stack-loc -16) (reg rax))
+  (subq (reg rbx) (reg rax)))
 \end{lstlisting}
 \end{lstlisting}
 This program is almost an x86 program. The remaining step is to apply
 This program is almost an x86 program. The remaining step is to apply
 the patch instructions pass. In this example, the trivial move of
 the patch instructions pass. In this example, the trivial move of
@@ -1886,9 +1893,9 @@ the patch instructions pass. In this example, the trivial move of
 \key{\%rax}. The following shows the portion of the program that
 \key{\%rax}. The following shows the portion of the program that
 changed.
 changed.
 \begin{lstlisting}
 \begin{lstlisting}
-  (add (int 4) (reg rbx))
-  (mov (stack-loc -8) (reg rax)
-  (add (reg rax) (stack-loc -16))
+  (addq (int 4) (reg rbx))
+  (movq (stack-loc -8) (reg rax)
+  (addq (reg rax) (stack-loc -16))
 \end{lstlisting}
 \end{lstlisting}
 An overview of all of the passes involved in register allocation is
 An overview of all of the passes involved in register allocation is
 shown in Figure~\ref{fig:reg-alloc-passes}.
 shown in Figure~\ref{fig:reg-alloc-passes}.