1
0
mirror of https://github.com/golang/go synced 2024-10-02 16:28:34 -06:00

cmd/internal/obj/arm: support new arm instructions

There are two changes in this CL.

1. Add new forms of MOVH/MOVHS/MOVHU.
   MOVHS R0<<0(R1), R2   // ldrsh
   MOVH  R0<<0(R1), R2   // ldrsh
   MOVHU R0<<0(R1), R2   // ldrh
   MOVHS R2, R5<<0(R1)   // strh
   MOVH  R2, R5<<0(R1)   // strh
   MOVHU R2, R5<<0(R1)   // strh

2. Simpify "MVN $0xffffffaa, Rn" to "MOVW $0x55, Rn".
   It is originally assembled to two instructions.
   "MOVW offset(PC), R11"
   "MVN R11, Rn"

Change-Id: I8e863dcfb2bd8f21a04c5d627fa7beec0afe65fb
Reviewed-on: https://go-review.googlesource.com/53690
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:
Ben Shi 2017-08-08 08:14:24 +00:00 committed by Cherry Zhang
parent 310be7be5c
commit 75cb22cb2f
2 changed files with 68 additions and 4 deletions

View File

@ -1106,8 +1106,8 @@ jmp_label_3:
MVN.S R9>>R8, R7 // 3978f0e1 MVN.S R9>>R8, R7 // 3978f0e1
MVN.S R9->R8, R7 // 5978f0e1 MVN.S R9->R8, R7 // 5978f0e1
MVN.S R9@>R8, R7 // 7978f0e1 MVN.S R9@>R8, R7 // 7978f0e1
MVN $0xffffffae, R5 // MVN $4294967214, R5 // 51b0e0e30b50e0e1 MVN $0xffffffbe, R5 // MVN $4294967230, R5 // 4150a0e3
MVN.S $0xffffffae, R5 // MVN.S $4294967214, R5 // 51b0e0e30b50f0e1 MVN.S $0xffffffbf, R5 // MVN.S $4294967231, R5 // 4050b0e3
// MOVM // MOVM
MOVM.IA [R0,R2,R4,R6], (R1) // MOVM.U [R0,R2,R4,R6], (R1) // 550081e8 MOVM.IA [R0,R2,R4,R6], (R1) // MOVM.U [R0,R2,R4,R6], (R1) // 550081e8
@ -1490,6 +1490,30 @@ jmp_label_3:
MOVHS math·Exp(SB), R0 // MOVHS math.Exp(SB), R0 MOVHS math·Exp(SB), R0 // MOVHS math.Exp(SB), R0
MOVHU R0, math·Exp(SB) // MOVHU R0, math.Exp(SB) MOVHU R0, math·Exp(SB) // MOVHU R0, math.Exp(SB)
MOVHU math·Exp(SB), R0 // MOVHU math.Exp(SB), R0 MOVHU math·Exp(SB), R0 // MOVHU math.Exp(SB), R0
MOVHS R0<<0(R1), R2 // f02091e1
MOVHS.U R0<<0(R1), R2 // f02011e1
MOVHS.W R0<<0(R1), R2 // f020b1e1
MOVHS.P R0<<0(R1), R2 // f02091e0
MOVH R0<<0(R1), R2 // f02091e1
MOVH.U R0<<0(R1), R2 // f02011e1
MOVH.W R0<<0(R1), R2 // f020b1e1
MOVH.P R0<<0(R1), R2 // f02091e0
MOVHU R0<<0(R1), R2 // b02091e1
MOVHU.U R0<<0(R1), R2 // b02011e1
MOVHU.W R0<<0(R1), R2 // b020b1e1
MOVHU.P R0<<0(R1), R2 // b02091e0
MOVHS R2, R5<<0(R1) // b52081e1
MOVHS.U R2, R5<<0(R1) // b52001e1
MOVHS.W R2, R5<<0(R1) // b520a1e1
MOVHS.P R2, R5<<0(R1) // b52081e0
MOVH R2, R5<<0(R1) // b52081e1
MOVH.U R2, R5<<0(R1) // b52001e1
MOVH.W R2, R5<<0(R1) // b520a1e1
MOVH.P R2, R5<<0(R1) // b52081e0
MOVHU R2, R5<<0(R1) // b52081e1
MOVHU.U R2, R5<<0(R1) // b52001e1
MOVHU.W R2, R5<<0(R1) // b520a1e1
MOVHU.P R2, R5<<0(R1) // b52081e0
// //
// END // END

View File

@ -137,13 +137,13 @@ var optab = []Optab{
{AMOVW, C_SCON, C_NONE, C_REG, 12, 4, 0, 0, 0}, {AMOVW, C_SCON, C_NONE, C_REG, 12, 4, 0, 0, 0},
{AMOVW, C_LCON, C_NONE, C_REG, 12, 4, 0, LFROM, 0}, {AMOVW, C_LCON, C_NONE, C_REG, 12, 4, 0, LFROM, 0},
{AMOVW, C_LCONADDR, C_NONE, C_REG, 12, 4, 0, LFROM | LPCREL, 4}, {AMOVW, C_LCONADDR, C_NONE, C_REG, 12, 4, 0, LFROM | LPCREL, 4},
{AMVN, C_NCON, C_NONE, C_REG, 12, 4, 0, 0, 0},
{AADD, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0}, {AADD, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0},
{AADD, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0}, {AADD, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0},
{AAND, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0}, {AAND, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0},
{AAND, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0}, {AAND, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0},
{AORR, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0}, {AORR, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0},
{AORR, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0}, {AORR, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0},
{AMVN, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0},
{ACMP, C_NCON, C_REG, C_NONE, 13, 8, 0, 0, 0}, {ACMP, C_NCON, C_REG, C_NONE, 13, 8, 0, 0, 0},
{AADD, C_SCON, C_REG, C_REG, 13, 8, 0, 0, 0}, {AADD, C_SCON, C_REG, C_REG, 13, 8, 0, 0, 0},
{AADD, C_SCON, C_NONE, C_REG, 13, 8, 0, 0, 0}, {AADD, C_SCON, C_NONE, C_REG, 13, 8, 0, 0, 0},
@ -240,10 +240,16 @@ var optab = []Optab{
{AMOVBU, C_SHIFT, C_NONE, C_REG, 59, 4, 0, 0, 0}, {AMOVBU, C_SHIFT, C_NONE, C_REG, 59, 4, 0, 0, 0},
{AMOVB, C_SHIFT, C_NONE, C_REG, 60, 4, 0, 0, 0}, {AMOVB, C_SHIFT, C_NONE, C_REG, 60, 4, 0, 0, 0},
{AMOVBS, C_SHIFT, C_NONE, C_REG, 60, 4, 0, 0, 0}, {AMOVBS, C_SHIFT, C_NONE, C_REG, 60, 4, 0, 0, 0},
{AMOVH, C_SHIFT, C_NONE, C_REG, 60, 4, 0, 0, 0},
{AMOVHS, C_SHIFT, C_NONE, C_REG, 60, 4, 0, 0, 0},
{AMOVHU, C_SHIFT, C_NONE, C_REG, 60, 4, 0, 0, 0},
{AMOVW, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0}, {AMOVW, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0},
{AMOVB, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0}, {AMOVB, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0},
{AMOVBS, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0}, {AMOVBS, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0},
{AMOVBU, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0}, {AMOVBU, C_REG, C_NONE, C_SHIFT, 61, 4, 0, 0, 0},
{AMOVH, C_REG, C_NONE, C_SHIFT, 62, 4, 0, 0, 0},
{AMOVHS, C_REG, C_NONE, C_SHIFT, 62, 4, 0, 0, 0},
{AMOVHU, C_REG, C_NONE, C_SHIFT, 62, 4, 0, 0, 0},
{AMOVH, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0}, {AMOVH, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0},
{AMOVH, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0}, {AMOVH, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0},
{AMOVHS, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0}, {AMOVHS, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0},
@ -1944,6 +1950,8 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
case 12: /* movw $lcon, reg */ case 12: /* movw $lcon, reg */
if o.a1 == C_SCON { if o.a1 == C_SCON {
o1 = c.omvs(p, &p.From, int(p.To.Reg)) o1 = c.omvs(p, &p.From, int(p.To.Reg))
} else if p.As == AMVN {
o1 = c.omvr(p, &p.From, int(p.To.Reg))
} else { } else {
o1 = c.omvl(p, &p.From, int(p.To.Reg)) o1 = c.omvl(p, &p.From, int(p.To.Reg))
} }
@ -2293,7 +2301,13 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
c.ctxt.Diag("bad shift: %v", p) c.ctxt.Diag("bad shift: %v", p)
} }
o1 = c.olhrr(int(p.From.Offset), int(p.From.Reg), int(p.To.Reg), int(p.Scond)) o1 = c.olhrr(int(p.From.Offset), int(p.From.Reg), int(p.To.Reg), int(p.Scond))
switch p.As {
case AMOVB, AMOVBS:
o1 ^= 1<<5 | 1<<6 o1 ^= 1<<5 | 1<<6
case AMOVH, AMOVHS:
o1 ^= 1 << 6
default:
}
if p.Scond&C_UBIT != 0 { if p.Scond&C_UBIT != 0 {
o1 &^= 1 << 23 o1 &^= 1 << 23
} }
@ -2307,6 +2321,19 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
o1 |= 1 << 22 o1 |= 1 << 22
} }
case 62: /* MOVH/MOVHS/MOVHU Reg, Reg<<0(Reg) -> strh */
if p.To.Reg == 0 {
c.ctxt.Diag("MOV to shifter operand")
}
if p.To.Offset&(^0xf) != 0 {
c.ctxt.Diag("bad shift: %v", p)
}
o1 = c.olhrr(int(p.To.Offset), int(p.To.Reg), int(p.From.Reg), int(p.Scond))
o1 ^= 1 << 20
if p.Scond&C_UBIT != 0 {
o1 &^= 1 << 23
}
/* reloc ops */ /* reloc ops */
case 64: /* mov/movb/movbu R,addr */ case 64: /* mov/movb/movbu R,addr */
o1 = c.omvl(p, &p.To, REGTMP) o1 = c.omvl(p, &p.To, REGTMP)
@ -3113,6 +3140,19 @@ func (c *ctxt5) omvs(p *obj.Prog, a *obj.Addr, dr int) uint32 {
return o1 return o1
} }
// MVN $C_NCON, Reg -> MOVW $C_RCON, Reg
func (c *ctxt5) omvr(p *obj.Prog, a *obj.Addr, dr int) uint32 {
o1 := c.oprrr(p, AMOVW, int(p.Scond))
o1 |= (uint32(dr) & 15) << 12
v := immrot(^uint32(a.Offset))
if v == 0 {
c.ctxt.Diag("%v: missing literal", p)
return 0
}
o1 |= uint32(v)
return o1
}
func (c *ctxt5) omvl(p *obj.Prog, a *obj.Addr, dr int) uint32 { func (c *ctxt5) omvl(p *obj.Prog, a *obj.Addr, dr int) uint32 {
var o1 uint32 var o1 uint32
if p.Pcond == nil { if p.Pcond == nil {