From: fanzha02 Date: Wed, 21 Mar 2018 10:49:24 +0000 (+0000) Subject: cmd/internal/obj/arm64: fix the bug of incorrect handling negative offset of LDP... X-Git-Tag: go1.11beta1~841 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=4d59b14400aff02ded4ccf62a7518266ea8fd767;p=gostls13.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 TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang --- diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s index ec32e0ff34..b5d44ebe50 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64.s +++ b/src/cmd/asm/internal/asm/testdata/arm64.s @@ -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 diff --git a/src/cmd/internal/obj/arm64/a.out.go b/src/cmd/internal/obj/arm64/a.out.go index 3010204109..70cc522a46 100644 --- a/src/cmd/internal/obj/arm64/a.out.go +++ b/src/cmd/internal/obj/arm64/a.out.go @@ -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 diff --git a/src/cmd/internal/obj/arm64/anames7.go b/src/cmd/internal/obj/arm64/anames7.go index a0ff54024a..92f0cec942 100644 --- a/src/cmd/internal/obj/arm64/anames7.go +++ b/src/cmd/internal/obj/arm64/anames7.go @@ -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", diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index 043a16c45a..3f1aee8c2b 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -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)