riscv64: add disassembly support and tests for zacas Add disassembly support and tests for Zacas extension on RISCV64. Change-Id: Iea42ead99f5eba68f88c7a64e58cebba43d89a85 GitHub-Last-Rev: d6398d2ffb46f506af06d68b73126346f3795bcc GitHub-Pull-Request: golang/arch#17 Reviewed-on: https://go-review.googlesource.com/c/arch/+/735520 Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Mark Ryan <markdryan@meta.com> Reviewed-by: Meng Zhuo <mengzhuo1203@gmail.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/riscv64/riscv64asm/decode.go b/riscv64/riscv64asm/decode.go index 390edfa..c0223df 100644 --- a/riscv64/riscv64asm/decode.go +++ b/riscv64/riscv64asm/decode.go
@@ -61,6 +61,10 @@ continue } + if !validEncoding(f.op, x) { + continue Search + } + // Decode args. var args Args k := 0 @@ -594,3 +598,17 @@ } return newargs } + +func validEncoding(op Op, x uint32) bool { + switch op { + // The AMOCAS_Q requires the first register in the pair to be even numbered; + // encodings with odd numbered registers specified in rs2 and rd are reserved. + case AMOCAS_Q, AMOCAS_Q_AQ, AMOCAS_Q_AQRL, AMOCAS_Q_RL: + rd := (x >> 7) & 0x1f + rs2 := (x >> 20) & 0x1f + if (rd&1) != 0 || (rs2&1) != 0 { + return false + } + } + return true +}
diff --git a/riscv64/riscv64asm/objdump_test.go b/riscv64/riscv64asm/objdump_test.go index ddaa28c..f47fbe7 100644 --- a/riscv64/riscv64asm/objdump_test.go +++ b/riscv64/riscv64asm/objdump_test.go
@@ -88,6 +88,12 @@ return true } + // Zacas instructions are supported by objdump 2.43 and later. + // Note: amocas.q requires rd and rs2 to be even-numbered registers. + if strings.HasPrefix(dec.text, ".insn") && isZacasOp(inst.Op) && !objdumpVersionAtLeast(version, "2.43") { + return true + } + return false } @@ -128,3 +134,13 @@ } return false } + +func isZacasOp(op Op) bool { + switch op { + case AMOCAS_D, AMOCAS_D_AQ, AMOCAS_D_AQRL, AMOCAS_D_RL, + AMOCAS_Q, AMOCAS_Q_AQ, AMOCAS_Q_AQRL, AMOCAS_Q_RL, + AMOCAS_W, AMOCAS_W_AQ, AMOCAS_W_AQRL, AMOCAS_W_RL: + return true + } + return false +}
diff --git a/riscv64/riscv64asm/objdumpext_test.go b/riscv64/riscv64asm/objdumpext_test.go index acbd925..4ab234d 100644 --- a/riscv64/riscv64asm/objdumpext_test.go +++ b/riscv64/riscv64asm/objdumpext_test.go
@@ -289,7 +289,7 @@ strtabsize := len("\x00.text\x00.riscv.attributes\x00.shstrtab\x00") // RISC-V objdump needs the .riscv.attributes section to identify extensions. exts := "rv64i2p0_m2p0_a2p0_f2p0_d2p0_q2p0_c2p0_v1p0_" + - "zicbom1p0_zicbop1p0_zicboz1p0_zicond1p0_zmmul1p0_" + + "zacas1p0_zicbom1p0_zicbop1p0_zicboz1p0_zicond1p0_zmmul1p0_" + "zfh1p0_zfhmin1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0_" + "zvkg1p0_zvkned1p0_zvknha1p0_zvknhb1p0_zvksed1p0_zvksh1p0" b := buildRISCVAttributes(exts)
diff --git a/riscv64/riscv64asm/plan9x.go b/riscv64/riscv64asm/plan9x.go index 59f2a5b..e74621a 100644 --- a/riscv64/riscv64asm/plan9x.go +++ b/riscv64/riscv64asm/plan9x.go
@@ -49,7 +49,9 @@ case AMOADD_D, AMOADD_D_AQ, AMOADD_D_RL, AMOADD_D_AQRL, AMOADD_W, AMOADD_W_AQ, AMOADD_W_RL, AMOADD_W_AQRL, AMOAND_D, AMOAND_D_AQ, AMOAND_D_RL, AMOAND_D_AQRL, - AMOAND_W, AMOAND_W_AQ, AMOAND_W_RL, AMOAND_W_AQRL, AMOMAXU_D, AMOMAXU_D_AQ, + AMOAND_W, AMOAND_W_AQ, AMOAND_W_RL, AMOAND_W_AQRL, AMOCAS_D, AMOCAS_D_AQ, + AMOCAS_D_AQRL, AMOCAS_D_RL, AMOCAS_Q, AMOCAS_Q_AQ, AMOCAS_Q_AQRL, AMOCAS_Q_RL, + AMOCAS_W, AMOCAS_W_AQ, AMOCAS_W_AQRL, AMOCAS_W_RL, AMOMAXU_D, AMOMAXU_D_AQ, AMOMAXU_D_RL, AMOMAXU_D_AQRL, AMOMAXU_W, AMOMAXU_W_AQ, AMOMAXU_W_RL, AMOMAXU_W_AQRL, AMOMAX_D, AMOMAX_D_AQ, AMOMAX_D_RL, AMOMAX_D_AQRL, AMOMAX_W, AMOMAX_W_AQ, AMOMAX_W_RL, AMOMAX_W_AQRL, AMOMINU_D, AMOMINU_D_AQ, AMOMINU_D_RL, AMOMINU_D_AQRL, AMOMINU_W,
diff --git a/riscv64/riscv64asm/tables.go b/riscv64/riscv64asm/tables.go index f96c307..e08b749 100644 --- a/riscv64/riscv64asm/tables.go +++ b/riscv64/riscv64asm/tables.go
@@ -29,6 +29,18 @@ AMOAND_W_AQ AMOAND_W_AQRL AMOAND_W_RL + AMOCAS_D + AMOCAS_D_AQ + AMOCAS_D_AQRL + AMOCAS_D_RL + AMOCAS_Q + AMOCAS_Q_AQ + AMOCAS_Q_AQRL + AMOCAS_Q_RL + AMOCAS_W + AMOCAS_W_AQ + AMOCAS_W_AQRL + AMOCAS_W_RL AMOMAXU_D AMOMAXU_D_AQ AMOMAXU_D_AQRL @@ -1053,6 +1065,18 @@ AMOAND_W_AQ: "AMOAND.W.AQ", AMOAND_W_AQRL: "AMOAND.W.AQRL", AMOAND_W_RL: "AMOAND.W.RL", + AMOCAS_D: "AMOCAS.D", + AMOCAS_D_AQ: "AMOCAS.D.AQ", + AMOCAS_D_AQRL: "AMOCAS.D.AQRL", + AMOCAS_D_RL: "AMOCAS.D.RL", + AMOCAS_Q: "AMOCAS.Q", + AMOCAS_Q_AQ: "AMOCAS.Q.AQ", + AMOCAS_Q_AQRL: "AMOCAS.Q.AQRL", + AMOCAS_Q_RL: "AMOCAS.Q.RL", + AMOCAS_W: "AMOCAS.W", + AMOCAS_W_AQ: "AMOCAS.W.AQ", + AMOCAS_W_AQRL: "AMOCAS.W.AQRL", + AMOCAS_W_RL: "AMOCAS.W.RL", AMOMAXU_D: "AMOMAXU.D", AMOMAXU_D_AQ: "AMOMAXU.D.AQ", AMOMAXU_D_AQRL: "AMOMAXU.D.AQRL", @@ -2098,6 +2122,30 @@ {mask: 0xfe00707f, value: 0x6600202f, op: AMOAND_W_AQRL, args: argTypeList{arg_rd, arg_rs2, arg_rs1_ptr}}, // AMOAND.W.RL rd, rs2, rs1_ptr {mask: 0xfe00707f, value: 0x6200202f, op: AMOAND_W_RL, args: argTypeList{arg_rd, arg_rs2, arg_rs1_ptr}}, + // AMOCAS.D rd, rs2, rs1_ptr + {mask: 0xfe00707f, value: 0x2800302f, op: AMOCAS_D, args: argTypeList{arg_rd, arg_rs2, arg_rs1_ptr}}, + // AMOCAS.D.AQ rd, rs2, rs1_ptr + {mask: 0xfe00707f, value: 0x2c00302f, op: AMOCAS_D_AQ, args: argTypeList{arg_rd, arg_rs2, arg_rs1_ptr}}, + // AMOCAS.D.AQRL rd, rs2, rs1_ptr + {mask: 0xfe00707f, value: 0x2e00302f, op: AMOCAS_D_AQRL, args: argTypeList{arg_rd, arg_rs2, arg_rs1_ptr}}, + // AMOCAS.D.RL rd, rs2, rs1_ptr + {mask: 0xfe00707f, value: 0x2a00302f, op: AMOCAS_D_RL, args: argTypeList{arg_rd, arg_rs2, arg_rs1_ptr}}, + // AMOCAS.Q rd, rs2, rs1_ptr + {mask: 0xfe00707f, value: 0x2800402f, op: AMOCAS_Q, args: argTypeList{arg_rd, arg_rs2, arg_rs1_ptr}}, + // AMOCAS.Q.AQ rd, rs2, rs1_ptr + {mask: 0xfe00707f, value: 0x2c00402f, op: AMOCAS_Q_AQ, args: argTypeList{arg_rd, arg_rs2, arg_rs1_ptr}}, + // AMOCAS.Q.AQRL rd, rs2, rs1_ptr + {mask: 0xfe00707f, value: 0x2e00402f, op: AMOCAS_Q_AQRL, args: argTypeList{arg_rd, arg_rs2, arg_rs1_ptr}}, + // AMOCAS.Q.RL rd, rs2, rs1_ptr + {mask: 0xfe00707f, value: 0x2a00402f, op: AMOCAS_Q_RL, args: argTypeList{arg_rd, arg_rs2, arg_rs1_ptr}}, + // AMOCAS.W rd, rs2, rs1_ptr + {mask: 0xfe00707f, value: 0x2800202f, op: AMOCAS_W, args: argTypeList{arg_rd, arg_rs2, arg_rs1_ptr}}, + // AMOCAS.W.AQ rd, rs2, rs1_ptr + {mask: 0xfe00707f, value: 0x2c00202f, op: AMOCAS_W_AQ, args: argTypeList{arg_rd, arg_rs2, arg_rs1_ptr}}, + // AMOCAS.W.AQRL rd, rs2, rs1_ptr + {mask: 0xfe00707f, value: 0x2e00202f, op: AMOCAS_W_AQRL, args: argTypeList{arg_rd, arg_rs2, arg_rs1_ptr}}, + // AMOCAS.W.RL rd, rs2, rs1_ptr + {mask: 0xfe00707f, value: 0x2a00202f, op: AMOCAS_W_RL, args: argTypeList{arg_rd, arg_rs2, arg_rs1_ptr}}, // AMOMAXU.D rd, rs2, rs1_ptr {mask: 0xfe00707f, value: 0xe000302f, op: AMOMAXU_D, args: argTypeList{arg_rd, arg_rs2, arg_rs1_ptr}}, // AMOMAXU.D.AQ rd, rs2, rs1_ptr
diff --git a/riscv64/riscv64asm/testdata/gnucases.txt b/riscv64/riscv64asm/testdata/gnucases.txt index db1fc8f..e28d4a5 100644 --- a/riscv64/riscv64asm/testdata/gnucases.txt +++ b/riscv64/riscv64asm/testdata/gnucases.txt
@@ -19,6 +19,18 @@ afa26360| amoand.w x5,x6,(x7) afa26364| amoand.w.aq x5,x6,(x7) afa26362| amoand.w.rl x5,x6,(x7) +afa2632e| amocas.w.aqrl x5,x6,(x7) +afa2632c| amocas.w.aq x5,x6,(x7) +afa2632a| amocas.w.rl x5,x6,(x7) +afa26328| amocas.w x5,x6,(x7) +afb2632e| amocas.d.aqrl x5,x6,(x7) +afb2632c| amocas.d.aq x5,x6,(x7) +afb2632a| amocas.d.rl x5,x6,(x7) +afb26328| amocas.d x5,x6,(x7) +2fc2632e| amocas.q.aqrl x4,x6,(x7) +2fc2632c| amocas.q.aq x4,x6,(x7) +2fc2632a| amocas.q.rl x4,x6,(x7) +2fc26328| amocas.q x4,x6,(x7) afb263e0| amomaxu.d x5,x6,(x7) afb263e4| amomaxu.d.aq x5,x6,(x7) afb263e2| amomaxu.d.rl x5,x6,(x7)
diff --git a/riscv64/riscv64asm/testdata/plan9cases.txt b/riscv64/riscv64asm/testdata/plan9cases.txt index a361d65..554834b 100644 --- a/riscv64/riscv64asm/testdata/plan9cases.txt +++ b/riscv64/riscv64asm/testdata/plan9cases.txt
@@ -19,6 +19,18 @@ afa26360| AMOANDW X6, (X7), X5 afa26364| AMOANDW X6, (X7), X5 afa26362| AMOANDW X6, (X7), X5 +afa2632e| AMOCASW X6, (X7), X5 +afa2632c| AMOCASW X6, (X7), X5 +afa2632a| AMOCASW X6, (X7), X5 +afa26328| AMOCASW X6, (X7), X5 +afb2632e| AMOCASD X6, (X7), X5 +afb2632c| AMOCASD X6, (X7), X5 +afb2632a| AMOCASD X6, (X7), X5 +afb26328| AMOCASD X6, (X7), X5 +2fc2632e| AMOCASQ X6, (X7), X4 +2fc2632c| AMOCASQ X6, (X7), X4 +2fc2632a| AMOCASQ X6, (X7), X4 +2fc26328| AMOCASQ X6, (X7), X4 afb263e0| AMOMAXUD X6, (X7), X5 afb263e4| AMOMAXUD X6, (X7), X5 afb263e2| AMOMAXUD X6, (X7), X5
diff --git a/riscv64/riscv64spec/spec.go b/riscv64/riscv64spec/spec.go index 887dd14..77d61de 100644 --- a/riscv64/riscv64spec/spec.go +++ b/riscv64/riscv64spec/spec.go
@@ -32,6 +32,7 @@ "rv_m", "rv_q", "rv_v", + "rv_zacas", "rv_zba", "rv_zbb", "rv_zbc", @@ -53,6 +54,7 @@ "rv64_i", "rv64_m", "rv64_q", + "rv64_zacas", "rv64_zba", "rv64_zbb", "rv64_zbs",