From 448089854a971274db839a1cacea008b48134a19 Mon Sep 17 00:00:00 2001 From: erifan01 Date: Wed, 12 Dec 2018 08:29:51 +0000 Subject: [PATCH] cmd/asm: add arm64 v8.1 atomic instructions This change adds several arm64 v8.1 atomic instructions and test cases. They are LDADDAx, LDADDLx, LDANDAx, LDANDALx, LDANDLx, LDEORAx, LDEORALx, LDEORLx, LDORAx, LDORALx, LDORLx, SWPAx and SWPLx. Their form is consistent with the form of the existing atomic instructions. For instructions STXRx, STLXRx, STXPx and STLXPx, the second destination register can't be RSP. This CL also adds a check for this. LDADDx Rs, (Rb), Rt: *Rb -> Rt, Rs + *Rb -> *Rb LDANDx Rs, (Rb), Rt: *Rb -> Rt, Rs AND NOT(*Rb) -> *Rb LDEORx Rs, (Rb), Rt: *Rb -> Rt, Rs EOR *Rb -> *Rb LDORx Rs, (Rb), Rt: *Rb -> Rt, Rs OR *Rb -> *Rb Change-Id: I9f9b0245958cb57ab7d88c66fb9159b23b9017fd Reviewed-on: https://go-review.googlesource.com/c/go/+/157001 Reviewed-by: Cherry Zhang Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot --- src/cmd/asm/internal/arch/arm64.go | 13 +- src/cmd/asm/internal/asm/testdata/arm64.s | 133 +++++++++++++-- .../asm/internal/asm/testdata/arm64error.s | 120 +++++++++++++ src/cmd/internal/obj/arm64/a.out.go | 70 +++++++- src/cmd/internal/obj/arm64/anames.go | 70 +++++++- src/cmd/internal/obj/arm64/asm7.go | 158 +++++++++++------- 6 files changed, 469 insertions(+), 95 deletions(-) diff --git a/src/cmd/asm/internal/arch/arm64.go b/src/cmd/asm/internal/arch/arm64.go index 98858bd181..3817fcd5c2 100644 --- a/src/cmd/asm/internal/arch/arm64.go +++ b/src/cmd/asm/internal/arch/arm64.go @@ -72,14 +72,11 @@ func IsARM64STLXR(op obj.As) bool { switch op { case arm64.ASTLXRB, arm64.ASTLXRH, arm64.ASTLXRW, arm64.ASTLXR, arm64.ASTXRB, arm64.ASTXRH, arm64.ASTXRW, arm64.ASTXR, - arm64.ASTXP, arm64.ASTXPW, arm64.ASTLXP, arm64.ASTLXPW, - arm64.ASWPB, arm64.ASWPH, arm64.ASWPW, arm64.ASWPD, - arm64.ASWPALB, arm64.ASWPALH, arm64.ASWPALW, arm64.ASWPALD, - arm64.ALDADDB, arm64.ALDADDH, arm64.ALDADDW, arm64.ALDADDD, - arm64.ALDANDB, arm64.ALDANDH, arm64.ALDANDW, arm64.ALDANDD, - arm64.ALDEORB, arm64.ALDEORH, arm64.ALDEORW, arm64.ALDEORD, - arm64.ALDORB, arm64.ALDORH, arm64.ALDORW, arm64.ALDORD, - arm64.ALDADDALD, arm64.ALDADDALW, arm64.ALDADDALH, arm64.ALDADDALB: + arm64.ASTXP, arm64.ASTXPW, arm64.ASTLXP, arm64.ASTLXPW: + return true + } + // atomic instructions + if arm64.IsAtomicInstruction(op) { return true } return false diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s index b54fd86045..77671223c9 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64.s +++ b/src/cmd/asm/internal/asm/testdata/arm64.s @@ -659,14 +659,14 @@ again: STXP (R1, R2), (RSP), R10 // e10b2ac8 STXPW (R1, R2), (R3), R10 // 61082a88 STXPW (R1, R2), (RSP), R10 // e10b2a88 - SWPD R5, (R6), R7 // c78025f8 - SWPD R5, (RSP), R7 // e78325f8 - SWPW R5, (R6), R7 // c78025b8 - SWPW R5, (RSP), R7 // e78325b8 - SWPH R5, (R6), R7 // c7802578 - SWPH R5, (RSP), R7 // e7832578 - SWPB R5, (R6), R7 // c7802538 - SWPB R5, (RSP), R7 // e7832538 + SWPAD R5, (R6), R7 // c780a5f8 + SWPAD R5, (RSP), R7 // e783a5f8 + SWPAW R5, (R6), R7 // c780a5b8 + SWPAW R5, (RSP), R7 // e783a5b8 + SWPAH R5, (R6), R7 // c780a578 + SWPAH R5, (RSP), R7 // e783a578 + SWPAB R5, (R6), R7 // c780a538 + SWPAB R5, (RSP), R7 // e783a538 SWPALD R5, (R6), R7 // c780e5f8 SWPALD R5, (RSP), R7 // e783e5f8 SWPALW R5, (R6), R7 // c780e5b8 @@ -675,6 +675,38 @@ again: SWPALH R5, (RSP), R7 // e783e578 SWPALB R5, (R6), R7 // c780e538 SWPALB R5, (RSP), R7 // e783e538 + SWPD R5, (R6), R7 // c78025f8 + SWPD R5, (RSP), R7 // e78325f8 + SWPW R5, (R6), R7 // c78025b8 + SWPW R5, (RSP), R7 // e78325b8 + SWPH R5, (R6), R7 // c7802578 + SWPH R5, (RSP), R7 // e7832578 + SWPB R5, (R6), R7 // c7802538 + SWPB R5, (RSP), R7 // e7832538 + SWPLD R5, (R6), R7 // c78065f8 + SWPLD R5, (RSP), R7 // e78365f8 + SWPLW R5, (R6), R7 // c78065b8 + SWPLW R5, (RSP), R7 // e78365b8 + SWPLH R5, (R6), R7 // c7806578 + SWPLH R5, (RSP), R7 // e7836578 + SWPLB R5, (R6), R7 // c7806538 + SWPLB R5, (RSP), R7 // e7836538 + LDADDAD R5, (R6), R7 // c700a5f8 + LDADDAD R5, (RSP), R7 // e703a5f8 + LDADDAW R5, (R6), R7 // c700a5b8 + LDADDAW R5, (RSP), R7 // e703a5b8 + LDADDAH R5, (R6), R7 // c700a578 + LDADDAH R5, (RSP), R7 // e703a578 + LDADDAB R5, (R6), R7 // c700a538 + LDADDAB R5, (RSP), R7 // e703a538 + LDADDALD R5, (R6), R7 // c700e5f8 + LDADDALD R5, (RSP), R7 // e703e5f8 + LDADDALW R5, (R6), R7 // c700e5b8 + LDADDALW R5, (RSP), R7 // e703e5b8 + LDADDALH R5, (R6), R7 // c700e578 + LDADDALH R5, (RSP), R7 // e703e578 + LDADDALB R5, (R6), R7 // c700e538 + LDADDALB R5, (RSP), R7 // e703e538 LDADDD R5, (R6), R7 // c70025f8 LDADDD R5, (RSP), R7 // e70325f8 LDADDW R5, (R6), R7 // c70025b8 @@ -683,6 +715,30 @@ again: LDADDH R5, (RSP), R7 // e7032578 LDADDB R5, (R6), R7 // c7002538 LDADDB R5, (RSP), R7 // e7032538 + LDADDLD R5, (R6), R7 // c70065f8 + LDADDLD R5, (RSP), R7 // e70365f8 + LDADDLW R5, (R6), R7 // c70065b8 + LDADDLW R5, (RSP), R7 // e70365b8 + LDADDLH R5, (R6), R7 // c7006578 + LDADDLH R5, (RSP), R7 // e7036578 + LDADDLB R5, (R6), R7 // c7006538 + LDADDLB R5, (RSP), R7 // e7036538 + LDANDAD R5, (R6), R7 // c710a5f8 + LDANDAD R5, (RSP), R7 // e713a5f8 + LDANDAW R5, (R6), R7 // c710a5b8 + LDANDAW R5, (RSP), R7 // e713a5b8 + LDANDAH R5, (R6), R7 // c710a578 + LDANDAH R5, (RSP), R7 // e713a578 + LDANDAB R5, (R6), R7 // c710a538 + LDANDAB R5, (RSP), R7 // e713a538 + LDANDALD R5, (R6), R7 // c710e5f8 + LDANDALD R5, (RSP), R7 // e713e5f8 + LDANDALW R5, (R6), R7 // c710e5b8 + LDANDALW R5, (RSP), R7 // e713e5b8 + LDANDALH R5, (R6), R7 // c710e578 + LDANDALH R5, (RSP), R7 // e713e578 + LDANDALB R5, (R6), R7 // c710e538 + LDANDALB R5, (RSP), R7 // e713e538 LDANDD R5, (R6), R7 // c71025f8 LDANDD R5, (RSP), R7 // e71325f8 LDANDW R5, (R6), R7 // c71025b8 @@ -691,6 +747,30 @@ again: LDANDH R5, (RSP), R7 // e7132578 LDANDB R5, (R6), R7 // c7102538 LDANDB R5, (RSP), R7 // e7132538 + LDANDLD R5, (R6), R7 // c71065f8 + LDANDLD R5, (RSP), R7 // e71365f8 + LDANDLW R5, (R6), R7 // c71065b8 + LDANDLW R5, (RSP), R7 // e71365b8 + LDANDLH R5, (R6), R7 // c7106578 + LDANDLH R5, (RSP), R7 // e7136578 + LDANDLB R5, (R6), R7 // c7106538 + LDANDLB R5, (RSP), R7 // e7136538 + LDEORAD R5, (R6), R7 // c720a5f8 + LDEORAD R5, (RSP), R7 // e723a5f8 + LDEORAW R5, (R6), R7 // c720a5b8 + LDEORAW R5, (RSP), R7 // e723a5b8 + LDEORAH R5, (R6), R7 // c720a578 + LDEORAH R5, (RSP), R7 // e723a578 + LDEORAB R5, (R6), R7 // c720a538 + LDEORAB R5, (RSP), R7 // e723a538 + LDEORALD R5, (R6), R7 // c720e5f8 + LDEORALD R5, (RSP), R7 // e723e5f8 + LDEORALW R5, (R6), R7 // c720e5b8 + LDEORALW R5, (RSP), R7 // e723e5b8 + LDEORALH R5, (R6), R7 // c720e578 + LDEORALH R5, (RSP), R7 // e723e578 + LDEORALB R5, (R6), R7 // c720e538 + LDEORALB R5, (RSP), R7 // e723e538 LDEORD R5, (R6), R7 // c72025f8 LDEORD R5, (RSP), R7 // e72325f8 LDEORW R5, (R6), R7 // c72025b8 @@ -699,6 +779,30 @@ again: LDEORH R5, (RSP), R7 // e7232578 LDEORB R5, (R6), R7 // c7202538 LDEORB R5, (RSP), R7 // e7232538 + LDEORLD R5, (R6), R7 // c72065f8 + LDEORLD R5, (RSP), R7 // e72365f8 + LDEORLW R5, (R6), R7 // c72065b8 + LDEORLW R5, (RSP), R7 // e72365b8 + LDEORLH R5, (R6), R7 // c7206578 + LDEORLH R5, (RSP), R7 // e7236578 + LDEORLB R5, (R6), R7 // c7206538 + LDEORLB R5, (RSP), R7 // e7236538 + LDORAD R5, (R6), R7 // c730a5f8 + LDORAD R5, (RSP), R7 // e733a5f8 + LDORAW R5, (R6), R7 // c730a5b8 + LDORAW R5, (RSP), R7 // e733a5b8 + LDORAH R5, (R6), R7 // c730a578 + LDORAH R5, (RSP), R7 // e733a578 + LDORAB R5, (R6), R7 // c730a538 + LDORAB R5, (RSP), R7 // e733a538 + LDORALD R5, (R6), R7 // c730e5f8 + LDORALD R5, (RSP), R7 // e733e5f8 + LDORALW R5, (R6), R7 // c730e5b8 + LDORALW R5, (RSP), R7 // e733e5b8 + LDORALH R5, (R6), R7 // c730e578 + LDORALH R5, (RSP), R7 // e733e578 + LDORALB R5, (R6), R7 // c730e538 + LDORALB R5, (RSP), R7 // e733e538 LDORD R5, (R6), R7 // c73025f8 LDORD R5, (RSP), R7 // e73325f8 LDORW R5, (R6), R7 // c73025b8 @@ -707,11 +811,14 @@ again: LDORH R5, (RSP), R7 // e7332578 LDORB R5, (R6), R7 // c7302538 LDORB R5, (RSP), R7 // e7332538 - LDADDALD R2, (R1), R3 // 2300e2f8 - LDADDALW R2, (R1), R3 // 2300e2b8 - LDADDALH R2, (R1), R3 // 2300e278 - LDADDALB R2, (R1), R3 // 2300e238 - + LDORLD R5, (R6), R7 // c73065f8 + LDORLD R5, (RSP), R7 // e73365f8 + LDORLW R5, (R6), R7 // c73065b8 + LDORLW R5, (RSP), R7 // e73365b8 + LDORLH R5, (R6), R7 // c7306578 + LDORLH R5, (RSP), R7 // e7336578 + LDORLB R5, (R6), R7 // c7306538 + LDORLB R5, (RSP), R7 // e7336538 // RET // // LTYPEA comma diff --git a/src/cmd/asm/internal/asm/testdata/arm64error.s b/src/cmd/asm/internal/asm/testdata/arm64error.s index 357db80222..387836dcbe 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64error.s +++ b/src/cmd/asm/internal/asm/testdata/arm64error.s @@ -112,4 +112,124 @@ TEXT errors(SB),$0 FSTPD (R1, R2), (R0) // ERROR "invalid register pair" FMOVS (F2), F0 // ERROR "illegal combination" FMOVD F0, (F1) // ERROR "illegal combination" + LDADDD R5, (R6), ZR // ERROR "illegal destination register" + LDADDW R5, (R6), ZR // ERROR "illegal destination register" + LDADDH R5, (R6), ZR // ERROR "illegal destination register" + LDADDB R5, (R6), ZR // ERROR "illegal destination register" + LDADDLD R5, (R6), ZR // ERROR "illegal destination register" + LDADDLW R5, (R6), ZR // ERROR "illegal destination register" + LDADDLH R5, (R6), ZR // ERROR "illegal destination register" + LDADDLB R5, (R6), ZR // ERROR "illegal destination register" + LDANDD R5, (R6), ZR // ERROR "illegal destination register" + LDANDW R5, (R6), ZR // ERROR "illegal destination register" + LDANDH R5, (R6), ZR // ERROR "illegal destination register" + LDANDB R5, (R6), ZR // ERROR "illegal destination register" + LDANDLD R5, (R6), ZR // ERROR "illegal destination register" + LDANDLW R5, (R6), ZR // ERROR "illegal destination register" + LDANDLH R5, (R6), ZR // ERROR "illegal destination register" + LDANDLB R5, (R6), ZR // ERROR "illegal destination register" + LDEORD R5, (R6), ZR // ERROR "illegal destination register" + LDEORW R5, (R6), ZR // ERROR "illegal destination register" + LDEORH R5, (R6), ZR // ERROR "illegal destination register" + LDEORB R5, (R6), ZR // ERROR "illegal destination register" + LDEORLD R5, (R6), ZR // ERROR "illegal destination register" + LDEORLW R5, (R6), ZR // ERROR "illegal destination register" + LDEORLH R5, (R6), ZR // ERROR "illegal destination register" + LDEORLB R5, (R6), ZR // ERROR "illegal destination register" + LDORD R5, (R6), ZR // ERROR "illegal destination register" + LDORW R5, (R6), ZR // ERROR "illegal destination register" + LDORH R5, (R6), ZR // ERROR "illegal destination register" + LDORB R5, (R6), ZR // ERROR "illegal destination register" + LDORLD R5, (R6), ZR // ERROR "illegal destination register" + LDORLW R5, (R6), ZR // ERROR "illegal destination register" + LDORLH R5, (R6), ZR // ERROR "illegal destination register" + LDORLB R5, (R6), ZR // ERROR "illegal destination register" + LDADDAD R5, (R6), RSP // ERROR "illegal destination register" + LDADDAW R5, (R6), RSP // ERROR "illegal destination register" + LDADDAH R5, (R6), RSP // ERROR "illegal destination register" + LDADDAB R5, (R6), RSP // ERROR "illegal destination register" + LDADDALD R5, (R6), RSP // ERROR "illegal destination register" + LDADDALW R5, (R6), RSP // ERROR "illegal destination register" + LDADDALH R5, (R6), RSP // ERROR "illegal destination register" + LDADDALB R5, (R6), RSP // ERROR "illegal destination register" + LDADDD R5, (R6), RSP // ERROR "illegal destination register" + LDADDW R5, (R6), RSP // ERROR "illegal destination register" + LDADDH R5, (R6), RSP // ERROR "illegal destination register" + LDADDB R5, (R6), RSP // ERROR "illegal destination register" + LDADDLD R5, (R6), RSP // ERROR "illegal destination register" + LDADDLW R5, (R6), RSP // ERROR "illegal destination register" + LDADDLH R5, (R6), RSP // ERROR "illegal destination register" + LDADDLB R5, (R6), RSP // ERROR "illegal destination register" + LDANDAD R5, (R6), RSP // ERROR "illegal destination register" + LDANDAW R5, (R6), RSP // ERROR "illegal destination register" + LDANDAH R5, (R6), RSP // ERROR "illegal destination register" + LDANDAB R5, (R6), RSP // ERROR "illegal destination register" + LDANDALD R5, (R6), RSP // ERROR "illegal destination register" + LDANDALW R5, (R6), RSP // ERROR "illegal destination register" + LDANDALH R5, (R6), RSP // ERROR "illegal destination register" + LDANDALB R5, (R6), RSP // ERROR "illegal destination register" + LDANDD R5, (R6), RSP // ERROR "illegal destination register" + LDANDW R5, (R6), RSP // ERROR "illegal destination register" + LDANDH R5, (R6), RSP // ERROR "illegal destination register" + LDANDB R5, (R6), RSP // ERROR "illegal destination register" + LDANDLD R5, (R6), RSP // ERROR "illegal destination register" + LDANDLW R5, (R6), RSP // ERROR "illegal destination register" + LDANDLH R5, (R6), RSP // ERROR "illegal destination register" + LDANDLB R5, (R6), RSP // ERROR "illegal destination register" + LDEORAD R5, (R6), RSP // ERROR "illegal destination register" + LDEORAW R5, (R6), RSP // ERROR "illegal destination register" + LDEORAH R5, (R6), RSP // ERROR "illegal destination register" + LDEORAB R5, (R6), RSP // ERROR "illegal destination register" + LDEORALD R5, (R6), RSP // ERROR "illegal destination register" + LDEORALW R5, (R6), RSP // ERROR "illegal destination register" + LDEORALH R5, (R6), RSP // ERROR "illegal destination register" + LDEORALB R5, (R6), RSP // ERROR "illegal destination register" + LDEORD R5, (R6), RSP // ERROR "illegal destination register" + LDEORW R5, (R6), RSP // ERROR "illegal destination register" + LDEORH R5, (R6), RSP // ERROR "illegal destination register" + LDEORB R5, (R6), RSP // ERROR "illegal destination register" + LDEORLD R5, (R6), RSP // ERROR "illegal destination register" + LDEORLW R5, (R6), RSP // ERROR "illegal destination register" + LDEORLH R5, (R6), RSP // ERROR "illegal destination register" + LDEORLB R5, (R6), RSP // ERROR "illegal destination register" + LDORAD R5, (R6), RSP // ERROR "illegal destination register" + LDORAW R5, (R6), RSP // ERROR "illegal destination register" + LDORAH R5, (R6), RSP // ERROR "illegal destination register" + LDORAB R5, (R6), RSP // ERROR "illegal destination register" + LDORALD R5, (R6), RSP // ERROR "illegal destination register" + LDORALW R5, (R6), RSP // ERROR "illegal destination register" + LDORALH R5, (R6), RSP // ERROR "illegal destination register" + LDORALB R5, (R6), RSP // ERROR "illegal destination register" + LDORD R5, (R6), RSP // ERROR "illegal destination register" + LDORW R5, (R6), RSP // ERROR "illegal destination register" + LDORH R5, (R6), RSP // ERROR "illegal destination register" + LDORB R5, (R6), RSP // ERROR "illegal destination register" + LDORLD R5, (R6), RSP // ERROR "illegal destination register" + LDORLW R5, (R6), RSP // ERROR "illegal destination register" + LDORLH R5, (R6), RSP // ERROR "illegal destination register" + LDORLB R5, (R6), RSP // ERROR "illegal destination register" + SWPAD R5, (R6), RSP // ERROR "illegal destination register" + SWPAW R5, (R6), RSP // ERROR "illegal destination register" + SWPAH R5, (R6), RSP // ERROR "illegal destination register" + SWPAB R5, (R6), RSP // ERROR "illegal destination register" + SWPALD R5, (R6), RSP // ERROR "illegal destination register" + SWPALW R5, (R6), RSP // ERROR "illegal destination register" + SWPALH R5, (R6), RSP // ERROR "illegal destination register" + SWPALB R5, (R6), RSP // ERROR "illegal destination register" + SWPD R5, (R6), RSP // ERROR "illegal destination register" + SWPW R5, (R6), RSP // ERROR "illegal destination register" + SWPH R5, (R6), RSP // ERROR "illegal destination register" + SWPB R5, (R6), RSP // ERROR "illegal destination register" + SWPLD R5, (R6), RSP // ERROR "illegal destination register" + SWPLW R5, (R6), RSP // ERROR "illegal destination register" + SWPLH R5, (R6), RSP // ERROR "illegal destination register" + SWPLB R5, (R6), RSP // ERROR "illegal destination register" + STXR R5, (R6), RSP // ERROR "illegal destination register" + STXRW R5, (R6), RSP // ERROR "illegal destination register" + STLXR R5, (R6), RSP // ERROR "illegal destination register" + STLXRW R5, (R6), RSP // ERROR "illegal destination register" + STXP (R5, R7), (R6), RSP // ERROR "illegal destination register" + STXPW (R5, R7), (R6), RSP // ERROR "illegal destination register" + STLXP (R5, R7), (R6), RSP // ERROR "illegal destination register" + STLXP (R5, R7), (R6), RSP // ERROR "illegal destination register" RET diff --git a/src/cmd/internal/obj/arm64/a.out.go b/src/cmd/internal/obj/arm64/a.out.go index 18cdd10f9b..944eab1955 100644 --- a/src/cmd/internal/obj/arm64/a.out.go +++ b/src/cmd/internal/obj/arm64/a.out.go @@ -598,18 +598,38 @@ const ( AHVC AIC AISB + ALDADDAB + ALDADDAD + ALDADDAH + ALDADDAW ALDADDALB + ALDADDALD ALDADDALH ALDADDALW - ALDADDALD ALDADDB + ALDADDD ALDADDH ALDADDW - ALDADDD + ALDADDLB + ALDADDLD + ALDADDLH + ALDADDLW + ALDANDAB + ALDANDAD + ALDANDAH + ALDANDAW + ALDANDALB + ALDANDALD + ALDANDALH + ALDANDALW ALDANDB + ALDANDD ALDANDH ALDANDW - ALDANDD + ALDANDLB + ALDANDLD + ALDANDLH + ALDANDLW ALDAR ALDARB ALDARH @@ -620,14 +640,38 @@ const ( ALDAXRB ALDAXRH ALDAXRW + ALDEORAB + ALDEORAD + ALDEORAH + ALDEORAW + ALDEORALB + ALDEORALD + ALDEORALH + ALDEORALW ALDEORB + ALDEORD ALDEORH ALDEORW - ALDEORD + ALDEORLB + ALDEORLD + ALDEORLH + ALDEORLW + ALDORAB + ALDORAD + ALDORAH + ALDORAW + ALDORALB + ALDORALD + ALDORALH + ALDORALW ALDORB + ALDORD ALDORH ALDORW - ALDORD + ALDORLB + ALDORLD + ALDORLH + ALDORLW ALDP ALDPW ALDPSW @@ -779,14 +823,22 @@ const ( AMOVPS AMOVPSW AMOVPW - ASWPD + ASWPAD + ASWPAW + ASWPAH + ASWPAB ASWPALD - ASWPW ASWPALW - ASWPH ASWPALH - ASWPB ASWPALB + ASWPD + ASWPW + ASWPH + ASWPB + ASWPLD + ASWPLW + ASWPLH + ASWPLB ABEQ ABNE ABCS diff --git a/src/cmd/internal/obj/arm64/anames.go b/src/cmd/internal/obj/arm64/anames.go index 55e2b5bafb..5af6fdc8de 100644 --- a/src/cmd/internal/obj/arm64/anames.go +++ b/src/cmd/internal/obj/arm64/anames.go @@ -95,18 +95,38 @@ var Anames = []string{ "HVC", "IC", "ISB", + "LDADDAB", + "LDADDAD", + "LDADDAH", + "LDADDAW", "LDADDALB", + "LDADDALD", "LDADDALH", "LDADDALW", - "LDADDALD", "LDADDB", + "LDADDD", "LDADDH", "LDADDW", - "LDADDD", + "LDADDLB", + "LDADDLD", + "LDADDLH", + "LDADDLW", + "LDANDAB", + "LDANDAD", + "LDANDAH", + "LDANDAW", + "LDANDALB", + "LDANDALD", + "LDANDALH", + "LDANDALW", "LDANDB", + "LDANDD", "LDANDH", "LDANDW", - "LDANDD", + "LDANDLB", + "LDANDLD", + "LDANDLH", + "LDANDLW", "LDAR", "LDARB", "LDARH", @@ -117,14 +137,38 @@ var Anames = []string{ "LDAXRB", "LDAXRH", "LDAXRW", + "LDEORAB", + "LDEORAD", + "LDEORAH", + "LDEORAW", + "LDEORALB", + "LDEORALD", + "LDEORALH", + "LDEORALW", "LDEORB", + "LDEORD", "LDEORH", "LDEORW", - "LDEORD", + "LDEORLB", + "LDEORLD", + "LDEORLH", + "LDEORLW", + "LDORAB", + "LDORAD", + "LDORAH", + "LDORAW", + "LDORALB", + "LDORALD", + "LDORALH", + "LDORALW", "LDORB", + "LDORD", "LDORH", "LDORW", - "LDORD", + "LDORLB", + "LDORLD", + "LDORLH", + "LDORLW", "LDP", "LDPW", "LDPSW", @@ -276,14 +320,22 @@ var Anames = []string{ "MOVPS", "MOVPSW", "MOVPW", - "SWPD", + "SWPAD", + "SWPAW", + "SWPAH", + "SWPAB", "SWPALD", - "SWPW", "SWPALW", - "SWPH", "SWPALH", - "SWPB", "SWPALB", + "SWPD", + "SWPW", + "SWPH", + "SWPB", + "SWPLD", + "SWPLW", + "SWPLH", + "SWPLB", "BEQ", "BNE", "BCS", diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index cbe5796234..ef9991a36b 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -79,6 +79,95 @@ type Optab struct { scond uint16 } +func IsAtomicInstruction(as obj.As) bool { + _, ok := atomicInstructions[as] + return ok +} + +// known field values of an instruction. +var atomicInstructions = map[obj.As]uint32{ + ALDADDAD: 3<<30 | 0x1c5<<21 | 0x00<<10, + ALDADDAW: 2<<30 | 0x1c5<<21 | 0x00<<10, + ALDADDAH: 1<<30 | 0x1c5<<21 | 0x00<<10, + ALDADDAB: 0<<30 | 0x1c5<<21 | 0x00<<10, + ALDADDALD: 3<<30 | 0x1c7<<21 | 0x00<<10, + ALDADDALW: 2<<30 | 0x1c7<<21 | 0x00<<10, + ALDADDALH: 1<<30 | 0x1c7<<21 | 0x00<<10, + ALDADDALB: 0<<30 | 0x1c7<<21 | 0x00<<10, + ALDADDD: 3<<30 | 0x1c1<<21 | 0x00<<10, + ALDADDW: 2<<30 | 0x1c1<<21 | 0x00<<10, + ALDADDH: 1<<30 | 0x1c1<<21 | 0x00<<10, + ALDADDB: 0<<30 | 0x1c1<<21 | 0x00<<10, + ALDADDLD: 3<<30 | 0x1c3<<21 | 0x00<<10, + ALDADDLW: 2<<30 | 0x1c3<<21 | 0x00<<10, + ALDADDLH: 1<<30 | 0x1c3<<21 | 0x00<<10, + ALDADDLB: 0<<30 | 0x1c3<<21 | 0x00<<10, + ALDANDAD: 3<<30 | 0x1c5<<21 | 0x04<<10, + ALDANDAW: 2<<30 | 0x1c5<<21 | 0x04<<10, + ALDANDAH: 1<<30 | 0x1c5<<21 | 0x04<<10, + ALDANDAB: 0<<30 | 0x1c5<<21 | 0x04<<10, + ALDANDALD: 3<<30 | 0x1c7<<21 | 0x04<<10, + ALDANDALW: 2<<30 | 0x1c7<<21 | 0x04<<10, + ALDANDALH: 1<<30 | 0x1c7<<21 | 0x04<<10, + ALDANDALB: 0<<30 | 0x1c7<<21 | 0x04<<10, + ALDANDD: 3<<30 | 0x1c1<<21 | 0x04<<10, + ALDANDW: 2<<30 | 0x1c1<<21 | 0x04<<10, + ALDANDH: 1<<30 | 0x1c1<<21 | 0x04<<10, + ALDANDB: 0<<30 | 0x1c1<<21 | 0x04<<10, + ALDANDLD: 3<<30 | 0x1c3<<21 | 0x04<<10, + ALDANDLW: 2<<30 | 0x1c3<<21 | 0x04<<10, + ALDANDLH: 1<<30 | 0x1c3<<21 | 0x04<<10, + ALDANDLB: 0<<30 | 0x1c3<<21 | 0x04<<10, + ALDEORAD: 3<<30 | 0x1c5<<21 | 0x08<<10, + ALDEORAW: 2<<30 | 0x1c5<<21 | 0x08<<10, + ALDEORAH: 1<<30 | 0x1c5<<21 | 0x08<<10, + ALDEORAB: 0<<30 | 0x1c5<<21 | 0x08<<10, + ALDEORALD: 3<<30 | 0x1c7<<21 | 0x08<<10, + ALDEORALW: 2<<30 | 0x1c7<<21 | 0x08<<10, + ALDEORALH: 1<<30 | 0x1c7<<21 | 0x08<<10, + ALDEORALB: 0<<30 | 0x1c7<<21 | 0x08<<10, + ALDEORD: 3<<30 | 0x1c1<<21 | 0x08<<10, + ALDEORW: 2<<30 | 0x1c1<<21 | 0x08<<10, + ALDEORH: 1<<30 | 0x1c1<<21 | 0x08<<10, + ALDEORB: 0<<30 | 0x1c1<<21 | 0x08<<10, + ALDEORLD: 3<<30 | 0x1c3<<21 | 0x08<<10, + ALDEORLW: 2<<30 | 0x1c3<<21 | 0x08<<10, + ALDEORLH: 1<<30 | 0x1c3<<21 | 0x08<<10, + ALDEORLB: 0<<30 | 0x1c3<<21 | 0x08<<10, + ALDORAD: 3<<30 | 0x1c5<<21 | 0x0c<<10, + ALDORAW: 2<<30 | 0x1c5<<21 | 0x0c<<10, + ALDORAH: 1<<30 | 0x1c5<<21 | 0x0c<<10, + ALDORAB: 0<<30 | 0x1c5<<21 | 0x0c<<10, + ALDORALD: 3<<30 | 0x1c7<<21 | 0x0c<<10, + ALDORALW: 2<<30 | 0x1c7<<21 | 0x0c<<10, + ALDORALH: 1<<30 | 0x1c7<<21 | 0x0c<<10, + ALDORALB: 0<<30 | 0x1c7<<21 | 0x0c<<10, + ALDORD: 3<<30 | 0x1c1<<21 | 0x0c<<10, + ALDORW: 2<<30 | 0x1c1<<21 | 0x0c<<10, + ALDORH: 1<<30 | 0x1c1<<21 | 0x0c<<10, + ALDORB: 0<<30 | 0x1c1<<21 | 0x0c<<10, + ALDORLD: 3<<30 | 0x1c3<<21 | 0x0c<<10, + ALDORLW: 2<<30 | 0x1c3<<21 | 0x0c<<10, + ALDORLH: 1<<30 | 0x1c3<<21 | 0x0c<<10, + ALDORLB: 0<<30 | 0x1c3<<21 | 0x0c<<10, + ASWPAD: 3<<30 | 0x1c5<<21 | 0x20<<10, + ASWPAW: 2<<30 | 0x1c5<<21 | 0x20<<10, + ASWPAH: 1<<30 | 0x1c5<<21 | 0x20<<10, + ASWPAB: 0<<30 | 0x1c5<<21 | 0x20<<10, + ASWPALD: 3<<30 | 0x1c7<<21 | 0x20<<10, + ASWPALW: 2<<30 | 0x1c7<<21 | 0x20<<10, + ASWPALH: 1<<30 | 0x1c7<<21 | 0x20<<10, + ASWPALB: 0<<30 | 0x1c7<<21 | 0x20<<10, + ASWPD: 3<<30 | 0x1c1<<21 | 0x20<<10, + ASWPW: 2<<30 | 0x1c1<<21 | 0x20<<10, + ASWPH: 1<<30 | 0x1c1<<21 | 0x20<<10, + ASWPB: 0<<30 | 0x1c1<<21 | 0x20<<10, + ASWPLD: 3<<30 | 0x1c3<<21 | 0x20<<10, + ASWPLW: 2<<30 | 0x1c3<<21 | 0x20<<10, + ASWPLH: 1<<30 | 0x1c3<<21 | 0x20<<10, + ASWPLB: 0<<30 | 0x1c3<<21 | 0x20<<10, +} + var oprange [ALAST & obj.AMask][]Optab var xcmp [C_NCLASS][C_NCLASS]bool @@ -2213,33 +2302,9 @@ func buildop(ctxt *obj.Link) { oprangeset(AMOVZW, t) case ASWPD: - oprangeset(ASWPALD, t) - oprangeset(ASWPB, t) - oprangeset(ASWPH, t) - oprangeset(ASWPW, t) - oprangeset(ASWPALB, t) - oprangeset(ASWPALH, t) - oprangeset(ASWPALW, t) - oprangeset(ALDADDALB, t) - oprangeset(ALDADDALH, t) - oprangeset(ALDADDALW, t) - oprangeset(ALDADDALD, t) - oprangeset(ALDADDB, t) - oprangeset(ALDADDH, t) - oprangeset(ALDADDW, t) - oprangeset(ALDADDD, t) - oprangeset(ALDANDB, t) - oprangeset(ALDANDH, t) - oprangeset(ALDANDW, t) - oprangeset(ALDANDD, t) - oprangeset(ALDEORB, t) - oprangeset(ALDEORH, t) - oprangeset(ALDEORW, t) - oprangeset(ALDEORD, t) - oprangeset(ALDORB, t) - oprangeset(ALDORH, t) - oprangeset(ALDORW, t) - oprangeset(ALDORD, t) + for i := range atomicInstructions { + oprangeset(i, t) + } case ABEQ: oprangeset(ABNE, t) @@ -3659,39 +3724,17 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { o1 |= uint32(p.From.Reg&31) << 5 o1 |= uint32(p.To.Reg & 31) - case 47: /* SWPx Rs, (Rb), Rt: Rs -> (Rb) -> Rt */ + case 47: /* SWPx/LDADDx/LDANDx/LDEORx/LDORx Rs, (Rb), Rt */ rs := p.From.Reg rt := p.RegTo2 rb := p.To.Reg - switch p.As { - case ASWPD, ASWPALD, ALDADDALD, ALDADDD, ALDANDD, ALDEORD, ALDORD: // 64-bit - o1 = 3 << 30 - case ASWPW, ASWPALW, ALDADDALW, ALDADDW, ALDANDW, ALDEORW, ALDORW: // 32-bit - o1 = 2 << 30 - case ASWPH, ASWPALH, ALDADDALH, ALDADDH, ALDANDH, ALDEORH, ALDORH: // 16-bit - o1 = 1 << 30 - case ASWPB, ASWPALB, ALDADDALB, ALDADDB, ALDANDB, ALDEORB, ALDORB: // 8-bit - o1 = 0 << 30 - default: - c.ctxt.Diag("illegal instruction: %v\n", p) - } - switch p.As { - case ASWPD, ASWPW, ASWPH, ASWPB, ASWPALD, ASWPALW, ASWPALH, ASWPALB: - o1 |= 0x20 << 10 - case ALDADDALD, ALDADDALW, ALDADDALH, ALDADDALB, ALDADDD, ALDADDW, ALDADDH, ALDADDB: - o1 |= 0x00 << 10 - case ALDANDD, ALDANDW, ALDANDH, ALDANDB: - o1 |= 0x04 << 10 - case ALDEORD, ALDEORW, ALDEORH, ALDEORB: - o1 |= 0x08 << 10 - case ALDORD, ALDORW, ALDORH, ALDORB: - o1 |= 0x0c << 10 - } - switch p.As { - case ALDADDALD, ALDADDALW, ALDADDALH, ALDADDALB, ASWPALD, ASWPALW, ASWPALH, ASWPALB: - o1 |= 3 << 22 + + fields := atomicInstructions[p.As] + // rt can't be sp. rt can't be r31 when field A is 0, A bit is the 23rd bit. + if rt == REG_RSP || (rt == REGZERO && (fields&(1<<23) == 0)) { + c.ctxt.Diag("illegal destination register: %v\n", p) } - o1 |= 0x1c1<<21 | uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31) + o1 |= fields | uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31) case 48: /* ADD $C_ADDCON2, Rm, Rd */ op := c.opirr(p, p.As) @@ -3846,6 +3889,9 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { c.ctxt.Diag("constrained unpredictable behavior: %v", p) } } + if s == REG_RSP { + c.ctxt.Diag("illegal destination register: %v\n", p) + } o1 = c.opstore(p, p.As) if p.RegTo2 != obj.REG_NONE { -- 2.50.0