]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/asm: Fix encoding error of register offset shifted by 0 on arm64
authoreric fang <eric.fang@arm.com>
Tue, 18 Jul 2023 06:50:49 +0000 (06:50 +0000)
committerEric Fang <eric.fang@arm.com>
Mon, 24 Jul 2023 01:11:41 +0000 (01:11 +0000)
The following instruction is wrongly encoded on arm64:
MOVD (R2)(R3<<0), R1
It's incorrectly encoded as
MOVD (R2)(R3<<3), R1

The reason for the error is that we hard-coded the shift encoding to 6,
which is correct for the MOVB and MOVBU instructions because it only
allows a shift amount of 0, but it is wrong for the MOVD instruction
because it also allows other shift values.

For instructions MOVB, MOVBU and FMOVB, the extension amount must be 0,
encoded in "S" as 0 if omitted, or as 1 if present. But in Go, we don't
distinguish between Rn.<EXT> and Rn.<EXT><<0, so we encode it as that
does not present. This makes no difference to the function of the
instruction.

Change-Id: I2afe3498392cc9b2ecd524c7744f28b9d6d107b8
Reviewed-on: https://go-review.googlesource.com/c/go/+/510995
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Eric Fang <eric.fang@arm.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

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

index 11bd6785524443c9b599347a23892e79d6096bce..2c7d638319b554cdfeabe4bf5cc84d78784fa3ed 100644 (file)
@@ -595,6 +595,7 @@ TEXT        foo(SB), DUPOK|NOSPLIT, $-8
        MOVD    (R3)(R6*1), R5                  // 656866f8
        MOVD    (R2)(R6), R4                    // 446866f8
        MOVWU   (R19)(R20<<2), R20              // 747a74b8
+       MOVD    (R2)(R3<<0), R1                 // 416863f8
        MOVD    (R2)(R6<<3), R4                 // 447866f8
        MOVD    (R3)(R7.SXTX<<3), R8            // 68f867f8
        MOVWU   (R5)(R4.UXTW), R10              // aa4864b8
@@ -604,7 +605,7 @@ TEXT        foo(SB), DUPOK|NOSPLIT, $-8
        MOVHU   (R1)(R2<<1), R5                 // 25786278
        MOVB    (R9)(R3.UXTW), R6               // 2649a338
        MOVB    (R10)(R6), R15                  // 4f69a638
-       MOVB    (R29)(R30<<0), R14              // ae7bbe38
+       MOVB    (R29)(R30<<0), R14              // ae6bbe38
        MOVB    (R29)(R30), R14                 // ae6bbe38
        MOVH    (R5)(R7.SXTX<<1), R19           // b3f8a778
        MOVH    (R8)(R4<<1), R10                // 0a79a478
index 7ef3a7f5f06162338e6bc985d0b17d3b7fb4ec78..cc002a1584d2c7afb3fba07d8544913eb5d7da23 100644 (file)
@@ -186,7 +186,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$-8
        MOVBU.P 42(R2), R12                        // 4ca44238
        MOVBU.W -27(R2), R14                       // 4e5c5e38
        MOVBU 2916(R24), R3                        // 03936d39
-       MOVBU (R19)(R14<<0), R23                   // 777a6e38
+       MOVBU (R19)(R14<<0), R23                   // 776a6e38
        MOVBU (R2)(R8.SXTX), R19                   // 53e86838
        MOVBU (R27)(R23), R14                      // 6e6b7738
        MOVHU.P 107(R14), R13                      // cdb54678
index ff8daad85784113632282bfac9b9edf1037c5b16..2ee7b0f6c62bee070e3d1fd199d477be281270bb 100644 (file)
@@ -7601,6 +7601,11 @@ func (c *ctxt7) encRegShiftOrExt(p *obj.Prog, a *obj.Addr, r int16) uint32 {
        case REG_UXTW <= r && r < REG_UXTX:
                if a.Type == obj.TYPE_MEM {
                        if num == 0 {
+                               // According to the arm64 specification, for instructions MOVB, MOVBU and FMOVB,
+                               // the extension amount must be 0, encoded in "S" as 0 if omitted, or as 1 if present.
+                               // But in Go, we don't distinguish between Rn.UXTW and Rn.UXTW<<0, so we encode it as
+                               // that does not present. This makes no difference to the function of the instruction.
+                               // This is also true for extensions LSL, SXTW and SXTX.
                                return roff(rm, 2, 2)
                        } else {
                                return roff(rm, 2, 6)
@@ -7636,7 +7641,11 @@ func (c *ctxt7) encRegShiftOrExt(p *obj.Prog, a *obj.Addr, r int16) uint32 {
                }
        case REG_LSL <= r && r < REG_ARNG:
                if a.Type == obj.TYPE_MEM { // (R1)(R2<<1)
-                       return roff(rm, 3, 6)
+                       if num == 0 {
+                               return roff(rm, 3, 2)
+                       } else {
+                               return roff(rm, 3, 6)
+                       }
                } else if isADDWop(p.As) {
                        return roff(rm, 2, num)
                }