Commit 44808985 authored by erifan01's avatar erifan01 Committed by Cherry Zhang

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/+/157001Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 40d8c3d3
......@@ -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
......
......@@ -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
......
......@@ -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
......@@ -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
......
......@@ -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",
......
......@@ -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 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment