aboutsummaryrefslogtreecommitdiff
path: root/src/assembly.tex
blob: 862ae01a00a41e57770731f205af0cf5279a31be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
\chapter{RISC-V Assembly Programmer's Handbook}
\label{assembly}

This chapter is a placeholder for an assembly programmer's manual.

Table~\ref{regmap} lists the assembler mnemonics for the {\tt x} and {\tt f}
registers and their role in the first standard calling convention.

\vspace{0.2in}
\begin{table*}[htbp]
\begin{center}
\begin{tabular}{|l|l|l|l|}

  \hline
  Register            & ABI Name            & Description        & Saver \\ \hline
  \tt x0              & \tt zero            & Hard-wired zero    & --- \\
  \tt x1              & \tt ra              & Return address     & Caller \\
  \tt x2              & \tt sp              & Stack pointer      & Callee \\
  \tt x3              & \tt gp              & Global pointer     & --- \\
  \tt x4              & \tt tp              & Thread pointer     & --- \\
  \tt x5              & {\tt t0}            & Temporary/alternate link register& Caller \\
  {\tt x6}--{\tt 7}   & {\tt t1}--{\tt 2}   & Temporaries        & Caller \\
  \tt x8              & {\tt s0}/\tt fp     & Saved register/frame pointer & Callee \\
  \tt x9              & {\tt s1}            & Saved register     & Callee \\
  {\tt x10}--{\tt 11} & {\tt a0}--{\tt 1}   & Function arguments/return values & Caller \\
  {\tt x12}--{\tt 17} & {\tt a2}--{\tt 7}   & Function arguments & Caller \\
  {\tt x18}--{\tt 27} & {\tt s2}--{\tt 11}  & Saved registers    & Callee \\
  {\tt x28}--{\tt 31} & {\tt t3}--{\tt 6}   & Temporaries        & Caller \\
  \hline
  {\tt f0}--{\tt 7}   & {\tt ft0}--{\tt 7}  & FP temporaries     & Caller \\
  {\tt f8}--{\tt 9}   & {\tt fs0}--{\tt 1}  & FP saved registers & Callee \\
  {\tt f10}--{\tt 11} & {\tt fa0}--{\tt 1}  & FP arguments/return values & Caller \\
  {\tt f12}--{\tt 17} & {\tt fa2}--{\tt 7}  & FP arguments       & Caller \\
  {\tt f18}--{\tt 27} & {\tt fs2}--{\tt 11} & FP saved registers & Callee \\
  {\tt f28}--{\tt 31} & {\tt ft8}--{\tt 11} & FP temporaries     & Caller \\
  \hline

 \end{tabular}
\end{center}
\caption{Assembler mnemonics for RISC-V integer and floating-point
  registers, and their role in the first standard calling convention.}
\label{regmap}
\end{table*}

\pagebreak

\begin{commentary}
  There may be future different calling conventions, but note that
  registers {\tt x1}, {\tt x2}, and {\tt x5} have special meanings
  encoded in the standard ISA and/or the compressed extension.
\end{commentary}

Tables~\ref{pseudos} and \ref{csr-pseudos} contain a listing of standard
RISC-V pseudoinstructions.

\begin{table}[h]
\begin{small}
\begin{center}
\begin{tabular}{l l l}
pseudoinstruction & Base Instruction(s) & Meaning \\ \hline

\tt la rd, symbol (\emph{non-PIC}) & {\tt auipc rd, ${\tt delta[31:12]} + {\tt delta[11]}$} & Load absolute address, \\
                  & {\tt addi rd, rd, delta[11:0]}                         & where ${\tt delta} = {\tt symbol} - {\tt pc}$ \\[1ex]
\tt la rd, symbol (\emph{PIC})& {\tt auipc rd, ${\tt delta[31:12]} + {\tt delta[11]}$} & Load absolute address, \\
                  & {\tt l\{w|d\} rd, rd, delta[11:0]}                         & where ${\tt delta} = {\tt GOT[symbol]} - {\tt pc}$ \\[1ex]
\tt lla rd, symbol& {\tt auipc rd, ${\tt delta[31:12]} + {\tt delta[11]}$} & Load local address, \\
                  & {\tt addi rd, rd, delta[11:0]}                         & where ${\tt delta} = {\tt symbol} - {\tt pc}$ \\[1ex]
\tt l\{b|h|w|d\} rd, symbol & {\tt auipc rd, ${\tt delta[31:12]} + {\tt delta[11]}$} & Load global \\
                            & {\tt l\{b|h|w|d\} rd, delta[11:0](rd)}                 & \\[1ex]
\tt s\{b|h|w|d\} rd, symbol, rt & {\tt auipc rt, ${\tt delta[31:12]} + {\tt delta[11]}$} & Store global \\
                               & {\tt s\{b|h|w|d\} rd, delta[11:0](rt)}                 & \\[1ex]
\tt fl\{w|d\} rd, symbol, rt & {\tt auipc rt, ${\tt delta[31:12]} + {\tt delta[11]}$} & Floating-point load global \\
                             & {\tt fl\{w|d\} rd, delta[11:0](rt)}                    & \\[1ex]
\tt fs\{w|d\} rd, symbol, rt & {\tt auipc rt, ${\tt delta[31:12]} + {\tt delta[11]}$} & Floating-point store global \\
                             & {\tt fs\{w|d\} rd, delta[11:0](rt)}                    & \\[1ex]
\multicolumn{3}{p{.99\textwidth}}{\small \em The base instructions use {\tt pc}-relative addressing, so the linker subtracts {\tt pc} from {\tt symbol} to get {\tt delta}.  The linker adds {\tt delta[11]} to the 20-bit high part, counteracting sign extension of the 12-bit low part.} \\
~\\
\hline
{\tt nop} & {\tt addi x0, x0, 0} & No operation \\
{\tt li rd, immediate} & {\em Myriad sequences} & Load immediate \\
{\tt mv rd, rs} & {\tt addi rd, rs, 0} & Copy register \\
{\tt not rd, rs} & {\tt xori rd, rs, -1} & One's complement \\
{\tt neg rd, rs} & {\tt sub rd, x0, rs} & Two's complement \\
{\tt negw rd, rs} & {\tt subw rd, x0, rs} & Two's complement word \\
{\tt sext.w rd, rs} & {\tt addiw rd, rs, 0} & Sign extend word \\
{\tt seqz rd, rs} & {\tt sltiu rd, rs, 1} & Set if $=$ zero \\
{\tt snez rd, rs} & {\tt sltu rd, x0, rs} & Set if $\neq$ zero \\
{\tt sltz rd, rs} & {\tt slt rd, rs, x0} & Set if $<$ zero \\
{\tt sgtz rd, rs} & {\tt slt rd, x0, rs} & Set if $>$ zero \\
\hline
{\tt fmv.s rd, rs} & {\tt fsgnj.s rd, rs, rs} & Copy single-precision register \\
{\tt fabs.s rd, rs} & {\tt fsgnjx.s rd, rs, rs} & Single-precision absolute value \\
{\tt fneg.s rd, rs} & {\tt fsgnjn.s rd, rs, rs} & Single-precision negate \\
{\tt fmv.d rd, rs} & {\tt fsgnj.d rd, rs, rs} & Copy double-precision register \\
{\tt fabs.d rd, rs} & {\tt fsgnjx.d rd, rs, rs} & Double-precision absolute value \\
{\tt fneg.d rd, rs} & {\tt fsgnjn.d rd, rs, rs} & Double-precision negate \\
\hline
{\tt beqz rs, offset} & {\tt beq rs, x0, offset} & Branch if $=$ zero \\
{\tt bnez rs, offset} & {\tt bne rs, x0, offset} & Branch if $\neq$ zero \\
{\tt blez rs, offset} & {\tt bge x0, rs, offset} & Branch if $\leq$ zero \\
{\tt bgez rs, offset} & {\tt bge rs, x0, offset} & Branch if $\geq$ zero \\
{\tt bltz rs, offset} & {\tt blt rs, x0, offset} & Branch if $<$ zero \\
{\tt bgtz rs, offset} & {\tt blt x0, rs, offset} & Branch if $>$ zero \\
\hline
{\tt bgt rs, rt, offset} & {\tt blt rt, rs, offset} & Branch if $>$ \\
{\tt ble rs, rt, offset} & {\tt bge rt, rs, offset} & Branch if $\leq$ \\
{\tt bgtu rs, rt, offset} & {\tt bltu rt, rs, offset} & Branch if $>$, unsigned \\
{\tt bleu rs, rt, offset} & {\tt bgeu rt, rs, offset} & Branch if $\leq$, unsigned \\
\hline

\end{tabular}
\end{center}
\end{small}
\caption{RISC-V pseudoinstructions.}
\label{pseudos}
\end{table}

\begin{table}[h]
\begin{small}
\begin{center}
\begin{tabular}{l l l}
pseudoinstruction & Base Instruction & Meaning \\ \hline

{\tt j offset} & {\tt jal x0, offset} & Jump \\
{\tt jal offset} & {\tt jal x1, offset} & Jump and link \\
{\tt jr rs} & {\tt jalr x0, 0(rs)} & Jump register \\
{\tt jalr rs} & {\tt jalr x1, 0(rs)} & Jump and link register \\
{\tt ret} & {\tt jalr x0, 0(x1)} & Return from subroutine \\
\tt call offset & {\tt auipc x1, ${\tt offset[31:12]} + {\tt offset[11]}$} & Call far-away subroutine \\
                & {\tt jalr x1, offset[11:0](x1)}                          & \\
\tt tail offset & {\tt auipc x6, ${\tt offset[31:12]} + {\tt offset[11]}$} & Tail call far-away subroutine \\
                & {\tt jalr x0, offset[11:0](x6)}                          & \\
\hline
{\tt fence} & {\tt fence iorw, iorw} & Fence on all memory and I/O \\
\hline
{\tt rdinstret[h] rd} & {\tt csrrs rd, instret[h], x0} & Read instructions-retired counter \\
{\tt rdcycle[h] rd} & {\tt csrrs rd, cycle[h], x0} & Read cycle counter \\
{\tt rdtime[h] rd} & {\tt csrrs rd, time[h], x0} & Read real-time clock \\
\hline
{\tt csrr rd, csr} & {\tt csrrs rd, csr, x0} & Read CSR \\
{\tt csrw csr, rs} & {\tt csrrw x0, csr, rs} & Write CSR \\
{\tt csrs csr, rs} & {\tt csrrs x0, csr, rs} & Set bits in CSR \\
{\tt csrc csr, rs} & {\tt csrrc x0, csr, rs} & Clear bits in CSR \\
\hline
{\tt csrwi csr, imm} & {\tt csrrwi x0, csr, imm} & Write CSR, immediate \\
{\tt csrsi csr, imm} & {\tt csrrsi x0, csr, imm} & Set bits in CSR, immediate \\
{\tt csrci csr, imm} & {\tt csrrci x0, csr, imm} & Clear bits in CSR, immediate \\
\hline
{\tt frcsr rd} & {\tt csrrs rd, fcsr, x0} & Read FP control/status register \\
{\tt fscsr rd, rs} & {\tt csrrw rd, fcsr, rs} & Swap FP control/status register \\
{\tt fscsr rs} & {\tt csrrw x0, fcsr, rs} & Write FP control/status register \\
\hline
{\tt frrm rd} & {\tt csrrs rd, frm, x0} & Read FP rounding mode \\
{\tt fsrm rd, rs} & {\tt csrrw rd, frm, rs} & Swap FP rounding mode \\
{\tt fsrm rs} & {\tt csrrw x0, frm, rs} & Write FP rounding mode \\
\hline
{\tt frflags rd} & {\tt csrrs rd, fflags, x0} & Read FP exception flags \\
{\tt fsflags rd, rs} & {\tt csrrw rd, fflags, rs} & Swap FP exception flags \\
{\tt fsflags rs} & {\tt csrrw x0, fflags, rs} & Write FP exception flags \\
\hline

\end{tabular}
\end{center}
\end{small}
\caption{RISC-V pseudoinstructions.}
\label{csr-pseudos}
\end{table}