aboutsummaryrefslogtreecommitdiff
path: root/src/rv64.adoc
blob: 531158a2a454a7e4f0b3da8e67af117326438585 (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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
[[rv64]]
== RV64I Base Integer Instruction Set, Version 2.1

This chapter describes the RV64I base integer instruction set, which
builds upon the RV32I variant described in <<rv32>>.
This chapter presents only the differences with RV32I, so should be read
in conjunction with the earlier chapter.

=== Register State

RV64I widens the integer registers and supported user address space to
64 bits (XLEN=64 in <<gprs>>).

=== Integer Computational Instructions

Most integer computational instructions operate on XLEN-bit values.
Additional instruction variants are provided to manipulate 32-bit values
in RV64I, indicated by a 'W' suffix to the opcode. These "*W"
instructions ignore the upper 32 bits of their inputs and always produce
32-bit signed values, sign-extending them to 64 bits, i.e. bits XLEN-1
through 31 are equal.

[NOTE]
====
The compiler and calling convention maintain an invariant that all
32-bit values are held in a sign-extended format in 64-bit registers.
Even 32-bit unsigned integers extend bit 31 into bits 63 through 32.
Consequently, conversion between unsigned and signed 32-bit integers is
a no-op, as is conversion from a signed 32-bit integer to a signed
64-bit integer. Existing 64-bit wide SLTU and unsigned branch compares
still operate correctly on unsigned 32-bit integers under this
invariant. Similarly, existing 64-bit wide logical operations on 32-bit
sign-extended integers preserve the sign-extension property. A few new
instructions (ADD[I]W/SUBW/SxxW) are required for addition and shifts to
ensure reasonable performance for 32-bit values.
====
(((RV64I, shifts)))
(((RV64I, compares)))

==== Integer Register-Immediate Instructions

include::images/wavedrom/rv64i-base-int.adoc[]
[[rv64i-base-int]]
//.RV64I register-immediate instructions

ADDIW is an RV64I instruction that adds the sign-extended 12-bit
immediate to register _rs1_ and produces the proper sign extension of a
32-bit result in _rd_. Overflows are ignored and the result is the low
32 bits of the result sign-extended to 64 bits. Note, ADDIW _rd, rs1, 0_
writes the sign extension of the lower 32 bits of register _rs1_ into
register _rd_ (assembler pseudoinstruction SEXT.W).

include::images/wavedrom/rv64i-slli.adoc[]
[[rv64i-slli]]
//.RV64I register-immediate (descr ADDIW) instructions

Shifts by a constant are encoded as a specialization of the I-type
format using the same instruction opcode as RV32I. The operand to be
shifted is in _rs1_, and the shift amount is encoded in the lower 6 bits
of the I-immediate field for RV64I. The right shift type is encoded in
bit 30. SLLI is a logical left shift (zeros are shifted into the lower
bits); SRLI is a logical right shift (zeros are shifted into the upper
bits); and SRAI is an arithmetic right shift (the original sign bit is
copied into the vacated upper bits).
(((RV64I, SLLI)))
(((RV64I, SRKIW)))
(((RV64I, SRLIW)))
(((RV64I, RV64I-only)))

include::images/wavedrom/rv64i-slliw.adoc[]
[[rv64i-slliw]]

SLLIW, SRLIW, and SRAIW are RV64I-only instructions that are analogously
defined but operate on 32-bit values and sign-extend their 32-bit
results to 64 bits. SLLIW, SRLIW, and SRAIW encodings with
_imm[5] &#8800; 0_ are reserved.

[NOTE]
====
Previously, SLLIW, SRLIW, and SRAIW with _imm[5] &#8800; 0_
were defined to cause illegal-instruction exceptions, whereas now they
are marked as reserved. This is a backwards-compatible change.
====

include::images/wavedrom/rv64_lui-auipc.adoc[]
[[rv64_lui-auipc]]
//.RV64I register-immediate (descr) instructions

LUI (load upper immediate) uses the same opcode as RV32I. LUI places the
32-bit U-immediate into register _rd_, filling in the lowest 12 bits
with zeros. The 32-bit result is sign-extended to 64 bits.
(((RV64I, LUI)))

AUIPC (add upper immediate to `pc`) uses the same opcode as RV32I. AUIPC
is used to build `pc`-relative addresses and uses the U-type format.
AUIPC forms a 32-bit offset from the U-immediate, filling in the lowest
12 bits with zeros, sign-extends the result to 64 bits, adds it to the
address of the AUIPC instruction, then places the result in register
_rd_.

[NOTE]
====
Note that the set of address offsets that can be formed by pairing LUI
with LD, AUIPC with JALR, etc. in RV64I is
[latexmath:[${-}2^{31}{-}2^{11}$], latexmath:[$2^{31}{-}2^{11}{-}1$]].
====

==== Integer Register-Register Operations

//this diagramdoesn't match the tex specification
include::images/wavedrom/rv64i_int-reg-reg.adoc[]
[[int_reg-reg]]
//.RV64I integer register-register instructions

ADDW and SUBW are RV64I-only instructions that are defined analogously
to ADD and SUB but operate on 32-bit values and produce signed 32-bit
results. Overflows are ignored, and the low 32-bits of the result is
sign-extended to 64-bits and written to the destination register.
(((RV64I-only, ADDW)))
(((RV64I-only, SUBW)))

SLL, SRL, and SRA perform logical left, logical right, and arithmetic
right shifts on the value in register _rs1_ by the shift amount held in
register _rs2_. In RV64I, only the low 6 bits of _rs2_ are considered
for the shift amount.

SLLW, SRLW, and SRAW are RV64I-only instructions that are analogously
defined but operate on 32-bit values and sign-extend their 32-bit
results to 64 bits. The shift amount is given by _rs2[4:0]_.
(((RV64I-only, SLLW)))
(((RV64I-only, SRLW)))
(((RV64I-only, SRAW)))

=== Load and Store Instructions

RV64I extends the address space to 64 bits. The execution environment
will define what portions of the address space are legal to access.

include::images/wavedrom/load_store.adoc[]
[[load_store]]
//.Load and store instructions

The LD instruction loads a 64-bit value from memory into register _rd_
for RV64I.
(((RV64I, LD)))

The LW instruction loads a 32-bit value from memory and sign-extends
this to 64 bits before storing it in register _rd_ for RV64I. The LWU
instruction, on the other hand, zero-extends the 32-bit value from
memory for RV64I. LH and LHU are defined analogously for 16-bit values,
as are LB and LBU for 8-bit values. The SD, SW, SH, and SB instructions
store 64-bit, 32-bit, 16-bit, and 8-bit values from the low bits of
register _rs2_ to memory respectively.

[[rv64i-hints]]
=== HINT Instructions

All instructions that are microarchitectural HINTs in RV32I (see
<<rv32>>) are also HINTs in RV64I.
The additional computational instructions in RV64I expand both the
standard and custom HINT encoding spaces.
(((RV64I, HINT)))

<<rv64i-h>> lists all RV64I HINT code points. 91% of the
HINT space is reserved for standard HINTs, but none are presently
defined. The remainder of the HINT space is designated for custom HINTs;
no standard HINTs will ever be defined in this subspace.

[[rv64i-h]]
.RV64I HINT instructions.
[float="center",align="center",cols="<,<,^,<", options="header", grid="all"]
|===
|Instruction |Constraints |Code Points |Purpose
|LUI |_rd_=_x0_ |latexmath:[$2^{20}$] .9+.^|_Designated for future standard use_

|AUIPC |_rd_=_x0_ |latexmath:[$2^{20}$]

|ADDI |_rd_=_x0_, and either _rs1_≠_x0_ or _imm_≠0  |latexmath:[$2^{17}-1$]

|ANDI |_rd_=_x0_ |latexmath:[$2^{17}$]

|ORI |_rd_=_x0_ |latexmath:[$2^{17}$]

|XORI |_rd_=_x0_ |latexmath:[$2^{17}$]

|ADDIW |_rd_=_x0_ |latexmath:[$2^{17}$]

|ADD |_rd_=_x0_, _rs1_≠_x0_ |latexmath:[$2^{10}-32$]

|ADD |_rd_=_x0_, _rs1_=_x0_, _rs2_≠_x2_-_x5_| 28

|ADD |_rd_=_x0_, _rs1_=_x0_, _rs2_=_x2_-_x5_| 4 | (_rs2_=_x2_) NTL.P1 +
 (_rs2_=_x3_) NTL.PALL +
 (_rs2_=_x4_) NTL.S1 +
 (_rs2_=_x5_) NTL.ALL

|SUB |_rd_=_x0_ |latexmath:[$2^{10}$] .16+.^| _Designated for future standard use_

|AND |_rd_=_x0_ |latexmath:[$2^{10}$]

|OR |_rd_=_x0_ |latexmath:[$2^{10}$]

|XOR |_rd_=_x0_ |latexmath:[$2^{10}$]

|SLL |_rd_=_x0_ |latexmath:[$2^{10}$]

|SRL |_rd_=_x0_ |latexmath:[$2^{10}$]

|SRA |_rd_=_x0_ |latexmath:[$2^{10}$]

|ADDW |_rd_=_x0_ |latexmath:[$2^{10}$]

|SUBW |_rd_=_x0_ |latexmath:[$2^{10}$]

|SLLW |_rd_=_x0_ |latexmath:[$2^{10}$]

|SRLW |_rd_=_x0_ |latexmath:[$2^{10}$]

|SRAW |_rd_=_x0_ |latexmath:[$2^{10}$]

|FENCE |_rd_=_x0_, _rs1_≠_x0_,_fm_=0, and either _pred_=0 or _succ_=0 |latexmath:[$2^{10}-63$]

|FENCE |_rd_≠_x0_, _rs1_=_x0_, _fm_=0, and either _pred_=0 or _succ_=0  |latexmath:[$2^{10}-63$]

|FENCE |_rd_=_rs1_=_x0_, _fm_=0, _pred_=0, _succ_≠0 |15

|FENCE |_pred_=0 or _succ_=0, _pred_≠W, _succ_ =0  | 15

|FENCE |_rd_=_rs1_=_x0_, _fm_=0, _pred_=W, _succ_=0 |1 | PAUSE

|SLTI |_rd_=_x0_ |latexmath:[$2^{17}$] .10+.^|_Designated for custom use_

|SLTIU |_rd_=_x0_ |latexmath:[$2^{17}$]

|SLLI |_rd_=_x0_ |latexmath:[$2^{11}$]

|SRLI |_rd_=_x0_ |latexmath:[$2^{11}$]

|SRAI |_rd_=_x0_ |latexmath:[$2^{11}$]

|SLLIW |_rd_=_x0_ |latexmath:[$2^{10}$]

|SRLIW |_rd_=_x0_ |latexmath:[$2^{10}$]

|SRAIW |_rd_=_x0_ |latexmath:[$2^{10}$]

|SLT |_rd_=_x0_ |latexmath:[$2^{10}$]

|SLTU |_rd_=_x0_ |latexmath:[$2^{10}$]
|===