Skip to content

Commit 7ab4b55

Browse files
zhangfanniecherrymui
authored andcommitted
cmd/internal/obj/arm64: add CONSTRAINED UNPREDICTABLE behavior check for some load/store
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Cherry Zhang <[email protected]>
1 parent 9c2be4c commit 7ab4b55

File tree

4 files changed

+95
-12
lines changed

4 files changed

+95
-12
lines changed

src/cmd/asm/internal/asm/testdata/arm64.s

+1
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@ again:
654654
CALL foo(SB)
655655

656656
// LDP/STP
657+
LDP (R0), (R0, R1) // 000440a9
657658
LDP (R0), (R1, R2) // 010840a9
658659
LDP 8(R0), (R1, R2) // 018840a9
659660
LDP -8(R0), (R1, R2) // 01887fa9

src/cmd/asm/internal/asm/testdata/arm64enc.s

+2-2
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$-8
188188
MOVBU (R18)(R14<<0), R23 // 577a6e38
189189
MOVBU (R2)(R8.SXTX), R19 // 53e86838
190190
MOVBU (R27)(R23), R14 // MOVBU (R27)(R23*1), R14 // 6e6b7738
191-
MOVHU.P 107(R13), R13 // adb54678
192-
MOVHU.W 192(R2), R2 // 420c4c78
191+
MOVHU.P 107(R14), R13 // cdb54678
192+
MOVHU.W 192(R3), R2 // 620c4c78
193193
MOVHU 6844(R4), R18 // 92787579
194194
MOVHU (R5)(R25.SXTW), R15 // afc87978
195195
//TODO MOVBW.P 77(R18), R11 // 4bd6c438

src/cmd/asm/internal/asm/testdata/arm64error.s

+25-9
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,37 @@ TEXT errors(SB),$0
88
ADDSW R7->32, R14, R13 // ERROR "shift amount out of range 0 to 31"
99
ADD R1.UXTB<<5, R2, R3 // ERROR "shift amount out of range 0 to 4"
1010
ADDS R1.UXTX<<7, R2, R3 // ERROR "shift amount out of range 0 to 4"
11+
AND $0x22220000, R2, RSP // ERROR "illegal combination"
12+
ANDS $0x22220000, R2, RSP // ERROR "illegal combination"
13+
ADD R1, R2, R3, R4 // ERROR "illegal combination"
1114
BICW R7@>33, R5, R16 // ERROR "shift amount out of range 0 to 31"
15+
CINC CS, R2, R3, R4 // ERROR "illegal combination"
16+
CSEL LT, R1, R2 // ERROR "illegal combination"
17+
LDP.P 8(R2), (R2, R3) // ERROR "constrained unpredictable behavior"
18+
LDP.W 8(R3), (R2, R3) // ERROR "constrained unpredictable behavior"
19+
LDP (R1), (R2, R2) // ERROR "constrained unpredictable behavior"
20+
LDP (R0), (F0, F1) // ERROR "invalid register pair"
21+
LDP (R0), (R3, ZR) // ERROR "invalid register pair"
22+
LDXPW (RSP), (R2, R2) // ERROR "constrained unpredictable behavior"
23+
LDAXPW (R5), (R2, R2) // ERROR "constrained unpredictable behavior"
1224
MOVD.P 300(R2), R3 // ERROR "offset out of range [-255,254]"
1325
MOVD.P R3, 344(R2) // ERROR "offset out of range [-255,254]"
1426
MOVD (R3)(R7.SXTX<<2), R8 // ERROR "invalid index shift amount"
1527
MOVWU (R5)(R4.UXTW<<3), R10 // ERROR "invalid index shift amount"
1628
MOVWU (R5)(R4<<1), R10 // ERROR "invalid index shift amount"
1729
MOVB (R5)(R4.SXTW<<5), R10 // ERROR "invalid index shift amount"
1830
MOVH R5, (R6)(R2<<3) // ERROR "invalid index shift amount"
31+
MADD R1, R2, R3 // ERROR "illegal combination"
32+
MOVD.P R1, 8(R1) // ERROR "constrained unpredictable behavior"
33+
MOVD.W 16(R2), R2 // ERROR "constrained unpredictable behavior"
34+
STP (F2, F3), (R0) // ERROR "invalid register pair"
35+
STP.W (R1, R2), 8(R1) // ERROR "constrained unpredictable behavior"
36+
STP.P (R1, R2), 8(R2) // ERROR "constrained unpredictable behavior"
37+
STLXP (R6, R11), (RSP), R6 // ERROR "constrained unpredictable behavior"
38+
STXP (R6, R11), (R2), R2 // ERROR "constrained unpredictable behavior"
39+
STLXR R3, (RSP), R3 // ERROR "constrained unpredictable behavior"
40+
STXR R3, (R4), R4 // ERROR "constrained unpredictable behavior"
41+
STLXRB R2, (R5), R5 // ERROR "constrained unpredictable behavior"
1942
VLD1 (R8)(R13), [V2.B16] // ERROR "illegal combination"
2043
VLD1 8(R9), [V2.B16] // ERROR "illegal combination"
2144
VST1 [V1.B16], (R8)(R13) // ERROR "illegal combination"
@@ -83,15 +106,8 @@ TEXT errors(SB),$0
83106
VST1.P [V1.B16], (R8)(R9<<1) // ERROR "invalid extended register"
84107
VREV64 V1.H4, V2.H8 // ERROR "invalid arrangement"
85108
VREV64 V1.D1, V2.D1 // ERROR "invalid arrangement"
86-
ADD R1, R2, R3, R4 // ERROR "illegal combination"
87-
MADD R1, R2, R3 // ERROR "illegal combination"
88-
CINC CS, R2, R3, R4 // ERROR "illegal combination"
89-
CSEL LT, R1, R2 // ERROR "illegal combination"
90-
AND $0x22220000, R2, RSP // ERROR "illegal combination"
91-
ANDS $0x22220000, R2, RSP // ERROR "illegal combination"
92-
LDP (R0), (F0, F1) // ERROR "invalid register pair"
93-
LDP (R0), (R3, ZR) // ERROR "invalid register pair"
94-
STP (F2, F3), (R0) // ERROR "invalid register pair"
95109
FLDPD (R0), (R1, R2) // ERROR "invalid register pair"
110+
FLDPD (R1), (F2, F2) // ERROR "constrained unpredictable behavior"
111+
FLDPS (R2), (F3, F3) // ERROR "constrained unpredictable behavior"
96112
FSTPD (R1, R2), (R0) // ERROR "invalid register pair"
97113
RET

src/cmd/internal/obj/arm64/asm7.go

+67-1
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,23 @@ func (c *ctxt7) regoff(a *obj.Addr) uint32 {
10851085
return uint32(c.instoffset)
10861086
}
10871087

1088+
func isSTLXRop(op obj.As) bool {
1089+
switch op {
1090+
case ASTLXR, ASTLXRW, ASTLXRB, ASTLXRH,
1091+
ASTXR, ASTXRW, ASTXRB, ASTXRH:
1092+
return true
1093+
}
1094+
return false
1095+
}
1096+
1097+
func isSTXPop(op obj.As) bool {
1098+
switch op {
1099+
case ASTXP, ASTLXP, ASTXPW, ASTLXPW:
1100+
return true
1101+
}
1102+
return false
1103+
}
1104+
10881105
func isRegShiftOrExt(a *obj.Addr) bool {
10891106
return (a.Index-obj.RBaseARM64)&REG_EXT != 0 || (a.Index-obj.RBaseARM64)&REG_LSL != 0
10901107
}
@@ -2502,6 +2519,17 @@ func SYSARG4(op1 int, Cn int, Cm int, op2 int) int {
25022519
return SYSARG5(0, op1, Cn, Cm, op2)
25032520
}
25042521

2522+
// checkUnpredictable checks if the sourse and transfer registers are the same register.
2523+
// ARM64 manual says it is "constrained unpredictable" if the src and dst registers of STP/LDP are same.
2524+
func (c *ctxt7) checkUnpredictable(p *obj.Prog, isload bool, wback bool, rn int16, rt1 int16, rt2 int16) {
2525+
if wback && rn != REGSP && (rn == rt1 || rn == rt2) {
2526+
c.ctxt.Diag("constrained unpredictable behavior: %v", p)
2527+
}
2528+
if isload && rt1 == rt2 {
2529+
c.ctxt.Diag("constrained unpredictable behavior: %v", p)
2530+
}
2531+
}
2532+
25052533
/* checkindex checks if index >= 0 && index <= maxindex */
25062534
func (c *ctxt7) checkindex(p *obj.Prog, index, maxindex int) {
25072535
if index < 0 || index > maxindex {
@@ -2940,6 +2968,10 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
29402968
}
29412969

29422970
case 22: /* movT (R)O!,R; movT O(R)!, R -> ldrT */
2971+
if p.As != AFMOVS && p.As != AFMOVD && p.From.Reg != REGSP && p.From.Reg == p.To.Reg {
2972+
c.ctxt.Diag("constrained unpredictable behavior: %v", p)
2973+
}
2974+
29432975
v := int32(p.From.Offset)
29442976

29452977
if v < -256 || v > 255 {
@@ -2954,6 +2986,10 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
29542986
o1 |= ((uint32(v) & 0x1FF) << 12) | (uint32(p.From.Reg&31) << 5) | uint32(p.To.Reg&31)
29552987

29562988
case 23: /* movT R,(R)O!; movT O(R)!, R -> strT */
2989+
if p.As != AFMOVS && p.As != AFMOVD && p.To.Reg != REGSP && p.From.Reg == p.To.Reg {
2990+
c.ctxt.Diag("constrained unpredictable behavior: %v", p)
2991+
}
2992+
29572993
v := int32(p.To.Offset)
29582994

29592995
if v < -256 || v > 255 {
@@ -3551,21 +3587,37 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
35513587
o1 |= 0x1F << 16
35523588
o1 |= uint32(p.From.Reg&31) << 5
35533589
if p.As == ALDXP || p.As == ALDXPW || p.As == ALDAXP || p.As == ALDAXPW {
3590+
if int(p.To.Reg) == int(p.To.Offset) {
3591+
c.ctxt.Diag("constrained unpredictable behavior: %v", p)
3592+
}
35543593
o1 |= uint32(p.To.Offset&31) << 10
35553594
} else {
35563595
o1 |= 0x1F << 10
35573596
}
35583597
o1 |= uint32(p.To.Reg & 31)
35593598

35603599
case 59: /* stxr/stlxr/stxp/stlxp */
3600+
s := p.RegTo2
3601+
n := p.To.Reg
3602+
t := p.From.Reg
3603+
if isSTLXRop(p.As) {
3604+
if s == t || (s == n && n != REGSP) {
3605+
c.ctxt.Diag("constrained unpredictable behavior: %v", p)
3606+
}
3607+
} else if isSTXPop(p.As) {
3608+
t2 := int16(p.From.Offset)
3609+
if (s == t || s == t2) || (s == n && n != REGSP) {
3610+
c.ctxt.Diag("constrained unpredictable behavior: %v", p)
3611+
}
3612+
}
35613613
o1 = c.opstore(p, p.As)
35623614

35633615
if p.RegTo2 != obj.REG_NONE {
35643616
o1 |= uint32(p.RegTo2&31) << 16
35653617
} else {
35663618
o1 |= 0x1F << 16
35673619
}
3568-
if p.As == ASTXP || p.As == ASTXPW || p.As == ASTLXP || p.As == ASTLXPW {
3620+
if isSTXPop(p.As) {
35693621
o1 |= uint32(p.From.Offset&31) << 10
35703622
}
35713623
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
61776229

61786230
/* genrate instruction encoding for LDP/LDPW/LDPSW/STP/STPW */
61796231
func (c *ctxt7) opldpstp(p *obj.Prog, o *Optab, vo int32, rbase, rl, rh, ldp uint32) uint32 {
6232+
wback := false
6233+
if o.scond == C_XPOST || o.scond == C_XPRE {
6234+
wback = true
6235+
}
6236+
switch p.As {
6237+
case ALDP, ALDPW, ALDPSW:
6238+
c.checkUnpredictable(p, true, wback, p.From.Reg, p.To.Reg, int16(p.To.Offset))
6239+
case ASTP, ASTPW:
6240+
if wback == true {
6241+
c.checkUnpredictable(p, false, true, p.To.Reg, p.From.Reg, int16(p.From.Offset))
6242+
}
6243+
case AFLDPD, AFLDPS:
6244+
c.checkUnpredictable(p, true, false, p.From.Reg, p.To.Reg, int16(p.To.Offset))
6245+
}
61806246
var ret uint32
61816247
// check offset
61826248
switch p.As {

0 commit comments

Comments
 (0)