Skip to content

Commit

Permalink
cmd/internal/obj/arm: add BFC/BFI to arm's assembler
Browse files Browse the repository at this point in the history
BFC (Bit Field Clear) and BFI (Bit Field Insert) were
introduced in ARMv6T2, and the compiler can use them
to do further optimization.

Change-Id: I5a3fbcd2c2400c9bf4b939da6366c854c744c27f
Reviewed-on: https://go-review.googlesource.com/72891
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
  • Loading branch information
benshi001 authored and cherrymui committed Nov 3, 2017
1 parent 6de5383 commit 1ac8846
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 7 deletions.
5 changes: 3 additions & 2 deletions src/cmd/asm/internal/arch/arm.go
Expand Up @@ -122,10 +122,11 @@ func IsARMMRC(op obj.As) bool {
return false
}

// IsARMBFX reports whether the op is arm.BFX or arm.BFXU
// IsARMBFX reports whether the op (as defined by an arm.A* constant) is one the
// BFX-like instructions which are in the form of "op $width, $LSB, (Reg,) Reg".
func IsARMBFX(op obj.As) bool {
switch op {
case arm.ABFX, arm.ABFXU:
case arm.ABFX, arm.ABFXU, arm.ABFC, arm.ABFI:
return true
}
return false
Expand Down
5 changes: 4 additions & 1 deletion src/cmd/asm/internal/asm/testdata/arm.s
Expand Up @@ -1029,11 +1029,14 @@ jmp_label_3:
SWI $65535 // ffff00ef
SWI // 000000ef

// BFX/BFXU
// BFX/BFXU/BFC/BFI
BFX $16, $8, R1, R2 // BFX $16, R1, $8, R2 // 5124afe7
BFX $29, $2, R8 // 5881bce7
BFXU $16, $8, R1, R2 // BFXU $16, R1, $8, R2 // 5124efe7
BFXU $29, $2, R8 // 5881fce7
BFC $29, $2, R8 // 1f81dee7
BFI $29, $2, R8 // 1881dee7
BFI $16, $8, R1, R2 // BFI $16, R1, $8, R2 // 1124d7e7

// synthetic arithmatic
ADD $0xffffffaa, R2, R3 // ADD $4294967210, R2, R3 // 55b0e0e30b3082e0
Expand Down
1 change: 1 addition & 0 deletions src/cmd/asm/internal/asm/testdata/armerror.s
Expand Up @@ -149,6 +149,7 @@ TEXT errors(SB),$0
BFX $-2, $4, R2, R3 // ERROR "wrong width or LSB"
BFXU $4, R2, R5, R2 // ERROR "missing or wrong LSB"
BFXU $4, R2, R5 // ERROR "missing or wrong LSB"
BFC $12, $8, R2, R3 // ERROR "illegal combination"
MOVB R0>>8, R2 // ERROR "illegal shift"
MOVH R0<<16, R2 // ERROR "illegal shift"
MOVBS R0->8, R2 // ERROR "illegal shift"
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/internal/obj/arm/a.out.go
Expand Up @@ -320,6 +320,8 @@ const (

ABFX
ABFXU
ABFC
ABFI

AMULWT
AMULWB
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/internal/obj/arm/anames.go
Expand Up @@ -131,6 +131,8 @@ var Anames = []string{
"XTAHU",
"BFX",
"BFXU",
"BFC",
"BFI",
"MULWT",
"MULWB",
"MULBB",
Expand Down
25 changes: 21 additions & 4 deletions src/cmd/internal/obj/arm/asm5.go
Expand Up @@ -69,7 +69,7 @@ type Optab struct {
param int16
flag int8
pcrelsiz uint8
scond uint8 // optional flags accepted by the instruction
scond uint8 // optional flags accepted by the instruction
}

type Opcross [32][2][32]uint8
Expand Down Expand Up @@ -1679,6 +1679,8 @@ func buildop(ctxt *obj.Link) {

case ABFX:
opset(ABFXU, r0)
opset(ABFC, r0)
opset(ABFI, r0)

case ACLZ:
opset(AREV, r0)
Expand Down Expand Up @@ -2033,23 +2035,32 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
r := int(p.Reg)
o1 |= (uint32(rf)&15)<<8 | (uint32(r)&15)<<0 | (uint32(rt)&15)<<16 | (uint32(rt2)&15)<<12

case 18: /* BFX/BFXU */
case 18: /* BFX/BFXU/BFC/BFI */
o1 = c.oprrr(p, p.As, int(p.Scond))
rt := int(p.To.Reg)
r := int(p.Reg)
if r == 0 {
r = rt
} else if p.As == ABFC { // only "BFC $width, $lsb, Reg" is accepted, p.Reg must be 0
c.ctxt.Diag("illegal combination: %v", p)
}
if p.GetFrom3() == nil || p.GetFrom3().Type != obj.TYPE_CONST {
c.ctxt.Diag("%v: missing or wrong LSB", p)
break
}
lsb := p.GetFrom3().Offset
width := p.From.Offset
if lsb < 0 || lsb > 31 || width <= 0 || (lsb+width) > 31 {
if lsb < 0 || lsb > 31 || width <= 0 || (lsb+width) > 32 {
c.ctxt.Diag("%v: wrong width or LSB", p)
}
o1 |= (uint32(r)&15)<<0 | (uint32(rt)&15)<<12 | uint32(lsb)<<7 | uint32(width-1)<<16
switch p.As {
case ABFX, ABFXU: // (width-1) is encoded
o1 |= (uint32(r)&15)<<0 | (uint32(rt)&15)<<12 | uint32(lsb)<<7 | uint32(width-1)<<16
case ABFC, ABFI: // MSB is encoded
o1 |= (uint32(r)&15)<<0 | (uint32(rt)&15)<<12 | uint32(lsb)<<7 | uint32(lsb+width-1)<<16
default:
c.ctxt.Diag("illegal combination: %v", p)
}

case 20: /* mov/movb/movbu R,O(R) */
c.aclass(&p.To)
Expand Down Expand Up @@ -3022,6 +3033,12 @@ func (c *ctxt5) oprrr(p *obj.Prog, a obj.As, sc int) uint32 {
case ABFXU:
return o | 0x3f<<21 | 0x5<<4

case ABFC:
return o | 0x3e<<21 | 0x1f

case ABFI:
return o | 0x3e<<21 | 0x1<<4

case AXTAB:
return o | 0x6a<<20 | 0x7<<4

Expand Down

0 comments on commit 1ac8846

Please sign in to comment.