diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go index 91a2fc22ff3..a81de43845e 100644 --- a/src/cmd/internal/obj/x86/asm6.go +++ b/src/cmd/internal/obj/x86/asm6.go @@ -5374,7 +5374,7 @@ func (ab *AsmBuf) asmins(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) { if int64(r.Off) < p.Pc { break } - if ab.rexflag != 0 && !ab.vexflag { + if ab.rexflag != 0 && !ab.vexflag && !ab.evexflag { r.Off++ } if r.Type == objabi.R_PCREL { diff --git a/src/cmd/internal/obj/x86/issue19518_test.go b/src/cmd/internal/obj/x86/pcrelative_test.go similarity index 67% rename from src/cmd/internal/obj/x86/issue19518_test.go rename to src/cmd/internal/obj/x86/pcrelative_test.go index 174e2dd846f..51b60cf93e5 100644 --- a/src/cmd/internal/obj/x86/issue19518_test.go +++ b/src/cmd/internal/obj/x86/pcrelative_test.go @@ -6,6 +6,7 @@ package x86_test import ( "bytes" + "fmt" "internal/testenv" "io/ioutil" "os" @@ -17,7 +18,7 @@ import ( const asmData = ` GLOBL zeros<>(SB),8,$64 TEXT ·testASM(SB),4,$0 -VMOVDQU zeros<>(SB), Y8 // PC relative relocation is off by 1, for Y8-15 +VMOVUPS zeros<>(SB), %s // PC relative relocation is off by 1, for Y8-Y15, Z8-15 and Z24-Z31 RET ` @@ -31,13 +32,13 @@ func main() { } ` -func objdumpOutput(t *testing.T) []byte { - tmpdir, err := ioutil.TempDir("", "19518") +func objdumpOutput(t *testing.T, mname, source string) []byte { + tmpdir, err := ioutil.TempDir("", mname) if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpdir) - err = ioutil.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte("module issue19518\n"), 0666) + err = ioutil.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte(fmt.Sprintf("module %s\n", mname)), 0666) if err != nil { t.Fatal(err) } @@ -46,7 +47,7 @@ func objdumpOutput(t *testing.T) []byte { t.Fatal(err) } defer tmpfile.Close() - _, err = tmpfile.WriteString(asmData) + _, err = tmpfile.WriteString(source) if err != nil { t.Fatal(err) } @@ -85,17 +86,19 @@ func objdumpOutput(t *testing.T) []byte { return objout } -func TestVexPCrelative(t *testing.T) { +func TestVexEvexPCrelative(t *testing.T) { testenv.MustHaveGoBuild(t) - objout := objdumpOutput(t) - data := bytes.Split(objout, []byte("\n")) - for idx := len(data) - 1; idx >= 0; idx-- { - // OBJDUMP doesn't know about VMOVDQU, - // so instead of checking that it was assembled correctly, - // check that RET wasn't overwritten. - if bytes.Index(data[idx], []byte("RET")) != -1 { - return +LOOP: + for _, reg := range []string{"Y0", "Y8", "Z0", "Z8", "Z16", "Z24"} { + asm := fmt.Sprintf(asmData, reg) + objout := objdumpOutput(t, "pcrelative", asm) + data := bytes.Split(objout, []byte("\n")) + for idx := len(data) - 1; idx >= 0; idx-- { + // check that RET wasn't overwritten. + if bytes.Index(data[idx], []byte("RET")) != -1 { + continue LOOP + } } + t.Errorf("VMOVUPS zeros<>(SB), %s overwrote RET", reg) } - t.Fatal("RET was overwritten") }