mirror of
https://github.com/golang/go
synced 2024-11-19 21:04:43 -07: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:
parent
5f29a7a705
commit
556fb16bbd
10
src/cmd/asm/internal/asm/testdata/arm64enc.s
vendored
10
src/cmd/asm/internal/asm/testdata/arm64enc.s
vendored
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user