mirror of https://github.com/golang/go.git
cmd/internal/obj/arm64: fix the bug of incorrect handling negative offset of LDP/STP/LDPW/STPW
The current assembler will report error when the negative offset is in the range of [-256, 0) and is not the multiples of 4/8. The fix introduces C_NSAUTO_8, C_NSAUTO_4 and C_NAUTO4K. C_NPAUTO includes C_NSAUTO_8 instead of C_NSAUTO, C_NAUTO4K includes C_NSAUTO_8, C_NSAUTO_4 and C_NSAUTO. So that assembler will encode the negative offset that is greater than -4095 and is not the multiples of 4/8 as two instructions. Add the test cases. Fixed #24471 Change-Id: I42f34e3b8a9fc52c9e8b41504294271aafade639 Reviewed-on: https://go-review.googlesource.com/102635 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
5a91c83ce8
commit
4d59b14400
|
|
@ -540,8 +540,12 @@ again:
|
|||
LDP 1024(RSP), (R1, R2) // fb031091610b40a9
|
||||
LDP.W 8(RSP), (R1, R2) // e18bc0a9
|
||||
LDP.P 8(RSP), (R1, R2) // e18bc0a8
|
||||
LDP -31(R0), (R1, R2) // 1b7c00d1610b40a9
|
||||
LDP -4(R0), (R1, R2) // 1b1000d1610b40a9
|
||||
LDP -8(R0), (R1, R2) // 01887fa9
|
||||
LDP x(SB), (R1, R2)
|
||||
LDP x+8(SB), (R1, R2)
|
||||
LDPW -5(R0), (R1, R2) // 1b1400d1610b4029
|
||||
LDPW (R0), (R1, R2) // 01084029
|
||||
LDPW 4(R0), (R1, R2) // 01884029
|
||||
LDPW -4(R0), (R1, R2) // 01887f29
|
||||
|
|
@ -579,6 +583,7 @@ again:
|
|||
STP.W (R3, R4), 8(R5) // a39080a9
|
||||
STP.P (R3, R4), 8(R5) // a39080a8
|
||||
STP (R3, R4), -8(R5) // a3903fa9
|
||||
STP (R3, R4), -4(R5) // bb1000d1631300a9
|
||||
STP (R3, R4), 11(R0) // 1b2c0091631300a9
|
||||
STP (R3, R4), 1024(R0) // 1b001091631300a9
|
||||
STP (R3, R4), (RSP) // e31300a9
|
||||
|
|
@ -595,6 +600,7 @@ again:
|
|||
STPW.W (R3, R4), 4(R5) // a3908029
|
||||
STPW.P (R3, R4), 4(R5) // a3908028
|
||||
STPW (R3, R4), -4(R5) // a3903f29
|
||||
STPW (R3, R4), -5(R5) // bb1400d163130029
|
||||
STPW (R3, R4), 11(R0) // 1b2c009163130029
|
||||
STPW (R3, R4), 1024(R0) // 1b00109163130029
|
||||
STPW (R3, R4), (RSP) // e3130029
|
||||
|
|
|
|||
|
|
@ -425,8 +425,11 @@ const (
|
|||
C_LBRA
|
||||
|
||||
C_ZAUTO // 0(RSP)
|
||||
C_NPAUTO // -512 <= x < 0, 0 mod 8
|
||||
C_NSAUTO_8 // -256 <= x < 0, 0 mod 8
|
||||
C_NSAUTO_4 // -256 <= x < 0, 0 mod 4
|
||||
C_NSAUTO // -256 <= x < 0
|
||||
C_NPAUTO // -512 <= x < 0, 0 mod 8
|
||||
C_NAUTO4K // -4095 <= x < 0
|
||||
C_PSAUTO_8 // 0 to 255, 0 mod 8
|
||||
C_PSAUTO_4 // 0 to 255, 0 mod 4
|
||||
C_PSAUTO // 0 to 255
|
||||
|
|
@ -450,9 +453,12 @@ const (
|
|||
C_SEXT16 // 0 to 65520
|
||||
C_LEXT
|
||||
|
||||
C_ZOREG // 0(R)
|
||||
C_NPOREG // must mirror NPAUTO, etc
|
||||
C_ZOREG // 0(R)
|
||||
C_NSOREG_8 // must mirror C_NSAUTO_8, etc
|
||||
C_NSOREG_4
|
||||
C_NSOREG
|
||||
C_NPOREG
|
||||
C_NOREG4K
|
||||
C_PSOREG_8
|
||||
C_PSOREG_4
|
||||
C_PSOREG
|
||||
|
|
|
|||
|
|
@ -37,8 +37,11 @@ var cnames7 = []string{
|
|||
"SBRA",
|
||||
"LBRA",
|
||||
"ZAUTO",
|
||||
"NPAUTO",
|
||||
"NSAUTO_8",
|
||||
"NSAUTO_4",
|
||||
"NSAUTO",
|
||||
"NPAUTO",
|
||||
"NAUTO4K",
|
||||
"PSAUTO_8",
|
||||
"PSAUTO_4",
|
||||
"PSAUTO",
|
||||
|
|
@ -61,8 +64,11 @@ var cnames7 = []string{
|
|||
"SEXT16",
|
||||
"LEXT",
|
||||
"ZOREG",
|
||||
"NPOREG",
|
||||
"NSOREG_8",
|
||||
"NSOREG_4",
|
||||
"NSOREG",
|
||||
"NPOREG",
|
||||
"NOREG4K",
|
||||
"PSOREG_8",
|
||||
"PSOREG_4",
|
||||
"PSOREG",
|
||||
|
|
|
|||
|
|
@ -473,6 +473,9 @@ var optab = []Optab{
|
|||
{ALDP, C_UAUTO4K, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0},
|
||||
{ALDP, C_UAUTO4K, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPRE},
|
||||
{ALDP, C_UAUTO4K, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPOST},
|
||||
{ALDP, C_NAUTO4K, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0},
|
||||
{ALDP, C_NAUTO4K, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPRE},
|
||||
{ALDP, C_NAUTO4K, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPOST},
|
||||
{ALDP, C_LAUTO, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, 0},
|
||||
{ALDP, C_LAUTO, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, C_XPRE},
|
||||
{ALDP, C_LAUTO, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, C_XPOST},
|
||||
|
|
@ -485,6 +488,9 @@ var optab = []Optab{
|
|||
{ALDP, C_UOREG4K, C_NONE, C_PAIR, 74, 8, 0, 0, 0},
|
||||
{ALDP, C_UOREG4K, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPRE},
|
||||
{ALDP, C_UOREG4K, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPOST},
|
||||
{ALDP, C_NOREG4K, C_NONE, C_PAIR, 74, 8, 0, 0, 0},
|
||||
{ALDP, C_NOREG4K, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPRE},
|
||||
{ALDP, C_NOREG4K, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPOST},
|
||||
{ALDP, C_LOREG, C_NONE, C_PAIR, 75, 12, 0, LFROM, 0},
|
||||
{ALDP, C_LOREG, C_NONE, C_PAIR, 75, 12, 0, LFROM, C_XPRE},
|
||||
{ALDP, C_LOREG, C_NONE, C_PAIR, 75, 12, 0, LFROM, C_XPOST},
|
||||
|
|
@ -499,6 +505,9 @@ var optab = []Optab{
|
|||
{ASTP, C_PAIR, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, 0},
|
||||
{ASTP, C_PAIR, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, C_XPRE},
|
||||
{ASTP, C_PAIR, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, C_XPOST},
|
||||
{ASTP, C_PAIR, C_NONE, C_NAUTO4K, 76, 12, REGSP, 0, 0},
|
||||
{ASTP, C_PAIR, C_NONE, C_NAUTO4K, 76, 12, REGSP, 0, C_XPRE},
|
||||
{ASTP, C_PAIR, C_NONE, C_NAUTO4K, 76, 12, REGSP, 0, C_XPOST},
|
||||
{ASTP, C_PAIR, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, 0},
|
||||
{ASTP, C_PAIR, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, C_XPRE},
|
||||
{ASTP, C_PAIR, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, C_XPOST},
|
||||
|
|
@ -511,59 +520,74 @@ var optab = []Optab{
|
|||
{ASTP, C_PAIR, C_NONE, C_UOREG4K, 76, 8, 0, 0, 0},
|
||||
{ASTP, C_PAIR, C_NONE, C_UOREG4K, 76, 8, 0, 0, C_XPRE},
|
||||
{ASTP, C_PAIR, C_NONE, C_UOREG4K, 76, 8, 0, 0, C_XPOST},
|
||||
{ASTP, C_PAIR, C_NONE, C_NOREG4K, 76, 8, 0, 0, 0},
|
||||
{ASTP, C_PAIR, C_NONE, C_NOREG4K, 76, 8, 0, 0, C_XPRE},
|
||||
{ASTP, C_PAIR, C_NONE, C_NOREG4K, 76, 8, 0, 0, C_XPOST},
|
||||
{ASTP, C_PAIR, C_NONE, C_LOREG, 77, 12, 0, LTO, 0},
|
||||
{ASTP, C_PAIR, C_NONE, C_LOREG, 77, 12, 0, LTO, C_XPRE},
|
||||
{ASTP, C_PAIR, C_NONE, C_LOREG, 77, 12, 0, LTO, C_XPOST},
|
||||
{ASTP, C_PAIR, C_NONE, C_ADDR, 87, 12, 0, 0, 0},
|
||||
|
||||
// differ from LDP/STP for C_NSAUTO_4/C_PSAUTO_4/C_NSOREG_4/C_PSOREG_4
|
||||
{ALDPW, C_NSAUTO, C_NONE, C_PAIR, 66, 4, REGSP, 0, 0},
|
||||
{ALDPW, C_NSAUTO, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPRE},
|
||||
{ALDPW, C_NSAUTO, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPOST},
|
||||
{ALDPW, C_NSAUTO_4, C_NONE, C_PAIR, 66, 4, REGSP, 0, 0},
|
||||
{ALDPW, C_NSAUTO_4, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPRE},
|
||||
{ALDPW, C_NSAUTO_4, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPOST},
|
||||
{ALDPW, C_PSAUTO_4, C_NONE, C_PAIR, 66, 4, REGSP, 0, 0},
|
||||
{ALDPW, C_PSAUTO_4, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPRE},
|
||||
{ALDPW, C_PSAUTO_4, C_NONE, C_PAIR, 66, 4, REGSP, 0, C_XPOST},
|
||||
{ALDPW, C_UAUTO4K, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0},
|
||||
{ALDPW, C_UAUTO4K, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPRE},
|
||||
{ALDPW, C_UAUTO4K, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPOST},
|
||||
{ALDPW, C_NAUTO4K, C_NONE, C_PAIR, 74, 8, REGSP, 0, 0},
|
||||
{ALDPW, C_NAUTO4K, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPRE},
|
||||
{ALDPW, C_NAUTO4K, C_NONE, C_PAIR, 74, 8, REGSP, 0, C_XPOST},
|
||||
{ALDPW, C_LAUTO, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, 0},
|
||||
{ALDPW, C_LAUTO, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, C_XPRE},
|
||||
{ALDPW, C_LAUTO, C_NONE, C_PAIR, 75, 12, REGSP, LFROM, C_XPOST},
|
||||
{ALDPW, C_NSOREG, C_NONE, C_PAIR, 66, 4, 0, 0, 0},
|
||||
{ALDPW, C_NSOREG, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE},
|
||||
{ALDPW, C_NSOREG, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST},
|
||||
{ALDPW, C_NSOREG_4, C_NONE, C_PAIR, 66, 4, 0, 0, 0},
|
||||
{ALDPW, C_NSOREG_4, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE},
|
||||
{ALDPW, C_NSOREG_4, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST},
|
||||
{ALDPW, C_PSOREG_4, C_NONE, C_PAIR, 66, 4, 0, 0, 0},
|
||||
{ALDPW, C_PSOREG_4, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE},
|
||||
{ALDPW, C_PSOREG_4, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST},
|
||||
{ALDPW, C_UOREG4K, C_NONE, C_PAIR, 74, 8, 0, 0, 0},
|
||||
{ALDPW, C_UOREG4K, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPRE},
|
||||
{ALDPW, C_UOREG4K, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPOST},
|
||||
{ALDPW, C_NOREG4K, C_NONE, C_PAIR, 74, 8, 0, 0, 0},
|
||||
{ALDPW, C_NOREG4K, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPRE},
|
||||
{ALDPW, C_NOREG4K, C_NONE, C_PAIR, 74, 8, 0, 0, C_XPOST},
|
||||
{ALDPW, C_LOREG, C_NONE, C_PAIR, 75, 12, 0, LFROM, 0},
|
||||
{ALDPW, C_LOREG, C_NONE, C_PAIR, 75, 12, 0, LFROM, C_XPRE},
|
||||
{ALDPW, C_LOREG, C_NONE, C_PAIR, 75, 12, 0, LFROM, C_XPOST},
|
||||
{ALDPW, C_ADDR, C_NONE, C_PAIR, 88, 12, 0, 0, 0},
|
||||
|
||||
{ASTPW, C_PAIR, C_NONE, C_NSAUTO, 67, 4, REGSP, 0, 0},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NSAUTO, 67, 4, REGSP, 0, C_XPRE},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NSAUTO, 67, 4, REGSP, 0, C_XPOST},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NSAUTO_4, 67, 4, REGSP, 0, 0},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NSAUTO_4, 67, 4, REGSP, 0, C_XPRE},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NSAUTO_4, 67, 4, REGSP, 0, C_XPOST},
|
||||
{ASTPW, C_PAIR, C_NONE, C_PSAUTO_4, 67, 4, REGSP, 0, 0},
|
||||
{ASTPW, C_PAIR, C_NONE, C_PSAUTO_4, 67, 4, REGSP, 0, C_XPRE},
|
||||
{ASTPW, C_PAIR, C_NONE, C_PSAUTO_4, 67, 4, REGSP, 0, C_XPOST},
|
||||
{ASTPW, C_PAIR, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, 0},
|
||||
{ASTPW, C_PAIR, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, C_XPRE},
|
||||
{ASTPW, C_PAIR, C_NONE, C_UAUTO4K, 76, 8, REGSP, 0, C_XPOST},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NAUTO4K, 76, 12, REGSP, 0, 0},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NAUTO4K, 76, 12, REGSP, 0, C_XPRE},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NAUTO4K, 76, 12, REGSP, 0, C_XPOST},
|
||||
{ASTPW, C_PAIR, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, 0},
|
||||
{ASTPW, C_PAIR, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, C_XPRE},
|
||||
{ASTPW, C_PAIR, C_NONE, C_LAUTO, 77, 12, REGSP, LTO, C_XPOST},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NSOREG, 67, 4, 0, 0, 0},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NSOREG, 67, 4, 0, 0, C_XPRE},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NSOREG, 67, 4, 0, 0, C_XPOST},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NSOREG_4, 67, 4, 0, 0, 0},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NSOREG_4, 67, 4, 0, 0, C_XPRE},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NSOREG_4, 67, 4, 0, 0, C_XPOST},
|
||||
{ASTPW, C_PAIR, C_NONE, C_PSOREG_4, 67, 4, 0, 0, 0},
|
||||
{ASTPW, C_PAIR, C_NONE, C_PSOREG_4, 67, 4, 0, 0, C_XPRE},
|
||||
{ASTPW, C_PAIR, C_NONE, C_PSOREG_4, 67, 4, 0, 0, C_XPOST},
|
||||
{ASTPW, C_PAIR, C_NONE, C_UOREG4K, 76, 8, 0, 0, 0},
|
||||
{ASTPW, C_PAIR, C_NONE, C_UOREG4K, 76, 8, 0, 0, C_XPRE},
|
||||
{ASTPW, C_PAIR, C_NONE, C_UOREG4K, 76, 8, 0, 0, C_XPOST},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NOREG4K, 76, 8, 0, 0, 0},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NOREG4K, 76, 8, 0, 0, C_XPRE},
|
||||
{ASTPW, C_PAIR, C_NONE, C_NOREG4K, 76, 8, 0, 0, C_XPOST},
|
||||
{ASTPW, C_PAIR, C_NONE, C_LOREG, 77, 12, 0, LTO, 0},
|
||||
{ASTPW, C_PAIR, C_NONE, C_LOREG, 77, 12, 0, LTO, C_XPRE},
|
||||
{ASTPW, C_PAIR, C_NONE, C_LOREG, 77, 12, 0, LTO, C_XPOST},
|
||||
|
|
@ -996,8 +1020,11 @@ func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) {
|
|||
C_UAUTO16K_8,
|
||||
C_UAUTO16K,
|
||||
C_UAUTO32K,
|
||||
C_NSAUTO_8,
|
||||
C_NSAUTO_4,
|
||||
C_NSAUTO,
|
||||
C_NPAUTO,
|
||||
C_NAUTO4K,
|
||||
C_LAUTO,
|
||||
C_PPOREG,
|
||||
C_PSOREG,
|
||||
|
|
@ -1013,8 +1040,11 @@ func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) {
|
|||
C_UOREG16K_8,
|
||||
C_UOREG16K,
|
||||
C_UOREG32K,
|
||||
C_NSOREG_8,
|
||||
C_NSOREG_4,
|
||||
C_NSOREG,
|
||||
C_NPOREG,
|
||||
C_NOREG4K,
|
||||
C_LOREG,
|
||||
C_LACON,
|
||||
C_LCON,
|
||||
|
|
@ -1221,12 +1251,21 @@ func autoclass(l int64) int {
|
|||
}
|
||||
|
||||
if l < 0 {
|
||||
if l >= -256 && (l&7) == 0 {
|
||||
return C_NSAUTO_8
|
||||
}
|
||||
if l >= -256 && (l&3) == 0 {
|
||||
return C_NSAUTO_4
|
||||
}
|
||||
if l >= -256 {
|
||||
return C_NSAUTO
|
||||
}
|
||||
if l >= -512 && (l&7) == 0 {
|
||||
return C_NPAUTO
|
||||
}
|
||||
if l >= -4095 {
|
||||
return C_NAUTO4K
|
||||
}
|
||||
return C_LAUTO
|
||||
}
|
||||
|
||||
|
|
@ -1649,63 +1688,113 @@ func cmp(a int, b int) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
case C_NSAUTO_4:
|
||||
if b == C_NSAUTO_8 {
|
||||
return true
|
||||
}
|
||||
|
||||
case C_NSAUTO:
|
||||
switch b {
|
||||
case C_NSAUTO_4, C_NSAUTO_8:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_NPAUTO:
|
||||
switch b {
|
||||
case C_NSAUTO_8:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_NAUTO4K:
|
||||
switch b {
|
||||
case C_NSAUTO_8, C_NSAUTO_4, C_NSAUTO, C_NPAUTO:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_PSAUTO_8:
|
||||
if b == C_ZAUTO {
|
||||
return true
|
||||
}
|
||||
|
||||
case C_PSAUTO_4:
|
||||
if b == C_ZAUTO || b == C_PSAUTO_8 {
|
||||
switch b {
|
||||
case C_ZAUTO, C_PSAUTO_8:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_PSAUTO:
|
||||
if b == C_ZAUTO || b == C_PSAUTO_8 || b == C_PSAUTO_4 {
|
||||
switch b {
|
||||
case C_ZAUTO, C_PSAUTO_8, C_PSAUTO_4:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_PPAUTO:
|
||||
if b == C_ZAUTO || b == C_PSAUTO_8 {
|
||||
switch b {
|
||||
case C_ZAUTO, C_PSAUTO_8:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_UAUTO4K:
|
||||
switch b {
|
||||
case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PPAUTO, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8:
|
||||
case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8,
|
||||
C_PPAUTO, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_UAUTO8K:
|
||||
switch b {
|
||||
case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PPAUTO, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO8K_4, C_UAUTO8K_8:
|
||||
case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PPAUTO,
|
||||
C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO8K_4, C_UAUTO8K_8:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_UAUTO16K:
|
||||
switch b {
|
||||
case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PPAUTO, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO16K_8:
|
||||
case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PPAUTO,
|
||||
C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO16K_8:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_UAUTO32K:
|
||||
switch b {
|
||||
case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PPAUTO, C_UAUTO4K_8, C_UAUTO8K_8, C_UAUTO16K_8:
|
||||
case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8,
|
||||
C_PPAUTO, C_UAUTO4K_8, C_UAUTO8K_8, C_UAUTO16K_8:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_NPAUTO:
|
||||
return cmp(C_NSAUTO, b)
|
||||
|
||||
case C_LAUTO:
|
||||
switch b {
|
||||
case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PPAUTO,
|
||||
case C_ZAUTO, C_NSAUTO, C_NSAUTO_4, C_NSAUTO_8, C_NPAUTO,
|
||||
C_NAUTO4K, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PPAUTO,
|
||||
C_UAUTO4K, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8,
|
||||
C_UAUTO8K, C_UAUTO8K_4, C_UAUTO8K_8,
|
||||
C_UAUTO16K, C_UAUTO16K_8,
|
||||
C_UAUTO32K:
|
||||
return true
|
||||
}
|
||||
return cmp(C_NPAUTO, b)
|
||||
|
||||
case C_NSOREG_4:
|
||||
if b == C_NSOREG_8 {
|
||||
return true
|
||||
}
|
||||
|
||||
case C_NSOREG:
|
||||
switch b {
|
||||
case C_NSOREG_4, C_NSOREG_8:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_NPOREG:
|
||||
switch b {
|
||||
case C_NSOREG_8:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_NOREG4K:
|
||||
switch b {
|
||||
case C_NSOREG_8, C_NSOREG_4, C_NSOREG, C_NPOREG:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_PSOREG_4:
|
||||
switch b {
|
||||
|
|
@ -1727,41 +1816,44 @@ func cmp(a int, b int) bool {
|
|||
|
||||
case C_UOREG4K:
|
||||
switch b {
|
||||
case C_ZOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG, C_PPOREG, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8:
|
||||
case C_ZOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG,
|
||||
C_PPOREG, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_UOREG8K:
|
||||
switch b {
|
||||
case C_ZOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG, C_PPOREG, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG8K_4, C_UOREG8K_8:
|
||||
case C_ZOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG,
|
||||
C_PPOREG, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8,
|
||||
C_UOREG8K_4, C_UOREG8K_8:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_UOREG16K:
|
||||
switch b {
|
||||
case C_ZOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG, C_PPOREG, C_UOREG4K_4, C_UOREG4K_8, C_UOREG8K_4, C_UOREG8K_8, C_UOREG16K_8:
|
||||
case C_ZOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG,
|
||||
C_PPOREG, C_UOREG4K_4, C_UOREG4K_8, C_UOREG8K_4,
|
||||
C_UOREG8K_8, C_UOREG16K_8:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_UOREG32K:
|
||||
switch b {
|
||||
case C_ZOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG, C_PPOREG, C_UOREG4K_8, C_UOREG8K_8, C_UOREG16K_8:
|
||||
case C_ZOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG,
|
||||
C_PPOREG, C_UOREG4K_8, C_UOREG8K_8, C_UOREG16K_8:
|
||||
return true
|
||||
}
|
||||
|
||||
case C_NPOREG:
|
||||
return cmp(C_NSOREG, b)
|
||||
|
||||
case C_LOREG:
|
||||
switch b {
|
||||
case C_ZOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG, C_PPOREG,
|
||||
case C_ZOREG, C_NSOREG, C_NSOREG_4, C_NSOREG_8, C_NPOREG,
|
||||
C_NOREG4K, C_PSOREG_4, C_PSOREG_8, C_PSOREG, C_PPOREG,
|
||||
C_UOREG4K, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8,
|
||||
C_UOREG8K, C_UOREG8K_4, C_UOREG8K_8,
|
||||
C_UOREG16K, C_UOREG16K_8,
|
||||
C_UOREG32K:
|
||||
return true
|
||||
}
|
||||
return cmp(C_NPOREG, b)
|
||||
|
||||
case C_LBRA:
|
||||
if b == C_SBRA {
|
||||
|
|
@ -3614,20 +3706,29 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
|
|||
o1 |= (uint32(imm5&0x1f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31)
|
||||
|
||||
case 74:
|
||||
// add $O, R, Rtmp
|
||||
// add $O, R, Rtmp or sub $O, R, Rtmp
|
||||
// ldp (Rtmp), (R1, R2)
|
||||
r := int(p.From.Reg)
|
||||
if r == obj.REG_NONE {
|
||||
r = int(o.param)
|
||||
}
|
||||
if r == obj.REG_NONE {
|
||||
c.ctxt.Diag("invalid ldp source: %v\n", p)
|
||||
c.ctxt.Diag("invalid ldp source: %v", p)
|
||||
}
|
||||
v := int32(c.regoff(&p.From))
|
||||
if v < 0 || v > 4095 {
|
||||
c.ctxt.Diag("offset out of range%v\n", p)
|
||||
|
||||
if v > 0 {
|
||||
if v > 4095 {
|
||||
c.ctxt.Diag("offset out of range: %v", p)
|
||||
}
|
||||
o1 = c.oaddi(p, int32(c.opirr(p, AADD)), v, r, REGTMP)
|
||||
}
|
||||
if v < 0 {
|
||||
if v < -4095 {
|
||||
c.ctxt.Diag("offset out of range: %v", p)
|
||||
}
|
||||
o1 = c.oaddi(p, int32(c.opirr(p, ASUB)), -v, r, REGTMP)
|
||||
}
|
||||
o1 = c.oaddi(p, int32(c.opirr(p, AADD)), v, r, REGTMP)
|
||||
o2 |= c.opldpstp(p, o, 0, uint32(REGTMP), uint32(p.To.Reg), uint32(p.To.Offset), 1)
|
||||
|
||||
case 75:
|
||||
|
|
@ -3639,7 +3740,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
|
|||
r = int(o.param)
|
||||
}
|
||||
if r == obj.REG_NONE {
|
||||
c.ctxt.Diag("invalid ldp source: %v\n", p)
|
||||
c.ctxt.Diag("invalid ldp source: %v", p)
|
||||
}
|
||||
o1 = c.omovlit(AMOVD, p, &p.From, REGTMP)
|
||||
o2 = c.opxrrr(p, AADD, false)
|
||||
|
|
@ -3649,20 +3750,28 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
|
|||
o3 |= c.opldpstp(p, o, 0, uint32(REGTMP), uint32(p.To.Reg), uint32(p.To.Offset), 1)
|
||||
|
||||
case 76:
|
||||
// add $O, R, Rtmp
|
||||
// add $O, R, Rtmp or sub $O, R, Rtmp
|
||||
// stp (R1, R2), (Rtmp)
|
||||
r := int(p.To.Reg)
|
||||
if r == obj.REG_NONE {
|
||||
r = int(o.param)
|
||||
}
|
||||
if r == obj.REG_NONE {
|
||||
c.ctxt.Diag("invalid stp destination: %v\n", p)
|
||||
c.ctxt.Diag("invalid stp destination: %v", p)
|
||||
}
|
||||
v := int32(c.regoff(&p.To))
|
||||
if v < 0 || v > 4095 {
|
||||
c.ctxt.Diag("offset out of range%v\n", p)
|
||||
if v > 0 {
|
||||
if v > 4095 {
|
||||
c.ctxt.Diag("offset out of range: %v", p)
|
||||
}
|
||||
o1 = c.oaddi(p, int32(c.opirr(p, AADD)), v, r, REGTMP)
|
||||
}
|
||||
if v < 0 {
|
||||
if v < -4095 {
|
||||
c.ctxt.Diag("offset out of range: %v", p)
|
||||
}
|
||||
o1 = c.oaddi(p, int32(c.opirr(p, ASUB)), -v, r, REGTMP)
|
||||
}
|
||||
o1 = c.oaddi(p, int32(c.opirr(p, AADD)), v, r, REGTMP)
|
||||
o2 |= c.opldpstp(p, o, 0, uint32(REGTMP), uint32(p.From.Reg), uint32(p.From.Offset), 0)
|
||||
|
||||
case 77:
|
||||
|
|
@ -3674,7 +3783,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
|
|||
r = int(o.param)
|
||||
}
|
||||
if r == obj.REG_NONE {
|
||||
c.ctxt.Diag("invalid stp destination: %v\n", p)
|
||||
c.ctxt.Diag("invalid stp destination: %v", p)
|
||||
}
|
||||
o1 = c.omovlit(AMOVD, p, &p.To, REGTMP)
|
||||
o2 = c.opxrrr(p, AADD, false)
|
||||
|
|
|
|||
Loading…
Reference in New Issue