]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/arm64: fix the wrong ROR operator of some instructions
authoreric fang <eric.fang@arm.com>
Thu, 15 Apr 2021 03:27:55 +0000 (03:27 +0000)
committereric fang <eric.fang@arm.com>
Thu, 22 Apr 2021 01:40:02 +0000 (01:40 +0000)
Instructions such as ADD, SUB, CMP do not support ROR shift operations,
but we have not checked this at present. This CL adds this check.

Change-Id: Icac461f61ad6ddb60886a59ba34dddd29df1cc0f
Reviewed-on: https://go-review.googlesource.com/c/go/+/310035
Reviewed-by: eric fang <eric.fang@arm.com>
Reviewed-by: Cherry Zhang <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 474ed556d059ad96eb2904303dd1904a60c6e161..1744c09b98f868d512c5d461f24dd63567b99812 100644 (file)
@@ -32,6 +32,24 @@ TEXT errors(SB),$0
        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"
+       NEGW    R7<<33, R5                                       // ERROR "shift amount out of range 0 to 31"
+       NEGSW   R7<<33, R5                                       // ERROR "shift amount out of range 0 to 31"
+       ADD     R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+       ADDW    R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+       ADDS    R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+       ADDSW   R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+       SUB     R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+       SUBW    R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+       SUBS    R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+       SUBSW   R7@>2, R5, R16                                   // ERROR "unsupported shift operator"
+       CMP     R7@>2, R5                                        // ERROR "unsupported shift operator"
+       CMPW    R7@>2, R5                                        // ERROR "unsupported shift operator"
+       CMN     R7@>2, R5                                        // ERROR "unsupported shift operator"
+       CMNW    R7@>2, R5                                        // ERROR "unsupported shift operator"
+       NEG     R7@>2, R5                                        // ERROR "unsupported shift operator"
+       NEGW    R7@>2, R5                                        // ERROR "unsupported shift operator"
+       NEGS    R7@>2, R5                                        // ERROR "unsupported shift operator"
+       NEGSW   R7@>2, R5                                        // ERROR "unsupported shift operator"
        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"
index 2dbaea98b602c147176d46a1abc8fc341c563607..64067a4a1715ac08f89ddcfa112c226409e3c232 100644 (file)
@@ -321,12 +321,12 @@ var optab = []Optab{
        {ACMP, C_VCON, C_REG, C_NONE, C_NONE, 13, 20, 0, 0, 0},
        {AADD, C_SHIFT, C_REG, C_NONE, C_REG, 3, 4, 0, 0, 0},
        {AADD, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0},
-       {AADD, C_SHIFT, C_RSP, C_NONE, C_RSP, 107, 4, 0, 0, 0},
-       {AADD, C_SHIFT, C_NONE, C_NONE, C_RSP, 107, 4, 0, 0, 0},
+       {AADD, C_SHIFT, C_RSP, C_NONE, C_RSP, 26, 4, 0, 0, 0},
+       {AADD, C_SHIFT, C_NONE, C_NONE, C_RSP, 26, 4, 0, 0, 0},
        {AMVN, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0},
        {ACMP, C_SHIFT, C_REG, C_NONE, C_NONE, 3, 4, 0, 0, 0},
-       {ACMP, C_SHIFT, C_RSP, C_NONE, C_NONE, 107, 4, 0, 0, 0},
-       {ANEG, C_SHIFT, C_NONE, C_NONE, C_REG, 26, 4, 0, 0, 0},
+       {ACMP, C_SHIFT, C_RSP, C_NONE, C_NONE, 26, 4, 0, 0, 0},
+       {ANEG, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0},
        {AADD, C_REG, C_RSP, C_NONE, C_RSP, 27, 4, 0, 0, 0},
        {AADD, C_REG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0},
        {ACMP, C_REG, C_RSP, C_NONE, C_NONE, 27, 4, 0, 0, 0},
@@ -1355,6 +1355,14 @@ func isADDSop(op obj.As) bool {
        return false
 }
 
+func isNEGop(op obj.As) bool {
+       switch op {
+       case ANEG, ANEGW, ANEGS, ANEGSW:
+               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
 }
@@ -3251,13 +3259,17 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                if is64bit == 0 && amount >= 32 {
                        c.ctxt.Diag("shift amount out of range 0 to 31: %v", p)
                }
+               shift := (p.From.Offset >> 22) & 3
+               if (shift > 2 || shift < 0) && (isADDop(p.As) || isADDWop(p.As) || isNEGop(p.As)) {
+                       c.ctxt.Diag("unsupported shift operator: %v", p)
+               }
                o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
                rt := int(p.To.Reg)
                if p.To.Type == obj.TYPE_NONE {
                        rt = REGZERO
                }
                r := int(p.Reg)
-               if p.As == AMVN || p.As == AMVNW {
+               if p.As == AMVN || p.As == AMVNW || isNEGop(p.As) {
                        r = REGZERO
                } else if r == 0 {
                        r = rt
@@ -3665,12 +3677,40 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                rt := int(p.To.Reg)
                o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
 
-       case 26: /* negX Rm<<s, Rd -> subX Rm<<s, ZR, Rd */
-               o1 = c.oprrr(p, p.As)
+       case 26: // op R<<n, RSP, RSP (extended register)
+               // Refer to ARM reference manual, if "Rd" or "Rn" is RSP,
+               // it can be encoded as op(extended regster) instruction.
+               if !(p.To.Reg == REGSP || p.Reg == REGSP) {
+                       c.ctxt.Diag("expected SP reference: %v", p)
+                       break
+               }
+               if p.To.Reg == REGSP && (p.As == AADDS || p.As == AADDSW || p.As == ASUBS || p.As == ASUBSW) {
+                       c.ctxt.Diag("unexpected SP reference: %v", p)
+                       break
+               }
+               amount := (p.From.Offset >> 10) & 63
+               shift := (p.From.Offset >> 22) & 3
+               if shift != 0 {
+                       c.ctxt.Diag("illegal combination: %v", p)
+                       break
+               }
 
-               o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
+               if amount > 4 {
+                       c.ctxt.Diag("the left shift amount out of range 0 to 4: %v", p)
+                       break
+               }
+               rf := (p.From.Offset >> 16) & 31
                rt := int(p.To.Reg)
-               o1 |= (REGZERO & 31 << 5) | uint32(rt&31)
+               r := int(p.Reg)
+               if p.To.Type == obj.TYPE_NONE {
+                       rt = REGZERO
+               }
+               if r == 0 {
+                       r = rt
+               }
+
+               o1 = c.opxrrr(p, p.As, false)
+               o1 |= uint32(rf)<<16 | uint32(amount&7)<<10 | (uint32(r&31) << 5) | uint32(rt&31)
 
        case 27: /* op Rm<<n[,Rn],Rd (extended register) */
                if p.To.Reg == REG_RSP && isADDSop(p.As) {
@@ -5492,41 +5532,6 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                        c.ctxt.Diag("illegal destination register: %v\n", p)
                }
                o1 |= enc | uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31)
-
-       case 107: // op R<<n, RSP, RSP (extended register)
-               // Refer to ARM reference manual, if "Rd" or "Rn" is RSP,
-               // it can be encoded as op(extended regster) instruction.
-               if !(p.To.Reg == REGSP || p.Reg == REGSP) {
-                       c.ctxt.Diag("expected SP reference: %v", p)
-                       break
-               }
-               if p.To.Reg == REGSP && (p.As == AADDS || p.As == AADDSW || p.As == ASUBS || p.As == ASUBSW) {
-                       c.ctxt.Diag("unexpected SP reference: %v", p)
-                       break
-               }
-               amount := (p.From.Offset >> 10) & 63
-               shift := (p.From.Offset >> 22) & 3
-               if shift != 0 {
-                       c.ctxt.Diag("illegal combination: %v", p)
-                       break
-               }
-
-               if amount > 4 {
-                       c.ctxt.Diag("the left shift amount out of range 0 to 4: %v", p)
-                       break
-               }
-               rf := (p.From.Offset >> 16) & 31
-               rt := int(p.To.Reg)
-               r := int(p.Reg)
-               if p.To.Type == obj.TYPE_NONE {
-                       rt = REGZERO
-               }
-               if r == 0 {
-                       r = rt
-               }
-
-               o1 = c.opxrrr(p, p.As, false)
-               o1 |= uint32(rf)<<16 | uint32(amount&7)<<10 | (uint32(r&31) << 5) | uint32(rt&31)
        }
        out[0] = o1
        out[1] = o2