From: Joel Sing Date: Wed, 14 Aug 2024 16:48:09 +0000 (+1000) Subject: cmd/internal/obj/riscv: rework instruction encoding information X-Git-Tag: go1.24rc1~129 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=dc8ceb63a8413664c589059fca5806ff74486884;p=gostls13.git cmd/internal/obj/riscv: rework instruction encoding information Currently, instruction encoding is a slice of encoding types, which is indexed by a masked version of the riscv64 opcode. Additional information about some instructions (for example, if an instruction has a ternary form and if there is an immediate form for an instruction) is manually specified in other parts of the assembler code. Rework the instruction encoding information so that we use a table driven form, providing additional data for each instruction where relevant. This means that we can simplify other parts of the code by simply looking up the instruction data and reusing minimal logic. Change-Id: I7b3b6c61a4868647edf28bd7dbae2150e043ae00 Cq-Include-Trybots: luci.golang.try:gotip-linux-riscv64 Reviewed-on: https://go-review.googlesource.com/c/go/+/622535 LUCI-TryBot-Result: Go LUCI Reviewed-by: Cherry Mui Reviewed-by: Meng Zhuo Reviewed-by: Mark Ryan Reviewed-by: Dmitri Shuralyov --- diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go index a78c1c63a4..5f01c43e7b 100644 --- a/src/cmd/internal/obj/riscv/obj.go +++ b/src/cmd/internal/obj/riscv/obj.go @@ -53,18 +53,14 @@ func jalToSym(ctxt *obj.Link, p *obj.Prog, lr int16) { // progedit is called individually for each *obj.Prog. It normalizes instruction // formats and eliminates as many pseudo-instructions as possible. func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { + insData, err := instructionDataForAs(p.As) + if err != nil { + panic(fmt.Sprintf("failed to lookup instruction data for %v: %v", p.As, err)) + } // Expand binary instructions to ternary ones. if p.Reg == obj.REG_NONE { - switch p.As { - case AADDI, ASLTI, ASLTIU, AANDI, AORI, AXORI, ASLLI, ASRLI, ASRAI, - AADDIW, ASLLIW, ASRLIW, ASRAIW, AADDW, ASUBW, ASLLW, ASRLW, ASRAW, - AADD, AAND, AOR, AXOR, ASLL, ASRL, ASUB, ASRA, - AMUL, AMULH, AMULHU, AMULHSU, AMULW, ADIV, ADIVU, ADIVW, ADIVUW, - AREM, AREMU, AREMW, AREMUW, - AADDUW, ASH1ADD, ASH1ADDUW, ASH2ADD, ASH2ADDUW, ASH3ADD, ASH3ADDUW, ASLLIUW, - AANDN, AORN, AXNOR, AMAX, AMAXU, AMIN, AMINU, AROL, AROLW, AROR, ARORW, ARORI, ARORIW, - ABCLR, ABCLRI, ABEXT, ABEXTI, ABINV, ABINVI, ABSET, ABSETI: + if insData.ternary { p.Reg = p.To.Reg } } @@ -73,48 +69,14 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { // form of the instruction. if p.From.Type == obj.TYPE_CONST { switch p.As { - case AADD: - p.As = AADDI case ASUB: p.As, p.From.Offset = AADDI, -p.From.Offset - case ASLT: - p.As = ASLTI - case ASLTU: - p.As = ASLTIU - case AAND: - p.As = AANDI - case AOR: - p.As = AORI - case AXOR: - p.As = AXORI - case ASLL: - p.As = ASLLI - case ASRL: - p.As = ASRLI - case ASRA: - p.As = ASRAI - case AADDW: - p.As = AADDIW case ASUBW: p.As, p.From.Offset = AADDIW, -p.From.Offset - case ASLLW: - p.As = ASLLIW - case ASRLW: - p.As = ASRLIW - case ASRAW: - p.As = ASRAIW - case AROR: - p.As = ARORI - case ARORW: - p.As = ARORIW - case ABCLR: - p.As = ABCLRI - case ABEXT: - p.As = ABEXTI - case ABINV: - p.As = ABINVI - case ABSET: - p.As = ABSETI + default: + if insData.immForm != obj.AXXX { + p.As = insData.immForm + } } } @@ -1567,285 +1529,300 @@ var ( badEncoding = encoding{encode: func(*instruction) uint32 { return 0 }, validate: func(*obj.Link, *instruction) {}, length: 0} ) -// encodings contains the encodings for RISC-V instructions. -// Instructions are masked with obj.AMask to keep indices small. -var encodings = [ALAST & obj.AMask]encoding{ +// instructionData specifies details relating to a RISC-V instruction. +type instructionData struct { + enc encoding + immForm obj.As // immediate form of this instruction + ternary bool +} +// instructions contains details of RISC-V instructions, including +// their encoding type. Entries are masked with obj.AMask to keep +// indices small. +var instructions = [ALAST & obj.AMask]instructionData{ // Unprivileged ISA // 2.4: Integer Computational Instructions - AADDI & obj.AMask: iIIEncoding, - ASLTI & obj.AMask: iIIEncoding, - ASLTIU & obj.AMask: iIIEncoding, - AANDI & obj.AMask: iIIEncoding, - AORI & obj.AMask: iIIEncoding, - AXORI & obj.AMask: iIIEncoding, - ASLLI & obj.AMask: iIIEncoding, - ASRLI & obj.AMask: iIIEncoding, - ASRAI & obj.AMask: iIIEncoding, - ALUI & obj.AMask: uEncoding, - AAUIPC & obj.AMask: uEncoding, - AADD & obj.AMask: rIIIEncoding, - ASLT & obj.AMask: rIIIEncoding, - ASLTU & obj.AMask: rIIIEncoding, - AAND & obj.AMask: rIIIEncoding, - AOR & obj.AMask: rIIIEncoding, - AXOR & obj.AMask: rIIIEncoding, - ASLL & obj.AMask: rIIIEncoding, - ASRL & obj.AMask: rIIIEncoding, - ASUB & obj.AMask: rIIIEncoding, - ASRA & obj.AMask: rIIIEncoding, + AADDI & obj.AMask: {enc: iIIEncoding, ternary: true}, + ASLTI & obj.AMask: {enc: iIIEncoding, ternary: true}, + ASLTIU & obj.AMask: {enc: iIIEncoding, ternary: true}, + AANDI & obj.AMask: {enc: iIIEncoding, ternary: true}, + AORI & obj.AMask: {enc: iIIEncoding, ternary: true}, + AXORI & obj.AMask: {enc: iIIEncoding, ternary: true}, + ASLLI & obj.AMask: {enc: iIIEncoding, ternary: true}, + ASRLI & obj.AMask: {enc: iIIEncoding, ternary: true}, + ASRAI & obj.AMask: {enc: iIIEncoding, ternary: true}, + ALUI & obj.AMask: {enc: uEncoding}, + AAUIPC & obj.AMask: {enc: uEncoding}, + AADD & obj.AMask: {enc: rIIIEncoding, immForm: AADDI, ternary: true}, + ASLT & obj.AMask: {enc: rIIIEncoding, immForm: ASLTI, ternary: true}, + ASLTU & obj.AMask: {enc: rIIIEncoding, immForm: ASLTIU, ternary: true}, + AAND & obj.AMask: {enc: rIIIEncoding, immForm: AANDI, ternary: true}, + AOR & obj.AMask: {enc: rIIIEncoding, immForm: AORI, ternary: true}, + AXOR & obj.AMask: {enc: rIIIEncoding, immForm: AXORI, ternary: true}, + ASLL & obj.AMask: {enc: rIIIEncoding, immForm: ASLLI, ternary: true}, + ASRL & obj.AMask: {enc: rIIIEncoding, immForm: ASRLI, ternary: true}, + ASUB & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ASRA & obj.AMask: {enc: rIIIEncoding, immForm: ASRAI, ternary: true}, // 2.5: Control Transfer Instructions - AJAL & obj.AMask: jEncoding, - AJALR & obj.AMask: iIIEncoding, - ABEQ & obj.AMask: bEncoding, - ABNE & obj.AMask: bEncoding, - ABLT & obj.AMask: bEncoding, - ABLTU & obj.AMask: bEncoding, - ABGE & obj.AMask: bEncoding, - ABGEU & obj.AMask: bEncoding, + AJAL & obj.AMask: {enc: jEncoding}, + AJALR & obj.AMask: {enc: iIIEncoding}, + ABEQ & obj.AMask: {enc: bEncoding}, + ABNE & obj.AMask: {enc: bEncoding}, + ABLT & obj.AMask: {enc: bEncoding}, + ABLTU & obj.AMask: {enc: bEncoding}, + ABGE & obj.AMask: {enc: bEncoding}, + ABGEU & obj.AMask: {enc: bEncoding}, // 2.6: Load and Store Instructions - ALW & obj.AMask: iIIEncoding, - ALWU & obj.AMask: iIIEncoding, - ALH & obj.AMask: iIIEncoding, - ALHU & obj.AMask: iIIEncoding, - ALB & obj.AMask: iIIEncoding, - ALBU & obj.AMask: iIIEncoding, - ASW & obj.AMask: sIEncoding, - ASH & obj.AMask: sIEncoding, - ASB & obj.AMask: sIEncoding, + ALW & obj.AMask: {enc: iIIEncoding}, + ALWU & obj.AMask: {enc: iIIEncoding}, + ALH & obj.AMask: {enc: iIIEncoding}, + ALHU & obj.AMask: {enc: iIIEncoding}, + ALB & obj.AMask: {enc: iIIEncoding}, + ALBU & obj.AMask: {enc: iIIEncoding}, + ASW & obj.AMask: {enc: sIEncoding}, + ASH & obj.AMask: {enc: sIEncoding}, + ASB & obj.AMask: {enc: sIEncoding}, // 2.7: Memory Ordering - AFENCE & obj.AMask: iIIEncoding, + AFENCE & obj.AMask: {enc: iIIEncoding}, // 5.2: Integer Computational Instructions (RV64I) - AADDIW & obj.AMask: iIIEncoding, - ASLLIW & obj.AMask: iIIEncoding, - ASRLIW & obj.AMask: iIIEncoding, - ASRAIW & obj.AMask: iIIEncoding, - AADDW & obj.AMask: rIIIEncoding, - ASLLW & obj.AMask: rIIIEncoding, - ASRLW & obj.AMask: rIIIEncoding, - ASUBW & obj.AMask: rIIIEncoding, - ASRAW & obj.AMask: rIIIEncoding, + AADDIW & obj.AMask: {enc: iIIEncoding, ternary: true}, + ASLLIW & obj.AMask: {enc: iIIEncoding, ternary: true}, + ASRLIW & obj.AMask: {enc: iIIEncoding, ternary: true}, + ASRAIW & obj.AMask: {enc: iIIEncoding, ternary: true}, + AADDW & obj.AMask: {enc: rIIIEncoding, immForm: AADDIW, ternary: true}, + ASLLW & obj.AMask: {enc: rIIIEncoding, immForm: ASLLIW, ternary: true}, + ASRLW & obj.AMask: {enc: rIIIEncoding, immForm: ASRLIW, ternary: true}, + ASUBW & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ASRAW & obj.AMask: {enc: rIIIEncoding, immForm: ASRAIW, ternary: true}, // 5.3: Load and Store Instructions (RV64I) - ALD & obj.AMask: iIIEncoding, - ASD & obj.AMask: sIEncoding, + ALD & obj.AMask: {enc: iIIEncoding}, + ASD & obj.AMask: {enc: sIEncoding}, // 7.1: CSR Instructions - ACSRRS & obj.AMask: iIIEncoding, + ACSRRS & obj.AMask: {enc: iIIEncoding}, // 7.1: Multiplication Operations - AMUL & obj.AMask: rIIIEncoding, - AMULH & obj.AMask: rIIIEncoding, - AMULHU & obj.AMask: rIIIEncoding, - AMULHSU & obj.AMask: rIIIEncoding, - AMULW & obj.AMask: rIIIEncoding, - ADIV & obj.AMask: rIIIEncoding, - ADIVU & obj.AMask: rIIIEncoding, - AREM & obj.AMask: rIIIEncoding, - AREMU & obj.AMask: rIIIEncoding, - ADIVW & obj.AMask: rIIIEncoding, - ADIVUW & obj.AMask: rIIIEncoding, - AREMW & obj.AMask: rIIIEncoding, - AREMUW & obj.AMask: rIIIEncoding, + AMUL & obj.AMask: {enc: rIIIEncoding, ternary: true}, + AMULH & obj.AMask: {enc: rIIIEncoding, ternary: true}, + AMULHU & obj.AMask: {enc: rIIIEncoding, ternary: true}, + AMULHSU & obj.AMask: {enc: rIIIEncoding, ternary: true}, + AMULW & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ADIV & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ADIVU & obj.AMask: {enc: rIIIEncoding, ternary: true}, + AREM & obj.AMask: {enc: rIIIEncoding, ternary: true}, + AREMU & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ADIVW & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ADIVUW & obj.AMask: {enc: rIIIEncoding, ternary: true}, + AREMW & obj.AMask: {enc: rIIIEncoding, ternary: true}, + AREMUW & obj.AMask: {enc: rIIIEncoding, ternary: true}, // 8.2: Load-Reserved/Store-Conditional - ALRW & obj.AMask: rIIIEncoding, - ALRD & obj.AMask: rIIIEncoding, - ASCW & obj.AMask: rIIIEncoding, - ASCD & obj.AMask: rIIIEncoding, + ALRW & obj.AMask: {enc: rIIIEncoding}, + ALRD & obj.AMask: {enc: rIIIEncoding}, + ASCW & obj.AMask: {enc: rIIIEncoding}, + ASCD & obj.AMask: {enc: rIIIEncoding}, // 8.3: Atomic Memory Operations - AAMOSWAPW & obj.AMask: rIIIEncoding, - AAMOSWAPD & obj.AMask: rIIIEncoding, - AAMOADDW & obj.AMask: rIIIEncoding, - AAMOADDD & obj.AMask: rIIIEncoding, - AAMOANDW & obj.AMask: rIIIEncoding, - AAMOANDD & obj.AMask: rIIIEncoding, - AAMOORW & obj.AMask: rIIIEncoding, - AAMOORD & obj.AMask: rIIIEncoding, - AAMOXORW & obj.AMask: rIIIEncoding, - AAMOXORD & obj.AMask: rIIIEncoding, - AAMOMAXW & obj.AMask: rIIIEncoding, - AAMOMAXD & obj.AMask: rIIIEncoding, - AAMOMAXUW & obj.AMask: rIIIEncoding, - AAMOMAXUD & obj.AMask: rIIIEncoding, - AAMOMINW & obj.AMask: rIIIEncoding, - AAMOMIND & obj.AMask: rIIIEncoding, - AAMOMINUW & obj.AMask: rIIIEncoding, - AAMOMINUD & obj.AMask: rIIIEncoding, + AAMOSWAPW & obj.AMask: {enc: rIIIEncoding}, + AAMOSWAPD & obj.AMask: {enc: rIIIEncoding}, + AAMOADDW & obj.AMask: {enc: rIIIEncoding}, + AAMOADDD & obj.AMask: {enc: rIIIEncoding}, + AAMOANDW & obj.AMask: {enc: rIIIEncoding}, + AAMOANDD & obj.AMask: {enc: rIIIEncoding}, + AAMOORW & obj.AMask: {enc: rIIIEncoding}, + AAMOORD & obj.AMask: {enc: rIIIEncoding}, + AAMOXORW & obj.AMask: {enc: rIIIEncoding}, + AAMOXORD & obj.AMask: {enc: rIIIEncoding}, + AAMOMAXW & obj.AMask: {enc: rIIIEncoding}, + AAMOMAXD & obj.AMask: {enc: rIIIEncoding}, + AAMOMAXUW & obj.AMask: {enc: rIIIEncoding}, + AAMOMAXUD & obj.AMask: {enc: rIIIEncoding}, + AAMOMINW & obj.AMask: {enc: rIIIEncoding}, + AAMOMIND & obj.AMask: {enc: rIIIEncoding}, + AAMOMINUW & obj.AMask: {enc: rIIIEncoding}, + AAMOMINUD & obj.AMask: {enc: rIIIEncoding}, // 11.5: Single-Precision Load and Store Instructions - AFLW & obj.AMask: iFEncoding, - AFSW & obj.AMask: sFEncoding, + AFLW & obj.AMask: {enc: iFEncoding}, + AFSW & obj.AMask: {enc: sFEncoding}, // 11.6: Single-Precision Floating-Point Computational Instructions - AFADDS & obj.AMask: rFFFEncoding, - AFSUBS & obj.AMask: rFFFEncoding, - AFMULS & obj.AMask: rFFFEncoding, - AFDIVS & obj.AMask: rFFFEncoding, - AFMINS & obj.AMask: rFFFEncoding, - AFMAXS & obj.AMask: rFFFEncoding, - AFSQRTS & obj.AMask: rFFFEncoding, - AFMADDS & obj.AMask: rFFFFEncoding, - AFMSUBS & obj.AMask: rFFFFEncoding, - AFNMSUBS & obj.AMask: rFFFFEncoding, - AFNMADDS & obj.AMask: rFFFFEncoding, + AFADDS & obj.AMask: {enc: rFFFEncoding}, + AFSUBS & obj.AMask: {enc: rFFFEncoding}, + AFMULS & obj.AMask: {enc: rFFFEncoding}, + AFDIVS & obj.AMask: {enc: rFFFEncoding}, + AFMINS & obj.AMask: {enc: rFFFEncoding}, + AFMAXS & obj.AMask: {enc: rFFFEncoding}, + AFSQRTS & obj.AMask: {enc: rFFFEncoding}, + AFMADDS & obj.AMask: {enc: rFFFFEncoding}, + AFMSUBS & obj.AMask: {enc: rFFFFEncoding}, + AFNMSUBS & obj.AMask: {enc: rFFFFEncoding}, + AFNMADDS & obj.AMask: {enc: rFFFFEncoding}, // 11.7: Single-Precision Floating-Point Conversion and Move Instructions - AFCVTWS & obj.AMask: rFIEncoding, - AFCVTLS & obj.AMask: rFIEncoding, - AFCVTSW & obj.AMask: rIFEncoding, - AFCVTSL & obj.AMask: rIFEncoding, - AFCVTWUS & obj.AMask: rFIEncoding, - AFCVTLUS & obj.AMask: rFIEncoding, - AFCVTSWU & obj.AMask: rIFEncoding, - AFCVTSLU & obj.AMask: rIFEncoding, - AFSGNJS & obj.AMask: rFFFEncoding, - AFSGNJNS & obj.AMask: rFFFEncoding, - AFSGNJXS & obj.AMask: rFFFEncoding, - AFMVXW & obj.AMask: rFIEncoding, - AFMVWX & obj.AMask: rIFEncoding, + AFCVTWS & obj.AMask: {enc: rFIEncoding}, + AFCVTLS & obj.AMask: {enc: rFIEncoding}, + AFCVTSW & obj.AMask: {enc: rIFEncoding}, + AFCVTSL & obj.AMask: {enc: rIFEncoding}, + AFCVTWUS & obj.AMask: {enc: rFIEncoding}, + AFCVTLUS & obj.AMask: {enc: rFIEncoding}, + AFCVTSWU & obj.AMask: {enc: rIFEncoding}, + AFCVTSLU & obj.AMask: {enc: rIFEncoding}, + AFSGNJS & obj.AMask: {enc: rFFFEncoding}, + AFSGNJNS & obj.AMask: {enc: rFFFEncoding}, + AFSGNJXS & obj.AMask: {enc: rFFFEncoding}, + AFMVXW & obj.AMask: {enc: rFIEncoding}, + AFMVWX & obj.AMask: {enc: rIFEncoding}, // 11.8: Single-Precision Floating-Point Compare Instructions - AFEQS & obj.AMask: rFFIEncoding, - AFLTS & obj.AMask: rFFIEncoding, - AFLES & obj.AMask: rFFIEncoding, + AFEQS & obj.AMask: {enc: rFFIEncoding}, + AFLTS & obj.AMask: {enc: rFFIEncoding}, + AFLES & obj.AMask: {enc: rFFIEncoding}, // 11.9: Single-Precision Floating-Point Classify Instruction - AFCLASSS & obj.AMask: rFIEncoding, + AFCLASSS & obj.AMask: {enc: rFIEncoding}, // 12.3: Double-Precision Load and Store Instructions - AFLD & obj.AMask: iFEncoding, - AFSD & obj.AMask: sFEncoding, + AFLD & obj.AMask: {enc: iFEncoding}, + AFSD & obj.AMask: {enc: sFEncoding}, // 12.4: Double-Precision Floating-Point Computational Instructions - AFADDD & obj.AMask: rFFFEncoding, - AFSUBD & obj.AMask: rFFFEncoding, - AFMULD & obj.AMask: rFFFEncoding, - AFDIVD & obj.AMask: rFFFEncoding, - AFMIND & obj.AMask: rFFFEncoding, - AFMAXD & obj.AMask: rFFFEncoding, - AFSQRTD & obj.AMask: rFFFEncoding, - AFMADDD & obj.AMask: rFFFFEncoding, - AFMSUBD & obj.AMask: rFFFFEncoding, - AFNMSUBD & obj.AMask: rFFFFEncoding, - AFNMADDD & obj.AMask: rFFFFEncoding, + AFADDD & obj.AMask: {enc: rFFFEncoding}, + AFSUBD & obj.AMask: {enc: rFFFEncoding}, + AFMULD & obj.AMask: {enc: rFFFEncoding}, + AFDIVD & obj.AMask: {enc: rFFFEncoding}, + AFMIND & obj.AMask: {enc: rFFFEncoding}, + AFMAXD & obj.AMask: {enc: rFFFEncoding}, + AFSQRTD & obj.AMask: {enc: rFFFEncoding}, + AFMADDD & obj.AMask: {enc: rFFFFEncoding}, + AFMSUBD & obj.AMask: {enc: rFFFFEncoding}, + AFNMSUBD & obj.AMask: {enc: rFFFFEncoding}, + AFNMADDD & obj.AMask: {enc: rFFFFEncoding}, // 12.5: Double-Precision Floating-Point Conversion and Move Instructions - AFCVTWD & obj.AMask: rFIEncoding, - AFCVTLD & obj.AMask: rFIEncoding, - AFCVTDW & obj.AMask: rIFEncoding, - AFCVTDL & obj.AMask: rIFEncoding, - AFCVTWUD & obj.AMask: rFIEncoding, - AFCVTLUD & obj.AMask: rFIEncoding, - AFCVTDWU & obj.AMask: rIFEncoding, - AFCVTDLU & obj.AMask: rIFEncoding, - AFCVTSD & obj.AMask: rFFEncoding, - AFCVTDS & obj.AMask: rFFEncoding, - AFSGNJD & obj.AMask: rFFFEncoding, - AFSGNJND & obj.AMask: rFFFEncoding, - AFSGNJXD & obj.AMask: rFFFEncoding, - AFMVXD & obj.AMask: rFIEncoding, - AFMVDX & obj.AMask: rIFEncoding, + AFCVTWD & obj.AMask: {enc: rFIEncoding}, + AFCVTLD & obj.AMask: {enc: rFIEncoding}, + AFCVTDW & obj.AMask: {enc: rIFEncoding}, + AFCVTDL & obj.AMask: {enc: rIFEncoding}, + AFCVTWUD & obj.AMask: {enc: rFIEncoding}, + AFCVTLUD & obj.AMask: {enc: rFIEncoding}, + AFCVTDWU & obj.AMask: {enc: rIFEncoding}, + AFCVTDLU & obj.AMask: {enc: rIFEncoding}, + AFCVTSD & obj.AMask: {enc: rFFEncoding}, + AFCVTDS & obj.AMask: {enc: rFFEncoding}, + AFSGNJD & obj.AMask: {enc: rFFFEncoding}, + AFSGNJND & obj.AMask: {enc: rFFFEncoding}, + AFSGNJXD & obj.AMask: {enc: rFFFEncoding}, + AFMVXD & obj.AMask: {enc: rFIEncoding}, + AFMVDX & obj.AMask: {enc: rIFEncoding}, // 12.6: Double-Precision Floating-Point Compare Instructions - AFEQD & obj.AMask: rFFIEncoding, - AFLTD & obj.AMask: rFFIEncoding, - AFLED & obj.AMask: rFFIEncoding, + AFEQD & obj.AMask: {enc: rFFIEncoding}, + AFLTD & obj.AMask: {enc: rFFIEncoding}, + AFLED & obj.AMask: {enc: rFFIEncoding}, // 12.7: Double-Precision Floating-Point Classify Instruction - AFCLASSD & obj.AMask: rFIEncoding, + AFCLASSD & obj.AMask: {enc: rFIEncoding}, // Privileged ISA // 3.2.1: Environment Call and Breakpoint - AECALL & obj.AMask: iIIEncoding, - AEBREAK & obj.AMask: iIIEncoding, + AECALL & obj.AMask: {enc: iIIEncoding}, + AEBREAK & obj.AMask: {enc: iIIEncoding}, // // RISC-V Bit-Manipulation ISA-extensions (1.0) // // 1.1: Address Generation Instructions (Zba) - AADDUW & obj.AMask: rIIIEncoding, - ASH1ADD & obj.AMask: rIIIEncoding, - ASH1ADDUW & obj.AMask: rIIIEncoding, - ASH2ADD & obj.AMask: rIIIEncoding, - ASH2ADDUW & obj.AMask: rIIIEncoding, - ASH3ADD & obj.AMask: rIIIEncoding, - ASH3ADDUW & obj.AMask: rIIIEncoding, - ASLLIUW & obj.AMask: iIIEncoding, + AADDUW & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ASH1ADD & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ASH1ADDUW & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ASH2ADD & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ASH2ADDUW & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ASH3ADD & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ASH3ADDUW & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ASLLIUW & obj.AMask: {enc: iIIEncoding, ternary: true}, // 1.2: Basic Bit Manipulation (Zbb) - AANDN & obj.AMask: rIIIEncoding, - ACLZ & obj.AMask: rIIEncoding, - ACLZW & obj.AMask: rIIEncoding, - ACPOP & obj.AMask: rIIEncoding, - ACPOPW & obj.AMask: rIIEncoding, - ACTZ & obj.AMask: rIIEncoding, - ACTZW & obj.AMask: rIIEncoding, - AMAX & obj.AMask: rIIIEncoding, - AMAXU & obj.AMask: rIIIEncoding, - AMIN & obj.AMask: rIIIEncoding, - AMINU & obj.AMask: rIIIEncoding, - AORN & obj.AMask: rIIIEncoding, - ASEXTB & obj.AMask: rIIEncoding, - ASEXTH & obj.AMask: rIIEncoding, - AXNOR & obj.AMask: rIIIEncoding, - AZEXTH & obj.AMask: rIIEncoding, + AANDN & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ACLZ & obj.AMask: {enc: rIIEncoding}, + ACLZW & obj.AMask: {enc: rIIEncoding}, + ACPOP & obj.AMask: {enc: rIIEncoding}, + ACPOPW & obj.AMask: {enc: rIIEncoding}, + ACTZ & obj.AMask: {enc: rIIEncoding}, + ACTZW & obj.AMask: {enc: rIIEncoding}, + AMAX & obj.AMask: {enc: rIIIEncoding, ternary: true}, + AMAXU & obj.AMask: {enc: rIIIEncoding, ternary: true}, + AMIN & obj.AMask: {enc: rIIIEncoding, ternary: true}, + AMINU & obj.AMask: {enc: rIIIEncoding, ternary: true}, + AORN & obj.AMask: {enc: rIIIEncoding, ternary: true}, + ASEXTB & obj.AMask: {enc: rIIEncoding}, + ASEXTH & obj.AMask: {enc: rIIEncoding}, + AXNOR & obj.AMask: {enc: rIIIEncoding, ternary: true}, + AZEXTH & obj.AMask: {enc: rIIEncoding}, // 1.3: Bitwise Rotation (Zbb) - AROL & obj.AMask: rIIIEncoding, - AROLW & obj.AMask: rIIIEncoding, - AROR & obj.AMask: rIIIEncoding, - ARORI & obj.AMask: iIIEncoding, - ARORIW & obj.AMask: iIIEncoding, - ARORW & obj.AMask: rIIIEncoding, - AORCB & obj.AMask: iIIEncoding, - AREV8 & obj.AMask: iIIEncoding, + AROL & obj.AMask: {enc: rIIIEncoding, ternary: true}, + AROLW & obj.AMask: {enc: rIIIEncoding, ternary: true}, + AROR & obj.AMask: {enc: rIIIEncoding, immForm: ARORI, ternary: true}, + ARORI & obj.AMask: {enc: iIIEncoding, ternary: true}, + ARORIW & obj.AMask: {enc: iIIEncoding, ternary: true}, + ARORW & obj.AMask: {enc: rIIIEncoding, immForm: ARORIW, ternary: true}, + AORCB & obj.AMask: {enc: iIIEncoding}, + AREV8 & obj.AMask: {enc: iIIEncoding}, // 1.5: Single-bit Instructions (Zbs) - ABCLR & obj.AMask: rIIIEncoding, - ABCLRI & obj.AMask: iIIEncoding, - ABEXT & obj.AMask: rIIIEncoding, - ABEXTI & obj.AMask: iIIEncoding, - ABINV & obj.AMask: rIIIEncoding, - ABINVI & obj.AMask: iIIEncoding, - ABSET & obj.AMask: rIIIEncoding, - ABSETI & obj.AMask: iIIEncoding, + ABCLR & obj.AMask: {enc: rIIIEncoding, immForm: ABCLRI, ternary: true}, + ABCLRI & obj.AMask: {enc: iIIEncoding, ternary: true}, + ABEXT & obj.AMask: {enc: rIIIEncoding, immForm: ABEXTI, ternary: true}, + ABEXTI & obj.AMask: {enc: iIIEncoding, ternary: true}, + ABINV & obj.AMask: {enc: rIIIEncoding, immForm: ABINVI, ternary: true}, + ABINVI & obj.AMask: {enc: iIIEncoding, ternary: true}, + ABSET & obj.AMask: {enc: rIIIEncoding, immForm: ABSETI, ternary: true}, + ABSETI & obj.AMask: {enc: iIIEncoding, ternary: true}, // Escape hatch - AWORD & obj.AMask: rawEncoding, + AWORD & obj.AMask: {enc: rawEncoding}, // Pseudo-operations - obj.AFUNCDATA: pseudoOpEncoding, - obj.APCDATA: pseudoOpEncoding, - obj.ATEXT: pseudoOpEncoding, - obj.ANOP: pseudoOpEncoding, - obj.ADUFFZERO: pseudoOpEncoding, - obj.ADUFFCOPY: pseudoOpEncoding, - obj.APCALIGN: pseudoOpEncoding, + obj.AFUNCDATA: {enc: pseudoOpEncoding}, + obj.APCDATA: {enc: pseudoOpEncoding}, + obj.ATEXT: {enc: pseudoOpEncoding}, + obj.ANOP: {enc: pseudoOpEncoding}, + obj.ADUFFZERO: {enc: pseudoOpEncoding}, + obj.ADUFFCOPY: {enc: pseudoOpEncoding}, + obj.APCALIGN: {enc: pseudoOpEncoding}, } -// encodingForAs returns the encoding for an obj.As. -func encodingForAs(as obj.As) (encoding, error) { +// instructionDataForAs returns the instruction data for an obj.As. +func instructionDataForAs(as obj.As) (*instructionData, error) { if base := as &^ obj.AMask; base != obj.ABaseRISCV && base != 0 { - return badEncoding, fmt.Errorf("encodingForAs: not a RISC-V instruction %s", as) + return nil, fmt.Errorf("%v is not a RISC-V instruction", as) } asi := as & obj.AMask - if int(asi) >= len(encodings) { - return badEncoding, fmt.Errorf("encodingForAs: bad RISC-V instruction %s", as) + if int(asi) >= len(instructions) { + return nil, fmt.Errorf("bad RISC-V instruction %v", as) + } + return &instructions[asi], nil +} + +// encodingForAs returns the encoding for an obj.As. +func encodingForAs(as obj.As) (*encoding, error) { + insData, err := instructionDataForAs(as) + if err != nil { + return &badEncoding, err } - enc := encodings[asi] - if enc.validate == nil { - return badEncoding, fmt.Errorf("encodingForAs: no encoding for instruction %s", as) + if insData.enc.validate == nil { + return &badEncoding, fmt.Errorf("no encoding for instruction %s", as) } - return enc, nil + return &insData.enc, nil } type instruction struct {