From 5daefc5363080acd631ae97a84faf651a70d9888 Mon Sep 17 00:00:00 2001 From: eric fang Date: Thu, 15 Apr 2021 03:27:55 +0000 Subject: [PATCH] cmd/internal/obj/arm64: fix the wrong ROR operator of some instructions 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 Reviewed-by: Cherry Zhang Trust: eric fang Run-TryBot: eric fang TryBot-Result: Go Bot --- .../asm/internal/asm/testdata/arm64error.s | 18 ++++ src/cmd/internal/obj/arm64/asm7.go | 93 ++++++++++--------- 2 files changed, 67 insertions(+), 44 deletions(-) diff --git a/src/cmd/asm/internal/asm/testdata/arm64error.s b/src/cmd/asm/internal/asm/testdata/arm64error.s index 474ed556d0..1744c09b98 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64error.s +++ b/src/cmd/asm/internal/asm/testdata/arm64error.s @@ -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" diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index 2dbaea98b6..64067a4a17 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -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)®_EXT != 0 || (a.Index-obj.RBaseARM64)®_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< subX Rm<> 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<> 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 -- 2.50.0