mirror of
https://github.com/golang/go
synced 2024-11-23 16:50:06 -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:
parent
fc7a72596b
commit
0a5be12f5c
@ -205,6 +205,16 @@ func archArm() *Arch {
|
||||
"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)
|
||||
for i, s := range obj.Anames {
|
||||
instructions[s] = obj.As(i)
|
||||
|
@ -86,7 +86,6 @@ const (
|
||||
REG_CPSR // must be 2-aligned
|
||||
REG_SPSR
|
||||
|
||||
MAXREG
|
||||
REGRET = REG_R0
|
||||
/* compiler allocates R1 up as temps */
|
||||
/* 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
|
||||
}
|
||||
|
||||
// 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 (
|
||||
C_NONE = iota
|
||||
C_REG
|
||||
@ -135,6 +150,7 @@ const (
|
||||
C_FREG
|
||||
C_PSR
|
||||
C_FCR
|
||||
C_SPR /* REG_MB_SY */
|
||||
|
||||
C_RCON /* 0xff rotated */
|
||||
C_NCON /* ~RCON */
|
||||
@ -319,6 +335,8 @@ const (
|
||||
ALDREXD
|
||||
ASTREXD
|
||||
|
||||
ADMB
|
||||
|
||||
APLD
|
||||
|
||||
ACLZ
|
||||
|
@ -119,6 +119,7 @@ var Anames = []string{
|
||||
"STREX",
|
||||
"LDREXD",
|
||||
"STREXD",
|
||||
"DMB",
|
||||
"PLD",
|
||||
"CLZ",
|
||||
"REV",
|
||||
|
@ -15,6 +15,7 @@ var cnames5 = []string{
|
||||
"FREG",
|
||||
"PSR",
|
||||
"FCR",
|
||||
"SPR",
|
||||
"RCON",
|
||||
"NCON",
|
||||
"RCON2A",
|
||||
|
@ -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},
|
||||
{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},
|
||||
{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_SFCON, C_NONE, C_FREG, 81, 4, 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},
|
||||
}
|
||||
|
||||
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 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 {
|
||||
return C_PSR
|
||||
}
|
||||
if a.Reg >= REG_SPECIAL {
|
||||
return C_SPR
|
||||
}
|
||||
return C_GOK
|
||||
|
||||
case obj.TYPE_REGREG:
|
||||
@ -1697,6 +1717,7 @@ func buildop(ctxt *obj.Link) {
|
||||
ASTREX,
|
||||
ALDREXD,
|
||||
ASTREXD,
|
||||
ADMB,
|
||||
APLD,
|
||||
AAND,
|
||||
AMULA,
|
||||
@ -2786,6 +2807,35 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
|
||||
r = rt
|
||||
}
|
||||
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
|
||||
|
@ -68,6 +68,23 @@ func rconv(r int) string {
|
||||
|
||||
case REG_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)
|
||||
|
@ -785,7 +785,7 @@ TEXT runtime·armPublicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
|
||||
MOVB runtime·goarm(SB), R11
|
||||
CMP $7, R11
|
||||
BLT 2(PC)
|
||||
WORD $0xf57ff05e // DMB ST
|
||||
DMB MB_ST
|
||||
RET
|
||||
|
||||
// AES hashing not implemented for ARM
|
||||
|
@ -30,7 +30,7 @@ casl:
|
||||
MOVB runtime·goarm(SB), R11
|
||||
CMP $7, R11
|
||||
BLT 2(PC)
|
||||
WORD $0xf57ff05a // dmb ishst
|
||||
DMB MB_ISHST
|
||||
|
||||
STREX R3, (R1), R0
|
||||
CMP $0, R0
|
||||
@ -40,7 +40,7 @@ casl:
|
||||
MOVB runtime·goarm(SB), R11
|
||||
CMP $7, R11
|
||||
BLT 2(PC)
|
||||
WORD $0xf57ff05b // dmb ish
|
||||
DMB MB_ISH
|
||||
|
||||
MOVB R0, ret+12(FP)
|
||||
RET
|
||||
|
@ -12,13 +12,13 @@
|
||||
MOVB runtime·goarm(SB), R11; \
|
||||
CMP $7, R11; \
|
||||
BLT 2(PC); \
|
||||
WORD $0xf57ff05a // dmb ishst
|
||||
DMB MB_ISHST
|
||||
|
||||
#define DMB_ISH_7 \
|
||||
MOVB runtime·goarm(SB), R11; \
|
||||
CMP $7, R11; \
|
||||
BLT 2(PC); \
|
||||
WORD $0xf57ff05b // dmb ish
|
||||
DMB MB_ISH
|
||||
|
||||
TEXT ·armCompareAndSwapUint32(SB),NOSPLIT,$0-13
|
||||
MOVW addr+0(FP), R1
|
||||
|
@ -6,12 +6,6 @@
|
||||
|
||||
// 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
|
||||
B ·CompareAndSwapUint32(SB)
|
||||
|
||||
@ -64,11 +58,11 @@ TEXT ·LoadUint32(SB),NOSPLIT,$0-8
|
||||
MOVW addr+0(FP), R1
|
||||
load32loop:
|
||||
LDREX (R1), R2 // loads R2
|
||||
DMB_ISHST_7
|
||||
DMB MB_ISHST
|
||||
STREX R2, (R1), R0 // stores R2
|
||||
CMP $0, R0
|
||||
BNE load32loop
|
||||
DMB_ISH_7
|
||||
DMB MB_ISH
|
||||
MOVW R2, val+4(FP)
|
||||
RET
|
||||
|
||||
@ -92,11 +86,11 @@ TEXT ·StoreUint32(SB),NOSPLIT,$0-8
|
||||
MOVW val+4(FP), R2
|
||||
storeloop:
|
||||
LDREX (R1), R4 // loads R4
|
||||
DMB_ISHST_7
|
||||
DMB MB_ISHST
|
||||
STREX R2, (R1), R0 // stores R2
|
||||
CMP $0, R0
|
||||
BNE storeloop
|
||||
DMB_ISH_7
|
||||
DMB MB_ISH
|
||||
RET
|
||||
|
||||
TEXT ·StoreInt64(SB),NOSPLIT,$0
|
||||
|
@ -8,7 +8,7 @@
|
||||
MOVB runtime·goarm(SB), R11; \
|
||||
CMP $7, R11; \
|
||||
BLT 2(PC); \
|
||||
WORD $0xf57ff05b // dmb ish
|
||||
DMB MB_ISH
|
||||
|
||||
// Plan9/ARM atomic operations.
|
||||
// TODO(minux): this only supports ARMv6K or higher.
|
||||
|
Loading…
Reference in New Issue
Block a user