From c925e1546ee72e40ca5351f3773379e99a6b8cdf Mon Sep 17 00:00:00 2001 From: eric fang Date: Fri, 7 May 2021 05:48:18 +0000 Subject: [PATCH] cmd/internal/obj/arm64: disable AL and NV for some condition operation instructions According to the armv8-a reference manual, conditions AL and NV are not allowed for instructions CINC, CINV, CNEG, CSET and CSETM. This CL adds this check and the corresponding test cases. Change-Id: Icb496b7b13a353f41491f2de4d939a5cd88abb04 Reviewed-on: https://go-review.googlesource.com/c/go/+/317912 Reviewed-by: eric fang Reviewed-by: Cherry Mui Trust: eric fang Run-TryBot: eric fang TryBot-Result: Go Bot --- .../asm/internal/asm/testdata/arm64error.s | 10 ++++++++ src/cmd/internal/obj/arm64/asm7.go | 24 +++++++++---------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/cmd/asm/internal/asm/testdata/arm64error.s b/src/cmd/asm/internal/asm/testdata/arm64error.s index 66fc9107594..cf57179e430 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64error.s +++ b/src/cmd/asm/internal/asm/testdata/arm64error.s @@ -52,6 +52,16 @@ TEXT errors(SB),$0 NEGSW R7@>2, R5 // ERROR "unsupported shift operator" CINC CS, R2, R3, R4 // ERROR "illegal combination" CSEL LT, R1, R2 // ERROR "illegal combination" + CINC AL, R2, R3 // ERROR "invalid condition" + CINC NV, R2, R3 // ERROR "invalid condition" + CINVW AL, R2, R3 // ERROR "invalid condition" + CINV NV, R2, R3 // ERROR "invalid condition" + CNEG AL, R2, R3 // ERROR "invalid condition" + CNEGW NV, R2, R3 // ERROR "invalid condition" + CSET AL, R2 // ERROR "invalid condition" + CSET NV, R2 // ERROR "invalid condition" + CSETMW AL, R2 // ERROR "invalid condition" + CSETM NV, R2 // ERROR "invalid condition" LDP.P 8(R2), (R2, R3) // ERROR "constrained unpredictable behavior" LDP.W 8(R3), (R2, R3) // ERROR "constrained unpredictable behavior" LDP (R1), (R2, R2) // ERROR "constrained unpredictable behavior" diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index 575436d764a..b8c3cd97c76 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -3536,27 +3536,25 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { o1 = c.oprrr(p, p.As) cond := int(p.From.Reg) - if cond < COND_EQ || cond > COND_NV { + // AL and NV are not allowed for CINC/CINV/CNEG/CSET/CSETM instructions + if cond < COND_EQ || cond > COND_NV || (cond == COND_AL || cond == COND_NV) && p.From3Type() == obj.TYPE_NONE { c.ctxt.Diag("invalid condition: %v", p) } else { cond -= COND_EQ } r := int(p.Reg) - var rf int - if r != 0 { - if p.From3Type() == obj.TYPE_NONE { - /* CINC/CINV/CNEG */ - rf = r - cond ^= 1 - } else { - rf = int(p.GetFrom3().Reg) /* CSEL */ + var rf int = r + if p.From3Type() == obj.TYPE_NONE { + /* CINC/CINV/CNEG or CSET/CSETM*/ + if r == 0 { + /* CSET/CSETM */ + rf = REGZERO + r = rf } - } else { - /* CSET */ - rf = REGZERO - r = rf cond ^= 1 + } else { + rf = int(p.GetFrom3().Reg) /* CSEL */ } rt := int(p.To.Reg)