mirror of
https://github.com/golang/go
synced 2024-11-18 10:54:40 -07:00
cmd/internal/obj/arm64: add more atomic instructions
More atomic instructions were introduced in ARMv8.1. And this CL adds support for them and corresponding test cases. LDADD Rs, (Rb), Rt: (Rb) -> Rt, Rs+(Rb) -> (Rb) LDAND Rs, (Rb), Rt: (Rb) -> Rt, Rs&(Rb) -> (Rb) LDEOR Rs, (Rb), Rt: (Rb) -> Rt, Rs^(Rb) -> (Rb) LDOR Rs, (Rb), Rt: (Rb) -> Rt, Rs|(Rb) -> (Rb) Change-Id: Ifb9df86583c4dc54fb96274852c3b93a197045e4 Reviewed-on: https://go-review.googlesource.com/110535 Reviewed-by: Cherry Zhang <cherryyz@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
3c0bf181b7
commit
fc48dcb15f
@ -72,18 +72,12 @@ 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:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsARM64SWP reports whether the op (as defined by an arm64.A*
|
||||
// constant) is one of the SWP-like instructions that require special
|
||||
// handling.
|
||||
func IsARM64SWP(op obj.As) bool {
|
||||
switch op {
|
||||
case arm64.ASWPD, arm64.ASWPW, arm64.ASWPH, arm64.ASWPB:
|
||||
arm64.ASTXP, arm64.ASTXPW, arm64.ASTLXP, arm64.ASTLXPW,
|
||||
arm64.ASWPB, arm64.ASWPH, arm64.ASWPW, arm64.ASWPD,
|
||||
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:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
@ -570,12 +570,6 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||
prog.RegTo2 = a[2].Reg
|
||||
break
|
||||
}
|
||||
if arch.IsARM64SWP(op) {
|
||||
prog.From = a[1]
|
||||
prog.Reg = p.getRegister(prog, op, &a[0])
|
||||
prog.To = a[2]
|
||||
break
|
||||
}
|
||||
if arch.IsARM64TBL(op) {
|
||||
prog.From = a[0]
|
||||
if a[1].Type != obj.TYPE_REGLIST {
|
||||
|
50
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
50
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
@ -537,6 +537,46 @@ 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
|
||||
LDADDD R5, (R6), R7 // c70025f8
|
||||
LDADDD R5, (RSP), R7 // e70325f8
|
||||
LDADDW R5, (R6), R7 // c70025b8
|
||||
LDADDW R5, (RSP), R7 // e70325b8
|
||||
LDADDH R5, (R6), R7 // c7002578
|
||||
LDADDH R5, (RSP), R7 // e7032578
|
||||
LDADDB R5, (R6), R7 // c7002538
|
||||
LDADDB R5, (RSP), R7 // e7032538
|
||||
LDANDD R5, (R6), R7 // c71025f8
|
||||
LDANDD R5, (RSP), R7 // e71325f8
|
||||
LDANDW R5, (R6), R7 // c71025b8
|
||||
LDANDW R5, (RSP), R7 // e71325b8
|
||||
LDANDH R5, (R6), R7 // c7102578
|
||||
LDANDH R5, (RSP), R7 // e7132578
|
||||
LDANDB R5, (R6), R7 // c7102538
|
||||
LDANDB R5, (RSP), R7 // e7132538
|
||||
LDEORD R5, (R6), R7 // c72025f8
|
||||
LDEORD R5, (RSP), R7 // e72325f8
|
||||
LDEORW R5, (R6), R7 // c72025b8
|
||||
LDEORW R5, (RSP), R7 // e72325b8
|
||||
LDEORH R5, (R6), R7 // c7202578
|
||||
LDEORH R5, (RSP), R7 // e7232578
|
||||
LDEORB R5, (R6), R7 // c7202538
|
||||
LDEORB R5, (RSP), R7 // e7232538
|
||||
LDORD R5, (R6), R7 // c73025f8
|
||||
LDORD R5, (RSP), R7 // e73325f8
|
||||
LDORW R5, (R6), R7 // c73025b8
|
||||
LDORW R5, (RSP), R7 // e73325b8
|
||||
LDORH R5, (R6), R7 // c7302578
|
||||
LDORH R5, (RSP), R7 // e7332578
|
||||
LDORB R5, (R6), R7 // c7302538
|
||||
LDORB R5, (RSP), R7 // e7332538
|
||||
|
||||
// RET
|
||||
//
|
||||
@ -647,16 +687,6 @@ again:
|
||||
STPW (R3, R4), x(SB)
|
||||
STPW (R3, R4), x+8(SB)
|
||||
|
||||
// SWPD/SWPW/SWPH/SWPB
|
||||
SWPD R5, (R6), R7 // SWPD (R6), R5, R7 // c78025f8
|
||||
SWPD R5, (RSP), R7 // SWPD (RSP), R5, R7 // e78325f8
|
||||
SWPW R5, (R6), R7 // SWPW (R6), R5, R7 // c78025b8
|
||||
SWPW R5, (RSP), R7 // SWPW (RSP), R5, R7 // e78325b8
|
||||
SWPH R5, (R6), R7 // SWPH (R6), R5, R7 // c7802578
|
||||
SWPH R5, (RSP), R7 // SWPH (RSP), R5, R7 // e7832578
|
||||
SWPB R5, (R6), R7 // SWPB (R6), R5, R7 // c7802538
|
||||
SWPB R5, (RSP), R7 // SWPB (RSP), R5, R7 // e7832538
|
||||
|
||||
// END
|
||||
//
|
||||
// LTYPEE comma
|
||||
|
@ -594,6 +594,14 @@ const (
|
||||
AHVC
|
||||
AIC
|
||||
AISB
|
||||
ALDADDB
|
||||
ALDADDH
|
||||
ALDADDW
|
||||
ALDADDD
|
||||
ALDANDB
|
||||
ALDANDH
|
||||
ALDANDW
|
||||
ALDANDD
|
||||
ALDAR
|
||||
ALDARB
|
||||
ALDARH
|
||||
@ -604,6 +612,14 @@ const (
|
||||
ALDAXRB
|
||||
ALDAXRH
|
||||
ALDAXRW
|
||||
ALDEORB
|
||||
ALDEORH
|
||||
ALDEORW
|
||||
ALDEORD
|
||||
ALDORB
|
||||
ALDORH
|
||||
ALDORW
|
||||
ALDORD
|
||||
ALDP
|
||||
ALDPW
|
||||
ALDPSW
|
||||
|
@ -96,6 +96,14 @@ var Anames = []string{
|
||||
"HVC",
|
||||
"IC",
|
||||
"ISB",
|
||||
"LDADDB",
|
||||
"LDADDH",
|
||||
"LDADDW",
|
||||
"LDADDD",
|
||||
"LDANDB",
|
||||
"LDANDH",
|
||||
"LDANDW",
|
||||
"LDANDD",
|
||||
"LDAR",
|
||||
"LDARB",
|
||||
"LDARH",
|
||||
@ -106,6 +114,14 @@ var Anames = []string{
|
||||
"LDAXRB",
|
||||
"LDAXRH",
|
||||
"LDAXRW",
|
||||
"LDEORB",
|
||||
"LDEORH",
|
||||
"LDEORW",
|
||||
"LDEORD",
|
||||
"LDORB",
|
||||
"LDORH",
|
||||
"LDORW",
|
||||
"LDORD",
|
||||
"LDP",
|
||||
"LDPW",
|
||||
"LDPSW",
|
||||
|
@ -370,10 +370,6 @@ var optab = []Optab{
|
||||
{ACCMN, C_COND, C_REG, C_VCON, 19, 4, 0, 0, 0}, /* from3 either C_REG or C_VCON */
|
||||
{AFCCMPS, C_COND, C_FREG, C_VCON, 57, 4, 0, 0, 0},
|
||||
|
||||
/* SWPD/SWPW/SWPH/SWPB */
|
||||
{ASWPD, C_ZAUTO, C_REG, C_REG, 47, 4, REGSP, 0, 0},
|
||||
{ASWPD, C_ZOREG, C_REG, C_REG, 47, 4, 0, 0, 0},
|
||||
|
||||
/* scaled 12-bit unsigned displacement store */
|
||||
{AMOVB, C_REG, C_NONE, C_UAUTO4K, 20, 4, REGSP, 0, 0},
|
||||
{AMOVB, C_REG, C_NONE, C_UOREG4K, 20, 4, 0, 0, 0},
|
||||
@ -657,13 +653,15 @@ var optab = []Optab{
|
||||
{ASTPW, C_PAIR, C_NONE, C_LOREG, 77, 12, 0, LTO, C_XPOST},
|
||||
{ASTPW, C_PAIR, C_NONE, C_ADDR, 87, 12, 0, 0, 0},
|
||||
|
||||
{ASWPD, C_REG, C_NONE, C_ZOREG, 47, 4, 0, 0, 0}, // RegTo2=C_REG
|
||||
{ASWPD, C_REG, C_NONE, C_ZAUTO, 47, 4, REGSP, 0, 0}, // RegTo2=C_REG
|
||||
{ALDAR, C_ZOREG, C_NONE, C_REG, 58, 4, 0, 0, 0},
|
||||
{ALDXR, C_ZOREG, C_NONE, C_REG, 58, 4, 0, 0, 0},
|
||||
{ALDAXR, C_ZOREG, C_NONE, C_REG, 58, 4, 0, 0, 0},
|
||||
{ALDXP, C_ZOREG, C_NONE, C_PAIR, 58, 4, 0, 0, 0},
|
||||
{ASTLR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // to3=C_NONE
|
||||
{ASTXR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // to3=C_REG
|
||||
{ASTLXR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // to3=C_REG
|
||||
{ASTLR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // RegTo2=C_NONE
|
||||
{ASTXR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // RegTo2=C_REG
|
||||
{ASTLXR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // RegTo2=C_REG
|
||||
{ASTXP, C_PAIR, C_NONE, C_ZOREG, 59, 4, 0, 0, 0},
|
||||
|
||||
/* VLD1/VST1 */
|
||||
@ -1995,6 +1993,22 @@ func buildop(ctxt *obj.Link) {
|
||||
oprangeset(ASWPB, t)
|
||||
oprangeset(ASWPH, t)
|
||||
oprangeset(ASWPW, 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)
|
||||
|
||||
case ABEQ:
|
||||
oprangeset(ABNE, t)
|
||||
@ -3333,26 +3347,34 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
|
||||
o1 |= uint32(p.To.Reg & 31)
|
||||
|
||||
case 47: /* SWPx Rs, (Rb), Rt: Rs -> (Rb) -> Rt */
|
||||
v := int32(c.regoff(&p.From))
|
||||
rb := int(p.From.Reg)
|
||||
if v != 0 {
|
||||
c.ctxt.Diag("invalid offset: %v\n", p)
|
||||
}
|
||||
rs := p.Reg
|
||||
rt := p.To.Reg
|
||||
rs := p.From.Reg
|
||||
rt := p.RegTo2
|
||||
rb := p.To.Reg
|
||||
switch p.As {
|
||||
case ASWPD:
|
||||
case ASWPD, ALDADDD, ALDANDD, ALDEORD, ALDORD: // 64-bit
|
||||
o1 = 3 << 30
|
||||
case ASWPW:
|
||||
case ASWPW, ALDADDW, ALDANDW, ALDEORW, ALDORW: // 32-bit
|
||||
o1 = 2 << 30
|
||||
case ASWPH:
|
||||
case ASWPH, ALDADDH, ALDANDH, ALDEORH, ALDORH: // 16-bit
|
||||
o1 = 1 << 30
|
||||
case ASWPB:
|
||||
case ASWPB, ALDADDB, ALDANDB, ALDEORB, ALDORB: // 8-bit
|
||||
o1 = 0 << 30
|
||||
default:
|
||||
c.ctxt.Diag("illegal instruction: %v\n", p)
|
||||
}
|
||||
o1 |= 0x1c1<<21 | 0x20<<10 | uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31)
|
||||
switch p.As {
|
||||
case ASWPD, ASWPW, ASWPH, ASWPB:
|
||||
o1 |= 0x20 << 10
|
||||
case 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
|
||||
}
|
||||
o1 |= 0x1c1<<21 | uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31)
|
||||
|
||||
case 50: /* sys/sysl */
|
||||
o1 = c.opirr(p, p.As)
|
||||
|
Loading…
Reference in New Issue
Block a user