]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/arm64: add checks for incorrect use of REGTMP register
authorfanzha02 <fannie.zhang@arm.com>
Tue, 24 Aug 2021 04:46:54 +0000 (12:46 +0800)
committerfannie zhang <Fannie.Zhang@arm.com>
Thu, 9 Sep 2021 01:23:30 +0000 (01:23 +0000)
The current assembler uses REGTMP as a temporary destination register,
when optimizing one instruction into a multi-instruction sequence. But
in some cases, when the source register is REGTMP, this behavior is
incorrect.

For example:
  ADD $0x1234567, R27, R3

The current assembler encodes it into
  MOVD $17767, R27
  MOVK $(291<<16), R27
  ADD R27, R27, R3

It is illegal to overwrite R27. This CL adds the related checks.

Add test cases.

Change-Id: I0af373d9fd23d8f067c093778dd4cc76748faf38
Reviewed-on: https://go-review.googlesource.com/c/go/+/344689
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: fannie zhang <Fannie.Zhang@arm.com>

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

index 8b12b166804bf4eb0f233ef2bd2893a8996213f1..7b006432c079394630c109a3f645c72c0e07122f 100644 (file)
@@ -406,12 +406,12 @@ TEXT errors(SB),$0
        VBIF    V0.D2, V1.D2, V2.D2                              // ERROR "invalid arrangement"
        VUADDW  V9.B8, V12.H8, V14.B8                            // ERROR "invalid arrangement"
        VUADDW2 V9.B8, V12.S4, V14.S4                            // ERROR "operand mismatch"
-       VUMAX   V1.D2, V2.D2, V3.D2                              // ERROR "invalid arrangement"
-       VUMIN   V1.D2, V2.D2, V3.D2                              // ERROR "invalid arrangement"
+       VUMAX   V1.D2, V2.D2, V3.D2                              // ERROR "invalid arrangement"
+       VUMIN   V1.D2, V2.D2, V3.D2                              // ERROR "invalid arrangement"
        VUMAX   V1.B8, V2.B8, V3.B16                             // ERROR "operand mismatch"
        VUMIN   V1.H4, V2.S4, V3.H4                              // ERROR "operand mismatch"
        VSLI    $64, V7.D2, V8.D2                                // ERROR "shift out of range"
-       VUSRA   $0, V7.D2, V8.D2                                 // ERROR "shift out of range"
+       VUSRA   $0, V7.D2, V8.D2                                 // ERROR "shift out of range"
        CASPD   (R3, R4), (R2), (R8, R9)                         // ERROR "source register pair must start from even register"
        CASPD   (R2, R3), (R2), (R9, R10)                        // ERROR "destination register pair must start from even register"
        CASPD   (R2, R4), (R2), (R8, R9)                         // ERROR "source register pair must be contiguous"
@@ -419,8 +419,15 @@ TEXT errors(SB),$0
        ADD     R1>>2, RSP, R3                                   // ERROR "illegal combination"
        ADDS    R2<<3, R3, RSP                                   // ERROR "unexpected SP reference"
        CMP     R1<<5, RSP                                       // ERROR "the left shift amount out of range 0 to 4"
-       MOVD.P  y+8(FP), R1                                      // ERROR "illegal combination"
-       MOVD.W  x-8(SP), R1                                      // ERROR "illegal combination"
-       LDP.P   x+8(FP), (R0, R1)                                // ERROR "illegal combination"
-       LDP.W   x+8(SP), (R0, R1)                                // ERROR "illegal combination"
+       MOVD.P  y+8(FP), R1                                      // ERROR "illegal combination"
+       MOVD.W  x-8(SP), R1                                      // ERROR "illegal combination"
+       LDP.P   x+8(FP), (R0, R1)                                // ERROR "illegal combination"
+       LDP.W   x+8(SP), (R0, R1)                                // ERROR "illegal combination"
+       ADD     $0x1234567, R27, R3                              // ERROR "cannot use REGTMP as source"
+       ADD     $0x3fffffffc000, R27, R5                         // ERROR "cannot use REGTMP as source"
+       AND     $0x22220000, R27, R4                             // ERROR "cannot use REGTMP as source"
+       ANDW    $0x6006000060060, R27, R5                        // ERROR "cannot use REGTMP as source"
+       STP     (R3, R4), 0x1234567(R27)                         // ERROR "REGTMP used in large offset store"
+       LDP     0x1234567(R27), (R3, R4)                         // ERROR "REGTMP used in large offset load"
+       STP     (R26, R27), 700(R2)                              // ERROR "cannot use REGTMP as source"
        RET
index 8db25cf9675a80c3651b742c268bbecd5758559b..5d6caaed5f8e3c34cb5c33df0455bc90f28faf78 100644 (file)
@@ -3407,6 +3407,9 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                o4 = os[3]
 
        case 13: /* addop $vcon, [R], R (64 bit literal); cmp $lcon,R -> addop $lcon,R, ZR */
+               if p.Reg == REGTMP {
+                       c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
+               }
                if p.To.Reg == REG_RSP && isADDSop(p.As) {
                        c.ctxt.Diag("illegal destination register: %v\n", p)
                }
@@ -3724,6 +3727,9 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                o1 |= (uint32(r&31) << 5) | uint32(rt&31)
 
        case 28: /* logop $vcon, [R], R (64 bit literal) */
+               if p.Reg == REGTMP {
+                       c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
+               }
                o := uint32(0)
                num := uint8(0)
                cls := oclass(&p.From)
@@ -4354,6 +4360,9 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
 
                /* reloc ops */
        case 64: /* movT R,addr -> adrp + add + movT R, (REGTMP) */
+               if p.From.Reg == REGTMP {
+                       c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
+               }
                o1 = ADR(1, 0, REGTMP)
                o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
                rel := obj.Addrel(c.cursym)
@@ -4585,6 +4594,9 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                //      add Rtmp, R, Rtmp
                //      ldp (Rtmp), (R1, R2)
                r := int(p.From.Reg)
+               if r == REGTMP {
+                       c.ctxt.Diag("REGTMP used in large offset load: %v", p)
+               }
                if r == obj.REG_NONE {
                        r = int(o.param)
                }
@@ -4601,6 +4613,9 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
        case 76:
                //      add $O, R, Rtmp or sub $O, R, Rtmp
                //      stp (R1, R2), (Rtmp)
+               if p.From.Reg == REGTMP || p.From.Offset == REGTMP {
+                       c.ctxt.Diag("cannot use REGTMP as source: %v", p)
+               }
                r := int(p.To.Reg)
                if r == obj.REG_NONE {
                        r = int(o.param)
@@ -4628,6 +4643,9 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                //      add Rtmp, R, Rtmp
                //      stp (R1, R2), (Rtmp)
                r := int(p.To.Reg)
+               if r == REGTMP || p.From.Reg == REGTMP || p.From.Offset == REGTMP {
+                       c.ctxt.Diag("REGTMP used in large offset store: %v", p)
+               }
                if r == obj.REG_NONE {
                        r = int(o.param)
                }
@@ -4933,6 +4951,9 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                o1 |= (uint32(Q&1) << 30) | (uint32((r>>5)&7) << 16) | (uint32(r&0x1f) << 5) | uint32(rt&31)
 
        case 87: /* stp (r,r), addr(SB) -> adrp + add + stp */
+               if p.From.Reg == REGTMP || p.From.Offset == REGTMP {
+                       c.ctxt.Diag("cannot use REGTMP as source: %v", p)
+               }
                o1 = ADR(1, 0, REGTMP)
                o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
                rel := obj.Addrel(c.cursym)