From d75cc4b9c6e2acb4d0ed3d90c9a8b38094af281b Mon Sep 17 00:00:00 2001 From: Ruinan Date: Thu, 4 May 2023 12:31:36 +0800 Subject: [PATCH] cmd/asm: encode instructions like SHA1SU0 with a separate case for arm64 Before this CL, instructions such as SHA1SU0, AESD and AESE are encoded in case 1 together with FMOV/ADD, and some error checking is missing, for example: SHA1SU0 V1.B16, V2.B16, V3.B16 // wrong data arrangement SHA1SU0 V1.4S, V2.S4, V3.S4 // correct Both will be accepted by the assembler, but the first one is totally incorrect. This CL fixes these potential encoding issues by moving them into separate cases, adds some error tests, and also fixes a wrong encoding operand for ASHA1C. Change-Id: Ic778321a567735d48bc34a1247ee005c4ed9e11f Reviewed-on: https://go-review.googlesource.com/c/go/+/493195 Run-TryBot: Cherry Mui Reviewed-by: Heschi Kreinick Reviewed-by: Cherry Mui TryBot-Result: Gopher Robot --- .../asm/internal/asm/testdata/arm64error.s | 11 +++ src/cmd/internal/obj/arm64/asm7.go | 72 ++++++++++++++++--- 2 files changed, 72 insertions(+), 11 deletions(-) diff --git a/src/cmd/asm/internal/asm/testdata/arm64error.s b/src/cmd/asm/internal/asm/testdata/arm64error.s index fa5ec8e89c..354b64df02 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64error.s +++ b/src/cmd/asm/internal/asm/testdata/arm64error.s @@ -410,4 +410,15 @@ TEXT errors(SB),$0 DC VAE1IS // ERROR "illegal argument" DC VAE1IS, R0 // ERROR "illegal argument" DC IVAC // ERROR "missing register at operand 2" + AESD V1.B8, V2.B8 // ERROR "invalid arrangement" + AESE V1.D2, V2.D2 // ERROR "invalid arrangement" + AESIMC V1.S4, V2.S4 // ERROR "invalid arrangement" + SHA1SU1 V1.B16, V2.B16 // ERROR "invalid arrangement" + SHA256SU1 V1.B16, V2.B16, V3.B16 // ERROR "invalid arrangement" + SHA512SU1 V1.S4, V2.S4, V3.S4 // ERROR "invalid arrangement" + SHA256H V1.D2, V2, V3 // ERROR "invalid arrangement" + SHA512H V1.S4, V2, V3 // ERROR "invalid arrangement" + AESE V1.B16, V2.B8 // ERROR "invalid arrangement" + SHA256SU1 V1.S4, V2.B16, V3.S4 // ERROR "invalid arrangement" + SHA1H V1.B16, V2.B16 // ERROR "invalid operands" RET diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index 76361577d4..77c60812ac 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -833,13 +833,11 @@ var optab = []Optab{ {ATLBI, C_SPOP, C_NONE, C_NONE, C_ZREG, 107, 4, 0, 0, 0}, /* encryption instructions */ - {AAESD, C_VREG, C_NONE, C_NONE, C_VREG, 29, 4, 0, 0, 0}, // for compatibility with old code - {AAESD, C_ARNG, C_NONE, C_NONE, C_ARNG, 29, 4, 0, 0, 0}, // recommend using the new one for better readability - {ASHA1C, C_VREG, C_ZREG, C_NONE, C_VREG, 1, 4, 0, 0, 0}, - {ASHA1C, C_ARNG, C_VREG, C_NONE, C_VREG, 1, 4, 0, 0, 0}, - {ASHA1H, C_VREG, C_NONE, C_NONE, C_VREG, 29, 4, 0, 0, 0}, - {ASHA1SU0, C_ARNG, C_ARNG, C_NONE, C_ARNG, 1, 4, 0, 0, 0}, - {ASHA256H, C_ARNG, C_VREG, C_NONE, C_VREG, 1, 4, 0, 0, 0}, + {AAESD, C_VREG, C_NONE, C_NONE, C_VREG, 26, 4, 0, 0, 0}, // for compatibility with old code + {AAESD, C_ARNG, C_NONE, C_NONE, C_ARNG, 26, 4, 0, 0, 0}, // recommend using the new one for better readability + {ASHA1C, C_VREG, C_VREG, C_NONE, C_VREG, 49, 4, 0, 0, 0}, + {ASHA1C, C_ARNG, C_VREG, C_NONE, C_VREG, 49, 4, 0, 0, 0}, + {ASHA1SU0, C_ARNG, C_ARNG, C_NONE, C_ARNG, 63, 4, 0, 0, 0}, {AVREV32, C_ARNG, C_NONE, C_NONE, C_ARNG, 83, 4, 0, 0, 0}, {AVPMULL, C_ARNG, C_ARNG, C_NONE, C_ARNG, 93, 4, 0, 0, 0}, {AVEOR3, C_ARNG, C_ARNG, C_ARNG, C_ARNG, 103, 4, 0, 0, 0}, @@ -3083,12 +3081,12 @@ func buildop(ctxt *obj.Link) { oprangeset(ASHA1SU1, t) oprangeset(ASHA256SU0, t) oprangeset(ASHA512SU0, t) + oprangeset(ASHA1H, t) case ASHA1C: oprangeset(ASHA1P, t) oprangeset(ASHA1M, t) - - case ASHA256H: + oprangeset(ASHA256H, t) oprangeset(ASHA256H2, t) oprangeset(ASHA512H, t) oprangeset(ASHA512H2, t) @@ -3146,8 +3144,7 @@ func buildop(ctxt *obj.Link) { case AVTBL: oprangeset(AVTBX, t) - case ASHA1H, - AVCNT, + case AVCNT, AVMOV, AVLD1, AVST1, @@ -3789,6 +3786,32 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { rt := int(p.To.Reg) o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31) + case 26: /* op Vn, Vd; op Vn., Vd. */ + o1 = c.oprrr(p, p.As) + cf := c.aclass(&p.From) + af := (p.From.Reg >> 5) & 15 + at := (p.To.Reg >> 5) & 15 + var sz int16 + switch p.As { + case AAESD, AAESE, AAESIMC, AAESMC: + sz = ARNG_16B + case ASHA1SU1, ASHA256SU0: + sz = ARNG_4S + case ASHA512SU0: + sz = ARNG_2D + } + + if cf == C_ARNG { + if p.As == ASHA1H { + c.ctxt.Diag("invalid operands: %v", p) + } else { + if af != sz || af != at { + c.ctxt.Diag("invalid arrangement: %v", p) + } + } + } + o1 |= uint32(p.From.Reg&31)<<5 | uint32(p.To.Reg&31) + case 27: /* op Rm<, Vn, Vd */ + o1 = c.oprrr(p, p.As) + cf := c.aclass(&p.From) + af := (p.From.Reg >> 5) & 15 + sz := ARNG_4S + if p.As == ASHA512H || p.As == ASHA512H2 { + sz = ARNG_2D + } + if cf == C_ARNG && af != int16(sz) { + c.ctxt.Diag("invalid arrangement: %v", p) + } + o1 |= uint32(p.From.Reg&31)<<16 | uint32(p.Reg&31)<<5 | uint32(p.To.Reg&31) + case 50: /* sys/sysl */ o1 = c.opirr(p, p.As) @@ -4436,6 +4472,20 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { o2 |= uint32(r&31) << 5 o2 |= uint32(rt & 31) + case 63: /* op Vm., Vn., Vd. */ + o1 |= c.oprrr(p, p.As) + af := (p.From.Reg >> 5) & 15 + at := (p.To.Reg >> 5) & 15 + ar := (p.Reg >> 5) & 15 + sz := ARNG_4S + if p.As == ASHA512SU1 { + sz = ARNG_2D + } + if af != at || af != ar || af != int16(sz) { + c.ctxt.Diag("invalid arrangement: %v", p) + } + o1 |= uint32(p.From.Reg&31)<<16 | uint32(p.Reg&31)<<5 | uint32(p.To.Reg&31) + /* reloc ops */ case 64: /* movT R,addr -> adrp + movT R, (REGTMP) */ if p.From.Reg == REGTMP { -- 2.50.0