Commit b8a4eb4b authored by Ben Shi's avatar Ben Shi Committed by Cherry Zhang

cmd/internal/obj/arm: fix illegal forms of ARM VFP instruction

"ADDF F0, R1, F2" is silently accepted by the arm assembler and
assembled to the same binary code of "ADDF F0, F1, F2". So does
"CMPF F0, R1".

"ABSF F0, F1, F2" is also silently accepted and assembled to a
different instruction.

This patch reports those illegal forms and adds test cases.

fix #20464

Change-Id: I88b80dc29de24c6266ac7bf7bce1578c5adbc68c
Reviewed-on: https://go-review.googlesource.com/43931
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
parent 13ae3b3a
...@@ -305,7 +305,7 @@ func testErrors(t *testing.T, goarch, file string) { ...@@ -305,7 +305,7 @@ func testErrors(t *testing.T, goarch, file string) {
continue continue
} }
fileline := m[1] fileline := m[1]
if errors[fileline] != "" { if errors[fileline] != "" && errors[fileline] != line {
t.Errorf("multiple errors on %s:\n\t%s\n\t%s", fileline, errors[fileline], line) t.Errorf("multiple errors on %s:\n\t%s\n\t%s", fileline, errors[fileline], line)
continue continue
} }
......
...@@ -7,4 +7,17 @@ TEXT errors(SB),$0 ...@@ -7,4 +7,17 @@ TEXT errors(SB),$0
ADD.P R1, R2, R3 // ERROR "invalid .P suffix" ADD.P R1, R2, R3 // ERROR "invalid .P suffix"
SUB.W R2, R3 // ERROR "invalid .W suffix" SUB.W R2, R3 // ERROR "invalid .W suffix"
BL 4(R4) // ERROR "non-zero offset" BL 4(R4) // ERROR "non-zero offset"
ADDF F0, R1, F2 // ERROR "illegal combination"
SWI (R0) // ERROR "illegal combination"
NEGF F0, F1, F2 // ERROR "illegal combination"
NEGD F0, F1, F2 // ERROR "illegal combination"
ABSF F0, F1, F2 // ERROR "illegal combination"
ABSD F0, F1, F2 // ERROR "illegal combination"
SQRTF F0, F1, F2 // ERROR "illegal combination"
SQRTD F0, F1, F2 // ERROR "illegal combination"
MOVF F0, F1, F2 // ERROR "illegal combination"
MOVD F0, F1, F2 // ERROR "illegal combination"
MOVDF F0, F1, F2 // ERROR "illegal combination"
MOVFD F0, F1, F2 // ERROR "illegal combination"
END END
...@@ -228,8 +228,9 @@ var optab = []Optab{ ...@@ -228,8 +228,9 @@ var optab = []Optab{
{AMOVF, C_FREG, C_NONE, C_ADDR, 68, 8, 0, LTO | LPCREL, 4}, {AMOVF, C_FREG, C_NONE, C_ADDR, 68, 8, 0, LTO | LPCREL, 4},
{AMOVF, C_ADDR, C_NONE, C_FREG, 69, 8, 0, LFROM | LPCREL, 4}, {AMOVF, C_ADDR, C_NONE, C_FREG, 69, 8, 0, LFROM | LPCREL, 4},
{AADDF, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0}, {AADDF, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0},
{AADDF, C_FREG, C_REG, C_FREG, 54, 4, 0, 0, 0}, {AADDF, C_FREG, C_FREG, C_FREG, 54, 4, 0, 0, 0},
{AMOVF, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0}, {AMOVF, C_FREG, C_NONE, C_FREG, 55, 4, 0, 0, 0},
{ANEGF, C_FREG, C_NONE, C_FREG, 55, 4, 0, 0, 0},
{AMOVW, C_REG, C_NONE, C_FCR, 56, 4, 0, 0, 0}, {AMOVW, C_REG, C_NONE, C_FCR, 56, 4, 0, 0, 0},
{AMOVW, C_FCR, C_NONE, C_REG, 57, 4, 0, 0, 0}, {AMOVW, C_FCR, C_NONE, C_REG, 57, 4, 0, 0, 0},
{AMOVW, C_SHIFT, C_NONE, C_REG, 59, 4, 0, 0, 0}, {AMOVW, C_SHIFT, C_NONE, C_REG, 59, 4, 0, 0, 0},
...@@ -284,7 +285,7 @@ var optab = []Optab{ ...@@ -284,7 +285,7 @@ var optab = []Optab{
{ASTREX, C_SOREG, C_REG, C_REG, 78, 4, 0, 0, 0}, {ASTREX, C_SOREG, C_REG, C_REG, 78, 4, 0, 0, 0},
{AMOVF, C_ZFCON, C_NONE, C_FREG, 80, 8, 0, 0, 0}, {AMOVF, C_ZFCON, C_NONE, C_FREG, 80, 8, 0, 0, 0},
{AMOVF, C_SFCON, C_NONE, C_FREG, 81, 4, 0, 0, 0}, {AMOVF, C_SFCON, C_NONE, C_FREG, 81, 4, 0, 0, 0},
{ACMPF, C_FREG, C_REG, C_NONE, 82, 8, 0, 0, 0}, {ACMPF, C_FREG, C_FREG, C_NONE, 82, 8, 0, 0, 0},
{ACMPF, C_FREG, C_NONE, C_NONE, 83, 8, 0, 0, 0}, {ACMPF, C_FREG, C_NONE, C_NONE, 83, 8, 0, 0, 0},
{AMOVFW, C_FREG, C_NONE, C_FREG, 84, 4, 0, 0, 0}, {AMOVFW, C_FREG, C_NONE, C_FREG, 84, 4, 0, 0, 0},
{AMOVWF, C_FREG, C_NONE, C_FREG, 85, 4, 0, 0, 0}, {AMOVWF, C_FREG, C_NONE, C_FREG, 85, 4, 0, 0, 0},
...@@ -1325,7 +1326,14 @@ func (c *ctxt5) oplook(p *obj.Prog) *Optab { ...@@ -1325,7 +1326,14 @@ func (c *ctxt5) oplook(p *obj.Prog) *Optab {
a3-- a3--
a2 := C_NONE a2 := C_NONE
if p.Reg != 0 { if p.Reg != 0 {
a2 = C_REG switch {
case REG_F0 <= p.Reg && p.Reg <= REG_F15:
a2 = C_FREG
case REG_R0 <= p.Reg && p.Reg <= REG_R15:
a2 = C_REG
default:
c.ctxt.Diag("invalid register in %v", p)
}
} }
// If current instruction has a .S suffix (flags update), // If current instruction has a .S suffix (flags update),
...@@ -1353,8 +1361,7 @@ func (c *ctxt5) oplook(p *obj.Prog) *Optab { ...@@ -1353,8 +1361,7 @@ func (c *ctxt5) oplook(p *obj.Prog) *Optab {
} }
} }
c.ctxt.Diag("illegal combination %v; %v %v %v, %d %d", p, DRconv(a1), DRconv(a2), DRconv(a3), p.From.Type, p.To.Type) c.ctxt.Diag("illegal combination %v; %v %v %v; from %d %d; to %d %d", p, DRconv(a1), DRconv(a2), DRconv(a3), p.From.Type, p.From.Name, p.To.Type, p.To.Name)
c.ctxt.Diag("from %d %d to %d %d\n", p.From.Type, p.From.Name, p.To.Type, p.To.Name)
if ops == nil { if ops == nil {
ops = optab ops = optab
} }
...@@ -1590,14 +1597,15 @@ func buildop(ctxt *obj.Link) { ...@@ -1590,14 +1597,15 @@ func buildop(ctxt *obj.Link) {
opset(AMULD, r0) opset(AMULD, r0)
opset(ADIVF, r0) opset(ADIVF, r0)
opset(ADIVD, r0) opset(ADIVD, r0)
case ANEGF:
opset(ANEGD, r0)
opset(ASQRTF, r0) opset(ASQRTF, r0)
opset(ASQRTD, r0) opset(ASQRTD, r0)
opset(AMOVFD, r0) opset(AMOVFD, r0)
opset(AMOVDF, r0) opset(AMOVDF, r0)
opset(AABSF, r0) opset(AABSF, r0)
opset(AABSD, r0) opset(AABSD, r0)
opset(ANEGF, r0)
opset(ANEGD, r0)
case ACMPF: case ACMPF:
opset(ACMPD, r0) opset(ACMPD, r0)
...@@ -2167,13 +2175,18 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) { ...@@ -2167,13 +2175,18 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
r := int(p.Reg) r := int(p.Reg)
if r == 0 { if r == 0 {
r = rt r = rt
if p.As == AMOVF || p.As == AMOVD || p.As == AMOVFD || p.As == AMOVDF || p.As == ASQRTF || p.As == ASQRTD || p.As == AABSF || p.As == AABSD || p.As == ANEGF || p.As == ANEGD {
r = 0
}
} }
o1 |= (uint32(rf)&15)<<0 | (uint32(r)&15)<<16 | (uint32(rt)&15)<<12 o1 |= (uint32(rf)&15)<<0 | (uint32(r)&15)<<16 | (uint32(rt)&15)<<12
case 55: /* negf freg, freg */
o1 = c.oprrr(p, p.As, int(p.Scond))
rf := int(p.From.Reg)
rt := int(p.To.Reg)
o1 |= (uint32(rf)&15)<<0 | (uint32(rt)&15)<<12
case 56: /* move to FP[CS]R */ case 56: /* move to FP[CS]R */
o1 = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0xe<<24 | 1<<8 | 1<<4 o1 = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0xe<<24 | 1<<8 | 1<<4
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment