]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/arm64: fix assemble msr/mrs bug
authorfanzha02 <fannie.zhang@arm.com>
Tue, 13 Jun 2017 11:07:34 +0000 (11:07 +0000)
committerCherry Zhang <cherryyz@google.com>
Tue, 21 Nov 2017 14:00:35 +0000 (14:00 +0000)
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>

src/cmd/asm/internal/asm/testdata/arm64enc.s
src/cmd/internal/obj/arm64/asm7.go

index 2c0f32e971877df072a3ff974c22d9b1ba4a3afd..b02e0b32ec0c1c16b08829b48931deea2d3fc510 100644 (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
index c4aa6b62c81f843252df4a6fc9e9dd07cee1aebe..e15124073a5967275b1f32782d7375278864608c 100644 (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)