aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal/obj
diff options
context:
space:
mode:
authorJoel Sing <joel@sing.id.au>2024-08-15 02:48:09 +1000
committerJoel Sing <joel@sing.id.au>2024-11-21 22:31:25 +0000
commitdc8ceb63a8413664c589059fca5806ff74486884 (patch)
tree0a86d53999344cbef1ddb4d6b35f21c1798f36bb /src/cmd/internal/obj
parent83e6781cb75f9470430fd40c9751e846b998a49e (diff)
downloadgo-dc8ceb63a8413664c589059fca5806ff74486884.tar.xz
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 <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Meng Zhuo <mengzhuo1203@gmail.com> Reviewed-by: Mark Ryan <markdryan@rivosinc.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Diffstat (limited to 'src/cmd/internal/obj')
-rw-r--r--src/cmd/internal/obj/riscv/obj.go491
1 files changed, 234 insertions, 257 deletions
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 {