1
0
mirror of https://github.com/golang/go synced 2024-11-22 20:50:05 -07:00

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 <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>
This commit is contained in:
eric fang 2021-04-15 03:27:55 +00:00
parent 0636d88f6d
commit 5daefc5363
2 changed files with 67 additions and 44 deletions

View 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"

View 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