blob: 60174a0b3a245fc98b1a86e3e112cc9003bb743f [file] [log] [blame]
// 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
// 12.3: Integer Conditional Operations (Zicond)
ACZEROEQZ
ACZERONEZ
// 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
ACLDSP
ACFLDSP
ACSWSP
ACSDSP
ACFSDSP
// 26.3.2: Compressed Register-Based Loads and Stores
ACLW
ACLD
ACFLD
ACSW
ACSD
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
)