]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/arm64: disable AL and NV for some condition operation instructions
authoreric fang <eric.fang@arm.com>
Fri, 7 May 2021 05:48:18 +0000 (05:48 +0000)
committereric fang <eric.fang@arm.com>
Fri, 14 May 2021 07:53:46 +0000 (07:53 +0000)
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 <eric.fang@arm.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Trust: eric fang <eric.fang@arm.com>
Run-TryBot: eric fang <eric.fang@arm.com>
TryBot-Result: Go Bot <gobot@golang.org>

src/cmd/asm/internal/asm/testdata/arm64error.s
src/cmd/internal/obj/arm64/asm7.go

index 66fc9107594f39f796f040925f02ca5170c5adc4..cf57179e43016156cf148dcbd001c54d5620b00e 100644 (file)
@@ -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"
index 575436d764a9948e8e879133b7c6bf7914e7c6fa..b8c3cd97c76aa4f5f0455595cd14a836c4c35873 100644 (file)
@@ -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)