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 } }