summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Shi <powerman1st@163.com>2017-05-27 10:00:55 +0000
committerCherry Zhang <cherryyz@google.com>2017-06-05 17:03:54 +0000
commitc8ab8c1f99123173aa8840f82f2eb947f7353617 (patch)
treee3773cf8e79459c23ef112610e0dbed526afa1cd
parent3cc2da6397e5ca8efd5d0cf3e919f33bc74dc4b6 (diff)
downloadgo-git-c8ab8c1f99123173aa8840f82f2eb947f7353617.tar.gz
cmd/internal/obj/arm: fix constant decomposition
There are two issues in constant decomposition. 1. A typo in "func immrot2s" blocks "case 107" of []optab be triggered. 2. Though "ADD $0xffff, R0, R0" is decomposed to "ADD $0xff00, R0, R0" and "ADD $0x00ff, R0, R0" as expected, "ADD $0xffff, R0" still uses the constant pool, which should be the same as "ADD $0xffff, R0, R0". This patch fixes them and adds more instruction encoding tests. fix #20516 Change-Id: Icd7bdfa1946b29db15580dcb429111266f1384c6 Reviewed-on: https://go-review.googlesource.com/44335 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
-rw-r--r--src/cmd/asm/internal/asm/testdata/arm.s117
-rw-r--r--src/cmd/internal/obj/arm/asm5.go11
2 files changed, 127 insertions, 1 deletions
diff --git a/src/cmd/asm/internal/asm/testdata/arm.s b/src/cmd/asm/internal/asm/testdata/arm.s
index 1e26075611..30d24ac805 100644
--- a/src/cmd/asm/internal/asm/testdata/arm.s
+++ b/src/cmd/asm/internal/asm/testdata/arm.s
@@ -963,9 +963,13 @@ jmp_label_3:
// MUL
MUL R2, R3, R4 // 930204e0
+ MUL R2, R4 // 920404e0
MUL.S R2, R3, R4 // 930214e0
+ MUL.S R2, R4 // 920414e0
MULU R5, R6, R7 // 960507e0
+ MULU R5, R7 // 950707e0
MULU.S R5, R6, R7 // 960517e0
+ MULU.S R5, R7 // 950717e0
MULLU R1, R2, (R4, R3) // 923184e0
MULLU.S R1, R2, (R4, R3) // 923194e0
MULL R1, R2, (R4, R3) // 9231c4e0
@@ -1003,6 +1007,119 @@ jmp_label_3:
SWI $65535 // ffff00ef
SWI // 000000ef
+// synthetic arithmatic
+ ADD $0xffffffaa, R2, R3 // ADD $4294967210, R2, R3 // 55b0e0e30b3082e0
+ ADD $0xffffff55, R5 // ADD $4294967125, R5 // aab0e0e30b5085e0
+ ADD.S $0xffffffab, R2, R3 // ADD.S $4294967211, R2, R3 // 54b0e0e30b3092e0
+ ADD.S $0xffffff54, R5 // ADD.S $4294967124, R5 // abb0e0e30b5095e0
+ ADC $0xffffffac, R2, R3 // ADC $4294967212, R2, R3 // 53b0e0e30b30a2e0
+ ADC $0xffffff53, R5 // ADC $4294967123, R5 // acb0e0e30b50a5e0
+ ADC.S $0xffffffad, R2, R3 // ADC.S $4294967213, R2, R3 // 52b0e0e30b30b2e0
+ ADC.S $0xffffff52, R5 // ADC.S $4294967122, R5 // adb0e0e30b50b5e0
+ SUB $0xffffffae, R2, R3 // SUB $4294967214, R2, R3 // 51b0e0e30b3042e0
+ SUB $0xffffff51, R5 // SUB $4294967121, R5 // aeb0e0e30b5045e0
+ SUB.S $0xffffffaf, R2, R3 // SUB.S $4294967215, R2, R3 // 50b0e0e30b3052e0
+ SUB.S $0xffffff50, R5 // SUB.S $4294967120, R5 // afb0e0e30b5055e0
+ SBC $0xffffffb0, R2, R3 // SBC $4294967216, R2, R3 // 4fb0e0e30b30c2e0
+ SBC $0xffffff4f, R5 // SBC $4294967119, R5 // b0b0e0e30b50c5e0
+ SBC.S $0xffffffb1, R2, R3 // SBC.S $4294967217, R2, R3 // 4eb0e0e30b30d2e0
+ SBC.S $0xffffff4e, R5 // SBC.S $4294967118, R5 // b1b0e0e30b50d5e0
+ RSB $0xffffffb2, R2, R3 // RSB $4294967218, R2, R3 // 4db0e0e30b3062e0
+ RSB $0xffffff4d, R5 // RSB $4294967117, R5 // b2b0e0e30b5065e0
+ RSB.S $0xffffffb3, R2, R3 // RSB.S $4294967219, R2, R3 // 4cb0e0e30b3072e0
+ RSB.S $0xffffff4c, R5 // RSB.S $4294967116, R5 // b3b0e0e30b5075e0
+ RSC $0xffffffb4, R2, R3 // RSC $4294967220, R2, R3 // 4bb0e0e30b30e2e0
+ RSC $0xffffff4b, R5 // RSC $4294967115, R5 // b4b0e0e30b50e5e0
+ RSC.S $0xffffffb5, R2, R3 // RSC.S $4294967221, R2, R3 // 4ab0e0e30b30f2e0
+ RSC.S $0xffffff4a, R5 // RSC.S $4294967114, R5 // b5b0e0e30b50f5e0
+ AND $0xffffffaa, R2, R3 // AND $4294967210, R2, R3 // 55b0e0e30b3002e0
+ AND $0xffffff55, R5 // AND $4294967125, R5 // aab0e0e30b5005e0
+ AND.S $0xffffffab, R2, R3 // AND.S $4294967211, R2, R3 // 54b0e0e30b3012e0
+ AND.S $0xffffff54, R5 // AND.S $4294967124, R5 // abb0e0e30b5015e0
+ ORR $0xffffffaa, R2, R3 // ORR $4294967210, R2, R3 // 55b0e0e30b3082e1
+ ORR $0xffffff55, R5 // ORR $4294967125, R5 // aab0e0e30b5085e1
+ ORR.S $0xffffffab, R2, R3 // ORR.S $4294967211, R2, R3 // 54b0e0e30b3092e1
+ ORR.S $0xffffff54, R5 // ORR.S $4294967124, R5 // abb0e0e30b5095e1
+ EOR $0xffffffaa, R2, R3 // EOR $4294967210, R2, R3 // 55b0e0e30b3022e0
+ EOR $0xffffff55, R5 // EOR $4294967125, R5 // aab0e0e30b5025e0
+ EOR.S $0xffffffab, R2, R3 // EOR.S $4294967211, R2, R3 // 54b0e0e30b3032e0
+ EOR.S $0xffffff54, R5 // EOR.S $4294967124, R5 // abb0e0e30b5035e0
+ BIC $0xffffffaa, R2, R3 // BIC $4294967210, R2, R3 // 55b0e0e30b30c2e1
+ BIC $0xffffff55, R5 // BIC $4294967125, R5 // aab0e0e30b50c5e1
+ BIC.S $0xffffffab, R2, R3 // BIC.S $4294967211, R2, R3 // 54b0e0e30b30d2e1
+ BIC.S $0xffffff54, R5 // BIC.S $4294967124, R5 // abb0e0e30b50d5e1
+ CMP $0xffffffab, R2 // CMP $4294967211, R2 // 54b0e0e30b0052e1
+ CMN $0xffffffac, R3 // CMN $4294967212, R3 // 53b0e0e30b0073e1
+ TST $0xffffffad, R4 // TST $4294967213, R4 // 52b0e0e30b0014e1
+ TEQ $0xffffffae, R5 // TEQ $4294967214, R5 // 51b0e0e30b0035e1
+
+// immediate decomposition
+ ADD $0xff0000ff, R0, R1 // ADD $4278190335, R0, R1 // ff1080e2ff1481e2
+ EOR $0xff0000ff, R0, R1 // EOR $4278190335, R0, R1 // ff1020e2ff1421e2
+ ORR $0xff0000ff, R0, R1 // ORR $4278190335, R0, R1 // ff1080e3ff1481e3
+ SUB $0xff0000ff, R0, R1 // SUB $4278190335, R0, R1 // ff1040e2ff1441e2
+ BIC $0xff0000ff, R0, R1 // BIC $4278190335, R0, R1 // ff10c0e3ff14c1e3
+ RSB $0xff0000ff, R0, R1 // RSB $4278190335, R0, R1 // ff1060e2ff1481e2
+ ADC $0xff0000ff, R0, R1 // ADC $4278190335, R0, R1 // ff10a0e2ff1481e2
+ SBC $0xff0000ff, R0, R1 // SBC $4278190335, R0, R1 // ff10c0e2ff1441e2
+ RSC $0xff0000ff, R0, R1 // RSC $4278190335, R0, R1 // ff10e0e2ff1481e2
+ ADD $0x000fffff, R0, R1 // ADD $1048575, R0, R1 // 011680e2011041e2
+ ADC $0x000fffff, R0, R1 // ADC $1048575, R0, R1 // 0116a0e2011041e2
+ SUB $0x000fffff, R0, R1 // SUB $1048575, R0, R1 // 011640e2011081e2
+ SBC $0x000fffff, R0, R1 // SBC $1048575, R0, R1 // 0116c0e2011081e2
+ RSB $0x000fffff, R0, R1 // RSB $1048575, R0, R1 // 011660e2011041e2
+ RSC $0x000fffff, R0, R1 // RSC $1048575, R0, R1 // 0116e0e2011041e2
+ ADD $0xff0000ff, R1 // ADD $4278190335, R1 // ff1081e2ff1481e2
+ EOR $0xff0000ff, R1 // EOR $4278190335, R1 // ff1021e2ff1421e2
+ ORR $0xff0000ff, R1 // ORR $4278190335, R1 // ff1081e3ff1481e3
+ SUB $0xff0000ff, R1 // SUB $4278190335, R1 // ff1041e2ff1441e2
+ BIC $0xff0000ff, R1 // BIC $4278190335, R1 // ff10c1e3ff14c1e3
+ RSB $0xff0000ff, R1 // RSB $4278190335, R1 // ff1061e2ff1481e2
+ ADC $0xff0000ff, R1 // ADC $4278190335, R1 // ff10a1e2ff1481e2
+ SBC $0xff0000ff, R1 // SBC $4278190335, R1 // ff10c1e2ff1441e2
+ RSC $0xff0000ff, R1 // RSC $4278190335, R1 // ff10e1e2ff1481e2
+ ADD $0x000fffff, R1 // ADD $1048575, R1 // 011681e2011041e2
+ ADC $0x000fffff, R1 // ADC $1048575, R1 // 0116a1e2011041e2
+ SUB $0x000fffff, R1 // SUB $1048575, R1 // 011641e2011081e2
+ SBC $0x000fffff, R1 // SBC $1048575, R1 // 0116c1e2011081e2
+ RSB $0x000fffff, R1 // RSB $1048575, R1 // 011661e2011041e2
+ RSC $0x000fffff, R1 // RSC $1048575, R1 // 0116e1e2011041e2
+
+// MVN
+ MVN $0xff, R1 // MVN $255, R1 // ff10e0e3
+ MVN $0xff000000, R1 // MVN $4278190080, R1 // ff14e0e3
+ MVN.S $0xff, R1 // MVN.S $255, R1 // ff10f0e3
+ MVN.S $0xff000000, R1 // MVN.S $4278190080, R1 // ff14f0e3
+ MVN R9<<30, R7 // 097fe0e1
+ MVN R9>>30, R7 // 297fe0e1
+ MVN R9->30, R7 // 497fe0e1
+ MVN R9@>30, R7 // 697fe0e1
+ MVN.S R9<<30, R7 // 097ff0e1
+ MVN.S R9>>30, R7 // 297ff0e1
+ MVN.S R9->30, R7 // 497ff0e1
+ MVN.S R9@>30, R7 // 697ff0e1
+ MVN R9<<R8, R7 // 1978e0e1
+ MVN R9>>R8, R7 // 3978e0e1
+ MVN R9->R8, R7 // 5978e0e1
+ MVN R9@>R8, R7 // 7978e0e1
+ MVN.S R9<<R8, R7 // 1978f0e1
+ MVN.S R9>>R8, R7 // 3978f0e1
+ MVN.S R9->R8, R7 // 5978f0e1
+ MVN.S R9@>R8, R7 // 7978f0e1
+ MVN $0xffffffae, R5 // MVN $4294967214, R5 // 51b0e0e30b50e0e1
+ MVN.S $0xffffffae, R5 // MVN.S $4294967214, R5 // 51b0e0e30b50f0e1
+
+// MOVW
+mov_label_0:
+ MOVW $0xff, R9 // MOVW $255, R9 // ff90a0e3
+ MOVW $0xff000000, R9 // MOVW $4278190080, R9 // ff94a0e3
+ MOVW R3, R4 // 0340a0e1
+ MOVW $0xff(R0), R1 // MOVW $255(R0), R1 // ff1080e2
+ MOVW $-0xff(R0), R1 // MOVW $-255(R0), R1 // ff1040e2
+ MOVW $0xffffffae, R1 // MOVW $4294967214, R1 // 5110e0e3
+ MOVW $0xaaaaaaaa, R1 // MOVW $2863311530, R1
+ MOVW $mov_label_0(SB), R2 // MOVW $mov_label_0(SB), R2
+
//
// END
//
diff --git a/src/cmd/internal/obj/arm/asm5.go b/src/cmd/internal/obj/arm/asm5.go
index c27b470817..e17d312987 100644
--- a/src/cmd/internal/obj/arm/asm5.go
+++ b/src/cmd/internal/obj/arm/asm5.go
@@ -154,8 +154,11 @@ var optab = []Optab{
{AMVN, C_SCON, C_NONE, C_REG, 13, 8, 0, 0, 0},
{ACMP, C_SCON, C_REG, C_NONE, 13, 8, 0, 0, 0},
{AADD, C_RCON2A, C_REG, C_REG, 106, 8, 0, 0, 0},
+ {AADD, C_RCON2A, C_NONE, C_REG, 106, 8, 0, 0, 0},
{AORR, C_RCON2A, C_REG, C_REG, 106, 8, 0, 0, 0},
+ {AORR, C_RCON2A, C_NONE, C_REG, 106, 8, 0, 0, 0},
{AADD, C_RCON2S, C_REG, C_REG, 107, 8, 0, 0, 0},
+ {AADD, C_RCON2S, C_NONE, C_REG, 107, 8, 0, 0, 0},
{AADD, C_LCON, C_REG, C_REG, 13, 8, 0, LFROM, 0},
{AADD, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0},
{AAND, C_LCON, C_REG, C_REG, 13, 8, 0, LFROM, 0},
@@ -1063,7 +1066,7 @@ func immrot2a(v uint32) (uint32, uint32) {
// such that the encoded constants y, x satisfy y-x==v, y&x==0.
// Returns 0,0 if no such decomposition of v exists.
func immrot2s(v uint32) (uint32, uint32) {
- if immrot(v) == 0 {
+ if immrot(v) != 0 {
return v, 0
}
// suppose v in the form of {leading 00, upper effective bits, lower 8 effective bits, trailing 00}
@@ -1717,6 +1720,9 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
c.aclass(&p.From)
r := int(p.Reg)
rt := int(p.To.Reg)
+ if r == 0 {
+ r = rt
+ }
x, y := immrot2a(uint32(c.instoffset))
var as2 obj.As
switch p.As {
@@ -1744,6 +1750,9 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
c.aclass(&p.From)
r := int(p.Reg)
rt := int(p.To.Reg)
+ if r == 0 {
+ r = rt
+ }
y, x := immrot2s(uint32(c.instoffset))
var as2 obj.As
switch p.As {