From 0814a4c8cdc76cb3600680dc9a317ff59666fe5b Mon Sep 17 00:00:00 2001 From: Ana Pazos Date: Thu, 15 Aug 2024 19:16:59 -0700 Subject: [PATCH] Migration to RISC-V specifications template in asciidoc TODOs: - Fix rendering of Chinese characters in the generated PDF file. Characters referenced in https://github.com/riscv-non-isa/riscv-toolchain-conventions#list-of-vendor-prefixes - Fix reference to RISC-V Assembly Programmer's Manual after migration to RVI template is merged. --- .gitignore | 1 + .gitmodules | 3 + .pre-commit-config.yaml | 26 ++ CHANGELOG.md | 8 + CODE_OF_CONDUCT.md | 2 + CONTRIBUTING.md | 58 +++++ GOVERNANCE.md | 8 + LICENSE | 2 +- MAINTAINERS.md | 5 + Makefile | 88 +++++++ README.adoc | 107 ++++++++ README.mkd | 455 --------------------------------- docs-resources | 1 + src/contributors.adoc | 3 + src/preamble.adoc | 47 ++++ src/prelude.adoc | 96 +++++++ src/riscv-toolchain.adoc | 8 + src/toolchain-conventions.adoc | 416 ++++++++++++++++++++++++++++++ 18 files changed, 878 insertions(+), 456 deletions(-) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 .pre-commit-config.yaml create mode 100644 CHANGELOG.md create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 GOVERNANCE.md create mode 100644 MAINTAINERS.md create mode 100644 Makefile create mode 100644 README.adoc delete mode 100644 README.mkd create mode 160000 docs-resources create mode 100644 src/contributors.adoc create mode 100644 src/preamble.adoc create mode 100644 src/prelude.adoc create mode 100644 src/riscv-toolchain.adoc create mode 100644 src/toolchain-conventions.adoc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d9b4f01 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/build/* diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..cde1eb5 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "docs-resources"] + path = docs-resources + url = https://github.com/riscv/docs-resources.git diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..63fae1b --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,26 @@ +--- +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-json + - id: check-symlinks + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace + args: [--markdown-linebreak-ext=md] + + - repo: local + hooks: + - id: forbidden-file-extensions + name: forbidden-file-extensions + entry: disallow these file extensions + language: fail + # Disallow other asciidoc extensions except .adoc + files: .*\.(asciidoc|asc)$ + + - repo: https://github.com/jumanjihouse/pre-commit-hook-yamlfmt + rev: 0.2.3 + hooks: + - id: yamlfmt + args: [--mapping, '2', --sequence, '4', --offset, '2'] diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..11bddf3 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..f0c2967 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,2 @@ +# RISC-V Code of Conduct +All RISC-V International projects are governed by the RISC-V Code of Conduct found at https://riscv.org/community/community-code-of-conduct/. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..1d98c72 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,58 @@ +# Contribution Guidelines + +As an open-source project, we appreciate and encourage community members to submit patches directly to the project. To maintain a well-organized development environment, we have established standards and methods for submitting changes. This document outlines the process for submitting patches to the project, ensuring that your contribution is swiftly incorporated into the codebase. + +# Licensing + +Licensing is crucial for open-source projects, as it guarantees that the software remains available under the conditions specified by the author. + +This project employs the Creative Commons Attribution 4.0 International license, which can be found in the LICENSE file within the project's repository. + +Licensing defines the rights granted to you as an author by the copyright holder. It is essential for contributors to fully understand and accept these licensing rights. In some cases, the copyright holder may not be the contributor, such as when the contributor is working on behalf of a company. + +# Developer Certificate of Origin (DCO) +To uphold licensing criteria and demonstrate good faith, this project mandates adherence to the Developer Certificate of Origin (DCO) process. + +The DCO is an attestation appended to every contribution from each author. In the commit message of the contribution (explained in greater detail later in this document), the author adds a Signed-off-by statement, thereby accepting the DCO. + +When an author submits a patch, they affirm that they possess the right to submit the patch under the designated license. The DCO agreement is displayed below and at https://developercertificate.org. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b), or (c), and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. + +# DCO Sign-Off Methods +The DCO necessitates the inclusion of a sign-off message in the following format for each commit within the pull request: + +Signed-off-by: Stephano Cetola + +Please use your real name in the sign-off message. + +You can manually add the DCO text to your commit body or include either -s or --signoff in your standard Git commit commands. If you forget to incorporate the sign-off, you can also amend a previous commit with the sign-off by executing git commit --amend -s. If you have already pushed your changes to GitHub, you will need to force push your branch afterward using git push -f. + +Note: + +Ensure that the name and email address associated with your GitHub account match the name and email address in the Signed-off-by line of your commit message. diff --git a/GOVERNANCE.md b/GOVERNANCE.md new file mode 100644 index 0000000..115a37f --- /dev/null +++ b/GOVERNANCE.md @@ -0,0 +1,8 @@ +# Governance +This project is governed by the Toolchains SIG. + +The group can be joined by RISC-V members at: https://lists.riscv.org/g/sig-toolchains. + +Mailing list archives are available at: https://lists.riscv.org/g/sig-toolchains/topics. + +Community meetings schedule at: https://tech.riscv.org/calendar. diff --git a/LICENSE b/LICENSE index 06c608d..2f244ac 100644 --- a/LICENSE +++ b/LICENSE @@ -49,7 +49,7 @@ exhaustive, and do not form part of our licenses. such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. More_considerations - for the public: + for the public: wiki.creativecommons.org/Considerations_for_licensees ======================================================================= diff --git a/MAINTAINERS.md b/MAINTAINERS.md new file mode 100644 index 0000000..861f6bd --- /dev/null +++ b/MAINTAINERS.md @@ -0,0 +1,5 @@ +# Maintainers +This project is maintained by the following people: + +- Christoph Müllner ([cmuellner](https://github.com/cmuellner)) +- Ana Pazos ([apazos](https://github.com/apazos)) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3dcbbec --- /dev/null +++ b/Makefile @@ -0,0 +1,88 @@ +# Makefile for RISC-V Toolchain Conventions. +# +# This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 +# International License. To view a copy of this license, visit +# http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to +# Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. +# +# SPDX-License-Identifier: CC-BY-SA-4.0 +# +# Description: +# +# This Makefile is designed to automate the process of building and packaging +# the RISC-V Toolchain Conventions. + +DOCS := \ + riscv-toolchain.adoc + +DATE ?= $(shell date +%Y-%m-%d) +DOCKER_IMG := riscvintl/riscv-docs-base-container-image:latest + +ifneq ($(SKIP_DOCKER),true) + DOCKER_CMD := docker run --rm -v ${PWD}:/build -w /build \ + ${DOCKER_IMG} \ + /bin/sh -c + DOCKER_QUOTE := " +endif + +SRC_DIR := src +BUILD_DIR := build + +DOCS_PDF := $(DOCS:%.adoc=%.pdf) +DOCS_HTML := $(DOCS:%.adoc=%.html) + +XTRA_ADOC_OPTS := +ASCIIDOCTOR_PDF := asciidoctor-pdf +ASCIIDOCTOR_HTML := asciidoctor +OPTIONS := --trace \ + -a compress \ + -a revdate=${DATE} \ + -a pdf-style=docs-resources/themes/risc-v_spec-pdf.yml \ + -a pdf-fontsdir=docs-resources/fonts \ + $(XTRA_ADOC_OPTS) \ + -D build \ + --failure-level=ERROR +REQUIRES := --require=asciidoctor-lists + +.PHONY: all build clean build-container build-no-container build-docs + +all: build + +build-docs: $(DOCS_PDF) $(DOCS_HTML) + +vpath %.adoc $(SRC_DIR) + +%.pdf: %.adoc + $(DOCKER_CMD) $(DOCKER_QUOTE) $(ASCIIDOCTOR_PDF) $(OPTIONS) $(REQUIRES) $< $(DOCKER_QUOTE) + +%.html: %.adoc + $(DOCKER_CMD) $(DOCKER_QUOTE) $(ASCIIDOCTOR_HTML) $(OPTIONS) $(REQUIRES) $< $(DOCKER_QUOTE) + +build: + @echo "Checking if Docker is available..." + @if command -v docker >/dev/null 2>&1 ; then \ + echo "Docker is available, building inside Docker container..."; \ + $(MAKE) build-container; \ + else \ + echo "Docker is not available, building without Docker..."; \ + $(MAKE) build-no-container; \ + fi + +build-container: + @echo "Starting build inside Docker container..." + $(MAKE) build-docs + @echo "Build completed successfully inside Docker container." + +build-no-container: + @echo "Starting build..." + $(MAKE) SKIP_DOCKER=true build-docs + @echo "Build completed successfully." + +# Update docker image to latest +docker-pull-latest: + docker pull ${DOCKER_IMG} + +clean: + @echo "Cleaning up generated files..." + rm -rf $(BUILD_DIR) + @echo "Cleanup completed." diff --git a/README.adoc b/README.adoc new file mode 100644 index 0000000..9f68523 --- /dev/null +++ b/README.adoc @@ -0,0 +1,107 @@ += RISC-V Toolchain Conventions + +== License + +This work is licensed under a Creative Commons Attribution 4.0 International License (CC-BY-4.0). For details, see the link:LICENSE[LICENSE] file. + +== Maintainers + +The list of maintainers of this specification is maintained in the link:MAINTAINERS.md[MAINTAINERS] file. + +== Contributors + +The list of contributors to this specification is maintained in the link:src/contributors.adoc[contributors] file. + +For guidelines on how to contribute, refer to the link:CONTRIBUTING.md[CONTRIBUTING] file. + +== Governance + +The governance for this project is defined in the link:GOVERNANCE.md[GOVERNANCE] file. + +Community information, including meeting (if held) and mailing lists are detailed in this file. + +== Building the Document + +=== Directory Structure + +The following directories are used to organize the contents of this repo: + +* `dependencies/`: software dependencies needed to build the specification +* `docs-resources/`: resources for all specifications sourced from link:.gitmodules[git submodule] +* `src/`: source files for the specification +* `build/`: default directory where the build artifacts are generated + +=== Prerequisites + +To build the document, you'll need the following tools installed on your system: + +* Make +* asciiDoctor-pdf +* Docker + +=== Cloning the Repository + +```shell +git clone --recurse-submodules https://github.com/riscv-non-isa/riscv-toolchain-conventions.git +``` + +All in one single line: + +```shell +git clone --recurse-submodules https://github.com/riscv-non-isa/riscv-toolchain-conventions.git && cd riscv-toolchain-conventions && git submodule update --init --recursive + +``` + +=== Building the Documentation + +To start the build process, run: + +```shell +cd ./riscv-toolchain-conventions && make build +``` + +The link:Makefile[] script will check the availability of Docker on your system: + +* If Docker is available, the documentation will be built inside a Docker container using the image riscvintl/riscv-docs-base-container-image:latest. This ensures a consistent build environment across different systems. +* If Docker is not available, the documentation will be built directly on your system using the installed tools. + +The documentation is generated from the AsciiDoctor source files in your project. The primary source file is specified by the `HEADER_SOURCE` variable in the Makefile. + +The build process utilizes several options, including theming and font settings, and generates a PDF document as output. + +=== Cleaning up + +To clean up the generated files, run: + +```shell +make clean +``` + +== Enabling pre-commit checks locally + +The repository has some basic commit checks set up with https://pre-commit.com/[pre-commit] that will be enforced by the GitHub CI. +To ensure these checks are also run in the local repository while making changes the following can be done: + +.Installing pre-commit tool +[source,shell] +---- +# Do once on your system +pip3 install pre-commit +---- + +.Installing pre-commit git hook in repo +[source,shell] +---- +# Do once in local repo +pre-commit install +---- + +Rather than doing the above `pre-commit install` in every repo that uses it, you can do it https://pre-commit.com/#automatically-enabling-pre-commit-on-repositories[once on your system.] + +When enabling additional checks https://pre-commit.com/#plugins[by editing .pre-commit-config.yaml], it is recommended running the newly added check on all files in the repository. This can be done with the following command: + +.Running all pre-commit hooks on all files +[source,shell] +---- +pre-commit run --all-files +---- diff --git a/README.mkd b/README.mkd deleted file mode 100644 index 0efe165..0000000 --- a/README.mkd +++ /dev/null @@ -1,455 +0,0 @@ -# RISC-V Toolchain Conventions - -## Copyright and license information - -This document is authored by a [range of -contributors](https://github.com/riscv-non-isa/riscv-toolchain-conventions/graphs/contributors). - -Licensed under the Creative Commons Attribution 4.0 International License -(CC-BY 4.0). The full license text is available at -https://creativecommons.org/licenses/by/4.0/. - -## Aims - -This effort aims to document the expected behaviour and command-line interface -of RISC-V toolchains. In doing so, we can provide an avenue for members of the -GNU and LLVM communities to collaborate on standardising and extending these -conventions. A diverse range of RISC-V implementations and custom extensions -will inevitably result in vendor-specific toolchains being created and -distributed. By describing a clear preferred path for exposing vendor-specific -extensions or modifications, we can try to increase the likelihood that these -vendor toolchain distributions have a common interface and aren't gratuitously -different. - -## Status and roadmap - -This document is a work-in-progress, and contains many sections that serve -mainly to enumerate current gaps or oddities. The plan is to seek feedback and -further develop the proposal with the help of the RISC-V community, then to -seek input from the wider GCC and Clang developer communities for extensions -or changes beyond the current set of command-line options supported by GCC. - -See the [issues -list](https://github.com/riscv-non-isa/riscv-toolchain-conventions/issues) to -discuss any of the problems or TODO items described in this document. - -This document is currently targeted at toolchain implementers and developers, -but over time we hope it will also become a useful reference for RISC-V -toolchain users. - -## See also -* [RISC-V user-level ISA specification](https://riscv.org/technical/specifications/) - (Document Version 20191213) -* [RISC-V ELF psABI -specification](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc) -* [RISC-V Assembly Programmer's -Manual](https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md) -* [GCC RISC-V option -documentation](https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Options.html) - -## Specifying the target ISA with -march - -The compiler and assembler both accept the `-march` flag to specify the target -ISA, e.g. `rv32imafd`. The abbreviation `g` can be used to represent either -`IMAFD` (when targeting RISC-V ISA specification version 2.2 or earlier) or -`IMAFD_Zicsr_Zifencei` (version 20190608 or later) base and extensions, -e.g. `-march=rv64g`. A target `-march` which includes floating point -instructions implies a hardfloat calling convention, but can be overridden -using the `-mabi` flag (see the next section). - -The ISA subset naming conventions and canonical order are described in -Chapter `ISA Extension Naming Conventions` of the RISC-V user-level ISA -specification. However, tools do not currently follow this specification -(input is case sensitive, ...). - -The rule of ISA string become more complicated, due to extension implication -rules and more extensions added into RISC-V, the canonical order is non-obvious -to humans, so tools should accept the ISA string in non-canonical order to reduce -the burden of remembering the canonical order. - -Detailed rules for ISA string: - -1. First letter must be `i`, `e` or `g`. -2. Single-letter may be non-canonical order. -3. Multi-letter may be non-canonical order. -4. Multi-letter must be separated by underscore. -5. Version separator(`p`) has higher priority than `p` extension. - -Example: -``` -rv32ima_zicsr # Valid ISA string. -rv32i_zicsr_m # Valid ISA string. -rv32i_zicsr_ma # Valid ISA string. -rv32imac # Valid ISA string. -rv32mai # Invalid ISA string, first letter must be `i`, `e` or `g`. -rv32i_zicsrzifence # Valid ISA string, but it will interpreted as rv32 - # with base extension and `zicsrzifence` extension - # rather than `zicsr` and `zifence` extensions. -rv32i2p1 # Valid ISA string, it recognized as `I` extension with - # version 2.1 rather than `I` extension with with version - # 2.0 and `P` extension with 1.0. -``` - -If the 'C' (compressed) instruction set extension is targeted, the compiler -will generate compressed instructions where possible. - -NOTE: Single-letter extension with version (e.g. `m2p0`) is still treated as - a single-letter extension, it won't be treated as a multi-letter extension. - -NOTE: Any output of ISA string like `Tag_RISCV_arch` must be canonical order. - -NOTE: Cross-tool argument are highly recommended to be passed in canonical order - for backward compatibility. - -### Issues for consideration -* Whether `riscv32` and `riscv64` should be accepted as synonyms for `rv32` -and `rv64`. -* Whether the `-march` string should be parsed case insensitively. -* Exposing the ability to specify version numbers for a target extension. -* Specifying non-standard extensions. The ISA specification suggests naming -such as `rv32gXfirstext_Xsecondext`. In GCC or Clang it would be more -conventional to give a string such as `rv32g+firstext+secondext`. - -## Specifying the target ABI with -mabi - -RISC-V compilers support the following ABIs, which can be specified using -`-mabi`: - -* [`ilp32`](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#abi-ilp32): - int, long, pointers are 32-bit. GPRs and the stack are used for - parameter passing. -* [`ilp32f`](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#abi-ilp32f): - int, long, pointers are 32-bit. GPRs, 32-bit FPRs, and the stack are - used for parameter passing. -* [`ilp32d`](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#abi-ilp32d): - int, long, pointers are 32-bit. GPRs, 64-bit FPRs and the stack are - used for parameter passing. -* [`lp64`](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#abi-lp64): - long, pointers are 64-bit. GPRs and the the stack are used for - parameter passing. -* [`lp64f`](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#abi-lp64f): - long, pointers are 64-bit. GPRs, 32-bit FPRs, and the stack are used for - parameter passing. -* [`lp64d`](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#abi-lp64d): - long, pointers are 64-bit. GPRs, 64-bit FPRs, and the stack are used for - parameter passing. - -See the [RISC-V ELF -psABI](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc) -for more information on these ABIs. - -The default value for `-mabi` is system dependent. For cross-compilation, both -`-march` and `-mabi` should be specified. An error will be produced for -impossible combinations of `-march` and `-mabi` such as `-march=rv32i` and -`-mabi=ilp32f`. - -### Issues for consideration -* Should the `-mabi` string be parsed case insensitively? -* How should the RV32E ABI be specified? `ilp32e`? - -## Specifying the target code model with -mcmodel - -The target code model indicates constraints on symbols which the compiler can -exploit these constraints to generate more efficient code. Three code models are -currently defined for RISC-V: - -* `-mcmodel=medlow`. The program and its statically defined symbols must lie -within a single 2GiB address range, between the absolute addresses -2GiB and -+2GiB. `lui` and `addi` pairs are used to generate addresses. -* `-mcmodel=medany`. The program and its statically defined symbols must lie -within a single 4GiB address range. `auipc` and `addi` pairs are used to -generate addresses. -* Use of any PIC or PIE option (e.g. -fpic, -fPIC, -fpie or -fPIE) will enable -the medium position independent code model. This model is similar to the medium -any code model, but uses the global offset table (GOT) for non-local symbol -addresses. - -NOTE: When PIC or PIE mode enabled the `-mcmodel=medlow` will be suppressed. - -RISC-V psABI has a contain sections to describe the code model: -- [Medium low code model](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#medium-low-code-model): -mcmodel=medlow -- [Medium any code model](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#medium-low-code-model): -mcmodel=medany -- [Medium position independent code model](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#medium-position-independent-code-model): -fpic, -fPIC, -fpie or -fPIE. - -## Disassembler (objdump) behaviour - -A RISC-V ELF binary is not currently self-describing, in the sense that it -doesn't contain enough information to determine which variant of the RISC-V -architecture is being targeted. GNU objdump will currently attempt disassemble -any instruction whose encoding matches one of the standard RV32/RV64GC -extensions. - -objdump will default to showing pseudoinstructions and ABI register names. The -`numeric` disassembler argument can be used to use architectural register -names such as `x10`, while the `no-aliases` disassembler argument will ensure -only canonical instructions rather than pseudoinstructions or aliases are -printed. These arguments are specified using `-M`, e.g. `-M numeric` or `-M -numeric,no-aliases`. - -Perhaps surprisingly, the disassembler will default to hiding the difference -between compressed (16-bit) instructions and their 32-bit equivalent. e.g. -`c.addi sp, -16` will be printed as `addi sp, sp, -16`. - -### Issues for consideration -* The current GNU objdump behaviour will not provide useful results for cases -where non-standard extensions are implemented which reuse some of the standard -extension's encoding space. Making RISC-V ELF files self-describing (as -discussed [here](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/47)) would -avoid this problem. -* Would it be useful to have separate flags that control the printing of -pseudoinstructions and whether compressed instructions are printed directly or -not? - -## Assembler behaviour - -See the [RISC-V Assembly Programmer's -Manual](https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md) -for details on the syntax accepted by the assembler. - -The assembler will produce compressed instructions whenever possible if the -targeted RISC-V variant includes support for the 'C' compressed instruction -set. - -### Issues for consideration -* There is currently no way to enable support for the 'C' ISA extension, but to -disable the automatic 'compression' of instructions. - -## C/C++ preprocessor definitions - -* `__riscv`: defined for any RISC-V target. Older versions of the GCC -toolchain defined `__riscv__`. -* `__riscv_xlen`: 32 for RV32 and 64 for RV64. -* `__riscv_float_abi_soft`, `__riscv_float_abi_single`, -`__riscv_float_abi_double`: one of these three will be defined, depending on -target ABI. -* `__riscv_cmodel_medlow`, `__riscv_cmodel_medany`: one of these two will be -defined, depending on the target code model. -* `__riscv_mul`: defined when targeting the 'M' ISA extension. -* `__riscv_muldiv`: defined when targeting the 'M' ISA extension and -`-mno-div` has not been used. -* `__riscv_div`: defined when targeting the 'M' ISA extension and `-mno-div` -has not been used. -* `__riscv_atomic`: defined when targeting the 'A' ISA extension. -* `__riscv_flen`: 32 when targeting the 'F' ISA extension (but not 'D') and 64 -when targeting 'FD'. -* `__riscv_fdiv`: defined when targeting the 'F' or 'D' ISA extensions and -`-mno-fdiv` has not been used. -* `__riscv_fsqrt`: defined when targeting the 'F' or 'D' ISA extensions and -`-mno-fdiv` has not been used. -* `__riscv_compressed`: defined when targeting the 'C' ISA extension. - -### Issues for consideration -* What should the naming convention be for defines that indicate support for -non-standard extensions? -* What additional information could/should be exposed via preprocessor -defines? - -## Specifying stack alignment - -The default stack alignment is 16 bytes in RV32I and RV64I, and 4 bytes on -RV32E. There is not currently a way to specify an alternative stack alignment, -but the `-mpreferred-stack-boundary` and `-mincoming-stack-boundary` flags -supported by GCC on X86 could be adopted. - -## Save restore support - -The save restore optimization is enabled through the option `-msave-restore` -and reduces the amount of code in the prologue and epilogue by using -library functions instead of inline code to save and restore callee saved -registers. The library functions are provided in the emulation library and -have the following signatures: - -* `void __riscv_save_(void)` -* `void __riscv_restore_(void)` -* `void __riscv_restore_tailcall_(void *tail /* passed in t1 */)` (LLVM/compiler-rt only) - -`` is a value between 0 and 12 and corresponds to the number of -registers between `s0` and `s11` that are saved/restored. The return -address register `ra` is always included in the registers saved and restored. - -The `__riscv_save_` functions are called from the prologue, using `t0` as -the link register to avoid clobbering `ra`. They allocate stack space for the -registers and then save `ra` and the appropriate number of registers from -`s0`-`s11`. The `__riscv_restore_` functions are tail-called from the -epilogue. They restore the saved registers, deallocate the stack space for the -register, and then perform a return through the restored value of `ra`. - -`__riscv_restore_tailcall_` are additional entry points used when the -epilogue of the called function ends in a tail-call. Unlike -`__riscv_restore_` these are also provided the address of the function -which was originally tail-called as an argument, and after restoring -registers they make a tail-call through that argument instead of returning. -Note that the address of the function to tail-call is provided in register `t1`, -which differs from the normal calling convention. - -As of November 2021 the additional tail-call entry points are only -implemented in compiler-rt, and calls will only be generated by LLVM -when the option `-mllvm -save-restore-tailcall` is specified. - -## Conventions for vendor extensions - -Support for custom instruction set extensions are an important part of RISC-V, -with large encoding spaces reserved of vendor extensions. - -However, there are no official guidelines on naming the mnemonics. This section -defines guidelines which vendors are expected to follow if upstreaming support -for their extensions. Although vendor-provided toolchains are free to make -different choices, they are strongly urged to align with these guidelines in -order to ensure there is a straightforward path for upstreaming in the future. - -NOTE: Open source toolchain maintainer has final say on accepting vendor -extension, comply with this conventions isn't guarantee upstream will accept. - -### Vendor extension naming scheme - -According to the RISC-V ISA spec, non-standard extensions are named using a single `X` -followed by an alphabetical name and an optional version number. - -To make it easier to identify and prevent naming conflict, vendor extensions -should start with a vendor name, which could be an abbreviation of the full name. - -For example: -- `XVentanaCondOps` from Ventana -- `Xsfcflushdlone` from SiFive - -### Assembly mnemonic - -In order to avoid confusion between standard extension and other vendor -extensions, instruction mnemonics from vendor extensions must have a -prefix corresponding to the vendor's name. - -The vendor prefix should be at least two letters long - -e.g. `sf.` for SiFive, `vt.` for Ventana. No central registration with RISC-V -International or elsewhere is required before the prefix is used. - -NOTE: Although no centralized registration is required, vendors should add the -vendor prefix to the table *IF* vendors are interested to upstream their -extension to open source toolchain like LLVM or GNU toolchain. - -Vendors should also aim to follow the conventions used for naming mnemonics -in the ratified base ISA and extensions (e.g. the use of 'w', 'd', -'u', and 's' suffixes). - -### CSR naming scheme - -Vendors may define their own CSRs within the custom read-only CSR address range -specified in the RISC-V ISA spec. However, to avoid conflicts, each vendor CSR -must include a prefix corresponding to the vendor's name. - -The vendor prefix should match the prefix defined in assembly mnemonics and be -separated by a dot, e.g., `th.vxrm`. - -### List of vendor prefixes - - -Vendor | Prefix | URL -:--------------------- | :-------------- | :------------- -Open Hardware Group | cv | https://www.openhwgroup.org/ -SiFive | sf | https://www.sifive.com/ -T-Head | th | https://www.t-head.cn/ -Ventana Micro Systems | vt | https://www.ventanamicro.com/ -Nuclei | xl | https://nucleisys.com/ - -- NOTE: Vendor prefixes are case-insensitive. -- NOTE: The Nuclei instruction prefix `xl` is an abbreviation of "XinLai", which is the Chinese pronunciation of Nuclei(芯来). - -NOTE: OpenHW cores are all branded as CORE-V, hence the prefix. - -### List of vendor identifiers - -Vendor identifiers are dummy symbols used in the corresponding `R_RISCV_VENDOR` -relocation (irrespective of ELF class/XLEN) and must be unique amongst all -vendors providing custom relocations. Vendor identifiers may be suffixed with a -tag to provide extra relocations for a given vendor. - -Vendor | Symbol | -:--------------------- | :------ | -Open Hardware Group | COREV | - -### List of vendor extensions - -Vendor | Name | Version | ISA Document -:------ | :-------------- | :------------- | :--------------- -OpenHW | Xcvalu | 1.0.0 | [CORE-V Instruction Set Extensions](https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst) -OpenHW | Xcvbi | 1.0.0 | [CORE-V Instruction Set Extensions](https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst) -OpenHW | Xcvbitmanip | 1.0.0 | [CORE-V Instruction Set Extensions](https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst) -OpenHW | Xcvelw | 1.0.0 | [CORE-V Instruction Set Extensions](https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst) -OpenHW | Xcvhwlp | 1.0.0 | [CORE-V Instruction Set Extensions](https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst) -OpenHW | Xcvmac | 1.0.0 | [CORE-V Instruction Set Extensions](https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst) -OpenHW | Xcvmem | 1.0.0 | [CORE-V Instruction Set Extensions](https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst) -OpenHW | Xcvsimd | 1.0.0 | [CORE-V Instruction Set Extensions](https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst) -SiFive | XSFvqmaccdod | 1.0 | [SiFive Int8 Matrix Multiplication Extensions Specification](https://www.sifive.com/document-file/sifive-int8-matrix-multiplication-extensions-specification) -SiFive | XSFvqmaccqoq | 1.0 | [SiFive Int8 Matrix Multiplication Extensions Specification](https://www.sifive.com/document-file/sifive-int8-matrix-multiplication-extensions-specification) -SiFive | XSFvfnrclipxfqf | 1.0 | [FP32-to-int8 Ranged Clip Instructions (Xsfvfnrclipxfqf) Extension Specification](https://www.sifive.com/document-file/fp32-to-int8-ranged-clip-instructions) -SiFive | Xsfvfwmaccqqq | 1.0 | [Matrix Multiply Accumulate Instruction (Xsfvfwmaccqqq) Extension Specification](https://www.sifive.com/document-file/matrix-multiply-accumulate-instruction) -SiFive | XSFVCP | 1.0 | [SiFive Vector Coprocessor Interface Software Specification](https://sifive.cdn.prismic.io/sifive/c3829e36-8552-41f0-a841-79945784241b_vcix-spec-software.pdf) -T-Head | XTheadCmo | 1.0 | [T-Head ISA extension specification](https://github.com/T-head-Semi/thead-extension-spec/releases/latest) -T-Head | XTheadBa | 1.0 | [T-Head ISA extension specification](https://github.com/T-head-Semi/thead-extension-spec/releases/latest) -T-Head | XTheadBb | 1.0 | [T-Head ISA extension specification](https://github.com/T-head-Semi/thead-extension-spec/releases/latest) -T-Head | XTheadBs | 1.0 | [T-Head ISA extension specification](https://github.com/T-head-Semi/thead-extension-spec/releases/latest) -T-Head | XTheadCondMov | 1.0 | [T-Head ISA extension specification](https://github.com/T-head-Semi/thead-extension-spec/releases/latest) -T-Head | XTheadFMemIdx | 1.0 | [T-Head ISA extension specification](https://github.com/T-head-Semi/thead-extension-spec/releases/latest) -T-Head | XTheadFmv | 1.0 | [T-Head ISA extension specification](https://github.com/T-head-Semi/thead-extension-spec/releases/latest) -T-Head | XTheadInt | 1.0 | [T-Head ISA extension specification](https://github.com/T-head-Semi/thead-extension-spec/releases/latest) -T-Head | XTheadMac | 1.0 | [T-Head ISA extension specification](https://github.com/T-head-Semi/thead-extension-spec/releases/latest) -T-Head | XTheadMemPair | 1.0 | [T-Head ISA extension specification](https://github.com/T-head-Semi/thead-extension-spec/releases/latest) -T-Head | XTheadMemIdx | 1.0 | [T-Head ISA extension specification](https://github.com/T-head-Semi/thead-extension-spec/releases/latest) -T-Head | XTheadSync | 1.0 | [T-Head ISA extension specification](https://github.com/T-head-Semi/thead-extension-spec/releases/latest) -T-Head | XTheadVector | 1.0 | [T-Head ISA extension specification](https://github.com/T-head-Semi/thead-extension-spec/releases/latest) -Ventana | XVentanaCondOps | 1.0 | [VTx-family custom instructions](https://github.com/ventanamicro/ventana-custom-extensions/releases/download/v1.0.0/ventana-custom-extensions-v1.0.0.pdf) - -NOTE: Vendor extension names are case-insensitive, CamelCase is used here -for readability. - -NOTE: Additional information on the CORE-V ISA extensions can be found in the -[CORE-V ISA Extension -Naming](https://github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-isa-extension-naming.md) -specification, and in the draft [CORE-V Builtin -Function](https://github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md) -specification. - -## Common Toolchain Command Line Options - -This section lists common RISC-V specific toolchain command line options. - -### `-mstrict-align`/`-mno-strict-align` -Indicates that the compiler should not assume that unaligned scalar and -unaligned vector memory references are handled by the system. - -`-mstrict-align`: The compiler disallows misaligned memory access. -`-mno-strict-align`: The compiler allows misaligned memory access. - -The compiler's behavior will follow this order of precedence: - -- Use the setting from `-mstrict-align` / `-mno-strict-align` if either option - is given, taking the last one specified. -- Use the setting from `-mtune` if `-mstrict-align` / `-mno-strict-align` is not given. -- Use the setting from `-mcpu` if neither of the above options is given. -- Use the compiler's default setting if none of the above options are provided. - -NOTE: Non-strict also known as unaligned access or misaligned access -NOTE: The compiler may generate misaligned access if the program violates the - alignment assumption. -NOTE: This option does not affect inline assembly. - - -### `-mscalar-strict-align`/`-mno-scalar-strict-align`/`-mvector-strict-align`/`-mno-vector-strict-align` - -`-mscalar-strict-align`/`-mno-scalar-strict-align`: Similar to -`-mstrict-align`/`-mno-strict-align` but applied to scalar memory access only. - -`-mvector-strict-align`/`-mno-vector-strict-align`: Similar to -`-mstrict-align`/`-mno-strict-align` but applied to vector memory access only. - -The precedence among `-m[no]-scalar-strict-align`, `-m[no-]vector-strict-align`, -and `-m[no-]strict-align` is determined by the last one specified. - -## TODO - -* `-mdiv`, `-mno-div`, `-mfdiv`, `-mno-fdiv`, `-msave-restore`, - `-mno-save-restore`, `-mexplicit-relocs`, `-mno-explicit-relocs` - -## Appendix: Exposing a vendor-specific extension across the toolchain - -TODO. diff --git a/docs-resources b/docs-resources new file mode 160000 index 0000000..35203a4 --- /dev/null +++ b/docs-resources @@ -0,0 +1 @@ +Subproject commit 35203a4f123d0be162b6b5ea213a657b594f8c36 diff --git a/src/contributors.adoc b/src/contributors.adoc new file mode 100644 index 0000000..b2ae0ee --- /dev/null +++ b/src/contributors.adoc @@ -0,0 +1,3 @@ +== Contributors + +See https://github.com/riscv-non-isa/riscv-toolchain-conventions/graphs/contributors[]. diff --git a/src/preamble.adoc b/src/preamble.adoc new file mode 100644 index 0000000..09e85a7 --- /dev/null +++ b/src/preamble.adoc @@ -0,0 +1,47 @@ +[preface] +== Copyright and License Information + +The RISC-V Toolchain Conventions document is authored by a +https://github.com/riscv-non-isa/riscv-toolchain-conventions/graphs/contributors[range of contributors]. + +It is licensed under the Creative Commons Attribution 4.0 International License (CC-BY 4.0). + +The full license text is available at https://creativecommons.org/licenses/by/4.0/ + +[preface] +== Aims + +This effort aims to document the expected behaviour and command-line interface +of RISC-V toolchains. In doing so, we can provide an avenue for members of the +GNU and LLVM communities to collaborate on standardising and extending these +conventions. A diverse range of RISC-V implementations and custom extensions +will inevitably result in vendor-specific toolchains being created and +distributed. By describing a clear preferred path for exposing vendor-specific +extensions or modifications, we can try to increase the likelihood that these +vendor toolchain distributions have a common interface and aren't gratuitously +different. + +[preface] +== Status and Roadmap + +This document is a work-in-progress, and contains many sections that serve +mainly to enumerate current gaps or oddities. The plan is to seek feedback and +further develop the proposal with the help of the RISC-V community, then to +seek input from the wider GCC and Clang developer communities for extensions +or changes beyond the current set of command-line options supported by GCC. + +See the https://github.com/riscv-non-isa/riscv-toolchain-conventions/issues[issues list] +to discuss any of the problems or TODO items described in this document. + +This document is currently targeted at toolchain implementers and developers, +but over time we hope it will also become a useful reference for RISC-V +toolchain users. + +[preface] +== See also + +- https://riscv.org/technical/specifications/[RISC-V user-level ISA specification] +(Document Version 20191213) +- https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc[RISC-V ELF psABI specification] +- https://github.com/riscv-non-isa/riscv-asm-manual[RISC-V Assembly Programmer's Manual] +- https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Options.html[GCC RISC-V option documentation] diff --git a/src/prelude.adoc b/src/prelude.adoc new file mode 100644 index 0000000..cbcfe53 --- /dev/null +++ b/src/prelude.adoc @@ -0,0 +1,96 @@ += RISC-V Toolchain Conventions +Authors: several contributors +include::../docs-resources/global-config.adoc[] +// These variables need customization for the specification version and date +:docgroup: RISC-V Special Interest Group +:description: RISC-V Toolchain Conventions +//Note revdate and revnumber populated in Makefile +:revnumber: v0.0.0 +:revlifecycle: dev +ifeval::["{revlifecycle}" == "dev"] +:revremark: This document is in Development state. Change should be expected. +endif::[] +ifeval::["{revlifecycle}" == "discussion"] +:revremark: This document is in Discussion state. Change should be expected. +endif::[] +ifeval::["{revlifecycle}" == "stable"] +:revremark: This document is in Stable state. Assume it may change. +endif::[] +ifeval::["{revlifecycle}" == "frozen"] +:revremark: This document is in Frozen state. Change is extremely unlikely. +endif::[] +ifeval::["{revlifecycle}" == "ratified"] +:revremark: This document is in Ratified state. No changes are allowed. +endif::[] +// These variables should not require customization +:company: RISC-V +:url-riscv: http://riscv.org +:doctype: book +:preface-title: Preamble +:colophon: +:appendix-caption: Appendix +:imagesdir: ../docs-resources/images +:title-logo-image: image:risc-v_logo.png["RISC-V International Logo",pdfwidth=3.25in,align=center] +:experimental: +:reproducible: +:icons: font +:lang: en +:listing-caption: Listing +:sectnums: +:sectnumlevels: 5 +:toclevels: 5 +:toc: left +:source-highlighter: pygments +ifdef::backend-pdf[] +:source-highlighter: coderay +endif::[] +:data-uri: +:hide-uri-scheme: +:stem: latexmath +:footnote: +:xrefstyle: short + +ifeval::["{revlifecycle}" == "discussion"] +[WARNING] +.This document is in the link:http://riscv.org/spec-state[Discussion state] +==== +Assume everything can change. This document is not complete yet and was created only +for the purpose of conversation outside of the document. +==== +endif::[] +ifeval::["{revlifecycle}" == "dev"] +[WARNING] +.This document is in the link:http://riscv.org/spec-state[Development state] +==== +Assume everything can change. This draft specification will change before being accepted +as standard, so implementations made to this draft specification will likely not conform +to the future standard. +==== +endif::[] +ifeval::["{revlifecycle}" == "stable"] +[WARNING] +.This document is in the link:http://riscv.org/spec-state[Stable state] +==== +Assume anything could still change, but limited change should be expected. +==== +endif::[] +ifeval::["{revlifecycle}" == "frozen"] +.This document is in the link:http://riscv.org/spec-state[Frozen state] +==== +Change is extremely unlikely. A high threshold will be used, and a change +will only occur because of some truly critical issue being identified during +the public review cycle. Any other desired or needed changes can be the subject +of a follow-on new extension. +==== +endif::[] +ifeval::["{revlifecycle}" == "ratified"] +.This document is in the link:http://riscv.org/spec-state[Ratified state] +==== +No changes are allowed. Any desired or needed changes can be the subject +of a follow-on new extension. Ratified extensions are never revised. +==== +endif::[] + +[preface] +== List of tables +list-of::table[hide_empty_section=true, enhanced_rendering=true] diff --git a/src/riscv-toolchain.adoc b/src/riscv-toolchain.adoc new file mode 100644 index 0000000..4995ff3 --- /dev/null +++ b/src/riscv-toolchain.adoc @@ -0,0 +1,8 @@ +include::prelude.adoc[] + +include::preamble.adoc[] + +[preface] +include::contributors.adoc[] + +include::toolchain-conventions.adoc[] diff --git a/src/toolchain-conventions.adoc b/src/toolchain-conventions.adoc new file mode 100644 index 0000000..8f02372 --- /dev/null +++ b/src/toolchain-conventions.adoc @@ -0,0 +1,416 @@ +== Specifying the target ISA with -march + +The compiler and assembler both accept the `-march` flag to specify the target +ISA, e.g. `rv32imafd`. The abbreviation `g` can be used to represent either +`IMAFD` (when targeting RISC-V ISA specification version 2.2 or earlier) or +`IMAFD_Zicsr_Zifencei` (version 20190608 or later) base and extensions, +e.g. `-march=rv64g`. A target `-march` which includes floating point +instructions implies a hardfloat calling convention, but can be overridden +using the `-mabi` flag (see the next section). + +The ISA subset naming conventions and canonical order are described in +Chapter `ISA Extension Naming Conventions` of the RISC-V user-level ISA +specification. However, tools do not currently follow this specification +(input is case sensitive, ...). + +The rule of ISA string become more complicated, due to extension implication +rules and more extensions added into RISC-V, the canonical order is non-obvious +to humans, so tools should accept the ISA string in non-canonical order to reduce +the burden of remembering the canonical order. + +Detailed rules for ISA string: + +. First letter must be `i`, `e` or `g`. +. Single-letter may be non-canonical order. +. Multi-letter may be non-canonical order. +. Multi-letter must be separated by underscore. +. Version separator(`p`) has higher priority than `p` extension. + +Example: +[source, asm] +---- +rv32ima_zicsr # Valid ISA string. +rv32i_zicsr_m # Valid ISA string. +rv32i_zicsr_ma # Valid ISA string. +rv32imac # Valid ISA string. +rv32mai # Invalid ISA string, first letter must be `i`, `e` or `g`. +rv32i_zicsrzifence # Valid ISA string, but it will interpreted as rv32 + # with base extension and `zicsrzifence` extension + # rather than `zicsr` and `zifence` extensions. +rv32i2p1 # Valid ISA string, it recognized as `I` extension with + # version 2.1 rather than `I` extension with with version + # 2.0 and `P` extension with 1.0. +---- + +If the 'C' (compressed) instruction set extension is targeted, the compiler +will generate compressed instructions where possible. + +NOTE: Single-letter extension with version (e.g. `m2p0`) is still treated as +a single-letter extension, it won't be treated as a multi-letter extension. + +NOTE: Any output of ISA string like `Tag_RISCV_arch` must be canonical order. + +NOTE: Cross-tool argument are highly recommended to be passed in canonical order +for backward compatibility. + +=== Issues for consideration +- Whether `riscv32` and `riscv64` should be accepted as synonyms for `rv32` +and `rv64`. +- Whether the `-march` string should be parsed case insensitively. +- Exposing the ability to specify version numbers for a target extension. +- Specifying non-standard extensions. The ISA specification suggests naming +such as `rv32gXfirstext_Xsecondext`. In GCC or Clang it would be more +conventional to give a string such as `rv32g+firstext+secondext`. + +== Specifying the target ABI with -mabi + +- https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#abi-ilp32[`ilp32`]: + int, long, pointers are 32-bit. GPRs and the stack are used for + parameter passing. +- https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#abi-ilp32f[`ilp32f`]: + int, long, pointers are 32-bit. GPRs, 32-bit FPRs, and the stack are + used for parameter passing. +- https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#abi-ilp32d[`ilp32d`]: + int, long, pointers are 32-bit. GPRs, 64-bit FPRs and the stack are + used for parameter passing. +- https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#abi-lp64[`lp64`]: + long, pointers are 64-bit. GPRs and the the stack are used for + parameter passing. +- https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#abi-lp64f[`lp64f`]: + long, pointers are 64-bit. GPRs, 32-bit FPRs, and the stack are used for + parameter passing. +- https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#abi-lp64d[`lp64d`]: + long, pointers are 64-bit. GPRs, 64-bit FPRs, and the stack are used for + parameter passing. + +See the https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc[RISC-V ELF psABI] +for more information on these ABIs. + +The default value for `-mabi` is system dependent. For cross-compilation, both +`-march` and `-mabi` should be specified. An error will be produced for +impossible combinations of `-march` and `-mabi` such as `-march=rv32i` and +`-mabi=ilp32f`. + +=== Issues for consideration + +- Should the `-mabi` string be parsed case insensitively? +- How should the RV32E ABI be specified? `ilp32e`? + +== Specifying the target code model with -mcmodel + +The target code model indicates constraints on symbols which the compiler can +exploit these constraints to generate more efficient code. Three code models are +currently defined for RISC-V: + +- `-mcmodel=medlow`. The program and its statically defined symbols must lie +within a single 2GiB address range, between the absolute addresses -2GiB and ++2GiB. `lui` and `addi` pairs are used to generate addresses. +- `-mcmodel=medany`. The program and its statically defined symbols must lie +within a single 4GiB address range. `auipc` and `addi` pairs are used to +generate addresses. +- Use of any PIC or PIE option (e.g. -fpic, -fPIC, -fpie or -fPIE) will enable +the medium position independent code model. This model is similar to the medium +any code model, but uses the global offset table (GOT) for non-local symbol +addresses. + +NOTE: When PIC or PIE mode enabled the `-mcmodel=medlow` will be suppressed. + +RISC-V psABI has a contain sections to describe the code model: + +- https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#medium-low-code-model[Medium low code model]: -mcmodel=medlow +- https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#medium-low-code-model[Medium any code model]: -mcmodel=medany +- https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#medium-position-independent-code-model[Medium position independent code model]: -fpic, -fPIC, -fpie or -fPIE. + +== Disassembler (objdump) behaviour + +A RISC-V ELF binary is not currently self-describing, in the sense that it +doesn't contain enough information to determine which variant of the RISC-V +architecture is being targeted. GNU objdump will currently attempt disassemble +any instruction whose encoding matches one of the standard RV32/RV64GC +extensions. + +objdump will default to showing pseudoinstructions and ABI register names. The +`numeric` disassembler argument can be used to use architectural register +names such as `x10`, while the `no-aliases` disassembler argument will ensure +only canonical instructions rather than pseudoinstructions or aliases are +printed. These arguments are specified using `-M`, e.g. `-M numeric` or `-M +numeric,no-aliases`. + +Perhaps surprisingly, the disassembler will default to hiding the difference +between compressed (16-bit) instructions and their 32-bit equivalent. e.g. +`c.addi sp, -16` will be printed as `addi sp, sp, -16`. + +=== Issues for consideration + +- The current GNU objdump behaviour will not provide useful results for cases +where non-standard extensions are implemented which reuse some of the standard +extension's encoding space. Making RISC-V ELF files self-describing (as +discussed https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/47[here]) +would avoid this problem. +- Would it be useful to have separate flags that control the printing of +pseudoinstructions and whether compressed instructions are printed directly or +not? + +== Assembler behaviour + +See the https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md[RISC-V Assembly Programmer's Manual] +for details on the syntax accepted by the assembler. + +The assembler will produce compressed instructions whenever possible if the +targeted RISC-V variant includes support for the 'C' compressed instruction +set. + +=== Issues for consideration +* There is currently no way to enable support for the 'C' ISA extension, but to +disable the automatic 'compression' of instructions. + +== C/C++ preprocessor definitions + +- `+__riscv+`: defined for any RISC-V target. Older versions of the GCC +toolchain defined `+__riscv__+`. +- `+__riscv_xlen+`: 32 for RV32 and 64 for RV64. +- `+__riscv_float_abi_soft+`, `+__riscv_float_abi_single+`, +`+__riscv_float_abi_double+`: one of these three will be defined, depending on +target ABI. +- `+__riscv_cmodel_medlow+`, `+__riscv_cmodel_medany+`: one of these two will be +defined, depending on the target code model. +- `+__riscv_mul+`: defined when targeting the 'M' ISA extension. +- `+__riscv_muldiv+`: defined when targeting the 'M' ISA extension and +`-mno-div` has not been used. +- `+__riscv_div+`: defined when targeting the 'M' ISA extension and `-mno-div` +has not been used. +- `+__riscv_atomic+`: defined when targeting the 'A' ISA extension. +- `+__riscv_flen+`: 32 when targeting the 'F' ISA extension (but not 'D') and 64 +when targeting 'FD'. +- `+__riscv_fdiv+`: defined when targeting the 'F' or 'D' ISA extensions and +`-mno-fdiv` has not been used. +- `+__riscv_fsqrt+`: defined when targeting the 'F' or 'D' ISA extensions and +`-mno-fdiv` has not been used. +- `+__riscv_compressed+`: defined when targeting the 'C' ISA extension. + +=== Issues for consideration +- What should the naming convention be for defines that indicate support for +non-standard extensions? +- What additional information could/should be exposed via preprocessor +defines? + +== Specifying stack alignment + +The default stack alignment is 16 bytes in RV32I and RV64I, and 4 bytes on +RV32E. There is not currently a way to specify an alternative stack alignment, +but the `-mpreferred-stack-boundary` and `-mincoming-stack-boundary` flags +supported by GCC on X86 could be adopted. + +== Save restore support + +The save restore optimization is enabled through the option `-msave-restore` +and reduces the amount of code in the prologue and epilogue by using +library functions instead of inline code to save and restore callee saved +registers. The library functions are provided in the emulation library and +have the following signatures: + +- `void` `+__riscv_save_(void)+` +- `void` `+__riscv_restore_(void)+` +- `void` `+__riscv_restore_tailcall_+` `(void * tail /* passed in t1 */)` (LLVM/compiler-rt only) + +`` is a value between 0 and 12 and corresponds to the number of +registers between `s0` and `s11` that are saved/restored. The return +address register `ra` is always included in the registers saved and restored. + +The `+__riscv_save_+` functions are called from the prologue, using `t0` as +the link register to avoid clobbering `ra`. They allocate stack space for the +registers and then save `ra` and the appropriate number of registers from +`s0`-`s11`. The `+__riscv_restore_+` functions are tail-called from the +epilogue. They restore the saved registers, deallocate the stack space for the +register, and then perform a return through the restored value of `ra`. + +`+__riscv_restore_tailcall_+` are additional entry points used when the +epilogue of the called function ends in a tail-call. Unlike +`+__riscv_restore_+` these are also provided the address of the function +which was originally tail-called as an argument, and after restoring +registers they make a tail-call through that argument instead of returning. +Note that the address of the function to tail-call is provided in register `t1`, +which differs from the normal calling convention. + +As of November 2021 the additional tail-call entry points are only +implemented in compiler-rt, and calls will only be generated by LLVM +when the option `-mllvm -save-restore-tailcall` is specified. + +== Conventions for vendor extensions + +Support for custom instruction set extensions are an important part of RISC-V, +with large encoding spaces reserved of vendor extensions. + +However, there are no official guidelines on naming the mnemonics. This section +defines guidelines which vendors are expected to follow if upstreaming support +for their extensions. Although vendor-provided toolchains are free to make +different choices, they are strongly urged to align with these guidelines in +order to ensure there is a straightforward path for upstreaming in the future. + +NOTE: Open source toolchain maintainer has final say on accepting vendor +extension, comply with this conventions isn't guarantee upstream will accept. + +=== Vendor extension naming scheme + +According to the RISC-V ISA spec, non-standard extensions are named using a single `X` +followed by an alphabetical name and an optional version number. + +To make it easier to identify and prevent naming conflict, vendor extensions +should start with a vendor name, which could be an abbreviation of the full name. + +For example: + +- `XVentanaCondOps` from Ventana +- `Xsfcflushdlone` from SiFive + +=== Assembly mnemonic + +In order to avoid confusion between standard extension and other vendor +extensions, instruction mnemonics from vendor extensions must have a +prefix corresponding to the vendor's name. + +The vendor prefix should be at least two letters long + +e.g. `sf.` for SiFive, `vt.` for Ventana. No central registration with RISC-V +International or elsewhere is required before the prefix is used. + +NOTE: Although no centralized registration is required, vendors should add the +vendor prefix to the table _IF_ vendors are interested to upstream their +extension to open source toolchain like LLVM or GNU toolchain. + +Vendors should also aim to follow the conventions used for naming mnemonics +in the ratified base ISA and extensions (e.g. the use of 'w', 'd', +'u', and 's' suffixes). + +=== CSR naming scheme + +Vendors may define their own CSRs within the custom read-only CSR address range +specified in the RISC-V ISA spec. However, to avoid conflicts, each vendor CSR +must include a prefix corresponding to the vendor's name. + +The vendor prefix should match the prefix defined in assembly mnemonics and be +separated by a dot, e.g., `th.vxrm`. + +=== List of vendor prefixes + +.List of vendor prefixes +[%autowidth] +|=== +|*Vendor* |*Prefix* |*URL* +|Open Hardware Group | cv | https://www.openhwgroup.org/ +|SiFive | sf | https://www.sifive.com/ +|T-Head | th | https://www.t-head.cn/ +|Ventana Micro Systems | vt | https://www.ventanamicro.com/ +|Nuclei | xl | https://nucleisys.com/ +|=== + +NOTE: Vendor prefixes are case-insensitive. + +NOTE: The Nuclei instruction prefix `xl` is an abbreviation of "XinLai", which is the Chinese pronunciation of Nuclei(`+芯来+`). + +NOTE: OpenHW cores are all branded as CORE-V, hence the prefix. + +=== List of vendor identifiers +Vendor identifiers are dummy symbols used in the corresponding `R_RISCV_VENDOR` +relocation (irrespective of ELF class/XLEN) and must be unique amongst all +vendors providing custom relocations. Vendor identifiers may be suffixed with a +tag to provide extra relocations for a given vendor. + +.List of vendor identifiers +[%autowidth] +|=== +|*Vendor* |*Symbol* +|Open Hardware Group | COREV +|=== + +=== List of vendor extensions + +.List of vendor extensions +[cols="20,20,10,~"] +|=== +|*Vendor* |*Name* |*Version* |*ISA Document* +|OpenHW | Xcvalu | 1.0.0 | https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst[CORE-V Instruction Set Extensions] +|OpenHW | Xcvbi | 1.0.0 | https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst[CORE-V Instruction Set Extensions] +|OpenHW | Xcvbitmanip | 1.0.0 | https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst[CORE-V Instruction Set Extensions] +|OpenHW | Xcvelw | 1.0.0 | https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst[CORE-V Instruction Set Extensions] +|OpenHW | Xcvhwlp | 1.0.0 | https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst[CORE-V Instruction Set Extensions] +|OpenHW | Xcvmac | 1.0.0 | https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst[CORE-V Instruction Set Extensions] +|OpenHW | Xcvmem | 1.0.0 | https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst[CORE-V Instruction Set Extensions] +|OpenHW | Xcvsimd | 1.0.0 | https://github.com/openhwgroup/cv32e40p/blob/dev/docs/source/instruction_set_extensions.rst[CORE-V Instruction Set Extensions] +|SiFive | XSFvqmaccdod | 1.0 | https://www.sifive.com/document-file/sifive-int8-matrix-multiplication-extensions-specification[SiFive Int8 Matrix Multiplication Extensions Specification] +|SiFive | XSFvqmaccqoq | 1.0 | https://www.sifive.com/document-file/sifive-int8-matrix-multiplication-extensions-specification[SiFive Int8 Matrix Multiplication Extensions Specification] +|SiFive | XSFvfnrclipxfqf | 1.0 | https://www.sifive.com/document-file/fp32-to-int8-ranged-clip-instructions[FP32-to-int8 Ranged Clip Instructions (Xsfvfnrclipxfqf) Extension Specification] +|SiFive | Xsfvfwmaccqqq | 1.0 | https://www.sifive.com/document-file/matrix-multiply-accumulate-instruction[Matrix Multiply Accumulate Instruction (Xsfvfwmaccqqq) Extension Specification] +|SiFive | XSFVCP | 1.0 | https://sifive.cdn.prismic.io/sifive/c3829e36-8552-41f0-a841-79945784241b_vcix-spec-software.pdf[SiFive Vector Coprocessor Interface Software Specification] +|T-Head | XTheadCmo | 1.0 | https://github.com/T-head-Semi/thead-extension-spec/releases/latest[T-Head ISA extension specification] +|T-Head | XTheadBa | 1.0 | https://github.com/T-head-Semi/thead-extension-spec/releases/latest[T-Head ISA extension specification] +|T-Head | XTheadBb | 1.0 | https://github.com/T-head-Semi/thead-extension-spec/releases/latest[T-Head ISA extension specification] +|T-Head | XTheadBs | 1.0 | https://github.com/T-head-Semi/thead-extension-spec/releases/latest[T-Head ISA extension specification] +|T-Head | XTheadCondMov | 1.0 | https://github.com/T-head-Semi/thead-extension-spec/releases/latest[T-Head ISA extension specification] +|T-Head | XTheadFMemIdx | 1.0 | https://github.com/T-head-Semi/thead-extension-spec/releases/latest[T-Head ISA extension specification] +|T-Head | XTheadFmv | 1.0 | https://github.com/T-head-Semi/thead-extension-spec/releases/latest[T-Head ISA extension specification] +|T-Head | XTheadInt | 1.0 | https://github.com/T-head-Semi/thead-extension-spec/releases/latest[T-Head ISA extension specification] +|T-Head | XTheadMac | 1.0 | https://github.com/T-head-Semi/thead-extension-spec/releases/latest[T-Head ISA extension specification] +|T-Head | XTheadMemPair | 1.0 | https://github.com/T-head-Semi/thead-extension-spec/releases/latest[T-Head ISA extension specification] +|T-Head | XTheadMemIdx | 1.0 | https://github.com/T-head-Semi/thead-extension-spec/releases/latest[T-Head ISA extension specification] +|T-Head | XTheadSync | 1.0 | https://github.com/T-head-Semi/thead-extension-spec/releases/latest[T-Head ISA extension specification] +|T-Head | XTheadVector | 1.0 | https://github.com/T-head-Semi/thead-extension-spec/releases/latest[T-Head ISA extension specification] +|Ventana | XVentanaCondOps | 1.0 | https://github.com/ventanamicro/ventana-custom-extensions/releases/download/v1.0.0/ventana-custom-extensions-v1.0.0.pdf[VTx-family custom instructions] +|=== + +NOTE: Vendor extension names are case-insensitive, CamelCase is used here +for readability. + +NOTE: Additional information on the CORE-V ISA extensions can be found in the +https://github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-isa-extension-naming.md[CORE-V ISA Extension Naming] +specification, and in the draft +https://github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md[CORE-V Builtin Function] +specification. + +== Common Toolchain Command Line Options + +This section lists common RISC-V specific toolchain command line options. + +=== `-mstrict-align`/`-mno-strict-align` +Indicates that the compiler should not assume that unaligned scalar and +unaligned vector memory references are handled by the system. + + +`-mstrict-align`: The compiler disallows misaligned memory access. + +`-mno-strict-align`: The compiler allows misaligned memory access. + +The compiler's behavior will follow this order of precedence: + +- Use the setting from `-mstrict-align` / `-mno-strict-align` if either option +is given, taking the last one specified. +- Use the setting from `-mtune` if `-mstrict-align` / `-mno-strict-align` is not given. +- Use the setting from `-mcpu` if neither of the above options is given. +- Use the compiler's default setting if none of the above options are provided. + +NOTE: Non-strict also known as unaligned access or misaligned access + +NOTE: The compiler may generate misaligned access if the program violates the + alignment assumption. + +NOTE: This option does not affect inline assembly. + +=== `-mscalar-strict-align`/`-mno-scalar-strict-align`/`-mvector-strict-align`/`-mno-vector-strict-align` + +`-mscalar-strict-align`/`-mno-scalar-strict-align`: Similar to +`-mstrict-align`/`-mno-strict-align` but applied to scalar memory access only. + +`-mvector-strict-align`/`-mno-vector-strict-align`: Similar to +`-mstrict-align`/`-mno-strict-align` but applied to vector memory access only. + +The precedence among `-m[no]-scalar-strict-align`, `-m[no-]vector-strict-align`, +and `-m[no-]strict-align` is determined by the last one specified. + +== TODO + +- `-mdiv`, `-mno-div`, `-mfdiv`, `-mno-fdiv`, `-msave-restore`, + `-mno-save-restore`, `-mexplicit-relocs`, `-mno-explicit-relocs` + +== Appendix: Exposing a vendor-specific extension across the toolchain + +TODO.