]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/arm: add BFC/BFI to arm's assembler
authorBen Shi <powerman1st@163.com>
Tue, 24 Oct 2017 06:32:45 +0000 (06:32 +0000)
committerCherry Zhang <cherryyz@google.com>
Fri, 3 Nov 2017 14:06:21 +0000 (14:06 +0000)
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>
src/cmd/asm/internal/arch/arm.go
src/cmd/asm/internal/asm/testdata/arm.s
src/cmd/asm/internal/asm/testdata/armerror.s
src/cmd/internal/obj/arm/a.out.go
src/cmd/internal/obj/arm/anames.go
src/cmd/internal/obj/arm/asm5.go

index 4ee494a74ca4e499a388ae2e5241aa66988548b8..6e86ac0fbe278acf434ea0053853eac19fe16cf7 100644 (file)
@@ -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
index 319e07c21c3dc3f9ee79e20553c114d0f7af0db9..bc6cf07e83a5a2d11c01e70e4d9cb3f772460168 100644 (file)
@@ -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
index 6ded33d8e43d4d072f10d1f1017266be0bd33667..f2bed8d1c37fab9dc33d396871cfb80cec7530e4 100644 (file)
@@ -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"
index 385937ff6b9d354a5056f2dd44b9cc41c3107508..d4d951023008ab9997ef903eb094feb40ec15e93 100644 (file)
@@ -320,6 +320,8 @@ const (
 
        ABFX
        ABFXU
+       ABFC
+       ABFI
 
        AMULWT
        AMULWB
index 75921f45800305504f0894b692b965059d0a4992..cb60eba82457bc893812b188913cb8fb86d22a1c 100644 (file)
@@ -131,6 +131,8 @@ var Anames = []string{
        "XTAHU",
        "BFX",
        "BFXU",
+       "BFC",
+       "BFI",
        "MULWT",
        "MULWB",
        "MULBB",
index 67be8d720a4364a107489ac078ef48182cbff671..0439954fe9e660a0757eb006bd2cfafab5a0d976 100644 (file)
@@ -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
@@ -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)
@@ -2033,12 +2035,14 @@ 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)
@@ -2046,10 +2050,17 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
                }
                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)
@@ -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