1
0
mirror of https://github.com/golang/go synced 2024-10-02 16:28:34 -06:00

cmd/internal/obj/arm64: fix assemble msr/mrs bug

The arguments <pstatefield> is a struct that includes two elements,
element reg is special register, elememt enc is pstate field values.
The current code compares two different type values and get a incorrect
result.

The fix follows pstate field to create a systemreg struct,
each system register has a vaule to use in instruction.

Uncomment the msr/mrs cases.

Fixes #21464

Change-Id: I1bb1587ec8548f3e4bd8d5be4d7127bd10d53186
Reviewed-on: https://go-review.googlesource.com/56030
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:
fanzha02 2017-06-13 11:07:34 +00:00 committed by Cherry Zhang
parent 5f29a7a705
commit 556fb16bbd
2 changed files with 43 additions and 15 deletions

View File

@ -246,11 +246,11 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$-8
MOVKW $(3905<<16), R21 // MOVKW $255918080, R21 // 35e8a172
MOVK $(3905<<32), R21 // MOVK $16771847290880, R21 // 35e8c1f2
MOVD $0, R5 // 050080d2
// MRS $4567, R16 // f03a32d5
// MRS $32345, R6 // 26cb3fd5
// MSR R25, $3452 // 99af11d5
// MSR R25, $16896 // 194018d5
// MSR $6, DAIFClr // ff4603d5
MSR $1, SPSel // bf4100d5
MSR $9, DAIFSet // df4903d5
MSR $6, DAIFClr // ff4603d5
MRS ELR_EL1, R8 // 284038d5
MSR R16, ELR_EL1 // 304018d5
MSUBW R1, R1, R12, R5 // 8585011b
MSUB R19, R16, R26, R2 // 42c3139b
MULW R26, R5, R22 // b67c1a1b

View File

@ -607,14 +607,22 @@ var optab = []Optab{
* valid pstate field values, and value to use in instruction
*/
var pstatefield = []struct {
a uint32
b uint32
reg int16
enc uint32
}{
{REG_SPSel, 0<<16 | 4<<12 | 5<<5},
{REG_DAIFSet, 3<<16 | 4<<12 | 6<<5},
{REG_DAIFClr, 3<<16 | 4<<12 | 7<<5},
}
// the System register values, and value to use in instruction
var systemreg = []struct {
reg int16
enc uint32
}{
{REG_ELR_EL1, 8<<16 | 4<<12 | 1<<5},
}
func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p := cursym.Func.Text
if p == nil || p.Link == nil { // handle external functions and ELF section symbols
@ -2745,21 +2753,41 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
case 35: /* mov SPR,R -> mrs */
o1 = c.oprrr(p, AMRS)
v := int32(p.From.Offset)
v := uint32(0)
for i := 0; i < len(systemreg); i++ {
if systemreg[i].reg == p.From.Reg {
v = systemreg[i].enc
break
}
}
if v == 0 {
c.ctxt.Diag("illegal system register:\n%v", p)
}
if (o1 & uint32(v&^(3<<19))) != 0 {
c.ctxt.Diag("MRS register value overlap\n%v", p)
}
o1 |= uint32(v)
o1 |= v
o1 |= uint32(p.To.Reg & 31)
case 36: /* mov R,SPR */
o1 = c.oprrr(p, AMSR)
v := int32(p.To.Offset)
v := uint32(0)
for i := 0; i < len(systemreg); i++ {
if systemreg[i].reg == p.To.Reg {
v = systemreg[i].enc
break
}
}
if v == 0 {
c.ctxt.Diag("illegal system register:\n%v", p)
}
if (o1 & uint32(v&^(3<<19))) != 0 {
c.ctxt.Diag("MSR register value overlap\n%v", p)
}
o1 |= uint32(v)
o1 |= v
o1 |= uint32(p.From.Reg & 31)
case 37: /* mov $con,PSTATEfield -> MSR [immediate] */
@ -2768,10 +2796,10 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
}
o1 = c.opirr(p, AMSR)
o1 |= uint32((p.From.Offset & 0xF) << 8) /* Crm */
v := int32(0)
v := uint32(0)
for i := 0; i < len(pstatefield); i++ {
if int64(pstatefield[i].a) == p.To.Offset {
v = int32(pstatefield[i].b)
if pstatefield[i].reg == p.To.Reg {
v = pstatefield[i].enc
break
}
}
@ -2779,7 +2807,7 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
if v == 0 {
c.ctxt.Diag("illegal PSTATE field for immediate move\n%v", p)
}
o1 |= uint32(v)
o1 |= v
case 38: /* clrex [$imm] */
o1 = c.opimm(p, p.As)