]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/arm64: add CONSTRAINED UNPREDICTABLE behavior check for some load...
authorfanzha02 <fannie.zhang@arm.com>
Fri, 15 Jun 2018 10:20:00 +0000 (10:20 +0000)
committerCherry Zhang <cherryyz@google.com>
Thu, 6 Sep 2018 19:42:03 +0000 (19:42 +0000)
According to ARM64 manual, it is "constrained unpredictable behavior"
if the src and dst registers of some load/store instructions are same.
In order to completely prevent such unpredictable behavior, adding the
check for load/store instructions that are supported by the assembler
in the assembler.

Add test cases.

Update #25823

Change-Id: I64c14ad99ee543d778e7ec8ae6516a532293dbb3
Reviewed-on: https://go-review.googlesource.com/120660
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/asm/internal/asm/testdata/arm64.s
src/cmd/asm/internal/asm/testdata/arm64enc.s
src/cmd/asm/internal/asm/testdata/arm64error.s
src/cmd/internal/obj/arm64/asm7.go

index 361b7a45c0ce1c5346c5c9b9ea070d81b21a13b7..9e2e2b1dc5436ac872e9549433efce9f9e888b01 100644 (file)
@@ -654,6 +654,7 @@ again:
        CALL    foo(SB)
 
 // LDP/STP
+       LDP     (R0), (R0, R1)      // 000440a9
        LDP     (R0), (R1, R2)      // 010840a9
        LDP     8(R0), (R1, R2)     // 018840a9
        LDP     -8(R0), (R1, R2)    // 01887fa9
index ee4673c1ae1e45dbd42586b25b4f04ec189f23a6..432ab74493c204e9663c8316c263a24193459626 100644 (file)
@@ -188,8 +188,8 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$-8
    MOVBU (R18)(R14<<0), R23                   // 577a6e38
    MOVBU (R2)(R8.SXTX), R19                   // 53e86838
    MOVBU (R27)(R23), R14                      // MOVBU (R27)(R23*1), R14     // 6e6b7738
-   MOVHU.P 107(R13), R13                      // adb54678
-   MOVHU.W 192(R2), R2                        // 420c4c78
+   MOVHU.P 107(R14), R13                      // cdb54678
+   MOVHU.W 192(R3), R2                        // 620c4c78
    MOVHU 6844(R4), R18                        // 92787579
    MOVHU (R5)(R25.SXTW), R15                  // afc87978
    //TODO MOVBW.P 77(R18), R11                // 4bd6c438
index b2ec0cc42502b7fe6bb1b72fa667f5cfcdc764a7..bbdce479c517be7c7b3c03355cb4e3abbec9acb8 100644 (file)
@@ -8,7 +8,19 @@ TEXT errors(SB),$0
        ADDSW   R7->32, R14, R13                                 // ERROR "shift amount out of range 0 to 31"
        ADD     R1.UXTB<<5, R2, R3                               // ERROR "shift amount out of range 0 to 4"
        ADDS    R1.UXTX<<7, R2, R3                               // ERROR "shift amount out of range 0 to 4"
+       AND     $0x22220000, R2, RSP                             // ERROR "illegal combination"
+       ANDS    $0x22220000, R2, RSP                             // ERROR "illegal combination"
+       ADD     R1, R2, R3, R4                                   // ERROR "illegal combination"
        BICW    R7@>33, R5, R16                                  // ERROR "shift amount out of range 0 to 31"
+       CINC    CS, R2, R3, R4                                   // ERROR "illegal combination"
+       CSEL    LT, R1, R2                                       // ERROR "illegal combination"
+       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"
+       LDP     (R0), (F0, F1)                                   // ERROR "invalid register pair"
+       LDP     (R0), (R3, ZR)                                   // ERROR "invalid register pair"
+       LDXPW   (RSP), (R2, R2)                                  // ERROR "constrained unpredictable behavior"
+       LDAXPW  (R5), (R2, R2)                                   // ERROR "constrained unpredictable behavior"
        MOVD.P  300(R2), R3                                      // ERROR "offset out of range [-255,254]"
        MOVD.P  R3, 344(R2)                                      // ERROR "offset out of range [-255,254]"
        MOVD    (R3)(R7.SXTX<<2), R8                             // ERROR "invalid index shift amount"
@@ -16,6 +28,17 @@ TEXT errors(SB),$0
        MOVWU   (R5)(R4<<1), R10                                 // ERROR "invalid index shift amount"
        MOVB    (R5)(R4.SXTW<<5), R10                            // ERROR "invalid index shift amount"
        MOVH    R5, (R6)(R2<<3)                                  // ERROR "invalid index shift amount"
+       MADD    R1, R2, R3                                       // ERROR "illegal combination"
+       MOVD.P  R1, 8(R1)                                        // ERROR "constrained unpredictable behavior"
+       MOVD.W  16(R2), R2                                       // ERROR "constrained unpredictable behavior"
+       STP     (F2, F3), (R0)                                   // ERROR "invalid register pair"
+       STP.W   (R1, R2), 8(R1)                                  // ERROR "constrained unpredictable behavior"
+       STP.P   (R1, R2), 8(R2)                                  // ERROR "constrained unpredictable behavior"
+       STLXP   (R6, R11), (RSP), R6                             // ERROR "constrained unpredictable behavior"
+       STXP    (R6, R11), (R2), R2                              // ERROR "constrained unpredictable behavior"
+       STLXR   R3, (RSP), R3                                    // ERROR "constrained unpredictable behavior"
+       STXR    R3, (R4), R4                                     // ERROR "constrained unpredictable behavior"
+       STLXRB  R2, (R5), R5                                     // ERROR "constrained unpredictable behavior"
        VLD1    (R8)(R13), [V2.B16]                              // ERROR "illegal combination"
        VLD1    8(R9), [V2.B16]                                  // ERROR "illegal combination"
        VST1    [V1.B16], (R8)(R13)                              // ERROR "illegal combination"
@@ -83,15 +106,8 @@ TEXT errors(SB),$0
        VST1.P  [V1.B16], (R8)(R9<<1)                            // ERROR "invalid extended register"
        VREV64  V1.H4, V2.H8                                     // ERROR "invalid arrangement"
        VREV64  V1.D1, V2.D1                                     // ERROR "invalid arrangement"
-       ADD     R1, R2, R3, R4                                   // ERROR "illegal combination"
-       MADD    R1, R2, R3                                       // ERROR "illegal combination"
-       CINC    CS, R2, R3, R4                                   // ERROR "illegal combination"
-       CSEL    LT, R1, R2                                       // ERROR "illegal combination"
-       AND     $0x22220000, R2, RSP                             // ERROR "illegal combination"
-       ANDS    $0x22220000, R2, RSP                             // ERROR "illegal combination"
-       LDP     (R0), (F0, F1)                                   // ERROR "invalid register pair"
-       LDP     (R0), (R3, ZR)                                   // ERROR "invalid register pair"
-       STP     (F2, F3), (R0)                                   // ERROR "invalid register pair"
        FLDPD   (R0), (R1, R2)                                   // ERROR "invalid register pair"
+       FLDPD   (R1), (F2, F2)                                   // ERROR "constrained unpredictable behavior"
+       FLDPS   (R2), (F3, F3)                                   // ERROR "constrained unpredictable behavior"
        FSTPD   (R1, R2), (R0)                                   // ERROR "invalid register pair"
        RET
index 7507976257b92493e77c331331d41a56a9bd0e1b..09ffc5dccf72e2dc219ad3010543732ee8bdff53 100644 (file)
@@ -1085,6 +1085,23 @@ func (c *ctxt7) regoff(a *obj.Addr) uint32 {
        return uint32(c.instoffset)
 }
 
+func isSTLXRop(op obj.As) bool {
+       switch op {
+       case ASTLXR, ASTLXRW, ASTLXRB, ASTLXRH,
+               ASTXR, ASTXRW, ASTXRB, ASTXRH:
+               return true
+       }
+       return false
+}
+
+func isSTXPop(op obj.As) bool {
+       switch op {
+       case ASTXP, ASTLXP, ASTXPW, ASTLXPW:
+               return true
+       }
+       return false
+}
+
 func isRegShiftOrExt(a *obj.Addr) bool {
        return (a.Index-obj.RBaseARM64)&REG_EXT != 0 || (a.Index-obj.RBaseARM64)&REG_LSL != 0
 }
@@ -2502,6 +2519,17 @@ func SYSARG4(op1 int, Cn int, Cm int, op2 int) int {
        return SYSARG5(0, op1, Cn, Cm, op2)
 }
 
+// checkUnpredictable checks if the sourse and transfer registers are the same register.
+// ARM64 manual says it is "constrained unpredictable" if the src and dst registers of STP/LDP are same.
+func (c *ctxt7) checkUnpredictable(p *obj.Prog, isload bool, wback bool, rn int16, rt1 int16, rt2 int16) {
+       if wback && rn != REGSP && (rn == rt1 || rn == rt2) {
+               c.ctxt.Diag("constrained unpredictable behavior: %v", p)
+       }
+       if isload && rt1 == rt2 {
+               c.ctxt.Diag("constrained unpredictable behavior: %v", p)
+       }
+}
+
 /* checkindex checks if index >= 0 && index <= maxindex */
 func (c *ctxt7) checkindex(p *obj.Prog, index, maxindex int) {
        if index < 0 || index > maxindex {
@@ -2940,6 +2968,10 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                }
 
        case 22: /* movT (R)O!,R; movT O(R)!, R -> ldrT */
+               if p.As != AFMOVS && p.As != AFMOVD && p.From.Reg != REGSP && p.From.Reg == p.To.Reg {
+                       c.ctxt.Diag("constrained unpredictable behavior: %v", p)
+               }
+
                v := int32(p.From.Offset)
 
                if v < -256 || v > 255 {
@@ -2954,6 +2986,10 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                o1 |= ((uint32(v) & 0x1FF) << 12) | (uint32(p.From.Reg&31) << 5) | uint32(p.To.Reg&31)
 
        case 23: /* movT R,(R)O!; movT O(R)!, R -> strT */
+               if p.As != AFMOVS && p.As != AFMOVD && p.To.Reg != REGSP && p.From.Reg == p.To.Reg {
+                       c.ctxt.Diag("constrained unpredictable behavior: %v", p)
+               }
+
                v := int32(p.To.Offset)
 
                if v < -256 || v > 255 {
@@ -3551,6 +3587,9 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                o1 |= 0x1F << 16
                o1 |= uint32(p.From.Reg&31) << 5
                if p.As == ALDXP || p.As == ALDXPW || p.As == ALDAXP || p.As == ALDAXPW {
+                       if int(p.To.Reg) == int(p.To.Offset) {
+                               c.ctxt.Diag("constrained unpredictable behavior: %v", p)
+                       }
                        o1 |= uint32(p.To.Offset&31) << 10
                } else {
                        o1 |= 0x1F << 10
@@ -3558,6 +3597,19 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                o1 |= uint32(p.To.Reg & 31)
 
        case 59: /* stxr/stlxr/stxp/stlxp */
+               s := p.RegTo2
+               n := p.To.Reg
+               t := p.From.Reg
+               if isSTLXRop(p.As) {
+                       if s == t || (s == n && n != REGSP) {
+                               c.ctxt.Diag("constrained unpredictable behavior: %v", p)
+                       }
+               } else if isSTXPop(p.As) {
+                       t2 := int16(p.From.Offset)
+                       if (s == t || s == t2) || (s == n && n != REGSP) {
+                               c.ctxt.Diag("constrained unpredictable behavior: %v", p)
+                       }
+               }
                o1 = c.opstore(p, p.As)
 
                if p.RegTo2 != obj.REG_NONE {
@@ -3565,7 +3617,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                } else {
                        o1 |= 0x1F << 16
                }
-               if p.As == ASTXP || p.As == ASTXPW || p.As == ASTLXP || p.As == ASTLXPW {
+               if isSTXPop(p.As) {
                        o1 |= uint32(p.From.Offset&31) << 10
                }
                o1 |= uint32(p.To.Reg&31)<<5 | uint32(p.From.Reg&31)
@@ -6177,6 +6229,20 @@ func (c *ctxt7) opextr(p *obj.Prog, a obj.As, v int32, rn int, rm int, rt int) u
 
 /* genrate instruction encoding for LDP/LDPW/LDPSW/STP/STPW */
 func (c *ctxt7) opldpstp(p *obj.Prog, o *Optab, vo int32, rbase, rl, rh, ldp uint32) uint32 {
+       wback := false
+       if o.scond == C_XPOST || o.scond == C_XPRE {
+               wback = true
+       }
+       switch p.As {
+       case ALDP, ALDPW, ALDPSW:
+               c.checkUnpredictable(p, true, wback, p.From.Reg, p.To.Reg, int16(p.To.Offset))
+       case ASTP, ASTPW:
+               if wback == true {
+                       c.checkUnpredictable(p, false, true, p.To.Reg, p.From.Reg, int16(p.From.Offset))
+               }
+       case AFLDPD, AFLDPS:
+               c.checkUnpredictable(p, true, false, p.From.Reg, p.To.Reg, int16(p.To.Offset))
+       }
        var ret uint32
        // check offset
        switch p.As {