diff --git a/riscv64/riscv64asm/decode.go b/riscv64/riscv64asm/decode.go index 390edfa9..c0223dfd 100644 --- a/riscv64/riscv64asm/decode.go +++ b/riscv64/riscv64asm/decode.go @@ -61,6 +61,10 @@ Search: continue } + if !validEncoding(f.op, x) { + continue Search + } + // Decode args. var args Args k := 0 @@ -594,3 +598,17 @@ func convertCompressedIns(f *instFormat, args Args) Args { } 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 ddaa28c5..f47fbe7a 100644 --- a/riscv64/riscv64asm/objdump_test.go +++ b/riscv64/riscv64asm/objdump_test.go @@ -88,6 +88,12 @@ func allowedMismatchObjdump(text string, inst *Inst, dec ExtInst, version string 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 @@ func isZvkOp(op Op) bool { } 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 acbd9256..4ab234d3 100644 --- a/riscv64/riscv64asm/objdumpext_test.go +++ b/riscv64/riscv64asm/objdumpext_test.go @@ -289,7 +289,7 @@ func writeELF64(f *os.File, size int) error { 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 59f2a5b9..e74621a1 100644 --- a/riscv64/riscv64asm/plan9x.go +++ b/riscv64/riscv64asm/plan9x.go @@ -49,7 +49,9 @@ goSyntaxSwitch: 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 1de060f1..e02193e9 100644 --- a/riscv64/riscv64asm/tables.go +++ b/riscv64/riscv64asm/tables.go @@ -29,6 +29,18 @@ const ( 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 @@ var opstr = [...]string{ 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 @@ var instFormats = [...]instFormat{ {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 db1fc8f4..e28d4a53 100644 --- a/riscv64/riscv64asm/testdata/gnucases.txt +++ b/riscv64/riscv64asm/testdata/gnucases.txt @@ -19,6 +19,18 @@ afb26362| amoand.d.rl x5,x6,(x7) 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 a361d65e..554834b8 100644 --- a/riscv64/riscv64asm/testdata/plan9cases.txt +++ b/riscv64/riscv64asm/testdata/plan9cases.txt @@ -19,6 +19,18 @@ afb26362| AMOANDD X6, (X7), X5 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 7c01a444..f08c2513 100644 --- a/riscv64/riscv64spec/spec.go +++ b/riscv64/riscv64spec/spec.go @@ -32,6 +32,7 @@ var extensions = []string{ "rv_m", "rv_q", "rv_v", + "rv_zacas", "rv_zba", "rv_zbb", "rv_zbc", @@ -54,6 +55,7 @@ var extensions = []string{ "rv64_i", "rv64_m", "rv64_q", + "rv64_zacas", "rv64_zba", "rv64_zbb", "rv64_zbs",