From 236c567ba9b7767b6f1ebe32eb2d8f0018de8780 Mon Sep 17 00:00:00 2001 From: fanzha02 Date: Sun, 8 Apr 2018 12:36:30 +0000 Subject: [PATCH] cmd/internal/obj/arm64: refactor the extended/shifted register encoding to the backend 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 Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot --- src/cmd/asm/internal/arch/arm64.go | 30 ------------ src/cmd/internal/obj/arm64/asm7.go | 76 +++++++++++++++++++++++++++--- src/cmd/internal/obj/util.go | 12 +---- 3 files changed, 70 insertions(+), 48 deletions(-) diff --git a/src/cmd/asm/internal/arch/arm64.go b/src/cmd/asm/internal/arch/arm64.go index b311f4c738..2aadda4b9b 100644 --- a/src/cmd/asm/internal/arch/arm64.go +++ b/src/cmd/asm/internal/arch/arm64.go @@ -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") diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index 3f1aee8c2b..66163d789e 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -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<> 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[<> 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 +} diff --git a/src/cmd/internal/obj/util.go b/src/cmd/internal/obj/util.go index 2d457fd503..3b92dfcba3 100644 --- a/src/cmd/internal/obj/util.go +++ b/src/cmd/internal/obj/util.go @@ -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. -- 2.48.1