// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) // Portions Copyright © 1997-1999 Vita Nuova Limited // Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) // Portions Copyright © 2004,2006 Bruce Ellis // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) // Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others // Portions Copyright © 2009 The Go Authors. All rights reserved. // Portions Copyright © 2019 The Go Authors. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. package riscv import ( "errors" "fmt" "cmd/internal/obj" ) var CSRs map[uint16]string = csrs //go:generate go run ../stringer.go -i $GOFILE -o anames.go -p riscv const ( // Base register numberings. REG_X0 = obj.RBaseRISCV + iota REG_X1 REG_X2 REG_X3 REG_X4 REG_X5 REG_X6 REG_X7 REG_X8 REG_X9 REG_X10 REG_X11 REG_X12 REG_X13 REG_X14 REG_X15 REG_X16 REG_X17 REG_X18 REG_X19 REG_X20 REG_X21 REG_X22 REG_X23 REG_X24 REG_X25 REG_X26 REG_X27 REG_X28 REG_X29 REG_X30 REG_X31 // Floating Point register numberings. REG_F0 REG_F1 REG_F2 REG_F3 REG_F4 REG_F5 REG_F6 REG_F7 REG_F8 REG_F9 REG_F10 REG_F11 REG_F12 REG_F13 REG_F14 REG_F15 REG_F16 REG_F17 REG_F18 REG_F19 REG_F20 REG_F21 REG_F22 REG_F23 REG_F24 REG_F25 REG_F26 REG_F27 REG_F28 REG_F29 REG_F30 REG_F31 // Vector register numberings. REG_V0 REG_V1 REG_V2 REG_V3 REG_V4 REG_V5 REG_V6 REG_V7 REG_V8 REG_V9 REG_V10 REG_V11 REG_V12 REG_V13 REG_V14 REG_V15 REG_V16 REG_V17 REG_V18 REG_V19 REG_V20 REG_V21 REG_V22 REG_V23 REG_V24 REG_V25 REG_V26 REG_V27 REG_V28 REG_V29 REG_V30 REG_V31 // This marks the end of the register numbering. REG_END // General registers reassigned to ABI names. REG_ZERO = REG_X0 REG_RA = REG_X1 // aka REG_LR REG_SP = REG_X2 REG_GP = REG_X3 // aka REG_SB REG_TP = REG_X4 REG_T0 = REG_X5 REG_T1 = REG_X6 REG_T2 = REG_X7 REG_S0 = REG_X8 REG_S1 = REG_X9 REG_A0 = REG_X10 REG_A1 = REG_X11 REG_A2 = REG_X12 REG_A3 = REG_X13 REG_A4 = REG_X14 REG_A5 = REG_X15 REG_A6 = REG_X16 REG_A7 = REG_X17 REG_S2 = REG_X18 REG_S3 = REG_X19 REG_S4 = REG_X20 REG_S5 = REG_X21 REG_S6 = REG_X22 REG_S7 = REG_X23 REG_S8 = REG_X24 REG_S9 = REG_X25 REG_S10 = REG_X26 // aka REG_CTXT REG_S11 = REG_X27 // aka REG_G REG_T3 = REG_X28 REG_T4 = REG_X29 REG_T5 = REG_X30 REG_T6 = REG_X31 // aka REG_TMP // Go runtime register names. REG_CTXT = REG_S10 // Context for closures. REG_G = REG_S11 // G pointer. REG_LR = REG_RA // Link register. REG_TMP = REG_T6 // Reserved for assembler use. // ABI names for floating point registers. REG_FT0 = REG_F0 REG_FT1 = REG_F1 REG_FT2 = REG_F2 REG_FT3 = REG_F3 REG_FT4 = REG_F4 REG_FT5 = REG_F5 REG_FT6 = REG_F6 REG_FT7 = REG_F7 REG_FS0 = REG_F8 REG_FS1 = REG_F9 REG_FA0 = REG_F10 REG_FA1 = REG_F11 REG_FA2 = REG_F12 REG_FA3 = REG_F13 REG_FA4 = REG_F14 REG_FA5 = REG_F15 REG_FA6 = REG_F16 REG_FA7 = REG_F17 REG_FS2 = REG_F18 REG_FS3 = REG_F19 REG_FS4 = REG_F20 REG_FS5 = REG_F21 REG_FS6 = REG_F22 REG_FS7 = REG_F23 REG_FS8 = REG_F24 REG_FS9 = REG_F25 REG_FS10 = REG_F26 REG_FS11 = REG_F27 REG_FT8 = REG_F28 REG_FT9 = REG_F29 REG_FT10 = REG_F30 REG_FT11 = REG_F31 // Names generated by the SSA compiler. REGSP = REG_SP REGG = REG_G ) // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-dwarf.adoc#dwarf-register-numbers var RISCV64DWARFRegisters = map[int16]int16{ // Integer Registers. REG_X0: 0, REG_X1: 1, REG_X2: 2, REG_X3: 3, REG_X4: 4, REG_X5: 5, REG_X6: 6, REG_X7: 7, REG_X8: 8, REG_X9: 9, REG_X10: 10, REG_X11: 11, REG_X12: 12, REG_X13: 13, REG_X14: 14, REG_X15: 15, REG_X16: 16, REG_X17: 17, REG_X18: 18, REG_X19: 19, REG_X20: 20, REG_X21: 21, REG_X22: 22, REG_X23: 23, REG_X24: 24, REG_X25: 25, REG_X26: 26, REG_X27: 27, REG_X28: 28, REG_X29: 29, REG_X30: 30, REG_X31: 31, // Floating-Point Registers. REG_F0: 32, REG_F1: 33, REG_F2: 34, REG_F3: 35, REG_F4: 36, REG_F5: 37, REG_F6: 38, REG_F7: 39, REG_F8: 40, REG_F9: 41, REG_F10: 42, REG_F11: 43, REG_F12: 44, REG_F13: 45, REG_F14: 46, REG_F15: 47, REG_F16: 48, REG_F17: 49, REG_F18: 50, REG_F19: 51, REG_F20: 52, REG_F21: 53, REG_F22: 54, REG_F23: 55, REG_F24: 56, REG_F25: 57, REG_F26: 58, REG_F27: 59, REG_F28: 60, REG_F29: 61, REG_F30: 62, REG_F31: 63, } // Prog.Mark flags. const ( // USES_REG_TMP indicates that a machine instruction generated from the // corresponding *obj.Prog uses the temporary register. USES_REG_TMP = 1 << iota // NEED_JAL_RELOC is set on JAL instructions to indicate that a // R_RISCV_JAL relocation is needed. NEED_JAL_RELOC // NEED_CALL_RELOC is set on an AUIPC instruction to indicate that it // is the first instruction in an AUIPC + JAL pair that needs a // R_RISCV_CALL relocation. NEED_CALL_RELOC // NEED_PCREL_ITYPE_RELOC is set on AUIPC instructions to indicate that // it is the first instruction in an AUIPC + I-type pair that needs a // R_RISCV_PCREL_ITYPE relocation. NEED_PCREL_ITYPE_RELOC // NEED_PCREL_STYPE_RELOC is set on AUIPC instructions to indicate that // it is the first instruction in an AUIPC + S-type pair that needs a // R_RISCV_PCREL_STYPE relocation. NEED_PCREL_STYPE_RELOC // NEED_GOT_PCREL_ITYPE_RELOC is set on AUIPC instructions to indicate that // it is the first instruction in an AUIPC + I-type pair that needs a // R_RISCV_GOT_PCREL_ITYPE relocation. NEED_GOT_PCREL_ITYPE_RELOC ) // RISC-V mnemonics, as defined in the "opcodes" and "opcodes-pseudo" files // at https://github.com/riscv/riscv-opcodes. // // As well as some pseudo-mnemonics (e.g. MOV) used only in the assembler. // // See also "The RISC-V Instruction Set Manual" at https://riscv.org/technical/specifications/. // // If you modify this table, you MUST run 'go generate' to regenerate anames.go! const ( // // Unprivileged ISA (version 20240411) // // 2.4: Integer Computational Instructions AADDI = obj.ABaseRISCV + obj.A_ARCHSPECIFIC + iota ASLTI ASLTIU AANDI AORI AXORI ASLLI ASRLI ASRAI ALUI AAUIPC AADD ASLT ASLTU AAND AOR AXOR ASLL ASRL ASUB ASRA // 2.5: Control Transfer Instructions AJAL AJALR ABEQ ABNE ABLT ABLTU ABGE ABGEU // 2.6: Load and Store Instructions ALW ALWU ALH ALHU ALB ALBU ASW ASH ASB // 2.7: Memory Ordering Instructions AFENCE // 4.2: Integer Computational Instructions (RV64I) AADDIW ASLLIW ASRLIW ASRAIW AADDW ASLLW ASRLW ASUBW ASRAW // 4.3: Load and Store Instructions (RV64I) ALD ASD // 7.1: CSR Instructions (Zicsr) ACSRRW ACSRRS ACSRRC ACSRRWI ACSRRSI ACSRRCI // 13.1: Multiplication Operations AMUL AMULH AMULHU AMULHSU AMULW // 13.2: Division Operations ADIV ADIVU AREM AREMU ADIVW ADIVUW AREMW AREMUW // 14.2: Load-Reserved/Store-Conditional Instructions (Zalrsc) ALRD ASCD ALRW ASCW // 14.4: Atomic Memory Operations (Zaamo) AAMOSWAPD AAMOADDD AAMOANDD AAMOORD AAMOXORD AAMOMAXD AAMOMAXUD AAMOMIND AAMOMINUD AAMOSWAPW AAMOADDW AAMOANDW AAMOORW AAMOXORW AAMOMAXW AAMOMAXUW AAMOMINW AAMOMINUW // 20.5: Single-Precision Load and Store Instructions AFLW AFSW // 20.6: Single-Precision Floating-Point Computational Instructions AFADDS AFSUBS AFMULS AFDIVS AFMINS AFMAXS AFSQRTS AFMADDS AFMSUBS AFNMADDS AFNMSUBS // 20.7: Single-Precision Floating-Point Conversion and Move Instructions AFCVTWS AFCVTLS AFCVTSW AFCVTSL AFCVTWUS AFCVTLUS AFCVTSWU AFCVTSLU AFSGNJS AFSGNJNS AFSGNJXS AFMVXS AFMVSX AFMVXW AFMVWX // 20.8: Single-Precision Floating-Point Compare Instructions AFEQS AFLTS AFLES // 20.9: Single-Precision Floating-Point Classify Instruction AFCLASSS // 21.3: Double-Precision Load and Store Instructions AFLD AFSD // 21.4: Double-Precision Floating-Point Computational Instructions AFADDD AFSUBD AFMULD AFDIVD AFMIND AFMAXD AFSQRTD AFMADDD AFMSUBD AFNMADDD AFNMSUBD // 21.5: Double-Precision Floating-Point Conversion and Move Instructions AFCVTWD AFCVTLD AFCVTDW AFCVTDL AFCVTWUD AFCVTLUD AFCVTDWU AFCVTDLU AFCVTSD AFCVTDS AFSGNJD AFSGNJND AFSGNJXD AFMVXD AFMVDX // 21.6: Double-Precision Floating-Point Compare Instructions AFEQD AFLTD AFLED // 21.7: Double-Precision Floating-Point Classify Instruction AFCLASSD // 22.1 Quad-Precision Load and Store Instructions AFLQ AFSQ // 22.2: Quad-Precision Computational Instructions AFADDQ AFSUBQ AFMULQ AFDIVQ AFMINQ AFMAXQ AFSQRTQ AFMADDQ AFMSUBQ AFNMADDQ AFNMSUBQ // 22.3: Quad-Precision Convert and Move Instructions AFCVTWQ AFCVTLQ AFCVTSQ AFCVTDQ AFCVTQW AFCVTQL AFCVTQS AFCVTQD AFCVTWUQ AFCVTLUQ AFCVTQWU AFCVTQLU AFSGNJQ AFSGNJNQ AFSGNJXQ // 22.4: Quad-Precision Floating-Point Compare Instructions AFEQQ AFLEQ AFLTQ // 22.5: Quad-Precision Floating-Point Classify Instruction AFCLASSQ // // "C" Extension for Compressed Instructions // // 26.3.1: Compressed Stack-Pointer-Based Loads and Stores ACLWSP ACFLWSP ACLDSP ACFLDSP ACSWSP ACSDSP ACFSWSP ACFSDSP // 26.3.2: Compressed Register-Based Loads and Stores ACLW ACLD ACFLW ACFLD ACSW ACSD ACFSW ACFSD // 26.4: Compressed Control Transfer Instructions ACJ ACJR ACJALR ACBEQZ ACBNEZ // 26.5.1: Compressed Integer Constant-Generation Instructions ACLI ACLUI ACADDI ACADDIW ACADDI16SP ACADDI4SPN ACSLLI ACSRLI ACSRAI ACANDI // 26.5.3: Compressed Integer Register-Register Operations ACMV ACADD ACAND ACOR ACXOR ACSUB ACADDW ACSUBW // 26.5.5: Compressed NOP Instruction ACNOP // 26.5.6: Compressed Breakpoint Instruction ACEBREAK // // "B" Extension for Bit Manipulation, Version 1.0.0 // // 28.4.1: Address Generation Instructions (Zba) AADDUW ASH1ADD ASH1ADDUW ASH2ADD ASH2ADDUW ASH3ADD ASH3ADDUW ASLLIUW // 28.4.2: Basic Bit Manipulation (Zbb) AANDN AORN AXNOR ACLZ ACLZW ACTZ ACTZW ACPOP ACPOPW AMAX AMAXU AMIN AMINU ASEXTB ASEXTH AZEXTH // 28.4.3: Bitwise Rotation (Zbb) AROL AROLW AROR ARORI ARORIW ARORW AORCB AREV8 // 28.4.4: Single-bit Instructions (Zbs) ABCLR ABCLRI ABEXT ABEXTI ABINV ABINVI ABSET ABSETI // // "V" Standard Extension for Vector Operations, Version 1.0 // // 31.6: Configuration-Setting Instructions AVSETVLI AVSETIVLI AVSETVL // 31.7.4: Vector Unit-Stride Instructions AVLE8V AVLE16V AVLE32V AVLE64V AVSE8V AVSE16V AVSE32V AVSE64V AVLMV AVSMV // 31.7.5: Vector Strided Instructions AVLSE8V AVLSE16V AVLSE32V AVLSE64V AVSSE8V AVSSE16V AVSSE32V AVSSE64V // 31.7.6: Vector Indexed Instructions AVLUXEI8V AVLUXEI16V AVLUXEI32V AVLUXEI64V AVLOXEI8V AVLOXEI16V AVLOXEI32V AVLOXEI64V AVSUXEI8V AVSUXEI16V AVSUXEI32V AVSUXEI64V AVSOXEI8V AVSOXEI16V AVSOXEI32V AVSOXEI64V // 31.7.7: Unit-stride Fault-Only-First Loads AVLE8FFV AVLE16FFV AVLE32FFV AVLE64FFV // 31.7.8. Vector Load/Store Segment Instructions // 31.7.8.1. Vector Unit-Stride Segment Loads and Stores AVLSEG2E8V AVLSEG3E8V AVLSEG4E8V AVLSEG5E8V AVLSEG6E8V AVLSEG7E8V AVLSEG8E8V AVLSEG2E16V AVLSEG3E16V AVLSEG4E16V AVLSEG5E16V AVLSEG6E16V AVLSEG7E16V AVLSEG8E16V AVLSEG2E32V AVLSEG3E32V AVLSEG4E32V AVLSEG5E32V AVLSEG6E32V AVLSEG7E32V AVLSEG8E32V AVLSEG2E64V AVLSEG3E64V AVLSEG4E64V AVLSEG5E64V AVLSEG6E64V AVLSEG7E64V AVLSEG8E64V AVSSEG2E8V AVSSEG3E8V AVSSEG4E8V AVSSEG5E8V AVSSEG6E8V AVSSEG7E8V AVSSEG8E8V AVSSEG2E16V AVSSEG3E16V AVSSEG4E16V AVSSEG5E16V AVSSEG6E16V AVSSEG7E16V AVSSEG8E16V AVSSEG2E32V AVSSEG3E32V AVSSEG4E32V AVSSEG5E32V AVSSEG6E32V AVSSEG7E32V AVSSEG8E32V AVSSEG2E64V AVSSEG3E64V AVSSEG4E64V AVSSEG5E64V AVSSEG6E64V AVSSEG7E64V AVSSEG8E64V AVLSEG2E8FFV AVLSEG3E8FFV AVLSEG4E8FFV AVLSEG5E8FFV AVLSEG6E8FFV AVLSEG7E8FFV AVLSEG8E8FFV AVLSEG2E16FFV AVLSEG3E16FFV AVLSEG4E16FFV AVLSEG5E16FFV AVLSEG6E16FFV AVLSEG7E16FFV AVLSEG8E16FFV AVLSEG2E32FFV AVLSEG3E32FFV AVLSEG4E32FFV AVLSEG5E32FFV AVLSEG6E32FFV AVLSEG7E32FFV AVLSEG8E32FFV AVLSEG2E64FFV AVLSEG3E64FFV AVLSEG4E64FFV AVLSEG5E64FFV AVLSEG6E64FFV AVLSEG7E64FFV AVLSEG8E64FFV // 31.7.8.2. Vector Strided Segment Loads and Stores AVLSSEG2E8V AVLSSEG3E8V AVLSSEG4E8V AVLSSEG5E8V AVLSSEG6E8V AVLSSEG7E8V AVLSSEG8E8V AVLSSEG2E16V AVLSSEG3E16V AVLSSEG4E16V AVLSSEG5E16V AVLSSEG6E16V AVLSSEG7E16V AVLSSEG8E16V AVLSSEG2E32V AVLSSEG3E32V AVLSSEG4E32V AVLSSEG5E32V AVLSSEG6E32V AVLSSEG7E32V AVLSSEG8E32V AVLSSEG2E64V AVLSSEG3E64V AVLSSEG4E64V AVLSSEG5E64V AVLSSEG6E64V AVLSSEG7E64V AVLSSEG8E64V AVSSSEG2E8V AVSSSEG3E8V AVSSSEG4E8V AVSSSEG5E8V AVSSSEG6E8V AVSSSEG7E8V AVSSSEG8E8V AVSSSEG2E16V AVSSSEG3E16V AVSSSEG4E16V AVSSSEG5E16V AVSSSEG6E16V AVSSSEG7E16V AVSSSEG8E16V AVSSSEG2E32V AVSSSEG3E32V AVSSSEG4E32V AVSSSEG5E32V AVSSSEG6E32V AVSSSEG7E32V AVSSSEG8E32V AVSSSEG2E64V AVSSSEG3E64V AVSSSEG4E64V AVSSSEG5E64V AVSSSEG6E64V AVSSSEG7E64V AVSSSEG8E64V // 31.7.8.3. Vector Indexed Segment Loads and Stores AVLOXSEG2EI8V AVLOXSEG3EI8V AVLOXSEG4EI8V AVLOXSEG5EI8V AVLOXSEG6EI8V AVLOXSEG7EI8V AVLOXSEG8EI8V AVLOXSEG2EI16V AVLOXSEG3EI16V AVLOXSEG4EI16V AVLOXSEG5EI16V AVLOXSEG6EI16V AVLOXSEG7EI16V AVLOXSEG8EI16V AVLOXSEG2EI32V AVLOXSEG3EI32V AVLOXSEG4EI32V AVLOXSEG5EI32V AVLOXSEG6EI32V AVLOXSEG7EI32V AVLOXSEG8EI32V AVLOXSEG2EI64V AVLOXSEG3EI64V AVLOXSEG4EI64V AVLOXSEG5EI64V AVLOXSEG6EI64V AVLOXSEG7EI64V AVLOXSEG8EI64V AVSOXSEG2EI8V AVSOXSEG3EI8V AVSOXSEG4EI8V AVSOXSEG5EI8V AVSOXSEG6EI8V AVSOXSEG7EI8V AVSOXSEG8EI8V AVSOXSEG2EI16V AVSOXSEG3EI16V AVSOXSEG4EI16V AVSOXSEG5EI16V AVSOXSEG6EI16V AVSOXSEG7EI16V AVSOXSEG8EI16V AVSOXSEG2EI32V AVSOXSEG3EI32V AVSOXSEG4EI32V AVSOXSEG5EI32V AVSOXSEG6EI32V AVSOXSEG7EI32V AVSOXSEG8EI32V AVSOXSEG2EI64V AVSOXSEG3EI64V AVSOXSEG4EI64V AVSOXSEG5EI64V AVSOXSEG6EI64V AVSOXSEG7EI64V AVSOXSEG8EI64V AVLUXSEG2EI8V AVLUXSEG3EI8V AVLUXSEG4EI8V AVLUXSEG5EI8V AVLUXSEG6EI8V AVLUXSEG7EI8V AVLUXSEG8EI8V AVLUXSEG2EI16V AVLUXSEG3EI16V AVLUXSEG4EI16V AVLUXSEG5EI16V AVLUXSEG6EI16V AVLUXSEG7EI16V AVLUXSEG8EI16V AVLUXSEG2EI32V AVLUXSEG3EI32V AVLUXSEG4EI32V AVLUXSEG5EI32V AVLUXSEG6EI32V AVLUXSEG7EI32V AVLUXSEG8EI32V AVLUXSEG2EI64V AVLUXSEG3EI64V AVLUXSEG4EI64V AVLUXSEG5EI64V AVLUXSEG6EI64V AVLUXSEG7EI64V AVLUXSEG8EI64V AVSUXSEG2EI8V AVSUXSEG3EI8V AVSUXSEG4EI8V AVSUXSEG5EI8V AVSUXSEG6EI8V AVSUXSEG7EI8V AVSUXSEG8EI8V AVSUXSEG2EI16V AVSUXSEG3EI16V AVSUXSEG4EI16V AVSUXSEG5EI16V AVSUXSEG6EI16V AVSUXSEG7EI16V AVSUXSEG8EI16V AVSUXSEG2EI32V AVSUXSEG3EI32V AVSUXSEG4EI32V AVSUXSEG5EI32V AVSUXSEG6EI32V AVSUXSEG7EI32V AVSUXSEG8EI32V AVSUXSEG2EI64V AVSUXSEG3EI64V AVSUXSEG4EI64V AVSUXSEG5EI64V AVSUXSEG6EI64V AVSUXSEG7EI64V AVSUXSEG8EI64V // 31.7.9: Vector Load/Store Whole Register Instructions AVL1RE8V AVL1RE16V AVL1RE32V AVL1RE64V AVL2RE8V AVL2RE16V AVL2RE32V AVL2RE64V AVL4RE8V AVL4RE16V AVL4RE32V AVL4RE64V AVL8RE8V AVL8RE16V AVL8RE32V AVL8RE64V AVS1RV AVS2RV AVS4RV AVS8RV // 31.11.1: Vector Single-Width Integer Add and Subtract AVADDVV AVADDVX AVADDVI AVSUBVV AVSUBVX AVRSUBVX AVRSUBVI // 31.11.2: Vector Widening Integer Add/Subtract AVWADDUVV AVWADDUVX AVWSUBUVV AVWSUBUVX AVWADDVV AVWADDVX AVWSUBVV AVWSUBVX AVWADDUWV AVWADDUWX AVWSUBUWV AVWSUBUWX AVWADDWV AVWADDWX AVWSUBWV AVWSUBWX // 31.11.3: Vector Integer Extension AVZEXTVF2 AVSEXTVF2 AVZEXTVF4 AVSEXTVF4 AVZEXTVF8 AVSEXTVF8 // 31.11.4: Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions AVADCVVM AVADCVXM AVADCVIM AVMADCVVM AVMADCVXM AVMADCVIM AVMADCVV AVMADCVX AVMADCVI AVSBCVVM AVSBCVXM AVMSBCVVM AVMSBCVXM AVMSBCVV AVMSBCVX // 31.11.5: Vector Bitwise Logical Instructions AVANDVV AVANDVX AVANDVI AVORVV AVORVX AVORVI AVXORVV AVXORVX AVXORVI // 31.11.6: Vector Single-Width Shift Instructions AVSLLVV AVSLLVX AVSLLVI AVSRLVV AVSRLVX AVSRLVI AVSRAVV AVSRAVX AVSRAVI // 31.11.7: Vector Narrowing Integer Right Shift Instructions AVNSRLWV AVNSRLWX AVNSRLWI AVNSRAWV AVNSRAWX AVNSRAWI // 31.11.8: Vector Integer Compare Instructions AVMSEQVV AVMSEQVX AVMSEQVI AVMSNEVV AVMSNEVX AVMSNEVI AVMSLTUVV AVMSLTUVX AVMSLTVV AVMSLTVX AVMSLEUVV AVMSLEUVX AVMSLEUVI AVMSLEVV AVMSLEVX AVMSLEVI AVMSGTUVX AVMSGTUVI AVMSGTVX AVMSGTVI // 31.11.9: Vector Integer Min/Max Instructions AVMINUVV AVMINUVX AVMINVV AVMINVX AVMAXUVV AVMAXUVX AVMAXVV AVMAXVX // 31.11.10: Vector Single-Width Integer Multiply Instructions AVMULVV AVMULVX AVMULHVV AVMULHVX AVMULHUVV AVMULHUVX AVMULHSUVV AVMULHSUVX // 31.11.11: Vector Integer Divide Instructions AVDIVUVV AVDIVUVX AVDIVVV AVDIVVX AVREMUVV AVREMUVX AVREMVV AVREMVX // 31.11.12: Vector Widening Integer Multiply Instructions AVWMULVV AVWMULVX AVWMULUVV AVWMULUVX AVWMULSUVV AVWMULSUVX // 31.11.13: Vector Single-Width Integer Multiply-Add Instructions AVMACCVV AVMACCVX AVNMSACVV AVNMSACVX AVMADDVV AVMADDVX AVNMSUBVV AVNMSUBVX // 31.11.14: Vector Widening Integer Multiply-Add Instructions AVWMACCUVV AVWMACCUVX AVWMACCVV AVWMACCVX AVWMACCSUVV AVWMACCSUVX AVWMACCUSVX // 31.11.15: Vector Integer Merge Instructions AVMERGEVVM AVMERGEVXM AVMERGEVIM // 31.11.16: Vector Integer Move Instructions AVMVVV AVMVVX AVMVVI // 31.12.1: Vector Single-Width Saturating Add and Subtract AVSADDUVV AVSADDUVX AVSADDUVI AVSADDVV AVSADDVX AVSADDVI AVSSUBUVV AVSSUBUVX AVSSUBVV AVSSUBVX // 31.12.2: Vector Single-Width Averaging Add and Subtract AVAADDUVV AVAADDUVX AVAADDVV AVAADDVX AVASUBUVV AVASUBUVX AVASUBVV AVASUBVX // 31.12.3: Vector Single-Width Fractional Multiply with Rounding and Saturation AVSMULVV AVSMULVX // 31.12.4: Vector Single-Width Scaling Shift Instructions AVSSRLVV AVSSRLVX AVSSRLVI AVSSRAVV AVSSRAVX AVSSRAVI // 31.12.5: Vector Narrowing Fixed-Point Clip Instructions AVNCLIPUWV AVNCLIPUWX AVNCLIPUWI AVNCLIPWV AVNCLIPWX AVNCLIPWI // 31.13.2: Vector Single-Width Floating-Point Add/Subtract Instructions AVFADDVV AVFADDVF AVFSUBVV AVFSUBVF AVFRSUBVF // 31.13.3: Vector Widening Floating-Point Add/Subtract Instructions AVFWADDVV AVFWADDVF AVFWSUBVV AVFWSUBVF AVFWADDWV AVFWADDWF AVFWSUBWV AVFWSUBWF // 31.13.4: Vector Single-Width Floating-Point Multiply/Divide Instructions AVFMULVV AVFMULVF AVFDIVVV AVFDIVVF AVFRDIVVF // 31.13.5: Vector Widening Floating-Point Multiply AVFWMULVV AVFWMULVF // 31.13.6: Vector Single-Width Floating-Point Fused Multiply-Add Instructions AVFMACCVV AVFMACCVF AVFNMACCVV AVFNMACCVF AVFMSACVV AVFMSACVF AVFNMSACVV AVFNMSACVF AVFMADDVV AVFMADDVF AVFNMADDVV AVFNMADDVF AVFMSUBVV AVFMSUBVF AVFNMSUBVV AVFNMSUBVF // 31.13.7: Vector Widening Floating-Point Fused Multiply-Add Instructions AVFWMACCVV AVFWMACCVF AVFWNMACCVV AVFWNMACCVF AVFWMSACVV AVFWMSACVF AVFWNMSACVV AVFWNMSACVF // 31.13.8: Vector Floating-Point Square-Root Instruction AVFSQRTV // 31.13.9: Vector Floating-Point Reciprocal Square-Root Estimate Instruction AVFRSQRT7V // 31.13.10: Vector Floating-Point Reciprocal Estimate Instruction AVFREC7V // 31.13.11: Vector Floating-Point MIN/MAX Instructions AVFMINVV AVFMINVF AVFMAXVV AVFMAXVF // 31.13.12: Vector Floating-Point Sign-Injection Instructions AVFSGNJVV AVFSGNJVF AVFSGNJNVV AVFSGNJNVF AVFSGNJXVV AVFSGNJXVF // 31.13.13: Vector Floating-Point Compare Instructions AVMFEQVV AVMFEQVF AVMFNEVV AVMFNEVF AVMFLTVV AVMFLTVF AVMFLEVV AVMFLEVF AVMFGTVF AVMFGEVF // 31.13.14: Vector Floating-Point Classify Instruction AVFCLASSV // 31.13.15: Vector Floating-Point Merge Instruction AVFMERGEVFM // 31.13.16: Vector Floating-Point Move Instruction AVFMVVF // 31.13.17: Single-Width Floating-Point/Integer Type-Convert Instructions AVFCVTXUFV AVFCVTXFV AVFCVTRTZXUFV AVFCVTRTZXFV AVFCVTFXUV AVFCVTFXV // 31.13.18: Widening Floating-Point/Integer Type-Convert Instructions AVFWCVTXUFV AVFWCVTXFV AVFWCVTRTZXUFV AVFWCVTRTZXFV AVFWCVTFXUV AVFWCVTFXV AVFWCVTFFV // 31.13.19: Narrowing Floating-Point/Integer Type-Convert Instructions AVFNCVTXUFW AVFNCVTXFW AVFNCVTRTZXUFW AVFNCVTRTZXFW AVFNCVTFXUW AVFNCVTFXW AVFNCVTFFW AVFNCVTRODFFW // 31.14.1: Vector Single-Width Integer Reduction Instructions AVREDSUMVS AVREDMAXUVS AVREDMAXVS AVREDMINUVS AVREDMINVS AVREDANDVS AVREDORVS AVREDXORVS // 31.14.2: Vector Widening Integer Reduction Instructions AVWREDSUMUVS AVWREDSUMVS // 31.14.3: Vector Single-Width Floating-Point Reduction Instructions AVFREDOSUMVS AVFREDUSUMVS AVFREDMAXVS AVFREDMINVS // 31.14.4: Vector Widening Floating-Point Reduction Instructions AVFWREDOSUMVS AVFWREDUSUMVS // 31.15: Vector Mask Instructions AVMANDMM AVMNANDMM AVMANDNMM AVMXORMM AVMORMM AVMNORMM AVMORNMM AVMXNORMM AVCPOPM AVFIRSTM AVMSBFM AVMSIFM AVMSOFM AVIOTAM AVIDV // 31.16.1: Integer Scalar Move Instructions AVMVXS AVMVSX // 31.16.2: Floating-Point Scalar Move Instructions AVFMVFS AVFMVSF // 31.16.3: Vector Slide Instructions AVSLIDEUPVX AVSLIDEUPVI AVSLIDEDOWNVX AVSLIDEDOWNVI AVSLIDE1UPVX AVFSLIDE1UPVF AVSLIDE1DOWNVX AVFSLIDE1DOWNVF // 31.16.4: Vector Register Gather Instructions AVRGATHERVV AVRGATHEREI16VV AVRGATHERVX AVRGATHERVI // 31.16.5: Vector Compress Instruction AVCOMPRESSVM // 31.16.6: Whole Vector Register Move AVMV1RV AVMV2RV AVMV4RV AVMV8RV // // Privileged ISA (version 20240411) // // 3.3.1: Environment Call and Breakpoint AECALL ASCALL AEBREAK ASBREAK // 3.3.2: Trap-Return Instructions AMRET ASRET ADRET // 3.3.3: Wait for Interrupt AWFI // 10.2: Supervisor Memory-Management Fence Instruction ASFENCEVMA // The escape hatch. Inserts a single 32-bit word. AWORD // Pseudo-instructions. These get translated by the assembler into other // instructions, based on their operands. ABEQZ ABGEZ ABGT ABGTU ABGTZ ABLE ABLEU ABLEZ ABLTZ ABNEZ AFABSD AFABSS AFNED AFNEGD AFNEGS AFNES AMOV AMOVB AMOVBU AMOVD AMOVF AMOVH AMOVHU AMOVW AMOVWU ANEG ANEGW ANOT ARDCYCLE ARDINSTRET ARDTIME ASEQZ ASNEZ AVFABSV AVFNEGV AVL1RV AVL2RV AVL4RV AVL8RV AVMCLRM AVMFGEVV AVMFGTVV AVMMVM AVMNOTM AVMSETM AVMSGEUVI AVMSGEUVV AVMSGEVI AVMSGEVV AVMSGTUVV AVMSGTVV AVMSLTUVI AVMSLTVI AVNCVTXXW AVNEGV AVNOTV AVWCVTUXXV AVWCVTXXV // End marker ALAST ) // opSuffix encoding to uint8 which fit into p.Scond var rmSuffixSet = map[string]uint8{ "RNE": RM_RNE, "RTZ": RM_RTZ, "RDN": RM_RDN, "RUP": RM_RUP, "RMM": RM_RMM, } const rmSuffixBit uint8 = 1 << 7 func rmSuffixEncode(s string) (uint8, error) { if s == "" { return 0, errors.New("empty suffix") } enc, ok := rmSuffixSet[s] if !ok { return 0, fmt.Errorf("invalid encoding for unknown suffix:%q", s) } return enc | rmSuffixBit, nil } func rmSuffixString(u uint8) (string, error) { if u&rmSuffixBit == 0 { return "", fmt.Errorf("invalid suffix, require round mode bit:%x", u) } u &^= rmSuffixBit for k, v := range rmSuffixSet { if v == u { return k, nil } } return "", fmt.Errorf("unknown suffix:%x", u) } const ( RM_RNE uint8 = iota // Round to Nearest, ties to Even RM_RTZ // Round towards Zero RM_RDN // Round Down RM_RUP // Round Up RM_RMM // Round to Nearest, ties to Max Magnitude ) type SpecialOperand int const ( SPOP_BEGIN SpecialOperand = obj.SpecialOperandRISCVBase SPOP_RVV_BEGIN // Vector mask policy. SPOP_MA SpecialOperand = obj.SpecialOperandRISCVBase + iota - 2 SPOP_MU // Vector tail policy. SPOP_TA SPOP_TU // Vector register group multiplier (VLMUL). SPOP_M1 SPOP_M2 SPOP_M4 SPOP_M8 SPOP_MF2 SPOP_MF4 SPOP_MF8 // Vector selected element width (VSEW). SPOP_E8 SPOP_E16 SPOP_E32 SPOP_E64 SPOP_RVV_END // CSR names. 4096 special operands are reserved for RISC-V CSR names. SPOP_CSR_BEGIN = SPOP_RVV_END SPOP_CSR_END = SPOP_CSR_BEGIN + 4096 SPOP_END = SPOP_CSR_END + 1 ) var specialOperands = map[SpecialOperand]struct { encoding uint32 name string }{ SPOP_MA: {encoding: 1, name: "MA"}, SPOP_MU: {encoding: 0, name: "MU"}, SPOP_TA: {encoding: 1, name: "TA"}, SPOP_TU: {encoding: 0, name: "TU"}, SPOP_M1: {encoding: 0, name: "M1"}, SPOP_M2: {encoding: 1, name: "M2"}, SPOP_M4: {encoding: 2, name: "M4"}, SPOP_M8: {encoding: 3, name: "M8"}, SPOP_MF8: {encoding: 5, name: "MF8"}, SPOP_MF4: {encoding: 6, name: "MF4"}, SPOP_MF2: {encoding: 7, name: "MF2"}, SPOP_E8: {encoding: 0, name: "E8"}, SPOP_E16: {encoding: 1, name: "E16"}, SPOP_E32: {encoding: 2, name: "E32"}, SPOP_E64: {encoding: 3, name: "E64"}, } func (so SpecialOperand) encode() uint32 { switch { case so >= SPOP_RVV_BEGIN && so < SPOP_RVV_END: op, ok := specialOperands[so] if ok { return op.encoding } case so >= SPOP_CSR_BEGIN && so < SPOP_CSR_END: csrNum := uint16(so - SPOP_CSR_BEGIN) if _, ok := csrs[csrNum]; ok { return uint32(csrNum) } } return 0 } // String returns the textual representation of a SpecialOperand. func (so SpecialOperand) String() string { switch { case so >= SPOP_RVV_BEGIN && so < SPOP_RVV_END: op, ok := specialOperands[so] if ok { return op.name } case so >= SPOP_CSR_BEGIN && so < SPOP_CSR_END: if csrName, ok := csrs[uint16(so-SPOP_CSR_BEGIN)]; ok { return csrName } } return "" } // All unary instructions which write to their arguments (as opposed to reading // from them) go here. The assembly parser uses this information to populate // its AST in a semantically reasonable way. // // Any instructions not listed here are assumed to either be non-unary or to read // from its argument. var unaryDst = map[obj.As]bool{ ARDCYCLE: true, ARDTIME: true, ARDINSTRET: true, } // Instruction encoding masks. const ( // BTypeImmMask is a mask including only the immediate portion of // B-type instructions. BTypeImmMask = 0xfe000f80 // CBTypeImmMask is a mask including only the immediate portion of // CB-type instructions. CBTypeImmMask = 0x1c7c // CJTypeImmMask is a mask including only the immediate portion of // CJ-type instructions. CJTypeImmMask = 0x1f7c // ITypeImmMask is a mask including only the immediate portion of // I-type instructions. ITypeImmMask = 0xfff00000 // JTypeImmMask is a mask including only the immediate portion of // J-type instructions. JTypeImmMask = 0xfffff000 // STypeImmMask is a mask including only the immediate portion of // S-type instructions. STypeImmMask = 0xfe000f80 // UTypeImmMask is a mask including only the immediate portion of // U-type instructions. UTypeImmMask = 0xfffff000 )