From a607408403df7515f831fef64991222673a50a68 Mon Sep 17 00:00:00 2001 From: fanzha02 Date: Wed, 20 Jan 2021 17:58:21 +0800 Subject: [PATCH] cmd/internal/obj/arm64: add support for op(extended register) with RSP arguments Refer to ARM reference manual, like add(extended register) instructions, the extension is encoded in the "option" field. If "Rd" or "Rn" is RSP and "option" is "010" then LSL is preferred. Therefore, the instrution "add Rm< Run-TryBot: fannie zhang TryBot-Result: Go Bot Reviewed-by: Cherry Zhang --- src/cmd/asm/internal/asm/testdata/arm64.s | 10 ++++ .../asm/internal/asm/testdata/arm64error.s | 3 ++ src/cmd/internal/obj/arm64/asm7.go | 46 +++++++++++++++++-- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s index 86357083208..d859171103d 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64.s +++ b/src/cmd/asm/internal/asm/testdata/arm64.s @@ -64,6 +64,16 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 CMN R1.SXTX<<2, R10 // 5fe921ab CMPW R2.UXTH<<3, R11 // 7f2d226b CMNW R1.SXTB, R9 // 3f81212b + ADD R1<<1, RSP, R3 // e367218b + ADDW R1<<2, R3, RSP // 7f48210b + SUB R1<<3, RSP // ff6f21cb + SUBS R1<<4, RSP, R3 // e37321eb + ADDS R1<<1, RSP, R4 // e46721ab + CMP R1<<2, RSP // ff6b21eb + CMN R1<<3, RSP // ff6f21ab + ADDS R1<<1, ZR, R4 // e40701ab + ADD R3<<50, ZR, ZR // ffcb038b + CMP R4<<24, ZR // ff6304eb CMPW $0x60060, R2 // CMPW $393312, R2 // 1b0c8052db00a0725f001b6b CMPW $40960, R0 // 1f284071 CMPW $27745, R2 // 3b8c8d525f001b6b diff --git a/src/cmd/asm/internal/asm/testdata/arm64error.s b/src/cmd/asm/internal/asm/testdata/arm64error.s index 1c8eaa17524..64bade20512 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64error.s +++ b/src/cmd/asm/internal/asm/testdata/arm64error.s @@ -368,4 +368,7 @@ TEXT errors(SB),$0 CASPD (R2, R3), (R2), (R9, R10) // ERROR "destination register pair must start from even register" CASPD (R2, R4), (R2), (R8, R9) // ERROR "source register pair must be contiguous" CASPD (R2, R3), (R2), (R8, R10) // ERROR "destination register pair must be contiguous" + ADD R1>>2, RSP, R3 // ERROR "illegal combination" + ADDS R2<<3, R3, RSP // ERROR "unexpected SP reference" + CMP R1<<5, RSP // ERROR "the left shift amount out of range 0 to 4" RET diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index e9f18e1bf03..275799aad32 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -321,15 +321,17 @@ var optab = []Optab{ {ACMP, C_VCON, C_REG, C_NONE, C_NONE, 13, 20, 0, 0, 0}, {AADD, C_SHIFT, C_REG, C_NONE, C_REG, 3, 4, 0, 0, 0}, {AADD, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0}, + {AADD, C_SHIFT, C_RSP, C_NONE, C_RSP, 107, 4, 0, 0, 0}, + {AADD, C_SHIFT, C_NONE, C_NONE, C_RSP, 107, 4, 0, 0, 0}, {AMVN, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0}, {ACMP, C_SHIFT, C_REG, C_NONE, C_NONE, 3, 4, 0, 0, 0}, + {ACMP, C_SHIFT, C_RSP, C_NONE, C_NONE, 107, 4, 0, 0, 0}, {ANEG, C_SHIFT, C_NONE, C_NONE, C_REG, 26, 4, 0, 0, 0}, {AADD, C_REG, C_RSP, C_NONE, C_RSP, 27, 4, 0, 0, 0}, {AADD, C_REG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0}, {ACMP, C_REG, C_RSP, C_NONE, C_NONE, 27, 4, 0, 0, 0}, {AADD, C_EXTREG, C_RSP, C_NONE, C_RSP, 27, 4, 0, 0, 0}, {AADD, C_EXTREG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0}, - {AMVN, C_EXTREG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0}, {ACMP, C_EXTREG, C_RSP, C_NONE, C_NONE, 27, 4, 0, 0, 0}, {AADD, C_REG, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, {AADD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0, 0, 0}, @@ -5458,6 +5460,41 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { c.ctxt.Diag("illegal destination register: %v\n", p) } o1 |= enc | uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31) + + case 107: // op R<> 10) & 63 + shift := (p.From.Offset >> 22) & 3 + if shift != 0 { + c.ctxt.Diag("illegal combination: %v", p) + break + } + + if amount > 4 { + c.ctxt.Diag("the left shift amount out of range 0 to 4: %v", p) + break + } + rf := (p.From.Offset >> 16) & 31 + rt := int(p.To.Reg) + r := int(p.Reg) + if p.To.Type == obj.TYPE_NONE { + rt = REGZERO + } + if r == 0 { + r = rt + } + + o1 = c.opxrrr(p, p.As, false) + o1 |= uint32(rf)<<16 | uint32(amount&7)<<10 | (uint32(r&31) << 5) | uint32(rt&31) } out[0] = o1 out[1] = o2 @@ -6394,11 +6431,10 @@ func (c *ctxt7) opbit(p *obj.Prog, a obj.As) uint32 { func (c *ctxt7) opxrrr(p *obj.Prog, a obj.As, extend bool) uint32 { extension := uint32(0) if !extend { - switch a { - case AADD, ACMN, AADDS, ASUB, ACMP, ASUBS: + if isADDop(a) { extension = LSL0_64 - - case AADDW, ACMNW, AADDSW, ASUBW, ACMPW, ASUBSW: + } + if isADDWop(a) { extension = LSL0_32 } }