RISC-V Dependent Features
*************************

RISC-V Options
==============

The following table lists all available RISC-V specific options.

-fpic
-fPIC
     Generate position-independent code

-fno-pic
     Don't generate position-independent code (default)

-march=ISA
     Select the base isa, as specified by ISA.  For example -march=rv32ima. If this option and the architecture attributes aren't set, then assembler will check the default configure setting --with-arch=ISA.

-misa-spec=ISAspec
     Select the default isa spec version.  If the version of ISA isn't set by -march, then assembler helps to set the version according to the default chosen spec.  If this option isn't set, then assembler will check the default configure setting --with-isa-spec=ISAspec.

-mpriv-spec=PRIVspec
     Select the privileged spec version.  We can decide whether the CSR is valid or not according to the chosen spec.  If this option and the privilege attributes aren't set, then assembler will check the default configure setting --with-priv-spec=PRIVspec.

-mabi=ABI
     Selects the ABI, which is either "ilp32" or "lp64", optionally followed by "f", "d", or "q" to indicate single-precision, double-precision, or quad-precision floating-point calling convention, or none to indicate the soft-float calling convention.  Also, "ilp32" can optionally be followed by "e" to indicate the RVE ABI, which is always soft-float.

-mrelax
     Take advantage of linker relaxations to reduce the number of instructions required to materialize symbol addresses. (default)

-mno-relax
     Don't do linker relaxations.

-march-attr
     Generate the default contents for the riscv elf attribute section if the .attribute directives are not set.  This section is used to record the information that a linker or runtime loader needs to check compatibility. This information includes ISA string, stack alignment requirement, unaligned memory accesses, and the major, minor and revision version of privileged specification.

-mno-arch-attr
     Don't generate the default riscv elf attribute section if the .attribute directives are not set.

-mcsr-check
     Enable the CSR checking for the ISA-dependent CRS and the read-only CSR. The ISA-dependent CSR are only valid when the specific ISA is set.  The read-only CSR can not be written by the CSR instructions.

-mno-csr-check
     Don't do CSR checking.

RISC-V Directives
=================

The following table lists all available RISC-V specific directives.

.align SIZE-LOG-2
     Align to the given boundary, with the size given as log2 the number of bytes to align to.

.half VALUE
.word VALUE
.dword VALUE
     Emits a half-word, word, or double-word value at the current position.

.dtprelword VALUE
.dtpreldword VALUE
     Emits a DTP-relative word (or double-word) at the current position.  This is meant to be used by the compiler in shared libraries for DWARF debug info for thread local variables.

.bss
     Sets the current section to the BSS section.

.uleb128 VALUE
.sleb128 VALUE
     Emits a signed or unsigned LEB128 value at the current position.  This only accepts constant expressions, because symbol addresses can change with relaxation, and we don't support relocations to modify LEB128 values at link time.

.option ARGUMENT
     Modifies RISC-V specific assembler options inline with the assembly code. This is used when particular instruction sequences must be assembled with a specific set of options.  For example, since we relax addressing sequences to shorter GP-relative sequences when possible the initial load of GP must not be relaxed and should be emitted as something like

          	.option push
          	.option norelax
          	la gp, __global_pointer$
          	.option pop

     in order to produce after linker relaxation the expected

          	auipc gp, %pcrel_hi(__global_pointer$)
          	addi gp, gp, %pcrel_lo(__global_pointer$)

     instead of just

          	addi gp, gp, 0

     It's not expected that options are changed in this manner during regular use, but there are a handful of esoteric cases like the one above where users need to disable particular features of the assembler for particular code sequences. The complete list of option arguments is shown below:

     push
     pop
          Pushes or pops the current option stack.  These should be used whenever changing an option in line with assembly code in order to ensure the user's command-line options are respected for the bulk of the file being assembled.

     rvc
     norvc
          Enables or disables the generation of compressed instructions.  Instructions are opportunistically compressed by the RISC-V assembler when possible, but sometimes this behavior is not desirable.

     pic
     nopic
          Enables or disables position-independent code generation.  Unless you really know what you're doing, this should only be at the top of a file.

     relax
     norelax
          Enables or disables relaxation.  The RISC-V assembler and linker opportunistically relax some code sequences, but sometimes this behavior is not desirable.

csr-check
no-csr-check
     Enables or disables the CSR checking.

.insn VALUE
.insn VALUE
     This directive permits the numeric representation of an instructions and makes the assembler insert the operands according to one of the instruction formats for .insn (RISC-V-Formats). For example, the instruction add a0, a1, a2 could be written as .insn r 0x33, 0, 0, a0, a1, a2.

.attribute TAG, VALUE
     Set the object attribute TAG to VALUE.

     The TAG is either an attribute number, or one of the following: Tag_RISCV_arch, Tag_RISCV_stack_align, Tag_RISCV_unaligned_access, Tag_RISCV_priv_spec, Tag_RISCV_priv_spec_minor, Tag_RISCV_priv_spec_revision.

RISC-V Assembler Modifiers
==========================

The RISC-V assembler supports following modifiers for relocatable addresses used in RISC-V instruction operands.  However, we also support some pseudo instructions that are easier to use than these modifiers.

%lo(SYMBOL)
     The low 12 bits of absolute address for SYMBOL.

%hi(SYMBOL)
     The high 20 bits of absolute address for SYMBOL.  This is usually used with the %lo modifier to represent a 32-bit absolute address.

          	lui        a0, %hi(SYMBOL)     // R_RISCV_HI20
          	addi       a0, a0, %lo(SYMBOL) // R_RISCV_LO12_I

          	lui        a0, %hi(SYMBOL)     // R_RISCV_HI20
          	load/store a0, %lo(SYMBOL)(a0) // R_RISCV_LO12_I/S

%pcrel_lo(LABEL)
     The low 12 bits of relative address between pc and SYMBOL. The SYMBOL is related to the high part instruction which is marked by LABEL.

%pcrel_hi(SYMBOL)
     The high 20 bits of relative address between pc and SYMBOL. This is usually used with the %pcrel_lo modifier to represent a +/-2GB pc-relative range.

          LABEL:
          	auipc      a0, %pcrel_hi(SYMBOL)    // R_RISCV_PCREL_HI20
          	addi       a0, a0, %pcrel_lo(LABEL) // R_RISCV_PCREL_LO12_I

          LABEL:
          	auipc      a0, %pcrel_hi(SYMBOL)    // R_RISCV_PCREL_HI20
          	load/store a0, %pcrel_lo(LABEL)(a0) // R_RISCV_PCREL_LO12_I/S

     Or you can use the pseudo lla/lw/sw/... instruction to do this.

          	lla  a0, SYMBOL

%got_pcrel_hi(SYMBOL)
     The high 20 bits of relative address between pc and the GOT entry of SYMBOL.  This is usually used with the %pcrel_lo modifier to access the GOT entry.

          LABEL:
          	auipc      a0, %got_pcrel_hi(SYMBOL) // R_RISCV_GOT_HI20
          	addi       a0, a0, %pcrel_lo(LABEL)  // R_RISCV_PCREL_LO12_I

          LABEL:
          	auipc      a0, %got_pcrel_hi(SYMBOL) // R_RISCV_GOT_HI20
          	load/store a0, %pcrel_lo(LABEL)(a0)  // R_RISCV_PCREL_LO12_I/S

     Also, the pseudo la instruction with PIC has similar behavior.

%tprel_add(SYMBOL)
     This is used purely to associate the R_RISCV_TPREL_ADD relocation for TLS relaxation.  This one is only valid as the fourth operand to the normally 3 operand add instruction.

%tprel_lo(SYMBOL)
     The low 12 bits of relative address between tp and SYMBOL.

%tprel_hi(SYMBOL)
     The high 20 bits of relative address between tp and SYMBOL.  This is usually used with the %tprel_lo and %tprel_add modifiers to access the thread local variable SYMBOL in TLS Local Exec.

          	lui        a5, %tprel_hi(SYMBOL)          // R_RISCV_TPREL_HI20
          	add        a5, a5, tp, %tprel_add(SYMBOL) // R_RISCV_TPREL_ADD
          	load/store t0, %tprel_lo(SYMBOL)(a5)      // R_RISCV_TPREL_LO12_I/S

%tls_ie_pcrel_hi(SYMBOL)
     The high 20 bits of relative address between pc and GOT entry.  It is usually used with the %pcrel_lo modifier to access the thread local variable SYMBOL in TLS Initial Exec.

          	la.tls.ie  a5, SYMBOL
          	add        a5, a5, tp
          	load/store t0, 0(a5)

     The pseudo la.tls.ie instruction can be expended to

          LABEL:
          	auipc a5, %tls_ie_pcrel_hi(SYMBOL) // R_RISCV_TLS_GOT_HI20
          	load  a5, %pcrel_lo(LABEL)(a5)     // R_RISCV_PCREL_LO12_I

%tls_gd_pcrel_hi(SYMBOL)
     The high 20 bits of relative address between pc and GOT entry.  It is usually used with the %pcrel_lo modifier to access the thread local variable SYMBOL in TLS Global Dynamic.

          	la.tls.gd  a0, SYMBOL
          	call       __tls_get_addr@plt
          	mv         a5, a0
          	load/store t0, 0(a5)

     The pseudo la.tls.gd instruction can be expended to

          LABEL:
          	auipc a0, %tls_gd_pcrel_hi(SYMBOL) // R_RISCV_TLS_GD_HI20
          	addi  a0, a0, %pcrel_lo(LABEL)     // R_RISCV_PCREL_LO12_I

RISC-V Instruction Formats
==========================

The RISC-V Instruction Set Manual Volume I: User-Level ISA lists 12 instruction formats where some of the formats have multiple variants. For the .insn pseudo directive the assembler recognizes some of the formats. Typically, the most general variant of the instruction format is used by the .insn directive.

The following table lists the abbreviations used in the table of instruction formats:

     opcode   Unsigned immediate or opcode name for 7-bits opcode.
     opcode2   Unsigned immediate or opcode name for 2-bits opcode.
     func7   Unsigned immediate for 7-bits function code.
     func6   Unsigned immediate for 6-bits function code.
     func4   Unsigned immediate for 4-bits function code.
     func3   Unsigned immediate for 3-bits function code.
     func2   Unsigned immediate for 2-bits function code.
     rd   Destination register number for operand x, can be GPR or FPR.
     rd'   Destination register number for operand x,
     only accept s0-s1, a0-a5, fs0-fs1 and fa0-fa5.
     rs1   First source register number for operand x, can be GPR or FPR.
     rs1'   First source register number for operand x,
     only accept s0-s1, a0-a5, fs0-fs1 and fa0-fa5.
     rs2   Second source register number for operand x, can be GPR or FPR.
     rs2'   Second source register number for operand x,
     only accept s0-s1, a0-a5, fs0-fs1 and fa0-fa5.
     simm12   Sign-extended 12-bit immediate for operand x.
     simm20   Sign-extended 20-bit immediate for operand x.
     simm6   Sign-extended 6-bit immediate for operand x.
     uimm8   Unsigned 8-bit immediate for operand x.
     symbol   Symbol or lable reference for operand x.

The following table lists all available opcode name:

C0

C1

C2
     Opcode space for compressed instructions.

LOAD
     Opcode space for load instructions.

LOAD_FP
     Opcode space for floating-point load instructions.

STORE
     Opcode space for store instructions.

STORE_FP
     Opcode space for floating-point store instructions.

AUIPC
     Opcode space for auipc instruction.

LUI
     Opcode space for lui instruction.

BRANCH
     Opcode space for branch instructions.

JAL
     Opcode space for jal instruction.

JALR
     Opcode space for jalr instruction.

OP
     Opcode space for ALU instructions.

OP_32
     Opcode space for 32-bits ALU instructions.

OP_IMM
     Opcode space for ALU with immediate instructions.

OP_IMM_32
     Opcode space for 32-bits ALU with immediate instructions.

OP_FP
     Opcode space for floating-point operation instructions.

MADD
     Opcode space for madd instruction.

MSUB
     Opcode space for msub instruction.

NMADD
     Opcode space for nmadd instruction.

NMSUB
     Opcode space for msub instruction.

AMO
     Opcode space for atomic memory operation instructions.

MISC_MEM
     Opcode space for misc instructions.

SYSTEM
     Opcode space for system instructions.

CUSTOM_0

CUSTOM_1

CUSTOM_2

CUSTOM_3
     Opcode space for customize instructions.

An instruction is two or four bytes in length and must be aligned on a 2 byte boundary. The first two bits of the instruction specify the length of the instruction, 00, 01 and 10 indicates a two byte instruction, 11 indicates a four byte instruction.

The following table lists the RISC-V instruction formats that are available with the .insn pseudo directive:

R type: .insn r opcode, func3, func7, rd, rs1, rs2
     +-------+-----+-----+-------+----+-------------+
     | func7 | rs2 | rs1 | func3 | rd |      opcode |
     +-------+-----+-----+-------+----+-------------+
     31      25    20    15      12   7             0

R type with 4 register operands: .insn r opcode, func3, func2, rd, rs1, rs2, rs3
R4 type: .insn r4 opcode, func3, func2, rd, rs1, rs2, rs3
     +-----+-------+-----+-----+-------+----+-------------+
     | rs3 | func2 | rs2 | rs1 | func3 | rd |      opcode |
     +-----+-------+-----+-----+-------+----+-------------+
     31    27      25    20    15      12   7             0

I type: .insn i opcode, func3, rd, rs1, simm12
I type: .insn i opcode, func3, rd, simm12(rs1)
     +-------------+-----+-------+----+-------------+
     |      simm12 | rs1 | func3 | rd |      opcode |
     +-------------+-----+-------+----+-------------+
     31            20    15      12   7             0

S type: .insn s opcode, func3, rs2, simm12(rs1)
     +--------------+-----+-----+-------+-------------+-------------+
     | simm12[11:5] | rs2 | rs1 | func3 | simm12[4:0] |      opcode |
     +--------------+-----+-----+-------+-------------+-------------+
     31             25    20    15      12            7             0

B type: .insn s opcode, func3, rs1, rs2, symbol
SB type: .insn sb opcode, func3, rs1, rs2, symbol
     +------------+--------------+-----+-----+-------+-------------+-------------+--------+
     | simm12[12] | simm12[10:5] | rs2 | rs1 | func3 | simm12[4:1] | simm12[11]] | opcode |
     +------------+--------------+-----+-----+-------+-------------+-------------+--------+
     31          30            25    20    15      12           7            0

U type: .insn u opcode, rd, simm20
     +---------------------------+----+-------------+
     |                    simm20 | rd |      opcode |
     +---------------------------+----+-------------+
     31                          12   7             0

J type: .insn j opcode, rd, symbol
UJ type: .insn uj opcode, rd, symbol
     +------------+--------------+------------+---------------+----+-------------+
     | simm20[20] | simm20[10:1] | simm20[11] | simm20[19:12] | rd |      opcode |
     +------------+--------------+------------+---------------+----+-------------+
     31           30             21           20              12   7             0

CR type: .insn cr opcode2, func4, rd, rs2
     +---------+--------+-----+---------+
     |   func4 | rd/rs1 | rs2 | opcode2 |
     +---------+--------+-----+---------+
     15        12       7     2        0

CI type: .insn ci opcode2, func3, rd, simm6
     +---------+-----+--------+-----+---------+
     |   func3 | imm | rd/rs1 | imm | opcode2 |
     +---------+-----+--------+-----+---------+
     15        13    12       7     2         0

CIW type: .insn ciw opcode2, func3, rd, uimm8
     +---------+--------------+-----+---------+
     |   func3 |          imm | rd' | opcode2 |
     +---------+--------------+-----+---------+
     15        13             7     2         0

CA type: .insn ca opcode2, func6, func2, rd, rs2
     +---------+----------+-------+------+--------+
     |   func6 | rd'/rs1' | func2 | rs2' | opcode |
     +---------+----------+-------+------+--------+
     15        10         7       5      2        0

CB type: .insn cb opcode2, func3, rs1, symbol
     +---------+--------+------+--------+---------+
     |   func3 | offset | rs1' | offset | opcode2 |
     +---------+--------+------+--------+---------+
     15        13       10     7        2         0

CJ type: .insn cj opcode2, symbol
     +---------+--------------------+---------+
     |   func3 |        jump target | opcode2 |
     +---------+--------------------+---------+
     15        13             7     2         0

For the complete list of all instruction format variants see The RISC-V Instruction Set Manual Volume I: User-Level ISA.

RISC-V Object Attribute
=======================

RISC-V attributes have a string value if the tag number is odd and an integer value if the tag number is even.

Tag_RISCV_stack_align (4)
     Tag_RISCV_strict_align records the N-byte stack alignment for this object.  The default value is 16 for RV32I or RV64I, and 4 for RV32E.

     The smallest value will be used if object files with different Tag_RISCV_stack_align values are merged.

Tag_RISCV_arch (5)
     Tag_RISCV_arch contains a string for the target architecture taken from the option -march.  Different architectures will be integrated into a superset when object files are merged.

     Note that the version information of the target architecture must be presented explicitly in the attribute and abbreviations must be expanded.  The version information, if not given by -march, must be in accordance with the default specified by the tool.  For example, the architecture RV32I has to be recorded in the attribute as RV32I2P0 in which 2P0 stands for the default version of its base ISA.  On the other hand, the architecture RV32G has to be presented as RV32I2P0_M2P0_A2P0_F2P0_D2P0 in which the abbreviation G is expanded to the IMAFD combination with default versions of the standard extensions.

Tag_RISCV_unaligned_access (6)
     Tag_RISCV_unaligned_access is 0 for files that do not allow any unaligned memory accesses, and 1 for files that do allow unaligned memory accesses.

Tag_RISCV_priv_spec (8)

Tag_RISCV_priv_spec_minor (10)

Tag_RISCV_priv_spec_revision (12)
     Tag_RISCV_priv_spec contains the major/minor/revision version information of the privileged specification.  It will report errors if object files of different privileged specification versions are merged.