riscv64: improve disassembler support for FENCE This commit adds disassembler support for FENCE.TSO in both gnu and plan9 disassembly. It also adds support for FENCE operands in plan9 disassembly. These were previously supported for gnu syntax disassembly but not for plan9 disassembly. We also add a few more checks to ensure that reserved FENCE encodings are decoded as full fences, rather than say FENCE ,. Change-Id: I89fb8cef3fc57a2dcd282bd9c4c27d63f47eaea0 Reviewed-on: https://go-review.googlesource.com/c/arch/+/762800 Reviewed-by: Carlos Amedee <carlos@golang.org> Reviewed-by: Damien Neil <dneil@google.com> Reviewed-by: Joel Sing <joel@sing.id.au> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/riscv64/riscv64asm/gnu.go b/riscv64/riscv64asm/gnu.go index 254bc1f..324b365 100644 --- a/riscv64/riscv64asm/gnu.go +++ b/riscv64/riscv64asm/gnu.go
@@ -241,17 +241,25 @@ args = args[:len(args)-1] } - // When both pred and succ equals to iorw, the GNU objdump will omit them. case FENCE: - if inst.Args[0].(MemOrder).String() == "iorw" && - inst.Args[1].(MemOrder).String() == "iorw" { - args = nil + fm := inst.Enc >> 28 + pred := inst.Args[0].(MemOrder).String() + succ := inst.Args[1].(MemOrder).String() + if fm == 0b1000 { + if pred == "rw" && succ == "rw" { + return "fence.tso" + } + return op } // PAUSE is encoded as a FENCE instruction with pred=W, succ=0. - if inst.Args[0].(MemOrder).String() == "w" && - inst.Args[1].(MemOrder).String() == "" { - op = "pause" - args = nil + if pred == "w" && succ == "" { + return "pause" + } + if fm != 0 || pred == "" || succ == "" || (pred == "iorw" && succ == "iorw") { + // We've either got a full fence or a reserved encoding which should be + // treated as a full fence. When both pred and succ equals to iorw, GNU + // objdump will omit them. + return op } case FSGNJX_D:
diff --git a/riscv64/riscv64asm/plan9x.go b/riscv64/riscv64asm/plan9x.go index 2a20d0d..59f2a5b 100644 --- a/riscv64/riscv64asm/plan9x.go +++ b/riscv64/riscv64asm/plan9x.go
@@ -199,14 +199,26 @@ } } - // Fence instruction in plan9 doesn't have any operands. case FENCE: - // PAUSE is encoded as a FENCE instruction with pred=W, succ=0. - if inst.Args[0].(MemOrder).String() == "w" && - inst.Args[1].(MemOrder).String() == "" { - op = "PAUSE" + fm := inst.Enc >> 28 + pred := inst.Args[0].(MemOrder).String() + succ := inst.Args[1].(MemOrder).String() + if fm == 0b1000 { + if pred == "rw" && succ == "rw" { + return "FENCE.TSO" + } + return op } - args = nil + // PAUSE is encoded as a FENCE instruction with pred=W, succ=0. + if pred == "w" && succ == "" { + return "PAUSE" + } + if fm != 0 || pred == "" || succ == "" || (pred == "iorw" && succ == "iorw") { + // We've either got a full fence or a reserved encoding which should be + // treated as a full fence. + return op + } + args[0], args[1] = args[1], args[0] case FMADD_D, FMADD_H, FMADD_Q, FMADD_S, FMSUB_D, FMSUB_H, FMSUB_Q, FMSUB_S, FNMADD_D, FNMADD_H, FNMADD_Q, FNMADD_S,
diff --git a/riscv64/riscv64asm/testdata/gnucases.txt b/riscv64/riscv64asm/testdata/gnucases.txt index a338493..ac9712c 100644 --- a/riscv64/riscv64asm/testdata/gnucases.txt +++ b/riscv64/riscv64asm/testdata/gnucases.txt
@@ -176,6 +176,7 @@ 0f00f00d| fence iow,iorw 0f00f007| fence orw,iorw 0f00f00f| fence +0f000000| fence 0f001004| fence o,w 0f002004| fence o,r 0f004004| fence o,o @@ -184,6 +185,7 @@ 0f002008| fence i,r 0f004008| fence i,o 0f008008| fence i,i +0f003083| fence.tso 0f100000| fence.i d32210a2| feq.d x5,f0,f1 d32210a4| feq.h x5,f0,f1
diff --git a/riscv64/riscv64asm/testdata/plan9cases.txt b/riscv64/riscv64asm/testdata/plan9cases.txt index 55a9260..8ad8c77 100644 --- a/riscv64/riscv64asm/testdata/plan9cases.txt +++ b/riscv64/riscv64asm/testdata/plan9cases.txt
@@ -157,32 +157,33 @@ 53f0201c| FDIVH F2, F1, F0 53f0201e| FDIVQ F2, F1, F0 53f02018| FDIVS F2, F1, F0 -# Fence instruction in plan9 doesn't have any operands. -0f001001| FENCE -0f002001| FENCE -0f004001| FENCE -0f008001| FENCE -0f001002| FENCE -0f002002| FENCE -0f004002| FENCE -0f008002| FENCE -0f003003| FENCE -0f00f003| FENCE -0f00300f| FENCE -0f00300c| FENCE -0f00c003| FENCE -0f00f00e| FENCE -0f00f00d| FENCE -0f00f007| FENCE +0f001001| FENCE W, W +0f002001| FENCE W, R +0f004001| FENCE W, O +0f008001| FENCE W, I +0f001002| FENCE R, W +0f002002| FENCE R, R +0f004002| FENCE R, O +0f008002| FENCE R, I +0f003003| FENCE RW, RW +0f00f003| FENCE RW, IORW +0f00300f| FENCE IORW, RW +0f00300c| FENCE IO, RW +0f00c003| FENCE RW, IO +0f00f00e| FENCE IOR, IORW +0f00f00d| FENCE IOW, IORW +0f00f007| FENCE ORW, IORW 0f00f00f| FENCE -0f001004| FENCE -0f002004| FENCE -0f004004| FENCE -0f008004| FENCE -0f001008| FENCE -0f002008| FENCE -0f004008| FENCE -0f008008| FENCE +0f000000| FENCE +0f001004| FENCE O, W +0f002004| FENCE O, R +0f004004| FENCE O, O +0f008004| FENCE O, I +0f001008| FENCE I, W +0f002008| FENCE I, R +0f004008| FENCE I, O +0f008008| FENCE I, I +0f003083| FENCE.TSO 0f100000| FENCEI d32210a2| FEQD F1, F0, X5 d32210a4| FEQH F1, F0, X5