1
0
mirror of https://github.com/golang/go synced 2024-11-23 18:40:03 -07:00

cmd/internal/obj/arm: add DMB instruction

Change-Id: Ib67a61d5b37af210ff15d60d72bd5238b9c2d0ca
Reviewed-on: https://go-review.googlesource.com/94815
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Yuval Pavel Zholkover 2018-02-16 15:54:55 +02:00 committed by Cherry Zhang
parent fc7a72596b
commit 0a5be12f5c
11 changed files with 108 additions and 17 deletions

View File

@ -205,6 +205,16 @@ func archArm() *Arch {
"R": true, "R": true,
} }
// special operands for DMB/DSB instructions
register["MB_SY"] = arm.REG_MB_SY
register["MB_ST"] = arm.REG_MB_ST
register["MB_ISH"] = arm.REG_MB_ISH
register["MB_ISHST"] = arm.REG_MB_ISHST
register["MB_NSH"] = arm.REG_MB_NSH
register["MB_NSHST"] = arm.REG_MB_NSHST
register["MB_OSH"] = arm.REG_MB_OSH
register["MB_OSHST"] = arm.REG_MB_OSHST
instructions := make(map[string]obj.As) instructions := make(map[string]obj.As)
for i, s := range obj.Anames { for i, s := range obj.Anames {
instructions[s] = obj.As(i) instructions[s] = obj.As(i)

View File

@ -86,7 +86,6 @@ const (
REG_CPSR // must be 2-aligned REG_CPSR // must be 2-aligned
REG_SPSR REG_SPSR
MAXREG
REGRET = REG_R0 REGRET = REG_R0
/* compiler allocates R1 up as temps */ /* compiler allocates R1 up as temps */
/* compiler allocates register variables R3 up */ /* compiler allocates register variables R3 up */
@ -124,6 +123,22 @@ func init() {
f(REG_F0, REG_F15, 64, 2) // Use d0 through D15, aka S0, S2, ..., S30 f(REG_F0, REG_F15, 64, 2) // Use d0 through D15, aka S0, S2, ..., S30
} }
// Special registers, after subtracting obj.RBaseARM, bit 9 indicates
// a special register and the low bits select the register.
const (
REG_SPECIAL = obj.RBaseARM + 1<<9 + iota
REG_MB_SY
REG_MB_ST
REG_MB_ISH
REG_MB_ISHST
REG_MB_NSH
REG_MB_NSHST
REG_MB_OSH
REG_MB_OSHST
MAXREG
)
const ( const (
C_NONE = iota C_NONE = iota
C_REG C_REG
@ -135,6 +150,7 @@ const (
C_FREG C_FREG
C_PSR C_PSR
C_FCR C_FCR
C_SPR /* REG_MB_SY */
C_RCON /* 0xff rotated */ C_RCON /* 0xff rotated */
C_NCON /* ~RCON */ C_NCON /* ~RCON */
@ -319,6 +335,8 @@ const (
ALDREXD ALDREXD
ASTREXD ASTREXD
ADMB
APLD APLD
ACLZ ACLZ

View File

@ -119,6 +119,7 @@ var Anames = []string{
"STREX", "STREX",
"LDREXD", "LDREXD",
"STREXD", "STREXD",
"DMB",
"PLD", "PLD",
"CLZ", "CLZ",
"REV", "REV",

View File

@ -15,6 +15,7 @@ var cnames5 = []string{
"FREG", "FREG",
"PSR", "PSR",
"FCR", "FCR",
"SPR",
"RCON", "RCON",
"NCON", "NCON",
"RCON2A", "RCON2A",

View File

@ -303,6 +303,9 @@ var optab = []Optab{
{AMOVHU, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT}, {AMOVHU, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
{ALDREX, C_SOREG, C_NONE, C_REG, 77, 4, 0, 0, 0, 0}, {ALDREX, C_SOREG, C_NONE, C_REG, 77, 4, 0, 0, 0, 0},
{ASTREX, C_SOREG, C_REG, C_REG, 78, 4, 0, 0, 0, 0}, {ASTREX, C_SOREG, C_REG, C_REG, 78, 4, 0, 0, 0, 0},
{ADMB, C_NONE, C_NONE, C_NONE, 110, 4, 0, 0, 0, 0},
{ADMB, C_LCON, C_NONE, C_NONE, 110, 4, 0, 0, 0, 0},
{ADMB, C_SPR, C_NONE, C_NONE, 110, 4, 0, 0, 0, 0},
{AMOVF, C_ZFCON, C_NONE, C_FREG, 80, 8, 0, 0, 0, 0}, {AMOVF, C_ZFCON, C_NONE, C_FREG, 80, 8, 0, 0, 0, 0},
{AMOVF, C_SFCON, C_NONE, C_FREG, 81, 4, 0, 0, 0, 0}, {AMOVF, C_SFCON, C_NONE, C_FREG, 81, 4, 0, 0, 0, 0},
{ACMPF, C_FREG, C_FREG, C_NONE, 82, 8, 0, 0, 0, 0}, {ACMPF, C_FREG, C_FREG, C_NONE, 82, 8, 0, 0, 0, 0},
@ -331,6 +334,20 @@ var optab = []Optab{
{obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0, 0, 0}, {obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0, 0, 0},
} }
var mbOp = []struct {
reg int16
enc uint32
}{
{REG_MB_SY, 15},
{REG_MB_ST, 14},
{REG_MB_ISH, 11},
{REG_MB_ISHST, 10},
{REG_MB_NSH, 7},
{REG_MB_NSHST, 6},
{REG_MB_OSH, 3},
{REG_MB_OSHST, 2},
}
var oprange [ALAST & obj.AMask][]Optab var oprange [ALAST & obj.AMask][]Optab
var xcmp [C_GOK + 1][C_GOK + 1]bool var xcmp [C_GOK + 1][C_GOK + 1]bool
@ -1103,6 +1120,9 @@ func (c *ctxt5) aclass(a *obj.Addr) int {
if a.Reg == REG_CPSR || a.Reg == REG_SPSR { if a.Reg == REG_CPSR || a.Reg == REG_SPSR {
return C_PSR return C_PSR
} }
if a.Reg >= REG_SPECIAL {
return C_SPR
}
return C_GOK return C_GOK
case obj.TYPE_REGREG: case obj.TYPE_REGREG:
@ -1697,6 +1717,7 @@ func buildop(ctxt *obj.Link) {
ASTREX, ASTREX,
ALDREXD, ALDREXD,
ASTREXD, ASTREXD,
ADMB,
APLD, APLD,
AAND, AAND,
AMULA, AMULA,
@ -2786,6 +2807,35 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
r = rt r = rt
} }
o1 |= (uint32(rf)&15)<<8 | (uint32(r)&15)<<0 | (uint32(rt)&15)<<16 o1 |= (uint32(rf)&15)<<8 | (uint32(r)&15)<<0 | (uint32(rt)&15)<<16
case 110: /* dmb [mbop | $con] */
o1 = 0xf57ff050
mbop := uint32(0)
switch c.aclass(&p.From) {
case C_SPR:
for _, f := range mbOp {
if f.reg == p.From.Reg {
mbop = f.enc
break
}
}
case C_RCON:
for _, f := range mbOp {
enc := uint32(c.instoffset)
if f.enc == enc {
mbop = enc
break
}
}
case C_NONE:
mbop = 0xf
}
if mbop == 0 {
c.ctxt.Diag("illegal mb option:\n%v", p)
}
o1 |= mbop
} }
out[0] = o1 out[0] = o1

View File

@ -68,6 +68,23 @@ func rconv(r int) string {
case REG_SPSR: case REG_SPSR:
return "SPSR" return "SPSR"
case REG_MB_SY:
return "MB_SY"
case REG_MB_ST:
return "MB_ST"
case REG_MB_ISH:
return "MB_ISH"
case REG_MB_ISHST:
return "MB_ISHST"
case REG_MB_NSH:
return "MB_NSH"
case REG_MB_NSHST:
return "MB_NSHST"
case REG_MB_OSH:
return "MB_OSH"
case REG_MB_OSHST:
return "MB_OSHST"
} }
return fmt.Sprintf("Rgok(%d)", r-obj.RBaseARM) return fmt.Sprintf("Rgok(%d)", r-obj.RBaseARM)

View File

@ -785,7 +785,7 @@ TEXT runtime·armPublicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
MOVB runtime·goarm(SB), R11 MOVB runtime·goarm(SB), R11
CMP $7, R11 CMP $7, R11
BLT 2(PC) BLT 2(PC)
WORD $0xf57ff05e // DMB ST DMB MB_ST
RET RET
// AES hashing not implemented for ARM // AES hashing not implemented for ARM

View File

@ -30,7 +30,7 @@ casl:
MOVB runtime·goarm(SB), R11 MOVB runtime·goarm(SB), R11
CMP $7, R11 CMP $7, R11
BLT 2(PC) BLT 2(PC)
WORD $0xf57ff05a // dmb ishst DMB MB_ISHST
STREX R3, (R1), R0 STREX R3, (R1), R0
CMP $0, R0 CMP $0, R0
@ -40,7 +40,7 @@ casl:
MOVB runtime·goarm(SB), R11 MOVB runtime·goarm(SB), R11
CMP $7, R11 CMP $7, R11
BLT 2(PC) BLT 2(PC)
WORD $0xf57ff05b // dmb ish DMB MB_ISH
MOVB R0, ret+12(FP) MOVB R0, ret+12(FP)
RET RET

View File

@ -12,13 +12,13 @@
MOVB runtime·goarm(SB), R11; \ MOVB runtime·goarm(SB), R11; \
CMP $7, R11; \ CMP $7, R11; \
BLT 2(PC); \ BLT 2(PC); \
WORD $0xf57ff05a // dmb ishst DMB MB_ISHST
#define DMB_ISH_7 \ #define DMB_ISH_7 \
MOVB runtime·goarm(SB), R11; \ MOVB runtime·goarm(SB), R11; \
CMP $7, R11; \ CMP $7, R11; \
BLT 2(PC); \ BLT 2(PC); \
WORD $0xf57ff05b // dmb ish DMB MB_ISH
TEXT ·armCompareAndSwapUint32(SB),NOSPLIT,$0-13 TEXT ·armCompareAndSwapUint32(SB),NOSPLIT,$0-13
MOVW addr+0(FP), R1 MOVW addr+0(FP), R1

View File

@ -6,12 +6,6 @@
// Darwin/ARM atomic operations. // Darwin/ARM atomic operations.
#define DMB_ISHST_7 \
WORD $0xf57ff05a // dmb ishst
#define DMB_ISH_7 \
WORD $0xf57ff05b // dmb ish
TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0 TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0
B ·CompareAndSwapUint32(SB) B ·CompareAndSwapUint32(SB)
@ -64,11 +58,11 @@ TEXT ·LoadUint32(SB),NOSPLIT,$0-8
MOVW addr+0(FP), R1 MOVW addr+0(FP), R1
load32loop: load32loop:
LDREX (R1), R2 // loads R2 LDREX (R1), R2 // loads R2
DMB_ISHST_7 DMB MB_ISHST
STREX R2, (R1), R0 // stores R2 STREX R2, (R1), R0 // stores R2
CMP $0, R0 CMP $0, R0
BNE load32loop BNE load32loop
DMB_ISH_7 DMB MB_ISH
MOVW R2, val+4(FP) MOVW R2, val+4(FP)
RET RET
@ -92,11 +86,11 @@ TEXT ·StoreUint32(SB),NOSPLIT,$0-8
MOVW val+4(FP), R2 MOVW val+4(FP), R2
storeloop: storeloop:
LDREX (R1), R4 // loads R4 LDREX (R1), R4 // loads R4
DMB_ISHST_7 DMB MB_ISHST
STREX R2, (R1), R0 // stores R2 STREX R2, (R1), R0 // stores R2
CMP $0, R0 CMP $0, R0
BNE storeloop BNE storeloop
DMB_ISH_7 DMB MB_ISH
RET RET
TEXT ·StoreInt64(SB),NOSPLIT,$0 TEXT ·StoreInt64(SB),NOSPLIT,$0

View File

@ -8,7 +8,7 @@
MOVB runtime·goarm(SB), R11; \ MOVB runtime·goarm(SB), R11; \
CMP $7, R11; \ CMP $7, R11; \
BLT 2(PC); \ BLT 2(PC); \
WORD $0xf57ff05b // dmb ish DMB MB_ISH
// Plan9/ARM atomic operations. // Plan9/ARM atomic operations.
// TODO(minux): this only supports ARMv6K or higher. // TODO(minux): this only supports ARMv6K or higher.