mirror of
https://github.com/golang/go
synced 2024-11-19 05:14:50 -07:00
cmd/asm: implement MCR instruction on ARM
It's an oddball that needs special treatment because it is not really an opcode, but a variant of MRC. The String method of Prog still needs updating to print it nicely. Change-Id: I6005b7f2234ccd3d4ac1f658948e3be97cf1f1c2 Reviewed-on: https://go-review.googlesource.com/7220 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
7b0c73aa28
commit
5d987f1513
@ -186,6 +186,10 @@ func archArm() *Arch {
|
||||
// Annoying aliases.
|
||||
instructions["B"] = obj.AJMP
|
||||
instructions["BL"] = obj.ACALL
|
||||
// MCR differs from MRC by the way fields of the word are encoded.
|
||||
// (Details in arm.go). Here we add the instruction so parse will find
|
||||
// it, but give it an opcode number known only to us.
|
||||
instructions["MCR"] = aMCR
|
||||
|
||||
return &Arch{
|
||||
LinkArch: &arm.Linkarm,
|
||||
|
@ -105,19 +105,26 @@ func IsARMSTREX(op int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// MCR is not defined by the obj/arm; instead we define it privately here.
|
||||
// It is encoded as an MRC with a bit inside the instruction word,
|
||||
// passed to arch.ARMMRCOffset.
|
||||
const aMCR = arm.ALAST + 1
|
||||
|
||||
// IsARMMRC reports whether the op (as defined by an arm.A* constant) is
|
||||
// MRC or MCR
|
||||
func IsARMMRC(op int) bool {
|
||||
switch op {
|
||||
case arm.AMRC /*, arm.AMCR*/ :
|
||||
case arm.AMRC, aMCR: // Note: aMCR is defined in this package.
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ARMMRCOffset implements the peculiar encoding of the MRC and MCR instructions.
|
||||
func ARMMRCOffset(op int, cond string, x0, x1, x2, x3, x4, x5 int64) (offset int64, ok bool) {
|
||||
// TODO only MRC is defined.
|
||||
// The difference between MRC and MCR is represented by a bit high in the word, not
|
||||
// in the usual way by the opcode itself. Asm must use AMRC for both instructions, so
|
||||
// we return the opcode for MRC so that asm doesn't need to import obj/arm.
|
||||
func ARMMRCOffset(op int, cond string, x0, x1, x2, x3, x4, x5 int64) (offset int64, op0 int16, ok bool) {
|
||||
op1 := int64(0)
|
||||
if op == arm.AMRC {
|
||||
op1 = 1
|
||||
@ -136,7 +143,7 @@ func ARMMRCOffset(op int, cond string, x0, x1, x2, x3, x4, x5 int64) (offset int
|
||||
((x4 & 15) << 0) | // Crm
|
||||
((x5 & 7) << 5) | // coprocessor information
|
||||
(1 << 4) /* must be set */
|
||||
return offset, true
|
||||
return offset, arm.AMRC, true
|
||||
}
|
||||
|
||||
// IsARMMULA reports whether the op (as defined by an arm.A* constant) is
|
||||
|
@ -567,12 +567,13 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
|
||||
x4 := int64(p.getRegister(prog, op, &a[4]))
|
||||
x5 := p.getConstant(prog, op, &a[5])
|
||||
// Cond is handled specially for this instruction.
|
||||
offset, ok := arch.ARMMRCOffset(op, cond, x0, x1, x2, x3, x4, x5)
|
||||
offset, MRC, ok := arch.ARMMRCOffset(op, cond, x0, x1, x2, x3, x4, x5)
|
||||
if !ok {
|
||||
p.errorf("unrecognized condition code .%q", cond)
|
||||
}
|
||||
prog.To.Offset = offset
|
||||
cond = ""
|
||||
prog.As = MRC // Both instructions are coded as MRC.
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
|
Loading…
Reference in New Issue
Block a user