]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/arm64: refactor the extended/shifted register encoding to the backend
authorfanzha02 <fannie.zhang@arm.com>
Sun, 8 Apr 2018 12:36:30 +0000 (12:36 +0000)
committerCherry Zhang <cherryyz@google.com>
Wed, 18 Apr 2018 19:19:57 +0000 (19:19 +0000)
The current code encodes the register and the shift/extension into a.Offset
field and this is done in the frontend. The CL refactors it to have the
frontend record the register/shift/extension information in a.Reg or a.Index
and leave the encoding stuff for the backend.

Change-Id: I600f456aec95377b7b79cd58e94afcb30aca5d19
Reviewed-on: https://go-review.googlesource.com/106815
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/asm/internal/arch/arm64.go
src/cmd/internal/obj/arm64/asm7.go
src/cmd/internal/obj/util.go

index b311f4c738ff560f53b5f0814c305e5775f2391d..2aadda4b9bb3c4dec5397aa631b35703fe5cce24 100644 (file)
@@ -132,14 +132,8 @@ func arm64RegisterNumber(name string, n int16) (int16, bool) {
        return 0, false
 }
 
-// rm is the Rm register value, o is the extension, amount is the left shift value.
-func roff(rm uint32, o uint32, amount int16) int64 {
-       return int64((rm&31)<<16 | o<<13 | uint32(amount)<<10)
-}
-
 // ARM64RegisterExtension parses an ARM64 register with extension or arrangement.
 func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, isIndex bool) error {
-       rm := uint32(reg)
        Rnum := (reg & 31) + int16(num<<5)
        if isAmount {
                if num < 0 || num > 7 {
@@ -155,7 +149,6 @@ func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, i
                        return errors.New("invalid shift for the register offset addressing mode")
                }
                a.Reg = arm64.REG_UXTB + Rnum
-               a.Offset = roff(rm, 0, num)
        case "UXTH":
                if !isAmount {
                        return errors.New("invalid register extension")
@@ -164,7 +157,6 @@ func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, i
                        return errors.New("invalid shift for the register offset addressing mode")
                }
                a.Reg = arm64.REG_UXTH + Rnum
-               a.Offset = roff(rm, 1, num)
        case "UXTW":
                if !isAmount {
                        return errors.New("invalid register extension")
@@ -172,14 +164,8 @@ func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, i
                // effective address of memory is a base register value and an offset register value.
                if a.Type == obj.TYPE_MEM {
                        a.Index = arm64.REG_UXTW + Rnum
-                       if num == 0 {
-                               a.Offset = roff(rm, 2, 2)
-                       } else {
-                               a.Offset = roff(rm, 2, 6)
-                       }
                } else {
                        a.Reg = arm64.REG_UXTW + Rnum
-                       a.Offset = roff(rm, 2, num)
                }
        case "UXTX":
                if !isAmount {
@@ -189,13 +175,11 @@ func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, i
                        return errors.New("invalid shift for the register offset addressing mode")
                }
                a.Reg = arm64.REG_UXTX + Rnum
-               a.Offset = roff(rm, 3, num)
        case "SXTB":
                if !isAmount {
                        return errors.New("invalid register extension")
                }
                a.Reg = arm64.REG_SXTB + Rnum
-               a.Offset = roff(rm, 4, num)
        case "SXTH":
                if !isAmount {
                        return errors.New("invalid register extension")
@@ -204,21 +188,14 @@ func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, i
                        return errors.New("invalid shift for the register offset addressing mode")
                }
                a.Reg = arm64.REG_SXTH + Rnum
-               a.Offset = roff(rm, 5, num)
        case "SXTW":
                if !isAmount {
                        return errors.New("invalid register extension")
                }
                if a.Type == obj.TYPE_MEM {
                        a.Index = arm64.REG_SXTW + Rnum
-                       if num == 0 {
-                               a.Offset = roff(rm, 6, 2)
-                       } else {
-                               a.Offset = roff(rm, 6, 6)
-                       }
                } else {
                        a.Reg = arm64.REG_SXTW + Rnum
-                       a.Offset = roff(rm, 6, num)
                }
        case "SXTX":
                if !isAmount {
@@ -226,21 +203,14 @@ func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, i
                }
                if a.Type == obj.TYPE_MEM {
                        a.Index = arm64.REG_SXTX + Rnum
-                       if num == 0 {
-                               a.Offset = roff(rm, 7, 2)
-                       } else {
-                               a.Offset = roff(rm, 7, 6)
-                       }
                } else {
                        a.Reg = arm64.REG_SXTX + Rnum
-                       a.Offset = roff(rm, 7, num)
                }
        case "LSL":
                if !isAmount {
                        return errors.New("invalid register extension")
                }
                a.Index = arm64.REG_LSL + Rnum
-               a.Offset = roff(rm, 3, 6)
        case "B8":
                if isIndex {
                        return errors.New("invalid register extension")
index 3f1aee8c2beda5d89d1cbd811e000f49bc5eaa6c..66163d789e9a4893f1ba025f258e45fb5444b36f 100644 (file)
@@ -2511,11 +2511,12 @@ func (c *ctxt7) checkShiftAmount(p *obj.Prog, a *obj.Addr) {
                if amount != 2 && amount != 0 {
                        c.ctxt.Diag("invalid index shift amount: %v", p)
                }
-
        case AMOVD:
                if amount != 3 && amount != 0 {
                        c.ctxt.Diag("invalid index shift amount: %v", p)
                }
+       default:
+               panic("invalid operation")
        }
 }
 
@@ -2955,14 +2956,13 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                o1 |= (REGZERO & 31 << 5) | uint32(rt&31)
 
        case 27: /* op Rm<<n[,Rn],Rd (extended register) */
-
                if (p.From.Reg-obj.RBaseARM64)&REG_EXT != 0 {
                        amount := (p.From.Reg >> 5) & 7
                        if amount > 4 {
                                c.ctxt.Diag("shift amount out of range 0 to 4: %v", p)
                        }
                        o1 = c.opxrrr(p, p.As, true)
-                       o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
+                       o1 |= c.encRegShiftOrExt(&p.From, p.From.Reg) /* includes reg, op, etc */
                } else {
                        o1 = c.opxrrr(p, p.As, false)
                        o1 |= uint32(p.From.Reg&31) << 16
@@ -4467,11 +4467,12 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                o1 |= (uint32(Q&1) << 30) | (uint32(r&31) << 16) | ((opcode & 7) << 13) | (uint32(S&1) << 12) | (uint32(size&3) << 10) | (uint32(rf&31) << 5) | uint32(rt&31)
 
        case 98: /* MOVD (Rn)(Rm.SXTW[<<amount]),Rd */
-               if p.From.Offset != 0 {
+               if isRegShiftOrExt(&p.From) {
                        // extended or shifted offset register.
                        c.checkShiftAmount(p, &p.From)
+
                        o1 = c.opldrr(p, p.As, true)
-                       o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
+                       o1 |= c.encRegShiftOrExt(&p.From, p.From.Index) /* includes reg, op, etc */
                } else {
                        // (Rn)(Rm), no extension or shift.
                        o1 = c.opldrr(p, p.As, false)
@@ -4482,11 +4483,12 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                o1 |= uint32(rt & 31)
 
        case 99: /* MOVD Rt, (Rn)(Rm.SXTW[<<amount]) */
-               if p.To.Offset != 0 {
+               if isRegShiftOrExt(&p.To) {
                        // extended or shifted offset register.
                        c.checkShiftAmount(p, &p.To)
+
                        o1 = c.opstrr(p, p.As, true)
-                       o1 |= uint32(p.To.Offset) /* includes reg, op, etc */
+                       o1 |= c.encRegShiftOrExt(&p.To, p.To.Index) /* includes reg, op, etc */
                } else {
                        // (Rn)(Rm), no extension or shift.
                        o1 = c.opstrr(p, p.As, false)
@@ -6093,3 +6095,63 @@ func movesize(a obj.As) int {
                return -1
        }
 }
+
+// rm is the Rm register value, o is the extension, amount is the left shift value.
+func roff(rm int16, o uint32, amount int16) uint32 {
+       return uint32(rm&31)<<16 | o<<13 | uint32(amount)<<10
+}
+
+// encRegShiftOrExt returns the encoding of shifted/extended register, Rx<<n and Rx.UXTW<<n, etc.
+func (c *ctxt7) encRegShiftOrExt(a *obj.Addr, r int16) uint32 {
+       var num, rm int16
+       num = (r >> 5) & 7
+       rm = r & 31
+       switch {
+       case REG_UXTB <= r && r < REG_UXTH:
+               return roff(rm, 0, num)
+       case REG_UXTH <= r && r < REG_UXTW:
+               return roff(rm, 1, num)
+       case REG_UXTW <= r && r < REG_UXTX:
+               if a.Type == obj.TYPE_MEM {
+                       if num == 0 {
+                               return roff(rm, 2, 2)
+                       } else {
+                               return roff(rm, 2, 6)
+                       }
+               } else {
+                       return roff(rm, 2, num)
+               }
+       case REG_UXTX <= r && r < REG_SXTB:
+               return roff(rm, 3, num)
+       case REG_SXTB <= r && r < REG_SXTH:
+               return roff(rm, 4, num)
+       case REG_SXTH <= r && r < REG_SXTW:
+               return roff(rm, 5, num)
+       case REG_SXTW <= r && r < REG_SXTX:
+               if a.Type == obj.TYPE_MEM {
+                       if num == 0 {
+                               return roff(rm, 6, 2)
+                       } else {
+                               return roff(rm, 6, 6)
+                       }
+               } else {
+                       return roff(rm, 6, num)
+               }
+       case REG_SXTX <= r && r < REG_SPECIAL:
+               if a.Type == obj.TYPE_MEM {
+                       if num == 0 {
+                               return roff(rm, 7, 2)
+                       } else {
+                               return roff(rm, 7, 6)
+                       }
+               } else {
+                       return roff(rm, 7, num)
+               }
+       case REG_LSL <= r && r < (REG_LSL+1<<8):
+               return roff(rm, 3, 6)
+       default:
+               c.ctxt.Diag("unsupported register extension type.")
+       }
+
+       return 0
+}
index 2d457fd5035cce0b8f09031dbce946e6a1a2b39f..3b92dfcba37e6fb70de4ff2f077bf7920723cb59 100644 (file)
@@ -299,17 +299,7 @@ func Mconv(a *Addr) string {
                case a.Offset == 0:
                        str = fmt.Sprintf("(%v)", Rconv(int(a.Reg)))
                case a.Offset != 0:
-                       switch objabi.GOARCH {
-                       case "arm64":
-                               // the register and the extension/shift are encoded in a.Offset.
-                               if a.Index != 0 {
-                                       str = fmt.Sprintf("(%v)", Rconv(int(a.Reg)))
-                                       return str
-                               }
-                               fallthrough
-                       default:
-                               str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(int(a.Reg)))
-                       }
+                       str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(int(a.Reg)))
                }
 
                // Note: a.Reg == REG_NONE encodes the default base register for the NAME_ type.