[[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 <>. 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 <>). === 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] ≠ 0_ are reserved. [NOTE] ==== Previously, SLLIW, SRLIW, and SRAIW with _imm[5] ≠ 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 <>) are also HINTs in RV64I. The additional computational instructions in RV64I expand both the standard and custom HINT encoding spaces. (((RV64I, HINT))) <> 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}$] |===