From db955cdec4987a6fc76bf1d0269c37a80500b580 Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Mon, 22 Jun 2026 10:14:14 +0200 Subject: [PATCH 1/5] Mirror ISA extension organization for CSRs --- csrs.csv => csrs/csrs.csv | 0 csrs32.csv => csrs/csrs32.csv | 0 csrs/unratified/.gitkeep | 0 pyproject.toml | 3 +-- src/riscv_opcodes/c_utils.py | 8 +++--- src/riscv_opcodes/chisel_utils.py | 12 ++++----- src/riscv_opcodes/constants.py | 11 ++++---- src/riscv_opcodes/go_utils.py | 9 ++++--- src/riscv_opcodes/parse.py | 24 ++++++++++++----- src/riscv_opcodes/resources.py | 10 ++++++++ src/riscv_opcodes/rust_utils.py | 8 +++--- src/riscv_opcodes/shared_utils.py | 40 ++++++++++++++++++++--------- src/riscv_opcodes/sverilog_utils.py | 7 +++-- 13 files changed, 83 insertions(+), 49 deletions(-) rename csrs.csv => csrs/csrs.csv (100%) rename csrs32.csv => csrs/csrs32.csv (100%) create mode 100644 csrs/unratified/.gitkeep diff --git a/csrs.csv b/csrs/csrs.csv similarity index 100% rename from csrs.csv rename to csrs/csrs.csv diff --git a/csrs32.csv b/csrs/csrs32.csv similarity index 100% rename from csrs32.csv rename to csrs/csrs32.csv diff --git a/csrs/unratified/.gitkeep b/csrs/unratified/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/pyproject.toml b/pyproject.toml index 7555c214..a0f8e057 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,5 @@ build-backend = "hatchling.build" "extensions" = "riscv_opcodes/extensions" "arg_lut.csv" = "riscv_opcodes/arg_lut.csv" "causes.csv" = "riscv_opcodes/causes.csv" -"csrs.csv" = "riscv_opcodes/csrs.csv" -"csrs32.csv" = "riscv_opcodes/csrs32.csv" +"csrs" = "riscv_opcodes/csrs" "encoding.h" = "riscv_opcodes/encoding.h" diff --git a/src/riscv_opcodes/c_utils.py b/src/riscv_opcodes/c_utils.py index 198a37f1..907e7c41 100644 --- a/src/riscv_opcodes/c_utils.py +++ b/src/riscv_opcodes/c_utils.py @@ -2,15 +2,15 @@ import os import pprint -from .constants import causes, csrs, csrs32 +from .constants import causes from .resources import read_text_resource -from .shared_utils import InstrDict, arg_lut +from .shared_utils import CsrDict, InstrDict, arg_lut pp = pprint.PrettyPrinter(indent=2) logging.basicConfig(level=logging.INFO, format="%(levelname)s:: %(message)s") -def make_c(instr_dict: InstrDict): +def make_c(instr_dict: InstrDict, csr_dict: CsrDict): mask_match_str = "" declare_insn_str = "" for i in instr_dict: @@ -24,7 +24,7 @@ def make_c(instr_dict: InstrDict): csr_names_str = "" declare_csr_str = "" - for num, name in csrs + csrs32: + for num, name in [csr for csrs in csr_dict.values() for csr in csrs]: csr_names_str += f"#define CSR_{name.upper()} {hex(num)}\n" declare_csr_str += f"DECLARE_CSR({name}, CSR_{name.upper()})\n" diff --git a/src/riscv_opcodes/chisel_utils.py b/src/riscv_opcodes/chisel_utils.py index c2ddca88..6c1233be 100644 --- a/src/riscv_opcodes/chisel_utils.py +++ b/src/riscv_opcodes/chisel_utils.py @@ -1,14 +1,14 @@ import logging import pprint -from .constants import causes, csrs, csrs32 -from .shared_utils import InstrDict, instr_dict_2_extensions +from .constants import causes +from .shared_utils import CsrDict, InstrDict, instr_dict_2_extensions pp = pprint.PrettyPrinter(indent=2) logging.basicConfig(level=logging.INFO, format="%(levelname)s:: %(message)s") -def make_chisel(instr_dict: InstrDict, spinal_hdl: bool = False): +def make_chisel(instr_dict: InstrDict, csr_dict: CsrDict, spinal_hdl: bool = False): chisel_names = "" cause_names_str = "" @@ -48,19 +48,19 @@ def make_chisel(instr_dict: InstrDict, spinal_hdl: bool = False): cause_names_str += """ res.toArray }""" - for num, name in csrs + csrs32: + for num, name in [csr for csrs in csr_dict.values() for csr in csrs]: csr_names_str += f" val {name} = {hex(num)}\n" csr_names_str += """ val all = { val res = collection.mutable.ArrayBuffer[Int]() """ - for num, name in csrs: + for num, name in csr_dict.get("csrs", []): csr_names_str += f""" res += {name}\n""" csr_names_str += """ res.toArray } val all32 = { val res = collection.mutable.ArrayBuffer(all:_*) """ - for num, name in csrs32: + for num, name in csr_dict.get("csrs32", []): csr_names_str += f""" res += {name}\n""" csr_names_str += """ res.toArray }""" diff --git a/src/riscv_opcodes/constants.py b/src/riscv_opcodes/constants.py index 34c75cd8..60dc8c4b 100644 --- a/src/riscv_opcodes/constants.py +++ b/src/riscv_opcodes/constants.py @@ -1,7 +1,7 @@ import csv import re -from .resources import open_text_resource +from .resources import open_text_resource, read_lines # TODO: The constants in this file should be in all caps. overlapping_extensions = { @@ -60,14 +60,13 @@ def read_int_map_csv(filename: str) -> "list[tuple[int, str]]": Returns: list of tuple: A list of (int, str) tuples extracted from the CSV file. """ - with open_text_resource(filename) as f: - csv_reader = csv.reader(f, skipinitialspace=True) - return [(int(row[0], 0), row[1]) for row in csv_reader] + return [ + (int(row[0], 0), row[1]) + for row in csv.reader(read_lines(filename), skipinitialspace=True) + ] causes = read_int_map_csv("causes.csv") -csrs = read_int_map_csv("csrs.csv") -csrs32 = read_int_map_csv("csrs32.csv") def read_arg_lut_csv(filename: str) -> "dict[str, tuple[int, int]]": diff --git a/src/riscv_opcodes/go_utils.py b/src/riscv_opcodes/go_utils.py index 4c5748ae..bbd32250 100644 --- a/src/riscv_opcodes/go_utils.py +++ b/src/riscv_opcodes/go_utils.py @@ -2,14 +2,13 @@ import pprint from typing import Sequence -from .constants import csrs -from .shared_utils import InstrDict, signed +from .shared_utils import CsrDict, InstrDict, signed pp = pprint.PrettyPrinter(indent=2) logging.basicConfig(level=logging.INFO, format="%(levelname)s:: %(message)s") -def make_go(instr_dict: InstrDict, extensions: Sequence[str]): +def make_go(instr_dict: InstrDict, extensions: Sequence[str], csr_dict: CsrDict): args = 'make inst.go EXTENSIONS="' + " ".join(extensions) + '"' prelude = f"""// Code generated by {args}; DO NOT EDIT.""" @@ -54,7 +53,9 @@ def make_go(instr_dict: InstrDict, extensions: Sequence[str]): instr_str += f""" case A{i.upper().replace("_","")}: return &inst{{ {hex(opcode)}, {hex(funct3)}, {hex(rs1)}, {hex(rs2)}, {signed(csr,12)}, {hex(funct7)} }} """ - for num, name in sorted(csrs, key=lambda row: row[0]): + for num, name in sorted( + [csr for csrs in csr_dict.values() for csr in csrs], key=lambda csr: csr[0] + ): csrs_map_str += f'{hex(num)} : "{name.upper()}",\n' with open("inst.go", "w", encoding="utf-8") as file: diff --git a/src/riscv_opcodes/parse.py b/src/riscv_opcodes/parse.py index c58e9b65..6390324f 100644 --- a/src/riscv_opcodes/parse.py +++ b/src/riscv_opcodes/parse.py @@ -9,7 +9,7 @@ from .go_utils import make_go from .latex_utils import make_latex_table, make_priv_latex_table from .rust_utils import make_rust -from .shared_utils import add_segmented_vls_insn, create_inst_dict +from .shared_utils import add_segmented_vls_insn, create_csr_dict, create_inst_dict from .sverilog_utils import make_sverilog from .svg_utils import make_svg @@ -22,6 +22,7 @@ def generate_extensions( extensions: list[str], + csrs: list[str], include_pseudo: bool, c: bool, chisel: bool, @@ -33,6 +34,7 @@ def generate_extensions( svg: bool, warn_overlap: bool = False, ): + csr_dict = create_csr_dict(csrs) instr_dict = create_inst_dict(extensions, include_pseudo, warn_overlap=warn_overlap) instr_dict = dict(sorted(instr_dict.items())) instr_dict_with_segment = add_segmented_vls_insn(instr_dict) @@ -48,27 +50,27 @@ def generate_extensions( warn_overlap=warn_overlap, ) instr_dict_c = dict(sorted(instr_dict_c.items())) - make_c(instr_dict_c) + make_c(instr_dict_c, csr_dict) logging.info("encoding.out.h generated successfully") if chisel: - make_chisel(instr_dict) + make_chisel(instr_dict, csr_dict) logging.info("inst.chisel generated successfully") if spinalhdl: - make_chisel(instr_dict, True) + make_chisel(instr_dict, csr_dict, True) logging.info("inst.spinalhdl generated successfully") if sverilog: - make_sverilog(instr_dict) + make_sverilog(instr_dict, csr_dict) logging.info("inst.sverilog generated successfully") if rust: - make_rust(instr_dict) + make_rust(instr_dict, csr_dict) logging.info("inst.rs generated successfully") if go: - make_go(instr_dict_with_segment, extensions) + make_go(instr_dict_with_segment, extensions, csr_dict) logging.info("inst.go generated successfully") if latex: @@ -111,6 +113,13 @@ def main(): nargs="*", help="Extensions to use. This is a glob of the rv_.. files, e.g. 'rv*' will give all extensions.", ) + parser.add_argument( + "--csr", + action="append", + dest="csrs", + default=None, + help="CSRs to use. If omitted, all CSR sets are included.", + ) args = parser.parse_args() @@ -118,6 +127,7 @@ def main(): generate_extensions( args.extensions, + args.csrs, args.pseudo, args.c, args.chisel, diff --git a/src/riscv_opcodes/resources.py b/src/riscv_opcodes/resources.py index e9398ec8..fba043bb 100644 --- a/src/riscv_opcodes/resources.py +++ b/src/riscv_opcodes/resources.py @@ -37,3 +37,13 @@ def open_text_resource(path_relative_to_root: str) -> IO[str]: Open a text file relative to the root of this repo. """ return resource_root().joinpath(path_relative_to_root).open("r", encoding="utf-8") + + +def read_lines(file: str) -> "list[str]": + """ + Reads lines from a file and returns non-blank, non-comment lines. + The file must be a resource relative to the root of this repo. + """ + with open_text_resource(file) as fp: + lines = (line.rstrip() for line in fp) + return [line for line in lines if line and not line.startswith("#")] diff --git a/src/riscv_opcodes/rust_utils.py b/src/riscv_opcodes/rust_utils.py index 74e17eb9..b01b46c1 100644 --- a/src/riscv_opcodes/rust_utils.py +++ b/src/riscv_opcodes/rust_utils.py @@ -1,19 +1,19 @@ import logging import pprint -from .constants import causes, csrs, csrs32 -from .shared_utils import InstrDict +from .constants import causes +from .shared_utils import CsrDict, InstrDict pp = pprint.PrettyPrinter(indent=2) logging.basicConfig(level=logging.INFO, format="%(levelname)s:: %(message)s") -def make_rust(instr_dict: InstrDict): +def make_rust(instr_dict: InstrDict, csr_dict: CsrDict): mask_match_str = "" for i in instr_dict: mask_match_str += f'const MATCH_{i.upper().replace(".","_")}: u32 = {(instr_dict[i]["match"])};\n' mask_match_str += f'const MASK_{i.upper().replace(".","_")}: u32 = {(instr_dict[i]["mask"])};\n' - for num, name in csrs + csrs32: + for num, name in [csr for csrs in csr_dict.values() for csr in csrs]: mask_match_str += f"const CSR_{name.upper()}: u16 = {hex(num)};\n" for num, name in causes: mask_match_str += ( diff --git a/src/riscv_opcodes/shared_utils.py b/src/riscv_opcodes/shared_utils.py index 452b6083..f4dfafb6 100644 --- a/src/riscv_opcodes/shared_utils.py +++ b/src/riscv_opcodes/shared_utils.py @@ -1,4 +1,5 @@ import copy +import csv import logging import os import pprint @@ -6,7 +7,7 @@ from fnmatch import fnmatch from io import StringIO from itertools import chain -from typing import Dict, NoReturn, Optional, TypedDict +from typing import Dict, List, NoReturn, Optional, Tuple, TypedDict from .constants import ( arg_lut, @@ -17,7 +18,7 @@ pseudo_regex, single_fixed, ) -from .resources import open_text_resource, resource_root +from .resources import read_lines, resource_root LOG_FORMAT = "%(levelname)s:: %(message)s" LOG_LEVEL = logging.INFO @@ -165,6 +166,7 @@ class SingleInstr(TypedDict): InstrDict = Dict[str, SingleInstr] +CsrDict = Dict[str, List[Tuple[int, str]]] # Processing main function for a line in the encoding file @@ -395,16 +397,6 @@ def create_expanded_instruction( return (new_name, new_single_dict) -def read_lines(file: str) -> "list[str]": - """ - Reads lines from a file and returns non-blank, non-comment lines. - The file must be a resource relative to the root of this repo. - """ - with open_text_resource(file) as fp: - lines = (line.rstrip() for line in fp) - return [line for line in lines if line and not line.startswith("#")] - - # Update the instruction dictionary def process_standard_instructions( lines: "list[str]", @@ -543,6 +535,30 @@ def validate_instruction_in_extension( ) +# Construct a dictionary of CSR sets +def create_csr_dict(csrs: "Optional[list[str]]" = None) -> CsrDict: + d: CsrDict = {} + for file in (resource_root() / "csrs").iterdir(): + name = file.name.removesuffix(".csv") + if file.is_file() and (not csrs or name in csrs): + d[name] = [ + (int(row[0], 0), row[1]) + for row in csv.reader( + read_lines("csrs/" + file.name), skipinitialspace=True + ) + ] + for file in (resource_root() / "csrs" / "unratified").iterdir(): + name = file.name.removesuffix(".csv") + if file.is_file() and (not csrs or name in csrs): + d[name] = [ + (int(row[0], 0), row[1]) + for row in csv.reader( + read_lines("csrs/unratified/" + file.name), skipinitialspace=True + ) + ] + return d + + # Construct a dictionary of instructions filtered by specified criteria def create_inst_dict( file_filter: "list[str]", diff --git a/src/riscv_opcodes/sverilog_utils.py b/src/riscv_opcodes/sverilog_utils.py index c17be9f0..295e7611 100644 --- a/src/riscv_opcodes/sverilog_utils.py +++ b/src/riscv_opcodes/sverilog_utils.py @@ -2,19 +2,18 @@ import pprint from pathlib import Path -from .constants import csrs, csrs32 -from .shared_utils import InstrDict +from .shared_utils import CsrDict, InstrDict pp = pprint.PrettyPrinter(indent=2) logging.basicConfig(level=logging.INFO, format="%(levelname)s:: %(message)s") -def make_sverilog(instr_dict: InstrDict): +def make_sverilog(instr_dict: InstrDict, csr_dict: CsrDict): names_str = "" for i in instr_dict: names_str += f" localparam [31:0] {i.upper().replace('.','_'):<18s} = 32'b{instr_dict[i]['encoding'].replace('-','?')};\n" names_str += " /* CSR Addresses */\n" - for num, name in csrs + csrs32: + for num, name in [csr for csrs in csr_dict.values() for csr in csrs]: names_str += ( f" localparam logic [11:0] CSR_{name.upper()} = 12'h{hex(num)[2:]};\n" ) From 7455b9b27ad69b94372fbc92feb71f43a378b926 Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Mon, 20 Jul 2026 14:22:06 +0200 Subject: [PATCH 2/5] Run tests with `--warn-overlap` flag --- .github/workflows/python-app.yml | 2 +- Makefile | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 2b81cdcb..ecc16920 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -46,7 +46,7 @@ jobs: # Generate all output with code coverage. Unfortunately due to limitations in # the `coverage` tool we need to run `riscv_opcodes` as a module. - name: Generate - run: uv run -- coverage run -m riscv_opcodes -c -chisel -sverilog -rust -latex -spinalhdl -svg -go "rv*" "unratified/rv*" + run: uv run -- coverage run -m riscv_opcodes --warn-overlap -c -chisel -sverilog -rust -latex -spinalhdl -svg -go "rv*" "unratified/rv*" - name: Check C output run: cat encoding.out.h | cpp diff --git a/Makefile b/Makefile index 45a00ff7..51a5f423 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ ENV_H := ../riscv-tests/env/encoding.h OPENOCD_H := ../riscv-openocd/src/target/riscv/encoding.h INSTALL_HEADER_FILES := $(ISASIM_H) $(PK_H) $(ENV_H) $(OPENOCD_H) PSEUDO_FLAG := $(if $(PSEUDO),-pseudo,) +FLAGS := --warn-overlap ifeq ($(shell command -v uv 2>/dev/null),) RUNNER := PYTHONPATH=src python -m @@ -21,25 +22,25 @@ pseudo: @$(MAKE) PSEUDO=1 everything everything: - @$(RUNNER) riscv_opcodes $(PSEUDO_FLAG) -c -go -chisel -sverilog -rust -latex -spinalhdl $(EXTENSIONS) + @$(RUNNER) riscv_opcodes $(FLAGS) $(PSEUDO_FLAG) -c -go -chisel -sverilog -rust -latex -spinalhdl $(EXTENSIONS) encoding.out.h: - @$(RUNNER) riscv_opcodes -c $(PSEUDO_FLAG) $(EXTENSIONS) + @$(RUNNER) riscv_opcodes $(FLAGS) -c $(PSEUDO_FLAG) $(EXTENSIONS) inst.chisel: - @$(RUNNER) riscv_opcodes -chisel $(PSEUDO_FLAG) $(EXTENSIONS) + @$(RUNNER) riscv_opcodes $(FLAGS) -chisel $(PSEUDO_FLAG) $(EXTENSIONS) inst.go: - @$(RUNNER) riscv_opcodes -go $(PSEUDO_FLAG) $(EXTENSIONS) + @$(RUNNER) riscv_opcodes $(FLAGS) -go $(PSEUDO_FLAG) $(EXTENSIONS) latex: - @$(RUNNER) riscv_opcodes -latex $(PSEUDO_FLAG) $(EXTENSIONS) + @$(RUNNER) riscv_opcodes $(FLAGS) -latex $(PSEUDO_FLAG) $(EXTENSIONS) inst.sverilog: - @$(RUNNER) riscv_opcodes -sverilog $(PSEUDO_FLAG) $(EXTENSIONS) + @$(RUNNER) riscv_opcodes $(FLAGS) -sverilog $(PSEUDO_FLAG) $(EXTENSIONS) inst.rs: - @$(RUNNER) riscv_opcodes -rust $(PSEUDO_FLAG) $(EXTENSIONS) + @$(RUNNER) riscv_opcodes $(FLAGS) -rust $(PSEUDO_FLAG) $(EXTENSIONS) clean: rm -f inst* priv-instr-table.tex encoding.out.h @@ -58,4 +59,4 @@ instr-table.tex: latex priv-instr-table.tex: latex inst.spinalhdl: - @$(RUNNER) riscv_opcodes -spinalhdl $(PSEUDO_FLAG) $(EXTENSIONS) + @$(RUNNER) riscv_opcodes $(FLAGS) -spinalhdl $(PSEUDO_FLAG) $(EXTENSIONS) From 4cbf75b4f40d1d6000a8aebd2e8b619ff802264a Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Mon, 27 Apr 2026 00:14:36 +0200 Subject: [PATCH 3/5] Add PULP extensions --- PULP.md | 6 + arg_lut.csv | 7 + csrs/unratified/rv_xpulp.csv | 15 ++ encoding.h | 22 ++ extensions/unratified/rv32_xb | 90 +++++++ extensions/unratified/rv32_xcvmem | 31 +++ extensions/unratified/rv32_xpulpabs | 3 + extensions/unratified/rv32_xpulpbitop | 26 ++ extensions/unratified/rv32_xpulpbr | 4 + extensions/unratified/rv32_xpulpclip | 6 + extensions/unratified/rv32_xpulphwloop | 10 + extensions/unratified/rv32_xpulpmacsi | 4 + extensions/unratified/rv32_xpulpminmax | 10 + extensions/unratified/rv32_xpulppostmod | 32 +++ extensions/unratified/rv32_xpulpslet | 4 + extensions/unratified/rv32_xpulpvect | 233 ++++++++++++++++++ .../unratified/rv32_xpulpvectshufflepack | 17 ++ extensions/unratified/rv_xcopift | 7 + extensions/unratified/rv_xdma | 14 ++ extensions/unratified/rv_xfrep | 6 + extensions/unratified/rv_xipu | 101 ++++++++ extensions/unratified/rv_xsmallfloat_b | 66 +++++ extensions/unratified/rv_xsmallfloat_h | 74 ++++++ extensions/unratified/rv_xsmallfloat_vb | 108 ++++++++ extensions/unratified/rv_xsmallfloat_vh | 95 +++++++ extensions/unratified/rv_xsmallfloat_vs | 91 +++++++ extensions/unratified/rv_xssr | 8 + pulp-llvm-extensions.txt | 20 ++ 28 files changed, 1110 insertions(+) create mode 100644 PULP.md create mode 100644 csrs/unratified/rv_xpulp.csv create mode 100644 extensions/unratified/rv32_xb create mode 100644 extensions/unratified/rv32_xcvmem create mode 100644 extensions/unratified/rv32_xpulpabs create mode 100644 extensions/unratified/rv32_xpulpbitop create mode 100644 extensions/unratified/rv32_xpulpbr create mode 100644 extensions/unratified/rv32_xpulpclip create mode 100644 extensions/unratified/rv32_xpulphwloop create mode 100644 extensions/unratified/rv32_xpulpmacsi create mode 100644 extensions/unratified/rv32_xpulpminmax create mode 100644 extensions/unratified/rv32_xpulppostmod create mode 100644 extensions/unratified/rv32_xpulpslet create mode 100644 extensions/unratified/rv32_xpulpvect create mode 100644 extensions/unratified/rv32_xpulpvectshufflepack create mode 100644 extensions/unratified/rv_xcopift create mode 100644 extensions/unratified/rv_xdma create mode 100644 extensions/unratified/rv_xfrep create mode 100644 extensions/unratified/rv_xipu create mode 100644 extensions/unratified/rv_xsmallfloat_b create mode 100644 extensions/unratified/rv_xsmallfloat_h create mode 100644 extensions/unratified/rv_xsmallfloat_vb create mode 100644 extensions/unratified/rv_xsmallfloat_vh create mode 100644 extensions/unratified/rv_xsmallfloat_vs create mode 100644 extensions/unratified/rv_xssr create mode 100644 pulp-llvm-extensions.txt diff --git a/PULP.md b/PULP.md new file mode 100644 index 00000000..46c29471 --- /dev/null +++ b/PULP.md @@ -0,0 +1,6 @@ +# Adding a custom ISA extension + +If you have a custom ISA extension, create a new file under `extensions/unratified`. +The extension name should be prefixed with an `x` to properly identify custom extensions; refer to the existing extensions. + +Finally, list the extension in `pulp-extensions.txt` for it to be picked up as a PULP extension, e.g. by our compiler generation scripts. diff --git a/arg_lut.csv b/arg_lut.csv index 23f5f0d0..ee2b126d 100644 --- a/arg_lut.csv +++ b/arg_lut.csv @@ -113,3 +113,10 @@ "p_rd_p", 11, 8 "p_rs1_p", 19, 16 "p_rs2_p", 24, 21 +"shamt", 25, 20 +"prs3", 11, 7 +"L", 7, 7 +"uimms", 19, 15 +"Luimm5", 29, 25 +"stagger_max", 14, 12 +"stagger_mask", 11, 8 diff --git a/csrs/unratified/rv_xpulp.csv b/csrs/unratified/rv_xpulp.csv new file mode 100644 index 00000000..4a4adaed --- /dev/null +++ b/csrs/unratified/rv_xpulp.csv @@ -0,0 +1,15 @@ +# PULP/Snitch custom CSRs. +# +# format of a line in this file: +# 0xENCODING, "csr_name" +0x7C0, "ssr" +0x7C3, "sc" +0x7C4, "user_low" +0x7C5, "user_high" +# Smallfloat and misc PULP CSRs +0x7C1, "fpmode" +0x7C2, "barrier" +0x7C6, "copift" +0x7C7, "dump" +0x7D1, "stacklimit" +0x800, "fmode" diff --git a/encoding.h b/encoding.h index 288df167..aeca6fbb 100644 --- a/encoding.h +++ b/encoding.h @@ -486,6 +486,28 @@ #define IRQ_RAS_LOW_PRIO 35 #define IRQ_RAS_HIGH_PRIO 43 +/* PULP/Snitch custom interrupt sources */ +#define IRQ_HOST 13 /* legacy alias for IRQ_LCOF */ +#define IRQ_S_CLUSTER 17 +#define IRQ_M_CLUSTER 19 +#define IRQ_M_ACC 20 /* machine-level accelerator interrupt */ + +#define MIP_SCIP (1 << IRQ_S_CLUSTER) +#define MIP_MCIP (1 << IRQ_M_CLUSTER) +#define MIP_MXIP (1 << IRQ_M_ACC) + +/* PULP/Snitch custom CSR addresses */ +#define CSR_SSR 0x7C0 // Stream semantic registers +#define CSR_FPMODE 0x7C1 // Floating-point mode +#define CSR_BARRIER 0x7C2 // Hardware barrier +#define CSR_SC 0x7C3 // Scalar chaining +#define CSR_USER_LOW 0x7C4 // AWUSER[31:0] +#define CSR_USER_HIGH 0x7C5 // AWUSER[63:32] +#define CSR_COPIFT 0x7C6 // Enable COPIFT +#define CSR_DUMP 0x7C7 // Dump CSR +#define CSR_STACKLIMIT 0x7D1 // Mempool stack overflow limit +#define CSR_FMODE 0x800 // Floating-point mode (legacy) + /* page table entry (PTE) fields */ #define PTE_V 0x001 /* Valid */ #define PTE_R 0x002 /* Read */ diff --git a/extensions/unratified/rv32_xb b/extensions/unratified/rv32_xb new file mode 100644 index 00000000..3716c4ad --- /dev/null +++ b/extensions/unratified/rv32_xb @@ -0,0 +1,90 @@ +# RV32B: bit manipulation + +# INFO: overlaps with rv32_xpulpminmax, rv32_xpulpbitop, rv32_xpulpbitopsmall + +# Since the original draft proposal, the following have now been ratified +# in rv_zbb. +# With the same encoding +# andn rd rs1 rs2 31..25=32 14..12=7 6..2=0x0C 1..0=3 +# orn rd rs1 rs2 31..25=32 14..12=6 6..2=0x0C 1..0=3 +# xnor rd rs1 rs2 31..25=32 14..12=4 6..2=0x0C 1..0=3 +# clz rd rs1 31..20=0x600 14..12=1 6..2=0x04 1..0=3 +# ctz rd rs1 31..20=0x601 14..12=1 6..2=0x04 1..0=3 +# sext.b rd rs1 31..20=0x604 14..12=1 6..2=0x04 1..0=3 +# sext.h rd rs1 31..20=0x605 14..12=1 6..2=0x04 1..0=3 +# rol rd rs1 rs2 31..25=48 14..12=1 6..2=0x0C 1..0=3 +# ror rd rs1 rs2 31..25=48 14..12=5 6..2=0x0C 1..0=3 +# min rd rs1 rs2 31..25=5 14..12=4 6..2=0x0C 1..0=3 +# maxu rd rs1 rs2 31..25=5 14..12=7 6..2=0x0C 1..0=3 +# With swapped encoding +# max rd rs1 rs2 31..25=5 14..12=5 6..2=0x0C 1..0=3 +# minu rd rs1 rs2 31..25=5 14..12=6 6..2=0x0C 1..0=3 +# Same encoding but changed name (pcnt -> cpop) +# pcnt rd rs1 31..20=0x602 14..12=1 6..2=0x04 1..0=3 + +# Since the original draft proposal, the following have now been ratified +# in rv64_zbb, with almost the same encoding (shamt -> shamtd) +# rori rd rs1 31..26=24 shamt 14..12=5 6..2=0x04 1..0=3 + +# Since the original draft proposal, the following have now been ratified +# in rv_zba, with the same encoding. +# sh1add rd rs1 rs2 31..25=16 14..12=2 6..2=0x0C 1..0=3 +# sh2add rd rs1 rs2 31..25=16 14..12=4 6..2=0x0C 1..0=3 +# sh3add rd rs1 rs2 31..25=16 14..12=6 6..2=0x0C 1..0=3 + +# Since the original draft proposal, the following have now been ratified +# in rv_zbc, with the same encoding. +# clmul rd rs1 rs2 31..25=5 14..12=1 6..2=0x0C 1..0=3 +# clmulr rd rs1 rs2 31..25=5 14..12=2 6..2=0x0C 1..0=3 +# clmulh rd rs1 rs2 31..25=5 14..12=3 6..2=0x0C 1..0=3 + +# Since the original draft proposal, the following have now been ratified +# in rv_zbkb, with the same encoding. +# pack rd rs1 rs2 31..25=4 14..12=4 6..2=0x0C 1..0=3 +# packh rd rs1 rs2 31..25=4 14..12=7 6..2=0x0C 1..0=3 + + +slo rd rs1 rs2 31..25=16 14..12=1 6..2=0x0C 1..0=3 +sro rd rs1 rs2 31..25=16 14..12=5 6..2=0x0C 1..0=3 + +sbclr rd rs1 rs2 31..25=36 14..12=1 6..2=0x0C 1..0=3 +sbset rd rs1 rs2 31..25=20 14..12=1 6..2=0x0C 1..0=3 +sbinv rd rs1 rs2 31..25=52 14..12=1 6..2=0x0C 1..0=3 +sbext rd rs1 rs2 31..25=36 14..12=5 6..2=0x0C 1..0=3 +gorc rd rs1 rs2 31..25=20 14..12=5 6..2=0x0C 1..0=3 +grev rd rs1 rs2 31..25=52 14..12=5 6..2=0x0C 1..0=3 + +sloi rd rs1 31..26=8 shamt 14..12=1 6..2=0x04 1..0=3 +sroi rd rs1 31..26=8 shamt 14..12=5 6..2=0x04 1..0=3 + +sbclri rd rs1 31..26=18 shamt 14..12=1 6..2=0x04 1..0=3 +sbseti rd rs1 31..26=10 shamt 14..12=1 6..2=0x04 1..0=3 +sbinvi rd rs1 31..26=26 shamt 14..12=1 6..2=0x04 1..0=3 +sbexti rd rs1 31..26=18 shamt 14..12=5 6..2=0x04 1..0=3 +gorci rd rs1 31..26=10 shamt 14..12=5 6..2=0x04 1..0=3 +grevi rd rs1 31..26=26 shamt 14..12=5 6..2=0x04 1..0=3 + +cmix rd rs1 rs2 rs3 26..25=3 14..12=1 6..2=0x0C 1..0=3 +cmov rd rs1 rs2 rs3 26..25=3 14..12=5 6..2=0x0C 1..0=3 + +fsl rd rs1 rs2 rs3 26..25=2 14..12=1 6..2=0x0C 1..0=3 +fsr rd rs1 rs2 rs3 26..25=2 14..12=5 6..2=0x0C 1..0=3 +fsri rd rs1 shamt rs3 26=1 14..12=5 6..2=0x04 1..0=3 + +crc32.b rd rs1 31..20=0x610 14..12=1 6..2=0x04 1..0=3 +crc32.h rd rs1 31..20=0x611 14..12=1 6..2=0x04 1..0=3 +crc32.w rd rs1 31..20=0x612 14..12=1 6..2=0x04 1..0=3 +crc32c.b rd rs1 31..20=0x618 14..12=1 6..2=0x04 1..0=3 +crc32c.h rd rs1 31..20=0x619 14..12=1 6..2=0x04 1..0=3 +crc32c.w rd rs1 31..20=0x61A 14..12=1 6..2=0x04 1..0=3 + +shfl rd rs1 rs2 31..25=4 14..12=1 6..2=0x0C 1..0=3 +unshfl rd rs1 rs2 31..25=4 14..12=5 6..2=0x0C 1..0=3 +# Name conflict with rv_zbs' bext instruction +# bext rd rs1 rs2 31..25=4 14..12=6 6..2=0x0C 1..0=3 +bdep rd rs1 rs2 31..25=36 14..12=6 6..2=0x0C 1..0=3 +packu rd rs1 rs2 31..25=36 14..12=4 6..2=0x0C 1..0=3 +bfp rd rs1 rs2 31..25=36 14..12=7 6..2=0x0C 1..0=3 + +shfli rd rs1 31..25=4 shamtw 14..12=1 6..2=0x04 1..0=3 +unshfli rd rs1 31..25=4 shamtw 14..12=5 6..2=0x04 1..0=3 diff --git a/extensions/unratified/rv32_xcvmem b/extensions/unratified/rv32_xcvmem new file mode 100644 index 00000000..fd5d692a --- /dev/null +++ b/extensions/unratified/rv32_xcvmem @@ -0,0 +1,31 @@ +# CORE-V Xcvmem extension: post-incrementing load & store operations +# and register-register loads & store operations +# Encodings as defined by OpenHW Group CV32E40P v1.3.2 + +# Post-increment and reg-reg loads +cv.lb.irpost rd rs1 imm12 14..12=0 6..2=0x02 1..0=3 +cv.lbu.irpost rd rs1 imm12 14..12=4 6..2=0x02 1..0=3 +cv.lh.irpost rd rs1 imm12 14..12=1 6..2=0x02 1..0=3 +cv.lhu.irpost rd rs1 imm12 14..12=5 6..2=0x02 1..0=3 +cv.lw.irpost rd rs1 imm12 14..12=2 6..2=0x02 1..0=3 +cv.lb.rrpost rd rs1 rs2 31..25=0x00 14..12=3 6..2=0x0A 1..0=3 +cv.lbu.rrpost rd rs1 rs2 31..25=0x08 14..12=3 6..2=0x0A 1..0=3 +cv.lh.rrpost rd rs1 rs2 31..25=0x01 14..12=3 6..2=0x0A 1..0=3 +cv.lhu.rrpost rd rs1 rs2 31..25=0x09 14..12=3 6..2=0x0A 1..0=3 +cv.lw.rrpost rd rs1 rs2 31..25=0x02 14..12=3 6..2=0x0A 1..0=3 +cv.lb.rr rd rs1 rs2 31..25=0x04 14..12=3 6..2=0x0A 1..0=3 +cv.lbu.rr rd rs1 rs2 31..25=0x0C 14..12=3 6..2=0x0A 1..0=3 +cv.lh.rr rd rs1 rs2 31..25=0x05 14..12=3 6..2=0x0A 1..0=3 +cv.lhu.rr rd rs1 rs2 31..25=0x0D 14..12=3 6..2=0x0A 1..0=3 +cv.lw.rr rd rs1 rs2 31..25=0x06 14..12=3 6..2=0x0A 1..0=3 + +# Post-increment and reg-reg stores +cv.sb.irpost rs1 rs2 imm12hi imm12lo 14..12=0 6..2=0x0A 1..0=3 +cv.sh.irpost rs1 rs2 imm12hi imm12lo 14..12=1 6..2=0x0A 1..0=3 +cv.sw.irpost rs1 rs2 imm12hi imm12lo 14..12=2 6..2=0x0A 1..0=3 +cv.sb.rrpost rs1 rs2 prs3 31..25=0x10 14..12=3 6..2=0x0A 1..0=3 +cv.sh.rrpost rs1 rs2 prs3 31..25=0x11 14..12=3 6..2=0x0A 1..0=3 +cv.sw.rrpost rs1 rs2 prs3 31..25=0x12 14..12=3 6..2=0x0A 1..0=3 +cv.sb.rr rs1 rs2 prs3 31..25=0x14 14..12=3 6..2=0x0A 1..0=3 +cv.sh.rr rs1 rs2 prs3 31..25=0x15 14..12=3 6..2=0x0A 1..0=3 +cv.sw.rr rs1 rs2 prs3 31..25=0x16 14..12=3 6..2=0x0A 1..0=3 diff --git a/extensions/unratified/rv32_xpulpabs b/extensions/unratified/rv32_xpulpabs new file mode 100644 index 00000000..e27d5f7e --- /dev/null +++ b/extensions/unratified/rv32_xpulpabs @@ -0,0 +1,3 @@ +# Xpulp extension subset: general ALU operations: abs + +p.abs rd rs1 31..25=2 24..20=0 14..12=0 6..2=0x0C 1..0=3 diff --git a/extensions/unratified/rv32_xpulpbitop b/extensions/unratified/rv32_xpulpbitop new file mode 100644 index 00000000..9c2b912f --- /dev/null +++ b/extensions/unratified/rv32_xpulpbitop @@ -0,0 +1,26 @@ +# Xpulp extension subset: bit manipulation operations & general ALU operations + +# INFO: overlaps with rv32_b +# INFO: this is a superset of rv32_xpulpbitopsmall + +p.exths rd rs1 31..25=8 24..20=0 14..12=4 6..2=0x0C 1..0=3 +p.exthz rd rs1 31..25=8 24..20=0 14..12=5 6..2=0x0C 1..0=3 +p.extbs rd rs1 31..25=8 24..20=0 14..12=6 6..2=0x0C 1..0=3 +p.extbz rd rs1 31..25=8 24..20=0 14..12=7 6..2=0x0C 1..0=3 + +p.extract rd rs1 Luimm5 imm5 31..30=3 14..12=0 6..2=0x0C 1..0=3 +p.extractr rd rs1 rs2 31..30=2 29..25=0 14..12=0 6..2=0x0C 1..0=3 +p.extractu rd rs1 Luimm5 imm5 31..30=3 14..12=1 6..2=0x0C 1..0=3 +p.extractur rd rs1 rs2 31..30=2 29..25=0 14..12=1 6..2=0x0C 1..0=3 +p.insert rd rs1 Luimm5 imm5 31..30=3 14..12=2 6..2=0x0C 1..0=3 +p.insertr rd rs1 rs2 31..30=2 29..25=0 14..12=2 6..2=0x0C 1..0=3 +p.bset rd rs1 Luimm5 imm5 31..30=3 14..12=4 6..2=0x0C 1..0=3 +p.bsetr rd rs1 rs2 31..30=2 29..25=0 14..12=4 6..2=0x0C 1..0=3 +p.bclr rd rs1 Luimm5 imm5 31..30=3 14..12=3 6..2=0x0C 1..0=3 +p.bclrr rd rs1 rs2 31..30=2 29..25=0 14..12=3 6..2=0x0C 1..0=3 + +p.cnt rd rs1 rs2 31..25=8 14..12=3 6..2=0x0C 1..0=3 +p.clb rd rs1 31..25=8 24..20=0 14..12=2 6..2=0x0C 1..0=3 +p.fl1 rd rs1 31..25=8 24..20=0 14..12=1 6..2=0x0C 1..0=3 +p.ff1 rd rs1 31..25=8 24..20=0 14..12=0 6..2=0x0C 1..0=3 +p.ror rd rs1 31..25=4 24..20=0 14..12=5 6..2=0x0C 1..0=3 diff --git a/extensions/unratified/rv32_xpulpbr b/extensions/unratified/rv32_xpulpbr new file mode 100644 index 00000000..d836223a --- /dev/null +++ b/extensions/unratified/rv32_xpulpbr @@ -0,0 +1,4 @@ +# Xpulp extension subset: immediate branching operations + +p.beqimm rs1 imm5 bimm12hi bimm12lo 14..12=2 6..2=0x18 1..0=3 +p.bneimm rs1 imm5 bimm12hi bimm12lo 14..12=3 6..2=0x18 1..0=3 diff --git a/extensions/unratified/rv32_xpulpclip b/extensions/unratified/rv32_xpulpclip new file mode 100644 index 00000000..2a7d0a2b --- /dev/null +++ b/extensions/unratified/rv32_xpulpclip @@ -0,0 +1,6 @@ +# Xpulp extension subset: general ALU operations: clip + +p.clip rd rs1 imm5 31..25=10 14..12=1 6..2=0x0C 1..0=3 +p.clipr rd rs1 rs2 31..25=10 14..12=5 6..2=0x0C 1..0=3 +p.clipu rd rs1 imm5 31..25=10 14..12=2 6..2=0x0C 1..0=3 +p.clipur rd rs1 rs2 31..25=10 14..12=6 6..2=0x0C 1..0=3 diff --git a/extensions/unratified/rv32_xpulphwloop b/extensions/unratified/rv32_xpulphwloop new file mode 100644 index 00000000..3117f0ec --- /dev/null +++ b/extensions/unratified/rv32_xpulphwloop @@ -0,0 +1,10 @@ +# Xpulp extension subset: hardware loop operations + +# INFO: overlaps with rv_ipu + +lp.starti L imm12 19..15=0 14..12=0 11..8=0 6..2=0x1E 1..0=3 +lp.endi L imm12 19..15=0 14..12=1 11..8=0 6..2=0x1E 1..0=3 +lp.count L rs1 31..20=0 14..12=2 11..8=0 6..2=0x1E 1..0=3 +lp.counti L imm12 19..15=0 14..12=3 11..8=0 6..2=0x1E 1..0=3 +lp.setup L rs1 imm12 14..12=4 11..8=0 6..2=0x1E 1..0=3 +lp.setupi L imm12 uimms 14..12=5 11..8=0 6..2=0x1E 1..0=3 diff --git a/extensions/unratified/rv32_xpulpmacsi b/extensions/unratified/rv32_xpulpmacsi new file mode 100644 index 00000000..d9d08f85 --- /dev/null +++ b/extensions/unratified/rv32_xpulpmacsi @@ -0,0 +1,4 @@ +# Xpulp extension subset: MAC operations + +p.mac rd rs1 rs2 31..25=33 14..12=0 6..2=0x0C 1..0=3 +p.msu rd rs1 rs2 31..25=33 14..12=1 6..2=0x0C 1..0=3 diff --git a/extensions/unratified/rv32_xpulpminmax b/extensions/unratified/rv32_xpulpminmax new file mode 100644 index 00000000..3c4b9c3d --- /dev/null +++ b/extensions/unratified/rv32_xpulpminmax @@ -0,0 +1,10 @@ +# Xpulp extension subset: general ALU operations: min, max, avg + +# INFO: overlaps with rv32_b, rv_ipu + +p.min rd rs1 rs2 31..25=2 14..12=4 6..2=0x0C 1..0=3 +p.minu rd rs1 rs2 31..25=2 14..12=5 6..2=0x0C 1..0=3 +p.max rd rs1 rs2 31..25=2 14..12=6 6..2=0x0C 1..0=3 +p.maxu rd rs1 rs2 31..25=2 14..12=7 6..2=0x0C 1..0=3 +p.addN rd rs1 rs2 31..30=0 Luimm5 14..12=2 6..2=0x16 1..0=3 +p.adduN rd rs1 rs2 31..30=2 Luimm5 14..12=2 6..2=0x16 1..0=3 diff --git a/extensions/unratified/rv32_xpulppostmod b/extensions/unratified/rv32_xpulppostmod new file mode 100644 index 00000000..2937bc46 --- /dev/null +++ b/extensions/unratified/rv32_xpulppostmod @@ -0,0 +1,32 @@ +# Xpulp extension subset: post-incrementing load & store operations +# and register-register loads & store operations + +# INFO: overlaps with rv_frep, rv_ssr, rv_dma + +# Post-increment and reg-reg loads +p.lb.irpost rd rs1 imm12 14..12=0 6..2=0x02 1..0=3 +p.lbu.irpost rd rs1 imm12 14..12=4 6..2=0x02 1..0=3 +p.lh.irpost rd rs1 imm12 14..12=1 6..2=0x02 1..0=3 +p.lhu.irpost rd rs1 imm12 14..12=5 6..2=0x02 1..0=3 +p.lw.irpost rd rs1 imm12 14..12=2 6..2=0x02 1..0=3 +p.lb.rrpost rd rs1 rs2 31..25=0x00 14..12=7 6..2=0x02 1..0=3 +p.lbu.rrpost rd rs1 rs2 31..25=0x20 14..12=7 6..2=0x02 1..0=3 +p.lh.rrpost rd rs1 rs2 31..25=0x08 14..12=7 6..2=0x02 1..0=3 +p.lhu.rrpost rd rs1 rs2 31..25=0x28 14..12=7 6..2=0x02 1..0=3 +p.lw.rrpost rd rs1 rs2 31..25=0x10 14..12=7 6..2=0x02 1..0=3 +p.lb.rr rd rs1 rs2 31..25=0x00 14..12=7 6..2=0x00 1..0=3 +p.lbu.rr rd rs1 rs2 31..25=0x20 14..12=7 6..2=0x00 1..0=3 +p.lh.rr rd rs1 rs2 31..25=0x08 14..12=7 6..2=0x00 1..0=3 +p.lhu.rr rd rs1 rs2 31..25=0x28 14..12=7 6..2=0x00 1..0=3 +p.lw.rr rd rs1 rs2 31..25=0x10 14..12=7 6..2=0x00 1..0=3 + +# Post-increment and reg-reg stores +p.sb.irpost rs1 rs2 imm12hi imm12lo 14..12=0 6..2=0x0A 1..0=3 +p.sh.irpost rs1 rs2 imm12hi imm12lo 14..12=1 6..2=0x0A 1..0=3 +p.sw.irpost rs1 rs2 imm12hi imm12lo 14..12=2 6..2=0x0A 1..0=3 +p.sb.rrpost rs1 rs2 prs3 31..25=0x00 14..12=4 6..2=0x0A 1..0=3 +p.sh.rrpost rs1 rs2 prs3 31..25=0x00 14..12=5 6..2=0x0A 1..0=3 +p.sw.rrpost rs1 rs2 prs3 31..25=0x00 14..12=6 6..2=0x0A 1..0=3 +p.sb.rr rs1 rs2 prs3 31..25=0x00 14..12=4 6..2=0x08 1..0=3 +p.sh.rr rs1 rs2 prs3 31..25=0x00 14..12=5 6..2=0x08 1..0=3 +p.sw.rr rs1 rs2 prs3 31..25=0x00 14..12=6 6..2=0x08 1..0=3 diff --git a/extensions/unratified/rv32_xpulpslet b/extensions/unratified/rv32_xpulpslet new file mode 100644 index 00000000..56ef914a --- /dev/null +++ b/extensions/unratified/rv32_xpulpslet @@ -0,0 +1,4 @@ +# Xpulp extension subset: general ALU operations: slet + +p.slet rd rs1 rs2 31..25=2 14..12=2 6..2=0x0C 1..0=3 +p.sletu rd rs1 rs2 31..25=2 14..12=3 6..2=0x0C 1..0=3 diff --git a/extensions/unratified/rv32_xpulpvect b/extensions/unratified/rv32_xpulpvect new file mode 100644 index 00000000..f695f21b --- /dev/null +++ b/extensions/unratified/rv32_xpulpvect @@ -0,0 +1,233 @@ +# Xpulp extension subset: SIMD ALU operations and Dot Product operations +# and SIMD comparison operations + +# format of a line in this file: +# +# +# is given by specifying one or more range/value pairs: +# hi..lo=value or bit=value or arg=value (e.g. 6..2=0x45 10=1 rd=0) +# +# is one of rd, rs1, rs2, rs3, aqrl, fm, pred, succ, rm, +# funct3, imm20, jimm20, imm12, imm12hi, bimm12hi, imm12lo, +# bimm12lo, zimm, shamt, shamtw, imm5, imm6, vd, vs3, vs1, vs2, +# vm, wd, amoop, nf, simm5, zimm11, prs3, L, uimms, Luimm5, +# vseglen, stagger_max, stagger_mask + +pv.add.h rd rs1 rs2 31..27=0 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.add.sc.h rd rs1 rs2 31..27=0 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.add.sci.h rd rs1 imm6 31..27=0 26=0 14..12=6 6..2=0x15 1..0=3 +pv.add.b rd rs1 rs2 31..27=0 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.add.sc.b rd rs1 rs2 31..27=0 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.add.sci.b rd rs1 imm6 31..27=0 26=0 14..12=7 6..2=0x15 1..0=3 +pv.sub.h rd rs1 rs2 31..27=1 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.sub.sc.h rd rs1 rs2 31..27=1 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.sub.sci.h rd rs1 imm6 31..27=1 26=0 14..12=6 6..2=0x15 1..0=3 +pv.sub.b rd rs1 rs2 31..27=1 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.sub.sc.b rd rs1 rs2 31..27=1 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.sub.sci.b rd rs1 imm6 31..27=1 26=0 14..12=7 6..2=0x15 1..0=3 + +pv.avg.h rd rs1 rs2 31..27=2 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.avg.sc.h rd rs1 rs2 31..27=2 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.avg.sci.h rd rs1 imm6 31..27=2 26=0 14..12=6 6..2=0x15 1..0=3 +pv.avg.b rd rs1 rs2 31..27=2 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.avg.sc.b rd rs1 rs2 31..27=2 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.avg.sci.b rd rs1 imm6 31..27=2 26=0 14..12=7 6..2=0x15 1..0=3 +pv.avgu.h rd rs1 rs2 31..27=3 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.avgu.sc.h rd rs1 rs2 31..27=3 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.avgu.sci.h rd rs1 imm6 31..27=3 26=0 14..12=6 6..2=0x15 1..0=3 +pv.avgu.b rd rs1 rs2 31..27=3 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.avgu.sc.b rd rs1 rs2 31..27=3 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.avgu.sci.b rd rs1 imm6 31..27=3 26=0 14..12=7 6..2=0x15 1..0=3 + +pv.min.h rd rs1 rs2 31..27=4 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.min.sc.h rd rs1 rs2 31..27=4 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.min.sci.h rd rs1 imm6 31..27=4 26=0 14..12=6 6..2=0x15 1..0=3 +pv.min.b rd rs1 rs2 31..27=4 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.min.sc.b rd rs1 rs2 31..27=4 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.min.sci.b rd rs1 imm6 31..27=4 26=0 14..12=7 6..2=0x15 1..0=3 +pv.minu.h rd rs1 rs2 31..27=5 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.minu.sc.h rd rs1 rs2 31..27=5 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.minu.sci.h rd rs1 imm6 31..27=5 26=0 14..12=6 6..2=0x15 1..0=3 +pv.minu.b rd rs1 rs2 31..27=5 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.minu.sc.b rd rs1 rs2 31..27=5 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.minu.sci.b rd rs1 imm6 31..27=5 26=0 14..12=7 6..2=0x15 1..0=3 + +pv.max.h rd rs1 rs2 31..27=6 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.max.sc.h rd rs1 rs2 31..27=6 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.max.sci.h rd rs1 imm6 31..27=6 26=0 14..12=6 6..2=0x15 1..0=3 +pv.max.b rd rs1 rs2 31..27=6 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.max.sc.b rd rs1 rs2 31..27=6 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.max.sci.b rd rs1 imm6 31..27=6 26=0 14..12=7 6..2=0x15 1..0=3 +pv.maxu.h rd rs1 rs2 31..27=7 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.maxu.sc.h rd rs1 rs2 31..27=7 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.maxu.sci.h rd rs1 imm6 31..27=7 26=0 14..12=6 6..2=0x15 1..0=3 +pv.maxu.b rd rs1 rs2 31..27=7 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.maxu.sc.b rd rs1 rs2 31..27=7 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.maxu.sci.b rd rs1 imm6 31..27=7 26=0 14..12=7 6..2=0x15 1..0=3 + +pv.srl.h rd rs1 rs2 31..27=8 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.srl.sc.h rd rs1 rs2 31..27=8 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.srl.sci.h rd rs1 imm6 31..27=8 26=0 14..12=6 6..2=0x15 1..0=3 +pv.srl.b rd rs1 rs2 31..27=8 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.srl.sc.b rd rs1 rs2 31..27=8 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.srl.sci.b rd rs1 imm6 31..27=8 26=0 14..12=7 6..2=0x15 1..0=3 +pv.sra.h rd rs1 rs2 31..27=9 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.sra.sc.h rd rs1 rs2 31..27=9 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.sra.sci.h rd rs1 imm6 31..27=9 26=0 14..12=6 6..2=0x15 1..0=3 +pv.sra.b rd rs1 rs2 31..27=9 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.sra.sc.b rd rs1 rs2 31..27=9 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.sra.sci.b rd rs1 imm6 31..27=9 26=0 14..12=7 6..2=0x15 1..0=3 +pv.sll.h rd rs1 rs2 31..27=10 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.sll.sc.h rd rs1 rs2 31..27=10 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.sll.sci.h rd rs1 imm6 31..27=10 26=0 14..12=6 6..2=0x15 1..0=3 +pv.sll.b rd rs1 rs2 31..27=10 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.sll.sc.b rd rs1 rs2 31..27=10 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.sll.sci.b rd rs1 imm6 31..27=10 26=0 14..12=7 6..2=0x15 1..0=3 + +pv.or.h rd rs1 rs2 31..27=11 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.or.sc.h rd rs1 rs2 31..27=11 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.or.sci.h rd rs1 imm6 31..27=11 26=0 14..12=6 6..2=0x15 1..0=3 +pv.or.b rd rs1 rs2 31..27=11 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.or.sc.b rd rs1 rs2 31..27=11 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.or.sci.b rd rs1 imm6 31..27=11 26=0 14..12=7 6..2=0x15 1..0=3 +pv.xor.h rd rs1 rs2 31..27=12 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.xor.sc.h rd rs1 rs2 31..27=12 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.xor.sci.h rd rs1 imm6 31..27=12 26=0 14..12=6 6..2=0x15 1..0=3 +pv.xor.b rd rs1 rs2 31..27=12 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.xor.sc.b rd rs1 rs2 31..27=12 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.xor.sci.b rd rs1 imm6 31..27=12 26=0 14..12=7 6..2=0x15 1..0=3 +pv.and.h rd rs1 rs2 31..27=13 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.and.sc.h rd rs1 rs2 31..27=13 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.and.sci.h rd rs1 imm6 31..27=13 26=0 14..12=6 6..2=0x15 1..0=3 +pv.and.b rd rs1 rs2 31..27=13 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.and.sc.b rd rs1 rs2 31..27=13 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.and.sci.b rd rs1 imm6 31..27=13 26=0 14..12=7 6..2=0x15 1..0=3 + +pv.abs.h rd rs1 31..27=14 26=0 25=0 24..20=0 14..12=0 6..2=0x15 1..0=3 +pv.abs.b rd rs1 31..27=14 26=0 25=0 24..20=0 14..12=1 6..2=0x15 1..0=3 + +pv.extract.h rd rs1 imm6 31..27=15 26=0 14..12=6 6..2=0x15 1..0=3 +pv.extract.b rd rs1 imm6 31..27=15 26=0 14..12=7 6..2=0x15 1..0=3 +pv.extractu.h rd rs1 imm6 31..27=18 26=0 14..12=6 6..2=0x15 1..0=3 +pv.extractu.b rd rs1 imm6 31..27=18 26=0 14..12=7 6..2=0x15 1..0=3 +pv.insert.h rd rs1 imm6 31..27=22 26=0 14..12=6 6..2=0x15 1..0=3 +pv.insert.b rd rs1 imm6 31..27=22 26=0 14..12=7 6..2=0x15 1..0=3 + +pv.dotsp.h rd rs1 rs2 31..27=19 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.dotsp.sc.h rd rs1 rs2 31..27=19 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.dotsp.sci.h rd rs1 imm6 31..27=19 26=0 14..12=6 6..2=0x15 1..0=3 +pv.dotsp.b rd rs1 rs2 31..27=19 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.dotsp.sc.b rd rs1 rs2 31..27=19 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.dotsp.sci.b rd rs1 imm6 31..27=19 26=0 14..12=7 6..2=0x15 1..0=3 + +pv.dotup.h rd rs1 rs2 31..27=16 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.dotup.sc.h rd rs1 rs2 31..27=16 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.dotup.sci.h rd rs1 imm6 31..27=16 26=0 14..12=6 6..2=0x15 1..0=3 +pv.dotup.b rd rs1 rs2 31..27=16 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.dotup.sc.b rd rs1 rs2 31..27=16 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.dotup.sci.b rd rs1 imm6 31..27=16 26=0 14..12=7 6..2=0x15 1..0=3 + +pv.dotusp.h rd rs1 rs2 31..27=17 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.dotusp.sc.h rd rs1 rs2 31..27=17 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.dotusp.sci.h rd rs1 imm6 31..27=17 26=0 14..12=6 6..2=0x15 1..0=3 +pv.dotusp.b rd rs1 rs2 31..27=17 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.dotusp.sc.b rd rs1 rs2 31..27=17 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.dotusp.sci.b rd rs1 imm6 31..27=17 26=0 14..12=7 6..2=0x15 1..0=3 + +pv.sdotsp.h rd rs1 rs2 31..27=23 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.sdotsp.sc.h rd rs1 rs2 31..27=23 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.sdotsp.sci.h rd rs1 imm6 31..27=23 26=0 14..12=6 6..2=0x15 1..0=3 +pv.sdotsp.b rd rs1 rs2 31..27=23 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.sdotsp.sc.b rd rs1 rs2 31..27=23 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.sdotsp.sci.b rd rs1 imm6 31..27=23 26=0 14..12=7 6..2=0x15 1..0=3 + +pv.sdotup.h rd rs1 rs2 31..27=20 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.sdotup.sc.h rd rs1 rs2 31..27=20 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.sdotup.sci.h rd rs1 imm6 31..27=20 26=0 14..12=6 6..2=0x15 1..0=3 +pv.sdotup.b rd rs1 rs2 31..27=20 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.sdotup.sc.b rd rs1 rs2 31..27=20 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.sdotup.sci.b rd rs1 imm6 31..27=20 26=0 14..12=7 6..2=0x15 1..0=3 + +pv.sdotusp.h rd rs1 rs2 31..27=21 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.sdotusp.sc.h rd rs1 rs2 31..27=21 26=0 25=0 14..12=4 6..2=0x15 1..0=3 +pv.sdotusp.sci.h rd rs1 imm6 31..27=21 26=0 14..12=6 6..2=0x15 1..0=3 +pv.sdotusp.b rd rs1 rs2 31..27=21 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.sdotusp.sc.b rd rs1 rs2 31..27=21 26=0 25=0 14..12=5 6..2=0x15 1..0=3 +pv.sdotusp.sci.b rd rs1 imm6 31..27=21 26=0 14..12=7 6..2=0x15 1..0=3 + +pv.cmpeq.h rd rs1 rs2 31..27=0 26=1 25=0 14..12=0 6..2=0x15 1..0=3 +pv.cmpeq.sc.h rd rs1 rs2 31..27=0 26=1 25=0 14..12=4 6..2=0x15 1..0=3 +pv.cmpeq.sci.h rd rs1 imm6 31..27=0 26=1 14..12=6 6..2=0x15 1..0=3 +pv.cmpeq.b rd rs1 rs2 31..27=0 26=1 25=0 14..12=1 6..2=0x15 1..0=3 +pv.cmpeq.sc.b rd rs1 rs2 31..27=0 26=1 25=0 14..12=5 6..2=0x15 1..0=3 +pv.cmpeq.sci.b rd rs1 imm6 31..27=0 26=1 14..12=7 6..2=0x15 1..0=3 + +pv.cmpne.h rd rs1 rs2 31..27=1 26=1 25=0 14..12=0 6..2=0x15 1..0=3 +pv.cmpne.sc.h rd rs1 rs2 31..27=1 26=1 25=0 14..12=4 6..2=0x15 1..0=3 +pv.cmpne.sci.h rd rs1 imm6 31..27=1 26=1 14..12=6 6..2=0x15 1..0=3 +pv.cmpne.b rd rs1 rs2 31..27=1 26=1 25=0 14..12=1 6..2=0x15 1..0=3 +pv.cmpne.sc.b rd rs1 rs2 31..27=1 26=1 25=0 14..12=5 6..2=0x15 1..0=3 +pv.cmpne.sci.b rd rs1 imm6 31..27=1 26=1 14..12=7 6..2=0x15 1..0=3 + +pv.cmpgt.h rd rs1 rs2 31..27=2 26=1 25=0 14..12=0 6..2=0x15 1..0=3 +pv.cmpgt.sc.h rd rs1 rs2 31..27=2 26=1 25=0 14..12=4 6..2=0x15 1..0=3 +pv.cmpgt.sci.h rd rs1 imm6 31..27=2 26=1 14..12=6 6..2=0x15 1..0=3 +pv.cmpgt.b rd rs1 rs2 31..27=2 26=1 25=0 14..12=1 6..2=0x15 1..0=3 +pv.cmpgt.sc.b rd rs1 rs2 31..27=2 26=1 25=0 14..12=5 6..2=0x15 1..0=3 +pv.cmpgt.sci.b rd rs1 imm6 31..27=2 26=1 14..12=7 6..2=0x15 1..0=3 + +pv.cmpge.h rd rs1 rs2 31..27=3 26=1 25=0 14..12=0 6..2=0x15 1..0=3 +pv.cmpge.sc.h rd rs1 rs2 31..27=3 26=1 25=0 14..12=4 6..2=0x15 1..0=3 +pv.cmpge.sci.h rd rs1 imm6 31..27=3 26=1 14..12=6 6..2=0x15 1..0=3 +pv.cmpge.b rd rs1 rs2 31..27=3 26=1 25=0 14..12=1 6..2=0x15 1..0=3 +pv.cmpge.sc.b rd rs1 rs2 31..27=3 26=1 25=0 14..12=5 6..2=0x15 1..0=3 +pv.cmpge.sci.b rd rs1 imm6 31..27=3 26=1 14..12=7 6..2=0x15 1..0=3 + +pv.cmplt.h rd rs1 rs2 31..27=4 26=1 25=0 14..12=0 6..2=0x15 1..0=3 +pv.cmplt.sc.h rd rs1 rs2 31..27=4 26=1 25=0 14..12=4 6..2=0x15 1..0=3 +pv.cmplt.sci.h rd rs1 imm6 31..27=4 26=1 14..12=6 6..2=0x15 1..0=3 +pv.cmplt.b rd rs1 rs2 31..27=4 26=1 25=0 14..12=1 6..2=0x15 1..0=3 +pv.cmplt.sc.b rd rs1 rs2 31..27=4 26=1 25=0 14..12=5 6..2=0x15 1..0=3 +pv.cmplt.sci.b rd rs1 imm6 31..27=4 26=1 14..12=7 6..2=0x15 1..0=3 + +pv.cmple.h rd rs1 rs2 31..27=5 26=1 25=0 14..12=0 6..2=0x15 1..0=3 +pv.cmple.sc.h rd rs1 rs2 31..27=5 26=1 25=0 14..12=4 6..2=0x15 1..0=3 +pv.cmple.sci.h rd rs1 imm6 31..27=5 26=1 14..12=6 6..2=0x15 1..0=3 +pv.cmple.b rd rs1 rs2 31..27=5 26=1 25=0 14..12=1 6..2=0x15 1..0=3 +pv.cmple.sc.b rd rs1 rs2 31..27=5 26=1 25=0 14..12=5 6..2=0x15 1..0=3 +pv.cmple.sci.b rd rs1 imm6 31..27=5 26=1 14..12=7 6..2=0x15 1..0=3 + +pv.cmpgtu.h rd rs1 rs2 31..27=6 26=1 25=0 14..12=0 6..2=0x15 1..0=3 +pv.cmpgtu.sc.h rd rs1 rs2 31..27=6 26=1 25=0 14..12=4 6..2=0x15 1..0=3 +pv.cmpgtu.sci.h rd rs1 imm6 31..27=6 26=1 14..12=6 6..2=0x15 1..0=3 +pv.cmpgtu.b rd rs1 rs2 31..27=6 26=1 25=0 14..12=1 6..2=0x15 1..0=3 +pv.cmpgtu.sc.b rd rs1 rs2 31..27=6 26=1 25=0 14..12=5 6..2=0x15 1..0=3 +pv.cmpgtu.sci.b rd rs1 imm6 31..27=6 26=1 14..12=7 6..2=0x15 1..0=3 + +pv.cmpgeu.h rd rs1 rs2 31..27=7 26=1 25=0 14..12=0 6..2=0x15 1..0=3 +pv.cmpgeu.sc.h rd rs1 rs2 31..27=7 26=1 25=0 14..12=4 6..2=0x15 1..0=3 +pv.cmpgeu.sci.h rd rs1 imm6 31..27=7 26=1 14..12=6 6..2=0x15 1..0=3 +pv.cmpgeu.b rd rs1 rs2 31..27=7 26=1 25=0 14..12=1 6..2=0x15 1..0=3 +pv.cmpgeu.sc.b rd rs1 rs2 31..27=7 26=1 25=0 14..12=5 6..2=0x15 1..0=3 +pv.cmpgeu.sci.b rd rs1 imm6 31..27=7 26=1 14..12=7 6..2=0x15 1..0=3 + +pv.cmpltu.h rd rs1 rs2 31..27=8 26=1 25=0 14..12=0 6..2=0x15 1..0=3 +pv.cmpltu.sc.h rd rs1 rs2 31..27=8 26=1 25=0 14..12=4 6..2=0x15 1..0=3 +pv.cmpltu.sci.h rd rs1 imm6 31..27=8 26=1 14..12=6 6..2=0x15 1..0=3 +pv.cmpltu.b rd rs1 rs2 31..27=8 26=1 25=0 14..12=1 6..2=0x15 1..0=3 +pv.cmpltu.sc.b rd rs1 rs2 31..27=8 26=1 25=0 14..12=5 6..2=0x15 1..0=3 +pv.cmpltu.sci.b rd rs1 imm6 31..27=8 26=1 14..12=7 6..2=0x15 1..0=3 + +pv.cmpleu.h rd rs1 rs2 31..27=9 26=1 25=0 14..12=0 6..2=0x15 1..0=3 +pv.cmpleu.sc.h rd rs1 rs2 31..27=9 26=1 25=0 14..12=4 6..2=0x15 1..0=3 +pv.cmpleu.sci.h rd rs1 imm6 31..27=9 26=1 14..12=6 6..2=0x15 1..0=3 +pv.cmpleu.b rd rs1 rs2 31..27=9 26=1 25=0 14..12=1 6..2=0x15 1..0=3 +pv.cmpleu.sc.b rd rs1 rs2 31..27=9 26=1 25=0 14..12=5 6..2=0x15 1..0=3 +pv.cmpleu.sci.b rd rs1 imm6 31..27=9 26=1 14..12=7 6..2=0x15 1..0=3 + +pv.add.h.div2 rd rs1 rs2 31..27=14 26=1 25=0 14..12=2 6..2=0x15 1..0=3 +pv.add.h.div4 rd rs1 rs2 31..27=14 26=1 25=0 14..12=4 6..2=0x15 1..0=3 +pv.add.h.div8 rd rs1 rs2 31..27=14 26=1 25=0 14..12=6 6..2=0x15 1..0=3 +pv.sub.h.div2 rd rs1 rs2 31..27=12 26=1 25=0 14..12=2 6..2=0x15 1..0=3 +pv.sub.h.div4 rd rs1 rs2 31..27=12 26=1 25=0 14..12=4 6..2=0x15 1..0=3 +pv.sub.h.div8 rd rs1 rs2 31..27=12 26=1 25=0 14..12=6 6..2=0x15 1..0=3 diff --git a/extensions/unratified/rv32_xpulpvectshufflepack b/extensions/unratified/rv32_xpulpvectshufflepack new file mode 100644 index 00000000..39633f2b --- /dev/null +++ b/extensions/unratified/rv32_xpulpvectshufflepack @@ -0,0 +1,17 @@ +# Xpulp extension subset: shuffle & pack operations + +# INFO: overlaps with rv_v (RVV) + +pv.shuffle.h rd rs1 rs2 31..27=24 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.shuffle.sci.h rd rs1 imm6 31..27=24 26=0 14..12=6 6..2=0x15 1..0=3 +pv.shuffle.b rd rs1 rs2 31..27=24 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.shufflei0.sci.b rd rs1 imm6 31..27=24 26=0 14..12=7 6..2=0x15 1..0=3 +pv.shufflei1.sci.b rd rs1 imm6 31..27=29 26=0 14..12=7 6..2=0x15 1..0=3 +pv.shufflei2.sci.b rd rs1 imm6 31..27=30 26=0 14..12=7 6..2=0x15 1..0=3 +pv.shufflei3.sci.b rd rs1 imm6 31..27=31 26=0 14..12=7 6..2=0x15 1..0=3 +pv.shuffle2.h rd rs1 rs2 31..27=25 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.shuffle2.b rd rs1 rs2 31..27=25 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.pack rd rs1 rs2 31..27=26 26=0 25=0 14..12=0 6..2=0x15 1..0=3 +pv.pack.h rd rs1 rs2 31..27=26 26=0 25=1 14..12=0 6..2=0x15 1..0=3 +pv.packhi.b rd rs1 rs2 31..27=27 26=0 25=0 14..12=1 6..2=0x15 1..0=3 +pv.packlo.b rd rs1 rs2 31..27=28 26=0 25=0 14..12=1 6..2=0x15 1..0=3 diff --git a/extensions/unratified/rv_xcopift b/extensions/unratified/rv_xcopift new file mode 100644 index 00000000..02c988db --- /dev/null +++ b/extensions/unratified/rv_xcopift @@ -0,0 +1,7 @@ +# COPIFT extension +# Both customized flt.d.copift and fcvt.d.wu.copift utilize ssr for data reading and writing + +flt.d.copift rd rs1 rs2 31..27=0x14 14..12=1 26..25=1 6..2=0x0A 1..0=3 + +fcvt.d.w.copift rd rs1 24..20=0 31..27=0x1A rm 26..25=1 6..2=0x0A 1..0=3 +fcvt.d.wu.copift rd rs1 24..20=1 31..27=0x1A rm 26..25=1 6..2=0x0A 1..0=3 diff --git a/extensions/unratified/rv_xdma b/extensions/unratified/rv_xdma new file mode 100644 index 00000000..13ff96cd --- /dev/null +++ b/extensions/unratified/rv_xdma @@ -0,0 +1,14 @@ +# Asynchronous Data Movement extension + +# INFO: overlaps with rv32_xpulppostmod + +dmsrc rs1 rs2 11..7=0 31..25=0 14..12=0 6..2=0x0A 1..0=0x3 +dmdst rs1 rs2 11..7=0 31..25=1 14..12=0 6..2=0x0A 1..0=0x3 +dmcpyi rd rs1 imm5 31..25=2 14..12=0 6..2=0x0A 1..0=0x3 +dmcpy rd rs1 rs2 31..25=3 14..12=0 6..2=0x0A 1..0=0x3 +dmstati rd imm5 19..15=0 31..25=4 14..12=0 6..2=0x0A 1..0=0x3 +dmstat rd rs2 19..15=0 31..25=5 14..12=0 6..2=0x0A 1..0=0x3 +dmstr rs1 rs2 11..7=0 31..25=6 14..12=0 6..2=0x0A 1..0=0x3 +dmrep rs1 24..20=0 11..7=0 31..25=7 14..12=0 6..2=0x0A 1..0=0x3 +dmuser rs1 rs2 11..7=0 31..25=8 14..12=0 6..2=0x0A 1..0=0x3 +dminit rd rs1 imm5 31..25=9 14..12=0 6..2=0x0A 1..0=0x3 diff --git a/extensions/unratified/rv_xfrep b/extensions/unratified/rv_xfrep new file mode 100644 index 00000000..94c9c60a --- /dev/null +++ b/extensions/unratified/rv_xfrep @@ -0,0 +1,6 @@ +# Floating-Point Repetition extension + +# INFO: overlaps with rv32_xpulppostmod + +frep.o rs1 imm12 stagger_max stagger_mask 7=1 6..2=0x02 1..0=3 +irep rd rs1 imm12 rm 6..2=0x0F 1..0=3 diff --git a/extensions/unratified/rv_xipu b/extensions/unratified/rv_xipu new file mode 100644 index 00000000..fe3c0998 --- /dev/null +++ b/extensions/unratified/rv_xipu @@ -0,0 +1,101 @@ +# Integer processing unit extension + +# INFO: overlaps with rv32_xpulphwloop, rv32_xpulpminmax + +imv.x.w rd rs1 24..20=0 31..27=0x1C 14..12=0 26..25=0 6..2=0x16 1..0=3 +imv.w.x rd rs1 24..20=0 31..27=0x1E 14..12=0 26..25=0 6..2=0x16 1..0=3 + +iaddi rd rs1 imm12 14..12=0 6..2=0x1E 1..0=3 +islli rd rs1 31..26=0 shamt 14..12=1 6..2=0x1E 1..0=3 +islti rd rs1 imm12 14..12=2 6..2=0x1E 1..0=3 +isltiu rd rs1 imm12 14..12=3 6..2=0x1E 1..0=3 +ixori rd rs1 imm12 14..12=4 6..2=0x1E 1..0=3 +isrli rd rs1 31..26=0 shamt 14..12=5 6..2=0x1E 1..0=3 +israi rd rs1 31..26=16 shamt 14..12=5 6..2=0x1E 1..0=3 +iori rd rs1 imm12 14..12=6 6..2=0x1E 1..0=3 +iandi rd rs1 imm12 14..12=7 6..2=0x1E 1..0=3 + +iadd rd rs1 rs2 31..25=0 14..12=0 6..2=0x16 1..0=3 +isub rd rs1 rs2 31..25=32 14..12=0 6..2=0x16 1..0=3 +isll rd rs1 rs2 31..25=0 14..12=1 6..2=0x16 1..0=3 +islt rd rs1 rs2 31..25=0 14..12=2 6..2=0x16 1..0=3 +isltu rd rs1 rs2 31..25=0 14..12=3 6..2=0x16 1..0=3 +ixor rd rs1 rs2 31..25=0 14..12=4 6..2=0x16 1..0=3 +isrl rd rs1 rs2 31..25=0 14..12=5 6..2=0x16 1..0=3 +isra rd rs1 rs2 31..25=32 14..12=5 6..2=0x16 1..0=3 +ior rd rs1 rs2 31..25=0 14..12=6 6..2=0x16 1..0=3 +iand rd rs1 rs2 31..25=0 14..12=7 6..2=0x16 1..0=3 + +imadd rd rs1 rs2 rs3 26..25=1 14..12=0 6..2=0x16 1..0=3 +imsub rd rs1 rs2 rs3 26..25=1 14..12=1 6..2=0x16 1..0=3 +inmsub rd rs1 rs2 rs3 26..25=1 14..12=2 6..2=0x16 1..0=3 +inmadd rd rs1 rs2 rs3 26..25=1 14..12=3 6..2=0x16 1..0=3 + +imul rd rs1 rs2 31..25=2 14..12=0 6..2=0x16 1..0=3 +imulh rd rs1 rs2 31..25=2 14..12=1 6..2=0x16 1..0=3 +imulhsu rd rs1 rs2 31..25=2 14..12=2 6..2=0x16 1..0=3 +imulhu rd rs1 rs2 31..25=2 14..12=3 6..2=0x16 1..0=3 + +iandn rd rs1 rs2 31..25=32 14..12=7 6..2=0x16 1..0=3 +iorn rd rs1 rs2 31..25=32 14..12=6 6..2=0x16 1..0=3 +ixnor rd rs1 rs2 31..25=32 14..12=4 6..2=0x16 1..0=3 + +islo rd rs1 rs2 31..25=16 14..12=1 6..2=0x16 1..0=3 +isro rd rs1 rs2 31..25=16 14..12=5 6..2=0x16 1..0=3 +irol rd rs1 rs2 31..25=48 14..12=1 6..2=0x16 1..0=3 +iror rd rs1 rs2 31..25=48 14..12=5 6..2=0x16 1..0=3 + +isbclr rd rs1 rs2 31..25=36 14..12=1 6..2=0x16 1..0=3 +isbset rd rs1 rs2 31..25=20 14..12=1 6..2=0x16 1..0=3 +isbinv rd rs1 rs2 31..25=52 14..12=1 6..2=0x16 1..0=3 +isbext rd rs1 rs2 31..25=36 14..12=5 6..2=0x16 1..0=3 +igorc rd rs1 rs2 31..25=20 14..12=5 6..2=0x16 1..0=3 +igrev rd rs1 rs2 31..25=52 14..12=5 6..2=0x16 1..0=3 + +isloi rd rs1 31..26=8 shamt 14..12=1 6..2=0x1E 1..0=3 +isroi rd rs1 31..26=8 shamt 14..12=5 6..2=0x1E 1..0=3 +irori rd rs1 31..26=24 shamt 14..12=5 6..2=0x1E 1..0=3 + +isbclri rd rs1 31..26=18 shamt 14..12=1 6..2=0x1E 1..0=3 +isbseti rd rs1 31..26=10 shamt 14..12=1 6..2=0x1E 1..0=3 +isbinvi rd rs1 31..26=26 shamt 14..12=1 6..2=0x1E 1..0=3 +isbexti rd rs1 31..26=18 shamt 14..12=5 6..2=0x1E 1..0=3 +igorci rd rs1 31..26=10 shamt 14..12=5 6..2=0x1E 1..0=3 +igrevi rd rs1 31..26=26 shamt 14..12=5 6..2=0x1E 1..0=3 + +iclz rd rs1 31..20=0x600 14..12=2 6..2=0x16 1..0=3 +ictz rd rs1 31..20=0x601 14..12=2 6..2=0x16 1..0=3 +ipcnt rd rs1 31..20=0x602 14..12=2 6..2=0x16 1..0=3 +isext.b rd rs1 31..20=0x604 14..12=2 6..2=0x16 1..0=3 +isext.h rd rs1 31..20=0x605 14..12=2 6..2=0x16 1..0=3 + +icrc32.b rd rs1 31..20=0x610 14..12=1 6..2=0x16 1..0=3 +icrc32.h rd rs1 31..20=0x611 14..12=1 6..2=0x16 1..0=3 +icrc32.w rd rs1 31..20=0x612 14..12=1 6..2=0x16 1..0=3 +icrc32c.b rd rs1 31..20=0x618 14..12=1 6..2=0x16 1..0=3 +icrc32c.h rd rs1 31..20=0x619 14..12=1 6..2=0x16 1..0=3 +icrc32c.w rd rs1 31..20=0x61A 14..12=1 6..2=0x16 1..0=3 + +ish1add rd rs1 rs2 31..25=16 14..12=2 6..2=0x16 1..0=3 +ish2add rd rs1 rs2 31..25=16 14..12=4 6..2=0x16 1..0=3 +ish3add rd rs1 rs2 31..25=16 14..12=6 6..2=0x16 1..0=3 + +iclmul rd rs1 rs2 31..25=5 14..12=1 6..2=0x16 1..0=3 +iclmulr rd rs1 rs2 31..25=5 14..12=2 6..2=0x16 1..0=3 +iclmulh rd rs1 rs2 31..25=5 14..12=3 6..2=0x16 1..0=3 +imin rd rs1 rs2 31..25=5 14..12=4 6..2=0x16 1..0=3 +imax rd rs1 rs2 31..25=5 14..12=5 6..2=0x16 1..0=3 +iminu rd rs1 rs2 31..25=5 14..12=6 6..2=0x16 1..0=3 +imaxu rd rs1 rs2 31..25=5 14..12=7 6..2=0x16 1..0=3 + +ishfl rd rs1 rs2 31..25=4 14..12=1 6..2=0x16 1..0=3 +iunshfl rd rs1 rs2 31..25=4 14..12=5 6..2=0x16 1..0=3 +ibext rd rs1 rs2 31..25=4 14..12=6 6..2=0x16 1..0=3 +ibdep rd rs1 rs2 31..25=36 14..12=6 6..2=0x16 1..0=3 +ipack rd rs1 rs2 31..25=4 14..12=4 6..2=0x16 1..0=3 +ipacku rd rs1 rs2 31..25=36 14..12=4 6..2=0x16 1..0=3 +ipackh rd rs1 rs2 31..25=4 14..12=7 6..2=0x16 1..0=3 +ibfp rd rs1 rs2 31..25=36 14..12=7 6..2=0x16 1..0=3 + +ishfli rd rs1 31..25=4 shamtw 14..12=1 6..2=0x1E 1..0=3 +iunshfli rd rs1 31..25=4 shamtw 14..12=5 6..2=0x1E 1..0=3 diff --git a/extensions/unratified/rv_xsmallfloat_b b/extensions/unratified/rv_xsmallfloat_b new file mode 100644 index 00000000..edb52e76 --- /dev/null +++ b/extensions/unratified/rv_xsmallfloat_b @@ -0,0 +1,66 @@ +# Smallfloat extension; based on Occamy + +# ASCII Art from here: https://fsymbols.com/generators/carty/ + +# ░██████╗░█████╗░░█████╗░██╗░░░░░░█████╗░██████╗░ +# ██╔════╝██╔══██╗██╔══██╗██║░░░░░██╔══██╗██╔══██╗ +# ╚█████╗░██║░░╚═╝███████║██║░░░░░███████║██████╔╝ +# ░╚═══██╗██║░░██╗██╔══██║██║░░░░░██╔══██║██╔══██╗ +# ██████╔╝╚█████╔╝██║░░██║███████╗██║░░██║██║░░██║ +# ╚═════╝░░╚════╝░╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚═╝ + +#SMALLFLOAT SCALAR (fmt: 0=s, 1=d, 2=h (ha with rm=0b101) 3=b) +# same instrucion format as F extension +# collected under "Xsmallfloat" name - naming not final + +# █▀█ █░█ ▄▀█ █▀█ ▀█▀ █▀▀ █▀█ +# ▀▀█ █▄█ █▀█ █▀▄ ░█░ ██▄ █▀▄ + +# RV32Xfquarter - quarter-precision floats +# startgroup Xfquarter quarter-precision floats +flb rd rs1 imm12 14..12=0 6..2=0x01 1..0=3 +fsb imm12hi rs1 rs2 imm12lo 14..12=0 6..2=0x09 1..0=3 +fmadd.b rd rs1 rs2 rs3 rm 26..25=3 6..2=0x10 1..0=3 +fmsub.b rd rs1 rs2 rs3 rm 26..25=3 6..2=0x11 1..0=3 +fnmsub.b rd rs1 rs2 rs3 rm 26..25=3 6..2=0x12 1..0=3 +fnmadd.b rd rs1 rs2 rs3 rm 26..25=3 6..2=0x13 1..0=3 +fadd.b rd rs1 rs2 31..27=0x00 rm 26..25=3 6..2=0x14 1..0=3 +fsub.b rd rs1 rs2 31..27=0x01 rm 26..25=3 6..2=0x14 1..0=3 +fmul.b rd rs1 rs2 31..27=0x02 rm 26..25=3 6..2=0x14 1..0=3 +fdiv.b rd rs1 rs2 31..27=0x03 rm 26..25=3 6..2=0x14 1..0=3 +fsqrt.b rd rs1 24..20=0 31..27=0x0B rm 26..25=3 6..2=0x14 1..0=3 +fsgnj.b rd rs1 rs2 31..27=0x04 14..12=0 26..25=3 6..2=0x14 1..0=3 +fsgnjn.b rd rs1 rs2 31..27=0x04 14..12=1 26..25=3 6..2=0x14 1..0=3 +fsgnjx.b rd rs1 rs2 31..27=0x04 14..12=2 26..25=3 6..2=0x14 1..0=3 +fmin.b rd rs1 rs2 31..27=0x05 14..12=0 26..25=3 6..2=0x14 1..0=3 +fmax.b rd rs1 rs2 31..27=0x05 14..12=1 26..25=3 6..2=0x14 1..0=3 +feq.b rd rs1 rs2 31..27=0x14 14..12=2 26..25=3 6..2=0x14 1..0=3 +flt.b rd rs1 rs2 31..27=0x14 14..12=1 26..25=3 6..2=0x14 1..0=3 +fle.b rd rs1 rs2 31..27=0x14 14..12=0 26..25=3 6..2=0x14 1..0=3 +fcvt.w.b rd rs1 24..20=0 31..27=0x18 rm 26..25=3 6..2=0x14 1..0=3 +fcvt.wu.b rd rs1 24..20=1 31..27=0x18 rm 26..25=3 6..2=0x14 1..0=3 +fcvt.b.w rd rs1 24..20=0 31..27=0x1A rm 26..25=3 6..2=0x14 1..0=3 +fcvt.b.wu rd rs1 24..20=1 31..27=0x1A rm 26..25=3 6..2=0x14 1..0=3 +fmv.x.b rd rs1 24..20=0 31..27=0x1C 14..12=0 26..25=3 6..2=0x14 1..0=3 +fclass.b rd rs1 24..20=0 31..27=0x1C 14..12=1 26..25=3 6..2=0x14 1..0=3 +fmv.b.x rd rs1 24..20=0 31..27=0x1E 14..12=0 26..25=3 6..2=0x14 1..0=3 +# RV64Xfquarter: in addition to the above +fcvt.l.b rd rs1 24..20=2 31..27=0x18 rm 26..25=3 6..2=0x14 1..0=3 +fcvt.lu.b rd rs1 24..20=3 31..27=0x18 rm 26..25=3 6..2=0x14 1..0=3 +fcvt.b.l rd rs1 24..20=2 31..27=0x1A rm 26..25=3 6..2=0x14 1..0=3 +fcvt.b.lu rd rs1 24..20=3 31..27=0x1A rm 26..25=3 6..2=0x14 1..0=3 +# XfquarterwithF - quarter-precision conversions with F extension +fcvt.s.b rd rs1 24..20=3 31..27=0x08 14..12=0 26..25=0 6..2=0x14 1..0=3 +fcvt.b.s rd rs1 24..20=0 31..27=0x08 rm 26..25=3 6..2=0x14 1..0=3 +# XfquarterwithD - quarter-precision conversions with D extension (in addition to XfquarterwithF) +fcvt.d.b rd rs1 24..20=3 31..27=0x08 14..12=0 26..25=1 6..2=0x14 1..0=3 +fcvt.b.d rd rs1 24..20=1 31..27=0x08 rm 26..25=3 6..2=0x14 1..0=3 +# Xfquarterwithhalf - quarter-precision conversions with Xfhalf extension +fcvt.h.b rd rs1 24..20=3 31..27=0x08 14..12=0 26..25=2 6..2=0x14 1..0=3 +fcvt.b.h rd rs1 24..20=2 31..27=0x08 rm 26..25=3 6..2=0x14 1..0=3 +# endgroup + +# startgroup Xfauxquarter quarter-precision auxiliary operations - requires Xfquarter extension +fmulex.s.b rd rs1 rs2 31..27=0x09 rm 26..25=3 6..2=0x14 1..0=3 +fmacex.s.b rd rs1 rs2 31..27=0x0A rm 26..25=3 6..2=0x14 1..0=3 +# endgroup diff --git a/extensions/unratified/rv_xsmallfloat_h b/extensions/unratified/rv_xsmallfloat_h new file mode 100644 index 00000000..5ce52f85 --- /dev/null +++ b/extensions/unratified/rv_xsmallfloat_h @@ -0,0 +1,74 @@ +# Smallfloat extension; based on Occamy + +# ASCII Art from here: https://fsymbols.com/generators/carty/ + +# ░██████╗░█████╗░░█████╗░██╗░░░░░░█████╗░██████╗░ +# ██╔════╝██╔══██╗██╔══██╗██║░░░░░██╔══██╗██╔══██╗ +# ╚█████╗░██║░░╚═╝███████║██║░░░░░███████║██████╔╝ +# ░╚═══██╗██║░░██╗██╔══██║██║░░░░░██╔══██║██╔══██╗ +# ██████╔╝╚█████╔╝██║░░██║███████╗██║░░██║██║░░██║ +# ╚═════╝░░╚════╝░╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝╚═╝░░╚═╝ + +#SMALLFLOAT SCALAR (fmt: 0=s, 1=d, 2=h (ha with rm=0b101) 3=b) +# same instrucion format as F extension +# collected under "Xsmallfloat" name - naming not final + +# █░█ ▄▀█ █░░ █▀▀ +# █▀█ █▀█ █▄▄ █▀░ + +# Since the original draft proposal, the following have now been ratified +# in rv_zfhmin. +# With the same encoding +# flh rd rs1 imm12 14..12=1 6..2=0x01 1..0=3 +# fsh imm12hi rs1 rs2 imm12lo 14..12=1 6..2=0x09 1..0=3 +# fcvt.h.s rd rs1 24..20=0 31..27=0x08 rm 26..25=2 6..2=0x14 1..0=3 +# fmv.x.h rd rs1 24..20=0 31..27=0x1C 14..12=0 26..25=2 6..2=0x14 1..0=3 +# fmv.h.x rd rs1 24..20=0 31..27=0x1E 14..12=0 26..25=2 6..2=0x14 1..0=3 +# With encoding which is a superset of the original proposal, +# `rm` bits 14..12 no longer hardcoded to zero +# fcvt.s.h rd rs1 24..20=2 31..27=0x08 14..12=0 26..25=0 6..2=0x14 1..0=3 + +# Since the original draft proposal, the following have now been ratified +# in rv_zfh, with the same encoding: +# fmadd.h rd rs1 rs2 rs3 rm 26..25=2 6..2=0x10 1..0=3 +# fmsub.h rd rs1 rs2 rs3 rm 26..25=2 6..2=0x11 1..0=3 +# fnmsub.h rd rs1 rs2 rs3 rm 26..25=2 6..2=0x12 1..0=3 +# fnmadd.h rd rs1 rs2 rs3 rm 26..25=2 6..2=0x13 1..0=3 +# fadd.h rd rs1 rs2 31..27=0x00 rm 26..25=2 6..2=0x14 1..0=3 +# fsub.h rd rs1 rs2 31..27=0x01 rm 26..25=2 6..2=0x14 1..0=3 +# fmul.h rd rs1 rs2 31..27=0x02 rm 26..25=2 6..2=0x14 1..0=3 +# fdiv.h rd rs1 rs2 31..27=0x03 rm 26..25=2 6..2=0x14 1..0=3 +# fsqrt.h rd rs1 24..20=0 31..27=0x0B rm 26..25=2 6..2=0x14 1..0=3 +# fsgnj.h rd rs1 rs2 31..27=0x04 14..12=0 26..25=2 6..2=0x14 1..0=3 +# fsgnjn.h rd rs1 rs2 31..27=0x04 14..12=1 26..25=2 6..2=0x14 1..0=3 +# fsgnjx.h rd rs1 rs2 31..27=0x04 14..12=2 26..25=2 6..2=0x14 1..0=3 +# fmin.h rd rs1 rs2 31..27=0x05 14..12=0 26..25=2 6..2=0x14 1..0=3 +# fmax.h rd rs1 rs2 31..27=0x05 14..12=1 26..25=2 6..2=0x14 1..0=3 +# feq.h rd rs1 rs2 31..27=0x14 14..12=2 26..25=2 6..2=0x14 1..0=3 +# flt.h rd rs1 rs2 31..27=0x14 14..12=1 26..25=2 6..2=0x14 1..0=3 +# fle.h rd rs1 rs2 31..27=0x14 14..12=0 26..25=2 6..2=0x14 1..0=3 +# fclass.h rd rs1 24..20=0 31..27=0x1C 14..12=1 26..25=2 6..2=0x14 1..0=3 +# fcvt.w.h rd rs1 24..20=0 31..27=0x18 rm 26..25=2 6..2=0x14 1..0=3 +# fcvt.wu.h rd rs1 24..20=1 31..27=0x18 rm 26..25=2 6..2=0x14 1..0=3 +# fcvt.h.w rd rs1 24..20=0 31..27=0x1A rm 26..25=2 6..2=0x14 1..0=3 +# fcvt.h.wu rd rs1 24..20=1 31..27=0x1A rm 26..25=2 6..2=0x14 1..0=3 + +# Since the original draft proposal, the following have now been ratified +# in rv64_zfh, with the same encoding: +# fcvt.l.h rd rs1 24..20=2 31..27=0x18 rm 26..25=2 6..2=0x14 1..0=3 +# fcvt.lu.h rd rs1 24..20=3 31..27=0x18 rm 26..25=2 6..2=0x14 1..0=3 +# fcvt.h.l rd rs1 24..20=2 31..27=0x1A rm 26..25=2 6..2=0x14 1..0=3 +# fcvt.h.lu rd rs1 24..20=3 31..27=0x1A rm 26..25=2 6..2=0x14 1..0=3 + +# Since the original draft proposal, the following have now been ratified +# in rv_d_zfhmin, with the same encoding: +# fcvt.h.d rd rs1 24..20=1 31..27=0x08 rm 26..25=2 6..2=0x14 1..0=3 +# With encoding which is a superset of the original proposal, +# `rm` bits 14..12 no longer hardcoded to zero +# fcvt.d.h rd rs1 24..20=2 31..27=0x08 14..12=0 26..25=1 6..2=0x14 1..0=3 + +# Xfauxhalf - half-precision auxiliary operations - requires Xfhalf extension +# startgroup Xfauxhalf half-precision auxiliary operations - requires Xfhalf extension +fmulex.s.h rd rs1 rs2 31..27=0x09 rm 26..25=2 6..2=0x14 1..0=3 +fmacex.s.h rd rs1 rs2 31..27=0x0A rm 26..25=2 6..2=0x14 1..0=3 +# endgroup diff --git a/extensions/unratified/rv_xsmallfloat_vb b/extensions/unratified/rv_xsmallfloat_vb new file mode 100644 index 00000000..da1637f0 --- /dev/null +++ b/extensions/unratified/rv_xsmallfloat_vb @@ -0,0 +1,108 @@ +# Smallfloat extension; based on Occamy + +# ASCII Art from here: https://fsymbols.com/generators/carty/ + +# ██╗░░░██╗███████╗░█████╗░████████╗░█████╗░██████╗░ +# ██║░░░██║██╔════╝██╔══██╗╚══██╔══╝██╔══██╗██╔══██╗ +# ╚██╗░██╔╝█████╗░░██║░░╚═╝░░░██║░░░██║░░██║██████╔╝ +# ░╚████╔╝░██╔══╝░░██║░░██╗░░░██║░░░██║░░██║██╔══██╗ +# ░░╚██╔╝░░███████╗╚█████╔╝░░░██║░░░╚█████╔╝██║░░██║ +# ░░░╚═╝░░░╚══════╝░╚════╝░░░░╚═╝░░░░╚════╝░╚═╝░░╚═╝ + +#SMALLFLOAT VECTORIAL (vfmt: 0=s (ILLEGAL in RV32), 1=ah, 2=h, 3=b) +# 31..30=2 29..25=vecfltop rs2 rs1 14=R 13..12=vfmt rd 6..2=OP 1..0=3 +# 29..25=0x00 is already used by a bitman instruction +# collected under Xfvec - naming not final + +# █▀█ █░█ ▄▀█ █▀█ ▀█▀ █▀▀ █▀█ +# ▀▀█ █▄█ █▀█ █▀▄ ░█░ ██▄ █▀▄ + +# Xfvecquarter - vectorial quarter-precision floats - requires FLEN >= 16 +# startgroup Xfvecquarter vectorial quarter-precision floats - requires FLEN >= 16 +vfadd.b rd rs1 rs2 31..30=2 29..25=0x01 14=0 13..12=3 6..2=0x0C 1..0=3 +vfadd.r.b rd rs1 rs2 31..30=2 29..25=0x01 14=1 13..12=3 6..2=0x0C 1..0=3 +vfsub.b rd rs1 rs2 31..30=2 29..25=0x02 14=0 13..12=3 6..2=0x0C 1..0=3 +vfsub.r.b rd rs1 rs2 31..30=2 29..25=0x02 14=1 13..12=3 6..2=0x0C 1..0=3 +vfmul.b rd rs1 rs2 31..30=2 29..25=0x03 14=0 13..12=3 6..2=0x0C 1..0=3 +vfmul.r.b rd rs1 rs2 31..30=2 29..25=0x03 14=1 13..12=3 6..2=0x0C 1..0=3 +vfdiv.b rd rs1 rs2 31..30=2 29..25=0x04 14=0 13..12=3 6..2=0x0C 1..0=3 +vfdiv.r.b rd rs1 rs2 31..30=2 29..25=0x04 14=1 13..12=3 6..2=0x0C 1..0=3 +vfmin.b rd rs1 rs2 31..30=2 29..25=0x05 14=0 13..12=3 6..2=0x0C 1..0=3 +vfmin.r.b rd rs1 rs2 31..30=2 29..25=0x05 14=1 13..12=3 6..2=0x0C 1..0=3 +vfmax.b rd rs1 rs2 31..30=2 29..25=0x06 14=0 13..12=3 6..2=0x0C 1..0=3 +vfmax.r.b rd rs1 rs2 31..30=2 29..25=0x06 14=1 13..12=3 6..2=0x0C 1..0=3 +vfsqrt.b rd rs1 24..20=0 31..30=2 29..25=0x07 14=0 13..12=3 6..2=0x0C 1..0=3 +vfmac.b rd rs1 rs2 31..30=2 29..25=0x08 14=0 13..12=3 6..2=0x0C 1..0=3 +vfmac.r.b rd rs1 rs2 31..30=2 29..25=0x08 14=1 13..12=3 6..2=0x0C 1..0=3 +vfmre.b rd rs1 rs2 31..30=2 29..25=0x09 14=0 13..12=3 6..2=0x0C 1..0=3 +vfmre.r.b rd rs1 rs2 31..30=2 29..25=0x09 14=1 13..12=3 6..2=0x0C 1..0=3 +vfsgnj.b rd rs1 rs2 31..30=2 29..25=0x0D 14=0 13..12=3 6..2=0x0C 1..0=3 +vfsgnj.r.b rd rs1 rs2 31..30=2 29..25=0x0D 14=1 13..12=3 6..2=0x0C 1..0=3 +vfsgnjn.b rd rs1 rs2 31..30=2 29..25=0x0E 14=0 13..12=3 6..2=0x0C 1..0=3 +vfsgnjn.r.b rd rs1 rs2 31..30=2 29..25=0x0E 14=1 13..12=3 6..2=0x0C 1..0=3 +vfsgnjx.b rd rs1 rs2 31..30=2 29..25=0x0F 14=0 13..12=3 6..2=0x0C 1..0=3 +vfsgnjx.r.b rd rs1 rs2 31..30=2 29..25=0x0F 14=1 13..12=3 6..2=0x0C 1..0=3 +vfeq.b rd rs1 rs2 31..30=2 29..25=0x10 14=0 13..12=3 6..2=0x0C 1..0=3 +vfeq.r.b rd rs1 rs2 31..30=2 29..25=0x10 14=1 13..12=3 6..2=0x0C 1..0=3 +vfne.b rd rs1 rs2 31..30=2 29..25=0x11 14=0 13..12=3 6..2=0x0C 1..0=3 +vfne.r.b rd rs1 rs2 31..30=2 29..25=0x11 14=1 13..12=3 6..2=0x0C 1..0=3 +vflt.b rd rs1 rs2 31..30=2 29..25=0x12 14=0 13..12=3 6..2=0x0C 1..0=3 +vflt.r.b rd rs1 rs2 31..30=2 29..25=0x12 14=1 13..12=3 6..2=0x0C 1..0=3 +vfge.b rd rs1 rs2 31..30=2 29..25=0x13 14=0 13..12=3 6..2=0x0C 1..0=3 +vfge.r.b rd rs1 rs2 31..30=2 29..25=0x13 14=1 13..12=3 6..2=0x0C 1..0=3 +vfle.b rd rs1 rs2 31..30=2 29..25=0x14 14=0 13..12=3 6..2=0x0C 1..0=3 +vfle.r.b rd rs1 rs2 31..30=2 29..25=0x14 14=1 13..12=3 6..2=0x0C 1..0=3 +vfgt.b rd rs1 rs2 31..30=2 29..25=0x15 14=0 13..12=3 6..2=0x0C 1..0=3 +vfgt.r.b rd rs1 rs2 31..30=2 29..25=0x15 14=1 13..12=3 6..2=0x0C 1..0=3 +# XfvecquarternothirtytwoD: only unless RV32D +vfmv.x.b rd rs1 24..20=0 31..30=2 29..25=0x0C 14=0 13..12=3 6..2=0x0C 1..0=3 +vfmv.b.x rd rs1 24..20=0 31..30=2 29..25=0x0C 14=1 13..12=3 6..2=0x0C 1..0=3 +vfclass.b rd rs1 24..20=1 31..30=2 29..25=0x0C 14=0 13..12=3 6..2=0x0C 1..0=3 +vfcvt.x.b rd rs1 24..20=2 31..30=2 29..25=0x0C 14=0 13..12=3 6..2=0x0C 1..0=3 +vfcvt.xu.b rd rs1 24..20=2 31..30=2 29..25=0x0C 14=1 13..12=3 6..2=0x0C 1..0=3 +vfcvt.b.x rd rs1 24..20=3 31..30=2 29..25=0x0C 14=0 13..12=3 6..2=0x0C 1..0=3 +vfcvt.b.xu rd rs1 24..20=3 31..30=2 29..25=0x0C 14=1 13..12=3 6..2=0x0C 1..0=3 +# XfvecquarterwithF - vectorial quarter-precision conversions with F extension, a-d legality depends on FLEN +vfcpka.b.s rd rs1 rs2 31..30=2 29..25=0x18 14=0 13..12=3 6..2=0x0C 1..0=3 +vfcpkb.b.s rd rs1 rs2 31..30=2 29..25=0x18 14=1 13..12=3 6..2=0x0C 1..0=3 +vfcpkc.b.s rd rs1 rs2 31..30=2 29..25=0x19 14=0 13..12=3 6..2=0x0C 1..0=3 +vfcpkd.b.s rd rs1 rs2 31..30=2 29..25=0x19 14=1 13..12=3 6..2=0x0C 1..0=3 +# XfvecquarterwithD - vectorial quarter-precision conversions with D extension, a-d legality depends on FLEN (in addition to above) +vfcpka.b.d rd rs1 rs2 31..30=2 29..25=0x1A 14=0 13..12=3 6..2=0x0C 1..0=3 +vfcpkb.b.d rd rs1 rs2 31..30=2 29..25=0x1A 14=1 13..12=3 6..2=0x0C 1..0=3 +vfcpkc.b.d rd rs1 rs2 31..30=2 29..25=0x1B 14=0 13..12=3 6..2=0x0C 1..0=3 +vfcpkd.b.d rd rs1 rs2 31..30=2 29..25=0x1B 14=1 13..12=3 6..2=0x0C 1..0=3 +# Xfvecsinglewithdouble - vectorial single-precision conversions with double +vfcvt.d.s rd rs1 24..20=4 31..30=2 29..25=0x0C 14=0 13..12=1 6..2=0x0C 1..0=3 +vfcvtu.d.s rd rs1 24..20=4 31..30=2 29..25=0x0C 14=1 13..12=1 6..2=0x0C 1..0=3 +# Xfvecquarterwithsingle - vectorial quarter-precision conversions with Xfvecsingle extension +vfcvt.s.b rd rs1 24..20=7 31..30=2 29..25=0x0C 14=0 13..12=0 6..2=0x0C 1..0=3 +vfcvtu.s.b rd rs1 24..20=7 31..30=2 29..25=0x0C 14=1 13..12=0 6..2=0x0C 1..0=3 +vfcvt.b.s rd rs1 24..20=4 31..30=2 29..25=0x0C 14=0 13..12=3 6..2=0x0C 1..0=3 +vfcvtu.b.s rd rs1 24..20=4 31..30=2 29..25=0x0C 14=1 13..12=3 6..2=0x0C 1..0=3 +# Xfvecquarterwithhalf - vectorial quarter-precision conversions with Xfvechalf extension +vfcvt.h.b rd rs1 24..20=7 31..30=2 29..25=0x0C 14=0 13..12=2 6..2=0x0C 1..0=3 +vfcvtu.h.b rd rs1 24..20=7 31..30=2 29..25=0x0C 14=1 13..12=2 6..2=0x0C 1..0=3 +vfcvt.b.h rd rs1 24..20=6 31..30=2 29..25=0x0C 14=0 13..12=3 6..2=0x0C 1..0=3 +vfcvtu.b.h rd rs1 24..20=6 31..30=2 29..25=0x0C 14=1 13..12=3 6..2=0x0C 1..0=3 +vfcvt.b.b rd rs1 24..20=7 31..30=2 29..25=0x0C 14=0 13..12=3 6..2=0x0C 1..0=3 +vfcvtu.b.b rd rs1 24..20=7 31..30=2 29..25=0x0C 14=1 13..12=3 6..2=0x0C 1..0=3 +# endgroup + +# startgroup Xfauxvecquarter vectorial quarter-precision auxiliary operations - requires Xfvecquarter extension +vfsum.b rd rs1 24..20=0x07 31..30=2 29..25=0x07 14=0 13..12=3 6..2=0x0C 1..0=3 +vfnsum.b rd rs1 24..20=0x07 31..30=2 29..25=0x17 14=0 13..12=3 6..2=0x0C 1..0=3 +#vfdotp.b rd rs1 rs2 31..30=2 29..25=0x0A 14=0 13..12=3 6..2=0x0C 1..0=3 +#vfdotp.r.b rd rs1 rs2 31..30=2 29..25=0x0A 14=1 13..12=3 6..2=0x0C 1..0=3 +#vfavg.b rd rs1 rs2 31..30=2 29..25=0x16 14=0 13..12=3 6..2=0x0C 1..0=3 +#vfavg.r.b rd rs1 rs2 31..30=2 29..25=0x16 14=1 13..12=3 6..2=0x0C 1..0=3 +# endgroup + +# startgroup Xfexpauxvecquarter vectorial quarter-precision expanding auxiliary operations +vfsumex.h.b rd rs1 24..20=0x17 31..30=2 29..25=0x07 14=0 13..12=2 6..2=0x0C 1..0=3 +vfnsumex.h.b rd rs1 24..20=0x17 31..30=2 29..25=0x17 14=0 13..12=2 6..2=0x0C 1..0=3 +vfdotpex.h.b rd rs1 rs2 31..30=2 29..25=0x0B 14=0 13..12=2 6..2=0x0C 1..0=3 +vfdotpex.h.r.b rd rs1 rs2 31..30=2 29..25=0x0B 14=1 13..12=2 6..2=0x0C 1..0=3 +vfndotpex.h.b rd rs1 rs2 31..30=2 29..25=0x1D 14=0 13..12=2 6..2=0x0C 1..0=3 +vfndotpex.h.r.b rd rs1 rs2 31..30=2 29..25=0x1D 14=1 13..12=2 6..2=0x0C 1..0=3 +# endgroup diff --git a/extensions/unratified/rv_xsmallfloat_vh b/extensions/unratified/rv_xsmallfloat_vh new file mode 100644 index 00000000..974bf8eb --- /dev/null +++ b/extensions/unratified/rv_xsmallfloat_vh @@ -0,0 +1,95 @@ +# Smallfloat extension; based on Occamy + +# ASCII Art from here: https://fsymbols.com/generators/carty/ + +# ██╗░░░██╗███████╗░█████╗░████████╗░█████╗░██████╗░ +# ██║░░░██║██╔════╝██╔══██╗╚══██╔══╝██╔══██╗██╔══██╗ +# ╚██╗░██╔╝█████╗░░██║░░╚═╝░░░██║░░░██║░░██║██████╔╝ +# ░╚████╔╝░██╔══╝░░██║░░██╗░░░██║░░░██║░░██║██╔══██╗ +# ░░╚██╔╝░░███████╗╚█████╔╝░░░██║░░░╚█████╔╝██║░░██║ +# ░░░╚═╝░░░╚══════╝░╚════╝░░░░╚═╝░░░░╚════╝░╚═╝░░╚═╝ + +#SMALLFLOAT VECTORIAL (vfmt: 0=s (ILLEGAL in RV32), 1=ah, 2=h, 3=b) +# 31..30=2 29..25=vecfltop rs2 rs1 14=R 13..12=vfmt rd 6..2=OP 1..0=3 +# 29..25=0x00 is already used by a bitman instruction +# collected under Xfvec - naming not final + +# █░█ ▄▀█ █░░ █▀▀ +# █▀█ █▀█ █▄▄ █▀░ + +# Xfvechalf - vectorial half-precision floats - requires FLEN >= 32 +# startgroup Xfvechalf vectorial half-precision floats - requires FLEN >= 32 +vfadd.h rd rs1 rs2 31..30=2 29..25=0x01 14=0 13..12=2 6..2=0x0C 1..0=3 +vfadd.r.h rd rs1 rs2 31..30=2 29..25=0x01 14=1 13..12=2 6..2=0x0C 1..0=3 +vfsub.h rd rs1 rs2 31..30=2 29..25=0x02 14=0 13..12=2 6..2=0x0C 1..0=3 +vfsub.r.h rd rs1 rs2 31..30=2 29..25=0x02 14=1 13..12=2 6..2=0x0C 1..0=3 +vfmul.h rd rs1 rs2 31..30=2 29..25=0x03 14=0 13..12=2 6..2=0x0C 1..0=3 +vfmul.r.h rd rs1 rs2 31..30=2 29..25=0x03 14=1 13..12=2 6..2=0x0C 1..0=3 +vfdiv.h rd rs1 rs2 31..30=2 29..25=0x04 14=0 13..12=2 6..2=0x0C 1..0=3 +vfdiv.r.h rd rs1 rs2 31..30=2 29..25=0x04 14=1 13..12=2 6..2=0x0C 1..0=3 +vfmin.h rd rs1 rs2 31..30=2 29..25=0x05 14=0 13..12=2 6..2=0x0C 1..0=3 +vfmin.r.h rd rs1 rs2 31..30=2 29..25=0x05 14=1 13..12=2 6..2=0x0C 1..0=3 +vfmax.h rd rs1 rs2 31..30=2 29..25=0x06 14=0 13..12=2 6..2=0x0C 1..0=3 +vfmax.r.h rd rs1 rs2 31..30=2 29..25=0x06 14=1 13..12=2 6..2=0x0C 1..0=3 +vfsqrt.h rd rs1 24..20=0 31..30=2 29..25=0x07 14=0 13..12=2 6..2=0x0C 1..0=3 +vfmac.h rd rs1 rs2 31..30=2 29..25=0x08 14=0 13..12=2 6..2=0x0C 1..0=3 +vfmac.r.h rd rs1 rs2 31..30=2 29..25=0x08 14=1 13..12=2 6..2=0x0C 1..0=3 +vfmre.h rd rs1 rs2 31..30=2 29..25=0x09 14=0 13..12=2 6..2=0x0C 1..0=3 +vfmre.r.h rd rs1 rs2 31..30=2 29..25=0x09 14=1 13..12=2 6..2=0x0C 1..0=3 +vfclass.h rd rs1 24..20=1 31..30=2 29..25=0x0C 14=0 13..12=2 6..2=0x0C 1..0=3 +vfsgnj.h rd rs1 rs2 31..30=2 29..25=0x0D 14=0 13..12=2 6..2=0x0C 1..0=3 +vfsgnj.r.h rd rs1 rs2 31..30=2 29..25=0x0D 14=1 13..12=2 6..2=0x0C 1..0=3 +vfsgnjn.h rd rs1 rs2 31..30=2 29..25=0x0E 14=0 13..12=2 6..2=0x0C 1..0=3 +vfsgnjn.r.h rd rs1 rs2 31..30=2 29..25=0x0E 14=1 13..12=2 6..2=0x0C 1..0=3 +vfsgnjx.h rd rs1 rs2 31..30=2 29..25=0x0F 14=0 13..12=2 6..2=0x0C 1..0=3 +vfsgnjx.r.h rd rs1 rs2 31..30=2 29..25=0x0F 14=1 13..12=2 6..2=0x0C 1..0=3 +vfeq.h rd rs1 rs2 31..30=2 29..25=0x10 14=0 13..12=2 6..2=0x0C 1..0=3 +vfeq.r.h rd rs1 rs2 31..30=2 29..25=0x10 14=1 13..12=2 6..2=0x0C 1..0=3 +vfne.h rd rs1 rs2 31..30=2 29..25=0x11 14=0 13..12=2 6..2=0x0C 1..0=3 +vfne.r.h rd rs1 rs2 31..30=2 29..25=0x11 14=1 13..12=2 6..2=0x0C 1..0=3 +vflt.h rd rs1 rs2 31..30=2 29..25=0x12 14=0 13..12=2 6..2=0x0C 1..0=3 +vflt.r.h rd rs1 rs2 31..30=2 29..25=0x12 14=1 13..12=2 6..2=0x0C 1..0=3 +vfge.h rd rs1 rs2 31..30=2 29..25=0x13 14=0 13..12=2 6..2=0x0C 1..0=3 +vfge.r.h rd rs1 rs2 31..30=2 29..25=0x13 14=1 13..12=2 6..2=0x0C 1..0=3 +vfle.h rd rs1 rs2 31..30=2 29..25=0x14 14=0 13..12=2 6..2=0x0C 1..0=3 +vfle.r.h rd rs1 rs2 31..30=2 29..25=0x14 14=1 13..12=2 6..2=0x0C 1..0=3 +vfgt.h rd rs1 rs2 31..30=2 29..25=0x15 14=0 13..12=2 6..2=0x0C 1..0=3 +vfgt.r.h rd rs1 rs2 31..30=2 29..25=0x15 14=1 13..12=2 6..2=0x0C 1..0=3 +# XfvechalfnothirtytwoD: only unless RV32D +vfmv.x.h rd rs1 24..20=0 31..30=2 29..25=0x0C 14=0 13..12=2 6..2=0x0C 1..0=3 +vfmv.h.x rd rs1 24..20=0 31..30=2 29..25=0x0C 14=1 13..12=2 6..2=0x0C 1..0=3 +vfcvt.x.h rd rs1 24..20=2 31..30=2 29..25=0x0C 14=0 13..12=2 6..2=0x0C 1..0=3 +vfcvt.xu.h rd rs1 24..20=2 31..30=2 29..25=0x0C 14=1 13..12=2 6..2=0x0C 1..0=3 +vfcvt.h.x rd rs1 24..20=3 31..30=2 29..25=0x0C 14=0 13..12=2 6..2=0x0C 1..0=3 +vfcvt.h.xu rd rs1 24..20=3 31..30=2 29..25=0x0C 14=1 13..12=2 6..2=0x0C 1..0=3 +# XfvechalfwithF - vectorial half-precision conversions with F extension, a-d legality depends on FLEN +vfcpka.h.s rd rs1 rs2 31..30=2 29..25=0x18 14=0 13..12=2 6..2=0x0C 1..0=3 +vfcpkb.h.s rd rs1 rs2 31..30=2 29..25=0x18 14=1 13..12=2 6..2=0x0C 1..0=3 +vfcpkc.h.s rd rs1 rs2 31..30=2 29..25=0x19 14=0 13..12=2 6..2=0x0C 1..0=3 +vfcpkd.h.s rd rs1 rs2 31..30=2 29..25=0x19 14=1 13..12=2 6..2=0x0C 1..0=3 +# XfvechalfwithD - vectorial half-precision conversions with D extension, a-d legality depends on FLEN (in addition to the above) +vfcpka.h.d rd rs1 rs2 31..30=2 29..25=0x1A 14=0 13..12=2 6..2=0x0C 1..0=3 +vfcpkb.h.d rd rs1 rs2 31..30=2 29..25=0x1A 14=1 13..12=2 6..2=0x0C 1..0=3 +vfcpkc.h.d rd rs1 rs2 31..30=2 29..25=0x1B 14=0 13..12=2 6..2=0x0C 1..0=3 +vfcpkd.h.d rd rs1 rs2 31..30=2 29..25=0x1B 14=1 13..12=2 6..2=0x0C 1..0=3 +# Xfvecalthalfwithsingle - vectorial half-precision conversions with Xfvecsingle extension +vfcvt.s.h rd rs1 24..20=6 31..30=2 29..25=0x0C 14=0 13..12=0 6..2=0x0C 1..0=3 +vfcvtu.s.h rd rs1 24..20=6 31..30=2 29..25=0x0C 14=1 13..12=0 6..2=0x0C 1..0=3 +vfcvt.h.s rd rs1 24..20=4 31..30=2 29..25=0x0C 14=0 13..12=2 6..2=0x0C 1..0=3 +vfcvtu.h.s rd rs1 24..20=4 31..30=2 29..25=0x0C 14=1 13..12=2 6..2=0x0C 1..0=3 +# endgroup + +# startgroup Xfexpauxvechalf vectorial half-precision expanding auxiliary operations - requires Xfvechalf extension +vfsumex.s.h rd rs1 24..20=0x16 31..30=2 29..25=0x07 14=0 13..12=0 6..2=0x0C 1..0=3 +vfnsumex.s.h rd rs1 24..20=0x16 31..30=2 29..25=0x17 14=0 13..12=0 6..2=0x0C 1..0=3 +vfdotpex.s.h rd rs1 rs2 31..30=2 29..25=0x0B 14=0 13..12=0 6..2=0x0C 1..0=3 +vfdotpex.s.r.h rd rs1 rs2 31..30=2 29..25=0x0B 14=1 13..12=0 6..2=0x0C 1..0=3 +vfndotpex.s.h rd rs1 rs2 31..30=2 29..25=0x1D 14=0 13..12=0 6..2=0x0C 1..0=3 +vfndotpex.s.r.h rd rs1 rs2 31..30=2 29..25=0x1D 14=1 13..12=0 6..2=0x0C 1..0=3 +# endgroup + +# Xfauxvechalf - vectorial half-precision auxiliary operations - requires Xfvechalf extension +# startgroup Xfauxvechalf vectorial half-precision auxiliary operations - requires Xfvechalf extension +vfsum.h rd rs1 24..20=0x1E 31..30=2 29..25=0x07 14=0 13..12=2 6..2=0x0C 1..0=3 +vfnsum.h rd rs1 24..20=0x1E 31..30=2 29..25=0x17 14=0 13..12=2 6..2=0x0C 1..0=3 +# endgroup diff --git a/extensions/unratified/rv_xsmallfloat_vs b/extensions/unratified/rv_xsmallfloat_vs new file mode 100644 index 00000000..4d73add5 --- /dev/null +++ b/extensions/unratified/rv_xsmallfloat_vs @@ -0,0 +1,91 @@ +# Smallfloat extension; based on Occamy + +# ASCII Art from here: https://fsymbols.com/generators/carty/ + +# ██╗░░░██╗███████╗░█████╗░████████╗░█████╗░██████╗░ +# ██║░░░██║██╔════╝██╔══██╗╚══██╔══╝██╔══██╗██╔══██╗ +# ╚██╗░██╔╝█████╗░░██║░░╚═╝░░░██║░░░██║░░██║██████╔╝ +# ░╚████╔╝░██╔══╝░░██║░░██╗░░░██║░░░██║░░██║██╔══██╗ +# ░░╚██╔╝░░███████╗╚█████╔╝░░░██║░░░╚█████╔╝██║░░██║ +# ░░░╚═╝░░░╚══════╝░╚════╝░░░░╚═╝░░░░╚════╝░╚═╝░░╚═╝ + +#SMALLFLOAT VECTORIAL (vfmt: 0=s (ILLEGAL in RV32), 1=ah, 2=h, 3=b) +# 31..30=2 29..25=vecfltop rs2 rs1 14=R 13..12=vfmt rd 6..2=OP 1..0=3 +# 29..25=0x00 is already used by a bitman instruction +# collected under Xfvec - naming not final + +# █▀ █ █▄░█ █▀▀ █░░ █▀▀ +# ▄█ █ █░▀█ █▄█ █▄▄ ██▄ + +# Xfvecsingle - vectorial single-precision floats - requires FLEN >= 64 +# startgroup Xfvecsingle vectorial single-precision floats - requires FLEN >= 64 +vfadd.s rd rs1 rs2 31..30=2 29..25=0x01 14=0 13..12=0 6..2=0x0C 1..0=3 +vfadd.r.s rd rs1 rs2 31..30=2 29..25=0x01 14=1 13..12=0 6..2=0x0C 1..0=3 +vfsub.s rd rs1 rs2 31..30=2 29..25=0x02 14=0 13..12=0 6..2=0x0C 1..0=3 +vfsub.r.s rd rs1 rs2 31..30=2 29..25=0x02 14=1 13..12=0 6..2=0x0C 1..0=3 +vfmul.s rd rs1 rs2 31..30=2 29..25=0x03 14=0 13..12=0 6..2=0x0C 1..0=3 +vfmul.r.s rd rs1 rs2 31..30=2 29..25=0x03 14=1 13..12=0 6..2=0x0C 1..0=3 +vfdiv.s rd rs1 rs2 31..30=2 29..25=0x04 14=0 13..12=0 6..2=0x0C 1..0=3 +vfdiv.r.s rd rs1 rs2 31..30=2 29..25=0x04 14=1 13..12=0 6..2=0x0C 1..0=3 +vfmin.s rd rs1 rs2 31..30=2 29..25=0x05 14=0 13..12=0 6..2=0x0C 1..0=3 +vfmin.r.s rd rs1 rs2 31..30=2 29..25=0x05 14=1 13..12=0 6..2=0x0C 1..0=3 +vfmax.s rd rs1 rs2 31..30=2 29..25=0x06 14=0 13..12=0 6..2=0x0C 1..0=3 +vfmax.r.s rd rs1 rs2 31..30=2 29..25=0x06 14=1 13..12=0 6..2=0x0C 1..0=3 +vfsqrt.s rd rs1 24..20=0 31..30=2 29..25=0x07 14=0 13..12=0 6..2=0x0C 1..0=3 +vfmac.s rd rs1 rs2 31..30=2 29..25=0x08 14=0 13..12=0 6..2=0x0C 1..0=3 +vfmac.r.s rd rs1 rs2 31..30=2 29..25=0x08 14=1 13..12=0 6..2=0x0C 1..0=3 +vfmre.s rd rs1 rs2 31..30=2 29..25=0x09 14=0 13..12=0 6..2=0x0C 1..0=3 +vfmre.r.s rd rs1 rs2 31..30=2 29..25=0x09 14=1 13..12=0 6..2=0x0C 1..0=3 +vfclass.s rd rs1 24..20=1 31..30=2 29..25=0x0C 14=0 13..12=0 6..2=0x0C 1..0=3 +vfsgnj.s rd rs1 rs2 31..30=2 29..25=0x0D 14=0 13..12=0 6..2=0x0C 1..0=3 +vfsgnj.r.s rd rs1 rs2 31..30=2 29..25=0x0D 14=1 13..12=0 6..2=0x0C 1..0=3 +vfsgnjn.s rd rs1 rs2 31..30=2 29..25=0x0E 14=0 13..12=0 6..2=0x0C 1..0=3 +vfsgnjn.r.s rd rs1 rs2 31..30=2 29..25=0x0E 14=1 13..12=0 6..2=0x0C 1..0=3 +vfsgnjx.s rd rs1 rs2 31..30=2 29..25=0x0F 14=0 13..12=0 6..2=0x0C 1..0=3 +vfsgnjx.r.s rd rs1 rs2 31..30=2 29..25=0x0F 14=1 13..12=0 6..2=0x0C 1..0=3 +vfeq.s rd rs1 rs2 31..30=2 29..25=0x10 14=0 13..12=0 6..2=0x0C 1..0=3 +vfeq.r.s rd rs1 rs2 31..30=2 29..25=0x10 14=1 13..12=0 6..2=0x0C 1..0=3 +vfne.s rd rs1 rs2 31..30=2 29..25=0x11 14=0 13..12=0 6..2=0x0C 1..0=3 +vfne.r.s rd rs1 rs2 31..30=2 29..25=0x11 14=1 13..12=0 6..2=0x0C 1..0=3 +vflt.s rd rs1 rs2 31..30=2 29..25=0x12 14=0 13..12=0 6..2=0x0C 1..0=3 +vflt.r.s rd rs1 rs2 31..30=2 29..25=0x12 14=1 13..12=0 6..2=0x0C 1..0=3 +vfge.s rd rs1 rs2 31..30=2 29..25=0x13 14=0 13..12=0 6..2=0x0C 1..0=3 +vfge.r.s rd rs1 rs2 31..30=2 29..25=0x13 14=1 13..12=0 6..2=0x0C 1..0=3 +vfle.s rd rs1 rs2 31..30=2 29..25=0x14 14=0 13..12=0 6..2=0x0C 1..0=3 +vfle.r.s rd rs1 rs2 31..30=2 29..25=0x14 14=1 13..12=0 6..2=0x0C 1..0=3 +vfgt.s rd rs1 rs2 31..30=2 29..25=0x15 14=0 13..12=0 6..2=0x0C 1..0=3 +vfgt.r.s rd rs1 rs2 31..30=2 29..25=0x15 14=1 13..12=0 6..2=0x0C 1..0=3 +# XfvecsinglenothirtytwoD: only unless RV32D +vfmv.x.s rd rs1 24..20=0 31..30=2 29..25=0x0C 14=0 13..12=0 6..2=0x0C 1..0=3 +vfmv.s.x rd rs1 24..20=0 31..30=2 29..25=0x0C 14=1 13..12=0 6..2=0x0C 1..0=3 +vfcvt.x.s rd rs1 24..20=2 31..30=2 29..25=0x0C 14=0 13..12=0 6..2=0x0C 1..0=3 +vfcvt.xu.s rd rs1 24..20=2 31..30=2 29..25=0x0C 14=1 13..12=0 6..2=0x0C 1..0=3 +vfcvt.s.x rd rs1 24..20=3 31..30=2 29..25=0x0C 14=0 13..12=0 6..2=0x0C 1..0=3 +vfcvt.s.xu rd rs1 24..20=3 31..30=2 29..25=0x0C 14=1 13..12=0 6..2=0x0C 1..0=3 +# XfvecsinglewithF - vectorial single-precision conversions with F extension, a-d legality depends on FLEN +vfcpka.s.s rd rs1 rs2 31..30=2 29..25=0x18 14=0 13..12=0 6..2=0x0C 1..0=3 +vfcpkb.s.s rd rs1 rs2 31..30=2 29..25=0x18 14=1 13..12=0 6..2=0x0C 1..0=3 +vfcpkc.s.s rd rs1 rs2 31..30=2 29..25=0x19 14=0 13..12=0 6..2=0x0C 1..0=3 +vfcpkd.s.s rd rs1 rs2 31..30=2 29..25=0x19 14=1 13..12=0 6..2=0x0C 1..0=3 +# XfvecsinglewithD - vectorial single-precision conversions with D extension, a-d legality depends on FLEN (in addition to the above) +vfcpka.s.d rd rs1 rs2 31..30=2 29..25=0x1A 14=0 13..12=0 6..2=0x0C 1..0=3 +vfcpkb.s.d rd rs1 rs2 31..30=2 29..25=0x1A 14=1 13..12=0 6..2=0x0C 1..0=3 +vfcpkc.s.d rd rs1 rs2 31..30=2 29..25=0x1B 14=0 13..12=0 6..2=0x0C 1..0=3 +vfcpkd.s.d rd rs1 rs2 31..30=2 29..25=0x1B 14=1 13..12=0 6..2=0x0C 1..0=3 +# Xfvecalthalfwithhalf - vectorial alternate half-precision conversions with Xfvechalf extension +vfcvt.h.h rd rs1 24..20=5 31..30=2 29..25=0x0C 14=0 13..12=2 6..2=0x0C 1..0=3 +vfcvtu.h.h rd rs1 24..20=5 31..30=2 29..25=0x0C 14=1 13..12=2 6..2=0x0C 1..0=3 +# endgroup + +# startgroup Xfauxsingle single-precision auxiliary operations - requires F extension +# no instructions currently +# endgroup + +# startgroup Xfauxvecsingle vectorial single-precision auxiliary operations - requires Xfvecsingle extension +vfsum.s rd rs1 24..20=0x1C 31..30=2 29..25=0x07 14=0 13..12=0 6..2=0x0C 1..0=3 +vfnsum.s rd rs1 24..20=0x1C 31..30=2 29..25=0x17 14=0 13..12=0 6..2=0x0C 1..0=3 +#vfdotp.s rd rs1 rs2 31..30=2 29..25=0x0A 14=0 13..12=0 6..2=0x0C 1..0=3 +#vfdotp.r.s rd rs1 rs2 31..30=2 29..25=0x0A 14=1 13..12=0 6..2=0x0C 1..0=3 +#vfavg.s rd rs1 rs2 31..30=2 29..25=0x16 14=0 13..12=0 6..2=0x0C 1..0=3 +#vfavg.r.s rd rs1 rs2 31..30=2 29..25=0x16 14=1 13..12=0 6..2=0x0C 1..0=3 +# endgroup diff --git a/extensions/unratified/rv_xssr b/extensions/unratified/rv_xssr new file mode 100644 index 00000000..c79917e2 --- /dev/null +++ b/extensions/unratified/rv_xssr @@ -0,0 +1,8 @@ +# Stream Semantic Registers extension + +# INFO: overlaps with rv32_xpulppostmod + +scfgri rd imm12 19..15=0 14..12=1 6..2=0x0A 1..0=0x3 +scfgwi rs1 imm12 11..7=0 14..12=2 6..2=0x0A 1..0=0x3 +scfgr rd rs2 31..25=0 19..15=1 14..12=1 6..2=0x0A 1..0=0x3 +scfgw rs1 rs2 31..25=0 11..7=1 14..12=2 6..2=0x0A 1..0=0x3 diff --git a/pulp-llvm-extensions.txt b/pulp-llvm-extensions.txt new file mode 100644 index 00000000..6c010265 --- /dev/null +++ b/pulp-llvm-extensions.txt @@ -0,0 +1,20 @@ +unratified/rv_xdma +unratified/rv_xfrep +unratified/rv_xssr +unratified/rv_xipu +unratified/rv_xcopift +unratified/rv_xsmallfloat_h +unratified/rv_xsmallfloat_b +unratified/rv_xsmallfloat_vs +unratified/rv_xsmallfloat_vh +unratified/rv_xsmallfloat_vb +unratified/rv32_xb +unratified/rv32_xpulpabs +unratified/rv32_xpulpbitop +unratified/rv32_xpulpbr +unratified/rv32_xpulpclip +unratified/rv32_xpulpmacsi +unratified/rv32_xpulpminmax +unratified/rv32_xpulpslet +unratified/rv32_xpulpvect +unratified/rv32_xpulpvectshufflepack From 8dec2659d7718cf1635fc99c7342a33ea63a732a Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Thu, 30 Apr 2026 16:10:18 +0200 Subject: [PATCH 4/5] Add tablegen generation for LLVM 18 --- .gitignore | 3 + src/riscv_opcodes/llvm_utils.py | 1172 +++++++++++++++++++++++++++++++ src/riscv_opcodes/parse.py | 9 + 3 files changed, 1184 insertions(+) create mode 100644 src/riscv_opcodes/llvm_utils.py diff --git a/.gitignore b/.gitignore index 669631a8..e914d74a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,9 @@ inst.spinalhdl inst.sverilog inst.svg instr_dict.json +inst.*.td +csr.td +feature.td __pycache__/ diff --git a/src/riscv_opcodes/llvm_utils.py b/src/riscv_opcodes/llvm_utils.py new file mode 100644 index 00000000..95322a15 --- /dev/null +++ b/src/riscv_opcodes/llvm_utils.py @@ -0,0 +1,1172 @@ +import logging +import os +import re +from dataclasses import asdict, dataclass +from enum import Enum, IntEnum, auto, unique +from pathlib import Path +from typing import Any, List, Optional, Sequence, Set, Tuple + +from .shared_utils import CsrDict, InstrDict, read_extension_file + +logging.basicConfig(level=logging.INFO, format="%(levelname)s:: %(message)s") + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + +def _extract_bits(value: int, offset: int, n: int) -> str: + decimal = (value >> offset) & ((1 << n) - 1) + return "0b" + "{0:b}".format(decimal).zfill(n) + + + +def _is_vector(mnemonic: str) -> bool: + return mnemonic.startswith(("V", "v")) + + +def _ext_basename(ext_path: str) -> str: + """Return the basename of an extension file path, e.g. 'unratified/rv_xssr' -> 'rv_xssr'.""" + return os.path.basename(ext_path) + + +def _ext_to_name(ext_basename: str) -> str: + """Strip leading 'rv[32]_x' to get the RISC-V extension name, e.g. 'rv_xssr' -> 'ssr'.""" + name = ext_basename + if name.startswith("rv_x"): + name = name[4:] + if name.startswith("rv32_x"): + name = name[6:] + if name.startswith("rv64_x"): + name = name[6:] + return name + + +def _ext_to_defprefix(ext_name: str) -> str: + return ext_name.upper() + "_" + + +def _ext_to_decoderns(ext_name: str) -> str: + return ext_name + + +def _ext_to_camel(ext_name: str) -> str: + parts = [part for part in re.split(r"[^0-9A-Za-z]+", ext_name) if part] + return "".join(part[:1].upper() + part[1:] for part in parts) + + +def _ext_to_feature_name(ext_name: str) -> str: + return f"FeatureVendor{_ext_to_camel('x' + ext_name)}" + + +def _ext_to_feature_flag(ext_name: str) -> str: + return f"HasVendor{_ext_to_camel('x' + ext_name)}" + + +def _ext_to_feature_label(ext_name: str) -> str: + return ("x" + ext_name)[:1].upper() + ("x" + ext_name)[1:] + + +def _feature_description(ext_basename: str) -> str: + lines: list[str] = [] + for raw_line in read_extension_file(ext_basename).splitlines(): + if not raw_line.startswith("#"): + break + line = raw_line.removeprefix("#").strip() + if not line: + if lines: + break + continue + if line.startswith(("INFO:", "format of a line")): + continue + lines.append(line) + if line.endswith("extension"): + break + if not lines: + return "Custom extension" + return " ".join(lines) + + +def _ext_predicates(ext_basename: str) -> list[str]: + predicates = [_ext_to_feature_flag(_ext_to_name(ext_basename))] + if ext_basename.startswith("rv32_"): + predicates.append("IsRV32") + elif ext_basename.startswith("rv64_"): + predicates.append("IsRV64") + return predicates + + +def _render_properties(properties: dict) -> str: + if not properties: + return "" + items = ", ".join(f"{k} = {v}" for k, v in properties.items()) + return f"let {items} in\n" + + +def _indent_block(text: str, prefix: str = " ") -> str: + return "".join(prefix + line if line else line for line in text.splitlines(keepends=True)) + + +FP_MEM_LOAD_MNEMONICS = {"flh", "flah", "flb", "flab"} +FP_MEM_STORE_MNEMONICS = {"fsh", "fsah", "fsb", "fsab"} + + +# --------------------------------------------------------------------------- +# Data types +# --------------------------------------------------------------------------- + +@unique +class DataType(Enum): + f8 = "B" + f8alt = "AB" + f16 = "H" + f16alt = "AH" + f32 = "S" + f64 = "D" + integer = "X" + uinteger = "XU" + long = "L" + ulong = "LU" + wide = "W" + uwide = "WU" + + @classmethod + def from_str(cls, type_str: str) -> "DataType": + for label in cls: + if type_str == label.value: + return cls(label) + raise ValueError(f"DataType: cannot recognize data type from string: '{type_str}'") + + +# --------------------------------------------------------------------------- +# Instruction format +# --------------------------------------------------------------------------- + +@unique +class InstructionFormat(IntEnum): + R = 0 + RPRS3 = auto() + RLUIMM5 = auto() + I = auto() + R_RDZ = auto() + U = auto() + R4 = auto() + RVF = auto() + RFRM = auto() + IFRM = auto() + R4FRM = auto() + IIMM12 = auto() + IIMM12_RM = auto() + SIMM12 = auto() + IVF = auto() + ISHAMT = auto() + ISHAMTW = auto() + IIMM12_RS1Z = auto() + IIMM12_RDZ = auto() + FREP_O = auto() + RIMM5 = auto() + RIMM5_RS1Z = auto() + RIMM6 = auto() + R_RS1Z = auto() + R_RDZ_RS2Z = auto() + BIMM12 = auto() + + @classmethod + def _operand_map(cls): + return ( + (cls.R, {"rd", "rs1", "rs2"}), + (cls.RPRS3, {"rs1", "rs2", "prs3"}), + (cls.RLUIMM5, {"rd", "rs1", "rs2", "Luimm5"}), + (cls.I, {"rd", "rs1"}), + (cls.R_RDZ, {"rs1", "rs2"}), + (cls.U, {"rd"}), + (cls.R4, {"rd", "rs1", "rs2", "rs3"}), + (cls.RVF, {"rd", "rs1", "rs2"}), + (cls.RFRM, {"rd", "rs1", "rs2", "rm"}), + (cls.IFRM, {"rd", "rs1", "rm"}), + (cls.R4FRM, {"rs1", "rs2", "rs3", "rd", "rm"}), + (cls.IIMM12, {"rs1", "rd", "imm12"}), + (cls.IIMM12_RM, {"rs1", "rd", "imm12", "rm"}), + (cls.SIMM12, {"rs1", "rs2", "imm12lo", "imm12hi"}), + (cls.IVF, {"rd", "rs1"}), + (cls.ISHAMT, {"rd", "rs1", "shamt"}), + (cls.ISHAMT, {"rd", "rs1", "shamtd"}), + (cls.ISHAMTW, {"rd", "rs1", "shamtw"}), + (cls.IIMM12_RS1Z, {"rd", "imm12"}), + (cls.IIMM12_RDZ, {"rs1", "imm12"}), + (cls.FREP_O, {"rs1", "imm12", "stagger_max", "stagger_mask"}), + (cls.RIMM5, {"rd", "rs1", "imm5"}), + (cls.RIMM5_RS1Z, {"rd", "imm5"}), + (cls.RIMM6, {"rd", "rs1", "imm6"}), + (cls.R_RS1Z, {"rd", "rs2"}), + (cls.R_RDZ_RS2Z, {"rs1"}), + (cls.BIMM12, {"rs1", "imm5", "bimm12hi", "bimm12lo"}), + ) + + @classmethod + def from_operands(cls, operands: Set[str]) -> "InstructionFormat": + for fmt, ops in cls._operand_map(): + if operands == ops: + return cls(fmt) + raise ValueError( + f"InstructionFormat: cannot recognize format from operands: {operands}" + ) + + +# --------------------------------------------------------------------------- +# Encoding dataclass +# --------------------------------------------------------------------------- + +@dataclass +class Encoding: + opcode: str + rs1: str + rs2: str + csr: str + funct2: str + funct3: str + funct6: str + funct7: str + imm12: str + imm11_7: str + imm11_5: str + imm12hi: str + imm12lo: str + f2: str + vecfltop: str + r: str + vfmt: str + + @classmethod + def from_int(cls, value: int) -> "Encoding": + return cls( + opcode = _extract_bits(value, 0, 7), + rs1 = _extract_bits(value, 15, 5), + rs2 = _extract_bits(value, 20, 5), + csr = _extract_bits(value, 20, 12), + funct2 = _extract_bits(value, 25, 2), + funct3 = _extract_bits(value, 12, 3), + funct6 = _extract_bits(value, 26, 6), + funct7 = _extract_bits(value, 25, 7), + imm12 = _extract_bits(value, 20, 12), + imm11_7 = _extract_bits(value, 27, 5), + imm11_5 = _extract_bits(value, 25, 7), + imm12hi = _extract_bits(value, 25, 7), + imm12lo = _extract_bits(value, 7, 5), + f2 = _extract_bits(value, 30, 2), + vecfltop = _extract_bits(value, 25, 5), + r = _extract_bits(value, 14, 1), + vfmt = _extract_bits(value, 12, 2), + ) + + @classmethod + def from_string(cls, s: str) -> "Encoding": + return cls.from_int(int(s, 0)) + + +# --------------------------------------------------------------------------- +# Instruction dataclass +# --------------------------------------------------------------------------- + +@dataclass +class Instruction: + mnemonic: str + encoding: Encoding + format: InstructionFormat + encoding_repr: str + + @classmethod + def from_dict(cls, mnemonic: str, spec: dict) -> "Instruction": + fmt = InstructionFormat.from_operands(set(spec["variable_fields"])) + print(f"Instruction {mnemonic}: operands {spec['variable_fields']} -> format {fmt}") + enc = Encoding.from_string(spec["match"]) + if _is_vector(mnemonic): + if fmt == InstructionFormat.R: + fmt = InstructionFormat.RVF + elif fmt == InstructionFormat.I: + fmt = InstructionFormat.IVF + else: + raise RuntimeError( + f"Unknown vector instruction format for {mnemonic}: {fmt}" + ) + return cls(mnemonic=mnemonic, encoding=enc, format=fmt, + encoding_repr=spec["encoding"]) + + +# --------------------------------------------------------------------------- +# Operand type resolution +# --------------------------------------------------------------------------- + +TBLGEN_OPERAND_TYPES = { + DataType.f8: "FPR16", + DataType.f8alt: "FPR16", + DataType.f16: "FPR16", + DataType.f16alt: "FPR16", + DataType.f32: "FPR32", + DataType.f64: "FPR64", + DataType.integer: "GPR", + DataType.uinteger: "GPR", + DataType.long: "GPR", + DataType.ulong: "GPR", + DataType.wide: "GPR", + DataType.uwide: "GPR", +} + + +def _get_dtypes(mnemonic: str) -> dict: + if mnemonic == "flh": + return {"rs1": "GPR", "rd": TBLGEN_OPERAND_TYPES[DataType.f16]} + elif mnemonic == "flah": + return {"rs1": "GPR", "rd": TBLGEN_OPERAND_TYPES[DataType.f16alt]} + elif mnemonic == "flb": + return {"rs1": "GPR", "rd": TBLGEN_OPERAND_TYPES[DataType.f8]} + elif mnemonic == "flab": + return {"rs1": "GPR", "rd": TBLGEN_OPERAND_TYPES[DataType.f8alt]} + elif mnemonic == "fsh": + return {"rs1": "GPR", "rs2": TBLGEN_OPERAND_TYPES[DataType.f16]} + elif mnemonic == "fsah": + return {"rs1": "GPR", "rs2": TBLGEN_OPERAND_TYPES[DataType.f16alt]} + elif mnemonic == "fsb": + return {"rs1": "GPR", "rs2": TBLGEN_OPERAND_TYPES[DataType.f8]} + elif mnemonic == "fsab": + return {"rs1": "GPR", "rs2": TBLGEN_OPERAND_TYPES[DataType.f8alt]} + + # COPIFT instructions exchange data through SSR-backed floating-point + # registers even when their mnemonics resemble integer/FP conversions or + # comparisons. Their visible asm operands are therefore all FPR64. + if mnemonic.endswith(".copift"): + return {"rs1": "FPR64", "rs2": "FPR64", "rs3": "FPR64", "rd": "FPR64"} + + mn = mnemonic + if _is_vector(mn): + mn = re.sub(r"[\._][rR]", "", mn) + + inst_t = mn.upper().replace(".", "_").split("_")[1:] + try: + source_t = TBLGEN_OPERAND_TYPES[DataType.from_str(inst_t[-1])] + dest_t = TBLGEN_OPERAND_TYPES[DataType.from_str(inst_t[0])] + except (ValueError, IndexError): + # No recognizable FP type suffix: treat as integer instruction. + return {"rs1": "GPR", "rs2": "GPR", "rs3": "GPR", "rd": "GPR"} + + predicates = ("fclass", "feq", "fne", "fgt", "flt", "fle", "fge") + if re.match(r"^(v)?({})".format("|".join(predicates)), mnemonic, re.IGNORECASE): + dest_t = TBLGEN_OPERAND_TYPES[DataType.integer] + + return {"rs1": source_t, "rs2": source_t, "rs3": source_t, "rd": dest_t} + + +def _get_properties(mnemonic: str) -> dict: + props = {"hasSideEffects": 0, "mayLoad": 0, "mayStore": 0} + if mnemonic in ("flh", "flah", "flb", "flab"): + props["mayLoad"] = 1 + elif mnemonic in ("fsh", "fsah", "fsb", "fsab"): + props["mayStore"] = 1 + elif mnemonic in ("p.beqimm", "p.bneimm"): + props["isBranch"] = 1 + props["isTerminator"] = 1 + return props + + +# --------------------------------------------------------------------------- +# Instruction TableGen rendering +# --------------------------------------------------------------------------- + +def _tblgen_def(inst: Instruction, ext_name: str) -> str: + e = inst.encoding + dtype = _get_dtypes(inst.mnemonic) + defprefix = _ext_to_defprefix(ext_name) + decoderns = _ext_to_decoderns(ext_name) + tblgen_name = defprefix + inst.mnemonic.upper().replace(".", "_") + mnemonic = inst.mnemonic.replace("_", ".") + props = _get_properties(inst.mnemonic) + props["DecoderNamespace"] = f'"{decoderns}"' + props_str = _render_properties(props) + + fmt = inst.format + if fmt == InstructionFormat.R: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInstR<\n" + f" {e.funct7}, // funct7\n" + f" {e.funct3}, // funct3\n" + f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2),\n" + f" \"{mnemonic}\", \"$rd, $rs1, $rs2\">,\n" + f" Sched<[]>;\n" + ) + elif fmt == InstructionFormat.RLUIMM5: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInst<\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, uimm5:$imm5),\n" + f" \"{mnemonic}\", \"$rd, $rs1, $rs2, $imm5\",\n" + f" [], InstFormatR>,\n" + f" Sched<[]> {{\n" + f" bits<5> rd;\n" + f" bits<5> rs1;\n" + f" bits<5> rs2;\n" + f" bits<5> imm5;\n" + f" let Inst{{31-30}} = {e.funct2};\n" + f" let Inst{{29-25}} = imm5;\n" + f" let Inst{{24-20}} = rs2;\n" + f" let Inst{{19-15}} = rs1;\n" + f" let Inst{{14-12}} = {e.funct3};\n" + f" let Inst{{11-7}} = rd;\n" + f" let Inst{{6-0}} = {e.opcode};\n" + f"}}\n" + ) + elif fmt == InstructionFormat.RPRS3: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInst<\n" + f" (outs ),\n" + f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, {dtype['rs3']}:$prs3),\n" + f" \"{mnemonic}\", \"$rs1, $rs2, $prs3\",\n" + f" [], InstFormatR>,\n" + f" Sched<[]> {{\n" + f" bits<5> rs1;\n" + f" bits<5> rs2;\n" + f" bits<5> prs3;\n" + f" let Inst{{31-25}} = {e.funct7};\n" + f" let Inst{{24-20}} = rs2;\n" + f" let Inst{{19-15}} = rs1;\n" + f" let Inst{{14-12}} = {e.funct3};\n" + f" let Inst{{11-7}} = prs3;\n" + f" let Inst{{6-0}} = {e.opcode};\n" + f"}}\n" + ) + elif fmt == InstructionFormat.RIMM5: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInst<\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1, uimm5:$imm5),\n" + f" \"{mnemonic}\", \"$rd, $rs1, $imm5\",\n" + f" [], InstFormatR>,\n" + f" Sched<[]> {{\n" + f" bits<5> rd;\n" + f" bits<5> rs1;\n" + f" bits<5> imm5;\n" + f" let Inst{{31-25}} = {e.funct7};\n" + f" let Inst{{24-20}} = imm5;\n" + f" let Inst{{19-15}} = rs1;\n" + f" let Inst{{14-12}} = {e.funct3};\n" + f" let Inst{{11-7}} = rd;\n" + f" let Inst{{6-0}} = {e.opcode};\n" + f"}}\n" + ) + elif fmt == InstructionFormat.RIMM5_RS1Z: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInst<\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins uimm5:$imm5),\n" + f" \"{mnemonic}\", \"$rd, $imm5\",\n" + f" [], InstFormatR>,\n" + f" Sched<[]> {{\n" + f" bits<5> rd;\n" + f" bits<5> imm5;\n" + f" let Inst{{31-25}} = {e.funct7};\n" + f" let Inst{{24-20}} = imm5;\n" + f" let Inst{{19-15}} = 0b00000;\n" + f" let Inst{{14-12}} = {e.funct3};\n" + f" let Inst{{11-7}} = rd;\n" + f" let Inst{{6-0}} = {e.opcode};\n" + f"}}\n" + ) + elif fmt == InstructionFormat.RIMM6: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInst<\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1, simm6:$imm6),\n" + f" \"{mnemonic}\", \"$rd, $rs1, $imm6\",\n" + f" [], InstFormatR>,\n" + f" Sched<[]> {{\n" + f" bits<5> rd;\n" + f" bits<5> rs1;\n" + f" bits<6> imm6;\n" + f" let Inst{{31-26}} = {e.funct6};\n" + f" let Inst{{25-20}} = imm6;\n" + f" let Inst{{19-15}} = rs1;\n" + f" let Inst{{14-12}} = {e.funct3};\n" + f" let Inst{{11-7}} = rd;\n" + f" let Inst{{6-0}} = {e.opcode};\n" + f"}}\n" + ) + elif fmt == InstructionFormat.R_RS1Z: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInst<\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs2']}:$rs2),\n" + f" \"{mnemonic}\", \"$rd, $rs2\",\n" + f" [], InstFormatR>,\n" + f" Sched<[]> {{\n" + f" bits<5> rd;\n" + f" bits<5> rs2;\n" + f" let Inst{{31-25}} = {e.funct7};\n" + f" let Inst{{24-20}} = rs2;\n" + f" let Inst{{19-15}} = {e.rs1};\n" + f" let Inst{{14-12}} = {e.funct3};\n" + f" let Inst{{11-7}} = rd;\n" + f" let Inst{{6-0}} = {e.opcode};\n" + f"}}\n" + ) + elif fmt == InstructionFormat.R_RDZ_RS2Z: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInst<\n" + f" (outs ),\n" + f" (ins {dtype['rs1']}:$rs1),\n" + f" \"{mnemonic}\", \"$rs1\",\n" + f" [], InstFormatR>,\n" + f" Sched<[]> {{\n" + f" bits<5> rs1;\n" + f" let Inst{{31-25}} = {e.funct7};\n" + f" let Inst{{24-20}} = 0b00000;\n" + f" let Inst{{19-15}} = rs1;\n" + f" let Inst{{14-12}} = {e.funct3};\n" + f" let Inst{{11-7}} = 0b00000;\n" + f" let Inst{{6-0}} = {e.opcode};\n" + f"}}\n" + ) + elif fmt == InstructionFormat.I: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInstI<\n" + f" {e.funct3}, // funct3\n" + f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1),\n" + f" \"{mnemonic}\", \"$rd, $rs1\">,\n" + f" Sched<[]> {{\n" + f" let imm12 = {e.imm12};\n" + f"}}\n" + ) + elif fmt == InstructionFormat.IIMM12: + if inst.mnemonic in FP_MEM_LOAD_MNEMONICS: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInstI<\n" + f" {e.funct3}, // funct3\n" + f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins GPRMem:$rs1, simm12:$imm12),\n" + f" \"{mnemonic}\", \"$rd, ${{imm12}}(${{rs1}})\">,\n" + f" Sched<[]>;\n" + ) + return ( + f"{props_str}" + f"def {tblgen_name} : RVInstI<\n" + f" {e.funct3}, // funct3\n" + f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1, simm12:$imm12),\n" + f" \"{mnemonic}\", \"$rd, $rs1, ${{imm12}}(${{rs1}})\">,\n" + f" Sched<[]>;\n" + ) + elif fmt == InstructionFormat.IIMM12_RM: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInst<\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1, simm12:$imm12, frmarg:$frm),\n" + f" \"{mnemonic}\", \"$rd, $rs1, $imm12, $frm\",\n" + f" [], InstFormatI>,\n" + f" Sched<[]> {{\n" + f" bits<5> rd;\n" + f" bits<5> rs1;\n" + f" bits<12> imm12;\n" + f" bits<3> frm;\n" + f" let Inst{{31-20}} = imm12;\n" + f" let Inst{{19-15}} = rs1;\n" + f" let Inst{{14-12}} = frm;\n" + f" let Inst{{11-7}} = rd;\n" + f" let Inst{{6-0}} = {e.opcode};\n" + f"}}\n" + f"def: InstAlias<\"{mnemonic} $rd, $rs1, $imm12\",\n" + f" ({tblgen_name} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, simm12:$imm12, FRM_DYN)>;\n" + ) + elif fmt == InstructionFormat.IIMM12_RS1Z: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInst<\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins simm12:$imm12),\n" + f" \"{mnemonic}\", \"$rd, $imm12\",\n" + f" [], InstFormatI>,\n" + f" Sched<[]> {{\n" + f" bits<5> rd;\n" + f" bits<12> imm12;\n" + f" let Inst{{31-20}} = imm12;\n" + f" let Inst{{19-15}} = 0b00000;\n" + f" let Inst{{14-12}} = {e.funct3};\n" + f" let Inst{{11-7}} = rd;\n" + f" let Inst{{6-0}} = {e.opcode};\n" + f"}}\n" + ) + elif fmt == InstructionFormat.IIMM12_RDZ: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInst<\n" + f" (outs ),\n" + f" (ins {dtype['rs1']}:$rs1, simm12:$imm12),\n" + f" \"{mnemonic}\", \"$rs1, $imm12\",\n" + f" [], InstFormatI>,\n" + f" Sched<[]> {{\n" + f" bits<5> rs1;\n" + f" bits<12> imm12;\n" + f" let Inst{{31-20}} = imm12;\n" + f" let Inst{{19-15}} = rs1;\n" + f" let Inst{{14-12}} = {e.funct3};\n" + f" let Inst{{11-7}} = 0b00000;\n" + f" let Inst{{6-0}} = {e.opcode};\n" + f"}}\n" + ) + elif fmt == InstructionFormat.FREP_O: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInst<\n" + f" (outs ),\n" + f" (ins {dtype['rs1']}:$rs1, simm12:$imm12, uimm3:$stagger_max, uimm4:$stagger_mask),\n" + f" \"{mnemonic}\", \"$rs1, $imm12, $stagger_max, $stagger_mask\",\n" + f" [], InstFormatI>,\n" + f" Sched<[]> {{\n" + f" bits<12> imm12;\n" + f" bits<5> rs1;\n" + f" bits<3> stagger_max;\n" + f" bits<4> stagger_mask;\n" + f" let Inst{{31-20}} = imm12;\n" + f" let Inst{{19-15}} = rs1;\n" + f" let Inst{{14-12}} = stagger_max;\n" + f" let Inst{{11-8}} = stagger_mask;\n" + f" let Inst{{7}} = 0b1;\n" + f" let Inst{{6-0}} = {e.opcode};\n" + f"}}\n" + ) + elif fmt == InstructionFormat.SIMM12: + if inst.mnemonic in FP_MEM_STORE_MNEMONICS: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInstS<\n" + f" {e.funct3}, // funct3\n" + f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" (outs ),\n" + f" (ins {dtype['rs2']}:$rs2, GPRMem:$rs1, simm12:$imm12),\n" + f" \"{mnemonic}\", \"$rs2, ${{imm12}}(${{rs1}})\">,\n" + f" Sched<[]>;\n" + ) + return ( + f"{props_str}" + f"def {tblgen_name} : RVInstS<\n" + f" {e.funct3}, // funct3\n" + f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" (outs ),\n" + f" (ins {dtype['rs2']}:$rs2, {dtype['rs1']}:$rs1, simm12:$imm12),\n" + f" \"{mnemonic}\", \"$rs2, ${{imm12}}(${{rs1}})\">,\n" + f" Sched<[]>;\n" + ) + elif fmt == InstructionFormat.ISHAMT: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInstIShift<\n" + f" {e.imm11_7}, // imm11_7\n" + f" {e.funct3}, // funct3\n" + f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1, uimmlog2xlen:$shamt),\n" + f" \"{mnemonic}\", \"$rd, $rs1, $shamt\">,\n" + f" Sched<[]>;\n" + ) + elif fmt == InstructionFormat.ISHAMTW: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInstIShiftW<\n" + f" {e.imm11_5}, // imm11_5\n" + f" {e.funct3}, // funct3\n" + f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1, uimm5:$shamt),\n" + f" \"{mnemonic}\", \"$rd, $rs1, $shamt\">,\n" + f" Sched<[]>;\n" + ) + elif fmt == InstructionFormat.R_RDZ: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInst<\n" + f" (outs ),\n" + f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2),\n" + f" \"{mnemonic}\", \"$rs1, $rs2\",\n" + f" [], InstFormatR>,\n" + f" Sched<[]> {{\n" + f" bits<5> rs1;\n" + f" bits<5> rs2;\n" + f" let Inst{{31-25}} = {e.funct7};\n" + f" let Inst{{24-20}} = rs2;\n" + f" let Inst{{19-15}} = rs1;\n" + f" let Inst{{14-12}} = {e.funct3};\n" + f" let Inst{{11-7}} = {e.imm12lo};\n" + f" let Inst{{6-0}} = {e.opcode};\n" + f"}}\n" + ) + elif fmt == InstructionFormat.BIMM12: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInstB<\n" + f" {e.funct3}, // funct3\n" + f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" (outs ),\n" + f" (ins {dtype['rs1']}:$rs1, simm5:$imm5, simm13_lsb0:$imm12),\n" + f" \"{mnemonic}\", \"$rs1, $imm5, $imm12\">,\n" + f" Sched<[]> {{\n" + f" bits<5> imm5;\n" + f" let rs2 = imm5;\n" + f"}}\n" + ) + elif fmt == InstructionFormat.R4: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInstR4<\n" + f" {e.funct2}, // funct2\n" + f" {e.funct3}, // funct3\n" + f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, {dtype['rs3']}:$rs3),\n" + f" \"{mnemonic}\", \"$rd, $rs1, $rs2, $rs3\">,\n" + f" Sched<[]>;\n" + ) + elif fmt == InstructionFormat.RFRM: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInstRFrm<\n" + f" {e.funct7}, // funct7\n" + f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, frmarg:$frm),\n" + f" \"{mnemonic}\", \"$rd, $rs1, $rs2, $frm\">,\n" + f" Sched<[]>;\n" + f"def: InstAlias<\"{mnemonic} $rd, $rs1, $rs2\",\n" + f" ({tblgen_name} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, FRM_DYN)>;\n" + ) + elif fmt == InstructionFormat.IFRM: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInstRFrm<\n" + f" {e.funct7}, // funct7\n" + f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1, frmarg:$frm),\n" + f" \"{mnemonic}\", \"$rd, $rs1, $frm\">,\n" + f" Sched<[]>\n" + f" {{ let rs2 = {e.rs2}; }}\n" + f"def: InstAlias<\"{mnemonic} $rd, $rs1\",\n" + f" ({tblgen_name} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, FRM_DYN)>;\n" + ) + elif fmt == InstructionFormat.R4FRM: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInstR4Frm<\n" + f" {e.funct2}, // funct2\n" + f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, {dtype['rs3']}:$rs3, frmarg:$frm),\n" + f" \"{mnemonic}\", \"$rd, $rs1, $rs2, $rs3, $frm\">,\n" + f" Sched<[]>;\n" + f"def: InstAlias<\"{mnemonic} $rd, $rs1, $rs2, $rs3\",\n" + f" ({tblgen_name} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, {dtype['rd']}:$rs3, FRM_DYN)>;\n" + ) + elif fmt == InstructionFormat.RVF: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInstR<\n" + f" {e.funct7}, // funct7 = f2:vecfltop\n" + f" {e.funct3}, // funct3 = r:vfmt\n" + f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2),\n" + f" \"{mnemonic}\", \"$rd, $rs1, $rs2\">,\n" + f" Sched<[]>;\n" + ) + elif fmt == InstructionFormat.IVF: + return ( + f"{props_str}" + f"def {tblgen_name} : RVInstR<\n" + f" {e.funct7}, // funct7 = f2:vecfltop\n" + f" {e.funct3}, // funct3 = r:vfmt\n" + f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1),\n" + f" \"{mnemonic}\", \"$rd, $rs1\">,\n" + f" Sched<[]> {{\n" + f" let rs2 = {e.rs2};\n" + f"}}\n" + ) + else: + raise NotImplementedError(f"TableGen rendering not implemented for format: {fmt}") + + +def _tblgen_alias( + inst: Instruction, + uses_mnemonic: str, + uses_extension: str, + defprefix: Optional[str], +) -> str: + dtype = _get_dtypes(inst.mnemonic) + mnemonic = inst.mnemonic.replace("_", ".") + use = uses_mnemonic.upper().replace(".", "_") + if defprefix: + use = defprefix + use + + fmt = inst.format + if fmt == InstructionFormat.R: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs1, $rs2\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2), 0>;\n" + ) + elif fmt == InstructionFormat.RLUIMM5: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs1, $rs2, $imm5\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, uimm5:$imm5), 0>;\n" + ) + elif fmt == InstructionFormat.RPRS3: + return ( + f"def : InstAlias<\"{mnemonic} $rs1, $rs2, $prs3\"," + f" ({use} {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, {dtype['rs3']}:$prs3), 0>;\n" + ) + elif fmt == InstructionFormat.RIMM5: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs1, $imm5\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, uimm5:$imm5), 0>;\n" + ) + elif fmt == InstructionFormat.RIMM5_RS1Z: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $imm5\"," + f" ({use} {dtype['rd']}:$rd, uimm5:$imm5), 0>;\n" + ) + elif fmt == InstructionFormat.RIMM6: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs1, $imm6\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, simm6:$imm6), 0>;\n" + ) + elif fmt == InstructionFormat.R_RS1Z: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs2\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs2']}:$rs2), 0>;\n" + ) + elif fmt == InstructionFormat.R_RDZ_RS2Z: + return ( + f"def : InstAlias<\"{mnemonic} $rs1\"," + f" ({use} {dtype['rs1']}:$rs1), 0>;\n" + ) + elif fmt == InstructionFormat.R_RDZ: + return ( + f"def : InstAlias<\"{mnemonic} $rs1, $rs2\"," + f" ({use} {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2), 0>;\n" + ) + elif fmt == InstructionFormat.I: + rm_arg = "" + if uses_mnemonic.startswith("fcvt") and uses_extension != "rv_xsflts": + rm_arg = ", FRM_DYN" + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs1\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1{rm_arg}), 0>;\n" + ) + elif fmt == InstructionFormat.IIMM12: + if inst.mnemonic in FP_MEM_LOAD_MNEMONICS: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $imm12($rs1)\"," + f" ({use} {dtype['rd']}:$rd, GPRMem:$rs1, simm12:$imm12), 0>;\n" + ) + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs1, $imm12\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, simm12:$imm12), 0>;\n" + ) + elif fmt == InstructionFormat.IIMM12_RM: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs1, $imm12, frmarg:$frm\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, simm12:$imm12, frmarg:$frm), 0>;\n" + ) + elif fmt == InstructionFormat.IIMM12_RS1Z: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $imm12\"," + f" ({use} {dtype['rd']}:$rd, simm12:$imm12), 0>;\n" + ) + elif fmt == InstructionFormat.IIMM12_RDZ: + return ( + f"def : InstAlias<\"{mnemonic} $rs1, $imm12\"," + f" ({use} {dtype['rs1']}:$rs1, simm12:$imm12), 0>;\n" + ) + elif fmt == InstructionFormat.FREP_O: + return ( + f"def : InstAlias<\"{mnemonic} $rs1, $imm12, $stagger_max, $stagger_mask\"," + f" ({use} {dtype['rs1']}:$rs1, simm12:$imm12, uimm3:$stagger_max, uimm4:$stagger_mask), 0>;\n" + ) + elif fmt == InstructionFormat.SIMM12: + if inst.mnemonic in FP_MEM_STORE_MNEMONICS: + return ( + f"def : InstAlias<\"{mnemonic} $rs2, $imm12($rs1)\"," + f" ({use} {dtype['rs2']}:$rs2, GPRMem:$rs1, simm12:$imm12), 0>;\n" + ) + return ( + f"def : InstAlias<\"{mnemonic} $rs2, $rs1, $imm12\"," + f" ({use} {dtype['rs2']}:$rs2, {dtype['rs1']}:$rs1, simm12:$imm12), 0>;\n" + ) + elif fmt == InstructionFormat.ISHAMT: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs1, $shamt\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, uimmlog2xlen:$shamt), 0>;\n" + ) + elif fmt == InstructionFormat.ISHAMTW: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs1, $shamt\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, uimm5:$shamt), 0>;\n" + ) + elif fmt == InstructionFormat.R4: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs1, $rs2, $rs3\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, {dtype['rs3']}:$rs3), 0>;\n" + ) + elif fmt == InstructionFormat.RFRM: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs1, $rs2\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, FRM_DYN), 0>;\n" + ) + elif fmt == InstructionFormat.IFRM: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs1\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, FRM_DYN), 0>;\n" + ) + elif fmt == InstructionFormat.R4FRM: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs1, $rs2, $rs3, frmarg:$frm\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, {dtype['rs3']}:$rs3, frmarg:$frm), 0>;\n" + ) + elif fmt == InstructionFormat.RVF: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs1, $rs2\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2), 0>;\n" + ) + elif fmt == InstructionFormat.IVF: + return ( + f"def : InstAlias<\"{mnemonic} $rd, $rs1\"," + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1), 0>;\n" + ) + else: + raise NotImplementedError(f"Alias rendering not implemented for format: {fmt}") + + +# --------------------------------------------------------------------------- +# CSR TableGen rendering +# --------------------------------------------------------------------------- + +def _csr_def_name(name: str) -> str: + sanitized = re.sub(r"[^A-Za-z0-9_]", "_", name) + return "SysReg_" + sanitized.upper() + + +def _tblgen_csr_def(num: int, name: str) -> str: + return f'def {_csr_def_name(name)} : SysReg<"{name}", 0x{num:03X}>;' + + +def make_llvm_csrs(csr_dict: CsrDict): + """Generate LLVM TableGen CSR definitions from per-extension CSR files.""" + lines = [ + "// Auto-generated by riscv_opcodes. DO NOT EDIT.", + "", + ] + + all_csrs = [pair for pairs in csr_dict.values() for pair in pairs] + for num, name in sorted(all_csrs, key=lambda item: item[0]): + lines.append(_tblgen_csr_def(num, name)) + + Path("csr.td").write_text("\n".join(lines) + "\n", encoding="utf-8") + logging.info("csr.td generated successfully") + + +def make_llvm_features(extensions: Sequence[str]): + """Generate LLVM TableGen feature definitions from the selected extensions.""" + lines = [ + "// Auto-generated by riscv_opcodes. DO NOT EDIT.", + "", + ] + seen: set[str] = set() + + for ext in extensions: + ext_basename = _ext_basename(ext) + if ext_basename in seen: + continue + seen.add(ext_basename) + + ext_name = _ext_to_name(ext_basename) + feature_name = _ext_to_feature_name(ext_name) + feature_flag = _ext_to_feature_flag(ext_name) + feature_label = _ext_to_feature_label(ext_name) + feature_desc = _feature_description(ext_basename) + feature_method = feature_flag[:1].lower() + feature_flag[1:] + + lines.extend([ + f"def {feature_name}", + f' : SubtargetFeature<"x{ext_name}", "{feature_flag}", "true",', + f' "\'{feature_label}\' ({feature_desc})">;', + f"def {feature_flag}", + f' : Predicate<"Subtarget->{feature_method}()">,', + f" AssemblerPredicate<(all_of {feature_name}),", + f' "\'{feature_label}\' ({feature_desc})">;', + "", + ]) + + Path("feature.td").write_text("\n".join(lines), encoding="utf-8") + logging.info("feature.td generated successfully") + +# --------------------------------------------------------------------------- +# LIT test rendering +# --------------------------------------------------------------------------- + +def _get_asm_operands(inst: Instruction) -> List[str]: + if inst.mnemonic in FP_MEM_LOAD_MNEMONICS: + return ["ft0", "0(x0)"] + if inst.mnemonic in FP_MEM_STORE_MNEMONICS: + return ["ft0", "0(x0)"] + + asm_operand_map = { + InstructionFormat.R: ("rd", "rs1", "rs2"), + InstructionFormat.RLUIMM5: ("rd", "rs1", "rs2", "imm5"), + InstructionFormat.RPRS3: ("rs1", "rs2", "prs3"), + InstructionFormat.I: ("rd", "rs1"), + InstructionFormat.R_RDZ: ("rs1", "rs2"), + InstructionFormat.U: ("rd",), + InstructionFormat.R4: ("rd", "rs1", "rs2", "rs3"), + InstructionFormat.RVF: ("rd", "rs1", "rs2"), + InstructionFormat.RFRM: ("rd", "rs1", "rs2", "rm"), + InstructionFormat.IFRM: ("rd", "rs1", "rm"), + InstructionFormat.R4FRM: ("rs1", "rs2", "rs3", "rd", "rm"), + InstructionFormat.IIMM12: ("rs1", "rd", "imm12"), + InstructionFormat.IIMM12_RM: ("rd", "rs1", "imm12", "rm"), + InstructionFormat.IIMM12_RS1Z: ("rd", "imm12"), + InstructionFormat.IIMM12_RDZ: ("rs1", "imm12"), + InstructionFormat.FREP_O: ("rs1", "imm12", "stagger_max", "stagger_mask"), + InstructionFormat.SIMM12: ("rs1", "rs2", "imm12lo", "imm12hi"), + InstructionFormat.IVF: ("rd", "rs1"), + InstructionFormat.ISHAMT: ("rd", "rs1", "shamt"), + InstructionFormat.ISHAMTW: ("rd", "rs1", "shamt"), + InstructionFormat.RIMM5: ("rd", "rs1", "imm5"), + InstructionFormat.RIMM5_RS1Z: ("rd", "imm5"), + InstructionFormat.RIMM6: ("rd", "rs1", "imm6"), + InstructionFormat.R_RS1Z: ("rd", "rs2"), + InstructionFormat.R_RDZ_RS2Z: ("rs1",), + } + dtypes = _get_dtypes(inst.mnemonic) + operands = [] + for op in asm_operand_map[inst.format]: + if op == "rm": + operands.append("rne") + elif op in {"imm12", "imm12lo", "imm12hi", "shamt", "imm5", "imm6", "stagger_max", "stagger_mask"}: + operands.append("0") + elif dtypes.get(op) == "GPR" or (op == "prs3" and dtypes.get("rs3") == "GPR"): + operands.append("x0") + else: + operands.append("ft0") + return operands + + +def _to_lit_test(instructions: dict, ext_name: str) -> str: + lines = [ + f"# RUN: llvm-mc %s -triple=riscv64 -mattr=+d,+{ext_name.lower()} " + f"-riscv-no-aliases -show-encoding | FileCheck %s", + "", + ] + for _, inst in instructions.items(): + operands = _get_asm_operands(inst) + asm = "{} {}".format(inst.mnemonic, ", ".join(operands)) + enc = inst.encoding_repr.replace("-", "0") + assert len(enc) == 32, f"Unexpected encoding length for {inst.mnemonic}" + chunks_repr = re.findall("[01]{8}", enc) + assert len(chunks_repr) == 4 + chunks_int = [int(v, 2) for v in chunks_repr] + chunks_hex = ["0x{:02x}".format(v) for v in chunks_int] + encoding = "[{}]".format(",".join(reversed(chunks_hex))) + lines.append(f"# CHECK: encoding: {encoding}") + lines.append(asm) + lines.append("") + return "\n".join(lines) + + +# --------------------------------------------------------------------------- +# Public entry point +# --------------------------------------------------------------------------- + +def make_llvm(instr_dict: InstrDict, extensions: Sequence[str], csr_dict: CsrDict): + """Generate LLVM TableGen definitions. + + Generates instruction definitions from the provided instruction dictionary. + Groups instructions by their first listed extension and writes one + ``inst..td`` file per extension group. + + Also generates ``feature.td`` and ``csr.td`` files with LLVM feature and + CSR definitions. + """ + # Group instructions by their canonical extension basename. + groups: dict[str, dict] = {} + for mnemonic, spec in instr_dict.items(): + ext_paths = spec.get("extension", []) + if not ext_paths: + continue + ext_key = _ext_basename(ext_paths[0]) + groups.setdefault(ext_key, {})[mnemonic] = spec + + for ext_basename_str, group_spec in groups.items(): + ext_name = _ext_to_name(ext_basename_str) + defprefix = _ext_to_defprefix(ext_name) + predicates = ", ".join(_ext_predicates(ext_basename_str)) + + instructions: dict[str, Instruction] = {} + pseudos: List[Instruction] = [] + uses: List[Tuple[str, str]] = [] + + for mnemonic, spec in group_spec.items(): + mn = mnemonic.replace("_", ".") + try: + inst = Instruction.from_dict(mn, spec) + except (ValueError, NotImplementedError) as e: + logging.warning(f"Skipping {mn}: {e}") + continue + if "is_pseudo_of" in spec: + inst_use = spec["is_pseudo_of"]["instruction"] + ext_use = spec["is_pseudo_of"]["extension"] + pseudos.append(inst) + uses.append((inst_use, ext_use)) + else: + instructions[mn] = inst + + lines = [ + "// Auto-generated by riscv_opcodes. DO NOT EDIT.", + "", + f"let Predicates = [{predicates}] in {{", + ] + + for _, inst in instructions.items(): + try: + lines.append(_indent_block(_tblgen_def(inst, ext_name))) + except (ValueError, NotImplementedError) as e: + logging.warning(f"Skipping render of {inst.mnemonic}: {e}") + + for pseudo, (inst_use, ext_use) in zip(pseudos, uses): + pfx = defprefix if inst_use in instructions else None + if pfx is None: + logging.info( + f"Alias to another extension: {pseudo.mnemonic:10} -> {ext_use}::{inst_use}" + ) + lines.append(_indent_block(_tblgen_alias(pseudo, inst_use, ext_use, pfx))) + + lines.append("}") + + out_path = Path(f"inst.{ext_name}.td") + out_path.write_text("\n".join(lines) + "\n", encoding="utf-8") + logging.info(f"inst.{ext_name}.td generated successfully") + + make_llvm_features(extensions) + make_llvm_csrs(csr_dict) diff --git a/src/riscv_opcodes/parse.py b/src/riscv_opcodes/parse.py index 6390324f..159b76fa 100644 --- a/src/riscv_opcodes/parse.py +++ b/src/riscv_opcodes/parse.py @@ -8,6 +8,7 @@ from .constants import emitted_pseudo_ops from .go_utils import make_go from .latex_utils import make_latex_table, make_priv_latex_table +from .llvm_utils import make_llvm from .rust_utils import make_rust from .shared_utils import add_segmented_vls_insn, create_csr_dict, create_inst_dict from .sverilog_utils import make_sverilog @@ -32,6 +33,7 @@ def generate_extensions( go: bool, latex: bool, svg: bool, + llvm: bool, warn_overlap: bool = False, ): csr_dict = create_csr_dict(csrs) @@ -83,6 +85,9 @@ def generate_extensions( make_svg(instr_dict) logging.info("inst.svg generated successfully") + if llvm: + make_llvm(instr_dict, extensions, csr_dict=csr_dict) + def main(): parser = argparse.ArgumentParser(description="Generate RISC-V constants headers") @@ -103,6 +108,9 @@ def main(): parser.add_argument("-go", action="store_true", help="Generate output for Go") parser.add_argument("-latex", action="store_true", help="Generate output for Latex") parser.add_argument("-svg", action="store_true", help="Generate .svg output") + parser.add_argument( + "-llvm", action="store_true", help="Generate LLVM TableGen output" + ) parser.add_argument( "--warn-overlap", action="store_true", @@ -137,5 +145,6 @@ def main(): args.go, args.latex, args.svg, + args.llvm, args.warn_overlap, ) From 08de734fd8c2d3132cbc47785c988a9b15fba0fa Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Mon, 20 Jul 2026 14:12:42 +0200 Subject: [PATCH 5/5] Update tablegen generation to LLVM 22 --- src/riscv_opcodes/llvm_utils.py | 621 ++++++++++++++++---------------- 1 file changed, 305 insertions(+), 316 deletions(-) diff --git a/src/riscv_opcodes/llvm_utils.py b/src/riscv_opcodes/llvm_utils.py index 95322a15..12b2a7ee 100644 --- a/src/riscv_opcodes/llvm_utils.py +++ b/src/riscv_opcodes/llvm_utils.py @@ -1,12 +1,13 @@ +# pylint: disable=too-many-lines import logging import os import re -from dataclasses import asdict, dataclass +from dataclasses import dataclass from enum import Enum, IntEnum, auto, unique from pathlib import Path -from typing import Any, List, Optional, Sequence, Set, Tuple +from typing import List, Optional, Sequence, Set, Tuple -from .shared_utils import CsrDict, InstrDict, read_extension_file +from .shared_utils import CsrDict, InstrDict, SingleInstr, read_extension_file logging.basicConfig(level=logging.INFO, format="%(levelname)s:: %(message)s") @@ -15,10 +16,10 @@ # Helpers # --------------------------------------------------------------------------- + def _extract_bits(value: int, offset: int, n: int) -> str: decimal = (value >> offset) & ((1 << n) - 1) - return "0b" + "{0:b}".format(decimal).zfill(n) - + return "0b" + f"{decimal:b}".zfill(n) def _is_vector(mnemonic: str) -> bool: @@ -96,7 +97,7 @@ def _ext_predicates(ext_basename: str) -> list[str]: return predicates -def _render_properties(properties: dict) -> str: +def _render_properties(properties: "dict[str, object]") -> str: if not properties: return "" items = ", ".join(f"{k} = {v}" for k, v in properties.items()) @@ -104,7 +105,9 @@ def _render_properties(properties: dict) -> str: def _indent_block(text: str, prefix: str = " ") -> str: - return "".join(prefix + line if line else line for line in text.splitlines(keepends=True)) + return "".join( + prefix + line if line else line for line in text.splitlines(keepends=True) + ) FP_MEM_LOAD_MNEMONICS = {"flh", "flah", "flb", "flab"} @@ -115,33 +118,37 @@ def _indent_block(text: str, prefix: str = " ") -> str: # Data types # --------------------------------------------------------------------------- + @unique class DataType(Enum): - f8 = "B" - f8alt = "AB" - f16 = "H" - f16alt = "AH" - f32 = "S" - f64 = "D" - integer = "X" - uinteger = "XU" - long = "L" - ulong = "LU" - wide = "W" - uwide = "WU" + F8 = "B" + F8ALT = "AB" + F16 = "H" + F16ALT = "AH" + F32 = "S" + F64 = "D" + INTEGER = "X" + UINTEGER = "XU" + LONG = "L" + ULONG = "LU" + WIDE = "W" + UWIDE = "WU" @classmethod def from_str(cls, type_str: str) -> "DataType": for label in cls: if type_str == label.value: return cls(label) - raise ValueError(f"DataType: cannot recognize data type from string: '{type_str}'") + raise ValueError( + f"DataType: cannot recognize data type from string: '{type_str}'" + ) # --------------------------------------------------------------------------- # Instruction format # --------------------------------------------------------------------------- + @unique class InstructionFormat(IntEnum): R = 0 @@ -174,21 +181,21 @@ class InstructionFormat(IntEnum): @classmethod def _operand_map(cls): return ( - (cls.R, {"rd", "rs1", "rs2"}), - (cls.RPRS3, {"rs1", "rs2", "prs3"}), + (cls.R, {"rd", "rs1", "rs2"}), + (cls.RPRS3, {"rs1", "rs2", "prs3"}), (cls.RLUIMM5, {"rd", "rs1", "rs2", "Luimm5"}), - (cls.I, {"rd", "rs1"}), - (cls.R_RDZ, {"rs1", "rs2"}), - (cls.U, {"rd"}), - (cls.R4, {"rd", "rs1", "rs2", "rs3"}), - (cls.RVF, {"rd", "rs1", "rs2"}), - (cls.RFRM, {"rd", "rs1", "rs2", "rm"}), - (cls.IFRM, {"rd", "rs1", "rm"}), - (cls.R4FRM, {"rs1", "rs2", "rs3", "rd", "rm"}), + (cls.I, {"rd", "rs1"}), + (cls.R_RDZ, {"rs1", "rs2"}), + (cls.U, {"rd"}), + (cls.R4, {"rd", "rs1", "rs2", "rs3"}), + (cls.RVF, {"rd", "rs1", "rs2"}), + (cls.RFRM, {"rd", "rs1", "rs2", "rm"}), + (cls.IFRM, {"rd", "rs1", "rm"}), + (cls.R4FRM, {"rs1", "rs2", "rs3", "rd", "rm"}), (cls.IIMM12, {"rs1", "rd", "imm12"}), (cls.IIMM12_RM, {"rs1", "rd", "imm12", "rm"}), (cls.SIMM12, {"rs1", "rs2", "imm12lo", "imm12hi"}), - (cls.IVF, {"rd", "rs1"}), + (cls.IVF, {"rd", "rs1"}), (cls.ISHAMT, {"rd", "rs1", "shamt"}), (cls.ISHAMT, {"rd", "rs1", "shamtd"}), (cls.ISHAMTW, {"rd", "rs1", "shamtw"}), @@ -217,6 +224,7 @@ def from_operands(cls, operands: Set[str]) -> "InstructionFormat": # Encoding dataclass # --------------------------------------------------------------------------- + @dataclass class Encoding: opcode: str @@ -240,23 +248,23 @@ class Encoding: @classmethod def from_int(cls, value: int) -> "Encoding": return cls( - opcode = _extract_bits(value, 0, 7), - rs1 = _extract_bits(value, 15, 5), - rs2 = _extract_bits(value, 20, 5), - csr = _extract_bits(value, 20, 12), - funct2 = _extract_bits(value, 25, 2), - funct3 = _extract_bits(value, 12, 3), - funct6 = _extract_bits(value, 26, 6), - funct7 = _extract_bits(value, 25, 7), - imm12 = _extract_bits(value, 20, 12), - imm11_7 = _extract_bits(value, 27, 5), - imm11_5 = _extract_bits(value, 25, 7), - imm12hi = _extract_bits(value, 25, 7), - imm12lo = _extract_bits(value, 7, 5), - f2 = _extract_bits(value, 30, 2), - vecfltop = _extract_bits(value, 25, 5), - r = _extract_bits(value, 14, 1), - vfmt = _extract_bits(value, 12, 2), + opcode=_extract_bits(value, 0, 7), + rs1=_extract_bits(value, 15, 5), + rs2=_extract_bits(value, 20, 5), + csr=_extract_bits(value, 20, 12), + funct2=_extract_bits(value, 25, 2), + funct3=_extract_bits(value, 12, 3), + funct6=_extract_bits(value, 26, 6), + funct7=_extract_bits(value, 25, 7), + imm12=_extract_bits(value, 20, 12), + imm11_7=_extract_bits(value, 27, 5), + imm11_5=_extract_bits(value, 25, 7), + imm12hi=_extract_bits(value, 25, 7), + imm12lo=_extract_bits(value, 7, 5), + f2=_extract_bits(value, 30, 2), + vecfltop=_extract_bits(value, 25, 5), + r=_extract_bits(value, 14, 1), + vfmt=_extract_bits(value, 12, 2), ) @classmethod @@ -268,6 +276,7 @@ def from_string(cls, s: str) -> "Encoding": # Instruction dataclass # --------------------------------------------------------------------------- + @dataclass class Instruction: mnemonic: str @@ -276,9 +285,11 @@ class Instruction: encoding_repr: str @classmethod - def from_dict(cls, mnemonic: str, spec: dict) -> "Instruction": + def from_dict(cls, mnemonic: str, spec: SingleInstr) -> "Instruction": fmt = InstructionFormat.from_operands(set(spec["variable_fields"])) - print(f"Instruction {mnemonic}: operands {spec['variable_fields']} -> format {fmt}") + print( + f"Instruction {mnemonic}: operands {spec['variable_fields']} -> format {fmt}" + ) enc = Encoding.from_string(spec["match"]) if _is_vector(mnemonic): if fmt == InstructionFormat.R: @@ -289,8 +300,9 @@ def from_dict(cls, mnemonic: str, spec: dict) -> "Instruction": raise RuntimeError( f"Unknown vector instruction format for {mnemonic}: {fmt}" ) - return cls(mnemonic=mnemonic, encoding=enc, format=fmt, - encoding_repr=spec["encoding"]) + return cls( + mnemonic=mnemonic, encoding=enc, format=fmt, encoding_repr=spec["encoding"] + ) # --------------------------------------------------------------------------- @@ -298,38 +310,38 @@ def from_dict(cls, mnemonic: str, spec: dict) -> "Instruction": # --------------------------------------------------------------------------- TBLGEN_OPERAND_TYPES = { - DataType.f8: "FPR16", - DataType.f8alt: "FPR16", - DataType.f16: "FPR16", - DataType.f16alt: "FPR16", - DataType.f32: "FPR32", - DataType.f64: "FPR64", - DataType.integer: "GPR", - DataType.uinteger: "GPR", - DataType.long: "GPR", - DataType.ulong: "GPR", - DataType.wide: "GPR", - DataType.uwide: "GPR", + DataType.F8: "FPR16", + DataType.F8ALT: "FPR16", + DataType.F16: "FPR16", + DataType.F16ALT: "FPR16", + DataType.F32: "FPR32", + DataType.F64: "FPR64", + DataType.INTEGER: "GPR", + DataType.UINTEGER: "GPR", + DataType.LONG: "GPR", + DataType.ULONG: "GPR", + DataType.WIDE: "GPR", + DataType.UWIDE: "GPR", } -def _get_dtypes(mnemonic: str) -> dict: +def _get_dtypes(mnemonic: str) -> "dict[str, str]": if mnemonic == "flh": - return {"rs1": "GPR", "rd": TBLGEN_OPERAND_TYPES[DataType.f16]} - elif mnemonic == "flah": - return {"rs1": "GPR", "rd": TBLGEN_OPERAND_TYPES[DataType.f16alt]} - elif mnemonic == "flb": - return {"rs1": "GPR", "rd": TBLGEN_OPERAND_TYPES[DataType.f8]} - elif mnemonic == "flab": - return {"rs1": "GPR", "rd": TBLGEN_OPERAND_TYPES[DataType.f8alt]} - elif mnemonic == "fsh": - return {"rs1": "GPR", "rs2": TBLGEN_OPERAND_TYPES[DataType.f16]} - elif mnemonic == "fsah": - return {"rs1": "GPR", "rs2": TBLGEN_OPERAND_TYPES[DataType.f16alt]} - elif mnemonic == "fsb": - return {"rs1": "GPR", "rs2": TBLGEN_OPERAND_TYPES[DataType.f8]} - elif mnemonic == "fsab": - return {"rs1": "GPR", "rs2": TBLGEN_OPERAND_TYPES[DataType.f8alt]} + return {"rs1": "GPR", "rd": TBLGEN_OPERAND_TYPES[DataType.F16]} + if mnemonic == "flah": + return {"rs1": "GPR", "rd": TBLGEN_OPERAND_TYPES[DataType.F16ALT]} + if mnemonic == "flb": + return {"rs1": "GPR", "rd": TBLGEN_OPERAND_TYPES[DataType.F8]} + if mnemonic == "flab": + return {"rs1": "GPR", "rd": TBLGEN_OPERAND_TYPES[DataType.F8ALT]} + if mnemonic == "fsh": + return {"rs1": "GPR", "rs2": TBLGEN_OPERAND_TYPES[DataType.F16]} + if mnemonic == "fsah": + return {"rs1": "GPR", "rs2": TBLGEN_OPERAND_TYPES[DataType.F16ALT]} + if mnemonic == "fsb": + return {"rs1": "GPR", "rs2": TBLGEN_OPERAND_TYPES[DataType.F8]} + if mnemonic == "fsab": + return {"rs1": "GPR", "rs2": TBLGEN_OPERAND_TYPES[DataType.F8ALT]} # COPIFT instructions exchange data through SSR-backed floating-point # registers even when their mnemonics resemble integer/FP conversions or @@ -344,20 +356,20 @@ def _get_dtypes(mnemonic: str) -> dict: inst_t = mn.upper().replace(".", "_").split("_")[1:] try: source_t = TBLGEN_OPERAND_TYPES[DataType.from_str(inst_t[-1])] - dest_t = TBLGEN_OPERAND_TYPES[DataType.from_str(inst_t[0])] + dest_t = TBLGEN_OPERAND_TYPES[DataType.from_str(inst_t[0])] except (ValueError, IndexError): # No recognizable FP type suffix: treat as integer instruction. return {"rs1": "GPR", "rs2": "GPR", "rs3": "GPR", "rd": "GPR"} predicates = ("fclass", "feq", "fne", "fgt", "flt", "fle", "fge") - if re.match(r"^(v)?({})".format("|".join(predicates)), mnemonic, re.IGNORECASE): - dest_t = TBLGEN_OPERAND_TYPES[DataType.integer] + if re.match(rf"^(v)?({'|'.join(predicates)})", mnemonic, re.IGNORECASE): + dest_t = TBLGEN_OPERAND_TYPES[DataType.INTEGER] return {"rs1": source_t, "rs2": source_t, "rs3": source_t, "rd": dest_t} -def _get_properties(mnemonic: str) -> dict: - props = {"hasSideEffects": 0, "mayLoad": 0, "mayStore": 0} +def _get_properties(mnemonic: str) -> "dict[str, object]": + props: "dict[str, object]" = {"hasSideEffects": 0, "mayLoad": 0, "mayStore": 0} if mnemonic in ("flh", "flah", "flb", "flab"): props["mayLoad"] = 1 elif mnemonic in ("fsh", "fsah", "fsb", "fsab"): @@ -368,10 +380,59 @@ def _get_properties(mnemonic: str) -> dict: return props +# --------------------------------------------------------------------------- +# Opcode def mapping +# --------------------------------------------------------------------------- + +# Maps 7-bit opcode bit strings to the existing OPC_* def names in +# RISCVInstrFormats.td. Using shared defs avoids per-instruction RISCVOpcode +# records, whose Name field is constrained to char Name[10]. +_RISCV_OPCODE_DEFS = { + "0b0000011": "OPC_LOAD", + "0b0000111": "OPC_LOAD_FP", + "0b0001011": "OPC_CUSTOM_0", + "0b0001111": "OPC_MISC_MEM", + "0b0010011": "OPC_OP_IMM", + "0b0010111": "OPC_AUIPC", + "0b0011011": "OPC_OP_IMM_32", + "0b0100011": "OPC_STORE", + "0b0100111": "OPC_STORE_FP", + "0b0101011": "OPC_CUSTOM_1", + "0b0101111": "OPC_AMO", + "0b0110011": "OPC_OP", + "0b0110111": "OPC_LUI", + "0b0111011": "OPC_OP_32", + "0b1000011": "OPC_MADD", + "0b1000111": "OPC_MSUB", + "0b1001011": "OPC_NMSUB", + "0b1001111": "OPC_NMADD", + "0b1010011": "OPC_OP_FP", + "0b1010111": "OPC_OP_V", + "0b1011011": "OPC_CUSTOM_2", + "0b1100011": "OPC_BRANCH", + "0b1100111": "OPC_JALR", + "0b1101111": "OPC_JAL", + "0b1110011": "OPC_SYSTEM", + "0b1111011": "OPC_CUSTOM_3", +} + + +def _opcode_ref(opcode_bits: str, instr_name: str) -> str: + """Return the TableGen expression for an opcode argument. + Uses an existing OPC_* def when available; falls back to an inline + RISCVOpcode<> with a truncated name that fits char Name[10].""" + if opcode_bits in _RISCV_OPCODE_DEFS: + return _RISCV_OPCODE_DEFS[opcode_bits] + # Fallback: inline record — truncate name to 9 chars to fit char Name[10] + short = instr_name[:9] + return f'RISCVOpcode<"{short}", {opcode_bits}>' + + # --------------------------------------------------------------------------- # Instruction TableGen rendering # --------------------------------------------------------------------------- + def _tblgen_def(inst: Instruction, ext_name: str) -> str: e = inst.encoding dtype = _get_dtypes(inst.mnemonic) @@ -390,26 +451,26 @@ def _tblgen_def(inst: Instruction, ext_name: str) -> str: f"def {tblgen_name} : RVInstR<\n" f" {e.funct7}, // funct7\n" f" {e.funct3}, // funct3\n" - f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" {_opcode_ref(e.opcode, tblgen_name)},\n" f" (outs {dtype['rd']}:$rd),\n" f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2),\n" - f" \"{mnemonic}\", \"$rd, $rs1, $rs2\">,\n" + f' "{mnemonic}", "$rd, $rs1, $rs2">,\n' f" Sched<[]>;\n" ) - elif fmt == InstructionFormat.RLUIMM5: + if fmt == InstructionFormat.RLUIMM5: return ( f"{props_str}" f"def {tblgen_name} : RVInst<\n" f" (outs {dtype['rd']}:$rd),\n" f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, uimm5:$imm5),\n" - f" \"{mnemonic}\", \"$rd, $rs1, $rs2, $imm5\",\n" + f' "{mnemonic}", "$rd, $rs1, $rs2, $imm5",\n' f" [], InstFormatR>,\n" f" Sched<[]> {{\n" f" bits<5> rd;\n" f" bits<5> rs1;\n" f" bits<5> rs2;\n" f" bits<5> imm5;\n" - f" let Inst{{31-30}} = {e.funct2};\n" + f" let Inst{{31-30}} = {e.f2};\n" f" let Inst{{29-25}} = imm5;\n" f" let Inst{{24-20}} = rs2;\n" f" let Inst{{19-15}} = rs1;\n" @@ -418,13 +479,13 @@ def _tblgen_def(inst: Instruction, ext_name: str) -> str: f" let Inst{{6-0}} = {e.opcode};\n" f"}}\n" ) - elif fmt == InstructionFormat.RPRS3: + if fmt == InstructionFormat.RPRS3: return ( f"{props_str}" f"def {tblgen_name} : RVInst<\n" f" (outs ),\n" f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, {dtype['rs3']}:$prs3),\n" - f" \"{mnemonic}\", \"$rs1, $rs2, $prs3\",\n" + f' "{mnemonic}", "$rs1, $rs2, $prs3",\n' f" [], InstFormatR>,\n" f" Sched<[]> {{\n" f" bits<5> rs1;\n" @@ -438,13 +499,13 @@ def _tblgen_def(inst: Instruction, ext_name: str) -> str: f" let Inst{{6-0}} = {e.opcode};\n" f"}}\n" ) - elif fmt == InstructionFormat.RIMM5: + if fmt == InstructionFormat.RIMM5: return ( f"{props_str}" f"def {tblgen_name} : RVInst<\n" f" (outs {dtype['rd']}:$rd),\n" f" (ins {dtype['rs1']}:$rs1, uimm5:$imm5),\n" - f" \"{mnemonic}\", \"$rd, $rs1, $imm5\",\n" + f' "{mnemonic}", "$rd, $rs1, $imm5",\n' f" [], InstFormatR>,\n" f" Sched<[]> {{\n" f" bits<5> rd;\n" @@ -458,13 +519,13 @@ def _tblgen_def(inst: Instruction, ext_name: str) -> str: f" let Inst{{6-0}} = {e.opcode};\n" f"}}\n" ) - elif fmt == InstructionFormat.RIMM5_RS1Z: + if fmt == InstructionFormat.RIMM5_RS1Z: return ( f"{props_str}" f"def {tblgen_name} : RVInst<\n" f" (outs {dtype['rd']}:$rd),\n" f" (ins uimm5:$imm5),\n" - f" \"{mnemonic}\", \"$rd, $imm5\",\n" + f' "{mnemonic}", "$rd, $imm5",\n' f" [], InstFormatR>,\n" f" Sched<[]> {{\n" f" bits<5> rd;\n" @@ -477,13 +538,13 @@ def _tblgen_def(inst: Instruction, ext_name: str) -> str: f" let Inst{{6-0}} = {e.opcode};\n" f"}}\n" ) - elif fmt == InstructionFormat.RIMM6: + if fmt == InstructionFormat.RIMM6: return ( f"{props_str}" f"def {tblgen_name} : RVInst<\n" f" (outs {dtype['rd']}:$rd),\n" f" (ins {dtype['rs1']}:$rs1, simm6:$imm6),\n" - f" \"{mnemonic}\", \"$rd, $rs1, $imm6\",\n" + f' "{mnemonic}", "$rd, $rs1, $imm6",\n' f" [], InstFormatR>,\n" f" Sched<[]> {{\n" f" bits<5> rd;\n" @@ -497,13 +558,13 @@ def _tblgen_def(inst: Instruction, ext_name: str) -> str: f" let Inst{{6-0}} = {e.opcode};\n" f"}}\n" ) - elif fmt == InstructionFormat.R_RS1Z: + if fmt == InstructionFormat.R_RS1Z: return ( f"{props_str}" f"def {tblgen_name} : RVInst<\n" f" (outs {dtype['rd']}:$rd),\n" f" (ins {dtype['rs2']}:$rs2),\n" - f" \"{mnemonic}\", \"$rd, $rs2\",\n" + f' "{mnemonic}", "$rd, $rs2",\n' f" [], InstFormatR>,\n" f" Sched<[]> {{\n" f" bits<5> rd;\n" @@ -516,13 +577,13 @@ def _tblgen_def(inst: Instruction, ext_name: str) -> str: f" let Inst{{6-0}} = {e.opcode};\n" f"}}\n" ) - elif fmt == InstructionFormat.R_RDZ_RS2Z: + if fmt == InstructionFormat.R_RDZ_RS2Z: return ( f"{props_str}" f"def {tblgen_name} : RVInst<\n" f" (outs ),\n" f" (ins {dtype['rs1']}:$rs1),\n" - f" \"{mnemonic}\", \"$rs1\",\n" + f' "{mnemonic}", "$rs1",\n' f" [], InstFormatR>,\n" f" Sched<[]> {{\n" f" bits<5> rs1;\n" @@ -534,48 +595,48 @@ def _tblgen_def(inst: Instruction, ext_name: str) -> str: f" let Inst{{6-0}} = {e.opcode};\n" f"}}\n" ) - elif fmt == InstructionFormat.I: + if fmt == InstructionFormat.I: return ( f"{props_str}" f"def {tblgen_name} : RVInstI<\n" f" {e.funct3}, // funct3\n" - f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" {_opcode_ref(e.opcode, tblgen_name)},\n" f" (outs {dtype['rd']}:$rd),\n" f" (ins {dtype['rs1']}:$rs1),\n" - f" \"{mnemonic}\", \"$rd, $rs1\">,\n" + f' "{mnemonic}", "$rd, $rs1">,\n' f" Sched<[]> {{\n" f" let imm12 = {e.imm12};\n" f"}}\n" ) - elif fmt == InstructionFormat.IIMM12: + if fmt == InstructionFormat.IIMM12: if inst.mnemonic in FP_MEM_LOAD_MNEMONICS: return ( f"{props_str}" f"def {tblgen_name} : RVInstI<\n" f" {e.funct3}, // funct3\n" - f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" {_opcode_ref(e.opcode, tblgen_name)},\n" f" (outs {dtype['rd']}:$rd),\n" - f" (ins GPRMem:$rs1, simm12:$imm12),\n" - f" \"{mnemonic}\", \"$rd, ${{imm12}}(${{rs1}})\">,\n" + f" (ins GPRMem:$rs1, simm12_lo:$imm12),\n" + f' "{mnemonic}", "$rd, ${{imm12}}(${{rs1}})">,\n' f" Sched<[]>;\n" ) return ( f"{props_str}" f"def {tblgen_name} : RVInstI<\n" - f" {e.funct3}, // funct3\n" - f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" - f" (outs {dtype['rd']}:$rd),\n" - f" (ins {dtype['rs1']}:$rs1, simm12:$imm12),\n" - f" \"{mnemonic}\", \"$rd, $rs1, ${{imm12}}(${{rs1}})\">,\n" - f" Sched<[]>;\n" + f" {e.funct3}, // funct3\n" + f" {_opcode_ref(e.opcode, tblgen_name)},\n" + f" (outs {dtype['rd']}:$rd),\n" + f" (ins {dtype['rs1']}:$rs1, simm12_lo:$imm12),\n" + f' "{mnemonic}", "$rd, $rs1, ${{imm12}}(${{rs1}})">,\n' + f" Sched<[]>;\n" ) - elif fmt == InstructionFormat.IIMM12_RM: + if fmt == InstructionFormat.IIMM12_RM: return ( f"{props_str}" f"def {tblgen_name} : RVInst<\n" f" (outs {dtype['rd']}:$rd),\n" - f" (ins {dtype['rs1']}:$rs1, simm12:$imm12, frmarg:$frm),\n" - f" \"{mnemonic}\", \"$rd, $rs1, $imm12, $frm\",\n" + f" (ins {dtype['rs1']}:$rs1, simm12_lo:$imm12, frmarg:$frm),\n" + f' "{mnemonic}", "$rd, $rs1, $imm12, $frm",\n' f" [], InstFormatI>,\n" f" Sched<[]> {{\n" f" bits<5> rd;\n" @@ -588,16 +649,16 @@ def _tblgen_def(inst: Instruction, ext_name: str) -> str: f" let Inst{{11-7}} = rd;\n" f" let Inst{{6-0}} = {e.opcode};\n" f"}}\n" - f"def: InstAlias<\"{mnemonic} $rd, $rs1, $imm12\",\n" - f" ({tblgen_name} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, simm12:$imm12, FRM_DYN)>;\n" + f'def: InstAlias<"{mnemonic} $rd, $rs1, $imm12",\n' + f" ({tblgen_name} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, simm12_lo:$imm12, FRM_DYN)>;\n" ) - elif fmt == InstructionFormat.IIMM12_RS1Z: + if fmt == InstructionFormat.IIMM12_RS1Z: return ( f"{props_str}" f"def {tblgen_name} : RVInst<\n" f" (outs {dtype['rd']}:$rd),\n" - f" (ins simm12:$imm12),\n" - f" \"{mnemonic}\", \"$rd, $imm12\",\n" + f" (ins simm12_lo:$imm12),\n" + f' "{mnemonic}", "$rd, $imm12",\n' f" [], InstFormatI>,\n" f" Sched<[]> {{\n" f" bits<5> rd;\n" @@ -609,13 +670,13 @@ def _tblgen_def(inst: Instruction, ext_name: str) -> str: f" let Inst{{6-0}} = {e.opcode};\n" f"}}\n" ) - elif fmt == InstructionFormat.IIMM12_RDZ: + if fmt == InstructionFormat.IIMM12_RDZ: return ( f"{props_str}" f"def {tblgen_name} : RVInst<\n" f" (outs ),\n" - f" (ins {dtype['rs1']}:$rs1, simm12:$imm12),\n" - f" \"{mnemonic}\", \"$rs1, $imm12\",\n" + f" (ins {dtype['rs1']}:$rs1, simm12_lo:$imm12),\n" + f' "{mnemonic}", "$rs1, $imm12",\n' f" [], InstFormatI>,\n" f" Sched<[]> {{\n" f" bits<5> rs1;\n" @@ -627,13 +688,13 @@ def _tblgen_def(inst: Instruction, ext_name: str) -> str: f" let Inst{{6-0}} = {e.opcode};\n" f"}}\n" ) - elif fmt == InstructionFormat.FREP_O: + if fmt == InstructionFormat.FREP_O: return ( f"{props_str}" f"def {tblgen_name} : RVInst<\n" f" (outs ),\n" - f" (ins {dtype['rs1']}:$rs1, simm12:$imm12, uimm3:$stagger_max, uimm4:$stagger_mask),\n" - f" \"{mnemonic}\", \"$rs1, $imm12, $stagger_max, $stagger_mask\",\n" + f" (ins {dtype['rs1']}:$rs1, simm12_lo:$imm12, uimm3:$stagger_max, uimm4:$stagger_mask),\n" + f' "{mnemonic}", "$rs1, $imm12, $stagger_max, $stagger_mask",\n' f" [], InstFormatI>,\n" f" Sched<[]> {{\n" f" bits<12> imm12;\n" @@ -648,59 +709,59 @@ def _tblgen_def(inst: Instruction, ext_name: str) -> str: f" let Inst{{6-0}} = {e.opcode};\n" f"}}\n" ) - elif fmt == InstructionFormat.SIMM12: + if fmt == InstructionFormat.SIMM12: if inst.mnemonic in FP_MEM_STORE_MNEMONICS: return ( f"{props_str}" f"def {tblgen_name} : RVInstS<\n" f" {e.funct3}, // funct3\n" - f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" {_opcode_ref(e.opcode, tblgen_name)},\n" f" (outs ),\n" - f" (ins {dtype['rs2']}:$rs2, GPRMem:$rs1, simm12:$imm12),\n" - f" \"{mnemonic}\", \"$rs2, ${{imm12}}(${{rs1}})\">,\n" + f" (ins {dtype['rs2']}:$rs2, GPRMem:$rs1, simm12_lo:$imm12),\n" + f' "{mnemonic}", "$rs2, ${{imm12}}(${{rs1}})">,\n' f" Sched<[]>;\n" ) return ( f"{props_str}" f"def {tblgen_name} : RVInstS<\n" - f" {e.funct3}, // funct3\n" - f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" {e.funct3}, // funct3\n" + f" {_opcode_ref(e.opcode, tblgen_name)},\n" f" (outs ),\n" - f" (ins {dtype['rs2']}:$rs2, {dtype['rs1']}:$rs1, simm12:$imm12),\n" - f" \"{mnemonic}\", \"$rs2, ${{imm12}}(${{rs1}})\">,\n" + f" (ins {dtype['rs2']}:$rs2, {dtype['rs1']}:$rs1, simm12_lo:$imm12),\n" + f' "{mnemonic}", "$rs2, ${{imm12}}(${{rs1}})">,\n' f" Sched<[]>;\n" ) - elif fmt == InstructionFormat.ISHAMT: + if fmt == InstructionFormat.ISHAMT: return ( f"{props_str}" f"def {tblgen_name} : RVInstIShift<\n" f" {e.imm11_7}, // imm11_7\n" f" {e.funct3}, // funct3\n" - f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" {_opcode_ref(e.opcode, tblgen_name)},\n" f" (outs {dtype['rd']}:$rd),\n" f" (ins {dtype['rs1']}:$rs1, uimmlog2xlen:$shamt),\n" - f" \"{mnemonic}\", \"$rd, $rs1, $shamt\">,\n" + f' "{mnemonic}", "$rd, $rs1, $shamt">,\n' f" Sched<[]>;\n" ) - elif fmt == InstructionFormat.ISHAMTW: + if fmt == InstructionFormat.ISHAMTW: return ( f"{props_str}" f"def {tblgen_name} : RVInstIShiftW<\n" f" {e.imm11_5}, // imm11_5\n" f" {e.funct3}, // funct3\n" - f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" {_opcode_ref(e.opcode, tblgen_name)},\n" f" (outs {dtype['rd']}:$rd),\n" f" (ins {dtype['rs1']}:$rs1, uimm5:$shamt),\n" - f" \"{mnemonic}\", \"$rd, $rs1, $shamt\">,\n" + f' "{mnemonic}", "$rd, $rs1, $shamt">,\n' f" Sched<[]>;\n" ) - elif fmt == InstructionFormat.R_RDZ: + if fmt == InstructionFormat.R_RDZ: return ( f"{props_str}" f"def {tblgen_name} : RVInst<\n" f" (outs ),\n" f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2),\n" - f" \"{mnemonic}\", \"$rs1, $rs2\",\n" + f' "{mnemonic}", "$rs1, $rs2",\n' f" [], InstFormatR>,\n" f" Sched<[]> {{\n" f" bits<5> rs1;\n" @@ -713,100 +774,99 @@ def _tblgen_def(inst: Instruction, ext_name: str) -> str: f" let Inst{{6-0}} = {e.opcode};\n" f"}}\n" ) - elif fmt == InstructionFormat.BIMM12: + if fmt == InstructionFormat.BIMM12: return ( f"{props_str}" f"def {tblgen_name} : RVInstB<\n" f" {e.funct3}, // funct3\n" - f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" {_opcode_ref(e.opcode, tblgen_name)},\n" f" (outs ),\n" - f" (ins {dtype['rs1']}:$rs1, simm5:$imm5, simm13_lsb0:$imm12),\n" - f" \"{mnemonic}\", \"$rs1, $imm5, $imm12\">,\n" + f" (ins {dtype['rs1']}:$rs1, simm5:$imm5, bare_simm13_lsb0:$imm12),\n" + f' "{mnemonic}", "$rs1, $imm5, $imm12">,\n' f" Sched<[]> {{\n" f" bits<5> imm5;\n" f" let rs2 = imm5;\n" f"}}\n" ) - elif fmt == InstructionFormat.R4: + if fmt == InstructionFormat.R4: return ( f"{props_str}" f"def {tblgen_name} : RVInstR4<\n" f" {e.funct2}, // funct2\n" f" {e.funct3}, // funct3\n" - f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" {_opcode_ref(e.opcode, tblgen_name)},\n" f" (outs {dtype['rd']}:$rd),\n" f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, {dtype['rs3']}:$rs3),\n" - f" \"{mnemonic}\", \"$rd, $rs1, $rs2, $rs3\">,\n" + f' "{mnemonic}", "$rd, $rs1, $rs2, $rs3">,\n' f" Sched<[]>;\n" ) - elif fmt == InstructionFormat.RFRM: + if fmt == InstructionFormat.RFRM: return ( f"{props_str}" f"def {tblgen_name} : RVInstRFrm<\n" f" {e.funct7}, // funct7\n" - f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" {_opcode_ref(e.opcode, tblgen_name)},\n" f" (outs {dtype['rd']}:$rd),\n" f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, frmarg:$frm),\n" - f" \"{mnemonic}\", \"$rd, $rs1, $rs2, $frm\">,\n" + f' "{mnemonic}", "$rd, $rs1, $rs2, $frm">,\n' f" Sched<[]>;\n" - f"def: InstAlias<\"{mnemonic} $rd, $rs1, $rs2\",\n" + f'def: InstAlias<"{mnemonic} $rd, $rs1, $rs2",\n' f" ({tblgen_name} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, FRM_DYN)>;\n" ) - elif fmt == InstructionFormat.IFRM: + if fmt == InstructionFormat.IFRM: return ( f"{props_str}" f"def {tblgen_name} : RVInstRFrm<\n" f" {e.funct7}, // funct7\n" - f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" {_opcode_ref(e.opcode, tblgen_name)},\n" f" (outs {dtype['rd']}:$rd),\n" f" (ins {dtype['rs1']}:$rs1, frmarg:$frm),\n" - f" \"{mnemonic}\", \"$rd, $rs1, $frm\">,\n" + f' "{mnemonic}", "$rd, $rs1, $frm">,\n' f" Sched<[]>\n" f" {{ let rs2 = {e.rs2}; }}\n" - f"def: InstAlias<\"{mnemonic} $rd, $rs1\",\n" + f'def: InstAlias<"{mnemonic} $rd, $rs1",\n' f" ({tblgen_name} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, FRM_DYN)>;\n" ) - elif fmt == InstructionFormat.R4FRM: + if fmt == InstructionFormat.R4FRM: return ( f"{props_str}" f"def {tblgen_name} : RVInstR4Frm<\n" f" {e.funct2}, // funct2\n" - f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" {_opcode_ref(e.opcode, tblgen_name)},\n" f" (outs {dtype['rd']}:$rd),\n" f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, {dtype['rs3']}:$rs3, frmarg:$frm),\n" - f" \"{mnemonic}\", \"$rd, $rs1, $rs2, $rs3, $frm\">,\n" + f' "{mnemonic}", "$rd, $rs1, $rs2, $rs3, $frm">,\n' f" Sched<[]>;\n" - f"def: InstAlias<\"{mnemonic} $rd, $rs1, $rs2, $rs3\",\n" + f'def: InstAlias<"{mnemonic} $rd, $rs1, $rs2, $rs3",\n' f" ({tblgen_name} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, {dtype['rd']}:$rs3, FRM_DYN)>;\n" ) - elif fmt == InstructionFormat.RVF: + if fmt == InstructionFormat.RVF: return ( f"{props_str}" f"def {tblgen_name} : RVInstR<\n" f" {e.funct7}, // funct7 = f2:vecfltop\n" f" {e.funct3}, // funct3 = r:vfmt\n" - f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" {_opcode_ref(e.opcode, tblgen_name)},\n" f" (outs {dtype['rd']}:$rd),\n" f" (ins {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2),\n" - f" \"{mnemonic}\", \"$rd, $rs1, $rs2\">,\n" + f' "{mnemonic}", "$rd, $rs1, $rs2">,\n' f" Sched<[]>;\n" ) - elif fmt == InstructionFormat.IVF: + if fmt == InstructionFormat.IVF: return ( f"{props_str}" f"def {tblgen_name} : RVInstR<\n" f" {e.funct7}, // funct7 = f2:vecfltop\n" f" {e.funct3}, // funct3 = r:vfmt\n" - f" RISCVOpcode<\"{tblgen_name}\", {e.opcode}>,\n" + f" {_opcode_ref(e.opcode, tblgen_name)},\n" f" (outs {dtype['rd']}:$rd),\n" f" (ins {dtype['rs1']}:$rs1),\n" - f" \"{mnemonic}\", \"$rd, $rs1\">,\n" + f' "{mnemonic}", "$rd, $rs1">,\n' f" Sched<[]> {{\n" f" let rs2 = {e.rs2};\n" f"}}\n" ) - else: - raise NotImplementedError(f"TableGen rendering not implemented for format: {fmt}") + raise NotImplementedError(f"TableGen rendering not implemented for format: {fmt}") def _tblgen_alias( @@ -824,145 +884,144 @@ def _tblgen_alias( fmt = inst.format if fmt == InstructionFormat.R: return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs1, $rs2\"," + f'def : InstAlias<"{mnemonic} $rd, $rs1, $rs2",' f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2), 0>;\n" ) - elif fmt == InstructionFormat.RLUIMM5: + if fmt == InstructionFormat.RLUIMM5: return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs1, $rs2, $imm5\"," + f'def : InstAlias<"{mnemonic} $rd, $rs1, $rs2, $imm5",' f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, uimm5:$imm5), 0>;\n" ) - elif fmt == InstructionFormat.RPRS3: + if fmt == InstructionFormat.RPRS3: return ( - f"def : InstAlias<\"{mnemonic} $rs1, $rs2, $prs3\"," + f'def : InstAlias<"{mnemonic} $rs1, $rs2, $prs3",' f" ({use} {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, {dtype['rs3']}:$prs3), 0>;\n" ) - elif fmt == InstructionFormat.RIMM5: + if fmt == InstructionFormat.RIMM5: return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs1, $imm5\"," + f'def : InstAlias<"{mnemonic} $rd, $rs1, $imm5",' f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, uimm5:$imm5), 0>;\n" ) - elif fmt == InstructionFormat.RIMM5_RS1Z: + if fmt == InstructionFormat.RIMM5_RS1Z: return ( - f"def : InstAlias<\"{mnemonic} $rd, $imm5\"," + f'def : InstAlias<"{mnemonic} $rd, $imm5",' f" ({use} {dtype['rd']}:$rd, uimm5:$imm5), 0>;\n" ) - elif fmt == InstructionFormat.RIMM6: + if fmt == InstructionFormat.RIMM6: return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs1, $imm6\"," + f'def : InstAlias<"{mnemonic} $rd, $rs1, $imm6",' f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, simm6:$imm6), 0>;\n" ) - elif fmt == InstructionFormat.R_RS1Z: + if fmt == InstructionFormat.R_RS1Z: return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs2\"," + f'def : InstAlias<"{mnemonic} $rd, $rs2",' f" ({use} {dtype['rd']}:$rd, {dtype['rs2']}:$rs2), 0>;\n" ) - elif fmt == InstructionFormat.R_RDZ_RS2Z: + if fmt == InstructionFormat.R_RDZ_RS2Z: return ( - f"def : InstAlias<\"{mnemonic} $rs1\"," - f" ({use} {dtype['rs1']}:$rs1), 0>;\n" + f'def : InstAlias<"{mnemonic} $rs1",' f" ({use} {dtype['rs1']}:$rs1), 0>;\n" ) - elif fmt == InstructionFormat.R_RDZ: + if fmt == InstructionFormat.R_RDZ: return ( - f"def : InstAlias<\"{mnemonic} $rs1, $rs2\"," + f'def : InstAlias<"{mnemonic} $rs1, $rs2",' f" ({use} {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2), 0>;\n" ) - elif fmt == InstructionFormat.I: + if fmt == InstructionFormat.I: rm_arg = "" if uses_mnemonic.startswith("fcvt") and uses_extension != "rv_xsflts": rm_arg = ", FRM_DYN" return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs1\"," + f'def : InstAlias<"{mnemonic} $rd, $rs1",' f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1{rm_arg}), 0>;\n" ) - elif fmt == InstructionFormat.IIMM12: + if fmt == InstructionFormat.IIMM12: if inst.mnemonic in FP_MEM_LOAD_MNEMONICS: return ( - f"def : InstAlias<\"{mnemonic} $rd, $imm12($rs1)\"," - f" ({use} {dtype['rd']}:$rd, GPRMem:$rs1, simm12:$imm12), 0>;\n" + f'def : InstAlias<"{mnemonic} $rd, $imm12($rs1)",' + f" ({use} {dtype['rd']}:$rd, GPRMem:$rs1, simm12_lo:$imm12), 0>;\n" ) return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs1, $imm12\"," - f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, simm12:$imm12), 0>;\n" + f'def : InstAlias<"{mnemonic} $rd, $rs1, $imm12",' + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, simm12_lo:$imm12), 0>;\n" ) - elif fmt == InstructionFormat.IIMM12_RM: + if fmt == InstructionFormat.IIMM12_RM: return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs1, $imm12, frmarg:$frm\"," - f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, simm12:$imm12, frmarg:$frm), 0>;\n" + f'def : InstAlias<"{mnemonic} $rd, $rs1, $imm12, frmarg:$frm",' + f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, simm12_lo:$imm12, frmarg:$frm), 0>;\n" ) - elif fmt == InstructionFormat.IIMM12_RS1Z: + if fmt == InstructionFormat.IIMM12_RS1Z: return ( - f"def : InstAlias<\"{mnemonic} $rd, $imm12\"," - f" ({use} {dtype['rd']}:$rd, simm12:$imm12), 0>;\n" + f'def : InstAlias<"{mnemonic} $rd, $imm12",' + f" ({use} {dtype['rd']}:$rd, simm12_lo:$imm12), 0>;\n" ) - elif fmt == InstructionFormat.IIMM12_RDZ: + if fmt == InstructionFormat.IIMM12_RDZ: return ( - f"def : InstAlias<\"{mnemonic} $rs1, $imm12\"," - f" ({use} {dtype['rs1']}:$rs1, simm12:$imm12), 0>;\n" + f'def : InstAlias<"{mnemonic} $rs1, $imm12",' + f" ({use} {dtype['rs1']}:$rs1, simm12_lo:$imm12), 0>;\n" ) - elif fmt == InstructionFormat.FREP_O: + if fmt == InstructionFormat.FREP_O: return ( - f"def : InstAlias<\"{mnemonic} $rs1, $imm12, $stagger_max, $stagger_mask\"," - f" ({use} {dtype['rs1']}:$rs1, simm12:$imm12, uimm3:$stagger_max, uimm4:$stagger_mask), 0>;\n" + f'def : InstAlias<"{mnemonic} $rs1, $imm12, $stagger_max, $stagger_mask",' + f" ({use} {dtype['rs1']}:$rs1, simm12_lo:$imm12, uimm3:$stagger_max, uimm4:$stagger_mask), 0>;\n" ) - elif fmt == InstructionFormat.SIMM12: + if fmt == InstructionFormat.SIMM12: if inst.mnemonic in FP_MEM_STORE_MNEMONICS: return ( - f"def : InstAlias<\"{mnemonic} $rs2, $imm12($rs1)\"," - f" ({use} {dtype['rs2']}:$rs2, GPRMem:$rs1, simm12:$imm12), 0>;\n" + f'def : InstAlias<"{mnemonic} $rs2, $imm12($rs1)",' + f" ({use} {dtype['rs2']}:$rs2, GPRMem:$rs1, simm12_lo:$imm12), 0>;\n" ) return ( - f"def : InstAlias<\"{mnemonic} $rs2, $rs1, $imm12\"," - f" ({use} {dtype['rs2']}:$rs2, {dtype['rs1']}:$rs1, simm12:$imm12), 0>;\n" + f'def : InstAlias<"{mnemonic} $rs2, $rs1, $imm12",' + f" ({use} {dtype['rs2']}:$rs2, {dtype['rs1']}:$rs1, simm12_lo:$imm12), 0>;\n" ) - elif fmt == InstructionFormat.ISHAMT: + if fmt == InstructionFormat.ISHAMT: return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs1, $shamt\"," + f'def : InstAlias<"{mnemonic} $rd, $rs1, $shamt",' f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, uimmlog2xlen:$shamt), 0>;\n" ) - elif fmt == InstructionFormat.ISHAMTW: + if fmt == InstructionFormat.ISHAMTW: return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs1, $shamt\"," + f'def : InstAlias<"{mnemonic} $rd, $rs1, $shamt",' f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, uimm5:$shamt), 0>;\n" ) - elif fmt == InstructionFormat.R4: + if fmt == InstructionFormat.R4: return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs1, $rs2, $rs3\"," + f'def : InstAlias<"{mnemonic} $rd, $rs1, $rs2, $rs3",' f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, {dtype['rs3']}:$rs3), 0>;\n" ) - elif fmt == InstructionFormat.RFRM: + if fmt == InstructionFormat.RFRM: return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs1, $rs2\"," + f'def : InstAlias<"{mnemonic} $rd, $rs1, $rs2",' f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, FRM_DYN), 0>;\n" ) - elif fmt == InstructionFormat.IFRM: + if fmt == InstructionFormat.IFRM: return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs1\"," + f'def : InstAlias<"{mnemonic} $rd, $rs1",' f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, FRM_DYN), 0>;\n" ) - elif fmt == InstructionFormat.R4FRM: + if fmt == InstructionFormat.R4FRM: return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs1, $rs2, $rs3, frmarg:$frm\"," + f'def : InstAlias<"{mnemonic} $rd, $rs1, $rs2, $rs3, frmarg:$frm",' f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2, {dtype['rs3']}:$rs3, frmarg:$frm), 0>;\n" ) - elif fmt == InstructionFormat.RVF: + if fmt == InstructionFormat.RVF: return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs1, $rs2\"," + f'def : InstAlias<"{mnemonic} $rd, $rs1, $rs2",' f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1, {dtype['rs2']}:$rs2), 0>;\n" ) - elif fmt == InstructionFormat.IVF: + if fmt == InstructionFormat.IVF: return ( - f"def : InstAlias<\"{mnemonic} $rd, $rs1\"," + f'def : InstAlias<"{mnemonic} $rd, $rs1",' f" ({use} {dtype['rd']}:$rd, {dtype['rs1']}:$rs1), 0>;\n" ) - else: - raise NotImplementedError(f"Alias rendering not implemented for format: {fmt}") + raise NotImplementedError(f"Alias rendering not implemented for format: {fmt}") # --------------------------------------------------------------------------- # CSR TableGen rendering # --------------------------------------------------------------------------- + def _csr_def_name(name: str) -> str: sanitized = re.sub(r"[^A-Za-z0-9_]", "_", name) return "SysReg_" + sanitized.upper() @@ -1008,97 +1067,27 @@ def make_llvm_features(extensions: Sequence[str]): feature_desc = _feature_description(ext_basename) feature_method = feature_flag[:1].lower() + feature_flag[1:] - lines.extend([ - f"def {feature_name}", - f' : SubtargetFeature<"x{ext_name}", "{feature_flag}", "true",', - f' "\'{feature_label}\' ({feature_desc})">;', - f"def {feature_flag}", - f' : Predicate<"Subtarget->{feature_method}()">,', - f" AssemblerPredicate<(all_of {feature_name}),", - f' "\'{feature_label}\' ({feature_desc})">;', - "", - ]) + lines.extend( + [ + f"def {feature_name}", + f' : RISCVExtension<1, 0, "{feature_desc}">;', + f"def {feature_flag}", + f' : Predicate<"Subtarget->{feature_method}()">,', + f" AssemblerPredicate<(all_of {feature_name}),", + f" \"'{feature_label}' ({feature_desc})\">;", + "", + ] + ) Path("feature.td").write_text("\n".join(lines), encoding="utf-8") logging.info("feature.td generated successfully") -# --------------------------------------------------------------------------- -# LIT test rendering -# --------------------------------------------------------------------------- - -def _get_asm_operands(inst: Instruction) -> List[str]: - if inst.mnemonic in FP_MEM_LOAD_MNEMONICS: - return ["ft0", "0(x0)"] - if inst.mnemonic in FP_MEM_STORE_MNEMONICS: - return ["ft0", "0(x0)"] - - asm_operand_map = { - InstructionFormat.R: ("rd", "rs1", "rs2"), - InstructionFormat.RLUIMM5: ("rd", "rs1", "rs2", "imm5"), - InstructionFormat.RPRS3: ("rs1", "rs2", "prs3"), - InstructionFormat.I: ("rd", "rs1"), - InstructionFormat.R_RDZ: ("rs1", "rs2"), - InstructionFormat.U: ("rd",), - InstructionFormat.R4: ("rd", "rs1", "rs2", "rs3"), - InstructionFormat.RVF: ("rd", "rs1", "rs2"), - InstructionFormat.RFRM: ("rd", "rs1", "rs2", "rm"), - InstructionFormat.IFRM: ("rd", "rs1", "rm"), - InstructionFormat.R4FRM: ("rs1", "rs2", "rs3", "rd", "rm"), - InstructionFormat.IIMM12: ("rs1", "rd", "imm12"), - InstructionFormat.IIMM12_RM: ("rd", "rs1", "imm12", "rm"), - InstructionFormat.IIMM12_RS1Z: ("rd", "imm12"), - InstructionFormat.IIMM12_RDZ: ("rs1", "imm12"), - InstructionFormat.FREP_O: ("rs1", "imm12", "stagger_max", "stagger_mask"), - InstructionFormat.SIMM12: ("rs1", "rs2", "imm12lo", "imm12hi"), - InstructionFormat.IVF: ("rd", "rs1"), - InstructionFormat.ISHAMT: ("rd", "rs1", "shamt"), - InstructionFormat.ISHAMTW: ("rd", "rs1", "shamt"), - InstructionFormat.RIMM5: ("rd", "rs1", "imm5"), - InstructionFormat.RIMM5_RS1Z: ("rd", "imm5"), - InstructionFormat.RIMM6: ("rd", "rs1", "imm6"), - InstructionFormat.R_RS1Z: ("rd", "rs2"), - InstructionFormat.R_RDZ_RS2Z: ("rs1",), - } - dtypes = _get_dtypes(inst.mnemonic) - operands = [] - for op in asm_operand_map[inst.format]: - if op == "rm": - operands.append("rne") - elif op in {"imm12", "imm12lo", "imm12hi", "shamt", "imm5", "imm6", "stagger_max", "stagger_mask"}: - operands.append("0") - elif dtypes.get(op) == "GPR" or (op == "prs3" and dtypes.get("rs3") == "GPR"): - operands.append("x0") - else: - operands.append("ft0") - return operands - - -def _to_lit_test(instructions: dict, ext_name: str) -> str: - lines = [ - f"# RUN: llvm-mc %s -triple=riscv64 -mattr=+d,+{ext_name.lower()} " - f"-riscv-no-aliases -show-encoding | FileCheck %s", - "", - ] - for _, inst in instructions.items(): - operands = _get_asm_operands(inst) - asm = "{} {}".format(inst.mnemonic, ", ".join(operands)) - enc = inst.encoding_repr.replace("-", "0") - assert len(enc) == 32, f"Unexpected encoding length for {inst.mnemonic}" - chunks_repr = re.findall("[01]{8}", enc) - assert len(chunks_repr) == 4 - chunks_int = [int(v, 2) for v in chunks_repr] - chunks_hex = ["0x{:02x}".format(v) for v in chunks_int] - encoding = "[{}]".format(",".join(reversed(chunks_hex))) - lines.append(f"# CHECK: encoding: {encoding}") - lines.append(asm) - lines.append("") - return "\n".join(lines) - # --------------------------------------------------------------------------- # Public entry point # --------------------------------------------------------------------------- + def make_llvm(instr_dict: InstrDict, extensions: Sequence[str], csr_dict: CsrDict): """Generate LLVM TableGen definitions. @@ -1110,7 +1099,7 @@ def make_llvm(instr_dict: InstrDict, extensions: Sequence[str], csr_dict: CsrDic CSR definitions. """ # Group instructions by their canonical extension basename. - groups: dict[str, dict] = {} + groups: "dict[str, InstrDict]" = {} for mnemonic, spec in instr_dict.items(): ext_paths = spec.get("extension", []) if not ext_paths: @@ -1136,7 +1125,7 @@ def make_llvm(instr_dict: InstrDict, extensions: Sequence[str], csr_dict: CsrDic continue if "is_pseudo_of" in spec: inst_use = spec["is_pseudo_of"]["instruction"] - ext_use = spec["is_pseudo_of"]["extension"] + ext_use = spec["is_pseudo_of"]["extension"] pseudos.append(inst) uses.append((inst_use, ext_use)) else: