diff --git a/Makefile b/Makefile index 625f886a..6c574e62 100644 --- a/Makefile +++ b/Makefile @@ -64,6 +64,7 @@ ifneq ($(SKIP_DOCKER),true) ${DOCKER_BIN} run --rm \ -v ${PWD}/$@.workdir:/build${DOCKER_VOL_SUFFIX} \ -v ${PWD}/src:/src:ro${DOCKER_EXTRA_VOL_SUFFIX} \ + -v ${PWD}/normative_rule_defs:/normative_rule_defs:ro${DOCKER_EXTRA_VOL_SUFFIX} \ -v ${PWD}/docs-resources:/docs-resources:ro${DOCKER_EXTRA_VOL_SUFFIX} \ -w /build \ $(DOCKER_USER_ARG) \ @@ -76,13 +77,13 @@ else endif ifdef UNRELIABLE_BUT_FASTER_INCREMENTAL_BUILDS -WORKDIR_SETUP = mkdir -p $@.workdir && ln -sfn ../../src ../../docs-resources $@.workdir/ +WORKDIR_SETUP = mkdir -p $@.workdir && ln -sfn ../../src ../../normative_rule_defs ../../docs-resources $@.workdir/ WORKDIR_TEARDOWN = mv $@.workdir/$@ $@ else WORKDIR_SETUP = \ rm -rf $@.workdir && \ mkdir -p $@.workdir && \ - ln -sfn ../../src ../../docs-resources $@.workdir/ + ln -sfn ../../src ../../normative_rule_defs ../../docs-resources $@.workdir/ WORKDIR_TEARDOWN = \ mv $@.workdir/$@ $@ && \ @@ -91,11 +92,14 @@ endif SRC_DIR := src BUILD_DIR := build +NORM_RULE_DEF_DIR := normative_rule_defs +DOC_NORM_TAG_SUFFIX := -norm-tags.json DOCS_PDF := $(addprefix $(BUILD_DIR)/, $(addsuffix .pdf, $(DOCS))) DOCS_HTML := $(addprefix $(BUILD_DIR)/, $(addsuffix .html, $(DOCS))) DOCS_EPUB := $(addprefix $(BUILD_DIR)/, $(addsuffix .epub, $(DOCS))) -DOCS_NORM_TAGS := $(addprefix $(BUILD_DIR)/, $(addsuffix -norm-tags.json, $(DOCS))) +DOCS_NORM_TAGS := $(addprefix $(BUILD_DIR)/, $(addsuffix $(DOC_NORM_TAG_SUFFIX), $(DOCS))) +NORM_RULES := $(BUILD_DIR)/norm-rules.json ENV := LANG=C.utf8 XTRA_ADOC_OPTS := @@ -104,6 +108,7 @@ ASCIIDOCTOR_PDF := $(ENV) asciidoctor-pdf ASCIIDOCTOR_HTML := $(ENV) asciidoctor ASCIIDOCTOR_EPUB := $(ENV) asciidoctor-epub3 ASCIIDOCTOR_TAGS := $(ENV) asciidoctor --backend tags --require=./docs-resources/converters/tags.rb +CREATE_NORM_RULE_TOOL := ruby docs-resources/tools/create_normative_rules.rb OPTIONS := --trace \ -a compress \ @@ -123,7 +128,7 @@ REQUIRES := --require=asciidoctor-bibtex \ --require=asciidoctor-mathematical \ --require=asciidoctor-sail -.PHONY: all build clean build-container build-no-container build-docs build-pdf build-html build-epub build-tags submodule-check +.PHONY: all build clean build-container build-no-container build-docs build-pdf build-html build-epub build-tags build-norm-rules submodule-check all: build @@ -138,10 +143,20 @@ build-pdf: $(DOCS_PDF) build-html: $(DOCS_HTML) build-epub: $(DOCS_EPUB) build-tags: $(DOCS_NORM_TAGS) -build: build-pdf build-html build-epub build-tags +build-norm-rules: $(NORM_RULES) +build: build-pdf build-html build-epub build-tags build-norm-rules ALL_SRCS := $(shell git ls-files $(SRC_DIR)) +# All normative rule definition input YAML files tracked under Git (ensure you at least stage new files). +NORM_RULE_DEF_FILES := $(shell git ls-files '$(NORM_RULE_DEF_DIR)/*.yaml') + +# Add -t to each normative tag input filename and add prefix of "/" to make into absolute pathname. +NORM_TAG_FILE_ARGS := $(foreach relative_pname,$(DOCS_NORM_TAGS),-t /$(relative_pname)) + +# Add -d to each normative rule definition filename +NORM_RULE_DEF_ARGS := $(foreach relative_pname,$(NORM_RULE_DEF_FILES),-d $(relative_pname)) + $(BUILD_DIR)/%.pdf: $(SRC_DIR)/%.adoc $(ALL_SRCS) $(BUILD_DIR)/%-norm-tags.json $(WORKDIR_SETUP) $(DOCKER_CMD) $(DOCKER_QUOTE) $(ASCIIDOCTOR_PDF) $(OPTIONS) $(REQUIRES) $< $(DOCKER_QUOTE) @@ -165,6 +180,13 @@ $(BUILD_DIR)/%-norm-tags.json: $(SRC_DIR)/%.adoc $(ALL_SRCS) docs-resources/conv $(DOCKER_CMD) $(DOCKER_QUOTE) $(ASCIIDOCTOR_TAGS) $(OPTIONS) -a tags-match-prefix='norm:' -a tags-output-suffix='-norm-tags.json' $(REQUIRES) $< $(DOCKER_QUOTE) $(WORKDIR_TEARDOWN) +$(NORM_RULES): $(DOCS_NORM_TAGS) $(NORM_RULE_DEF_FILES) + $(WORKDIR_SETUP) + cp -f $(DOCS_NORM_TAGS) $@.workdir + mkdir -p $@.workdir/build + $(DOCKER_CMD) $(DOCKER_QUOTE) $(CREATE_NORM_RULE_TOOL) $(NORM_TAG_FILE_ARGS) $(NORM_RULE_DEF_ARGS) $@ $(DOCKER_QUOTE) + $(WORKDIR_TEARDOWN) + # Update docker image to latest docker-pull-latest: ${DOCKER_BIN} pull ${DOCKER_IMG} diff --git a/normative_rule_defs/README.md b/normative_rule_defs/README.md new file mode 100644 index 00000000..318ae52c --- /dev/null +++ b/normative_rule_defs/README.md @@ -0,0 +1,22 @@ +# Normative Rule Definition Files + +This directory contains one normative rule definition file per adoc chapter file. +Each definition file has the same name as its corresponding adoc file with the extension changed from .adoc to .yaml. +See rv32.yaml for a good example of a definition file that includes additional informative comments. + +Each definition file provides the information required to create the normative rules for +its corresponding adoc file. The adoc file contains tags (AKA AsciiDoc anchors with names with a "norm:" prefix) of text associated with normative rules. + +In many cases there is a 1:1 mapping between normative rules and tags but not always (1:many, many:1, and many:many also exist). The definition files provide the mapping information to create normative rules from the tags. +The definition files also contain additional meta-data added to the normative rule definitions. + +The Ruby script in docs-resources/tools/create_normative_rules.rb consumes these definition files along with +the extracted normative tags from the ISA manual chapters to create a file containing all normative rules +for all ISA manuals (priv & unpriv). + +See the schemas in docs-resources/schemas for a machine-readable definition of the input and output file formats: +* File defs-schema.json is the format of the definition input file format (YAML). +* File norm-rules-schema.json is the format of the normative rule output file format (JSON). + +Using Visual Studio Code to edit the definition YAML files is encouraged since it provides +live schema feedback. diff --git a/normative_rule_defs/m-st-ext.yaml b/normative_rule_defs/m-st-ext.yaml new file mode 100644 index 00000000..1e864f64 --- /dev/null +++ b/normative_rule_defs/m-st-ext.yaml @@ -0,0 +1,37 @@ +# yaml-language-server: $schema=../docs-resources/schemas/defs-schema.json + +$schema: "../docs-resources/schemas/defs-schema.json#" + +# Used to create normative rules for m-st-ext.adoc file. +# Tags refer to anchors in any adoc file for any ISA manual. + +normative_rule_definitions: + - name: mul_op + tags: ["norm:mul_op"] + - names: [mulh_op, mulhu_op, mulhsu_op] + tags: ["norm:mulh_mulhu_mulhsu_op"] + - names: [div_op, divu_op] + tags: ["norm:div_divu_op"] + - names: [divw_op, divuw_op] + tags: ["norm:divw_divuw_op"] + - names: [rem_op, remu_op] + tags: ["norm:rem_remu_op"] + - names: [remw_op, remuw_op] + tags: ["norm:remw_remuw_op"] + - name: div_by_zero + tags: ["norm:div_by_zero"] + - name: rem_by_zero + tags: ["norm:rem_by_zero"] + - name: signed_div_overflow + tags: ["norm:signed_div_overflow"] + - name: rem_result_sign + tags: ["norm:rem_result_sign"] + - names: [remw_result_sign, remuw_result_sign] + tags: ["norm:remw_remuw_result_sign"] + - name: mulw_op + tags: ["norm:mulw_op"] + - name: mul_misa_M_dis + description: | + An illegal instruction exception is raised when the instruction is executed + and `misa.M` is 0. + tags: ["norm:misa_extensions_disabling"] diff --git a/normative_rule_defs/machine.yaml b/normative_rule_defs/machine.yaml new file mode 100644 index 00000000..18e830f9 --- /dev/null +++ b/normative_rule_defs/machine.yaml @@ -0,0 +1,93 @@ +# yaml-language-server: $schema=../docs-resources/schemas/defs-schema.json + +$schema: "../docs-resources/schemas/defs-schema.json#" + +# Used to create normative rules for rv32.adoc file. +# Tags refer to anchors in any adoc file for any ISA manual. + +normative_rule_definitions: + - name: M_highest_priv_mode + tags: ["norm:M_highest_priv_mode"] + - name: M_mode_at_reset + tags: ["norm:M_mode_at_reset"] + - name: M_access_all_lower_priv_CSRs + tags: ["norm:M_access_all_lower_priv_CSRs"] + - name: misa_acc + tags: ["norm:misa_acc"] + - name: misa_always_rd + tags: ["norm:misa_always_rd"] + - name: MISA_CSR_IMPLEMENTED + tags: ["norm:MISA_CSR_IMPLEMENTED"] + - name: misa_mxl_op + tags: + - "norm:misa_mxl_op_isa" + - "norm:misa_mxl_op_nz" + - name: misa_mxl_acc + tags: ["norm:misa_mxl_acc"] + - name: misa_sz + tags: ["norm:misa_sz"] + - name: misa_extensions_enc + tags: ["norm:misa_extensions_enc"] + - name: misa_extensions_op + tags: ["norm:misa_extensions_op"] + - name: misa_extensions_rst + tags: ["norm:misa_extensions_rst"] + - name: misa_extensions_disabling + description: what happens when you turn off bits + tags: ["norm:misa_extensions_disabling"] + - name: misa_extensions_impl_def + tags: ["norm:misa_extensions_impl_def"] + - name: misa_extensions_disabling_def + tags: ["norm:misa_extensions_disabling_def"] + - name: misa_extensions_rsv_ret_0 + tags: ["norm:misa_extensions_rsv_ret_0"] + - name: misa_i_op + tags: ["norm:misa_i_op"] + - name: misa_e_op + tags: ["norm:misa_e_op"] + - name: misa_x_op + tags: ["norm:misa_x_op"] + - name: misa_b_op + tags: ["norm:misa_b_op"] + - name: misa_m_op + tags: ["norm:misa_m_op"] + - name: misa_s_op + tags: ["norm:misa_s_op"] + - name: misa_u_op + tags: ["norm:misa_u_op"] + - name: misa_e_not_i + tags: ["norm:misa_e_not_i"] + - name: Zmmul_misa_m + tags: ["norm:Zmmul_misa_m"] + - name: misa_e_acc + tags: ["norm:misa_e_acc"] + - name: misa_extensions_dependencies + tags: ["norm:misa_extensions_dependencies"] + - name: misa_inc_ialign + tags: ["norm:misa_inc_ialign"] + - names: [mvendorid_sz, mvendorid_acc, mvendorid_op] + tags: ["norm:mvendorid_sz_acc_op"] + - name: mvendorid_always_rd + tags: ["norm:mvendorid_always_rd"] + - name: mvendorid_enc + tags: ["norm:mvendorid_enc"] + - name: mvendorid_bank_1_less_than_JEDEC + tags: ["norm:mvendorid_bank_1_less_than_JEDEC"] + - names: [marchid_sz, marchid_acc, marchid_op] + tags: ["norm:marchid_sz_acc_op"] + - name: marchid_always_rd + tags: ["norm:marchid_always_rd"] + - name: mimpid_op + tags: ["norm:mimpid_op"] + - name: mimpid_always_rd + tags: ["norm:mimpid_always_rd"] + - names: [mhartid_sz, mhartid_acc, mhartid_op] + tags: ["norm:mhartid_sz_acc_op"] + - name: mhartid_always_rd + tags: ["norm:mhartid_always_rd"] + - names: [mstatus_sz, mstatus_acc] + tags: ["norm:mstatus_sz_acc"] + - names: [mstatush_sz, mstatush_acc] + tags: ["norm:mstatush_sz_acc"] + - name: mstatush_enc + tags: ["norm:mstatush_enc"] diff --git a/normative_rule_defs/rv-32-64g.yaml b/normative_rule_defs/rv-32-64g.yaml new file mode 100644 index 00000000..d2b5352c --- /dev/null +++ b/normative_rule_defs/rv-32-64g.yaml @@ -0,0 +1,345 @@ +# yaml-language-server: $schema=../docs-resources/schemas/defs-schema.json + +$schema: "../docs-resources/schemas/defs-schema.json#" + +# All of these normative rule definitions are to table cells in the ISA manual instruction +# encoding tables and so there isn't any associated text with the normative rule. +# These definitions are still useful since there is still an AsciiDoc anchor in the table cell +# and so it can be used as a hyperlink target in PDF/HTML files. + +normative_rule_definitions: + - name: lui_enc + tags_without_text: + - name: "norm:lui_enc" + kind: instruction + instances: [lui] + - name: auipc_enc + tags_without_text: + - name: "norm:auipc_enc" + kind: instruction + instances: [auipc] + - name: jal_enc + tags_without_text: + - name: "norm:jal_enc" + kind: instruction + instances: [jal] + - name: jalr_enc + tags_without_text: + - name: "norm:jalr_enc" + kind: instruction + instances: [jalr] + - name: beq_enc + tags_without_text: + - name: "norm:beq_enc" + kind: instruction + instances: [beq] + - name: bne_enc + tags_without_text: + - name: "norm:bne_enc" + kind: instruction + instances: [bne] + - name: blt_enc + tags_without_text: + - name: "norm:blt_enc" + kind: instruction + instances: [blt] + - name: bge_enc + tags_without_text: + - name: "norm:bge_enc" + kind: instruction + instances: [bge] + - name: bltu_enc + tags_without_text: + - name: "norm:bltu_enc" + kind: instruction + instances: [bltu] + - name: bgeu_enc + tags_without_text: + - name: "norm:bgeu_enc" + kind: instruction + instances: [bgeu] + - name: lb_enc + tags_without_text: + - name: "norm:lb_enc" + kind: instruction + instances: [lb] + - name: lh_enc + tags_without_text: + - name: "norm:lh_enc" + kind: instruction + instances: [lh] + - name: lw_enc + tags_without_text: + - name: "norm:lw_enc" + kind: instruction + instances: [lw] + - name: lbu_enc + tags_without_text: + - name: "norm:lbu_enc" + kind: instruction + instances: [lbu] + - name: lhu_enc + tags_without_text: + - name: "norm:lhu_enc" + kind: instruction + instances: [lhu] + - name: sb_enc + tags_without_text: + - name: "norm:sb_enc" + kind: instruction + instances: [sb] + - name: sh_enc + tags_without_text: + - name: "norm:sh_enc" + kind: instruction + instances: [sh] + - name: sw_enc + tags_without_text: + - name: "norm:sw_enc" + kind: instruction + instances: [sw] + - name: addi_enc + tags_without_text: + - name: "norm:addi_enc" + kind: instruction + instances: [addi] + - name: slti_enc + tags_without_text: + - name: "norm:slti_enc" + kind: instruction + instances: [slti] + - name: sltiu_enc + tags_without_text: + - name: "norm:sltiu_enc" + kind: instruction + instances: [sltiu] + - name: xori_enc + tags_without_text: + - name: "norm:xori_enc" + kind: instruction + instances: [xori] + - name: ori_enc + tags_without_text: + - name: "norm:ori_enc" + kind: instruction + instances: [ori] + - name: andi_enc + tags_without_text: + - name: "norm:andi_enc" + kind: instruction + instances: [auipc] + - name: slli_enc + tags_without_text: + - name: "norm:slli_enc" + kind: instruction + instances: [slli] + - name: srli_enc + tags_without_text: + - name: "norm:srli_enc" + kind: instruction + instances: [srli] + - name: srai_enc + tags_without_text: + - name: "norm:srai_enc" + kind: instruction + instances: [srai] + - name: add_enc + tags_without_text: + - name: "norm:add_enc" + kind: instruction + instances: [add] + - name: sub_enc + tags_without_text: + - name: "norm:sub_enc" + kind: instruction + instances: [sub] + - name: sll_enc + tags_without_text: + - name: "norm:sll_enc" + kind: instruction + instances: [sll] + - name: slt_enc + tags_without_text: + - name: "norm:slt_enc" + kind: instruction + instances: [slt] + - name: sltu_enc + tags_without_text: + - name: "norm:sltu_enc" + kind: instruction + instances: [sltu] + - name: xor_enc + tags_without_text: + - name: "norm:xor_enc" + kind: instruction + instances: [xor] + - name: srl_enc + tags_without_text: + - name: "norm:srl_enc" + kind: instruction + instances: [srl] + - name: sra_enc + tags_without_text: + - name: "norm:sra_enc" + kind: instruction + instances: [sra] + - name: or_enc + tags_without_text: + - name: "norm:or_enc" + kind: instruction + instances: [or] + - name: and_enc + tags_without_text: + - name: "norm:and_enc" + kind: instruction + instances: [and] + - name: fence_enc + tags_without_text: + - name: "norm:fence_enc" + kind: instruction + instances: [fence] + - name: fence-tso_enc + tags_without_text: + - name: "norm:fence-tso_enc" + kind: instruction + instances: [fence-tso] + - name: pause_enc + tags_without_text: + - name: "norm:pause_enc" + kind: instruction + instances: [pause] + - name: ecall_enc + tags_without_text: + - name: "norm:ecall_enc" + kind: instruction + instances: [ecall] + - name: ebreak_enc + tags_without_text: + - name: "norm:ebreak_enc" + kind: instruction + instances: [ebreak] + - name: lwu_enc + tags_without_text: + - name: "norm:lwu_enc" + kind: instruction + instances: [lwu] + - name: ld_enc + tags_without_text: + - name: "norm:ld_enc" + kind: instruction + instances: [ld] + - name: sd_enc + tags_without_text: + - name: "norm:sd_enc" + kind: instruction + instances: [sd] + - name: addiw_enc + tags_without_text: + - name: "norm:addiw_enc" + kind: instruction + instances: [addiw] + - name: slliw_enc + tags_without_text: + - name: "norm:slliw_enc" + kind: instruction + instances: [slliw] + - name: srliw_enc + tags_without_text: + - name: "norm:srliw_enc" + kind: instruction + instances: [srliw] + - name: sraiw_enc + tags_without_text: + - name: "norm:sraiw_enc" + kind: instruction + instances: [sraiw] + - name: addw_enc + tags_without_text: + - name: "norm:addw_enc" + kind: instruction + instances: [addw] + - name: subw_enc + tags_without_text: + - name: "norm:subw_enc" + kind: instruction + instances: [subw] + - name: sllw_enc + tags_without_text: + - name: "norm:sllw_enc" + kind: instruction + instances: [sllw] + - name: srlw_enc + tags_without_text: + - name: "norm:srlw_enc" + kind: instruction + instances: [srlw] + - name: sraw_enc + tags_without_text: + - name: "norm:sraw_enc" + kind: instruction + instances: [sraw] + - name: mul_enc + tags_without_text: + - name: "norm:mul_enc" + kind: instruction + instances: [mul] + - name: mulh_enc + tags_without_text: + - name: "norm:mulh_enc" + kind: instruction + instances: [mulh] + - name: mulhsu_enc + tags_without_text: + - name: "norm:mulhsu_enc" + kind: instruction + instances: [mulhsu] + - name: mulhu_enc + tags_without_text: + - name: "norm:mulhu_enc" + kind: instruction + instances: [mulhu] + - name: div_enc + tags_without_text: + - name: "norm:div_enc" + kind: instruction + instances: [div] + - name: divu_enc + tags_without_text: + - name: "norm:divu_enc" + kind: instruction + instances: [divu] + - name: rem_enc + tags_without_text: + - name: "norm:rem_enc" + kind: instruction + instances: [rem] + - name: remu_enc + tags_without_text: + - name: "norm:remu_enc" + kind: instruction + instances: [remu] + - name: mulw_enc + tags_without_text: + - name: "norm:mulw_enc" + kind: instruction + instances: [mulw] + - name: divw_enc + tags_without_text: + - name: "norm:divw_enc" + kind: instruction + instances: [divw] + - name: divuw_enc + tags_without_text: + - name: "norm:divuw_enc" + kind: instruction + instances: [divuw] + - name: remw_enc + tags_without_text: + - name: "norm:remw_enc" + kind: instruction + instances: [remw] + - name: remuw_enc + tags_without_text: + - name: "norm:remuw_enc" + kind: instruction + instances: [remuw] diff --git a/normative_rule_defs/rv32.yaml b/normative_rule_defs/rv32.yaml new file mode 100644 index 00000000..6f7d6faa --- /dev/null +++ b/normative_rule_defs/rv32.yaml @@ -0,0 +1,152 @@ +# yaml-language-server: $schema=../docs-resources/schemas/defs-schema.json + +$schema: "../docs-resources/schemas/defs-schema.json#" + +# Used to create normative rules for rv32.adoc file. +# Tags refer to anchors in any adoc file for any ISA manual. + +normative_rule_definitions: + - name: rv32i_xreg_sz # Normative rule names are typically more compact than tag names since they appear in table cells + summary: RV32I XLEN # Few word summary of normative rule. + tags: ["norm:rv32i_xreg_sz"] + - name: rv32i_other_xregs + summary: Registers x1 to x31 + tags: ["norm:rv32i_rv64i_other_xregs"] # Same tag used in rv64.yaml (that chapter is written as deltas from this chapter) + - name: pcreg_op + description: | # Example where augmenting information in tags helps better define a normative rule + The `pc` contains a byte address so is incremented by 4 for 32-bit instructions and + 2 for 16-bit instructions. + tags: ["norm:pcreg_op"] + - names: [slti_op,sltiu_op] # Example of multiple normative rules using the same tag + tags: ["norm:slti_sltiu_op"] + - name: x0eq0 + summary: Register x0 always zero + tags: ["norm:x0eq0"] + - name: taken_cti_misaligned_exc + summary: CTI misaligned execution + tags: ["norm:taken_cti_misaligned_exc"] + - name: cond_br_no_ia_misaligned_exc_not_taken + summary: No IA misaligned exc on not taken + tags: ["norm:cond_br_no_ia_misaligned_exc_not_taken"] + - name: imm_always_sex + summary: Immediates always sign-extended + tags: ["norm:imm_always_sex"] + - name: addi_op + tags: ["norm:addi_op"] + - name: addi_overflow + summary: Treatment of overflow + tags: ["norm:addi_overflow"] + - names: [andi_op,ori_op,xori_op] + tags: ["norm:andi_ori_xori_op"] + - name: slli_op + tags: ["norm:slli_op"] + - name: srli_op + tags: ["norm:srli_op"] + - name: srai_op + tags: ["norm:srai_op"] + - name: lui_op + tags: ["norm:lui_op"] + - name: auipc_op + tags: ["norm:auipc_op"] + - name: R-type_operands + tags: ["norm:R-type_operands"] + - name: add_op + tags: ["norm:add_op"] + - name: sub_op + tags: ["norm:sub_op"] + - names: [add_overflow, sub_overflow] + tags: ["norm:add_sub_overflow"] + - names: [slt_op, sltu_op] + tags: ["norm:slt_sltu_op"] + - names: [and_op, or_op, xor_op] + tags: ["norm:and_or_xor_op"] + - names: [sll_op, srl_op, sra_op] + tags: ["norm:sll_srl_sra_op"] + - name: no_cti_delay_slots + tags: ["norm:no_cti_delay_slots"] + - name: ia_fault_exc_on_target + tags: ["norm:ia_fault_exc_on_target"] + - name: jal_target + tags: ["norm:jal_target"] + - name: jal_op + tags: ["norm:jal_op"] + - name: jalr_target + tags: ["norm:jalr_target"] + - name: jalr_op + tags: ["norm:jalr_op"] + - name: br_target + tags: ["norm:br_target"] + - names: [beq_op, bne_op] + tags: ["norm:beq_bne_op"] + - names: [blt_op, bltu_op] + tags: ["norm:blt_bltu_op"] + - names: [bge_op, bgeu_op] + tags: ["norm:bge_bgeu_op"] + - name: load_exc_x0 + tags: ["norm:load_exc_x0"] + - name: ENDIANNESS_LITTLE_OR_BIG + tags: ["norm:ENDIANNESS_LITTLE_OR_BIG"] + - name: ldst_endian_byte_invariant + tags: ["norm:ldst_endian_byte_invariant"] + - name: ldst_endian_byte_op + tags: ["norm:ldst_endian_byte_op"] + - name: ldst_little_endian_op + tags: ["norm:ldst_little_endian_op"] + - name: ldst_big_endian_op + tags: ["norm:ldst_big_endian_op"] + - name: ldst_ea + tags: ["norm:ldst_ea"] + - name: ldst_no_exc_aligned + tags: ["norm:ldst_no_exc_aligned"] + - name: load_op + tags: ["norm:load_op"] + - name: store_op + tags: ["norm:store_op"] + - name: lw_op + tags: ["norm:lw_op"] + - name: lh_op + tags: ["norm:lh_op"] + - name: lhu_op + tags: ["norm:lhu_op"] + - names: [lb_op] + tags: + - "norm:lb_lbu_op" + - "norm:lh_op" + - names: [lbu_op] + tags: + - "norm:lb_lbu_op" + - "norm:lhu_op" + - names: [sw_op, sh_op, sb_op] + tags: ["norm:sw_sh_sb_op"] + - name: MISALIGNED_LDST_EEI_DEPENDENT_BEHAVIOR + tags: ["norm:MISALIGNED_LDST_EEI_DEPENDENT_BEHAVIOR"] + - name: MISALIGNED_LDST_FULLY_HW_SUPPORTED + tags: ["norm:MISALIGNED_LDST_FULLY_HW_SUPPORTED"] + - name: MISALIGNED_LDST_INVISIBLE_TRAP + tags: ["norm:MISALIGNED_LDST_INVISIBLE_TRAP"] + - name: MISALIGNED_LDST_HW_OR_INVISIBLE_TRAP_FUNC_OF_ADDR + tags: ["norm:MISALIGNED_LDST_HW_OR_INVISIBLE_TRAP_FUNC_OF_ADDR"] + - name: MISALIGNED_LDST_FULLY_HW_SUPPORTED_OR_VISIBLE_TRAP + tags: ["norm:MISALIGNED_LDST_FULLY_HW_SUPPORTED_OR_VISIBLE_TRAP"] + - name: MISALIGNED_LDST_CONTAINED_OR_FATAL_TRAP + tags: ["norm:MISALIGNED_LDST_CONTAINED_OR_FATAL_TRAP"] + - name: ldst_addr_misaligned_or_access_fault_exc + tags: ["norm:ldst_addr_misaligned_or_access_fault_exc"] + - name: ldst_atomicity_for_aligned + tags: ["norm:ldst_atomicity_for_aligned"] + - name: fence_op + tags: ["norm:fence_op"] + - name: fence-tso_op + tags: ["norm:fence-tso_op"] + - name: fence-tso_ordering_rw_rw_ok + tags: ["norm:fence-tso_ordering_rw_rw_ok"] + - name: fence_unused_flds_rsv + tags: ["norm:fence_unused_flds_rsv"] + - name: fence_cons_ok + tags: ["norm:fence_cons_ok"] + - name: ecall_op + tags: ["norm:ecall_op"] + - name: ebreak_op + tags: ["norm:ebreak_op"] + - name: fence_null_pred_succ_inter + tags: ["norm:fence_null_pred_succ_inter"] diff --git a/normative_rule_defs/rv64.yaml b/normative_rule_defs/rv64.yaml new file mode 100644 index 00000000..cf0c97ac --- /dev/null +++ b/normative_rule_defs/rv64.yaml @@ -0,0 +1,69 @@ +# yaml-language-server: $schema=../docs-resources/schemas/defs-schema.json + +$schema: "../docs-resources/schemas/defs-schema.json#" + +# Used to create normative rules for rv64.adoc file. +# Tags refer to anchors in any adoc file for any ISA manual. + +normative_rule_definitions: + - name: rv64i_xreg_sz + summary: RV64I XLEN + tags: ["norm:rv64i_xreg_sz"] + - name: rv64_w_sex + tags: ["norm:rv64_w_sex"] + - name: rv64i_other_xregs + summary: Registers x1 to x31 + tags: ["norm:rv32i_rv64i_other_xregs"] + - name: addiw_op + tags: ["norm:addiw_op"] + - names: [slliw_op,srliw_op,sraiw_op] + tags: ["norm:slliw_srliw_sraiw_op"] + - names: [slliw_imm5_rsv,srliw_imm5_rsv,sraiw_imm5_rsv] + summary: Bit 5 of imm reserved + tags: ["norm:slliw_srliw_sraiw_imm5_rsv"] + - name: lui_op_rv64i + tags: ["norm:lui_op_rv64i"] + - name: auipc_op_rv64i + tags: ["norm:auipc_op_rv64i"] + - names: [addw_op,subw_op] + tags: ["norm:addw_subw_op"] + - names: [addw_overflow,subw_overflow] + tags: ["norm:addw_subw_overflow"] + - name: addiw_overflow + tags: ["norm:addiw_overflow"] + - names: [sll_sh_amt_rv64i,srl_sh_amt_rv64i,sra_sh_amt_rv64i] + tags: ["norm:sll_srl_sra_sh_amt_rv64i"] + - names: [sllw_op,srlw_op,sraw_op] + tags: ["norm:sllw_srlw_sraw_op"] + - name: ld_op_rv64i + tags: ["norm:ld_op_rv64i"] + - name: lw_op_rv64i + tags: ["norm:lw_op_rv64i"] + - name: lwu_op + tags: ["norm:lwu_op"] + - name: lh_op_rv64i + summary: "lh RV64I operation" + tags: + - "norm:ld_op_rv64i" # Example where multiple tags required to create a complete self-contained rule + - "norm:lw_op_rv64i" + - "norm:lh_lhu_lb_lbu_op_rv64i" + - name: lhu_rv64i_op + summary: "lhu RV64I operation" + tags: + - "norm:ld_op_rv64i" # Example where multiple tags required to create a complete self-contained rule + - "norm:lw_op_rv64i" + - "norm:lh_lhu_lb_lbu_op_rv64i" + - name: lb_rv64i_op + summary: "lb RV64I operation" + tags: + - "norm:ld_op_rv64i" # Example where multiple tags required to create a complete self-contained rule + - "norm:lw_op_rv64i" + - "norm:lh_lhu_lb_lbu_op_rv64i" + - name: lbu_rv64i_op + summary: "lbu RV64I operation" + tags: + - "norm:ld_op_rv64i" # Example where multiple tags required to create a complete self-contained rule + - "norm:lw_op_rv64i" + - "norm:lh_lhu_lb_lbu_op_rv64i" + - names: [sd_op_rv64i,sw_op_rv64i,sh_op_rv64i,sb_op_rv64i] + tags: ["norm:sd_sw_sh_sb_op_rv64i"] diff --git a/normative_rule_defs/zilsd.yaml b/normative_rule_defs/zilsd.yaml new file mode 100644 index 00000000..3f22fb38 --- /dev/null +++ b/normative_rule_defs/zilsd.yaml @@ -0,0 +1,40 @@ +# yaml-language-server: $schema=../docs-resources/schemas/defs-schema.json + +$schema: "../docs-resources/schemas/defs-schema.json#" + +# Used to create normative rules for zilsd.adoc file. +# Tags refer to anchors in any adoc file for any ISA manual. + +normative_rule_definitions: + - name: Zilsd_reg_pairs + tags: ["norm:Zilsd_reg_pairs"] + - name: Zilsd_bits_to_pair + tags: ["norm:Zilsd_bits_to_pair"] + - name: Zilsd_align8_no_exc + tags: ["norm:Zilsd_align8_no_exc"] + - name: Zilsd_align8_atomic_unknown + tags: ["norm:Zilsd_align8_atomic_unknown"] + - name: Zilsd_align4_atomic + tags: ["norm:Zilsd_align4_atomic"] + - name: Zilsd_ld_resume_trap + tags: ["norm:Zilsd_ld_resume_trap"] + - name: Zilsd_ld_x0 + tags: ["norm:Zilsd_ld_x0"] + - name: Zilsd_sd_x0 + tags: ["norm:Zilsd_sd_x0"] + - name: Zilsd_RVWMO_exc_misaligned + tags: ["norm:Zilsd_RVWMO_exc_misaligned"] + - name: Zilsd_align4_two_4byte + tags: ["norm:Zilsd_align4_two_4byte"] + - name: Zilsd_ld_op + tags: ["norm:Zilsd_ld_op"] + - name: Zilsd_sd_op + tags: ["norm:Zilsd_sd_op"] + - name: c-ldsp_op + tags: ["norm:c-ldsp_op"] + - name: c-sdsp_op + tags: ["norm:c-sdsp_op"] + - name: c-ld_op + tags: ["norm:c-ld_op"] + - name: c-sd_op + tags: ["norm:c-sd_op"] diff --git a/src/m-st-ext.adoc b/src/m-st-ext.adoc index c4f47ab4..22ff107f 100644 --- a/src/m-st-ext.adoc +++ b/src/m-st-ext.adoc @@ -22,9 +22,9 @@ include::images/wavedrom/m-st-ext-for-int-mult.edn[] (((MUL, MULHU))) (((MUL, MULHSU))) -[#norm:inst:mul:operation]#MUL performs an XLEN-bit×XLEN-bit multiplication of +[#norm:mul_op]#MUL performs an XLEN-bit×XLEN-bit multiplication of `rs1` by `rs2` and places the lower XLEN bits in the destination -register.# [#norm:insts:mulh-mulhu-mulhsu:operation]#MULH, MULHU, and MULHSU perform the same multiplication but +register.# [#norm:mulh_mulhu_mulhsu_op]#MULH, MULHU, and MULHSU perform the same multiplication but return the upper XLEN bits of the full 2×XLEN-bit product, for signed×signed, unsigned×unsigned, and `rs1`×unsigned `rs2` multiplication.# @@ -37,7 +37,7 @@ most-significant word of the multiplicand (which contains the sign bit) with the less-significant words of the multiplier (which are unsigned). ==== -[#norm:inst:mulw:operation]#MULW is an RV64 instruction that multiplies the lower 32 bits of the +[#norm:mulw_op]#MULW is an RV64 instruction that multiplies the lower 32 bits of the source registers, placing the sign extension of the lower 32 bits of the result into the destination register.# @@ -58,9 +58,9 @@ include::images/wavedrom/division-op.edn[] (((MUL, DIV))) (((MUL, DIVU))) -[#norm:insts:div-divu:operation]#DIV and DIVU perform an XLEN bits by XLEN bits signed and unsigned -integer division of `rs1` by `rs2`, rounding towards zero.# [#norm:insts:rem-remu:operation]#REM and REMU -provide the remainder of the corresponding division operation.# [#norm:inst:rem:result_sign]#For REM, +[#norm:div_divu_op]#DIV and DIVU perform an XLEN bits by XLEN bits signed and unsigned +integer division of `rs1` by `rs2`, rounding towards zero.# [#norm:rem_remu_op]#REM and REMU +provide the remainder of the corresponding division operation.# [#norm:rem_result_sign]#For REM, the sign of a nonzero result equals the sign of the dividend.# [NOTE] @@ -76,19 +76,19 @@ the recommended code sequence is: `DIV[U] rdq, rs1, rs2; REM[U] rdr,` Microarchitectures can then fuse these into a single divide operation instead of performing two separate divides. -[#norm:insts:divw-divuw:operation]#DIVW and DIVUW are RV64 instructions that divide the lower 32 bits of +[#norm:divw_divuw_op]#DIVW and DIVUW are RV64 instructions that divide the lower 32 bits of `rs1` by the lower 32 bits of `rs2`, treating them as signed and unsigned integers, placing the 32-bit quotient in `rd`, -sign-extended to 64 bits.# [#norm:insts:remw-remuw:operation]#REMW and REMUW are RV64 instructions that +sign-extended to 64 bits.# [#norm:remw_remuw_op]#REMW and REMUW are RV64 instructions that provide the corresponding signed and unsigned remainder -operations.# [#norm:insts:remw-remuw:result_sign]#BothREMW and REMUW always sign-extend the 32-bit result +operations.# [#norm:remw_remuw_result_sign]#BothREMW and REMUW always sign-extend the 32-bit result to 64 bits, including on a divide by zero.# (((MUL, div by zero))) The semantics for division by zero and division overflow are summarized -in <>. [#norm:instgrp:division:div_by_zero]#The quotient of division by zero has all bits -set#, and [#norm:instgrp:remainder:div_by_zero]#the remainder of division by zero equals the dividend.# -[#norm:instgrp:sign-division:overflow]#Signed division overflow occurs only when the most-negative integer is divided +in <>. [#norm:div_by_zero]#The quotient of division by zero has all bits +set#, and [#norm:rem_by_zero]#the remainder of division by zero equals the dividend.# +[#norm:signed_div_overflow]#Signed division overflow occurs only when the most-negative integer is divided by latexmath:[$-1$]. The quotient of a signed division with overflow is equal to the dividend, and the remainder is zero.# Unsigned division overflow cannot occur. diff --git a/src/machine.adoc b/src/machine.adoc index 0181c148..d5d3ca3f 100644 --- a/src/machine.adoc +++ b/src/machine.adoc @@ -2,8 +2,8 @@ == Machine-Level ISA, Version 1.13 This chapter describes the machine-level operations available in -[#norm:ext:Sm:highest_priv_mode]#machine-mode (M-mode), which is the highest privilege mode in a RISC-V -hart.# [#norm:ext:Sm:mode_at_reset]#M-mode is used for low-level access to a hardware platform and +[#norm:M_highest_priv_mode]#machine-mode (M-mode), which is the highest privilege mode in a RISC-V +hart.# [#norm:M_mode_at_reset]#M-mode is used for low-level access to a hardware platform and is the first mode entered at reset.# M-mode can also be used to implement features that are too difficult or expensive to implement in hardware directly. The RISC-V machine-level ISA contains a common core that is @@ -13,21 +13,22 @@ other details of the hardware implementation. === Machine-Level CSRs In addition to the machine-level CSRs described in this section, -[#norm:ext:Sm:access_all_lower_priv_CSRs]#M-mode code can access all CSRs at lower privilege levels.# +[#norm:M_access_all_lower_priv_CSRs]#M-mode code can access all CSRs at lower privilege levels.# [[misa]] ==== Machine ISA (`misa`) Register -[#norm:csr:misa:sw_rw]#The `misa` CSR is a *WARL* read-write register# reporting the ISA supported by the hart. -[#norm:csr:misa:always_readable]#This register must be readable in any implementation#, but [#norm:param:MISA_CSR_IMPLEMENTED:can_be_zero]#a value of zero can be returned to indicate the `misa` register has not been implemented#, requiring that CPU capabilities be determined through a separate non-standard mechanism. +[#norm:misa_acc]#The `misa` CSR is a *WARL* read-write register# reporting the ISA supported by the hart. +[#norm:misa_always_rd]#This register must be readable in any implementation#, +but [#norm:MISA_CSR_IMPLEMENTED]#a value of zero can be returned to indicate the `misa` register has not been implemented#, requiring that CPU capabilities be determined through a separate non-standard mechanism. .Machine ISA register (misa) include::images/bytefield/misareg.edn[] -[#norm:csrfld:misa:mxl:base_int_width]#The MXL (Machine XLEN) field encodes the native base integer ISA width as +[#norm:misa_mxl_op_isa]#The MXL (Machine XLEN) field encodes the native base integer ISA width as shown in <>.# -[#norm:csrfld:misa:mxl:ro]#The MXL field is read-only.# -[#norm:csrfld:misa:mxl:mxlen_if_misa_nz]#If `misa` is nonzero, the +[#norm:misa_mxl_acc]#The MXL field is read-only.# +[#norm:misa_mxl_op_nz]#If `misa` is nonzero, the MXL field indicates the effective XLEN in M-mode, a constant termed _MXLEN_.# XLEN is never greater than MXLEN, but XLEN might be smaller than MXLEN in less-privileged modes. @@ -45,7 +46,7 @@ less-privileged modes. _Reserved_ |=== -[#norm:csr:misa:sz]#The `misa` CSR is MXLEN bits wide.# +[#norm:misa_sz]#The `misa` CSR is MXLEN bits wide.# [NOTE] ==== @@ -60,19 +61,19 @@ immediate 2 in a register, then shifting the register left by 31 bits. If zero, the hart is RV32, else it is RV64. ==== -[#norm:csrfld:misa:extensions:enc]#The Extensions field encodes the presence of the standard extensions, +[#norm:misa_extensions_enc]#The Extensions field encodes the presence of the standard extensions, with a single bit per letter of the alphabet (bit 0 encodes presence of extension "A" , bit 1 encodes presence of extension "B", through to bit 25 which encodes "Z").# -[#norm:csrfld:misa:i:set]#The "I" bit will be set for the RV32I and RV64I base ISAs#, -and [#norm:csrfld:misa:e:set]#the "E" bit will be set for RV32E and RV64E.# -[#norm:csrfld:misa:extensions:can_be_writable]#The Extensions field is a *WARL* field that can contain writable bits where the +[#norm:misa_i_op]#The "I" bit will be set for the RV32I and RV64I base ISAs#, +and [#norm:misa_e_op]#the "E" bit will be set for RV32E and RV64E.# +[#norm:misa_extensions_op]#The Extensions field is a *WARL* field that can contain writable bits where the implementation allows the supported ISA to be modified.# -[#norm:csrfld:misa:extensions:reset]#At reset, +[#norm:misa_extensions_rst]#At reset, the Extensions field shall contain the maximal set of supported extensions, and "I" shall be selected over "E" if both are available.# -[[norm:csrfld:misa:extensions:disabling]] +[[norm:misa_extensions_disabling]] When a standard extension is disabled by clearing its bit in `misa`, the instructions and CSRs defined or modified by the extension revert to their defined or reserved behaviors as if the extension is not @@ -80,7 +81,7 @@ implemented. [NOTE] ==== -[[norm:csrfld:misa:extensions:impl_def]] +[[norm:misa_extensions_impl_def]] For a given RISC-V execution environment, an instruction, extension, or other feature of the RISC-V ISA is ordinarily judged to be _implemented_ or not by the observable execution behavior in that environment. For @@ -88,7 +89,7 @@ example, the F extension is said to be implemented for an execution environment if and only if the instructions that the RISC-V Unprivileged ISA defines for F execute as specified. -[[norm:csrfld:misa:extensions:disabling_def]] +[[norm:misa_extensions_disabling_def]] With this definition of _implemented_, disabling an extension by clearing its bit in `misa` results in the extension being considered _not implemented_ in M-mode. For example, setting `misa`.F=0 results in @@ -106,7 +107,7 @@ the same vein, "implemented and enabled" is redundant here; "implemented" suffices. ==== -[#norm:csrfld:misa:extensions:rsv_ret_0]#All bits that are reserved for future use must return zero when read.# +[#norm:misa_extensions_rsv_ret_0]#All bits that are reserved for future use must return zero when read.# .Encoding of Extensions field in `misa`. [%autowidth,float="center",align="center",cols=">,>,<",options="header",] @@ -192,23 +193,23 @@ _Reserved_ + _Reserved_ |=== -[#norm:csrfld:misa:x:set]#The "X" bit will be set if there are any non-standard extensions.# +[#norm:misa_x_op]#The "X" bit will be set if there are any non-standard extensions.# -[#norm:csrfld:misa:b:set]#When the "B" bit is 1, the implementation supports the instructions provided by the +[#norm:misa_b_op]#When the "B" bit is 1, the implementation supports the instructions provided by the Zba, Zbb, and Zbs extensions.# When the "B" bit is 0, it indicates that the implementation might not support one or more of the Zba, Zbb, or Zbs extensions. -[#norm:csrfld:misa:m:set]#When the "M" bit is 1, the implementation supports all multiply and +[#norm:misa_m_op]#When the "M" bit is 1, the implementation supports all multiply and division instructions defined by the M extension.# When the "M" bit is 0, it indicates that the implementation might not support those -instructions. However [#norm:ext:Zmmul:misa_m]#if the Zmmul extension is supported then +instructions. However [#norm:Zmmul_misa_m]#if the Zmmul extension is supported then the multiply instructions it specifies are supported irrespective of the value of the "M" bit.# -[#norm:csrfld:misa:s:set]#When the "S" bit is 1, the implementation supports supervisor mode.# +[#norm:misa_s_op]#When the "S" bit is 1, the implementation supports supervisor mode.# When the "S" bit is 0, the implementation might not support supervisor mode. -[#norm:csrfld:misa:u:set]#When the "U" bit is 1, the implementation supports user mode.# +[#norm:misa_u_op]#When the "U" bit is 1, the implementation supports user mode.# When the "U" bit is 0, the implementation might not support user mode. [NOTE] @@ -225,13 +226,13 @@ observed at any level, and supports a much richer command interface without burdening hardware designs. ==== -[#norm:csrfld:misa:e:ro]#The "E" bit is read-only.# -[#norm:csrfld:misa:e:not_i]#Unless `misa` is all read-only zero, the +[#norm:misa_e_acc]#The "E" bit is read-only.# +[#norm:misa_e_not_i]#Unless `misa` is all read-only zero, the "E" bit always reads as the complement of the "I" bit.# If an execution environment supports both RV32E and RV32I, software can select RV32E by clearing the "I" bit. -[#norm:csrfld:misa:extensions:dependencies]#If an ISA feature _x_ depends on an ISA feature _y_, then attempting to +[#norm:misa_extensions_dependencies]#If an ISA feature _x_ depends on an ISA feature _y_, then attempting to enable feature _x_ but disable feature _y_ results in both features being disabled.# For example, setting "F"=0 and "D"=1 results in both "F" and "D" being cleared. @@ -241,7 +242,7 @@ An implementation may impose additional constraints on the collective setting of two or more `misa` fields, in which case they function collectively as a single *WARL* field. An attempt to write an unsupported combination causes those bits to be set to some supported combination. -[#norm:csr:misa:inc_ialign]#Writing `misa` may increase IALIGN, e.g., by disabling the "C" +[#norm:misa_inc_ialign]#Writing `misa` may increase IALIGN, e.g., by disabling the "C" extension. If an instruction that would write `misa` increases IALIGN, and the subsequent instruction's address is not IALIGN-bit aligned, the write to `misa` is suppressed, leaving `misa` unchanged.# @@ -258,9 +259,9 @@ reserved, not necessarily illegal. ==== Machine Vendor ID (`mvendorid`) Register -[#norm:csr:mvendorid:sz_ro_meaning]#The `mvendorid` CSR is a 32-bit read-only register providing the JEDEC +[#norm:mvendorid_sz_acc_op]#The `mvendorid` CSR is a 32-bit read-only register providing the JEDEC manufacturer ID of the provider of the core.# -[#norm:csr:mvendorid:always_readable]#This register must be readable in any implementation, but a value of 0 can be returned to +[#norm:mvendorid_always_rd]#This register must be readable in any implementation, but a value of 0 can be returned to indicate the field is not implemented or that this is a non-commercial implementation.# //.Vendor ID register (`mvendorid`) @@ -269,7 +270,7 @@ indicate the field is not implemented or that this is a non-commercial implement .Vendor ID register (`mvendorid`) include::images/bytefield/mvendorid.edn[] -[#norm:csr:mvendorid:encoding]#JEDEC manufacturer IDs are ordinarily encoded as a sequence of one-byte +[#norm:mvendorid_enc]#JEDEC manufacturer IDs are ordinarily encoded as a sequence of one-byte continuation codes `0x7f`, terminated by a one-byte ID not equal to `0x7f`, with an odd parity bit in the most-significant bit of each byte. `mvendorid` encodes the number of one-byte continuation codes in the @@ -281,7 +282,7 @@ the parity bit.# For example, the JEDEC manufacturer ID [NOTE] ==== -[[norm:csr:mvendorid:bank_1_less_than_JEDEC]] +[[norm:mvendorid_bank_1_less_than_JEDEC]] In JEDEC's parlance, the bank number is one greater than the number of continuation codes; hence, the `mvendorid` Bank field encodes a value that is one less than the JEDEC bank number. @@ -295,9 +296,9 @@ ID with JEDEC has a one-time cost of $500. ==== Machine Architecture ID (`marchid`) Register -[#norm:csr:marchid:sz_ro_meaning]#The `marchid` CSR is an MXLEN-bit read-only register encoding the base +[#norm:marchid_sz_acc_op]#The `marchid` CSR is an MXLEN-bit read-only register encoding the base microarchitecture of the hart.# -[#norm:csr:marchid:always_readable]#This register must be readable in any +[#norm:marchid_always_rd]#This register must be readable in any implementation, but a value of 0 can be returned to indicate the field is not implemented.# The combination of `mvendorid` and `marchid` should uniquely identify the type of hart microarchitecture that is implemented. @@ -333,9 +334,9 @@ variants of a design. ==== Machine Implementation ID (`mimpid`) Register -[#norm:csr:mimpid:meaning]#The `mimpid` CSR provides a unique encoding of the version of the +[#norm:mimpid_op]#The `mimpid` CSR provides a unique encoding of the version of the processor implementation.# -[#norm:csr:mimpid:always_readable]#This register must be readable in any +[#norm:mimpid_always_rd]#This register must be readable in any implementation, but a value of 0 can be returned to indicate that the field is not implemented.# The Implementation value should reflect the design of the RISC-V processor itself and not any surrounding system. @@ -354,9 +355,9 @@ boundaries to ease human readability. ==== Hart ID (`mhartid`) Register -[#norm:csr:mhartid:sz_ro_meaning]#The `mhartid` CSR is an MXLEN-bit read-only register containing the +[#norm:mhartid_sz_acc_op]#The `mhartid` CSR is an MXLEN-bit read-only register containing the integer ID of the hardware thread running the code.# -[#norm:csr:mhartid:always_readable]#This register must be readable in any implementation.# +[#norm:mhartid_always_rd]#This register must be readable in any implementation.# Hart IDs might not necessarily be numbered contiguously in a multiprocessor system, but at least one hart must have a hart ID of zero. Hart IDs must be unique within the @@ -376,7 +377,7 @@ of the largest hart ID used in a system. ==== Machine Status (`mstatus` and `mstatush`) Registers -[#norm:csr:mstatus:sz_rw]#The `mstatus` register is an MXLEN-bit read/write register formatted as +[#norm:mstatus_sz_acc]#The `mstatus` register is an MXLEN-bit read/write register formatted as shown in <> for RV32 and <> for RV64.# The `mstatus` register keeps track of and controls the hart’s current operating state. A restricted view of `mstatus` appears as the `sstatus` register in the S-level ISA. @@ -389,8 +390,8 @@ include::images/wavedrom/mstatusreg-rv321.edn[] .Machine-mode status (`mstatus`) register for RV64 include::images/wavedrom/mstatusreg.edn[] -[#norm:csr:mstatush:sz_rw_rv32]#For RV32 only, `mstatush` is a 32-bit read/write register formatted as shown in <>.# -[#norm:csr:mstatush:encoding]#Bits 30:4 of `mstatush` generally contain the same fields found in bits 62:36 of `mstatus` for RV64. Fields SD, SXL, and UXL do not exist in `mstatush`.# +[#norm:mstatush_sz_acc]#For RV32 only, `mstatush` is a 32-bit read/write register formatted as shown in <>.# +[#norm:mstatush_enc]#Bits 30:4 of `mstatush` generally contain the same fields found in bits 62:36 of `mstatus` for RV64. Fields SD, SXL, and UXL do not exist in `mstatush`.# [[mstatushreg]] .Additional machine-mode status (`mstatush`) register for RV32. diff --git a/src/rv-32-64g.adoc b/src/rv-32-64g.adoc index 6f2a99df..fd2d2cf2 100644 --- a/src/rv-32-64g.adoc +++ b/src/rv-32-64g.adoc @@ -59,48 +59,48 @@ these more specialized additions. [%autowidth.stretch,float="center",align="center",cols="^2m,^2m,^2m,^2m,<2m,>3m, <4m, >4m, <4m, >4m, <4m, >4m, <4m, >4m, <6m"] |=== 15+^|*RV32I Base Instruction Set* -10+^|imm[31:12] 2+^|rd 2+^|0110111 <|[[norm:enc:insttable:lui]]LUI -10+^|imm[31:12] 2+^|rd 2+^|0010111 <|[[norm:enc:insttable:auipc]]AUIPC -10+^|imm[20\|10:1\|11\|19:12] 2+^|rd 2+^|1101111 <|[[norm:enc:insttable:jal]]JAL - 6+^|imm[11:0] 2+^|rs1 2+^|000 2+^|rd 2+^|1100111 <|[[norm:enc:insttable:jalr]]JALR - 4+^|imm[12\|10:5] 2+^|rs2 2+^|rs1 2+^|000 2+^|imm[4:1\|11] 2+^|1100011 <|[[norm:enc:insttable:beq]]BEQ - 4+^|imm[12\|10:5] 2+^|rs2 2+^|rs1 2+^|001 2+^|imm[4:1\|11] 2+^|1100011 <|[[norm:enc:insttable:bne]]BNE - 4+^|imm[12\|10:5] 2+^|rs2 2+^|rs1 2+^|100 2+^|imm[4:1\|11] 2+^|1100011 <|[[norm:enc:insttable:blt]]BLT - 4+^|imm[12\|10:5] 2+^|rs2 2+^|rs1 2+^|101 2+^|imm[4:1\|11] 2+^|1100011 <|[[norm:enc:insttable:bge]]BGE - 4+^|imm[12\|10:5] 2+^|rs2 2+^|rs1 2+^|110 2+^|imm[4:1\|11] 2+^|1100011 <|[[norm:enc:insttable:bltu]]BLTU - 4+^|imm[12\|10:5] 2+^|rs2 2+^|rs1 2+^|111 2+^|imm[4:1\|11] 2+^|1100011 <|[[norm:enc:insttable:bgeu]]BGEU - 6+^|imm[11:0] 2+^|rs1 2+^|000 2+^|rd 2+^|0000011 <|[[norm:enc:insttable:lb]]LB - 6+^|imm[11:0] 2+^|rs1 2+^|001 2+^|rd 2+^|0000011 <|[[norm:enc:insttable:lh]]LH - 6+^|imm[11:0] 2+^|rs1 2+^|010 2+^|rd 2+^|0000011 <|[[norm:enc:insttable:lw]]LW - 6+^|imm[11:0] 2+^|rs1 2+^|100 2+^|rd 2+^|0000011 <|[[norm:enc:insttable:lbu]]LBU - 6+^|imm[11:0] 2+^|rs1 2+^|101 2+^|rd 2+^|0000011 <|[[norm:enc:insttable:lbhu]]LHU - 4+^|imm[11:5] 2+^|rs2 2+^|rs1 2+^|000 2+^|imm[4:0] 2+^|0100011 <|[[norm:enc:insttable:sb]]SB - 4+^|imm[11:5] 2+^|rs2 2+^|rs1 2+^|001 2+^|imm[4:0] 2+^|0100011 <|[[norm:enc:insttable:sh]]SH - 4+^|imm[11:5] 2+^|rs2 2+^|rs1 2+^|010 2+^|imm[4:0] 2+^|0100011 <|[[norm:enc:insttable:sw]]SW - 6+^|imm[11:0] 2+^|rs1 2+^|000 2+^|rd 2+^|0010011 <|[[norm:enc:insttable:addi]]ADDI - 6+^|imm[11:0] 2+^|rs1 2+^|010 2+^|rd 2+^|0010011 <|[[norm:enc:insttable:slti]]SLTI - 6+^|imm[11:0] 2+^|rs1 2+^|011 2+^|rd 2+^|0010011 <|[[norm:enc:insttable:sltiu]]SLTIU - 6+^|imm[11:0] 2+^|rs1 2+^|100 2+^|rd 2+^|0010011 <|[[norm:enc:insttable:xori]]XORI - 6+^|imm[11:0] 2+^|rs1 2+^|110 2+^|rd 2+^|0010011 <|[[norm:enc:insttable:ori]]ORI - 6+^|imm[11:0] 2+^|rs1 2+^|111 2+^|rd 2+^|0010011 <|[[norm:enc:insttable:andi]]ANDI - 4+^|0000000 2+^|shamt 2+^|rs1 2+^|001 2+^|rd 2+^|0010011 <|[[norm:enc:insttable:slli]]SLLI - 4+^|0000000 2+^|shamt 2+^|rs1 2+^|101 2+^|rd 2+^|0010011 <|[[norm:enc:insttable:srli]]SRLI - 4+^|0100000 2+^|shamt 2+^|rs1 2+^|101 2+^|rd 2+^|0010011 <|[[norm:enc:insttable:srai]]SRAI - 4+^|0000000 2+^|rs2 2+^|rs1 2+^|000 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:add]]ADD - 4+^|0100000 2+^|rs2 2+^|rs1 2+^|000 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:sub]]SUB - 4+^|0000000 2+^|rs2 2+^|rs1 2+^|001 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:sll]]SLL - 4+^|0000000 2+^|rs2 2+^|rs1 2+^|010 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:slt]]SLT - 4+^|0000000 2+^|rs2 2+^|rs1 2+^|011 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:sltu]]SLTU - 4+^|0000000 2+^|rs2 2+^|rs1 2+^|100 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:xor]]XOR - 4+^|0000000 2+^|rs2 2+^|rs1 2+^|101 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:srl]]SRL - 4+^|0100000 2+^|rs2 2+^|rs1 2+^|101 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:sra]]SRA - 4+^|0000000 2+^|rs2 2+^|rs1 2+^|110 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:or]]OR - 4+^|0000000 2+^|rs2 2+^|rs1 2+^|111 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:and]]AND - 3+^|fm 2+^|pred 1+^|succ 2+^|rs1 2+^|000 2+^|rd 2+^|0001111 <|[[norm:enc:insttable:fence]]FENCE - 3+^|1000 2+^|0011 1+^|0011 2+^|00000 2+^|000 2+^|00000 2+^|0001111 <|[[norm:enc:insttable:fence-tso]]FENCE.TSO - 3+^|0000 2+^|0001 1+^|0000 2+^|00000 2+^|000 2+^|00000 2+^|0001111 <|[[norm:enc:insttable:pause]]PAUSE - 6+^|000000000000 2+^|00000 2+^|000 2+^|00000 2+^|1110011 <|[[norm:enc:insttable:ecall]]ECALL - 6+^|000000000001 2+^|00000 2+^|000 2+^|00000 2+^|1110011 <|[[norm:enc:insttable:ebreak]]EBREAK +10+^|imm[31:12] 2+^|rd 2+^|0110111 <|[[norm:lui_enc]]]LUI +10+^|imm[31:12] 2+^|rd 2+^|0010111 <|[[norm:auipc_enc]]]AUIPC +10+^|imm[20\|10:1\|11\|19:12] 2+^|rd 2+^|1101111 <|[[norm:jal_enc]]]JAL + 6+^|imm[11:0] 2+^|rs1 2+^|000 2+^|rd 2+^|1100111 <|[[norm:jalr_enc]]]JALR + 4+^|imm[12\|10:5] 2+^|rs2 2+^|rs1 2+^|000 2+^|imm[4:1\|11] 2+^|1100011 <|[[norm:beq_enc]]]BEQ + 4+^|imm[12\|10:5] 2+^|rs2 2+^|rs1 2+^|001 2+^|imm[4:1\|11] 2+^|1100011 <|[[norm:bne_enc]]]BNE + 4+^|imm[12\|10:5] 2+^|rs2 2+^|rs1 2+^|100 2+^|imm[4:1\|11] 2+^|1100011 <|[[norm:blt_enc]]]BLT + 4+^|imm[12\|10:5] 2+^|rs2 2+^|rs1 2+^|101 2+^|imm[4:1\|11] 2+^|1100011 <|[[norm:bge_enc]]]BGE + 4+^|imm[12\|10:5] 2+^|rs2 2+^|rs1 2+^|110 2+^|imm[4:1\|11] 2+^|1100011 <|[[norm:bltu_enc]]]BLTU + 4+^|imm[12\|10:5] 2+^|rs2 2+^|rs1 2+^|111 2+^|imm[4:1\|11] 2+^|1100011 <|[[norm:bgeu_enc]]]BGEU + 6+^|imm[11:0] 2+^|rs1 2+^|000 2+^|rd 2+^|0000011 <|[[norm:lb_enc]]]LB + 6+^|imm[11:0] 2+^|rs1 2+^|001 2+^|rd 2+^|0000011 <|[[norm:lh_enc]]]LH + 6+^|imm[11:0] 2+^|rs1 2+^|010 2+^|rd 2+^|0000011 <|[[norm:lw_enc]]]LW + 6+^|imm[11:0] 2+^|rs1 2+^|100 2+^|rd 2+^|0000011 <|[[norm:lbu_enc]]]LBU + 6+^|imm[11:0] 2+^|rs1 2+^|101 2+^|rd 2+^|0000011 <|[[norm:lhu_enc]]]LHU + 4+^|imm[11:5] 2+^|rs2 2+^|rs1 2+^|000 2+^|imm[4:0] 2+^|0100011 <|[[norm:sb_enc]]]SB + 4+^|imm[11:5] 2+^|rs2 2+^|rs1 2+^|001 2+^|imm[4:0] 2+^|0100011 <|[[norm:sh_enc]]]SH + 4+^|imm[11:5] 2+^|rs2 2+^|rs1 2+^|010 2+^|imm[4:0] 2+^|0100011 <|[[norm:sw_enc]]]SW + 6+^|imm[11:0] 2+^|rs1 2+^|000 2+^|rd 2+^|0010011 <|[[norm:addi_enc]]]ADDI + 6+^|imm[11:0] 2+^|rs1 2+^|010 2+^|rd 2+^|0010011 <|[[norm:slti_enc]]]SLTI + 6+^|imm[11:0] 2+^|rs1 2+^|011 2+^|rd 2+^|0010011 <|[[norm:sltiu_enc]]]SLTIU + 6+^|imm[11:0] 2+^|rs1 2+^|100 2+^|rd 2+^|0010011 <|[[norm:xori_enc]]]XORI + 6+^|imm[11:0] 2+^|rs1 2+^|110 2+^|rd 2+^|0010011 <|[[norm:ori_enc]]]ORI + 6+^|imm[11:0] 2+^|rs1 2+^|111 2+^|rd 2+^|0010011 <|[[norm:andi_enc]]]ANDI + 4+^|0000000 2+^|shamt 2+^|rs1 2+^|001 2+^|rd 2+^|0010011 <|[[norm:slli_enc]]]SLLI + 4+^|0000000 2+^|shamt 2+^|rs1 2+^|101 2+^|rd 2+^|0010011 <|[[norm:srli_enc]]]SRLI + 4+^|0100000 2+^|shamt 2+^|rs1 2+^|101 2+^|rd 2+^|0010011 <|[[norm:srai_enc]]]SRAI + 4+^|0000000 2+^|rs2 2+^|rs1 2+^|000 2+^|rd 2+^|0110011 <|[[norm:add_enc]]]ADD + 4+^|0100000 2+^|rs2 2+^|rs1 2+^|000 2+^|rd 2+^|0110011 <|[[norm:sub_enc]]]SUB + 4+^|0000000 2+^|rs2 2+^|rs1 2+^|001 2+^|rd 2+^|0110011 <|[[norm:sll_enc]]]SLL + 4+^|0000000 2+^|rs2 2+^|rs1 2+^|010 2+^|rd 2+^|0110011 <|[[norm:slt_enc]]]SLT + 4+^|0000000 2+^|rs2 2+^|rs1 2+^|011 2+^|rd 2+^|0110011 <|[[norm:sltu_enc]]]SLTU + 4+^|0000000 2+^|rs2 2+^|rs1 2+^|100 2+^|rd 2+^|0110011 <|[[norm:xor_enc]]]XOR + 4+^|0000000 2+^|rs2 2+^|rs1 2+^|101 2+^|rd 2+^|0110011 <|[[norm:srl_enc]]]SRL + 4+^|0100000 2+^|rs2 2+^|rs1 2+^|101 2+^|rd 2+^|0110011 <|[[norm:sra_enc]]]SRA + 4+^|0000000 2+^|rs2 2+^|rs1 2+^|110 2+^|rd 2+^|0110011 <|[[norm:or_enc]]]OR + 4+^|0000000 2+^|rs2 2+^|rs1 2+^|111 2+^|rd 2+^|0110011 <|[[norm:and_enc]]]AND + 3+^|fm 2+^|pred 1+^|succ 2+^|rs1 2+^|000 2+^|rd 2+^|0001111 <|[[norm:fence_enc]]]FENCE + 3+^|1000 2+^|0011 1+^|0011 2+^|00000 2+^|000 2+^|00000 2+^|0001111 <|[[norm:fence-tso_enc]]]FENCE.TSO + 3+^|0000 2+^|0001 1+^|0000 2+^|00000 2+^|000 2+^|00000 2+^|0001111 <|[[norm:pause_enc]]]PAUSE + 6+^|000000000000 2+^|00000 2+^|000 2+^|00000 2+^|1110011 <|[[norm:ecall_enc]]]ECALL + 6+^|000000000001 2+^|00000 2+^|000 2+^|00000 2+^|1110011 <|[[norm:ebreak_enc]]]EBREAK |=== <<< @@ -117,21 +117,21 @@ these more specialized additions. [%autowidth.stretch,float="center",align="center",cols="^2m,^2m,^2m,^2m,<2m,>3m, <4m, >4m, <4m, >4m, <4m, >4m, <4m, >4m, <6m"] |=== 15+^|*RV64I Base Instruction Set (in addition to RV32I)* - 6+^|imm[11:0] 2+^|rs1 2+^|110 2+^|rd 2+^|0000011 <|[[norm:enc:insttable:lwu]]LWU - 6+^|imm[11:0] 2+^|rs1 2+^|011 2+^|rd 2+^|0000011 <|[[norm:enc:insttable:ld]]LD - 4+^|imm[11:5] 2+^|rs2 2+^|rs1 2+^|011 2+^|imm[4:0] 2+^|0100011 <|[[norm:enc:insttable:sd]]SD + 6+^|imm[11:0] 2+^|rs1 2+^|110 2+^|rd 2+^|0000011 <|[[norm:lwu_enc]]]LWU + 6+^|imm[11:0] 2+^|rs1 2+^|011 2+^|rd 2+^|0000011 <|[[norm:ld_enc]]]LD + 4+^|imm[11:5] 2+^|rs2 2+^|rs1 2+^|011 2+^|imm[4:0] 2+^|0100011 <|[[norm:sd_enc]]]SD 3+^|000000 3+^|shamt 2+^|rs1 2+^|001 2+^|rd 2+^|0010011 <|SLLI 3+^|000000 3+^|shamt 2+^|rs1 2+^|101 2+^|rd 2+^|0010011 <|SRLI 3+^|010000 3+^|shamt 2+^|rs1 2+^|101 2+^|rd 2+^|0010011 <|SRAI - 6+^|imm[11:0] 2+^|rs1 2+^|000 2+^|rd 2+^|0011011 <|[[norm:enc:insttable:addiw]]ADDIW - 4+^|0000000 2+^|shamt 2+^|rs1 2+^|001 2+^|rd 2+^|0011011 <|[[norm:enc:insttable:slliw]]SLLIW - 4+^|0000000 2+^|shamt 2+^|rs1 2+^|101 2+^|rd 2+^|0011011 <|[[norm:enc:insttable:srliw]]SRLIW - 4+^|0100000 2+^|shamt 2+^|rs1 2+^|101 2+^|rd 2+^|0011011 <|[[norm:enc:insttable:sraiw]]SRAIW - 4+^|0000000 2+^|rs2 2+^|rs1 2+^|000 2+^|rd 2+^|0111011 <|[[norm:enc:insttable:addw]]ADDW - 4+^|0100000 2+^|rs2 2+^|rs1 2+^|000 2+^|rd 2+^|0111011 <|[[norm:enc:insttable:subw]]SUBW - 4+^|0000000 2+^|rs2 2+^|rs1 2+^|001 2+^|rd 2+^|0111011 <|[[norm:enc:insttable:sllw]]SLLW - 4+^|0000000 2+^|rs2 2+^|rs1 2+^|101 2+^|rd 2+^|0111011 <|[[norm:enc:insttable:srlw]]SRLW - 4+^|0100000 2+^|rs2 2+^|rs1 2+^|101 2+^|rd 2+^|0111011 <|[[norm:enc:insttable:sraw]]SRAW + 6+^|imm[11:0] 2+^|rs1 2+^|000 2+^|rd 2+^|0011011 <|[[norm:addiw_enc]]]ADDIW + 4+^|0000000 2+^|shamt 2+^|rs1 2+^|001 2+^|rd 2+^|0011011 <|[[norm:slliw_enc]]]SLLIW + 4+^|0000000 2+^|shamt 2+^|rs1 2+^|101 2+^|rd 2+^|0011011 <|[[norm:srliw_enc]]]SRLIW + 4+^|0100000 2+^|shamt 2+^|rs1 2+^|101 2+^|rd 2+^|0011011 <|[[norm:sraiw_enc]]]SRAIW + 4+^|0000000 2+^|rs2 2+^|rs1 2+^|000 2+^|rd 2+^|0111011 <|[[norm:addw_enc]]]ADDW + 4+^|0100000 2+^|rs2 2+^|rs1 2+^|000 2+^|rd 2+^|0111011 <|[[norm:subw_enc]]]SUBW + 4+^|0000000 2+^|rs2 2+^|rs1 2+^|001 2+^|rd 2+^|0111011 <|[[norm:sllw_enc]]]SLLW + 4+^|0000000 2+^|rs2 2+^|rs1 2+^|101 2+^|rd 2+^|0111011 <|[[norm:srlw_enc]]]SRLW + 4+^|0100000 2+^|rs2 2+^|rs1 2+^|101 2+^|rd 2+^|0111011 <|[[norm:sraw_enc]]]SRAW |=== [%autowidth.stretch,float="center",align="center",cols="^2m,^2m,^2m,^2m,<2m,>3m, <4m, >4m, <4m, >4m, <4m, >4m, <4m, >4m, <6m"] |=== @@ -153,24 +153,24 @@ these more specialized additions. [%autowidth.stretch,float="center",align="center",cols="^2m,^2m,^2m,^2m,<2m,>3m, <4m, >4m, <4m, >4m, <4m, >4m, <4m, >4m, <6m"] |=== 15+^|*RV32M Standard Extension* - 4+^|0000001 2+^|rs2 2+^|rs1 2+^|000 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:mul]]MUL - 4+^|0000001 2+^|rs2 2+^|rs1 2+^|001 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:mulh]]MULH - 4+^|0000001 2+^|rs2 2+^|rs1 2+^|010 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:mulhsu]]MULHSU - 4+^|0000001 2+^|rs2 2+^|rs1 2+^|011 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:mulhu]]MULHU - 4+^|0000001 2+^|rs2 2+^|rs1 2+^|100 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:div]]DIV - 4+^|0000001 2+^|rs2 2+^|rs1 2+^|101 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:divu]]DIVU - 4+^|0000001 2+^|rs2 2+^|rs1 2+^|110 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:rem]]REM - 4+^|0000001 2+^|rs2 2+^|rs1 2+^|111 2+^|rd 2+^|0110011 <|[[norm:enc:insttable:remu]]REMU + 4+^|0000001 2+^|rs2 2+^|rs1 2+^|000 2+^|rd 2+^|0110011 <|[[norm:mul_enc]]]MUL + 4+^|0000001 2+^|rs2 2+^|rs1 2+^|001 2+^|rd 2+^|0110011 <|[[norm:mulh_enc]]]MULH + 4+^|0000001 2+^|rs2 2+^|rs1 2+^|010 2+^|rd 2+^|0110011 <|[[norm:mulhsu_enc]]]MULHSU + 4+^|0000001 2+^|rs2 2+^|rs1 2+^|011 2+^|rd 2+^|0110011 <|[[norm:mulhu_enc]]]MULHU + 4+^|0000001 2+^|rs2 2+^|rs1 2+^|100 2+^|rd 2+^|0110011 <|[[norm:div_enc]]]DIV + 4+^|0000001 2+^|rs2 2+^|rs1 2+^|101 2+^|rd 2+^|0110011 <|[[norm:divu_enc]]]DIVU + 4+^|0000001 2+^|rs2 2+^|rs1 2+^|110 2+^|rd 2+^|0110011 <|[[norm:rem_enc]]]REM + 4+^|0000001 2+^|rs2 2+^|rs1 2+^|111 2+^|rd 2+^|0110011 <|[[norm:remu_enc]]]REMU |=== [%autowidth.stretch,float="center",align="center",cols="^2m,^2m,^2m,^2m,<2m,>3m, <4m, >4m, <4m, >4m, <4m, >4m, <4m, >4m, <6m"] |=== 15+^|*RV64M Standard Extension (in addition to RV32M)* - 4+^|0000001 2+^|rs2 2+^|rs1 2+^|000 2+^|rd 2+^|0111011 <|[[norm:enc:insttable:mulw]]MULW - 4+^|0000001 2+^|rs2 2+^|rs1 2+^|100 2+^|rd 2+^|0111011 <|[[norm:enc:insttable:divw]]DIVW - 4+^|0000001 2+^|rs2 2+^|rs1 2+^|101 2+^|rd 2+^|0111011 <|[[norm:enc:insttable:divuw]]DIVUW - 4+^|0000001 2+^|rs2 2+^|rs1 2+^|110 2+^|rd 2+^|0111011 <|[[norm:enc:insttable:remw]]REMW - 4+^|0000001 2+^|rs2 2+^|rs1 2+^|111 2+^|rd 2+^|0111011 <|[[norm:enc:insttable:remuw]]REMUW + 4+^|0000001 2+^|rs2 2+^|rs1 2+^|000 2+^|rd 2+^|0111011 <|[[norm:mulw_enc]]]MULW + 4+^|0000001 2+^|rs2 2+^|rs1 2+^|100 2+^|rd 2+^|0111011 <|[[norm:divw_enc]]]DIVW + 4+^|0000001 2+^|rs2 2+^|rs1 2+^|101 2+^|rd 2+^|0111011 <|[[norm:divuw_enc]]]DIVUW + 4+^|0000001 2+^|rs2 2+^|rs1 2+^|110 2+^|rd 2+^|0111011 <|[[norm:remw_enc]]]REMW + 4+^|0000001 2+^|rs2 2+^|rs1 2+^|111 2+^|rd 2+^|0111011 <|[[norm:remuw_enc]]]REMUW |=== <<< diff --git a/src/rv32.adoc b/src/rv32.adoc index 022195e3..a8034b2d 100644 --- a/src/rv32.adoc +++ b/src/rv32.adoc @@ -39,13 +39,13 @@ Most of the commentary for RV32I also applies to the RV64I base. === Programmers' Model for Base Integer ISA <> shows the unprivileged state for the base integer ISA. -[#norm:base:rv32i:xregwidth]#For RV32I, the 32 `x` registers are each 32 bits wide, -i.e., `XLEN=32`.# [#norm:basegrp:all:x0eq0]#Register `x0` is hardwired with all bits equal to 0.# -[#norm:bases:rv32i_rv64i:other-xregs]#General purpose registers `x1-x31` hold values that various +[#norm:rv32i_xreg_sz]#For RV32I, the 32 `x` registers are each 32 bits wide, +i.e., `XLEN=32`.# [#norm:x0eq0]#Register `x0` is hardwired with all bits equal to 0.# +[#norm:rv32i_rv64i_other_xregs]#General purpose registers `x1-x31` hold values that various instructions interpret as a collection of Boolean values, or as two's complement signed binary integers or unsigned binary integers.# -[[norm:basegrp:all:pcreg]] +[[norm:pcreg_op]] There is one additional unprivileged register: the program counter `pc` holds the address of the current instruction. @@ -136,10 +136,10 @@ RV32E subset, which only has 16 registers In the base RV32I ISA, there are four core instruction formats (R/I/S/U), as shown in <>. All are a fixed 32 bits in length. The base ISA has `IALIGN=32`, meaning that instructions must be aligned on a four-byte boundary in memory. -[#norm:instgrp:taken_cti:ia_misaligned_exc]#An instruction-address-misaligned exception is generated on a taken branch +[#norm:taken_cti_misaligned_exc]#An instruction-address-misaligned exception is generated on a taken branch or unconditional jump if the target address is not `IALIGN-bit` aligned. This exception is reported on the branch or jump instruction, not on the target instruction.# -[#norm:instgrp:cond_branch:no_ia_misaligned_exc_not_taken]#No instruction-address-misaligned exception is generated +[#norm:cond_br_no_ia_misaligned_exc_not_taken]#No instruction-address-misaligned exception is generated for a conditional branch that is not taken.# [NOTE] @@ -165,7 +165,7 @@ opcode space be used for non-conforming extensions. The RISC-V ISA keeps the source (_rs1_ and _rs2_) and destination (_rd_) registers at the same position in all formats to simplify decoding. -[#norm:basegrp:all:imm_always_sex]#Except for the 5-bit immediates used in CSR instructions (<>), +[#norm:imm_always_sex]#Except for the 5-bit immediates used in CSR instructions (<>), immediates are always sign-extended#, and are generally packed towards the leftmost available bits in the instruction and have been allocated to reduce hardware @@ -302,11 +302,11 @@ comparing the results of ADD and ADDW on the operands. include::images/wavedrom/integer-computational.edn[] //.Integer Computational Instructions -[#norm:inst:addi:operation]#ADDI adds the sign-extended 12-bit immediate to register _rs1_.# -[#norm:inst:addi:overflow]#Arithmetic overflow is ignored and the result is simply the low XLEN bits of the result.# +[#norm:addi_op]#ADDI adds the sign-extended 12-bit immediate to register _rs1_.# +[#norm:addi_overflow]#Arithmetic overflow is ignored and the result is simply the low XLEN bits of the result.# ADDI _rd, rs1, 0_ is used to implement the MV _rd, rs1_ assembler pseudoinstruction. -[#norm:insts:slti_sltiu:operation]#SLTI (set less than immediate) places the value 1 in register _rd_ if +[#norm:slti_sltiu_op]#SLTI (set less than immediate) places the value 1 in register _rd_ if register _rs1_ is less than the sign-extended immediate when both are treated as signed numbers, else 0 is written to _rd_. SLTIU is similar but compares the values as unsigned numbers (i.e., the immediate is @@ -314,7 +314,7 @@ first sign-extended to XLEN bits then treated as an unsigned number).# Note, SLTIU _rd, rs1, 1_ sets _rd_ to 1 if _rs1_ equals zero, otherwise sets _rd_ to 0 (assembler pseudoinstruction SEQZ _rd, rs_). -[#norm:insts:andi_ori_xori:operation]#ANDI, ORI, XORI are logical operations that perform bitwise AND, OR, and +[#norm:andi_ori_xori_op]#ANDI, ORI, XORI are logical operations that perform bitwise AND, OR, and XOR on register _rs1_ and the sign-extended 12-bit immediate and place the result in _rd_.# Note, XORI _rd, rs1, -1_ performs a bitwise logical inversion of register _rs1_ (assembler pseudoinstruction NOT _rd, rs_). @@ -327,21 +327,21 @@ Shifts by a constant are encoded as a specialization of the I-type format. The operand to be shifted is in _rs1_, and the shift amount is encoded in the lower 5 bits of the I-immediate field. The right shift type is encoded in bit 30. -[#norm:inst:slli:operation]#SLLI is a logical left shift (zeros are shifted into the lower bits);# -[#norm:inst:srli:operation]#SRLI is a logical right shift (zeros are shifted into the upper bits);# and -[#norm:inst:srai:operation]#SRAI is an arithmetic right shift (the original sign bit is copied into the vacated upper bits).# +[#norm:slli_op]#SLLI is a logical left shift (zeros are shifted into the lower bits);# +[#norm:srli_op]#SRLI is a logical right shift (zeros are shifted into the upper bits);# and +[#norm:srai_op]#SRAI is an arithmetic right shift (the original sign bit is copied into the vacated upper bits).# include::images/wavedrom/int-comp-lui-aiupc.edn[] [[int-comp-lui-aiupc]] //.Integer register-immediate, U-immediate LUI (load upper immediate) is used to build 32-bit constants and uses the U-type format. -[#norm:inst:lui:operation]#LUI places the 32-bit U-immediate value into the +[#norm:lui_op]#LUI places the 32-bit U-immediate value into the destination register _rd_, filling in the lowest 12 bits with zeros.# AUIPC (add upper immediate to `pc`) is used to build `pc`-relative addresses and uses the U-type format. -[#norm:inst:auipc:operation]#AUIPC forms a 32-bit offset from +[#norm:auipc_op]#AUIPC forms a 32-bit offset from the U-immediate, filling in the lowest 12 bits with zeros, adds this offset to the address of the AUIPC instruction, then places the result in register _rd_.# @@ -367,7 +367,7 @@ microarchitectures. ==== Integer Register-Register Operations -RV32I defines several arithmetic R-type operations. [#norm:basegrp:all:R-type_operands]#All operations read +RV32I defines several arithmetic R-type operations. [#norm:R-type_operands]#All operations read the _rs1_ and _rs2_ registers as source operands and write the result into register _rd_.# The _funct7_ and _funct3_ fields select the type of operation. @@ -375,16 +375,16 @@ include::images/wavedrom/int-reg-reg.edn[] [[int-reg-reg]] //.Integer register-register -[#norm:inst:add:operation]#ADD performs the addition of _rs1_ and _rs2_.# -[#norm:inst:sub:operation]#SUB performs the subtraction of _rs2_ from _rs1_.# -[#norm:insts:add_sub:overflow]#Overflows are ignored and the low XLEN bits of results are written to the destination _rd_.# -[#norm:insts:slt_sltu:operation]#SLT and SLTU perform signed and unsigned compares respectively, writing 1 to _rd_ if +[#norm:add_op]#ADD performs the addition of _rs1_ and _rs2_.# +[#norm:sub_op]#SUB performs the subtraction of _rs2_ from _rs1_.# +[#norm:add_sub_overflow]#Overflows are ignored and the low XLEN bits of results are written to the destination _rd_.# +[#norm:slt_sltu_op]#SLT and SLTU perform signed and unsigned compares respectively, writing 1 to _rd_ if _rs1_ < _rs2_, 0 otherwise.# Note, SLTU _rd_, _x0_, _rs2_ sets _rd_ to 1 if _rs2_ is not equal to zero, otherwise sets _rd_ to zero (assembler pseudoinstruction SNEZ _rd, rs_). -[#norm:insts:and_or_xor:operation]#AND, OR, and XOR perform bitwise logical operations.# +[#norm:and_or_xor_op]#AND, OR, and XOR perform bitwise logical operations.# -[#norm:insts:sll_srl_sra:operation]#SLL, SRL, and SRA perform logical left, logical right, and arithmetic +[#norm:sll_srl_sra_op]#SLL, SRL, and SRA perform logical left, logical right, and arithmetic right shifts on the value in register _rs1_ by the shift amount held in the lower 5 bits of register _rs2_.# @@ -421,19 +421,19 @@ hardware. === Control Transfer Instructions RV32I provides two types of control transfer instructions: unconditional jumps and conditional branches. -[#norm:instgrp:cti:no_cti_delay_slots]#Control transfer instructions in RV32I +[#norm:no_cti_delay_slots]#Control transfer instructions in RV32I do _not_ have architecturally visible delay slots.# -[#norm:instgrp:cti:ia_fault_exc_on_target]#If an instruction access-fault or instruction page-fault exception +[#norm:ia_fault_exc_on_target]#If an instruction access-fault or instruction page-fault exception occurs on the target of a jump or taken branch, the exception is reported on the target instruction, not on the jump or branch instruction.# ==== Unconditional Jumps The jump and link (JAL) instruction uses the J-type format, where the J-immediate encodes a signed offset in multiples of 2 bytes. -[#norm:inst:jal:target]#The offset is sign-extended and added to the address of the jump instruction to +[#norm:jal_target]#The offset is sign-extended and added to the address of the jump instruction to form the jump target address.# Jumps can therefore target a ±1 MiB range. -[#norm:inst:jal:operation]#JAL stores the address of the instruction +[#norm:jal_op]#JAL stores the address of the instruction following the jump ('pc'+4) into register _rd_.# The standard software calling convention uses 'x1' as the return address register and 'x5' as an alternate link register. @@ -456,10 +456,10 @@ include::images/wavedrom/ct-unconditional.edn[] //.The unconditional-jump instruction, JAL The indirect jump instruction JALR (jump and link register) uses the I-type encoding. -[#norm:inst:jalr:target]#The target address is obtained by adding the +[#norm:jalr_target]#The target address is obtained by adding the sign-extended 12-bit I-immediate to the register _rs1_, then setting the least-significant bit of the result to zero.# -[#norm:inst:jalr:operation]#The address of the +[#norm:jalr_op]#The address of the instruction following the jump (`pc`+4) is written to register _rd_.# Register `x0` can be used as the destination if the result is not required. @@ -559,7 +559,7 @@ is only pushed to enable macro-op fusion of the sequences: ==== Conditional Branches All branch instructions use the B-type instruction format. -[#norm:instgrp:branch:target]#The 12-bit B-immediate encodes signed offsets in multiples of 2 bytes. The offset +[#norm:br_target]#The 12-bit B-immediate encodes signed offsets in multiples of 2 bytes. The offset is sign-extended and added to the address of the branch instruction to give the target address.# The conditional branch range is ±4 KiB. @@ -568,10 +568,10 @@ include::images/wavedrom/ct-conditional.edn[] //.Conditional branches Branch instructions compare two registers. -[#norm:insts:beq_bne:operation]#BEQ and BNE take the branch if registers _rs1_ and _rs2_ are equal or unequal respectively.# -[#norm:insts:blt_bltu:operation]#BLT and BLTU take the branch if _rs1_ is less than _rs2_, using signed and +[#norm:beq_bne_op]#BEQ and BNE take the branch if registers _rs1_ and _rs2_ are equal or unequal respectively.# +[#norm:blt_bltu_op]#BLT and BLTU take the branch if _rs1_ is less than _rs2_, using signed and unsigned comparison respectively.# -[#norm:insts:bge_bgeu:operation]#BGE and BGEU take the branch if _rs1_ is greater than or equal to _rs2_, +[#norm:bge_bgeu_op]#BGE and BGEU take the branch if _rs1_ is greater than or equal to _rs2_, using signed and unsigned comparison respectively.# Note, BGT, BGTU, BLE, and BLEU can be synthesized by reversing the operands to BLT, BLTU, BGE, and BGEU, respectively. @@ -674,29 +674,29 @@ CPU registers. RV32I provides a 32-bit address space that is byte-addressed. The EEI will define what portions of the address space are legal to access with which instructions (e.g., some addresses might be read only, or support word access only). -[#norm:instgrp:load:exc_x0]#Loads with a destination of +[#norm:load_exc_x0]#Loads with a destination of `x0` must still raise any exceptions and cause any other side effects even though the load value is discarded.# -[#norm:param:endianness:little_or_big]#The EEI will define whether the memory system is little-endian or big-endian.# -[#norm:instgrp:load_store:endian_byte_invariant]#In RISC-V, endianness is byte-address invariant.# +[#norm:ENDIANNESS_LITTLE_OR_BIG]#The EEI will define whether the memory system is little-endian or big-endian.# +[#norm:ldst_endian_byte_invariant]#In RISC-V, endianness is byte-address invariant.# [NOTE] ==== -[[norm:instgrp:load_store:endian_byte_operation]] +[[norm:ldst_endian_byte_op]] In a system for which endianness is byte-address invariant, the following property holds: if a byte is stored to memory at some address in some endianness, then a byte-sized load from that address in any endianness returns the stored value. -[[norm:instgrp:load_store:little_endian_operation]] +[[norm:ldst_little_endian_op]] In a little-endian configuration, multibyte stores write the least-significant register byte at the lowest memory byte address, followed by the other register bytes in ascending order of their significance. Loads similarly transfer the contents of the lesser memory byte addresses to the less-significant register bytes. -[[norm:instgrp:load_store:big_endian_operation]] +[[norm:ldst_big_endian_op]] In a big-endian configuration, multibyte stores write the most-significant register byte at the lowest memory byte address, followed by the other register bytes in descending order of their @@ -710,44 +710,44 @@ include::images/wavedrom/load-store.edn[] Load and store instructions transfer a value between the registers and memory. Loads are encoded in the I-type format and stores are S-type. -[#norm:instgrp:load_store:ea]#The effective address is obtained by adding register _rs1_ to the +[#norm:ldst_ea]#The effective address is obtained by adding register _rs1_ to the sign-extended 12-bit offset.# -[#norm:instgrp:load:operation]#Loads copy a value from memory to register _rd_.# -[#norm:instgrp:store:operation]#Stores copy the value in register _rs2_ to memory.# +[#norm:load_op]#Loads copy a value from memory to register _rd_.# +[#norm:store_op]#Stores copy the value in register _rs2_ to memory.# -[#norm:inst:lw:operation]#The LW instruction loads a 32-bit value from memory into _rd_.# -[#norm:inst:lh:operation]#LH loads a 16-bit value from memory, then sign-extends to 32-bits before storing +[#norm:lw_op]#The LW instruction loads a 32-bit value from memory into _rd_.# +[#norm:lh_op]#LH loads a 16-bit value from memory, then sign-extends to 32-bits before storing in _rd_.# -[#norm:inst:lhu:operation]#LHU loads a 16-bit value from memory but then zero extends to +[#norm:lhu_op]#LHU loads a 16-bit value from memory but then zero extends to 32-bits before storing in _rd_.# -[#norm:insts:lb_lbu:operation]#LB and LBU are defined analogously for 8-bit values.# -[#norm:insts:sw_sh_sb:operation]#The SW, SH, and SB instructions store 32-bit, 16-bit, and +[#norm:lb_lbu_op]#LB and LBU are defined analogously for 8-bit values.# +[#norm:sw_sh_sb_op]#The SW, SH, and SB instructions store 32-bit, 16-bit, and 8-bit values from the low bits of register _rs2_ to memory.# -Regardless of EEI, [#norm:instgrp:load_store:no_exc_aligned]#loads and stores whose effective addresses are +Regardless of EEI, [#norm:ldst_no_exc_aligned]#loads and stores whose effective addresses are naturally aligned shall not raise an address-misaligned exception.# -[#norm:param:misaligned_ldst:eei_dependent_behavior]#Loads and stores whose effective address is not naturally aligned to the +[#norm:MISALIGNED_LDST_EEI_DEPENDENT_BEHAVIOR]#Loads and stores whose effective address is not naturally aligned to the referenced datatype (i.e., the effective address is not divisible by the size of the access in bytes) have behavior dependent on the EEI.# An EEI may guarantee that misaligned loads and stores are fully supported, and so the software running inside the execution environment will never experience a contained or fatal address-misaligned trap. In this case, the -[#norm:param:misaligned_ldst:fully_hw_supported]#misaligned loads and stores can be handled in hardware#, or -[#norm:param:misaligned_ldst:invisible_trap]#via an invisible trap into the execution environment implementation#, or possibly a -[#norm:param:misaligned_ldst:hw_or_invisible_trap_func_of_addr]#combination of hardware and invisible trap depending on address.# +[#norm:MISALIGNED_LDST_FULLY_HW_SUPPORTED]#misaligned loads and stores can be handled in hardware#, or +[#norm:MISALIGNED_LDST_INVISIBLE_TRAP]#via an invisible trap into the execution environment implementation#, or possibly a +[#norm:MISALIGNED_LDST_HW_OR_INVISIBLE_TRAP_FUNC_OF_ADDR]#combination of hardware and invisible trap depending on address.# An EEI may not guarantee misaligned loads and stores are handled invisibly. In this case, -[#norm:param:misaligned_ldst:fully_hw_supported_or_visible_trap]#loads and stores that are not naturally aligned +[#norm:MISALIGNED_LDST_FULLY_HW_SUPPORTED_OR_VISIBLE_TRAP]#loads and stores that are not naturally aligned may either complete execution successfully or raise an exception.# -[#norm:instgrp:load_store:addr_misaligned_or_access_fault_exc]#The exception raised can be either an +[#norm:ldst_addr_misaligned_or_access_fault_exc]#The exception raised can be either an address-misaligned exception or an access-fault exception. For a memory access that would otherwise be able to complete except for the misalignment, an access-fault exception can be raised instead of an address-misaligned exception if the misaligned access should not be emulated, e.g., if accesses to the memory region have side effects.# -[#norm:param:misaligned_ldst:contained_or_fatal_trap]#When an EEI does not guarantee misaligned loads and +[#norm:MISALIGNED_LDST_CONTAINED_OR_FATAL_TRAP]#When an EEI does not guarantee misaligned loads and stores are handled invisibly, the EEI must define if exceptions caused by address misalignment result in a contained trap (allowing software running inside the execution environment to handle the trap) or a fatal @@ -779,7 +779,7 @@ very simplified addressing modes (e.g., register indirect only). Even when misaligned loads and stores complete successfully, these accesses might run extremely slowly depending on the implementation (e.g., when implemented via an invisible trap). Furthermore, whereas -[#norm:instgrp:load_store:atomicity_for_aligned]#naturally aligned +[#norm:ldst_atomicity_for_aligned]#naturally aligned loads and stores are guaranteed to execute atomically#, misaligned loads and stores might not, and hence require additional synchronization to ensure atomicity. @@ -850,13 +850,13 @@ FENCE instruction. |=== The FENCE mode field _fm_ defines the semantics of the FENCE instruction. -[#norm:inst:fence:operation]#A `FENCE` +[#norm:fence_op]#A `FENCE` (with _fm_=`0000`) orders all memory operations in its predecessor set before all memory operations in its successor set.# A `FENCE.TSO` instruction is encoded as a FENCE instruction with _fm_=`1000`, _predecessor_=`RW`, and _successor_=`RW`. -[#norm:inst:fence-tso:operation]#`FENCE.TSO` orders +[#norm:fence-tso_op]#`FENCE.TSO` orders all load operations in its predecessor set before all memory operations in its successor set, and all store operations in its predecessor set before all store operations in its successor set. This leaves `non-AMO` @@ -865,12 +865,12 @@ store operations in the `FENCE.TSO's` predecessor set unordered with [NOTE] ==== -[[norm:inst:fence-tso:ordering_rw_rw_allowed]] +[[norm:fence-tso_ordering_rw_rw_ok]] Because `FENCE RW,RW` imposes a superset of the orderings that `FENCE.TSO` imposes, it is correct to ignore the _fm_ field and implement `FENCE.TSO` as `FENCE RW,RW`. ==== -[#norm:inst:fence:unused_fields_reserved]#The unused fields in the FENCE +[#norm:fence_unused_flds_rsv]#The unused fields in the FENCE instructions--_rs1_ and _rd_--are reserved for finer-grain fences in future extensions. For forward compatibility, base implementations shall ignore these fields#, and standard software @@ -882,7 +882,7 @@ non-reserved configurations. [NOTE] ==== -[[norm:inst:fence:conservative_allowed]] +[[norm:fence_cons_ok]] We chose a relaxed memory model to allow high performance from simple machine implementations and from likely future coprocessor or accelerator extensions. We separate out I/O ordering from memory R/W @@ -919,12 +919,12 @@ include::images/wavedrom/env-call-breakpoint.edn[] These two instructions cause a precise requested trap to the supporting execution environment. -[#norm:inst:ecall:operation]#The `ECALL` instruction is used to make a service request to the execution environment.# +[#norm:ecall_op]#The `ECALL` instruction is used to make a service request to the execution environment.# The `EEI` will define how parameters for the service request are passed, but usually these will be in defined locations in the integer register file. -[#norm:inst:ebreak:operation]#The `EBREAK` instruction is used to return control to a debugging environment.# +[#norm:ebreak_op]#The `EBREAK` instruction is used to return control to a debugging environment.# [NOTE] ==== @@ -999,7 +999,7 @@ _rs1_ and _rs2_ fields encode arguments to the HINT. However, a simple implementation can simply execute the HINT as an ADD of _rs1_ and _rs2_ that writes `x0`, which has no architecturally visible effect. -[[norm:inst:fence:null_pred_succ_intersection]] +[[norm:fence_null_pred_succ_inter]] As another example, a FENCE instruction with a zero _pred_ field and a zero _fm_ field is a HINT; the _succ_, _rs1_, and _rd_ fields encode the arguments to the HINT. A simple implementation can simply execute the diff --git a/src/rv64.adoc b/src/rv64.adoc index 53fa6246..c5ed2dac 100644 --- a/src/rv64.adoc +++ b/src/rv64.adoc @@ -8,14 +8,14 @@ in conjunction with the earlier chapter. === Register State -[#norm:base:rv64i:xregwidth]#RV64I widens the integer registers and supported user address space to +[#norm:rv64i_xreg_sz]#RV64I widens the integer registers and supported user address space to 64 bits (XLEN=64 in <>).# === Integer Computational Instructions Most integer computational instructions operate on XLEN-bit values. Additional instruction variants are provided to manipulate 32-bit values -in RV64I, indicated by a 'W' suffix to the opcode. [#norm:base:rv64i:w_sex_to_64]#These "*W" +in RV64I, indicated by a 'W' suffix to the opcode. [#norm:rv64_w_sex]#These "*W" instructions ignore the upper 32 bits of their inputs and always produce 32-bit signed values, sign-extending them to 64 bits, i.e. bits XLEN-1 through 31 are equal.# @@ -43,9 +43,9 @@ include::images/wavedrom/rv64i-base-int.edn[] [[rv64i-base-int]] //.RV64I register-immediate instructions -[#norm:inst:addiw:operation]#ADDIW is an RV64I instruction that adds the sign-extended 12-bit +[#norm:addiw_op]#ADDIW is an RV64I instruction that adds the sign-extended 12-bit immediate to register _rs1_ and produces the proper sign extension of a -32-bit result in _rd_.# [#norm:inst:addiw:overflow]#Overflows are ignored and the result is the low +32-bit result in _rd_.# [#norm:addiw_overflow]#Overflows are ignored and the result is the low 32 bits of the result sign-extended to 64 bits.# Note, ADDIW _rd, rs1, 0_ writes the sign extension of the lower 32 bits of register _rs1_ into register _rd_ (assembler pseudoinstruction SEXT.W). @@ -70,9 +70,9 @@ copied into the vacated upper bits). include::images/wavedrom/rv64i-slliw.edn[] [[rv64i-slliw]] -[#norm:insts:slliw_srliw_sraiw:operation]#SLLIW, SRLIW, and SRAIW are RV64I-only instructions that are analogously +[#norm:slliw_srliw_sraiw_op]#SLLIW, SRLIW, and SRAIW are RV64I-only instructions that are analogously defined but operate on 32-bit values and sign-extend their 32-bit -results to 64 bits.# [#norm:insts:slliw_srliw_sraiw:imm5_rsv]#SLLIW, SRLIW, and SRAIW encodings with +results to 64 bits.# [#norm:slliw_srliw_sraiw_imm5_rsv]#SLLIW, SRLIW, and SRAIW encodings with _imm[5] ≠ 0_ are reserved.# [NOTE] @@ -87,14 +87,14 @@ include::images/wavedrom/rv64-lui-auipc.edn[] //.RV64I register-immediate (descr) instructions LUI (load upper immediate) uses the same opcode as RV32I. -[#norm:inst:lui:rv64i_operation]#LUI places the +[#norm:lui_op_rv64i]#LUI places the 32-bit U-immediate into register _rd_, filling in the lowest 12 bits with zeros. The 32-bit result is sign-extended to 64 bits.# (((RV64I, LUI))) AUIPC (add upper immediate to `pc`) uses the same opcode as RV32I. AUIPC is used to build `pc`-relative addresses and uses the U-type format. -[#norm:inst:auipc:rv64i_operation]#AUIPC forms a 32-bit offset from the U-immediate, filling in the lowest +[#norm:auipc_op_rv64i]#AUIPC forms a 32-bit offset from the U-immediate, filling in the lowest 12 bits with zeros, sign-extends the result to 64 bits, adds it to the address of the AUIPC instruction, then places the result in register _rd_.# @@ -112,19 +112,19 @@ include::images/wavedrom/rv64i-int-reg-reg.edn[] [[int_reg-reg]] //.RV64I integer register-register instructions -[#norm:insts:addw_subw:operation]#ADDW and SUBW are RV64I-only instructions that are defined analogously +[#norm:addw_subw_op]#ADDW and SUBW are RV64I-only instructions that are defined analogously to ADD and SUB but operate on 32-bit values and produce signed 32-bit results.# -[#norm:insts:addw_subw:overflow]#Overflows are ignored, and the low 32-bits of the result is +[#norm:addw_subw_overflow]#Overflows are ignored, and the low 32-bits of the result is sign-extended to 64-bits and written to the destination register.# (((RV64I-only, ADDW))) (((RV64I-only, SUBW))) SLL, SRL, and SRA perform logical left, logical right, and arithmetic right shifts on the value in register _rs1_ by the shift amount held in -register _rs2_. [#norm:insts:sll_srl_sra:rv64i_sh_amt]#In RV64I, only the low 6 bits of _rs2_ are considered +register _rs2_. [#norm:sll_srl_sra_sh_amt_rv64i]#In RV64I, only the low 6 bits of _rs2_ are considered for the shift amount.# -[#norm:insts:sllw_srlw_sraw:operation]#SLLW, SRLW, and SRAW are RV64I-only instructions that are analogously +[#norm:sllw_srlw_sraw_op]#SLLW, SRLW, and SRAW are RV64I-only instructions that are analogously defined but operate on 32-bit values and sign-extend their 32-bit results to 64 bits. The shift amount is given by _rs2[4:0]_.# (((RV64I-only, SLLW))) @@ -140,15 +140,15 @@ include::images/wavedrom/load-store.edn[] [[load_store]] //.Load and store instructions -[#norm:inst:ld:rv64i_operation]#The LD instruction loads a 64-bit value from memory into register _rd_ +[#norm:ld_op_rv64i]#The LD instruction loads a 64-bit value from memory into register _rd_ for RV64I.# (((RV64I, LD))) -[#norm:inst:lw:rv64i_operation]#The LW instruction loads a 32-bit value from memory and sign-extends +[#norm:lw_op_rv64i]#The LW instruction loads a 32-bit value from memory and sign-extends this to 64 bits before storing it in register _rd_ for RV64I.# -[#norm:inst:lwu:operation]#The LWU instruction, on the other hand, zero-extends the 32-bit value from -memory for RV64I.# [#norm:insts:lh_lhu_lb_lbu:rv64i_operation]#LH and LHU are defined analogously for 16-bit values, -as are LB and LBU for 8-bit values.# [#norm:insts:sd_sw_sh_sb:rv64i_operation]#The SD, SW, SH, and SB instructions +[#norm:lwu_op]#The LWU instruction, on the other hand, zero-extends the 32-bit value from +memory for RV64I.# [#norm:lh_lhu_lb_lbu_op_rv64i]#LH and LHU are defined analogously for 16-bit values, +as are LB and LBU for 8-bit values.# [#norm:sd_sw_sh_sb_op_rv64i]#The SD, SW, SH, and SB instructions store 64-bit, 32-bit, 16-bit, and 8-bit values from the low bits of register _rs2_ to memory respectively.# diff --git a/src/zilsd.adoc b/src/zilsd.adoc index 34df4f58..c88f3de1 100644 --- a/src/zilsd.adoc +++ b/src/zilsd.adoc @@ -3,9 +3,9 @@ The Zilsd & Zclsd extensions provide load/store pair instructions for RV32, reusing the existing RV64 doubleword load/store instruction encodings. -[#norm:ext:Zilsd:reg_pairs]#Operands containing `src` for store instructions and `dest` for load instructions are held in aligned `x`-register pairs, i.e., register numbers must be even.# Use of misaligned (odd-numbered) registers for these operands is _reserved_. +[#norm:Zilsd_reg_pairs]#Operands containing `src` for store instructions and `dest` for load instructions are held in aligned `x`-register pairs, i.e., register numbers must be even.# Use of misaligned (odd-numbered) registers for these operands is _reserved_. -[[norm:ext:Zilsd:bits_to_pair]] +[[norm:Zilsd_bits_to_pair]] Regardless of endianness, the lower-numbered register holds the low-order bits, and the higher-numbered register holds the high-order bits: e.g., bits 31:0 of an operand in Zilsd might be held in register `x14`, with bits 63:32 of that operand held in `x15`. @@ -34,11 +34,11 @@ The Zilsd extension adds the following RV32-only instructions: |=== -[#norm:ext:Zilsd:align8_no_exc]#As the access size is 64-bit, accesses are only considered naturally aligned for effective addresses that are a multiple of 8. +[#norm:Zilsd_align8_no_exc]#As the access size is 64-bit, accesses are only considered naturally aligned for effective addresses that are a multiple of 8. In this case, these instructions are guaranteed to not raise an address-misaligned exception.# -[#norm:ext:Zilsd:align8_atomic_unknown]#Even if naturally aligned, the memory access might not be performed atomically.# +[#norm:Zilsd_align8_atomic_unknown]#Even if naturally aligned, the memory access might not be performed atomically.# -[#norm:ext:Zilsd:align4_atomic]#If the effective address is a multiple of 4, then each word access is required to be performed atomically.# +[#norm:Zilsd_align4_atomic]#If the effective address is a multiple of 4, then each word access is required to be performed atomically.# The following table summarizes the required behavior: @@ -50,7 +50,7 @@ The following table summarizes the required behavior: |else |no | yes |=== -[#norm:ext:Zilsd:ld_resume_trap]#To ensure resumable trap handling is possible for the load instructions, the base register must +[#norm:Zilsd_ld_resume_trap]#To ensure resumable trap handling is possible for the load instructions, the base register must have its original value if a trap is taken. The other register in the pair can have been updated. This affects x2 for the stack pointer relative instruction and rs1 otherwise.# @@ -100,20 +100,20 @@ Zclsd adds the following RV32-only instructions: === Use of x0 as operand -[[norm:ext:Zilsd:ld_x0]] +[[norm:Zilsd_ld_x0]] LD instructions with destination `x0` are processed as any other load, but the result is discarded entirely and x1 is not written. For C.LDSP, usage of `x0` as the destination is reserved. -[[norm:ext:Zilsd:sd_x0]] +[[norm:Zilsd_sd_x0]] If using `x0` as `src` of SD or C.SDSP, the entire 64-bit operand is zero — i.e., register `x1` is not accessed. C.LD and C.SD instructions can only use `x8-15`. === Exception Handling -[#norm:ext:Zilsd:RVWMO_exc_misaligned]#For the purposes of RVWMO and exception handling, LD and SD instructions are +[#norm:Zilsd_RVWMO_exc_misaligned]#For the purposes of RVWMO and exception handling, LD and SD instructions are considered to be misaligned loads and stores#, with one additional constraint: -[#norm:ext:Zilsd:align4_two_4byte]#an LD or SD instruction whose effective address is a multiple of 4 gives rise +[#norm:Zilsd_align4_two_4byte]#an LD or SD instruction whose effective address is a multiple of 4 gives rise to two 4-byte memory operations.# NOTE: This definition permits LD and SD instructions giving rise to exactly one @@ -156,9 +156,10 @@ Encoding (RV32):: .... Description:: -[#norm:inst:ld:Zilsd_op]#Loads a 64-bit value into registers `rd` and `rd+1`. +[[norm:Zilsd_ld_op]] +Loads a 64-bit value into registers `rd` and `rd+1`. The effective address is obtained by adding register rs1 to the -sign-extended 12-bit offset.# +sign-extended 12-bit offset. Included in: <> @@ -187,9 +188,10 @@ Encoding (RV32):: .... Description:: -[#norm:inst:sd:Zilsd_operation]#Stores a 64-bit value from registers `rs2` and `rs2+1`. +[[norm:Zilsd_sd_op]] +Stores a 64-bit value from registers `rs2` and `rs2+1`. The effective address is obtained by adding register rs1 to the -sign-extended 12-bit offset.# +sign-extended 12-bit offset. Included in: <> @@ -217,7 +219,8 @@ Encoding (RV32):: .... Description:: -[#norm:inst:c-ldsp:operation]#Loads stack-pointer relative 64-bit value into registers `rd'` and `rd'+1`. It computes its effective address by adding the zero-extended offset, scaled by 8, to the stack pointer, `x2`. It expands to `ld rd, offset(x2)`. C.LDSP is only valid when _rd_≠x0; the code points with _rd_=x0 are reserved.# +[[norm:c-ldsp_op]] +Loads stack-pointer relative 64-bit value into registers `rd'` and `rd'+1`. It computes its effective address by adding the zero-extended offset, scaled by 8, to the stack pointer, `x2`. It expands to `ld rd, offset(x2)`. C.LDSP is only valid when _rd_≠x0; the code points with _rd_=x0 are reserved. Included in: <> @@ -244,7 +247,8 @@ Encoding (RV32):: .... Description:: -[#norm:inst:c-sdsp:operation]#Stores a stack-pointer relative 64-bit value from registers `rs2'` and `rs2'+1`. It computes an effective address by adding the _zero_-extended offset, scaled by 8, to the stack pointer, `x2`. It expands to `sd rs2, offset(x2)`.# +[[norm:c-sdsp_op]] +Stores a stack-pointer relative 64-bit value from registers `rs2'` and `rs2'+1`. It computes an effective address by adding the _zero_-extended offset, scaled by 8, to the stack pointer, `x2`. It expands to `sd rs2, offset(x2)`. Included in: <> @@ -273,8 +277,9 @@ Encoding (RV32):: .... Description:: -[#norm:inst:c-ld:operation]#Loads a 64-bit value into registers `rd'` and `rd'+1`. -It computes an effective address by adding the zero-extended offset, scaled by 8, to the base address in register rs1'.# +[[norm:c-ld_op]] +Loads a 64-bit value into registers `rd'` and `rd'+1`. +It computes an effective address by adding the zero-extended offset, scaled by 8, to the base address in register rs1'. Included in: <> @@ -303,8 +308,9 @@ Encoding (RV32):: .... Description:: -[#norm:inst:c-sd:operation]#Stores a 64-bit value from registers `rs2'` and `rs2'+1`. +[[norm:c-sd_op]] +Stores a 64-bit value from registers `rs2'` and `rs2'+1`. It computes an effective address by adding the zero-extended offset, scaled by 8, to the base address in register rs1'. -It expands to `sd rs2', offset(rs1')`.# +It expands to `sd rs2', offset(rs1')`. Included in: <> diff --git a/tagging_normative_rules.adoc b/tagging_normative_rules.adoc new file mode 100644 index 00000000..0ed5675a --- /dev/null +++ b/tagging_normative_rules.adoc @@ -0,0 +1,134 @@ +== How to Tag Normative Rules in the ISA Manuals + +The ISA manuals contain a mix of normative and informative (AKA non-normative) content. +We use AsciiDoctor's anchor facility to tag normative text which is extracted by tools +provided in the link:https://github.com/riscv/docs-resources[docs-resources GitHub repository] +to create machine-readable and human-readable representations of normative rules. + +=== Tagging Normative Rules in RISC-V International Standards + +First, read the link:https://github.com/riscv/docs-resources/blob/main/normative-rules.md[How to Tag Normative Rules in RISC-V International Standards] for information that applies to all RISC-V International standards. This document provides information such as: + +* What exactly is a "normative rule"? +* How does one add normative rule tags to the AsciiDoc files using the AsciiDoc anchor facility? +* Ins and outs and gotchas when using the AsciiDoc anchor facility. +* How are the normative rules extracted from the AsciiDoc files? + +=== Tagging Normative Rules in ISA Manuals + +Now that you've read link:https://github.com/riscv/docs-resources/blob/normative-rules.md[How to Tag Normative Rules in RISC-V International Standards], here's some information specific to tagging normative rules +in the ISA manuals. + +The ISA manual builds upon the anchor naming convention of a "norm:" prefix by following it with +an enum identifying the ISA manual object type, another colon, +one or more names describing the object(s) related to the tag, +another colon and finally an ID that identifies the associated behavior. +It looks like this (where `<>` delimit names, `[]` indicates optional, `*` means 0 or more, and +`_` is used to separate multiple object names if needed): + +[source] +norm::[_]*: + +There are some cases (e.g., CSR field names) where there is a hierachy of object names and so there +are additional colon-separated object-names. +Here's what it looks like with 2 hiearchy levels with a parent/child relationship: + +[source] +norm::[_]*:[_child-]*: + +[NOTE] +We aren't too worried about having long tag names since they are invisible unless viewing the +raw AsciiDoc source so don't clutter the ISA manual output formats like PDFs. So, we've leaned +in the direction of having longer names that provide information about what is being tagged. + +The justification for this naming convention is: + +* Encourages consistency and regularity in names +* Helps ensure anchor names are unique across both ISA manuals (they are in one global namespace) +* Provides some information about which ISA objects (e.g., instructions, extensions, CSRs) are related to the tagged text + +=== Naming Convention Details + +The following table shows the supported ISA object types, the naming convention for them, +and examples for each. + +[%autowidth] +|=== +| Format | Description + +| Format `norm:base::` + +Example `norm:base:rv32i:xregsz` +| One base ISA (rv32i/rv32e/rv64i) + +| Format `norm:bases:[_]+:` + +Example `norm:bases:rv32i_rv64i:num-xregs` +| List of bases + +| Format `norm:basegrp::` + +Example `norm:base:all:x0eq0` +| Named group of bases (e.g., rv32, all) + +| Format `norm:ext::` + +Example `norm:Zilsd_reg_pairs` +| Single extension + +| Format `norm:exts:[_]:` + +Example `norm:exts:F_D:num-fregs` +| List of extensions + +| Format `norm:extgrp::` + +Example `norm:extgrp:security:attacks` +| Named group of extensions + +| Format `norm:enc:insttable:` + +Example `norm:enc:insttable:add` +| Table cell for instruction encoding + +| Format `norm:inst::` + +Example `norm:add_op` +| Single instruction + +| Format `norm:insts:[_]+:` + +Example `norm:add_sub_overflow` +| List of instructions + +| Format `norm:instgrp::` + +Example `norm:instgrp:division:div_by_zero` +| Named group of insts (e.g., branch, load) + +| Format `norm:csr::` + +Example `norm:misa_sz` +| Single CSR + +| Format `norm:csrs:[_]+:` + +Example `norm:csrs:mstatus_sstatus:sz` +| List of CSRs + +| Format `norm:csrgrp::` + +Example `norm:csrgrp:status:sz` +| Named group of CSRs + +| Format `norm:csrfld:::` + +Example `norm:misa_mxl_base_int_sz` +| Single CSR field + +| Format `norm:csrflds::[_]+:` + +Example `norm:csrflds:hip:vseip_vseie:ro` +| List of fields in the same CSR + +| Format `norm:csrsfld:[_]+::` + +Example `norm:csrsfld:vsip_vsie:ssi:operation` +| Same field in the listed CSRs + +| Format `norm:param::` + +Example `norm:endianness_little_or_big` +| Single parameter + +| Format `norm:params:[_]+:` + +Example `norm:params:mutable-misa-a_mutable-misa-b:operation` +| List of parameters + +| Format `norm:paramgrp::` + +Example `norm:paramgrp:mtval-va-report:operation` +| Named group of parameters +|===