diff options
Diffstat (limited to 'src/cmd/internal/obj')
| -rw-r--r-- | src/cmd/internal/obj/arm/a.out.go | 2 | ||||
| -rw-r--r-- | src/cmd/internal/obj/arm/anames.go | 2 | ||||
| -rw-r--r-- | src/cmd/internal/obj/arm/asm5.go | 34 |
3 files changed, 30 insertions, 8 deletions
diff --git a/src/cmd/internal/obj/arm/a.out.go b/src/cmd/internal/obj/arm/a.out.go index fd695ad0c9..fabd0cb50f 100644 --- a/src/cmd/internal/obj/arm/a.out.go +++ b/src/cmd/internal/obj/arm/a.out.go @@ -333,7 +333,9 @@ const ( ALDREX ASTREX ALDREXD + ALDREXB ASTREXD + ASTREXB ADMB diff --git a/src/cmd/internal/obj/arm/anames.go b/src/cmd/internal/obj/arm/anames.go index f5e92defc9..04537759c1 100644 --- a/src/cmd/internal/obj/arm/anames.go +++ b/src/cmd/internal/obj/arm/anames.go @@ -117,7 +117,9 @@ var Anames = []string{ "LDREX", "STREX", "LDREXD", + "LDREXB", "STREXD", + "STREXB", "DMB", "PLD", "CLZ", diff --git a/src/cmd/internal/obj/arm/asm5.go b/src/cmd/internal/obj/arm/asm5.go index a02519c147..bf9623c206 100644 --- a/src/cmd/internal/obj/arm/asm5.go +++ b/src/cmd/internal/obj/arm/asm5.go @@ -318,7 +318,9 @@ var optab = []Optab{ {AMOVW, C_REG, C_NONE, C_FREG, 88, 4, 0, 0, 0, 0}, {AMOVW, C_FREG, C_NONE, C_REG, 89, 4, 0, 0, 0, 0}, {ALDREXD, C_SOREG, C_NONE, C_REG, 91, 4, 0, 0, 0, 0}, + {ALDREXB, C_SOREG, C_NONE, C_REG, 91, 4, 0, 0, 0, 0}, {ASTREXD, C_SOREG, C_REG, C_REG, 92, 4, 0, 0, 0, 0}, + {ASTREXB, C_SOREG, C_REG, C_REG, 92, 4, 0, 0, 0, 0}, {APLD, C_SOREG, C_NONE, C_NONE, 95, 4, 0, 0, 0, 0}, {obj.AUNDEF, C_NONE, C_NONE, C_NONE, 96, 4, 0, 0, 0, 0}, {ACLZ, C_REG, C_NONE, C_REG, 97, 4, 0, 0, 0, 0}, @@ -1432,7 +1434,9 @@ func buildop(ctxt *obj.Link) { case ALDREX, ASTREX, ALDREXD, + ALDREXB, ASTREXD, + ASTREXB, ADMB, APLD, AAND, @@ -2397,30 +2401,44 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) { o1 |= (uint32(p.From.Reg) & 15) << 16 o1 |= (uint32(p.To.Reg) & 15) << 12 - case 91: /* ldrexd oreg,reg */ + case 91: /* ldrexd/ldrexb oreg,reg */ c.aclass(&p.From) if c.instoffset != 0 { c.ctxt.Diag("offset must be zero in LDREX") } - o1 = 0x1b<<20 | 0xf9f + + switch p.As { + case ALDREXD: + o1 = 0x1b << 20 + case ALDREXB: + o1 = 0x1d << 20 + } + o1 |= 0xf9f o1 |= (uint32(p.From.Reg) & 15) << 16 o1 |= (uint32(p.To.Reg) & 15) << 12 o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 - case 92: /* strexd reg,oreg,reg */ + case 92: /* strexd/strexb reg,oreg,reg */ c.aclass(&p.From) if c.instoffset != 0 { c.ctxt.Diag("offset must be zero in STREX") } - if p.Reg&1 != 0 { - c.ctxt.Diag("source register must be even in STREXD: %v", p) - } - if p.To.Reg == p.From.Reg || p.To.Reg == p.Reg || p.To.Reg == p.Reg+1 { + if p.To.Reg == p.From.Reg || p.To.Reg == p.Reg || (p.As == ASTREXD && p.To.Reg == p.Reg+1) { c.ctxt.Diag("cannot use same register as both source and destination: %v", p) } - o1 = 0x1a<<20 | 0xf90 + + switch p.As { + case ASTREXD: + if p.Reg&1 != 0 { + c.ctxt.Diag("source register must be even in STREXD: %v", p) + } + o1 = 0x1a << 20 + case ASTREXB: + o1 = 0x1c << 20 + } + o1 |= 0xf90 o1 |= (uint32(p.From.Reg) & 15) << 16 o1 |= (uint32(p.Reg) & 15) << 0 o1 |= (uint32(p.To.Reg) & 15) << 12 |
